Gráficos Renderizados pelo GDI+ não podem ser Ampliados por Lentes de Aumento

Traduções deste artigo Traduções deste artigo
ID do artigo: 319261 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sintomas

Os gráficos renderizados pelo GDI+ não podem ser ampliados por lentes de aumento. Esse problema afeta os programas que usam o GDI+, incluindo o Microsoft Office XP, o Microsoft Visio 2002, o Microsoft .NET Framework e o shell do Windows.

Causa

O GDI+ usa um mecanismo chamado de DCI para renderizar diretamente no buffer principal. O GDI+ não gera chamadas DDI GDI ao renderizar dessa maneira. No entanto, as lentes de aumento funcionam considerando que toda a renderização é feita pelo GDI. As lentes de aumento acoplam as chamadas DDI GDI, capturam todas as informações em um bitmap fora da tela, e desenham uma parte desse bitmap ampliado na tela.

Se uma lente de aumento for executada com um programa que usa o GDI+, algumas partes da tela serão desenhadas com a ampliação e outras, não.

Resolução

Para resolver esse problema, obtenha o service pack mais recente para o Windows XP. Para obter informações adicionais, clique no número abaixo para consultar o artigo na Base de Dados de Conhecimento da Microsoft:
322389 Como Obter o Service Pack Mais Recente do Windows XP
Para resolver esse problema, obtenha a atualização mencionada no seguinte artigo da Base de Dados de Conhecimento da Microsoft:
318966 Problemas ao Visualizar, Editar ou Imprimir Algumas Imagens no Windows XP

Para Desenvolvedores de Programas

Se for um desenvolvedor de programas, você deve atualizar o seu programa de forma que ele informe ao GDI+ para usar o GDI, e não DCI, na renderização. Cada instância do GDI+ contém uma janela oculta na parte superior cujo título é "GDI+ Window" e cujo nome de classe é GDI+ Hook Window Class. Quando você instala a atualização descrita no artigo Q318966, a janela oculta do GDI+ aguarda uma mensagem da janela particular chamada de "GDI+ Accessibility". Se receber essa mensagem, a janela oculta do GDI+ pára de usar o DCI na renderização, e começa a usar o GDI. Isso faz com que o GDI+ funcione corretamente com as lentes de aumento.

Quando carregada, uma lente de aumento precisa registrar uma mensagem da janela particular chamada "GDI+ Accessibility". Como o GDI+ registra uma mensagem particular com o mesmo nome, a lente de aumento pode se comunicar com o GDI+ usando essa mensagem. Assim, a lente deve procurar todas as janelas existentes na parte superior. Se encontrar alguma que tenha o nome "GDI+ Window" e cujo nome de classe seja GDI+ Hook Window Class, a lente deve enviar a mensagem "GDI+ Accessibility" para essas janelas. Isso faz com que os programas CDI+ já existentes ampliem corretamente.

A lente de aumento também deve procurar novos programas GDI+ carregados após a sua inicialização. A lente pode fazer isso definindo uma função de retorno de chamada usandoSetWinEventHook, chamada sempre que uma nova janela é criada. Se uma nova janela for criada com o título e o nome de classe corretos, a lente de aumento deve enviar a mensagem "GDI+ Accessibility" para ela.

Lembre-se de que após começar a usar o GDI, em vez do DCI, na renderização, uma instância particular do GDI+ não pode voltar a usar o DCI ? a menos que o programa seja fechado e reiniciado. O GDI+ renderiza mais lentamente ao usar o GDI do que usando o DCI. Se não precisar mais de uma lente com GDI+ e quiser aumentar o desempenho da renderização, o usuário pode reiniciar o programa GDI+.

Situação

A Microsoft informa que este problema pode ocorre em seu(s) produto(s) listado(s) na secção "Aplica-se" deste artigo. Esse problema foi corrigido primeiro no Windows XP Service Pack 1.

Mais Informações

O seguinte programa de exemplo mostra como usar os novos recursos do GDI+ em seu programa. Inclua os arquivos Gdipacs.c e Gdipacs.h em seu projeto. Você deve chamar GDIPlusDCIOff_Init quando o seu programa for iniciado. Isso faz com que todos os programas GDI+ existentes parem de renderizar usando o DCI, ao mesmo tempo em que os novos programas carregados também não usam o DCI para renderizar. Você deve chamar GDIPlusDCIOff_Uninit quando o seu programa for iniciado. Os programas GDI+ já existentes não podem voltar a usar o DCI, embora os novos programas GDI+ possam usá-lo normalmente.

O arquivo Testmain.c demonstra essa funcionalidade. Compile e execute o arquivo para testar a mensagem "GDI+ Accessibility" com os seus programas GDI+.

Código de Exemplo

A Microsoft fornece exemplos de programação apenas para ilustração, sem garantia explícita ou implícita, incluindo, mas sem limitar a, as garantias de comercialização e/ou adequação para uma finalidade em especial. Este artigo pressupõe que você conhece a linguagem de programação que está sendo demonstrada e também as ferramentas usadas para criar e depurar procedimentos. Os profissionais de suporte da Microsoft podem ajudar a explicar a funcionalidade de um procedimento, mas eles não modificarão esses exemplos para fornecer funcionalidades adicionais ou construir procedimentos para atender às suas necessidades. Se a sua experiência com programação for limitada, entre em contato com um Parceiro Certificado Microsoft ou com a linha paga de consultas da Microsoft no número (800) 936-5200. Para obter informações adicionais sobre Parceiros Certificados da Microsoft, favor visitar o seguinte site da Microsoft na Web:
http://www.microsoft.com/partner/referral/
Para obter informações adicionais sobre as opções de suporte disponíveis e sobre como entrar em contato com a Microsoft, visite o seguinte site da Microsoft na Web:
http://support.microsoft.com/default.aspx?scid=fh;PT-BR;CNTACTMS
/*********************** 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;
}
				

Propriedades

ID do artigo: 319261 - Última revisão: quinta-feira, 30 de outubro de 2003 - Revisão: 3.2
A informação contida neste artigo aplica-se a:
  • Microsoft .NET Framework 1.0 nas seguintes plataformas
    • Microsoft Windows XP Professional
  • Microsoft GDI+ 1.0 nas seguintes plataformas
    • Microsoft Windows XP Professional
  • Microsoft Office XP Standard Edition nas seguintes plataformas
    • Microsoft Windows XP Professional
  • Microsoft Visio 2002 Professional Edition nas seguintes plataformas
    • Microsoft Windows XP Professional
  • Microsoft Visio 2002 Standard Edition nas seguintes plataformas
    • Microsoft Windows XP Professional
Palavras-chave: 
kbbug kbfix kbshell kbwinxpsp1fix KB319261

Submeter comentários

 

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