Använda vanliga dialogrutor
Det här avsnittet beskriver uppgifter som anropar vanliga dialogrutor:
- välja en färg
- välja ett teckensnitt
- Öppna en fil
- Visa dialogrutan Skriv ut
- Använda utskriftsegenskapsbladet
- konfigurera den utskrivna sidan
- Hitta text
Välja en färg
I det här avsnittet beskrivs exempelkod som visar en dialogruta Color så att en användare kan välja en färg. Exempelkoden initierar först en CHOOSECOLOR- struktur och anropar sedan funktionen ChooseColor för att visa dialogrutan. Om funktionen returnerar TRUE, som anger att användaren har valt en färg, använder exempelkoden den valda färgen för att skapa en ny hel pensel.
I det här exemplet används CHOOSECOLOR- struktur för att initiera dialogrutan på följande sätt:
- Initierar lpCustColors medlem med en pekare till en statisk matris med värden. Färgerna i matrisen är inledningsvis svarta, men den statiska matrisen bevarar anpassade färger som skapats av användaren för efterföljande ChooseColor--anrop.
- Anger flaggan CC_RGBINIT och initierar rgbResult elementet för att ange den färg som initialt väljs när dialogrutan öppnas. Om det inte anges är standardvalet svart. I exemplet används rgbCurrent statisk variabel för att bevara det valda värdet mellan anrop till ChooseColor.
- Anger flaggan CC_FULLOPEN så att dialogrutans tillägg för anpassade färger alltid visas.
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;
}
Välja ett teckensnitt
I det här avsnittet beskrivs exempelkod som visar en dialogruta Teckensnitt så att en användare kan välja attributen för ett teckensnitt. Exempelkoden initierar först en CHOOSEFONT- struktur och anropar sedan funktionen ChooseFont för att visa dialogrutan.
I det här exemplet anges flaggan CF_SCREENFONTS för att ange att dialogrutan endast ska visa skärmteckensnitt. Den ställer in flaggan CF_EFFECTS för att visa kontroller som gör att användaren kan välja alternativ för utstrykning, understrykning och färg.
Om ChooseFont returnerar TRUE, vilket anger att användaren klickade på OK-knappen, innehåller CHOOSEFONT-strukturen information som beskriver teckensnitten och teckensnittsattributen som användaren har valt, inklusive medlemmarna i LOGFONT-strukturen som pekas ut av lpLogFont-medlemmen. rgbColors medlem innehåller den markerade textfärgen. Exempelkoden använder den här informationen för att ange teckensnitts- och textfärgen för enhetskontexten som är associerad med ägarfönstret.
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);
.
.
.
}
Öppna en fil
Not
Från och med Windows Vista har dialogrutan Gemensam fil ersatts av dialogrutan Gemensamt objekt när den används för att öppna en fil. Vi rekommenderar att du använder API:et för Common Item Dialog i stället för Common File Dialog API. Mer information finns i dialogrutan common item.
I det här avsnittet beskrivs exempelkod som visar en dialogruta Öppna så att en användare kan ange enheten, katalogen och namnet på en fil som ska öppnas. Exempelkoden initierar först en OPENFILENAME- struktur och anropar sedan funktionen GetOpenFileName för att visa dialogrutan.
I det här exemplet är lpstrFilter medlem en pekare till en buffert som anger två filnamnsfilter som användaren kan välja för att begränsa de filnamn som visas. Bufferten innehåller en dubbel-null avslutad matris med strängar där varje par med strängar anger ett filter. nFilterIndex medlem anger att det första mönstret används när dialogrutan skapas.
I det här exemplet anges flaggorna OFN_PATHMUSTEXIST och OFN_FILEMUSTEXIST i medlemmen Flags. Dessa flaggor gör att dialogrutan verifierar att sökvägen och filnamnet som anges av användaren faktiskt finns innan de returneras.
Funktionen GetOpenFileName returnerar TRUE- om användaren klickar på knappen OK och den angivna sökvägen och filnamnet finns. I det här fallet innehåller bufferten som pekas på av lpstrFile medlem sökvägen och filnamnet. Exempelkoden använder den här informationen i ett anrop till funktionen för att öppna filen.
Även om det här exemplet inte anger flaggan OFN_EXPLORER visas fortfarande standarddialogrutan Explorer-stil Öppna. Men om du vill ange en hook-procedur eller en anpassad mall och vill ha användargränssnittet i Explorer måste du ange flaggan OFN_EXPLORER.
Notera
I programmeringsspråket C är en sträng som omges av citattecken null-avslutad.
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);
Visa dialogrutan Skriv ut
I det här avsnittet beskrivs exempelkod som visar en dialogruta Skriv ut så att en användare kan välja alternativ för att skriva ut ett dokument. Exempelkoden initierar först en PRINTDLG- struktur och anropar sedan funktionen PrintDlg för att visa dialogrutan.
I det här exemplet anges flaggan PD_RETURNDC i fältet Flags i strukturen PRINTDLG. Detta gör att PrintDlg- returnerar ett enhetskontexthandtag till den valda skrivaren i hDC- medlem. Du kan använda handtaget för att återge utdata på skrivaren.
Vid indata anger exempelkoden hDevMode och hDevNames medlemmar till NULL-. Om funktionen returnerar TRUEreturnerar dessa medlemmar referenser till DEVNAMES strukturer som innehåller användarens indata och information om skrivaren. Du kan använda den här informationen för att förbereda utdata som ska skickas till den valda skrivaren.
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);
}
Använda utskriftsegenskapsbladet
I det här avsnittet beskrivs exempelkod som visar ett Skriv ut egenskapsblad så att en användare kan välja alternativ för att skriva ut ett dokument. Exempelkoden initierar först en PRINTDLGEX- struktur och anropar sedan funktionen PrintDlgEx för att visa egenskapsbladet.
Exempelkoden anger flaggan PD_RETURNDC i fältet Flags i strukturen PRINTDLG. Detta gör att funktionen PrintDlgEx returnerar en enhetskontextreferens till den valda skrivaren i hDC- medlem.
Vid indata tilldelar exempelkoden medlemmarna hDevMode och hDevNames värdet NULL. Om funktionen returnerar S_OKreturnerar dessa medlemmar referenser till DEVNAMES strukturer som innehåller användarens indata och information om skrivaren. Du kan använda den här informationen för att förbereda utdata som ska skickas till den valda skrivaren.
När utskriften har slutförts frigör exempelkoden DEVMODE-, DEVNAMESoch PRINTPAGERANGE buffertar och anropar funktionen DeleteDC för att ta bort enhetskontexten.
// 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;
}
Konfigurera den utskrivna sidan
I det här avsnittet beskrivs exempelkod som visar en dialogruta för utskriftsinställningar så att en användare kan välja attributen för den utskrivna sidan, till exempel papperstyp, papperskälla, sidorientering och sidmarginaler. Exempelkoden initierar först en PAGESETUPDLG- struktur och anropar sedan funktionen PageSetupDlg för att visa dialogrutan.
I det här exemplet anges flaggan PSD_MARGINS i medlemmen Flags och använder rtMargin-medlemmen för att ange de inledande marginalvärdena. Den anger flaggan PSD_INTHOUSANDTHSOFINCHES för att säkerställa att dialogrutan uttrycker marginaldimensioner i tusendelar av en tum.
Vid indata anger exempelkoden hDevMode och hDevNames medlemmar till NULL-. Om funktionen returnerar TRUEanvänder funktionen dessa medlemmar för att returnera referenser till DEVNAMES- strukturer som innehåller användarens indata och information om skrivaren. Du kan använda den här informationen för att förbereda utdata som ska skickas till den valda skrivaren.
Följande exempel aktiverar också en PagePaintHook hook-procedur för att anpassa hur innehållet ritas på exempelsidan.
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.
}
Följande exempel visar en PagePaintHook hook-procedur som ritar marginalrektangeln i exempelsidans område.
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;
}
Söka efter text
I det här avsnittet beskrivs exempelkod som visar och hanterar en dialogrutan Sök så att användaren kan ange parametrarna för en sökåtgärd. Dialogrutan skickar meddelanden till fönsterproceduren så att du kan utföra sökåtgärden.
Koden för att visa och hantera en dialogrutan Ersätt är liknande, förutom att den använder funktionen ReplaceText för att visa dialogrutan. Dialogrutan Ersätt skickar också meddelanden som svar på användarens klick på knapparna Ersätt och Ersätt alla.
Om du vill använda dialogrutan Hitta eller Ersätt måste du utföra tre separata uppgifter:
- Hämta en meddelandeidentifierare för det registrerade meddelandet FINDMSGSTRING.
- Visa dialogrutan.
- Bearbeta FINDMSGSTRING meddelanden när dialogrutan är öppen.
När du initierar programmet anropar du funktionen RegisterWindowMessage för att hämta en meddelandeidentifierare för FINDMSGSTRING- registrerat meddelande.
UINT uFindReplaceMsg; // message identifier for FINDMSGSTRING
uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);
För att visa en dialogruta för Sök, bör du först initiera en FINDREPLACE- struktur, och sedan anropa funktionen FindText. Observera att FINDREPLACE struktur och bufferten för söksträngen ska vara en global eller statisk variabel så att den inte hamnar utanför omfånget innan dialogrutan stängs. Du måste specificera fältet hwndOwner för att ange fönstret som tar emot de registrerade meddelandena. När du har skapat dialogrutan kan du flytta eller ändra den med hjälp av det returnerade handtaget.
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);
När dialogrutan är öppen måste huvudmeddelandeloopen innehålla ett anrop till funktionen IsDialogMessage. Skicka ett handtag till dialogrutan som en parameter i anropet IsDialogMessage. Detta säkerställer att dialogrutan bearbetar tangentbordsmeddelanden korrekt.
Om du vill övervaka meddelanden som skickas från dialogrutan måste fönsterproceduren söka efter FINDMSGSTRING- registrerat meddelande och bearbeta värdena som skickas i FINDREPLACE- struktur som i följande exempel.
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;
}