Freigeben über


Verwenden allgemeiner Dialogfelder

In diesem Abschnitt werden Aufgaben behandelt, die allgemeine Dialogfelder aufrufen:

Auswählen einer Farbe

In diesem Thema werden 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 WAHR 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 anfänglich schwarz, aber das statische Array behält benutzerdefinierte Farben bei, die vom Benutzer für nachfolgende ChooseColor-Aufrufe erstellt wurden.
  • Setzt das Flag CC_RGBINIT und initialisiert das Mitglied rgbResult, um die Farbe festzulegen, die anfangs ausgewählt wird, wenn das Dialogfeld geöffnet wird. Wenn nicht angegeben, ist die anfängliche Auswahl schwarz. Im Beispiel wird die statische rgbCurrent-Variable verwendet, um den ausgewählten Wert zwischen Aufrufen von ChooseColor beizubehalten.
  • Setzt das Flag CC_FULLOPEN , damit die Erweiterung für benutzerdefinierte Farben der Dialogbox 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 werden Beispielcode beschrieben, der ein Dialogfeld "Schriftart " anzeigt, damit 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 die CF_SCREENFONTS-Kennzeichnung festgelegt, um anzugeben, dass das Dialogfeld nur Bildschirmschriftarten anzeigen soll. Es legt das CF_EFFECTS-Flag fest, um Steuerelemente anzuzeigen, mit denen der Benutzer Durchstreichen, Unterstreichen und Farboptionen auswählen kann.

Wenn ChooseFontTRUE zurückgibt, was 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 das lpLogFont-Element verweist. 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 der Dialog "Gemeinsame Datei" durch den Dialog "Gemeinsame Elemente" ersetzt, wenn er zum Öffnen einer Datei verwendet wird. Wir empfehlen, die API für das allgemeine Elementdialogfeld anstelle der API für das allgemeine Dateidialogfeld zu verwenden. Weitere Informationen finden Sie im Dialogfeld "Allgemeines Element".

In diesem Thema werden Beispielcode beschrieben, der ein Dialogfeld " Öffnen " anzeigt, damit 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 das lpstrFilter-Element 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 Doppel-Null-terminiertes Array von Strings, in dem jedes Paar von Strings einen Filter angibt. Das Element "nFilterIndex " gibt an, dass das erste Muster beim Erstellen des Dialogfelds verwendet 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 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 Dateiname vorhanden sind. In diesem Fall enthält der puffer, auf den das lpstrFile-Element verweist, den Pfad und 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 weiterhin das standardmäßige Dialogfeld " Öffnen " im Explorer-Format angezeigt. Wenn Sie jedoch eine Hook-Prozedur oder eine benutzerdefinierte Vorlage bereitstellen möchten und die Benutzeroberfläche des Explorers verwenden möchten, müssen Sie das OFN_EXPLORER Flag festlegen.

Hinweis

In der Programmiersprache C wird eine in Anführungszeichen eingeschlossene Zeichenfolge durch ein Nullzeichen 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 werden 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. Dadurch gibt PrintDlg ein Gerätekontext-Handle für den ausgewählten Drucker im Mitglied hDC zurück. Sie können das Handle verwenden, um die Ausgabe auf dem Drucker wiederzugeben.

Bei eingaben legt der Beispielcode die Elemente "hDevMode " und "hDevNames " auf NULL fest. Wenn die Funktion WAHR 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 Eigenschaftsblatts Drucken

In diesem Thema wird Beispielcode beschrieben, der ein Druck-Eigenschaftenblatt anzeigt, sodass ein Benutzer Optionen für das 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-Element der PRINTDLG-Struktur fest. Dies bewirkt, dass die PrintDlgEx-Funktion ein Handle für den Gerätekontext an den ausgewählten Drucker im hDC-Mitglied zurückgibt.

Bei eingaben 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.

Nachdem der Druckvorgang abgeschlossen wurde, gibt der Beispielcode die DEVMODE, DEVNAMES und PRINTPAGERANGE Speicher 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 werden Beispielcode beschrieben, der ein Dialogfeld " Seite einrichten " 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-Element festgelegt und das rtMargin-Element verwendet, um die anfänglichen Randwerte anzugeben. Es legt die PSD_INTHOUSANDTHSOFINCHES-Kennzeichnung fest, um sicherzustellen, dass das Dialogfeld Randabmessungen in Tausendstel zoll ausdrückt.

Bei eingaben legt der Beispielcode die Elemente "hDevMode " und "hDevNames " auf NULL fest. Wenn die Funktion WAHR zurückgibt, verwendet die Funktion diese Member, um Handles zu 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 aktiviert auch eine PagePaintHook Hook-Prozedur, um das Zeichnen des Inhalts der Musterseite anzupassen.

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 beispielhafte PagePaintHook Hook-Prozedur, die das Randrechteck im Bereich der Musterseite 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 werden Beispielcode beschrieben, der ein Dialogfeld " Suchen " anzeigt und verwaltet, damit 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, außer dass er die ReplaceText-Funktion zum Anzeigen des Dialogfelds verwendet. Das Dialogfeld "Ersetzen " sendet auch Nachrichten als Reaktion auf Benutzerklicks auf die Schaltflächen "Alle ersetzen " und "Alle ersetzen ".

Um das Dialogfeld " Suchen " oder " Ersetzen " zu verwenden, müssen Sie drei separate Aufgaben ausführen:

  1. Rufen Sie einen Nachrichtenbezeichner für die registrierte FINDMSGSTRING-Nachricht ab.
  2. Zeigt das Dialogfeld an.
  3. Verarbeiten von FINDMSGSTRING-Meldungen , wenn das Dialogfeld geöffnet ist.

Rufen Sie beim Initialisieren der Anwendung die RegisterWindowMessage-Funktion auf, um einen Nachrichtenbezeichner für die registrierte NACHRICHT FINDMSGSTRING 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 vor dem Schließen des Dialogfelds nicht außerhalb des Gültigkeitsbereichs liegt. Sie müssen das hwndOwner-Mitglied festlegen, um das Fenster anzugeben, das die registrierten Nachrichten empfängt. Nachdem Sie das Dialogfeld erstellt haben, können Sie es mithilfe des zurückgegebenen Handles 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 die Hauptnachrichtenschleife einen Aufruf der IsDialogMessage-Funktion enthalten. Übergeben Sie ein Handle für das Dialogfeld als Parameter im Aufruf IsDialogMessage . Dadurch wird sichergestellt, dass das Dialogfeld Tastaturmeldungen ordnungsgemäß verarbeitet.

Um nachrichten zu überwachen, die aus dem Dialogfeld gesendet werden, muss ihre Fensterprozedur wie im folgenden Beispiel auf die registrierte FINDMSGSTRING-Nachricht überprüfen und die in der FINDREPLACE-Struktur übergebenen Werte verarbeiten.

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; 
}