GDI+ によって表示された画像が拡大鏡で拡大できない

文書翻訳 文書翻訳
文書番号: 319261 - 対象製品
この記事は、以前は次の ID で公開されていました: JP319261
すべて展開する | すべて折りたたむ

目次

現象

GDI+ によって表示された画像を拡大鏡で拡大できません。この問題は、Microsoft Office XP、Microsoft Visio 2002、Microsoft .NET Framework、Windows シェルなど、GDI+ を使用するすべてのプログラムで発生します。

原因

GDI+ では DCI というメカニズムを使用して、フロント バッファに直接表示を行います。この方法で表示する場合、GDI+ では GDI DDI 呼び出しを生成しません。しかし、拡大鏡は、すべての表示が GDI を介して行われることを前提として機能します。拡大鏡は GDI DDI 呼び出しをフックし、すべての表示をオフスクリーン ビットマップにキャプチャして、拡大されたビットマップの一部を画面上に描画します。

GDI+ を使用するプログラムと一緒に拡大鏡を実行すると、画面の中で、拡大されて描画される部分と、拡大されずに描画される部分が現れます。

解決方法

この問題を解決するには、Windows XP の最新の Service Pack を入手します。関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
322389 最新の Windows XP Service Pack を入手する方法
この問題を解決するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) に記載されている更新プログラムを入手してください。
318966 Windows XP で画像を表示、編集、または印刷する場合の問題

プログラム開発者向け

プログラム開発を行っている場合、GDI+ で、DCI ではなく GDI を使用して表示するようにプログラムを修正する必要があります。各 GDI+ インスタンスには、"GDI+ Window" という名前で、GDI+ Hook Window Class というクラス名の非表示のトップレベル ウィンドウが含まれています。「サポート技術情報」 (Microsoft Knowledge Base) の文書番号 318966 の資料に記載されている更新プログラムをインストールすると、GDI+ の非表示のウィンドウは "GDI+ Accessibility" という名前のプライベート ウィンドウ メッセージをリッスンします。GDI+ 非表示ウィンドウがこのメッセージを受け取ると、表示に DCI を使用せず、代わりに GDI を使用します。これによって、GDI+ が拡大鏡と正常に連携するようになります。

拡大鏡は、読み込まれたときに "GDI+ Accessibility" という名前のプライベート ウィンドウ メッセージを登録する必要があります。GDI+ でも、これと同じ名前のプライベート メッセージを登録するため、拡大鏡はこのメッセージを使用して GDI+ と通信することができます。拡大鏡は既存のすべてのトップレベル ウィンドウをスキャンする必要があります。拡大鏡が "GDI+ Window" という名前のウィンドウを見つけ、そのクラス名が GDI+ Hook Window Class である場合、拡大鏡は "GDI+ Accessibility" メッセージをそれらのウィンドウに送る必要があります。これによって、既存の GDI+ プログラムが正常に拡大されます。

また、拡大鏡は、その起動後に読み込まれる新しい GDI+ プログラムも監視する必要があります。拡大鏡はこれを実行するために、新しいウィンドウが作成されるたびに呼び出される SetWinEventHook を使用してコールバック関数を設定します。新しいウィンドウが正しい名前とクラス名で作成されたら、拡大鏡はそのウィンドウに "GDI+ Accessibility" メッセージを送る必要があります。

GDI+ の特定のインスタンスで、DCI ではなく GDI を使用した表示をいったん開始すると、プログラムを終了して再起動しない限り、再び DCI を使用するように切り替えることはできません。GDI+ の表示は、DCI を使用する場合よりも、GDI を使用する場合の方が遅くなります。GDI+ で拡大鏡が不要になった場合に、表示速度を速くするには、ユーザーは GDI+ プログラムを再起動することができます。

状況

マイクロソフトでは、この問題をこの資料の冒頭に記載したマイクロソフト製品の問題として認識しています。 この問題は、Windows XP Service Pack 1 で最初に修正されました。

詳細

以下のサンプル プログラムは、プログラムで新しい GDI+ 機能を使用する方法を示しています。プロジェクトで Gdipacs.c ファイルと Gdipacs.h ファイルをインクルードします。また、プログラムの起動時に GDIPlusDCIOff_Init を呼び出す必要があります。これにより、すべての既存の GDI+ プログラムで表示に DCI が使用されず、新しく読み込まれた GDI+ プログラムでも表示に DCI が使用されません。プログラムの終了時には、GDIPlusDCIOff_Uninit を呼び出します。既に実行中の GDI+ プログラムで DCI が使用されるように戻すことはできませんが、新しい GDI+ プログラムでは通常どおり DCI が使用されるようになります。

Testmain.c ファイルは、この機能の例を示しています。このファイルをコンパイルして実行し、GDI+ プログラムで "GDI+ Accessibility" メッセージをテストしてください。

サンプル コード

マイクロソフトは、この情報をプログラミング言語の使用方法の一例として提供するだけであり、市場性および特定目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。この資料は、例示されているプログラミング言語やプロシージャの作成およびデバッグに使用するツールについて理解されているユーザーを対象としています。Microsoft Support 担当者は、特定のプロシージャの機能についての問い合わせにはお答えできますが、ユーザー固有の目的に合わせた機能の追加、プロシージャの作成などの内容変更は行っておりません。プログラミングに習熟されていない場合、マイクロソフト認定パートナー、あるいはマイクロソフトの有償サポート窓口までお問い合わせください。マイクロソフト認定パートナー、有償サポート窓口については、次のマイクロソフト Web サイトを参照してください。
https://solutionfinder.microsoft.com/
http://www.microsoft.com/japan/microsoftservices/support/is.asp
利用可能なサポート オプションおよびマイクロソフトの問い合わせ先の詳細については、次のマイクロソフト Web サイトを参照してください。
http://support.microsoft.com/contactus/?ws=support
/*********************** Module*Header ************************\ 
* Module Name: gdipacs.h
*
* Copyright (c) 2002 Microsoft Corporation
\**************************************************************/ 

/* 
 * To tell GDI+ to stop using DCI:
 * Call GDIPlusDCIOff_Init as part of your program startup.
 * This must be called by a thread that has a message pump.
 * Before terminating, call GDIPlusDCIOff_Uninit on that
 * same thread to clean up.
 */ 

BOOL GDIPlusDCIOff_Init();
VOID GDIPlusDCIOff_Uninit();




/*********************** Module*Header ************************\ 
* Module Name: gdipacs.cpp
*
* Copyright (c) 2002 Microsoft Corporation
\**************************************************************/ 

// Need WINVER 0x0500 to get the definitions for WinEvents.
// (They will still work on Windows 95 and Windows NT 4.0 SP6.)
#define WINVER 0x0500
#include <windows.h>
#include "gdipacs.h"


#define GDIPLUS_TITLE      TEXT("GDI+ Window")
#define GDIPLUS_CLASSNAME  TEXT("GDI+ Hook Window Class")
#define GDIPLUS_DCIOFFMSG  TEXT("GDI+ Accessibility")


HWINEVENTHOOK ghWinEventHook = NULL;
UINT gwmGdipMessage = 0;


static BOOL IsGDIPlusWindow(HWND hwnd)
{
    TCHAR str[MAX_PATH];

     // Check that window is top-level and unowned...
     if(GetParent(hwnd) != NULL)
          return FALSE;

     // Check window class name...
    if(GetClassName(hwnd, str, MAX_PATH) == 0
     || lstrcmp(str, GDIPLUS_CLASSNAME) != 0)
          return FALSE;

     // Check window title...
    if(GetWindowText(hwnd, str, MAX_PATH) == 0
      || lstrcmp(str, GDIPLUS_TITLE) != 0)
          return FALSE;

     return TRUE;
}

static VOID SendDCIOFFMessage(HWND hwnd)
{
    SendMessage(hwnd, gwmGdipMessage, 0, 0);
    
#ifdef _DEBUG
     {
          TCHAR strDebug[MAX_PATH];

          // For debug purposes, output handle to hidden window.
          wsprintf(
               strDebug,
               TEXT("Sent GDI+ Message: HWND=%08x\n"),
               hwnd);

          OutputDebugString(strDebug);
     }
#endif
}



static BOOL CALLBACK WndEnumProc(
    HWND hwnd,
    LPARAM lParam
    )
{
     if(IsGDIPlusWindow(hwnd))
     {
          SendDCIOFFMessage(hwnd);
    }
    return TRUE;
}

VOID CALLBACK WindowCreateProc(
    HWINEVENTHOOK hWinEventHook,
    DWORD event,
    HWND hwnd,
    LONG idObject,
    LONG idChild,
    DWORD dwEventThread,
    DWORD dwmsEventTime
    )
{
    if (idObject == OBJID_WINDOW && IsGDIPlusWindow(hwnd))
     {
          SendDCIOFFMessage(hwnd);
    }
}



BOOL GDIPlusDCIOff_Init()
{
     if(ghWinEventHook != NULL)
          return FALSE;

     // Register the "turn off DCI" message...
    gwmGdipMessage = RegisterWindowMessage(GDIPLUS_DCIOFFMSG);
    if (gwmGdipMessage == 0)
    {
        return FALSE;
    }

     // Set a hook to watch for new windows being created...
    ghWinEventHook = SetWinEventHook(
        EVENT_OBJECT_CREATE,
        EVENT_OBJECT_CREATE,
        NULL,
        WindowCreateProc,
        0,
        0,
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
    if (ghWinEventHook == NULL)
    {
        return FALSE;
    }

     // Scan through existing windows...
    EnumWindows(WndEnumProc, 0);

     return TRUE;
}

VOID GDIPlusDCIOff_Uninit()
{
     if(ghWinEventHook != NULL)
     {
         UnhookWinEvent(ghWinEventHook);
          ghWinEventHook = NULL;
     }
}


/*********************** Module*Header ************************\ 
* Module Name: testmain.c
*
* Copyright (c) 2002 Microsoft Corporation
\**************************************************************/ 

/* 
 * Sample program that demonstrates using GDIPACS.h to turn off
 * the GDI+ use of DCI.
 */ 

#include <windows.h>
#include "gdipacs.h"

#define TITLE TEXT("GDI+ DCI Disabler")

int WINAPI
WinMain( HINSTANCE  hInstance,
         HINSTANCE  hPrevInstance,
         LPSTR      szCmdLine, 
         int        nCmdShow )
{
     MessageBox(NULL,TEXT("Click OK to start disabling use of DCI..."), TITLE, MB_OK);

     /*
      * GDIPlusDCIOff_Init() must be called from a thread that pumps
      * messages - typically the main UI thread. In this sample, the
      * MessageBox calls contain message pumps. A real-world program
      * likely has its own GetMessage() loop instead.
      */ 
     if( ! GDIPlusDCIOff_Init() )
     {
          MessageBox(NULL,TEXT("GDIPlusDCIOff_Init() failed"), TITLE, MB_OK);
          return 0;
     }

     MessageBox(NULL,TEXT("DCI is now turned off in all existing GDI+ programs. Click OK to turn on DCI again..."), TITLE, MB_OK);

     GDIPlusDCIOff_Uninit();
     
     MessageBox(NULL,TEXT("DCI remains turned off in all existing GDI+ programs, but will be turned on for new programs that start. Click OK to exit this sample."), TITLE, MB_OK);

    return 0;
}
				

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 319261 (最終更新日 2004-06-28) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。

プロパティ

文書番号: 319261 - 最終更新日: 2007年8月13日 - リビジョン: 5.4
この資料は以下の製品について記述したものです。
  • Microsoft .NET Framework 1.0?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
  • Microsoft GDI+ 1.0?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
  • Microsoft Office XP Standard?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
  • Microsoft Visio Professional Version 2002?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
  • Microsoft Visio Standard Version 2002?を以下の環境でお使いの場合
    • Microsoft Windows XP Professional
キーワード:?
kbbug kbfix kbshell kbwinxpsp1fix KB319261
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com