Книги, научные публикации Pages:     | 1 |   ...   | 10 | 11 | 12 |

Ч. Петзолд Программирование для Windowsо 95 в двух томах Том I BHV Ч Санкт-Петербург Дюссельдорф Киев Москва Санкт-Петербург Содержание ЧАСТЬ I ВВЕДЕНИЕ ...

-- [ Страница 12 ] --

//------------------------------------------------------------------- UINT CALLBACK ExStylePageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { switch(uMsg) { case PSPCB_CREATE :

// Store pointer to extended style data pTheExStyles =(LPDWORD) ppsp->lParam;

return TRUE;

case PSPCB_RELEASE :

break;

} return 0;

} //------------------------------------------------------------------- BOOL CALLBACK ExStyleDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG :

{ BOOL bCheck;

DWORD dwOrigStyle = *pTheExStyles;

bCheck =(dwOrigStyle & WS_EX_CLIENTEDGE);

SetButtonCheck(hwndDlg, IDC_CLIENTEDGE, bCheck);

bCheck =(dwOrigStyle & WS_EX_CONTEXTHELP);

SetButtonCheck(hwndDlg, IDC_CONTEXTHELP, bCheck);

bCheck =(dwOrigStyle & WS_EX_DLGMODALFRAME);

SetButtonCheck(hwndDlg, IDC_DLGMODALFRAME, bCheck);

bCheck =(dwOrigStyle & WS_EX_OVERLAPPEDWINDOW);

SetButtonCheck(hwndDlg, IDC_EXOVERLAPPED, bCheck);

bCheck =(dwOrigStyle & WS_EX_PALETTEWINDOW);

SetButtonCheck(hwndDlg, IDC_PALETTE, bCheck);

bCheck =(dwOrigStyle & WS_EX_STATICEDGE);

SetButtonCheck(hwndDlg, IDC_STATICEDGE, bCheck);

bCheck =(dwOrigStyle & WS_EX_TOOLWINDOW);

SetButtonCheck(hwndDlg, IDC_TOOLWINDOW, bCheck);

bCheck =(dwOrigStyle & WS_EX_WINDOWEDGE);

SetButtonCheck(hwndDlg, IDC_WINDOWEDGE, bCheck);

bCheck =(dwOrigStyle & WS_EX_ACCEPTFILES);

SetButtonCheck(hwndDlg, IDC_ACCEPTFILES, bCheck);

bCheck =(dwOrigStyle & WS_EX_APPWINDOW);

SetButtonCheck(hwndDlg, IDC_APPWINDOW, bCheck);

bCheck =(dwOrigStyle & WS_EX_TOPMOST);

SetButtonCheck(hwndDlg, IDC_TOPMOST, bCheck);

bCheck =(dwOrigStyle & WS_EX_TRANSPARENT);

SetButtonCheck(hwndDlg, IDC_TRANSPARENT, bCheck);

bCheck =(dwOrigStyle & WS_EX_CONTROLPARENT);

SetButtonCheck(hwndDlg, IDC_CONTROLPARENT, bCheck);

bCheck =(dwOrigStyle & WS_EX_MDICHILD);

SetButtonCheck(hwndDlg, IDC_MDICHILD, bCheck);

bCheck =(dwOrigStyle & WS_EX_NOPARENTNOTIFY);

SetButtonCheck(hwndDlg, IDC_NOPARENTNOTIFY, bCheck);

return TRUE;

} case WM_COMMAND :

{ WORD wNotifyCode = HIWORD(wParam);

WORD wID = LOWORD(wParam);

HWND hwndSheet;

switch(wID) { case IDC_CLIENTEDGE :

case IDC_CONTEXTHELP :

case IDC_DLGMODALFRAME :

case IDC_EXOVERLAPPED :

case IDC_PALETTE :

case IDC_STATICEDGE :

case IDC_TOOLWINDOW :

case IDC_WINDOWEDGE :

case IDC_ACCEPTFILES :

case IDC_APPWINDOW :

case IDC_TOPMOST :

case IDC_TRANSPARENT :

case IDC_CONTROLPARENT :

case IDC_MDICHILD :

case IDC_NOPARENTNOTIFY :

hwndSheet = GetParent(hwndDlg);

PropSheet_Changed(hwndSheet, hwndDlg);

break;

} return TRUE;

} case WM_HELP :

// Catch F1 key strike MessageBox(hwndDlg, "WM_HELP Message Received", "ExStyleDlgProc", MB_OK);

return TRUE;

case WM_NOTIFY :

{ LPNMHDR pnmh =(LPNMHDR) lParam;

// Handle Finish button on wizard page if(pnmh->code == PSN_WIZFINISH) { HWND hwndPS;

hwndPS = GetParent(hwndDlg);

PropSheet_Apply(hwndPS);

return TRUE;

} // Handle OK and Apply buttons if(pnmh->code == PSN_APPLY || pnmh->code == PSN_RESET) { HWND hwndPS;

HWND hwndActive;

// Overwrite current style value *pTheExStyles = FetchExStyles(hwndDlg);

// Tell main window to re-create child window hwndPS = GetParent(hwndDlg);

hwndActive = PropSheet_GetCurrentPageHwnd(hwndPS);

// Only re-create if we're the active page if(hwndDlg == hwndActive) PostMessage(hwndMain, PM_CREATEWINDOW, 0, 0L);

} // Destroy modeless dialog on OK or Cancel if((IsWindowEnabled(hwndMain)) && (pnmh->code == PSN_APPLY || pnmh->code == PSN_RESET)) { LPPSHNOTIFY psh =(LPPSHNOTIFY) lParam;

HWND hwndPropSheet;

// Ignore Apply button if(pnmh->code == PSN_APPLY && psh->lParam == 0) return TRUE;

// Clicking OK or Cancel, destroy property sheet hwndPropSheet = GetParent(hwndDlg);

DestroyWindow(hwndPropSheet);

hwndModeless = NULL;

} // Enable Back and Finish buttons on wizard page if(bWizard && pnmh->code == PSN_SETACTIVE) { HWND hwndSheet = GetParent(hwndDlg);

PropSheet_SetWizButtons(hwndSheet, PSWIZB_BACK | PSWIZB_FINISH);

} // Support for Help button if(pnmh->code == PSN_HELP) { MessageBox(hwndDlg, "PSN_HELP Notification Received", "ExStyleDlgProc", MB_OK);

} return TRUE;

} default :

return FALSE;

} } //------------------------------------------------------------------- DWORD FetchExStyles(HWND hwndDlg) { DWORD dwStyle = 0L;

if(QueryButtonCheck(hwndDlg, IDC_CLIENTEDGE)) { dwStyle |= WS_EX_CLIENTEDGE;

} if(QueryButtonCheck(hwndDlg, IDC_CONTEXTHELP)) { dwStyle |= WS_EX_CONTEXTHELP;

} if(QueryButtonCheck(hwndDlg, IDC_DLGMODALFRAME)) { dwStyle |= WS_EX_DLGMODALFRAME;

} if(QueryButtonCheck(hwndDlg, IDC_EXOVERLAPPED)) { dwStyle |= WS_EX_OVERLAPPEDWINDOW;

} if(QueryButtonCheck(hwndDlg, IDC_PALETTE)) { dwStyle |= WS_EX_PALETTEWINDOW;

} if(QueryButtonCheck(hwndDlg, IDC_STATICEDGE)) { dwStyle |= WS_EX_STATICEDGE;

} if(QueryButtonCheck(hwndDlg, IDC_TOOLWINDOW)) { dwStyle |= WS_EX_TOOLWINDOW;

} if(QueryButtonCheck(hwndDlg, IDC_WINDOWEDGE)) { dwStyle |= WS_EX_WINDOWEDGE;

} if(QueryButtonCheck(hwndDlg, IDC_ACCEPTFILES)) { dwStyle |= WS_EX_ACCEPTFILES;

} if(QueryButtonCheck(hwndDlg, IDC_APPWINDOW)) { dwStyle |= WS_EX_APPWINDOW;

} if(QueryButtonCheck(hwndDlg, IDC_TOPMOST)) { dwStyle |= WS_EX_TOPMOST;

} if(QueryButtonCheck(hwndDlg, IDC_TRANSPARENT)) { dwStyle |= WS_EX_TRANSPARENT;

} if(QueryButtonCheck(hwndDlg, IDC_CONTROLPARENT)) { dwStyle |= WS_EX_CONTROLPARENT;

} if(QueryButtonCheck(hwndDlg, IDC_MDICHILD)) { dwStyle |= WS_EX_MDICHILD;

} if(QueryButtonCheck(hwndDlg, IDC_NOPARENTNOTIFY)) { dwStyle |= WS_EX_NOPARENTNOTIFY;

} return dwStyle;

} HELPER.C /*-------------------------------- HELPER.C -- Helper routines (c) Paul Yao, --------------------------------*/ #include #include #include #include "property.h" //------------------------------------------------------------------- void SetButtonCheck(HWND hwndDlg, int CtrlID, BOOL bCheck) { HWND hwndCtrl = GetDlgItem(hwndDlg, CtrlID);

if(bCheck) { Button_SetCheck(hwndCtrl, BST_CHECKED);

} } //------------------------------------------------------------------- BOOL QueryButtonCheck(HWND hwndDlg, int CtrlID) { HWND hwndCtrl = GetDlgItem(hwndDlg, CtrlID);

int nCheck = Button_GetCheck(hwndCtrl);

return(nCheck == BST_CHECKED);

} PROPERTY.RC #include "property.h" #include IDI_APP ICON DISCARDABLE "PROPERTY.ICO" IDI_PAGE1 ICON DISCARDABLE "page1.ico" IDI_PAGE2 ICON DISCARDABLE "page2.ico" MAIN MENU DISCARDABLE { POPUP "&Property-Sheet-Styles" { MENUITEM "PSH_WIZARD", IDM_WIZARD MENUITEM SEPARATOR MENUITEM "PSH_HASHELP", IDM_HASHELP MENUITEM "PSH_MODELESS", IDM_MODELESS MENUITEM "PSH_NOAPPLYNOW", IDM_NOAPPLYNOW MENUITEM "PSH_PROPTITLE", IDM_PROPTITLE MENUITEM "PSH_RTLREADING", IDM_RTLREADING } POPUP "&Window" { MENUITEM "Properties", IDM_WINDOW_PROPERTIES } } IDD_STYLES DIALOG DISCARDABLE 0, 0, 292, STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Window Styles" FONT 8, "MS Sans Serif" { GROUPBOX "&Initial State",IDC_STATIC,7,7,94, CONTROL "WS_VISIBLE",IDC_VISIBLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,21,55, CONTROL "WS_DISABLED",IDC_DISABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,35,64, CONTROL "WS_MINIMIZE",IDC_MINIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,49,60, CONTROL "WS_MAXIMIZE",IDC_MAXIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,63,62, GROUPBOX "&Clipping",IDC_STATIC,7,80,94, CONTROL "WS_CLIPCHILDREN",IDC_CLIPCHILDREN,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,94,79, CONTROL "WS_CLIPSIBLINGS",IDC_CLIPSIBLINGS,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,108,75, GROUPBOX "&Window Components",IDC_STATIC,115,7,170, CONTROL "WS_BORDER",IDC_BORDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,21,60, CONTROL "WS_CAPTION",IDC_CAPTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,35,60, CONTROL "WS_DLGFRAME",IDC_DLGFRAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,49,68, CONTROL "WS_HSCROLL",IDC_HSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,63,71, CONTROL "WS_MAXIMIZEBOX",IDC_MAXIMIZEBOX,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,123,77,93, CONTROL "WS_MINIMIZEBOX",IDC_MINIMIZEBOX,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,123,91,90, CONTROL "WS_SYSMENU",IDC_SYSMENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,21,72, CONTROL "WS_THICKFRAME",IDC_THICKFRAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,35,77, CONTROL "WS_VSCROLL",IDC_VSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,49,74, } IDD_EXSTYLES DIALOG DISCARDABLE 0, 0, 330, STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Extended Window Styles" FONT 8, "MS Sans Serif" { GROUPBOX "&Non-Client Area",IDC_STATIC,7,7,263, CONTROL "WS_EX_CLIENTEDGE",IDC_CLIENTEDGE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,21,113, CONTROL "WS_EX_CONTEXTHELP",IDC_CONTEXTHELP,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,35,116, CONTROL "WS_EX_DLGMODALFRAME",IDC_DLGMODALFRAME,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,49,121, CONTROL "WS_EX_OVERLAPPEDWINDOW",IDC_EXOVERLAPPED,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,63,127, CONTROL "WS_EX_PALETTEWINDOW",IDC_PALETTE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,149,21,113, CONTROL "WS_EX_STATICEDGE",IDC_STATICEDGE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,149,35,102, CONTROL "WS_EX_TOOLWINDOW",IDC_TOOLWINDOW,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,149,49,101, CONTROL "WS_EX_WINDOWEDGE",IDC_WINDOWEDGE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,149,63,102, GROUPBOX "&Shell Interface",IDC_STATIC,8,80,214, CONTROL "WS_EX_ACCEPTFILES",IDC_ACCEPTFILES,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,90,97, CONTROL "WS_EX_APPWINDOW",IDC_APPWINDOW,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,104,96, CONTROL "WS_EX_TOPMOST",IDC_TOPMOST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,90,88, CONTROL "WS_EX_TRANSPARENT",IDC_TRANSPARENT,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,118,104,102, GROUPBOX "&Child Window",IDC_STATIC,7,121,316, CONTROL "WS_EX_CONTROLPARENT",IDC_CONTROLPARENT,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,14,135,105, CONTROL "WS_EX_MDICHILD",IDC_MDICHILD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,124,135,77, CONTROL "WS_EX_NOPARENTNOTIFY",IDC_NOPARENTNOTIFY,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,206,135,111, } PAGE1.ICO PAGE2.ICO PROPERTY.ICO Рис. 12.13 Исходный текст программы PROPERTY В ответ на сообщение WM_CREATE главное окно программы PROPERTY создает два дочерних окна. Первое окно с заголовком "First Window" представляет для нас основной интерес. Это окно изменяет размеры при изменении размеров родительского окна с тем, чтобы занимать 1/9 от размера его рабочей области. При изменении флагов стиля окна, родительское окно получает частное сообщение PM_CREATEWINDOW, в ответ на которое родительское окно уничтожает открытое дочернее окно, создает новое дочернее окно с указанными стилями, а затем посылает самому себе сообщение WM_SIZE для форсирования изменения размеров дочернего окна.

Флаги стиля для создания дочернего окна запоминаются в двух глобальных переменных, определенных в файле PROPERTY.C:

DWORD dwChildStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CAPTION;

DWORD dwChildExStyle = 0L;

Указатели на каждую из этих переменных передаются каждой странице свойств в поле lParam структуры PRPSHEETPAGE. Например, ниже показано, как dwChildStyle передается первой странице свойств (см. файл SHEET.C):

pspage[0].lParam =(LPARAM) &dwChildStyle;

Первая страница свойств извлекает это значение в своей оконной процедуре (StylePageProc). Расположенная в файле PAGE1.C, эта функция вызывается непосредственно перед созданием страницы свойств с кодом сообщения PSPCB_CREATE. Этот указатель запоминается в глобальной переменной, объявленной как static, и поэтому, имеющей область видимости, ограниченную этим исходным файлом:

// Сохранить указатель на данные о стиле pTheStyles =(LPDWORD) ppsp->lParam;

Здесь ppsp Ч указатель на структуру страницы свойств PROPSHEETPAGE, переданную в функцию страницы свойств.

Каждая страница свойств имеет указатель на данные, которые могут быть изменены в ней. Поэтому, когда становится необходимым применить сделанные изменения, каждая диалоговая процедура страницы свойств записывает эти изменения обратно в источник данных. Кажется, что было бы проще использовать глобальные переменные. Это общая практика при работе с обычными диалоговыми окнами. Но мы используем параметр lParam для того, чтобы показать, как "удаленная" страница свойств Ч такая как расположенная в динамически подключаемой библиотеке Ч может быть инициализирована без использования чего-либо кроме содержимого структуры PROPSHEETPAGE.

Внутри диалоговых процедур страниц свойств наиболее интересным является обработка сообщения WM_NOTIFY. При нажатии кнопок OK или Apply диалоговые процедуры получают уведомление PSN_APPLY. Как уже упоминалось ранее, страницы свойств создаются по мере их активизации пользователем. Только страницы, которые были реально созданы, получают уведомления. Это означает, что когда набор страниц свойств уничтожается, только одна или обе диалоговые процедуры могут получить уведомление PSN_APPLY.

Для того, чтобы быть уверенным в том, что изменения данных будут применены только один раз, каждая диалоговая процедура проверяет, являлась ли ее страница активной перед посылкой запроса PM_CREATEWINDOW главному окну программы. Это делается с помощью посылки сообщения PSM_GETCURRENTPAGEHWND окну набора страниц свойств, в ответ на которое возвращается описатель окна активной страницы. Запрос на воссоздание дочернего окна посылается функцией PostMessage с целью избежать временных проблем при посылке сообщения из диалоговой процедуры активной страницы:

HWND hwndPS = GetParent(hwndDlg);

HWND hwndActive = PropSheet_GetCurrentPageHwnd(hwndPS);

// Только для активной страницы if(hwndDlg == hwndActive) PostMessage(hwndMain, PM_CREATEWINDOW, 0, 0L);

Программа PROPERTY показывает, что все, что вы знаете о работе с диалоговыми окнами применимо к наборам страниц свойств. Имеется несколько различий, связанных с большей сложностью. Это касается мастеров, немодальных наборов страниц свойств и использования различных наборов кнопок.

Pages:     | 1 |   ...   | 10 | 11 | 12 |    Книги, научные публикации