Delen via


TN003: Toewijzing van Windows-handles aan objecten

Opmerking

De Microsoft Foundation Classes-bibliotheek (MFC) wordt nog steeds ondersteund. We voegen echter geen functies meer toe of werken de documentatie bij.

In deze opmerking worden de MFC-routines beschreven die ondersteuning bieden voor het toewijzen van Windows-objectgrepen aan C++-objecten.

Het probleem

Windows-objecten worden meestal vertegenwoordigd door verschillende HANDLE-objecten De MFC-klassen verpakken Windows-objectgrepen met C++-objecten. Met de handle wrapping-functies van de MFC-klassebibliotheek kunt u het C++-object vinden dat het Windows-object verpakt dat een bepaalde ingang heeft. Soms heeft een object echter geen C++ wrapper-object en op dit moment maakt het systeem een tijdelijk object om te fungeren als de C++-wrapper.

De Windows-objecten die gebruikmaken van handle maps zijn als volgt:

  • HWND (CWnd - en CWnd-afgeleide klassen)

  • HDC -klassen (CDC en CDC-afgeleide klassen)

  • HMENU (CMenu)

  • HPEN (CGdiObject)

  • HBRUSH (CGdiObject)

  • HFONT (CGdiObject)

  • HBITMAP (CGdiObject)

  • HPALETTE (CGdiObject)

  • HRGN (CGdiObject)

  • HIMAGELIST (CImageList)

  • SOCKET (CSocket)

Als u een handle naar een van deze objecten hebt, kunt u het MFC-object vinden dat de handle omhult door de statische methode FromHandle aan te roepen. Als u bijvoorbeeld een HWND met de naam hWnd hebt, retourneert de volgende regel een aanwijzer naar de CWnd die hWnd omhult:

CWnd::FromHandle(hWnd)

Als hWnd geen specifiek wrapper-object heeft, wordt er een tijdelijk CWnd object gemaakt om hWnd te verpakken. Hierdoor is het mogelijk om een geldig C++-object te verkrijgen vanaf elke ingang.

Nadat u een wrapper-object hebt, kunt u de handle ophalen uit een openbare lidvariabele van de wrapperklasse. In het geval van een CWnd, m_hWnd bevat de HWND voor dat object.

Handles koppelen aan MFC-objecten

Gezien een zojuist gemaakt handle-wrapper-object en een ingang aan een Windows-object, kunt u de twee koppelen door de Attach functie aan te roepen zoals in dit voorbeeld:

CWnd myWnd;
myWnd.Attach(hWnd);

Dit maakt een vermelding in de permanente kaart die myWnd en hWnd koppelt. Aanroepen van CWnd::FromHandle(hWnd) retourneert nu een pointer naar myWnd. Wanneer myWnd wordt verwijderd, zal de destructor automatisch hWnd vernietigen door de Windows DestroyWindow-functie aan te roepen. Als dit niet gewenst is, moet hWnd worden losgekoppeld van myWnd voordat myWnd wordt vernietigd (normaal gesproken bij het verlaten van het bereik waarop myWnd is gedefinieerd). De Detach methode doet dit.

myWnd.Detach();

Meer informatie over tijdelijke objecten

Tijdelijke objecten worden gemaakt wanneer FromHandle een handle krijgt die nog geen wrapper-object heeft. Deze tijdelijke objecten worden losgekoppeld van hun handle en verwijderd door deze DeleteTempMap functies. Standaard roept CWinThread::OnIdle automatisch DeleteTempMap aan voor elke klasse die tijdelijke handle maps ondersteunt. Dit betekent dat u niet kunt aannemen dat een aanwijzer naar een tijdelijk object geldig is voorbij het punt van uitgang van de functie waar de aanwijzer is verkregen.

Wrapper-objecten en meerdere threads

Zowel tijdelijke als permanente objecten worden per thread onderhouden. De ene thread heeft dus geen toegang tot de C++-wrapperobjecten van een andere thread, ongeacht of deze tijdelijk of permanent is.

Als u deze objecten van de ene thread naar de andere wilt doorgeven, verzendt u ze altijd als hun eigen HANDLE type. Het doorgeven van een C++-wrapperobject van de ene thread naar de andere leidt vaak tot onverwachte resultaten.

Zie ook

Technische notities per nummer
Technische Aantekeningen Per Categorie