CTRLTEST-Beispiel: Implementiert benutzerdefinierte Steuerelemente

Aktualisiert: November 2007

Anhand des CTRLTEST-Beispiels werden verschiedene Techniken zum Implementieren und Verwenden benutzerdefinierter Steuerelemente gezeigt:

  • Implementieren von CParsedEdit, eines speziellen Edit-Steuerelements, dessen Funktionalität von seiner Klassenbibliothek für Steuerelemente abgeleitet ist, sowie drei Methoden zur Verwendung benutzerdefinierter Steuerelemente.

  • Verwenden des Drehfeld-Steuerelements. Das Drehfeld-Steuerelement verfügt über kleine Schaltflächen mit Aufwärts- und Abwärtspfeilen zum Erhöhen oder Verringern eines Werts.

  • Implementieren von Bitmapschaltflächen für benutzerdefinierte Menübefehle unter Verwendung von CBitmapButton.

  • Zeichnen von Menüs und Listenfeldern im Besitzer (übergeordneten Fenster). Zugehörige Steuerelementklassen, die von der CMenu- oder der CListBox-Klasse abgeleitet sind, stellen dieses Feature nach einem objektorientierten Ansatz zur Verfügung.

  • Verwenden von Ressourcendateien, die nicht mit Microsoft Visual C++-Ressourcen-Editoren verwaltet werden können. Dies veranschaulicht die Vor- und Nachteile der Verwendung von RC2-Dateien in einem Dialogfeld mit benutzerdefinierten Steuerelementen, dessen Formate durch Konstanten in einer Headerdatei definiert sind.

Sämtliche Abbildungen in CTRLTEST werden durch Menübefehle aufgerufen.

Sicherheitshinweis:

Dieser Beispielcode dient dazu, ein Konzept zu veranschaulichen. Er sollte nicht für Anwendungen oder Websites verwendet werden, da dieser Code unter Umständen nicht die sicherste Codierungstechnik darstellt. Microsoft übernimmt keine Haftung für beiläufig entstandene Schäden oder Folgeschäden, falls der Beispielcode nicht bestimmungsgemäß verwendet wird.

So rufen Sie Beispiele und Anweisungen für ihre Installation ab

  • Klicken Sie in Visual Studio im Menü Hilfe auf Beispiele.

    Weitere Informationen finden Sie unter Suchen von Beispieldateien.

  • Die neueste Version und vollständige Liste mit Beispielen ist online unter Visual Studio 2008 Samples verfügbar.

  • Sie können auch Beispiele auf der Festplatte des Computers suchen. Standardmäßig werden Beispiele und eine Infodatei in einen Ordner unter \Programme\Visual Studio 9.0\Samples\ kopiert. Für Express Editions von Visual Studio sind alle Beispiele online verfügbar.

Erstellen und Ausführen des Beispiels

So erstellen Sie das CTRLTEST-Beispiel und führen es aus

  1. Öffnen Sie die Projektmappe Ctrltest.sln.

  2. Klicken Sie im Menü Erstellen auf Erstellen.

  3. Klicken Sie im Menü Debuggen auf Starten ohne Debuggen.

Beispiel: Implementierung und Verwendung von benutzerdefinierten Steuerelementen

Obwohl es möglich ist, benutzerdefinierte Steuerelemente durch Ableiten von der CWnd-Klasse zu implementieren, ist es viel einfacher, die Funktionalität eines Windows-Standardsteuerelements zu übernehmen und von dessen Steuerelementklasse in der Bibliothek abzuleiten. CTRLTEST geht dementsprechend vor, um ein spezialisiertes Edit-Steuerelement (CParsedEdit) zu implementieren. Dieses Edit-Steuerelement akzeptiert bei der Benutzereingabe nur bestimmte Zeichensätze: Numerische, alphabetische oder Nichtsteuerzeichen. CParsedEdit wird von CEdit abgeleitet. Mit dem OnChar-Meldungshandler werden die Zeichen entsprechend gefiltert.

Die Implementierung der Befehle im Menü Simple veranschaulicht drei Methoden für die Verwendung eines benutzerdefinierten Steuerelements. Diese Methoden unterscheiden sich darin, wie die Anwendung Instanzen des Steuerelements im Dialogfeld mit der CParsedEdit-Klasse verknüpft. Jeder Befehl im Menü Simple zeigt ein Dialogfeld mit den vier Instanzen des CParsedEdit-Steuerelements an. Die im Dialogfeld eingegebenen Daten werden als TRACE-Ausgabe an den Debugport gesendet. Die drei Befehle im Menü Simple lauten:

Testen C++-abgeleiteter Klassen

Die CParsedEdit-Steuerelemente sind Datenmember der Dialogfeldklasse. Die Steuerelemente werden durch Aufruf von CParsedEdit::CreateSet explizit in der OnInitDialog-Funktion des Dialogfelds erstellt. Siehe auch Dertest.cpp.

Testen einer registrierten "WNDCLASS"

CParsedEdit-Steuerelemente werden in einer Dialogfeldvorlagenressource (IDD_WNDCLASS_EDIT) als benutzerdefinierte Steuerelemente angelegt, deren WNDCLASS als "paredit" gekennzeichnet ist. Hierbei ist es hilfreich, die Eigenschaften dieser benutzerdefinierten Steuerelemente unter Verwendung des Visual C++-Dialog-Editors zu überprüfen.

  • Caption blank. Dies ist der Startwert, der im CParsedEdit-Steuerelement angezeigt wird.

  • Class:paredit. Dies ist der Name der WNDCLASS, die von CParsedEdit::RegisterControlClass vor dem Aufrufen des Dialogfelds in der Datei PAREDIT2.CPP registriert wird.

  • Visible:checked. Das Steuerelement ist sichtbar.

  • Tabstop:checked. Der Benutzer kann mit der TAB-TASTE zu diesem Steuerelement springen.

  • Style:0x5081002, 0x5081001, 0x5081003, 0x5081ffff für die vier analysierten Edit-Steuerelemente. Das Format 0x500000 gilt für WS_CHILD und WS_VISIBLE, während 0x1000 für WS_TABSTOP gilt. Alle benutzerdefinierten Steuerelemente weisen das Format WS_CHILD auf. Die Formate WS_VISIBLE und WS_TABSTOP werden automatisch vom Dialog-Editor festgelegt, wenn Sie die Visible- und Tabstop-Formate aktivieren. 0x80000 gilt für WS_BORDER. Da die Eigenschaftenseite des Dialog-Editors für ein benutzerdefiniertes Steuerelement alle Fensterstile bereitstellt (beispielsweise WS_BORDER), müssen Sie die Konstante unter \Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\WINUSER.H suchen. Die Stile 0x0001, 0x0002, 0x0004 und 0x0ffff werden in PAREDIT.H als PES_NUMBERS, PES_LETTERS, PER_OTHERCHARS und PES_ALL definiert.

  • Die hexadezimalen Formate in der Eigenschaftenseite des benutzerdefinierten Steuerelements sind nicht selbstdokumentierend. Wenn Sie die Verwendung von symbolischen Formaten bevorzugen, beispielsweise PES_NUMBERS und PES_LETTERS, können Sie alternativ eine separate Ressourcendatei von Hand bearbeiten, z. B. RES\Ctrltest.rc2. Diese Datei muss zur Kompilierzeit im Ressourcencompiler enthalten sein, kann aber nicht von Visual C++ während der Bearbeitung eingesehen werden. Eine Erläuterung der Vor- und Nachteile der manuellen Bearbeitung von benutzerdefinierten Steuerdialogfeldern in einer RC2-Datei finden Sie unter Verwenden von Ressourcendateien, die nicht mit Visual C++-Ressourcen-Editoren verwaltet werden können.

Testen von dynamischen Unterklassen

Die Steuerelemente werden in einer Dialogfeldvorlagenressource (IDD_SUB_EDIT in der Datei Ctrltest.rc) als Standard-Edit-Steuerelemente angelegt. Die Steuerelemente werden als CParsedEdit-Datenmember in der Dialogfeldklasse deklariert. Die OnInitDialog-Funktion des Dialogfelds ruft CParsedEdit::SubClassEdit auf. Daraufhin wird wiederum CWnd::SubclassDlgItem aufgerufen, um jede spezifische Instanz des Edit-Steuerelements mit der CParsedEdit-Klasse zu verknüpfen. Siehe auch Paredit.cpp.

Beispiel: Drehfeld-Steuerelement

Das CTRLTEST-Beispiel beinhaltet die Implementierung eines Drehfeld-Steuerelements. Das Drehfeld-Steuerelement verfügt über kleine Schaltflächen mit Aufwärts- und Abwärtspfeilen zum Erhöhen oder Verringern eines Werts.

Der Befehl Spin Control ruft ein Dialogfeld mit vier CParsedEdit-Steuerelementen auf, die jeweils mit einem Drehfeld-Steuerelement verknüpft sind. Die in die CParsedEdit-Steuerelemente dieses Dialogfelds eingegebenen Daten werden so gefiltert, dass sie ausschließlich nicht negative ganze Zahlen akzeptieren. Der Benutzer kann numerische Daten eingeben, indem er entweder den Wert in das CParsedEdit-Steuerelement eingibt oder das zugehörige Drehfeld-Steuerelement verwendet.

Beispiel: Bitmapschaltfläche

Die Implementierung der folgenden Befehle im Menü Custom veranschaulicht die verschiedenen Verwendungsmöglichkeiten von CBitmapButton:

  • Bitmap Button 1: Der Dialogfeldkonstruktor lädt die Bitmapressourcen explizit für jeden der drei Schaltflächenzustände (oben, unten und Fokus), indem CBitmapButton::LoadBitmaps aufgerufen wird.

  • Bitmap Button 2: Die OnInitDialog-Funktion des Dialogfelds ruft CBitmapButton::Autoload auf, um die Bitmapressourcen gemäß den nachstehenden Namenskonventionen zu laden. Der Fenstertext des Steuerelements wird als Basisressourcenname verwendet. Um die Ressourcennamen für die drei verschiedenen Bitmapbilder zu erstellen, werden die Buchstaben U (up=oben), D (down=unten) und F (Focus=Fokus) angehängt. So heißen beispielsweise die drei Bitmapressourcen der OK-Schaltfläche OKU, OKD und OKF.

  • Bitmap Button 3: Als Erweiterung des oben genannten zweiten Dialogfelds bietet dieses Dialogfeld einen vierten möglichen Schaltflächenzustand (deaktiviert). Um dieses Dialogfeld zu verwenden, klicken Sie auf die Bitmapschaltfläche mit dem Rechts- oder Linkspfeil, bis der angezeigte Wert entweder 1 (die niedrigste Zahl) oder 10 (die höchste Zahl) erreicht. Sobald das Limit erreicht ist, wird die Schaltfläche deaktiviert, und ein viertes Bitmapbild wird angezeigt. Nach der Namenskonvention für die Bitmapressource wird für den deaktivierten Zustand ein X-Suffix angefügt, wie in den Ressourcennamen PREVX und NEXTX ersichtlich ist.

Beispiel: Ownerdrawing (Menü und Listenfeld)

Verschiedene Windows-Steuerelemente und -Menüs verfügen über ein Ownerdrawing-Feature, mit dem das übergeordnete Fenster (oder das Besitzerfenster) eine beliebige Zeichnung im Clientbereich des Steuerelements anlegen kann (entgegen dem Verhalten von Standardsteuerelementen). Die entsprechenden Steuerelementklassen und die CMenu-Klasse stellen dieses Feature auf eine komfortablere, objektorientierte Weise zur Verfügung: Hierbei wird das Zeichnen vom Steuerelement oder der Menüklasse übernommen. Diese Technik wird "Selbstzeichnung" genannt.

CTRLTEST demonstriert die allgemeine Vorgehensweise beim Ownerdrawing, indem die folgenden Befehle im Menü Custom implementiert werden:

  • Custom Menu: Dieses Menüelement ruft ein von CMenu abgeleitetes CColorMenu-Popupmenü auf. Jedes Untermenüelement zeigt mithilfe des Selbstzeichnungsfeatures eine von acht Farben an. Ein Meldungsfeld bestätigt die Farbe, die Sie aus dem Untermenü ausgewählt haben.

  • Custom Listbox: Dieses Menüelement ruft ein Dialogfeld auf, in dem ein CColorListBox (abgeleitet von ClistBox) angezeigt wird. In diesem Listenfeld gibt es acht Einträge, von denen jeder mithilfe des Selbstzeichnungsfeatures in einer von acht Farben gezeichnet wurde. Die TRACE-Ausgabe bestätigt die im Listenfeld vorgenommene Auswahl.

Beispiel: Verwenden von Ressourcendateien, die nicht mit Visual C++-Ressourcen-Editoren verwaltet werden können

Die Ressourcendatei CTRLTEST\RES\Ctrltest.rc2 ist ein Beispiel für eine Ressourcendatei, die nicht mit Visual C++-Ressourcen-Editoren in einem lesbaren Format verwaltet werden kann. Sollten Sie versuchen, die Datei Ctrltest.rc2 in Visual C++ zu öffnen und anschließend zu speichern, würden Sie wichtige lesbare Daten verlieren, obwohl der Ressourcencompiler immer noch in der Lage wäre, die RC2-Datei zu kompilieren und eine äquivalente binäre RES-Datei zu erstellen. Deshalb wurde die Datei RES\Ctrltest.rc2 als #include-Anweisung mit einer Kompilierzeitdirektive zu Ctrltest.rc hinzugefügt. Die Direktive wird mit dem Befehl Resource File Set Includes festgelegt.

Die folgenden drei Kategorien lesbarer Daten können nicht mit Visual C++-Ressourcen-Editoren verwaltet werden. Zwei dieser Kategorien werden in der Datei Ctrltest.rc2 demonstriert:

  • Custom control styles symbols: Beispielsweise ist "msctls_updown32" ein Format, das für das Drehfeld-Steuerelement definiert ist. Obwohl Visual C++ dieses Symbol so interpretieren kann, wie es in der RC2-Datei eingelesen wird, würde Visual C++ die Datei als hexadezimalen Wert in die RC2-Datei zurückschreiben.

  • Standard Windows WS_ oder Formatsymbole in einem Steuerelement, das von einer standardmäßigen Windows-Steuerelementklasse abgeleitet ist: Beispielsweise ist ES_AUTOHSCROLL für das Drehfeld-Steuerelement im IDD_SPIN_EDIT-Dialogfeld definiert. Obwohl Visual C++ diese Symbole so interpretieren kann, wie es in der RC2-Datei eingelesen wird, würde Visual C++ die Datei als hexadezimalen Wert in die RC2-Dateien zurückschreiben.

  • Arithmetik in der RC-Datei: Ausdrücke wie "IDC_EDIT1+2", mit denen Steuerelemente im IDD_SPIN_EDIT-Dialogfeld identifiziert werden können, würden von Visual C++ als ein einzelner hexadezimaler Wert in die RC2-Datei zurückgeschrieben.

Das CTRLTEST-Beispiel veranschaulicht die Vor- und Nachteile der Verwendung von RC2-Dateien in einem Dialogfeld mit einem benutzerdefinierten Steuerelement, dessen Stile durch Konstanten in einer Headerdatei definiert sind. Beide Dialogfelder (IDD_WNDCLASS_EDIT und IDD_SPIN_EDIT) verfügen über benutzerdefinierte Steuerelemente mit symbolisch definierten Stilen. Während IDD_WNDCLASS in einer RC-Datei angelegt wird, die vom Visual C++-Dialog-Editor bearbeitet werden kann, lässt sich IDD_SPIN_EDIT in einer RC2-Datei ausschließlich manuell bearbeiten.

Im Folgenden werden die Unterschiede bei der Verwendung von RC- und RC2-Dateien zusammengefasst.

Das Ressourcenskript des IDD_WNDCLASS_EDIT-Dialogfelds ist in der Datei Ctrltest.rc definiert. Das Ressourcenskript des IDD_SPIN_EDIT-Dialogfelds ist dagegen in der Datei RES\Ctrltest.rc2 festgelegt. Das benutzerdefinierte WNDCLASS-Steuerelement des IDD_WNDCLASS_EDIT-Dialogfelds lautet "paredit", die Style-Konstanten sind in der Datei PAREDIT.H definiert, und eine Style-Konstante ist beispielsweise PES_NUMBER. IDD_WNDCLASS_EDIT kann mit Visual C++ bearbeitet werden, aber kann keine #define-Formate verwenden. IDD_SPIN_EDIT kann mit Visual C++ nicht bearbeitet werden, kann aber #define-Formate verwenden.

Der Nachteil besteht darin, dass Sie bei Verwendung der RC2-Datei zwar die lesbaren symbolischen Formate verwenden können, die in der Headerdatei des benutzerdefinierten Steuerelements festgelegt sind, diese RC2-Datei kann jedoch nicht mit dem Visual C++-Dialog-Editor bearbeitet werden. Es ist einfacher, das Layout des Dialogfelds mithilfe von Visual C++ festzulegen, als das Ressourcenskript manuell zu schreiben. Außerdem ist die Wahrscheinlichkeit von Fehlern beim manuellen Schreiben von Ressourcenskripts höher. Andererseits sind die Formate nicht selbstdokumentierend, wenn sie vom Visual C++-Dialog-Editor im hexadezimalen Format auf der Eigenschaftenseite der benutzerdefinierten Steuerelemente angezeigt werden.

Schlüsselwörter

Dieses Beispiel demonstriert die Verwendung der folgenden Schlüsselwörter:

AfxGetInstanceHandle; AfxMessageBox; AfxThrowResourceException; CBitmapButton::AutoLoad; CDC::FillRect; CDC::FrameRect; CDialog::DoModal; CDialog::EndDialog; CDialog::OnInitDialog; CDialog::OnOK; CDialog::OnSetFont; CEdit::Create; CEdit::SetSel; CFrameWnd::Create; CListBox::AddString; CListBox::CompareItem; CListBox::DrawItem; CListBox::GetItemData; CListBox::MeasureItem; CMenu::AppendMenu; CMenu::CreateMenu; CMenu::Detach; CMenu::DrawItem; CMenu::EnableMenuItem; CMenu::FromHandle; CMenu::GetMenuString; CMenu::MeasureItem; CRect::Width; CStatic::Create; CString::Format; CString::LoadString; CWinApp::InitInstance; CWnd::Attach; CWnd::EnableWindow; CWnd::FromHandle; CWnd::GetDlgCtrlID; CWnd::GetDlgItem; CWnd::GetDlgItemInt; CWnd::GetMenu; CWnd::GetParent; CWnd::GetWindowRect; CWnd::GetWindowText; CWnd::IsWindowEnabled; CWnd::MessageBox; CWnd::OnChar; CWnd::OnCommand; CWnd::OnVScroll; CWnd::PostNcDestroy; CWnd::SendMessage; CWnd::SetDlgItemInt; CWnd::SetFocus; CWnd::SetFont; CWnd::SetWindowPos; CWnd::ShowWindow; CWnd::SubclassDlgItem; CallWindowProc; GetBValue; GetClassInfo; GetGValue; GetRValue; GetSystemMetrics; HIWORD; IsCharAlpha; IsCharAlphaNumeric; LOWORD; MAKEINTRESOURCE; MAKELONG; MessageBeep; ModifyMenu; RGB; RegisterClass; SetWindowLong

Hinweis:

In diesem und einigen anderen Beispielen wurden die Änderungen an den Visual C++-Assistenten, -Bibliotheken und -Compilern noch nicht nachvollzogen. Sie demonstrieren aber dennoch, wie Sie die gewünschte Aufgabe durchführen können.

Siehe auch

Weitere Ressourcen

MFC-Beispiele