現在オフラインです。再接続するためにインターネットの接続を待っています

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

この記事は、以前は次の 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 サイトを参照してください。利用可能なサポート オプションおよびマイクロソフトの問い合わせ先の詳細については、次のマイクロソフト Web サイトを参照してください。
/*********************** 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 WINAPIWinMain( 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) を基に作成したものです。

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

文書番号:319261 - 最終更新日: 08/13/2007 19:46:00 - リビジョン: 5.4

  • Microsoft .NET Framework 1.0
  • Microsoft GDI+ 1.0
  • Microsoft Office XP Standard
  • Microsoft Visio Professional Version 2002
  • Microsoft Visio Standard Version 2002
  • kbbug kbfix kbshell kbwinxpsp1fix KB319261
フィードバック