Исходные тексты приложения Property Sheet Demo
Функции приложения Property Sheet Demo определены в файле psheet.c (листинг 6.1).
Листинг 6.1. Файл psheet\psheet.c
#define STRICT #include <windows.h> #include <windowsx.h> #include <commctrl.h> #include "resource.h" #include "afxres.h" #include "psheet.h"
// Структура, в которой хранятся параметры typedef struct { int nBold; int nItalic; int nUnderline; int nUseTabs; char szKeyWord[80]; } OPTIONS;
OPTIONS opt;
// Массив описаний страниц блокнота PROPSHEETPAGE psheetPage[3];
// Заголовок блокнота PROPSHEETHEADER psheetHeader;
// Идентификаторы страниц блокнота HPROPSHEETPAGE hPage[3];
HINSTANCE hInst; char szAppName[] = "PropSheetApp"; char szAppTitle[] = "Property Sheet Demo";
// ----------------------------------------------------- // Функция WinMain // ----------------------------------------------------- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hWnd; MSG msg;
hInst = hInstance;
// Преверяем, не было ли это приложение запущено ранее hWnd = FindWindow(szAppName, NULL); if(hWnd) { if(IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE); SetForegroundWindow(hWnd); return FALSE; }
// Регистрируем класс окна memset(&wc, 0, sizeof(wc)); wc.cbSize = sizeof(WNDCLASSEX); wc.hIconSm = LoadImage(hInst, MAKEINTRESOURCE(IDI_APPICONSM), IMAGE_ICON, 16, 16, 0); wc.style = 0; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 32, 32, 0); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU); wc.lpszClassName = szAppName; if(!RegisterClassEx(&wc)) if(!RegisterClass((LPWNDCLASS)&wc.style)) return FALSE;
// Создаем главное окно приложения hWnd = CreateWindow(szAppName, szAppTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL); if(!hWnd) return(FALSE);
// Отображаем окно и запускаем цикл обработки сообщений ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while(GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
// ----------------------------------------------------- // Функция WndProc // ----------------------------------------------------- LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hWnd, WM_CREATE, WndProc_OnCreate); HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy); HANDLE_MSG(hWnd, WM_COMMAND, WndProc_OnCommand);
default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } }
// ----------------------------------------------------- // Функция WndProc_OnCreate // ----------------------------------------------------- BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) { // Инициализируем библиотеку стандартных органов управления InitCommonControls();
// Инициализируем параметры opt.nBold = opt.nItalic = opt.nUnderline = opt.nUseTabs = 0; strcpy(opt.szKeyWord, "Undef");
return TRUE; }
// ----------------------------------------------------- // Функция WndProc_OnDestroy // ----------------------------------------------------- #pragma warning(disable: 4098) void WndProc_OnDestroy(HWND hWnd) { PostQuitMessage(0); return 0L; }
// ----------------------------------------------------- // Функция WndProc_OnCommand // ----------------------------------------------------- #pragma warning(disable: 4098) void WndProc_OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case ID_FILE_EXIT: PostQuitMessage(0); // завершаем работу приложения return 0L; break;
case ID_HELP_ABOUT: MessageBox(hWnd, "Property Sheet Demo Application, v.1.0\n" "(C) Alexandr Frolov, 1995\n" "Email: frolov@glas.apc.org", szAppTitle, MB_OK | MB_ICONINFORMATION); return 0L; break;
case ID_FILE_OPTIONS: { // Инициализируем страницы блокнота psheetPage[0].dwSize = sizeof(PROPSHEETPAGE); psheetPage[0].hInstance = hInst; psheetPage[0].pszIcon = MAKEINTRESOURCE(IDI_EFFECTS); psheetPage[0].dwFlags = PSP_USETITLE | PSP_USEICONID; psheetPage[0].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG1); psheetPage[0].pfnDlgProc = DlgProc1; psheetPage[0].pszTitle = "Set Effects"; psheetPage[0].lParam = 0;
// Добавляем страницу в блокнот, сохраняя ее // идентификатор в массиве hPage hPage[0] = CreatePropertySheetPage(&psheetPage[0]);
psheetPage[1].dwSize = sizeof(PROPSHEETPAGE); psheetPage[1].hInstance = hInst; psheetPage[1].pszIcon = MAKEINTRESOURCE(IDI_TAB); psheetPage[1].dwFlags = PSP_USETITLE | PSP_USEICONID; psheetPage[1].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG2); psheetPage[1].pfnDlgProc = DlgProc2; psheetPage[1].pszTitle = "Using Tabs"; psheetPage[1].lParam = 0; hPage[1] = CreatePropertySheetPage(&psheetPage[1]);
psheetPage[2].dwSize = sizeof(PROPSHEETPAGE); psheetPage[2].hInstance = hInst; psheetPage[2].pszIcon = MAKEINTRESOURCE(IDI_KEYWORD); psheetPage[2].dwFlags = PSP_USETITLE | PSP_USEICONID; psheetPage[2].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG3); psheetPage[2].pfnDlgProc = DlgProc3; psheetPage[2].pszTitle = "Keyword"; psheetPage[2].lParam = 0; hPage[2] = CreatePropertySheetPage(&psheetPage[2]);
// Инициализируем заголовок блокнота psheetHeader.dwSize = sizeof(PROPSHEETHEADER); psheetHeader.hInstance = hInst; psheetHeader.pszIcon = MAKEINTRESOURCE(IDI_APPICONSM); psheetHeader.dwFlags = PSH_USEICONID; psheetHeader.hwndParent = hWnd; psheetHeader.pszCaption = "Property Sheet Sample"; psheetHeader.nPages = sizeof(psheetPage) / sizeof(PROPSHEETPAGE); psheetHeader.phpage = (HPROPSHEETPAGE FAR *)&hPage[0];
// Создаем и отображаем блокнот PropertySheet(&psheetHeader);
return 0L; break; } default: break; } return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify, DefWindowProc); }
// ----------------------------------------------------- // Функция DlgProc1 // для первой страницы блокнота // ----------------------------------------------------- BOOL APIENTRY DlgProc1( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc1_OnInitDialog); HANDLE_MSG(hdlg, WM_COMMAND, DlgProc1_OnCommand); HANDLE_MSG(hdlg, WM_NOTIFY, DlgProc1_OnNotify); default: break; } return FALSE; }
// ----------------------------------------------------- // Функция DlgProc1_OnInitDialog // Вызывается при инициализации первой страницы блокнота // ----------------------------------------------------- BOOL DlgProc1_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam) { // Устанавливаем переключатели в соответствии // со значениями параметров, записанных в // структуре opt SendMessage(GetDlgItem(hdlg, IDC_BOLD), BM_SETCHECK, opt.nBold, 0L);
SendMessage(GetDlgItem(hdlg, IDC_ITALIC), BM_SETCHECK, opt.nItalic, 0L);
SendMessage(GetDlgItem(hdlg, IDC_UNDERLINE), BM_SETCHECK, opt.nUnderline, 0L); return TRUE; }
// ----------------------------------------------------- // Функция DlgProc1_OnNotify // Обрабатывает извещение от первой страницы блокнота // ----------------------------------------------------- LRESULT DlgProc1_OnNotify(HWND hdlg, int idFrom, NMHDR* pnmhdr) { switch(pnmhdr->code) { // Когда пользователь нажимает кнопку OK, получаем // состояние переключателей, расположенных в первой // странице блокнота, и сохраняем это состояние в // соответствующих полях структуры opt case PSN_APPLY: { opt.nBold = (int)SendMessage( GetDlgItem(hdlg, IDC_BOLD), BM_GETCHECK, 0L, 0L);
opt.nItalic = (int)SendMessage( GetDlgItem(hdlg, IDC_ITALIC), BM_GETCHECK, 0L, 0L);
opt.nUnderline = (int)SendMessage( GetDlgItem(hdlg, IDC_UNDERLINE), BM_GETCHECK, 0L, 0L); break; } default: break; } return FALSE; }
// ----------------------------------------------------- // Функция DlgProc1_OnCommand // ----------------------------------------------------- #pragma warning(disable: 4098) void DlgProc1_OnCommand(HWND hdlg, int id, HWND hwndCtl, UINT codeNotify) { // Разблокируем кнопку "Apply" PropSheet_Changed(GetParent(hdlg), hdlg); return NULL; }
// ----------------------------------------------------- // Функция DlgProc2 // для второй страницы блокнота // ----------------------------------------------------- BOOL APIENTRY DlgProc2(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc2_OnInitDialog); HANDLE_MSG(hdlg, WM_NOTIFY, DlgProc2_OnNotify); default: break; } return FALSE; }
// ----------------------------------------------------- // Функция DlgProc2_OnInitDialog // Вызывается при инициализации второй страницы блокнота // ----------------------------------------------------- BOOL DlgProc2_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam) { SendMessage(GetDlgItem(hdlg, IDC_USETABS), BM_SETCHECK, opt.nUseTabs, 0L);
SendMessage(GetDlgItem(hdlg, IDC_DONTUSETABS), BM_SETCHECK, (opt.nUseTabs) ? 0 : 1, 0L);
return TRUE; }
// ----------------------------------------------------- // Функция DlgProc2_OnNotify // Обрабатывает извещение от второй страницы блокнота // ----------------------------------------------------- LRESULT DlgProc2_OnNotify(HWND hdlg, int idFrom, NMHDR* pnmhdr) { switch(pnmhdr->code) { case PSN_SETACTIVE: { // Разблокируем кнопку Apply, когда страница // блокнота становится активной PropSheet_Changed(GetParent(hdlg), hdlg); break; }
case PSN_KILLACTIVE: { // Блокируем кнопку Apply, когда страница // блокнота становится неактивной PropSheet_UnChanged(GetParent(hdlg), hdlg); break; }
case PSN_APPLY: { opt.nUseTabs = (int)SendMessage( GetDlgItem(hdlg, IDC_USETABS), BM_GETCHECK, 0L, 0L); break; } default: break; } return FALSE; }
// ----------------------------------------------------- // Функция DlgProc3 // для третьей страницы блокнота // ----------------------------------------------------- BOOL APIENTRY DlgProc3(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc3_OnInitDialog); HANDLE_MSG(hdlg, WM_NOTIFY, DlgProc3_OnNotify); HANDLE_MSG(hdlg, WM_COMMAND, DlgProc3_OnCommand); default: break; } return FALSE; }
// ----------------------------------------------------- // Функция DlgProc3_OnInitDialog // Вызывается при инициализации третьей страницы блокнота // ----------------------------------------------------- BOOL DlgProc3_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam) { SetWindowText(GetDlgItem(hdlg, IDC_EDITKEYWORD), opt.szKeyWord);
return TRUE; }
// ----------------------------------------------------- // Функция DlgProc3_OnNotify // Обрабатывает извещение от третьей страницы блокнота // ----------------------------------------------------- LRESULT DlgProc3_OnNotify(HWND hdlg, int idFrom, NMHDR* pnmhdr) { switch(pnmhdr->code) { // Выполняем проверку длины ключевого слова, // которое не должно быть длиннее 8 символов case PSN_KILLACTIVE: { char szTempBuf[80];
// Получаем новое ключевое слово во временный буфер GetWindowText(GetDlgItem(hdlg, IDC_EDITKEYWORD), szTempBuf, 80);
// Проверяем его длину if(lstrlen(szTempBuf) > 8) { // Если длина больше 8 символов, выводим // предупреждающее сообщение MessageBox(NULL, "Too long keyword, " "must be shorter than 8 characters", szAppName, MB_OK | MB_ICONEXCLAMATION);
// Отменяем закрытие страницы блокнота SetWindowLong(hdlg, DWL_MSGRESULT, TRUE);
// Отменяем обновление параметров return TRUE; } else { // Если длина сообщения правильная, разрешаем // закрытие страницы блокнота и // обновление параметров SetWindowLong(hdlg, DWL_MSGRESULT, FALSE); return FALSE; } break; }
case PSN_APPLY: { GetWindowText(GetDlgItem(hdlg, IDC_EDITKEYWORD), opt.szKeyWord, 80); break; } default: break; } return FALSE; }
// ----------------------------------------------------- // Функция DlgProc3_OnCommand // ----------------------------------------------------- #pragma warning(disable: 4098) void DlgProc3_OnCommand(HWND hdlg, int id, HWND hwndCtl, UINT codeNotify) { // Сообщение от редактора текста if(id == IDC_EDITKEYWORD) { // Если пользователь изменил ключевое слово в окне // редактирования, разблокируем кнопку "Apply" if(codeNotify == EN_CHANGE) { PropSheet_Changed(GetParent(hdlg), hdlg); } } return FALSE; }
В файле psheet.h (листинг 6.2) находятся описания функций, определенных в приложении Property Sheet Demo.
Листинг 6.2. Файл psheet\psheet.h
// ----------------------------------------------------- // Описание функций // ----------------------------------------------------- LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct); void WndProc_OnDestroy(HWND hWnd); void WndProc_OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify); LRESULT WndProc_OnNotify(HWND hWnd, int idFrom, NMHDR FAR * pnmhdr); BOOL APIENTRY DlgProc1(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL DlgProc1_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
LRESULT DlgProc1_OnNotify( HWND hWnd, int idFrom, NMHDR* pnmhdr); void DlgProc1_OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify); BOOL APIENTRY DlgProc2(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL DlgProc2_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam); LRESULT DlgProc2_OnNotify(HWND hWnd, int idFrom, NMHDR* pnmhdr); BOOL APIENTRY DlgProc3(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL DlgProc3_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam); LRESULT DlgProc3_OnNotify(HWND hWnd, int idFrom, NMHDR* pnmhdr); void DlgProc3_OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify);
В файле resource.h (создается автоматически системой Microsoft Visual C++) находятся определения констант для работы с ресурсами приложения Property Sheet Demo. Этот файл представлен в листинге 6.3.
Листинг 6.3. Файл psheet\resource.h
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by PSHEET.RC // #define IDR_APPMENU 102 #define IDI_APPICON 103 #define IDI_APPICONSM 104 #define IDI_EFFECTS 105 #define IDI_TAB 106 #define IDI_KEYWORD 107 #define IDD_DIALOG1 121 #define IDD_DIALOG2 122 #define IDD_DIALOG3 123 #define IDC_BOLD 1000 #define IDC_ITALIC 1001 #define IDC_UNDERLINE 1002 #define IDC_USETABS 1004 #define IDC_EDITKEYWORD 1006 #define IDC_DONTUSETABS 1007 #define ID_FILE_EXIT 40001 #define ID_HELP_ABOUT 40003 #define ID_FILE_OPTIONS 40029
// Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 125 #define _APS_NEXT_COMMAND_VALUE 40030 #define _APS_NEXT_CONTROL_VALUE 1008 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
Файл psheet.rc (листинг 6.4) содержит определение ресурсов приложения Property Sheet Demo. Он создается автоматически.
Листинг 6.4. Файл psheet\psheet.rc
//Microsoft Visual C++ generated resource script. // #include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS ////////////////////////////////////////////////////////////// // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h"
////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS
////////////////////////////////////////////////////////////// // Menu //
IDR_APPMENU MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&Options...", ID_FILE_OPTIONS MENUITEM SEPARATOR MENUITEM "E&xit", ID_FILE_EXIT END POPUP "&Help" BEGIN MENUITEM "&About...", ID_HELP_ABOUT END END
#ifdef APSTUDIO_INVOKED ////////////////////////////////////////////////////////////// // TEXTINCLUDE //
1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END
2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END
3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END
////////////////////////////////////////////////////////////// #endif // APSTUDIO_INVOKED
////////////////////////////////////////////////////////////// // Icon //
IDI_APPICON ICON DISCARDABLE "psheet.ico" IDI_APPICONSM ICON DISCARDABLE "psheetsm.ico" IDI_EFFECTS ICON DISCARDABLE "EFFECTS.ICO" IDI_TAB ICON DISCARDABLE "TAB.ICO" IDI_KEYWORD ICON DISCARDABLE "KEYWORD.ICO"
////////////////////////////////////////////////////////////// // Dialog //
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU FONT 8, "MS Sans Serif" BEGIN CONTROL "Bold",IDC_BOLD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,17,23,35,10 CONTROL "Italic",IDC_ITALIC,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,17,34,35,10 CONTROL "Underline",IDC_UNDERLINE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,17,45,46,10 GROUPBOX "Effects",IDC_STATIC,6,9,112,53 END
IDD_DIALOG2 DIALOG DISCARDABLE 0, 0, 186, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU FONT 8, "MS Sans Serif" BEGIN CONTROL "Use Tabs", IDC_USETABS, "Button", BS_AUTORADIOBUTTON,18,22, 63,10 GROUPBOX "Tabs",IDC_STATIC,9,7,105,63 CONTROL "Don't use Tabs",IDC_DONTUSETABS,"Button", BS_AUTORADIOBUTTON,18,35,83,10 END
IDD_DIALOG3 DIALOG DISCARDABLE 0, 0, 211, 102 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU FONT 8, "MS Sans Serif" BEGIN EDITTEXT IDC_EDITKEYWORD,22,35,138,13,ES_AUTOHSCROLL GROUPBOX "Keyword",IDC_STATIC,9,15,166,52 END
////////////////////////////////////////////////////////////// // String Table //
STRINGTABLE DISCARDABLE BEGIN ID_FILE_EXIT "Quits the application" END
#ifndef APSTUDIO_INVOKED ////////////////////////////////////////////////////////////// // Generated from the TEXTINCLUDE 3 resource. ////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED