Verwenden allgemeiner Dialogfelder
In diesem Abschnitt werden Aufgaben behandelt, die allgemeine Dialogfelder aufrufen:
- Auswählen einer Farbe
- Auswählen einer Schriftart
- Öffnen einer Datei
- Anzeigen des Dialogfelds "Drucken"
- Verwenden des Druckeigenschaftenblatts
- Einrichten der gedruckten Seite
- Suchen nach Text
Auswählen einer Farbe
In diesem Thema wird der Beispielcode beschrieben, der ein Dialogfeld Farbe anzeigt, damit ein Benutzer eine Farbe auswählen kann. Der Beispielcode initialisiert zunächst eine CHOOSECOLOR-Struktur und ruft dann die ChooseColor-Funktion auf, um das Dialogfeld anzuzeigen. Wenn die Funktion TRUE zurückgibt und angibt, dass der Benutzer eine Farbe ausgewählt hat, verwendet der Beispielcode die ausgewählte Farbe, um einen neuen Volltonpinsel zu erstellen.
In diesem Beispiel wird die CHOOSECOLOR-Struktur verwendet, um das Dialogfeld wie folgt zu initialisieren:
- Initialisiert das lpCustColors-Element mit einem Zeiger auf ein statisches Array von Werten. Die Farben im Array sind zunächst schwarz, aber das statische Array behält benutzerdefinierte Farben bei, die vom Benutzer für nachfolgende ChooseColor-Aufrufe erstellt wurden.
- Legt das CC_RGBINIT-Flag fest und initialisiert das rgbResult-Element , um die Farbe anzugeben, die beim Öffnen des Dialogfelds zunächst ausgewählt wird. Wenn nicht angegeben, ist die anfängliche Auswahl schwarz. Im Beispiel wird die statische Variable rgbCurrent verwendet, um den ausgewählten Wert zwischen Aufrufen von ChooseColor beizubehalten.
- Legt das CC_FULLOPEN-Flag fest, damit die benutzerdefinierte Farberweiterung des Dialogfelds immer angezeigt wird.
CHOOSECOLOR cc; // common dialog box structure
static COLORREF acrCustClr[16]; // array of custom colors
HWND hwnd; // owner window
HBRUSH hbrush; // brush handle
static DWORD rgbCurrent; // initial color selection
// Initialize CHOOSECOLOR
ZeroMemory(&cc, sizeof(cc));
cc.lStructSize = sizeof(cc);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD) acrCustClr;
cc.rgbResult = rgbCurrent;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColor(&cc)==TRUE)
{
hbrush = CreateSolidBrush(cc.rgbResult);
rgbCurrent = cc.rgbResult;
}
Auswählen einer Schriftart
In diesem Thema wird Beispielcode beschrieben, der ein Dialogfeld Schriftart anzeigt, sodass ein Benutzer die Attribute einer Schriftart auswählen kann. Der Beispielcode initialisiert zunächst eine CHOOSEFONT-Struktur und ruft dann die ChooseFont-Funktion auf, um das Dialogfeld anzuzeigen.
In diesem Beispiel wird das CF_SCREENFONTS-Flag so festgelegt, dass im Dialogfeld nur Bildschirmschriftarten angezeigt werden sollen. Es legt das CF_EFFECTS-Flag fest, um Steuerelemente anzuzeigen, die es dem Benutzer ermöglichen, Streich-, Unterstrichen- und Farboptionen auszuwählen.
Wenn ChooseFontTRUE zurückgibt und angibt, dass der Benutzer auf die Schaltfläche OK geklickt hat, enthält die CHOOSEFONT-Struktur Informationen, die die vom Benutzer ausgewählten Schriftart- und Schriftartattribute beschreiben, einschließlich der Elemente der LOGFONT-Struktur , auf die vom lpLogFont-Member verwiesen wird. Das rgbColors-Element enthält die ausgewählte Textfarbe. Der Beispielcode verwendet diese Informationen, um die Schriftart und Die Textfarbe für den Gerätekontext festzulegen, der dem Besitzerfenster zugeordnet ist.
HWND hwnd; // owner window
HDC hdc; // display device context of owner window
CHOOSEFONT cf; // common dialog box structure
static LOGFONT lf; // logical font structure
static DWORD rgbCurrent; // current text color
HFONT hfont, hfontPrev;
DWORD rgbPrev;
// Initialize CHOOSEFONT
ZeroMemory(&cf, sizeof(cf));
cf.lStructSize = sizeof (cf);
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.rgbColors = rgbCurrent;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
if (ChooseFont(&cf)==TRUE)
{
hfont = CreateFontIndirect(cf.lpLogFont);
hfontPrev = SelectObject(hdc, hfont);
rgbCurrent= cf.rgbColors;
rgbPrev = SetTextColor(hdc, rgbCurrent);
.
.
.
}
Öffnen einer Datei
Hinweis
Ab Windows Vista wurde das Dialogfeld "Allgemeine Datei" durch das Dialogfeld "Gemeinsame Elemente" ersetzt, wenn es zum Öffnen einer Datei verwendet wird. Es wird empfohlen, die Dialog-API für allgemeine Elemente anstelle der Api für allgemeine Dateidialoge zu verwenden. Weitere Informationen finden Sie unter Allgemeines Elementdialogfeld.
In diesem Thema wird Beispielcode beschrieben, der ein Dialogfeld Öffnen anzeigt, sodass ein Benutzer das Laufwerk, das Verzeichnis und den Namen einer zu öffnenden Datei angeben kann. Der Beispielcode initialisiert zunächst eine OPENFILENAME-Struktur und ruft dann die GetOpenFileName-Funktion auf, um das Dialogfeld anzuzeigen.
In diesem Beispiel ist der lpstrFilter-Member ein Zeiger auf einen Puffer, der zwei Dateinamenfilter angibt, die der Benutzer auswählen kann, um die angezeigten Dateinamen einzuschränken. Der Puffer enthält ein double-NULL-beendetes Array von Zeichenfolgen, in dem jedes Zeichenfolgenpaar einen Filter angibt. Das nFilterIndex-Element gibt an, dass das erste Muster verwendet wird, wenn das Dialogfeld erstellt wird.
In diesem Beispiel werden die OFN_PATHMUSTEXIST - und OFN_FILEMUSTEXIST-Flags im Flags-Element festgelegt. Diese Flags führen dazu, dass das Dialogfeld vor der Rückgabe überprüft, ob der vom Benutzer angegebene Pfad und der vom Benutzer angegebene Dateiname tatsächlich vorhanden sind.
Die GetOpenFileName-Funktion gibt TRUE zurück, wenn der Benutzer auf die Schaltfläche OK klickt und der angegebene Pfad und der angegebene Dateiname vorhanden sind. In diesem Fall enthält der Puffer, auf den das lpstrFile-Element verweist, den Pfad und den Dateinamen. Der Beispielcode verwendet diese Informationen in einem Aufruf der Funktion, um die Datei zu öffnen.
Obwohl in diesem Beispiel das OFN_EXPLORER-Flag nicht festgelegt wird, wird dennoch das Standarddialogfeld öffnen Explorer angezeigt. Wenn Sie jedoch eine Hookprozedur oder eine benutzerdefinierte Vorlage bereitstellen möchten und die Explorer Benutzeroberfläche verwenden möchten, müssen Sie das flag OFN_EXPLORER festlegen.
Hinweis
In der Programmiersprache C ist eine in Anführungszeichen eingeschlossene Zeichenfolge null-beendet.
OPENFILENAME ofn; // common dialog box structure
char szFile[260]; // buffer for file name
HWND hwnd; // owner window
HANDLE hf; // file handle
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)==TRUE)
hf = CreateFile(ofn.lpstrFile,
GENERIC_READ,
0,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
Anzeigen des Dialogfelds "Drucken"
In diesem Thema wird der Beispielcode beschrieben, der ein Dialogfeld Drucken anzeigt, sodass ein Benutzer Optionen zum Drucken eines Dokuments auswählen kann. Der Beispielcode initialisiert zunächst eine PRINTDLG-Struktur und ruft dann die PrintDlg-Funktion auf, um das Dialogfeld anzuzeigen.
In diesem Beispiel wird das PD_RETURNDC-Flag im Flags-Element der PRINTDLG-Struktur festgelegt. Dies bewirkt , dass PrintDlg ein Gerätekontexthandle an den ausgewählten Drucker im hDC-Element zurückgibt. Sie können den Handle verwenden, um die Ausgabe auf dem Drucker zu rendern.
Bei der Eingabe legt der Beispielcode die Elemente hDevMode und hDevNames auf NULL fest. Wenn die Funktion TRUE zurückgibt, geben diese Member Handles an DEVNAMES-Strukturen zurück, die die Benutzereingabe und Informationen zum Drucker enthalten. Sie können diese Informationen verwenden, um die Ausgabe vorzubereiten, die an den ausgewählten Drucker gesendet werden soll.
PRINTDLG pd;
HWND hwnd;
// Initialize PRINTDLG
ZeroMemory(&pd, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner = hwnd;
pd.hDevMode = NULL; // Don't forget to free or store hDevMode.
pd.hDevNames = NULL; // Don't forget to free or store hDevNames.
pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
pd.nCopies = 1;
pd.nFromPage = 0xFFFF;
pd.nToPage = 0xFFFF;
pd.nMinPage = 1;
pd.nMaxPage = 0xFFFF;
if (PrintDlg(&pd)==TRUE)
{
// GDI calls to render output.
// Delete DC when done.
DeleteDC(pd.hDC);
}
Verwenden des Druckeigenschaftenblatts
In diesem Thema wird der Beispielcode beschrieben, der ein Print-Eigenschaftenblatt anzeigt, sodass ein Benutzer Optionen zum Drucken eines Dokuments auswählen kann. Der Beispielcode initialisiert zunächst eine PRINTDLGEX-Struktur und ruft dann die PrintDlgEx-Funktion auf, um das Eigenschaftenblatt anzuzeigen.
Der Beispielcode legt das PD_RETURNDC-Flag im Flags-Member der PRINTDLG-Struktur fest. Dies bewirkt, dass die PrintDlgEx-Funktion ein Gerätekontexthandle an den ausgewählten Drucker im hDC-Element zurückgibt.
Bei der Eingabe legt der Beispielcode die Elemente hDevMode und hDevNames auf NULL fest. Wenn die Funktion S_OK zurückgibt, geben diese Member Handles an DEVNAMES-Strukturen zurück, die die Benutzereingabe und Informationen zum Drucker enthalten. Sie können diese Informationen verwenden, um die Ausgabe vorzubereiten, die an den ausgewählten Drucker gesendet werden soll.
Nach Abschluss des Druckvorgangs gibt der Beispielcode die Puffer DEVMODE, DEVNAMES und PRINTPAGERANGE frei und ruft die DeleteDC-Funktion auf, um den Gerätekontext zu löschen.
// hWnd is the window that owns the property sheet.
HRESULT DisplayPrintPropertySheet(HWND hWnd)
{
HRESULT hResult;
PRINTDLGEX pdx = {0};
LPPRINTPAGERANGE pPageRanges = NULL;
// Allocate an array of PRINTPAGERANGE structures.
pPageRanges = (LPPRINTPAGERANGE) GlobalAlloc(GPTR, 10 * sizeof(PRINTPAGERANGE));
if (!pPageRanges)
return E_OUTOFMEMORY;
// Initialize the PRINTDLGEX structure.
pdx.lStructSize = sizeof(PRINTDLGEX);
pdx.hwndOwner = hWnd;
pdx.hDevMode = NULL;
pdx.hDevNames = NULL;
pdx.hDC = NULL;
pdx.Flags = PD_RETURNDC | PD_COLLATE;
pdx.Flags2 = 0;
pdx.ExclusionFlags = 0;
pdx.nPageRanges = 0;
pdx.nMaxPageRanges = 10;
pdx.lpPageRanges = pPageRanges;
pdx.nMinPage = 1;
pdx.nMaxPage = 1000;
pdx.nCopies = 1;
pdx.hInstance = 0;
pdx.lpPrintTemplateName = NULL;
pdx.lpCallback = NULL;
pdx.nPropertyPages = 0;
pdx.lphPropertyPages = NULL;
pdx.nStartPage = START_PAGE_GENERAL;
pdx.dwResultAction = 0;
// Invoke the Print property sheet.
hResult = PrintDlgEx(&pdx);
if ((hResult == S_OK) && pdx.dwResultAction == PD_RESULT_PRINT)
{
// User clicked the Print button, so use the DC and other information returned in the
// PRINTDLGEX structure to print the document.
}
if (pdx.hDevMode != NULL)
GlobalFree(pdx.hDevMode);
if (pdx.hDevNames != NULL)
GlobalFree(pdx.hDevNames);
if (pdx.lpPageRanges != NULL)
GlobalFree(pPageRanges);
if (pdx.hDC != NULL)
DeleteDC(pdx.hDC);
return hResult;
}
Einrichten der gedruckten Seite
In diesem Thema wird der Beispielcode beschrieben, der ein Dialogfeld Seiteneinrichtung anzeigt, sodass ein Benutzer die Attribute der gedruckten Seite auswählen kann, z. B. Papiertyp, Papierquelle, Seitenausrichtung und Seitenränder. Der Beispielcode initialisiert zunächst eine PAGESETUPDLG-Struktur und ruft dann die PageSetupDlg-Funktion auf, um das Dialogfeld anzuzeigen.
In diesem Beispiel wird das PSD_MARGINS-Flag im Flags-Member festgelegt und der rtMargin-Member verwendet, um die anfänglichen Randwerte anzugeben. Es legt das PSD_INTHOUSANDTHSOFINCHES-Flag fest, um sicherzustellen, dass das Dialogfeld Randabmessungen in tausendstel Zoll ausdrückt.
Bei der Eingabe legt der Beispielcode die Elemente hDevMode und hDevNames auf NULL fest. Wenn die Funktion TRUE zurückgibt, verwendet die Funktion diese Member, um Handles an DEVNAMES-Strukturen zurückzugeben, die die Benutzereingabe und Informationen zum Drucker enthalten. Sie können diese Informationen verwenden, um die Ausgabe vorzubereiten, die an den ausgewählten Drucker gesendet werden soll.
Das folgende Beispiel ermöglicht auch eine PagePaintHook-Hookprozedur zum Anpassen des Zeichnungsinhalts der Beispielseite.
PAGESETUPDLG psd; // common dialog box structure
HWND hwnd; // owner window
// Initialize PAGESETUPDLG
ZeroMemory(&psd, sizeof(psd));
psd.lStructSize = sizeof(psd);
psd.hwndOwner = hwnd;
psd.hDevMode = NULL; // Don't forget to free or store hDevMode.
psd.hDevNames = NULL; // Don't forget to free or store hDevNames.
psd.Flags = PSD_INTHOUSANDTHSOFINCHES | PSD_MARGINS |
PSD_ENABLEPAGEPAINTHOOK;
psd.rtMargin.top = 1000;
psd.rtMargin.left = 1250;
psd.rtMargin.right = 1250;
psd.rtMargin.bottom = 1000;
psd.lpfnPagePaintHook = PaintHook;
if (PageSetupDlg(&psd)==TRUE)
{
// check paper size and margin values here.
}
Das folgende Beispiel zeigt eine PagePaintHook-Hook-Beispielprozedur , die das Randrechteck im Beispielseitenbereich zeichnet:
BOOL CALLBACK PaintHook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LPRECT lprc;
COLORREF crMargRect;
HDC hdc, hdcOld;
switch (uMsg)
{
// Draw the margin rectangle.
case WM_PSD_MARGINRECT:
hdc = (HDC) wParam;
lprc = (LPRECT) lParam;
// Get the system highlight color.
crMargRect = GetSysColor(COLOR_HIGHLIGHT);
// Create a dash-dot pen of the system highlight color and
// select it into the DC of the sample page.
hdcOld = SelectObject(hdc, CreatePen(PS_DASHDOT, .5, crMargRect));
// Draw the margin rectangle.
Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom);
// Restore the previous pen to the DC.
SelectObject(hdc, hdcOld);
return TRUE;
default:
return FALSE;
}
return TRUE;
}
Suchen nach Text
In diesem Thema wird Beispielcode beschrieben, der ein Dialogfeld Suchen anzeigt und verwaltet, sodass der Benutzer die Parameter eines Suchvorgangs angeben kann. Das Dialogfeld sendet Nachrichten an die Fensterprozedur, damit Sie den Suchvorgang ausführen können.
Der Code zum Anzeigen und Verwalten eines Dialogfelds Ersetzen ist ähnlich, mit der Ausnahme, dass es die ReplaceText-Funktion verwendet, um das Dialogfeld anzuzeigen. Das Dialogfeld Ersetzen sendet auch Nachrichten als Reaktion auf Benutzerklicks auf die Schaltflächen Ersetzen und Alle ersetzen .
Um das Dialogfeld Suchen oder Ersetzen verwenden zu können, müssen Sie drei separate Aufgaben ausführen:
- Rufen Sie einen Nachrichtenbezeichner für die registrierte FINDMSGSTRING-Nachricht ab.
- Zeigt das Dialogfeld an.
- Verarbeiten sie FINDMSGSTRING-Nachrichten , wenn das Dialogfeld geöffnet ist.
Wenn Sie Ihre Anwendung initialisieren, rufen Sie die Funktion RegisterWindowMessage auf, um einen Nachrichtenbezeichner für die registrierte FINDMSGSTRING-Nachricht abzurufen.
UINT uFindReplaceMsg; // message identifier for FINDMSGSTRING
uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);
Um ein Suchdialogfeld anzuzeigen, initialisieren Sie zuerst eine FINDREPLACE-Struktur , und rufen Sie dann die FindText-Funktion auf. Beachten Sie, dass die FINDREPLACE-Struktur und der Puffer für die Suchzeichenfolge eine globale oder statische Variable sein sollten, damit sie nicht aus dem Bereich herauskommt, bevor das Dialogfeld geschlossen wird. Sie müssen das hwndOwner-Element festlegen, um das Fenster anzugeben, in dem die registrierten Nachrichten empfangen werden. Nachdem Sie das Dialogfeld erstellt haben, können Sie es mithilfe des zurückgegebenen Handle verschieben oder bearbeiten.
FINDREPLACE fr; // common dialog box structure
HWND hwnd; // owner window
CHAR szFindWhat[80]; // buffer receiving string
HWND hdlg = NULL; // handle to Find dialog box
// Initialize FINDREPLACE
ZeroMemory(&fr, sizeof(fr));
fr.lStructSize = sizeof(fr);
fr.hwndOwner = hwnd;
fr.lpstrFindWhat = szFindWhat;
fr.wFindWhatLen = 80;
fr.Flags = 0;
hdlg = FindText(&fr);
Wenn das Dialogfeld geöffnet ist, muss Ihre Standard Nachrichtenschleife einen Aufruf der IsDialogMessage-Funktion enthalten. Übergeben Sie ein Handle als Parameter im IsDialogMessage-Aufruf an das Dialogfeld. Dadurch wird sichergestellt, dass das Dialogfeld Tastaturmeldungen ordnungsgemäß verarbeitet.
Zum Überwachen von Nachrichten, die aus dem Dialogfeld gesendet werden, muss ihre Fensterprozedur nach der registrierten FINDMSGSTRING-Nachricht suchen und die werte verarbeiten, die in der FINDREPLACE-Struktur übergeben werden, wie im folgenden Beispiel beschrieben.
LPFINDREPLACE lpfr;
if (message == uFindReplaceMsg)
{
// Get pointer to FINDREPLACE structure from lParam.
lpfr = (LPFINDREPLACE)lParam;
// If the FR_DIALOGTERM flag is set,
// invalidate the handle that identifies the dialog box.
if (lpfr->Flags & FR_DIALOGTERM)
{
hdlg = NULL;
return 0;
}
// If the FR_FINDNEXT flag is set,
// call the application-defined search routine
// to search for the requested string.
if (lpfr->Flags & FR_FINDNEXT)
{
SearchFile(lpfr->lpstrFindWhat,
(BOOL) (lpfr->Flags & FR_DOWN),
(BOOL) (lpfr->Flags & FR_MATCHCASE));
}
return 0;
}