Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе рассматриваются задачи, которые вызывают общие диалоговые окна:
- Выбор цвета
- Выбор шрифта
- Открытие файла
- Отображение диалогового окна "Печать"
- Использование листа свойств печати
- Настройка печатной страницы
- Поиск текста
Выбор цвета
В этом разделе описывается пример кода, отображающий диалоговое окно "Цвет ", чтобы пользователь смог выбрать цвет. Пример кода сначала инициализирует структуру CHOOSECOLOR , а затем вызывает функцию ChooseColor для отображения диалогового окна. Если функция возвращает значение TRUE, указывающее, что пользователь выбрал цвет, пример кода использует выбранный цвет для создания новой сплошной кисти.
В этом примере используется структура CHOOSECOLOR для инициализации диалогового окна следующим образом:
- Инициализирует элемент lpCustColors указателем на статический массив значений. Цвета в массиве изначально черные, но статический массив сохраняет настраиваемые цвета, созданные пользователем для последующих вызовов ChooseColor .
- Задает флаг CC_RGBINIT и инициализирует элемент rgbResult , чтобы указать цвет, который изначально выбран при открытии диалогового окна. Если не указано, начальный выбор является черным. В примере используется статическая переменная rgbCurrent для сохранения выбранного значения между вызовами ChooseColor.
- Задает флаг CC_FULLOPEN , чтобы всегда отображалось расширение настраиваемых цветов диалогового окна.
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;
}
Выбор шрифта
В этом разделе описывается пример кода, отображающего диалоговое окно "Шрифт ", чтобы пользователь смог выбрать атрибуты шрифта. Пример кода сначала инициализирует структуру CHOOSEFONT , а затем вызывает функцию ChooseFont для отображения диалогового окна.
В этом примере устанавливается флаг CF_SCREENFONTS для указания того, что диалоговое окно должно отображать только экранные шрифты. Он задает флаг CF_EFFECTS для отображения элементов управления, позволяющих пользователю выбирать параметры зачеркивания, подчеркивания и цвета.
Если SelectFont возвращает значение TRUE, указывающее, что пользователь нажимал кнопку "ОК ", структура SELECTFONT содержит сведения, описывающие атрибуты шрифта и шрифта, выбранные пользователем, включая элементы структуры LOGFONT , на которые указывает элемент lpLogFont . Элемент rgbColors содержит выбранный цвет текста. В примере кода эти сведения используются для задания цвета шрифта и текста для контекста устройства, связанного с окном владельца.
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);
.
.
.
}
Открытие файла
Примечание.
Начиная с Windows Vista, диалоговое окно Общий файл было заменено на диалоговое окно Общего элемента для открытия файла. Рекомендуется использовать API общих диалоговых окон вместо API общих диалоговых окон. Дополнительные сведения см. в диалоговом окне общего элемента.
В этом разделе описывается пример кода, отображающий диалоговое окно "Открыть ", чтобы пользователь смог указать диск, каталог и имя открываемого файла. Пример кода сначала инициализирует структуру OPENFILENAME , а затем вызывает функцию GetOpenFileName для отображения диалогового окна.
В этом примере элемент lpstrFilter — это указатель на буфер, указывающий два фильтра имени файла, которые пользователь может выбрать, чтобы ограничить отображаемые имена файлов. Буфер содержит массив строк с двойным нулевым символом, в котором каждая пара строк задает фильтр. Член nFilterIndex указывает, что первый шаблон используется при создании диалогового окна.
В этом примере задаются флаги OFN_PATHMUSTEXIST и OFN_FILEMUSTEXIST в элементе Flags . Эти флаги вызывают проверку диалогового окна перед возвратом пути и имени файла, указанного пользователем.
Функция GetOpenFileName возвращает значение TRUE , если пользователь нажимает кнопку "ОК ", а указанный путь и имя файла существуют. В этом случае буфер, на который указывает элемент lpstrFile , содержит путь и имя файла. Пример кода использует эти сведения в вызове функции для открытия файла.
Хотя этот пример не задает флаг OFN_EXPLORER , он по-прежнему отображает диалоговое окно "Открыть в стиле обозревателя по умолчанию". Однако если вы хотите предоставить процедуру перехватчика или пользовательский шаблон, и вы хотите пользовательский интерфейс Обозревателя, необходимо задать флаг OFN_EXPLORER .
Примечание.
На языке программирования C строка, заключенная в кавычки, завершается значением NULL.
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);
Отображение диалогового окна "Печать"
В этом разделе описывается пример кода, отображающий диалоговое окно "Печать ", чтобы пользователь смог выбрать параметры печати документа. Пример кода сначала инициализирует структуру PRINTDLG , а затем вызывает функцию PrintDlg для отображения диалогового окна.
В этом примере задается флаг PD_RETURNDC в элементе Flags структуры PRINTDLG . Это приводит к тому, что PrintDlg возвращает дескриптор контекста устройства выбранному принтеру в элементе hDC . Вы можете использовать ручку для вывода данных на принтере.
При входе пример кода задает для элементов hDevMode и hDevNamesзначение NULL. Если функция возвращает TRUE, эти члены возвращают дескрипторы к структурам DEVNAMES, содержащим данные, введенные пользователем, и сведения о принтере. Эти сведения можно использовать для подготовки выходных данных для отправки на выбранный принтер.
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);
}
Использование листа свойств печати
В этом разделе описывается пример кода, отображающий лист свойств Print , чтобы пользователь смог выбрать параметры печати документа. Пример кода сначала инициализирует структуру PRINTDLGEX , а затем вызывает функцию PrintDlgEx для отображения листа свойств.
Пример кода задает флаг PD_RETURNDC в элементе Flags структуры PRINTDLG . Это приводит к тому, что функция PrintDlgEx возвращает дескриптор контекста устройства выбранному принтеру в элементе hDC .
При входе пример кода задает для элементов hDevMode и hDevNamesзначение NULL. Если функция возвращает S_OK, эти члены возвращают дескрипторы к структурам DEVNAMES, содержащим входные данные пользователя и информацию о принтере. Эти сведения можно использовать для подготовки выходных данных для отправки на выбранный принтер.
После завершения операции печати пример кода освобождает буферы DEVMODE, DEVNAMES и PRINTPAGERANGE и вызывает функцию DeleteDC для удаления контекста устройства.
// 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;
}
Настройка печатной страницы
В этом разделе описывается пример кода, отображающий диалоговое окно "Настройка страницы ", чтобы пользователь смог выбрать атрибуты печатной страницы, например тип бумаги, источник бумаги, ориентация страницы и поля страницы. Пример кода сначала инициализирует структуру PAGESETUPDLG , а затем вызывает функцию PageSetupDlg для отображения диалогового окна.
В этом примере устанавливается флаг PSD_MARGINS в элементе Flags и используется элемент rtMargin для указания начальных значений полей. Он задает флаг PSD_INTHOUSANDTHSOFINCHES , чтобы убедиться, что диалоговое окно выражает размеры полей в тысячах дюйма.
При входе пример кода задает для элементов hDevMode и hDevNamesзначение NULL. Если функция возвращает TRUE, она использует эти элементы для возвращения дескрипторов структур DEVNAMES, содержащих входные данные пользователя и сведения о принтере. Эти сведения можно использовать для подготовки выходных данных для отправки на выбранный принтер.
В следующем примере также используется процедура перехватчика PagePaintHook для кастомизации прорисовки содержимого примера страницы.
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.
}
В следующем примере показан пример процедуры перехватчика PagePaintHook , которая рисует прямоугольник поля в области страницы:
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;
}
Поиск текста
В этом разделе описывается пример кода, который отображает диалоговое окно "Поиск " и управляет ими, чтобы пользователь смог указать параметры операции поиска. Диалоговое окно отправляет сообщения в процедуру окна, чтобы вы могли выполнить операцию поиска.
Код для отображения диалогового окна "Замена " и управления ими аналогичен, за исключением того, что для отображения диалогового окна используется функция ReplaceText . Диалоговое окно "Замена" также отправляет сообщения в ответ на щелчки пользователя по кнопкам "Заменить" и "Заменить все".
Чтобы использовать диалоговое окно "Найти или заменить ", необходимо выполнить три отдельных задачи:
- Получите идентификатор сообщения для зарегистрированного сообщения FINDMSGSTRING .
- Отображение диалогового окна.
- Обработка сообщений FINDMSGSTRING при открытии диалогового окна.
При инициализации приложения вызовите функцию RegisterWindowMessage , чтобы получить идентификатор сообщения для зарегистрированного сообщения FINDMSGSTRING .
UINT uFindReplaceMsg; // message identifier for FINDMSGSTRING
uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);
Чтобы отобразить диалоговое окно "Поиск ", сначала инициализируйте структуру FINDREPLACE и вызовите функцию FindText . Обратите внимание, что структура FINDREPLACE и буфер строки поиска должны быть глобальной или статической переменной, чтобы она не выходила из области до закрытия диалогового окна. Необходимо задать элемент hwndOwner , чтобы указать окно, которое получает зарегистрированные сообщения. После того как вы создадите диалоговое окно, вы можете переместить его или управлять им с помощью возвращаемого дескриптора.
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);
При открытии диалогового окна основной цикл сообщений должен включать вызов функции IsDialogMessage . Передайте дескриптор окна диалога в качестве параметра в вызове IsDialogMessage. Это гарантирует, что диалоговое окно правильно обрабатывает сообщения клавиатуры.
Чтобы отслеживать сообщения, отправленные из диалогового окна, процедура окна должна проверить зарегистрированное сообщение FINDMSGSTRING и обработать значения, переданные в структуре FINDREPLACE , как показано в следующем примере.
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;
}