Delen via


TN014: Aangepaste besturingselementen

Deze nota beschrijft de MFC-ondersteuning voor aangepaste en zelfgetekende besturingselementen. Het beschrijft ook dynamische subklassen en beschrijft de relatie tussen CWnd-objecten en HWNDs.

In de MFC-voorbeeldtoepassing CTRLTEST ziet u hoe u veel aangepaste besturingselementen kunt gebruiken. Zie de broncode voor het MFC-voorbeeld CtrlTEST en online help.

Owner-Draw Bedieningselementen/menus

Windows biedt ondersteuning voor eigenaargetekende besturingselementen en menu's door het gebruik van Windows-berichten. Het bovenliggende venster van een besturingselement of menu ontvangt deze berichten en roept functies aan als reactie. U kunt deze functies overschrijven om het visuele uiterlijk en gedrag van uw owner-draw control of menu aan te passen.

MFC biedt rechtstreeks ondersteuning voor owner-draw met de volgende functies:

U kunt deze functies in uw CWnd afgeleide klasse overschrijven om aangepast tekengedrag te implementeren.

Deze aanpak leidt niet tot herbruikbare code. Als u twee vergelijkbare besturingselementen in twee verschillende CWnd klassen hebt, moet u het aangepaste besturingsgedrag op twee locaties implementeren. De door MFC ondersteunde zelftekeningscontrolearchitectuur lost dit probleem op.

Self-Draw Besturingselementen en menu's

MFC biedt een standaardimplementatie (in de CWnd en CMenu klasse) voor de standaard eigenaar-getekende berichten. Met deze standaardimplementatie worden de Owner-Draw parameters gedecodeerd en worden de Owner-Draw berichten gedistribueerd naar de controls of menu's. Dit wordt zelf tekenen genoemd omdat de tekencode zich in de klasse van het besturingselement of menu bevindt, niet in het venster eigenaar.

Met behulp van zelftekeningsbesturingselementen kunt u herbruikbare besturingsklassen bouwen die gebruikmaken van de semantiek van owner-draw om het besturingselement weer te geven. De code voor het tekenen van het besturingselement bevindt zich in de klasse van het besturingselement, niet in de bovenliggende klasse. Dit is een objectgeoriënteerde benadering voor het programmeren van aangepaste besturingselementen. Voeg de volgende lijst met functies toe aan uw zelftekeningklassen:

  • Voor zelftekenknoppen:

    CButton::DrawItem(LPDRAWITEMSTRUCT);
    // insert code to draw this button
    
  • Voor zelftekenmenu's:

    CMenu::MeasureItem(LPMEASUREITEMSTRUCT);
    // insert code to measure the size of an item in this menu
    CMenu::DrawItem(LPDRAWITEMSTRUCT);
    // insert code to draw an item in this menu
    
  • Voor zelftekenende keuzelijsten:

    CListBox::MeasureItem(LPMEASUREITEMSTRUCT);
    // insert code to measure the size of an item in this list box
    CListBox::DrawItem(LPDRAWITEMSTRUCT);
    // insert code to draw an item in this list box
    
    CListBox::CompareItem(LPCOMPAREITEMSTRUCT);
    // insert code to compare two items in this list box if LBS_SORT
    CListBox::DeleteItem(LPDELETEITEMSTRUCT);
    // insert code to delete an item from this list box
    
  • Voor zelfgemaakte keuzelijsten:

    CComboBox::MeasureItem(LPMEASUREITEMSTRUCT);
    // insert code to measure the size of an item in this combo box
    CComboBox::DrawItem(LPDRAWITEMSTRUCT);
    // insert code to draw an item in this combo box
    
    CComboBox::CompareItem(LPCOMPAREITEMSTRUCT);
    // insert code to compare two items in this combo box if CBS_SORT
    CComboBox::DeleteItem(LPDELETEITEMSTRUCT);
    // insert code to delete an item from this combo box
    

Zie de MFC-documentatie voor DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT en DELETEITEMSTRUCT voor meer informatie over de owner-draw structuren. Raadpleeg respectievelijk CWnd::OnDrawItem, CWnd::OnMeasureItem, CWnd::OnCompareItem, en CWnd::OnDeleteItem.

Zelftekeningsbesturingselementen en menu's gebruiken

Voor zelftekenmenu's moet u zowel de OnMeasureItem-methode als de OnDrawItem-methode overschrijven.

Voor zelftekenende keuzelijsten en keuzelijsten met invoervakken moet u overschrijven OnMeasureItem en OnDrawItem. U moet de stijl LBS_OWNERDRAWVARIABLE opgeven voor keuzelijsten of de stijl CBS_OWNERDRAWVARIABLE voor combovakken in de dialoogvenstersjabloon. De stijl OWNERDRAWFIXED werkt niet met zelftekeningitems omdat de vaste itemhoogte wordt bepaald voordat zelftekeningsbesturingselementen aan de keuzelijst worden gekoppeld. (U kunt de methoden CListBox::SetItemHeight en CComboBox::SetItemHeight gebruiken om deze beperking te overwinnen.)

Als u overschakelt naar de OWNERDRAWVARIABLE-stijl, zal het systeem automatisch de NOINTEGRALHEIGHT-stijl toepassen op het bedieningspaneel. Omdat het besturingselement geen integrale hoogte kan berekenen met items met variabele grootte, wordt de standaardstijl van INTEGRALHEIGHT genegeerd en is het besturingselement altijd NOINTEGRALHEIGHT. Als uw items een vaste hoogte hebben, kunt u voorkomen dat gedeeltelijke items worden getekend door de grootte van het besturingselement op te geven als een vermenigvuldiger met gehele getallen van de itemgrootte.

Voor zelftekenende lijstvakken en combinatielijsten met de stijl LBS_SORT of CBS_SORT moet u de OnCompareItem methode overschrijven.

Voor zelf-tekenende keuzelijsten en comboboxen wordt OnDeleteItem meestal niet overschreven. U kunt overschrijven OnDeleteItem als u een speciale verwerking wilt uitvoeren. Een geval waarin dit van toepassing is, is wanneer extra geheugen of andere bronnen worden opgeslagen voor elke keuzelijst of combobox-item.

Voorbeelden van Self-Drawing besturingselementen en menu's

Het algemene MFC-voorbeeld CTRLTEST bevat voorbeelden van een zelfgetekend menu en een zelfgetekende keuzelijst.

Het meest typische voorbeeld van een zelftekeningknop is een bitmapknop. Een bitmapknop is een knop met één, twee of drie bitmapafbeeldingen voor de verschillende statussen. Een voorbeeld hiervan is in de MFC-klasse CBitmapButton.

Dynamische subklassen

Af en toe wilt u de functionaliteit wijzigen van een object dat al bestaat. In de vorige voorbeelden moest u de bedieningselementen aanpassen voordat ze werden aangemaakt. Met dynamische subklassen kunt u een component aanpassen dat al eerder is aangemaakt.

Subklassen is de Windows-term voor het vervangen van de WndProc van een venster door een aangepaste WndProc en het aanroepen van de oude WndProc voor standaardfunctionaliteit.

Dit moet niet worden verward met C++-klasse-afleiding. Ter verduidelijking zijn de C++-termen basisklasse en afgeleide klasse vergelijkbaar met superklasse en subklasse in het Windows-objectmodel. C++ afleiding met MFC- en Windows-subklassen zijn functioneel vergelijkbaar, behalve C++ biedt geen ondersteuning voor dynamische subklassen.

De CWnd klasse biedt de verbinding tussen een C++-object (afgeleid van CWnd) en een Windows-vensterobject (ook wel bekend als een HWND).

Er zijn drie veelvoorkomende manieren waarop deze zijn gerelateerd:

  • CWnd maakt de HWND. U kunt het gedrag in een afgeleide klasse wijzigen door een klasse te maken die is afgeleid van CWnd. De HWND wordt gemaakt wanneer uw toepassing CWnd::Create aanroept.

  • De toepassing koppelt een CWnd aan een bestaande HWND. Het gedrag van het bestaande venster wordt niet gewijzigd. Dit is een geval van delegatie en wordt mogelijk gemaakt door CWnd::Attach aan te roepen om een bestaand HWND te koppelen aan een CWnd object.

  • CWnd is gekoppeld aan een bestaande HWND en u kunt het gedrag in een afgeleide klasse wijzigen. Dit wordt dynamische subklassen genoemd omdat we het gedrag, en daarom de klasse, van een Windows-object tijdens runtime wijzigen.

U kunt dynamische subklassen bereiken met behulp van de methoden CWnd::SubclassWindow en CWnd::SubclassDlgItem.

Beide routines voegen een CWnd object aan een bestaand HWNDobject toe. SubclassWindow neemt de HWND rechtstreeks. SubclassDlgItem is een helperfunctie die een besturings-id en het oudervenster ontvangt. SubclassDlgItem is ontworpen voor het koppelen van C++-objecten aan dialoogvensterbesturingselementen die zijn gemaakt op basis van een dialoogvenstersjabloon.

Zie het CTRLTEST voorbeeld voor verschillende voorbeelden van het gebruik van SubclassWindow en SubclassDlgItem.

Zie ook

Technische notities per nummer
Technische notities per categorie