Τα γραφικά που αποδίδονται από το GDI+ δεν είναι δυνατό να μεγεθυνθούν από τους μεγεθυντικούς φακούς της οθόνης

Μεταφράσεις άρθρων Μεταφράσεις άρθρων
Αναγν. άρθρου: 319261 - Δείτε τα προϊόντα στα οποία αναφέρεται το συγκεκριμένο άρθρο.
Ανάπτυξη όλων | Σύμπτυξη όλων

Σε αυτήν τη σελίδα

Συμπτώματα

Τα γραφικά που αποδίδονται από το GDI+ δεν είναι δυνατό να μεγεθυνθούν από τους μεγεθυντικούς φακούς της οθόνης. Αυτό το ζήτημα αφορά όλα τα προγράμματα που χρησιμοποιούν GDI+, συμπεριλαμβανομένων των Microsoft Office XP, Microsoft Visio 2002, Microsoft .NET Framework, καθώς και το κέλυφος των Windows.

Αιτία

Το GDI+ χρησιμοποιεί ένα μηχανισμό που ονομάζεται DCI για απόδοση απευθείας στο buffer πρώτου πλάνου. Το GDI+ δεν δημιουργεί κλήσεις GDI DDI κατά την απόδοση με αυτόν τον τρόπο. Ωστόσο, η λειτουργία των μεγεθυντικών φακών της οθόνης προϋποθέτει απόδοση μόνο μέσω GDI. Οι μεγεθυντικοί φακοί της οθόνης δεσμεύουν τις κλήσεις GDI DDI, καταγράφουν όλα τα στοιχεία της απόδοσης σε ένα bitmap εκτός οθόνης και εμφανίζουν σε μεγέθυνση στην οθόνη ένα τμήμα αυτού του bitmap.

Εάν ένας μεγεθυντικός φακός οθόνης εκτελείται σε ένα πρόγραμμα που χρησιμοποιεί GDI+, ορισμένα τμήματα της οθόνης εμφανίζονται σε μεγέθυνση και άλλα όχι.

Προτεινόμενη αντιμετώπιση

Για να επιλύσετε αυτό το ζήτημα, αποκτήστε το τελευταίο Service Pack για τα Windows XP. Για περισσότερες πληροφορίες, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft (Knowledge Base):
322389 Τρόπος λήψης του τελευταίου Service Pack των Windows XP
Για να επιλύσετε αυτό το ζήτημα, μπορείτε να αποκτήσετε την ενημερωμένη έκδοση που αναφέρεται στο ακόλουθο άρθρο της Γνωσιακής Βάσης της Microsoft (Knowledge Base):
318966 Ζητήματα κατά την προβολή, την επεξεργασία ή την εκτύπωση ορισμένων εικόνων στα Windows XP

Για προγραμματιστές

Εάν είστε προγραμματιστές, πρέπει να ενημερώσετε το πρόγραμμά σας, ώστε να δίνει εντολή στο GDI+ να χρησιμοποιεί GDI αντί για DCI για την απόδοση. Κάθε εμφάνιση GDI+ περιλαμβάνει ένα κρυφό παράθυρο ανώτατου επιπέδου με τίτλο "GDI+ Window" και όνομα κλάσης GDI+ Hook Window Class. Μετά την εγκατάσταση της ενημερωμένης έκδοσης που περιγράφεται στο άρθρο 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+ είναι μικρότερη όταν χρησιμοποιείται το GDI αντί για το DCI. Εάν ο χρήστης δεν χρειάζεται πια μεγεθυντικό φακό με GDI+ και θέλει να βελτιωθεί η απόδοση των γραφικών, μπορεί να κάνει επανεκκίνηση του προγράμματος GDI+.

Κατάσταση

Η Microsoft έχει επιβεβαιώσει ότι πρόκειται για ένα θέμα το οποίο παρουσιάζεται στα προϊόντα της που αναφέρονται στην αρχή αυτού του άρθρου. Το ζήτημα αυτό διορθώθηκε πρώτη φορά στο Service Pack 1 των Windows XP.

Περισσότερες πληροφορίες

Στο παράδειγμα που ακολουθεί υποδεικνύεται ο τρόπος χρήσης της νέας λειτουργίας GDI+ σε ένα πρόγραμμα. Συμπεριλάβετε τα αρχεία Gdipacs.c και Gdipacs.h στο έργο σας. Κατά την έναρξη του προγράμματος απαιτείται κλήση του GDIPlusDCIOff_Init. Με αυτήν την ενέργεια όλα τα υπάρχοντα προγράμματα GDI+ παύουν να χρησιμοποιούν DCI για την απόδοση και εξασφαλίζεται ότι όλα τα νέα προγράμματα GDI+ που φορτώνονται δεν θα χρησιμοποιήσουν DCI. Κατά την έξοδο από το πρόγραμμα απαιτείται κλήση του GDIPlusDCIOff_Uninit. Δεν είναι δυνατή η επαναφορά στη χρήση του DCI των προγραμμάτων GDI+ που εκτελούνται, αλλά τα νέα προγράμματα GDI+ θα χρησιμοποιήσουν DCI, όπως γίνεται κανονικά.

Το αρχείο Testmain.c παρουσιάζει αυτήν τη λειτουργία. Μεταγλωττίστε και εκτελέστε το αρχείο για να ελέγξετε το μήνυμα "GDI+ Accessibility" στα προγράμματα GDI+ που χρησιμοποιείτε.

Δείγμα κώδικα

Η Microsoft παρέχει παραδείγματα προγραμματισμού μόνο για επεξήγηση, χωρίς να παρέχει καμία εγγύηση, είτε σιωπηρή είτε ρητή, περιλαμβανομένων, ενδεικτικά, των σιωπηρών εγγυήσεων εμπορευσιμότητας ή/και καταλληλότητας για συγκεκριμένο σκοπό. Αυτό το άρθρο προϋποθέτει ότι είστε εξοικειωμένοι με τη γλώσσα προγραμματισμού που παρουσιάζεται, καθώς και με τα εργαλεία που χρησιμοποιούνται για τη δημιουργία και τον εντοπισμό σφαλμάτων διαδικασιών. Οι μηχανικοί υποστήριξης της Microsoft μπορούν να σας εξηγήσουν τη λειτουργικότητα μιας συγκεκριμένης διαδικασίας, αλλά δεν θα τροποποιήσουν αυτά τα παραδείγματα, για να παράσχουν πρόσθετες λειτουργίες, ούτε θα δημιουργήσουν διαδικασίες, για να καλύψουν τις συγκεκριμένες ανάγκες σας. Εάν δεν έχετε μεγάλη εμπειρία προγραμματισμού, ίσως χρειαστεί να επικοινωνήσετε με κάποιον πιστοποιημένο συνεργάτη της Microsoft (Microsoft Certified Partner) ή με τη γραμμή παροχής συμβουλών επί πληρωμή της Microsoft στο τηλέφωνο (800) 936-5200. Για περισσότερες πληροφορίες σχετικά με τους πιστοποιημένους συνεργάτες της Microsoft (Microsoft Certified Partners), επισκεφθείτε την ακόλουθη τοποθεσία της Microsoft στο Web (στα αγγλικά):
https://partner.microsoft.com/global/30000104
Για περισσότερες πληροφορίες σχετικά με τις επιλογές υποστήριξης που είναι διαθέσιμες και τον τρόπο επικοινωνίας με τη Microsoft, επισκεφθείτε την ακόλουθη τοποθεσία της Microsoft στο Web:
http://support.microsoft.com/default.aspx?scid=fh;EL;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;
}
				

Ιδιότητες

Αναγν. άρθρου: 319261 - Τελευταία αναθεώρηση: Παρασκευή, 1 Ιουνίου 2007 - Αναθεώρηση: 4.5
Οι πληροφορίες σε αυτό το άρθρο ισχύουν για:
  • Microsoft .NET Framework 1.0 στις ακόλουθες πλατφόρμες
    • Microsoft Windows XP Professional
  • Microsoft GDI+ 1.0 στις ακόλουθες πλατφόρμες
    • Microsoft Windows XP Professional
  • Microsoft Office XP Standard Edition στις ακόλουθες πλατφόρμες
    • Microsoft Windows XP Professional
  • Microsoft Visio 2002 Professional Edition στις ακόλουθες πλατφόρμες
    • Microsoft Windows XP Professional
  • Microsoft Visio 2002 Standard Edition στις ακόλουθες πλατφόρμες
    • Microsoft Windows XP Professional
Λέξεις-κλειδιά: 
kbbug kbfix kbshell kbwinxpsp1fix KB319261

Αποστολή σχολίων

 

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