Door GDI+ opgebouwde afbeeldingen kunnen niet worden vergroot door vergrootglasfuncties

Vertaalde artikelen Vertaalde artikelen
Artikel ID: 319261 - Bekijk de producten waarop dit artikel van toepassing is.
Dit artikel is eerder gepubliceerd onder NL319261
Alles uitklappen | Alles samenvouwen

Op deze pagina

Symptomen

Door GDI+ opgebouwde afbeeldingen kunnen niet worden vergroot door vergrootglasfuncties. Dit probleem geldt voor alle programma's die gebruikmaken van GDI+, inclusief Microsoft Office XP, Microsoft Visio 2002, Microsoft .NET Framework en de Windows-shell.

Oorzaak

GDI+ gebruikt een mechanisme dat bekendstaat als DCI waarmee afbeeldingen direct in de voorste buffer worden opgebouwd. Hierbij genereert GDI+ geen DDI-aanroepen voor de GDI. Vergrootglasfuncties voor het scherm gaan er echter vanuit dat het opbouwen geheel wordt uitgevoerd door GDI. Vergrootglasfuncties koppelen de DDI-aanroepen voor de GDI, leggen alle opbouwbewerkingen vast in een bitmap buiten het scherm en tekenen een gedeelte van deze bitmap vergroot op het scherm.

Als een vergrootglasfuncties wordt uitgevoerd met een programma dat gebruikmaakt van GDI+, worden sommige delen van het scherm vergroot getekend en sommige delen niet-vergroot.

Oplossing

U kunt dit probleem oplossen door het installeren van de update die in het volgende Microsoft Knowledge Base-artikel wordt vermeld:
318966 Problemen bij het weergeven, bewerken of afdrukken van sommige afbeeldingen in Windows XP

Voor programma-ontwikkelaars

Programma-ontwikkelaars dienen hun programma's zodanig bij te werken dat deze GDI+ opdracht geven om bij het opbouwen gebruik te maken van GDI in plaats van DCI. Elk GDI+-exemplaar bevat een verborgen venster van het bovenste niveau met de titel 'GDI+ Window', waarvan de klassennaam GDI+ Hook Window Class is. Wanneer u de in artikel Q318966 vermelde update installeert, controleert het verborgen GDI+-venster of een bericht van een privé-venster wordt verzonden met de naam 'GDI+ Accessibility'. Als het verborgen GDI+-venster dit bericht ontvangt, wordt het gebruik van DCI voor opbouwen beëindigd en wordt in plaats hiervan GDI gebruikt. Hierdoor werkt GDI+ correct in combinatie met vergrootglasfuncties.

Wanneer een vergrootglasfunctie voor het scherm wordt geladen, moet het een bericht van een privé-venster registreren met de naam 'GDI+ Accessibility'. GDI+ registreert een privé-bericht met dezelfde naam, zodat de vergrootglasfunctie kan communiceren met GDI+ door dit bericht te gebruiken. Vervolgens moet de vergrootglasfunctie alle bestaande vensters van het bovenste niveau controleren. Als de vergrootglasfunctie een venster vindt met de naam 'GDI+ Window' waarvan de klassennaam GDI+ Hook Window Class is, moet de vergrootglasfunctie het bericht 'GDI+ Accessibility' versturen aan deze vensters. Hierdoor werkt de vergrootglasfunctie van alle bestaande GDI+-programma's op de juiste manier.

Tevens moet de vergrootglasfunctie controleren of er geen nieuwe GDI+-programma's worden geladen nadat de functie is gestart. Dit gebeurt door een retouraanroepfunctie (callback) in te stellen en gebruik te maken van SetWinEventHook die wordt aangeroepen telkens wanneer een nieuw venster wordt gemaakt. Als er een nieuw venster wordt gemaakt met de juiste titel en klassennaam, moet de vergrootglasfunctie het bericht 'GDI+ Accessibility' naar dit venster verzenden.

Als een bepaald exemplaar van GDI+ eenmaal GDI is gaan gebruiken in plaats van DCI, is het niet mogelijk om terug te keren naar het gebruik van DCI, tenzij het programma wordt afgesloten en opnieuw wordt gestart. Het opbouwen met GDI verloopt voor GDI+ langzamer dan het opbouwen met DCI. Als de gebruiker geen vergrootglasfunctie meer nodig heeft met GDI+ en het opbouwen wil verbeteren, kan de gebruiker het GDI+-programma opnieuw starten.

Status

Microsoft heeft bevestigd dat dit probleem zich kan voordoen in de Microsoft-producten die worden genoemd in de sectie "De informatie in dit artikel is van toepassing op:" worden vermeld.

Meer informatie

In het volgende voorbeeldprogramma wordt beschreven hoe de nieuwe GDI+-functionaliteit kan worden gebruikt in uw programma. Sluit de bestanden Gdipacs.c en Gdipacs.h in uw project in. Wanneer het programma wordt gestart, moet GDIPlusDCIOff_Init worden aangeroepen. Dit zorgt ervoor dat alle bestaande GDI+-programma's het gebruik van DCI voor het opbouwen beëindigen en dat eventuele nieuwe GDI+-programma's die worden geladen geen gebruikmaken van DCI voor het opbouwen. Wanneer het programma wordt afgesloten, moet GDIPlusDCIOff_Uninit worden aangeroepen. Bestaande GDI+-programma's kunnen niet terug naar het gebruik van DCI, maar nieuwe GDI+-programma's maken normaal gesproken gebruik van DCI.

In het bestand Testmain.c wordt deze functionaliteit beschreven. U kunt het bestand compileren en uitvoeren om het bericht 'GDI+ Accessibility' te testen met uw GDI+-programma's.

Voorbeeldcode

De door Microsoft gebruikte programmeervoorbeelden dienen uitsluitend ter illustratie. Microsoft verleent dan ook geen enkele impliciete of expliciete garantie met betrekking tot deze voorbeelden. Er gelden geen impliciete garanties met betrekking tot verkoopbaarheid en/of geschiktheid voor een bepaald doel, noch enigerlei andere garanties. In dit artikel wordt ervan uitgegaan dat u bekend bent met de programmeertalen VBScript en VBA, alsmede met de hulpprogramma's waarmee procedures worden gemaakt en waarmee fouten in procedures worden opgespoord. U kunt desgewenst contact opnemen met Microsoft Productondersteuning voor uitleg over de functie van een bepaalde procedure. Microsoft Productondersteuning is echter niet bereid de voorbeelden aan te passen om extra functies toe te voegen of om procedures te maken die aan uw specifieke wensen voldoen. Als u nog niet zoveel programmeerervaring hebt, kunt u desgewenst contact opnemen met een Microsoft Certified Partner. Als u meer informatie wilt over Microsoft Certified Partners, bezoekt u het volgende adres op het World Wide Web:
http://www.microsoft.com/partner/referral/
Als u meer informatie wilt over andere ondersteuningsopties van Microsoft, bezoekt u het volgende adres op het World Wide Web:
http://support.microsoft.com/default.aspx?scid=fh;NL;CNTACT
/*********************** 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;
}

Eigenschappen

Artikel ID: 319261 - Laatste beoordeling: maandag 3 november 2003 - Wijziging: 2.1
De informatie in dit artikel is van toepassing op:
  • Microsoft GDI+ 1.0 op de volgende platformen
    • Microsoft Windows XP Professional
  • Microsoft Visio 2000 Professional Edition op de volgende platformen
    • Microsoft Windows XP Professional
  • Microsoft Visio 2000 Standard Edition op de volgende platformen
    • Microsoft Windows XP Professional
Trefwoorden: 
kbbug kbfix kbwinxppresp1fix kbwinxpsp1fix KB319261

Geef ons feedback

 

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