Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit onderwerp vindt u een overzicht van hoe u WPF-code (Windows Presentation Foundation) en Win32-code kunt gebruiken. WPF biedt een uitgebreide omgeving voor het maken van toepassingen. Als u echter een aanzienlijke investering in Win32-code hebt, is het mogelijk effectiever om een deel van die code opnieuw te gebruiken.
Basisbeginselen van WPF en Win32 Interoperation
Er zijn twee basistechnieken voor interoperation tussen WPF en Win32-code.
Host WPF-inhoud in een Win32-venster. Met deze techniek kunt u de geavanceerde grafische mogelijkheden van WPF gebruiken binnen het kader van een standaard Win32-venster en -toepassing.
Implementeer een Win32-venster binnen WPF-inhoud. Met deze techniek kunt u een bestaand aangepast Win32-besturingselement gebruiken in de context van andere WPF-inhoud en gegevens doorgeven over de grenzen.
Elk van deze technieken wordt conceptueel geïntroduceerd in dit onderwerp. Zie Walkthrough: WPF-inhoud hosten in Win32 voor een meer codegeoriënteerde illustratie van het hosten van WPF-inhoud in Win32. Zie Walkthrough: Een Win32-besturingselement hosten in WPF voor een meer codegeoriënteerde illustratie van het hosten van Win32 in WPF.
WPF-Interoperation-projects
WPF-API's zijn beheerde code, maar de meeste bestaande Win32-programma's worden geschreven in niet-beheerde C++. U kunt WPF-API's niet aanroepen vanuit een echt onbeheerd programma. Met behulp van de /clr-optie met de Microsoft Visual C++-compiler kunt u echter een gemengd beheerd, onbeheerd programma maken waarin u beheerde en onbeheerde API-aanroepen naadloos kunt combineren.
Een complicatie op projectniveau is dat u geen XAML-bestanden (Extensible Application Markup Language) kunt compileren in een C++-project. Er zijn verschillende projectdivisietechnieken om dit te compenseren.
Maak een C#-DLL die al uw XAML-pagina's bevat als een gecompileerde assembly en laat uw C++-uitvoerbare bestand die DLL als referentie opnemen.
Maak een uitvoerbaar C#-bestand voor de WPF-inhoud en laat deze verwijzen naar een C++ DLL die de Win32-inhoud bevat.
Gebruik Load om XAML tijdens runtime te laden in plaats van uw XAML te compileren.
Gebruik XAML helemaal niet en schrijf al uw WPF in code, bouw de elementstructuur van Applicationop.
Gebruik welke benadering het beste voor u werkt.
Opmerking
Als u C++/CLI nog niet eerder hebt gebruikt, ziet u mogelijk enkele 'nieuwe' trefwoorden, zoals gcnew en nullptr in de voorbeelden van interoperation-code. Deze trefwoorden vervangen de oudere dubbele onderstrepingstekensyntaxis (__gc) en bieden een meer natuurlijke syntaxis voor beheerde code in C++. Zie Component Extensions for Runtime Platformsvoor meer informatie over de door C++/CLI beheerde functies.
Hoe WPF Hwnds gebruikt
Om optimaal gebruik te maken van WPF 'HWND interop', moet u begrijpen hoe WPF HWND's gebruikt. Voor een HWND kunt u WPF-rendering niet combineren met DirectX-rendering of GDI/GDI+ rendering. Dit heeft een aantal gevolgen. In de eerste plaats, om deze renderingmodellen te combineren, moet u een interoperatieoplossing creëren en aangewezen segmenten van interoperabiliteit gebruiken voor elk renderingmodel dat u kiest te gebruiken. Het renderinggedrag creëert ook een beperking voor het 'luchtruim' voor wat uw interoperatieoplossing kan bereiken. Het concept "luchtruim" wordt uitvoeriger uitgelegd in het onderwerp Overzicht van technologieregio's.
Alle WPF-elementen op het scherm worden uiteindelijk ondersteund door een HWND. Wanneer u een WPF-Windowmaakt, maakt WPF een HWND op het hoogste niveau en gebruikt een HwndSource om de Window en de bijbehorende WPF-inhoud in de HWND te plaatsen. De rest van uw WPF-inhoud in de toepassing deelt die enkelvoudige HWND. Een uitzondering hierop zijn menu's, vervolgkeuzelijsten met invoervak en andere pop-ups. Deze elementen maken hun eigen venster op het hoogste niveau. Daarom kan een WPF-menu mogelijk langs de rand van het venster HWND gaan dat het bevat. Wanneer u HwndHost gebruikt om een HWND in WPF te plaatsen, informeert WPF Win32 hoe de nieuwe HWND ten opzichte van de WPF-Window HWND moet worden geplaatst.
Een gerelateerd concept voor HWND is transparantie binnen en tussen elke HWND. Dit wordt ook besproken in het onderwerp Overzicht van technologieregio's.
WPF-inhoud hosten in een Microsoft Win32-venster
De sleutel voor het hosten van een WPF in een Win32-venster is de HwndSource klasse. Deze klasse verpakt de WPF-inhoud in een Win32-venster, zodat de WPF-inhoud kan worden opgenomen in uw gebruikersinterface als een onderliggend venster. De volgende benadering combineert win32 en WPF in één toepassing.
Implementeer uw WPF-inhoud (het hoofdelement van de inhoud) als een beheerde klasse. Normaal gesproken neemt de klasse over van een van de klassen die meerdere onderliggende elementen kunnen bevatten en/of als hoofdelement kunnen worden gebruikt, zoals DockPanel of Page. In de volgende stappen wordt deze klasse aangeduid als de WPF-inhoudsklasse en worden exemplaren van de klasse aangeduid als WPF-inhoudsobjecten.
Implementeer een Windows-toepassing met C++/CLI. Als u begint met een bestaande niet-beheerde C++-toepassing, kunt u deze meestal inschakelen om beheerde code aan te roepen door de projectinstellingen te wijzigen zodat de
/clrcompilervlag wordt opgenomen (het volledige bereik van wat nodig is om ondersteuning te bieden/clrcompilatie wordt niet beschreven in dit onderwerp).Stel het threadingmodel in op Single Threaded Apartment (STA). WPF maakt gebruik van dit threadingmodel.
De WM_CREATE melding in uw vensterprocedure verwerken.
Ga als volgt te werk in de handler (of een functie die door de handler wordt aangeroepen):
Maak een nieuw HwndSource-object met het bovenliggende venster HWND als parameter
parent.Maak een exemplaar van uw WPF-inhoudsklasse.
Wijs een verwijzing naar het WPF-inhoudsobject toe aan de eigenschap HwndSource object RootVisual.
De eigenschap HwndSource object Handle bevat de venstergreep (HWND). Als u een HWND wilt verkrijgen dat u kunt gebruiken in het onbeheerde deel van uw toepassing, cast dan
Handle.ToPointer()naar een HWND.
Implementeer een beheerde klasse die een statisch veld bevat dat een verwijzing naar uw WPF-inhoudsobject bevat. Met deze klasse kunt u een verwijzing krijgen naar het WPF-inhoudsobject vanuit uw Win32-code, maar nog belangrijker is dat het voorkomt dat uw HwndSource onbedoeld door de garbage collector wordt opgehaald.
Ontvang meldingen van het WPF-inhoudsobject door een handler toe te voegen aan een of meer van de WPF-inhoudsobjecten.
Communiceer met het WPF-inhoudsobject met behulp van de verwijzing die u in het statische veld hebt opgeslagen om eigenschappen, aanroepmethoden, enzovoort in te stellen.
Opmerking
U kunt een of alle definitie van de WPF-inhoudsklasse uitvoeren voor Stap One in XAML met behulp van de standaard gedeeltelijke klasse van de inhoudsklasse, als u een afzonderlijke assembly maakt en ernaar verwijst. Hoewel u doorgaans een Application object opneemt als onderdeel van het compileren van de XAML in een assembly, gebruikt u die Application niet als onderdeel van de interoperation, maar gebruikt u slechts een of meer hoofdklassen voor XAML-bestanden waarnaar wordt verwezen door de toepassing en verwijst u naar de gedeeltelijke klassen. De rest van de procedure is in wezen vergelijkbaar met de procedure die hierboven wordt beschreven.
Elk van deze stappen wordt geïllustreerd via code in het onderwerp Walkthrough: WPF-inhoud hosten in Win32.
Een Microsoft Win32-venster hosten in WPF
De sleutel voor het hosten van een Win32-venster binnen andere WPF-inhoud is de HwndHost klasse. Deze klasse verpakt het venster in een WPF-element dat kan worden toegevoegd aan een WPF-elementstructuur. HwndHost ondersteunt ook API's waarmee u taken kunt uitvoeren, zoals het verwerken van berichten voor het gehoste venster. De basisprocedure is:
Maak een elementstructuur voor een WPF-toepassing (kan worden gebruikt via code of markeringen). Zoek een geschikt en toegestaan punt in de elementstructuur waar de HwndHost implementatie als onderliggend element kan worden toegevoegd. In de rest van deze stappen wordt dit element het reserveringselement genoemd.
Afgeleid van HwndHost om een object te maken dat uw Win32-inhoud bevat.
Binnen die hostklasse overschrijft u de HwndHost-methode BuildWindowCore. Retourneer de HWND van het gehoste venster. Mogelijk wilt u de werkelijke besturingselementen verpakken als een onderliggend venster van het geretourneerde venster; Het verpakken van de besturingselementen in een hostvenster biedt een eenvoudige manier voor uw WPF-inhoud om meldingen van de besturingselementen te ontvangen. Deze techniek helpt bij het corrigeren van sommige Win32-problemen met betrekking tot het verwerken van berichten op de gehoste besturingselementgrens.
Overschrijf de HwndHost methoden DestroyWindowCore en WndProc. Het doel hier is om opschoning en verwijdering van verwijzingen naar de gehoste inhoud te verwerken, met name als u verwijzingen naar niet-beheerde objecten hebt gemaakt.
Maak in uw code-behind-bestand een exemplaar van de hostklasse voor besturingselementen en maak dit een onderliggend element van het reserveringselement. Normaal gesproken gebruikt u een gebeurtenis-handler zoals Loadedof gebruikt u de gedeeltelijke klasseconstructor. Maar u kunt de interoperabiliteitsinhoud ook toevoegen via gedrag tijdens runtime.
Geselecteerde vensterberichten verwerken, zoals besturingsmeldingen. Er zijn twee benaderingen. Beide bieden identieke toegang tot de berichtenstroom, dus uw keuze is grotendeels een kwestie van programmeercomfort.
Implementeer berichtverwerking voor alle berichten (niet alleen uitschakelberichten) in uw overschrijving van de HwndHost methode WndProc.
Laat het hostende WPF-element de berichten verwerken door de gebeurtenis MessageHook af te handelen. Deze gebeurtenis wordt gegenereerd voor elk bericht dat naar de hoofdvensterprocedure van het gehoste venster wordt verzonden.
U kunt geen berichten van vensters verwerken die niet worden verwerkt met behulp van WndProc.
Communiceer met het gehoste venster met behulp van platform-aanroep om de onbeheerde
SendMessage-functie aan te roepen.
Met deze stappen maakt u een toepassing die werkt met muisinvoer. U kunt ondersteuning voor tabbladen toevoegen voor uw gehoste venster door de IKeyboardInputSink-interface te implementeren.
Elk van deze stappen wordt geïllustreerd via code in het onderwerp Walkthrough: Hosting a Win32 Control in WPF.
Hwnds binnen WPF
U kunt HwndHost zien als een speciale controle. (Technisch gezien is HwndHost een FrameworkElement afgeleide klasse, niet een Control afgeleide klasse, maar kan het worden beschouwd als een controle voor interoperation.) HwndHost abstracteert de onderliggende Win32-aard van de gehoste inhoud, zodat de rest van WPF de gehoste inhoud beschouwt als een ander besturingselementachtig object, dat invoer moet weergeven en verwerken. HwndHost gedraagt zich over het algemeen net als andere WPF-FrameworkElement, hoewel er enkele belangrijke verschillen zijn rond uitvoer (tekening en graphics) en invoer (muis en toetsenbord) op basis van beperkingen van wat de onderliggende HWND's kunnen ondersteunen.
Belangrijke verschillen in uitvoergedrag
FrameworkElement, de HwndHost basisklasse, heeft nogal wat eigenschappen die wijzigingen in de gebruikersinterface impliceren. Dit zijn eigenschappen zoals FrameworkElement.FlowDirection, die de indeling van elementen binnen dat element als ouder wijzigen. De meeste van deze eigenschappen zijn echter niet toegewezen aan mogelijke Win32-equivalenten, zelfs als dergelijke equivalenten kunnen bestaan. Te veel van deze eigenschappen en hun betekenissen zijn te specifiek voor de renderingtechnologie om praktisch te zijn voor toewijzingen. Het instellen van eigenschappen zoals FlowDirection op HwndHost heeft daarom geen effect.
HwndHost kan niet worden gedraaid, geschaald, scheefgetrokken of anderszins beïnvloed door een transformatie.
HwndHost biedt geen ondersteuning voor de eigenschap Opacity (alfamixing). Als inhoud binnen de HwndHostSystem.Drawing-bewerkingen uitvoert die alfagegevens bevatten, is dat op zichzelf geen schending, maar de HwndHost ondersteunt als geheel alleen Opacity = 1,0 (100%).
HwndHost wordt weergegeven boven op andere WPF-elementen in hetzelfde venster op het hoogste niveau. Een ToolTip of ContextMenu gegenereerd menu is echter een afzonderlijk venster op het hoogste niveau en gedraagt zich dus correct met HwndHost.
HwndHost houdt geen rekening met het afsnijdgebied van zijn bovenliggende UIElement. Dit is mogelijk een probleem als u probeert een HwndHost klasse in een schuifregio of Canvaste plaatsen.
Belangrijke verschillen in invoergedrag
Over het algemeen geldt dat invoerapparaten worden beperkt tot de HwndHost-gehoste Win32-regio, en gaan invoergebeurtenissen direct naar Win32.
Terwijl de muis zich boven HwndHostbevindt, ontvangt uw toepassing geen WPF-muisgebeurtenissen en wordt de waarde van de WPF-eigenschap IsMouseOver
false.Hoewel de HwndHost de toetsenbordfocus heeft, ontvangt uw toepassing geen WPF-toetsenbordgebeurtenissen en wordt de waarde van de WPF-eigenschap IsKeyboardFocusWithin
false.Wanneer de focus zich binnen de HwndHost bevindt en verschuift naar een ander besturingselement binnen de HwndHost, ontvangt uw toepassing niet de WPF-gebeurtenissen GotFocus of LostFocus.
Gerelateerde styluseigenschappen en -gebeurtenissen zijn analoog en rapporteren geen informatie terwijl de stylus boven HwndHostis.
Tabbing, Geheugensteuntjes en Sneltoetsen
Met de IKeyboardInputSink- en IKeyboardInputSite-interfaces kunt u een naadloze toetsenbordervaring maken voor gemengde WPF- en Win32-toepassingen:
Tabbing tussen Win32- en WPF-onderdelen
Mnemonics en accelerators die zowel werken wanneer de focus zich binnen een Win32-onderdeel bevindt als binnen een WPF-component.
De HwndHost- en HwndSource klassen bieden beide implementaties van IKeyboardInputSink, maar ze verwerken mogelijk niet alle invoerberichten die u wilt voor geavanceerdere scenario's. Overschrijf de juiste methoden om het gewenste toetsenbordgedrag te verkrijgen.
De interfaces bieden alleen ondersteuning voor wat er gebeurt tijdens de overgang tussen de WPF- en Win32-regio's. Binnen de Win32-regio wordt tabbladgedrag volledig beheerd door de Win32 geïmplementeerde logica voor tabbladen, indien van toepassing.
Zie ook
.NET Desktop feedback