Benutzerdefinierte Steuerelemente

Dieser Abschnitt enthält Informationen zu anwendungsdefinierte oder benutzerdefinierten Steuerelementen.

Die folgenden Themen werden erläutert.

Erstellen von Owner-Drawn-Steuerelementen

Schaltflächen, Menüs, statische Textsteuerelemente, Listenfelder und Kombinationsfelder können mit einem vom Besitzer gezeichneten Stilflag erstellt werden. Wenn ein Steuerelement über den vom Besitzer gezeichneten Stil verfügt, verarbeitet das System die Interaktion des Benutzers mit dem Steuerelement wie üblich. Dabei werden Aufgaben ausgeführt, z. B. die Erkennung, wann ein Benutzer eine Schaltfläche ausgewählt hat, und die Benachrichtigung des Besitzers der Schaltfläche über das Ereignis. Da das Steuerelement jedoch vom Besitzer gezeichnet wird, ist das übergeordnete Fenster des Steuerelements für die visuelle Darstellung des Steuerelements verantwortlich. Das übergeordnete Fenster empfängt immer dann eine Meldung, wenn das Steuerelement gezeichnet werden muss.

Bei Schaltflächen und statischen Textsteuerelementen wirkt sich der vom Besitzer gezeichnete Stil darauf aus, wie das System das gesamte Steuerelement zeichnet. Für Listen- und Kombinationsfelder zeichnet das übergeordnete Fenster die Elemente im Steuerelement, und das Steuerelement zeichnet eine eigene Kontur. Beispielsweise kann eine Anwendung ein Listenfeld so anpassen, dass neben jedem Element in der Liste eine kleine Bitmap angezeigt wird.

Der folgende Beispielcode zeigt, wie Sie ein vom Besitzer gezeichnetes statisches Textsteuerelement erstellen. Angenommen, Unicode ist definiert.

// g_myStatic is a global HWND variable.
g_myStatic = CreateWindowEx(0, L"STATIC", L"Some static text", 
            WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 
            25, 125, 150, 20, hDlg, 0, 0, 0);

Im folgenden Beispiel wird aus der Fensterprozedur für das Dialogfeld, das das im vorherigen Beispiel erstellte Steuerelement enthält, die meldung WM_DRAWITEM behandelt, indem der Text in einer benutzerdefinierten Farbe mit der Standardschriftart angezeigt wird. Beachten Sie, dass Sie BeginPaint und EndPaint nicht aufrufen müssen, wenn Sie WM_DRAWITEM verarbeiten.

case WM_DRAWITEM:
{
    LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)lParam;
    if (pDIS->hwndItem == g_myStatic)
    {
        SetTextColor(pDIS->hDC, RGB(100, 0, 100));
        WCHAR staticText[99];
        int len = SendMessage(myStatic, WM_GETTEXT, 
            ARRAYSIZE(staticText), (LPARAM)staticText);
        TextOut(pDIS->hDC, pDIS->rcItem.left, pDIS->rcItem.top, staticText, len);
    }
    return TRUE;
}

Weitere Informationen zu von Besitzern gezeichneten Steuerelementen finden Sie unter Erstellen eines vom Besitzer gezeichneten Listenfelds und von Besitzern gezeichnete Kombinationsfelder.

Unterklassen der Window-Klasse eines vorhandenen Steuerelements

Das Unterklassen eines vorhandenen Steuerelements ist eine weitere Möglichkeit, ein benutzerdefiniertes Steuerelement zu erstellen. Die Unterklassenprozedur kann das ausgewählte Verhalten des Steuerelements ändern, indem die Meldungen verarbeitet werden, die sich auf das ausgewählte Verhalten auswirken. Alle anderen Nachrichten werden an die ursprüngliche Fensterprozedur für das Steuerelement übergeben. Beispielsweise kann eine Anwendung eine kleine Bitmap neben dem Text in einem schreibgeschützten, einzeiligen Bearbeitungssteuerelement anzeigen, indem sie das Steuerelement unterklassiert und die WM_PAINT Nachricht verarbeitet. Weitere Informationen finden Sie unter Informationen zu Fensterprozeduren und Unterklassensteuerelementen.

Implementieren einer Application-Defined Window-Klasse

Um ein Steuerelement zu erstellen, das nicht explizit auf einem vorhandenen Steuerelement basiert, muss die Anwendung eine Fensterklasse erstellen und registrieren. Der Prozess zum Registrieren einer anwendungsdefinierten Fensterklasse für ein benutzerdefiniertes Steuerelement entspricht dem Registrieren einer Klasse für ein normales Fenster. Um ein benutzerdefiniertes Steuerelement zu erstellen, geben Sie den Namen der Fensterklasse in der CreateWindowEx-Funktion oder in einer Dialogfeldvorlage an. Jede Klasse muss über einen eindeutigen Namen, eine entsprechende Fensterprozedur und andere Informationen verfügen.

Mindestens zeichnet die Fensterprozedur das Steuerelement. Wenn eine Anwendung das -Steuerelement verwendet, um dem Benutzer die Eingabe von Informationen zu ermöglichen, verarbeitet die Fensterprozedur auch Eingabenachrichten von Tastatur und Maus und sendet Benachrichtigungen an das übergeordnete Fenster. Wenn das Steuerelement Steuermeldungen unterstützt, verarbeitet die Fensterprozedur außerdem Nachrichten, die vom übergeordneten Fenster oder anderen Fenstern an das Steuerelement gesendet werden. Beispielsweise verarbeiten Steuerelemente häufig die WM_GETDLGCODE Nachricht, die von Dialogfeldern gesendet wird, um ein Dialogfeld anweisen, Tastatureingaben auf eine bestimmte Weise zu verarbeiten.

Die Fensterprozedur für ein anwendungsdefiniertes Steuerelement sollte jede vordefinierte Steuerelementmeldung in der folgenden Tabelle verarbeiten, wenn sich die Meldung auf den Vorgang des Steuerelements auswirkt.

Nachricht Empfehlung
WM_GETDLGCODE Verarbeiten, wenn das Steuerelement die EINGABETASTE, ESC, TAB oder Pfeiltasten verwendet. Die IsDialogMessage-Funktion sendet diese Nachricht an Steuerelemente in einem Dialogfeld, um zu bestimmen, ob die Schlüssel verarbeitet oder an das Steuerelement übergeben werden sollen.
WM_GETFONT Verarbeiten, wenn die WM_SETFONT Nachricht ebenfalls verarbeitet wird.
WM_GETTEXT Verarbeiten, wenn der Steuerelementtext nicht mit dem von der CreateWindowEx-Funktion angegebenen Titel übereinstimmt.
WM_GETTEXTLENGTH Verarbeiten, wenn der Steuerelementtext nicht mit dem von der CreateWindowEx-Funktion angegebenen Titel übereinstimmt.
WM_KILLFOCUS Verarbeiten, wenn das Steuerelement ein Caret, ein Fokusrechteck oder ein anderes Element anzeigt, um anzugeben, dass es über den Eingabefokus verfügt.
WM_SETFOCUS Verarbeiten, wenn das Steuerelement ein Caret, ein Fokusrechteck oder ein anderes Element anzeigt, um anzugeben, dass es über den Eingabefokus verfügt.
WM_SETTEXT Verarbeiten, wenn der Steuerelementtext nicht mit dem von der CreateWindowEx-Funktion angegebenen Titel übereinstimmt.
WM_SETFONT Prozess, wenn das Steuerelement Text anzeigt. Das System sendet diese Meldung beim Erstellen eines Dialogfelds, das den stil "DS_SETFONT" aufweist.

 

Anwendungsdefinierte Steuerelementmeldungen sind spezifisch für das angegebene Steuerelement und müssen explizit mithilfe einer SendMessage - oder SendDlgItemMessage-Funktion an das Steuerelement gesendet werden. Der numerische Wert für jede Nachricht muss eindeutig sein und darf nicht mit den Werten anderer Fensternachrichten in Konflikt stehen. Um sicherzustellen, dass anwendungsdefinierte Nachrichtenwerte nicht in Konflikt stehen, sollte eine Anwendung jeden Wert erstellen, indem dem WM_USER Wert eine eindeutige Zahl hinzugefügt wird.

Senden von Benachrichtigungen aus einem Steuerelement

Benutzerdefinierte Steuerelemente sind möglicherweise erforderlich, um Benachrichtigungen über Ereignisse an das übergeordnete Fenster zu senden, damit die Hostanwendung auf diese Ereignisse reagieren kann. Beispielsweise kann eine benutzerdefinierte Listenansicht eine Benachrichtigung senden, wenn der Benutzer ein Element auswählt, und eine weitere Benachrichtigung, wenn auf ein Element doppelklicken wird.

Benachrichtigungen werden als WM_COMMAND oder WM_NOTIFY Nachrichten gesendet. WM_NOTIFY Nachrichten enthalten mehr Informationen als WM_COMMAND Nachrichten.

Der Steuerelementbezeichner ist eine eindeutige Nummer, die die Anwendung verwendet, um das Steuerelement zu identifizieren, das die Nachricht sendet. Die Anwendung legt den Bezeichner für ein Steuerelement fest, wenn das Steuerelement erstellt wird. Die Anwendung gibt den Bezeichner entweder im hMenu-Parameter der CreateWindowEx-Funktion oder im Id-Member der DLGITEMTEMPLATEEX-Struktur an.

Da das Steuerelement selbst den Steuerelementbezeichner nicht festgelegt, muss das Steuerelement den Bezeichner abrufen, bevor es Benachrichtigungen senden kann. Ein Steuerelement muss die GetDlgCtrlID-Funktion verwenden, um seinen eigenen Steuerelementbezeichner abzurufen. Obwohl der Steuerelementbezeichner beim Erstellen des Steuerelements als Menühandle angegeben wird, kann die GetMenu-Funktion nicht zum Abrufen des Bezeichners verwendet werden. Alternativ kann ein Steuerelement den Bezeichner aus dem hMenu-Member in der CREATESTRUCT-Struktur abrufen, während die WM_CREATE Nachricht verarbeitet wird.

In den folgenden Beispielen, in denen hwndControl das Handle des Steuerelementfensters ist und CN_VALUECHANGED eine benutzerdefinierte Benachrichtigungsdefinition ist, zeigen die beiden Möglichkeiten zum Senden einer steuerelementspezifischen Benachrichtigung.

 // Send as WM_COMMAND.
SendMessage(GetParent(hwndControl), 
    WM_COMMAND,
    MAKEWPARAM(GetDlgCtrlID(hwndControl), CN_VALUECHANGED),
    (LPARAM)hwndControl);

// Send as WM_NOTIFY.           
NMHDR nmh;
nmh.code = CN_VALUECHANGED;
nmh.idFrom = GetDlgCtrlID(hwndControl);
nmh.hwndFrom = hwndControl;
SendMessage(GetParent(hwndControl), 
    WM_NOTIFY, 
    (WPARAM)hwndControl, 
    (LPARAM)&nmh);

Beachten Sie, dass die NMHDR-Struktur Teil einer größeren steuerelementdefinierte Struktur sein kann, die zusätzliche Informationen enthält. Im Beispiel können die alten und neuen Werte des Steuerelements in dieser Struktur enthalten sein. (Solche erweiterten Strukturen werden mit vielen Standardbenachrichtigungen verwendet. Siehe z . B. LVN_INSERTITEM, die die NMLISTVIEW-Struktur verwendet.)

Zugriff

Alle gängigen Steuerelemente unterstützen Microsoft Active Accessibility (MSAA), die den programmgesteuerten Zugriff durch barrierefreie Anwendungen wie Sprachausgaben ermöglicht. MSAA ermöglicht auch Benutzeroberflächenautomatisierung, eine neuere Technologie, die Interaktion mit Steuerelementen.

Benutzerdefinierte Steuerelemente sollten entweder die IAccessible-Schnittstelle (zur Unterstützung von MSAA) oder die Benutzeroberflächenautomatisierung-Schnittstellen oder beides implementieren. Andernfalls können Produkte mit barrierefreier Technologie nur sehr begrenzte Informationen über das Steuerelementfenster erhalten, haben keinen Zugriff auf die Eigenschaften des Steuerelements und können keine Ereignisse im Steuerelement auslösen.

Weitere Informationen zum Barrierefreimachen Ihres Steuerelements finden Sie unter Windows Automation API.

Konzept

Allgemeine Steuerelementreferenz

Anpassen der Darstellung eines Steuerelements mithilfe von benutzerdefiniertem Zeichnen

Steuern von Nachrichten

Verwenden von visuellen Stilen mit Owner-Drawn-Steuerelementen