Операционная система Windows 95 для программиста© Александр Фролов, Григорий ФроловТом 22, М.: Диалог-МИФИ, 1993, 271 стр. 7.7. Приложение UpDownНесложное приложение UpDown демонстрирует, как это нетрудно догадаться из его названия, работу органа управления Up-Down. Дополнительно в этом приложении мы создаем комбинацию клавиш активизации, работаем с сообщением WM_SETHOTKEY и органом управления Hot Key. Если выбрать строку Options из главного меню приложения File, на экране появится диалоговая панель Value Selection, показанная на рис. 7.9.
Рис. 7.9. Диалоговая панель Value Selection В этой панели вы можете задать с помощью органа управления Up-Down некоторое значение, и посмотреть результат, нажав кнопку OK. В процессе инициализации своего главного окна приложение определяет комбинацию клавиш активизации <Ctrl + Alt + V>. Если нажать эту комбинацию клавиш, появится все та же диалоговая панель. Для изменения комбинации клавиш активизации вы можете передать фокус ввода органу управления Hot Key, нажать новую комбинацию клавиш и затем нажать кнопку Set HotKey. После этого новая комбинация клавиш может быть использована для активизации диалоговой панели Value Selection. Исходные тексты приложения UpDownИсходные тексты всех функций приложения UpDown собраны в файле updown.c (листинг 7.6). Листинг 7.6. Файл updown\updown.c #define STRICT #include <windows.h> #include <windowsx.h> #include <commctrl.h> #include "resource.h" #include "afxres.h" #include "updown.h" HINSTANCE hInst; char szAppName[] = "UpDownApp"; char szAppTitle[] = "Up-Down and HotKey Demo"; HWND hwndEdit; HWND hwndUpDown; HWND hwndMainWindow; HWND hwndHotKey; WORD wHotKey; // ----------------------------------------------------- // Функция 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); // Сохраняем идентификатор главного окна hwndMainWindow = hWnd; // Отображаем окно и запускаем цикл обработки сообщений 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); HANDLE_MSG(hWnd, WM_SYSCOMMAND, WndProc_OnSysCommand); default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } } // ----------------------------------------------------- // Функция WndProc_OnCreate // ----------------------------------------------------- BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) { // Инициализируем библиотеку стандартных органов управления InitCommonControls(); // Устанавливаем комбинацию клавиш активизации // диалоговой панели <Alt+Ctrl+V> SendMessage(hWnd, WM_SETHOTKEY, (WPARAM)MAKEWORD('V', HOTKEYF_ALT | HOTKEYF_CONTROL), 0); 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, "Up-Down and HotKey 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: { DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc); return 0L; break; } default: break; } return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify, DefWindowProc); } // ----------------------------------------------------- // Функция DlgProc // ----------------------------------------------------- BOOL APIENTRY DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc_OnInitDialog); HANDLE_MSG(hdlg, WM_COMMAND, DlgProc_OnCommand); default: break; } return FALSE; } // ----------------------------------------------------- // Функция DlgProc_OnInitDialog // Вызывается при инициализации первой страницы // ----------------------------------------------------- BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam) { // Получаем идентификатор редактора текста hwndEdit = GetDlgItem(hdlg, IDC_EDIT1); // Создаем орган управления Up-Down и подключаем // его к редактору текста. Задаем начальное // и конечное значение, инициализируем // редактор текста hwndUpDown = CreateUpDownControl( WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_WRAP | UDS_ARROWKEYS | UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, hdlg, IDC_UPDOWN, hInst, hwndEdit,10, 1, 1); // Получаем идентификатор органа Hot Key hwndHotKey = GetDlgItem(hdlg, IDC_HOTKEY); // Получаем код комбинации клавиш, которая // используется для активизации диалоговой панели wHotKey = (WORD)SendMessage(hwndMainWindow, WM_GETHOTKEY, 0, 0); // Устанавливаем начальное состояние органа Hot Key // в соответствии с полученным кодом if(wHotKey != 0) SendMessage(hwndHotKey, HKM_SETHOTKEY, wHotKey, 0); return TRUE; } // ----------------------------------------------------- // Функция DlgProc_OnCommand // ----------------------------------------------------- #pragma warning(disable: 4098) void DlgProc_OnCommand(HWND hdlg, int id, HWND hwndCtl, UINT codeNotify) { int nValue; char szBuf[80]; BOOL fError; switch (id) { case IDOK: { // Определяем и отображаем выбранное значение nValue = (int)GetDlgItemInt(hdlg, IDC_EDIT1, &fError, FALSE); wsprintf(szBuf, "Value:\t%d", nValue); MessageBox(NULL, szBuf, szAppTitle, MB_OK | MB_ICONINFORMATION); EndDialog(hdlg, TRUE); break; } case IDC_SETHOTKEYBUTTON: { // Получаем код комбинации клавиш, которая // используется для активизации диалоговой панели wHotKey = (WORD)SendMessage(hwndHotKey, HKM_GETHOTKEY, 0, 0); // Устанавливаем новую комбинацию клавиш для // активизации диалоговой панели SendMessage(hwndMainWindow, WM_SETHOTKEY, wHotKey, 0); break; } case IDCANCEL: { EndDialog(hdlg, TRUE); break; } default: return FALSE; } return TRUE; } // ----------------------------------------------------- // Функция WndProc_OnSysCommand // ----------------------------------------------------- #pragma warning(disable: 4098) void WndProc_OnSysCommand(HWND hwnd, UINT cmd, int x, int y) { // Если пришло сообщение от клавиши активизации, // посылаем функции главного окна сообщение WM_COMMAND // с кодом, соответствующем строке Options меню File // для активизации диалоговой панели if(cmd == SC_HOTKEY) { SendMessage(hwndMainWindow, WM_COMMAND, (WPARAM)MAKELONG(ID_FILE_OPTIONS, 0), 0L); return 0; } return FORWARD_WM_SYSCOMMAND(hwnd, cmd, x, y, DefWindowProc); } Описания функция и идентификатор IDC_UPDOWN органа управления Up-Down находятся в файле updown.h (листинг 7.7). Листинг 7.7 Файл updown\updown.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); BOOL APIENTRY DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL DlgProc_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam); void DlgProc_OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify); void WndProc_OnSysCommand(HWND hwnd, UINT cmd, int x, int y); #define IDC_UPDOWN 1224 В файле resource.h (листинг 7.8), созданном автоматически, определены константы идентификаторов ресурсов приложения. Листинг 7.8 Файл updown\resource.h //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by UPDOWN.RC // #define IDR_APPMENU 102 #define IDI_APPICON 103 #define IDI_APPICONSM 104 #define IDD_DIALOG1 121 #define IDC_EDIT1 1009 #define IDC_HOTKEY 1010 #define IDC_SETHOTKEYBUTTON 1011 #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 126 #define _APS_NEXT_COMMAND_VALUE 40030 #define _APS_NEXT_CONTROL_VALUE 1012 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif Файл updown.rc (листинг 7.9) содрежит определения ресурсов приложения. Листинг 7.9 Файл updown\updown.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 "updown.ico" IDI_APPICONSM ICON DISCARDABLE "updownsm.ico" ////////////////////////////////////////////////////////////// // Dialog // IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 194, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Value selection" FONT 8, "MS Sans Serif" BEGIN EDITTEXT IDC_EDIT1,15,9,40,13,ES_AUTOHSCROLL DEFPUSHBUTTON "OK",IDOK,130,6,50,14 PUSHBUTTON "Cancel",IDCANCEL,130,23,50,14 CONTROL "Generic1",IDC_HOTKEY,"msctls_hotkey32",WS_TABSTOP,13,66, 80,12 PUSHBUTTON "Set HotKey",IDC_SETHOTKEYBUTTON,130,65,50,14 GROUPBOX "Hot Key",IDC_STATIC,8,49,178,40 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 Описание функцийРасскажем о наиболее важных функциях, определенных в приложении Up-Down. WndProc_OnCreateФункция WndProc_OnCreate обрабатывает сообщение WM_CREATE , поступающее в функцию главного окна приложения при его инициализации. После инициализации библиотеки стандартных органов управления функция WndProc_OnCreate определяет комбинацию клавиш <Alt+Ctrl+V> как комбинацию клавиш активизации диалоговой панели Value Selection (рис. 7.9). Для этого главному окну приложения посылается сообщение WM_SETHOTKEY . WndProc_OnCommandФункция WndProc_OnCommand содержит обработчик сообщения WM_COMMAND , поступающего от главного меню приложения, а также в том случае, если пользователь нажимает комбинацию клавиш активизации диалоговой панели Value Selection. Если вместе с этим сообщением приходит код команды ID_FILE_OPTIONS, с помощью функции DialogBox создается указанная выше диалоговая панель. DlgProc_OnInitDialogФункция DlgProc_OnInitDialog вызывается при инициализации диалоговой панели Value Selection, когда в окно этой диалоговой панели приходит сообщение WM_INITDIALOG . При этом вначале соответствующий обработчик получает идентификатор окна редактора текста, к которому будет привязан орган управления Up-Down, и сохраняет его в переменной hwndEdit. Затем с помощью функции CreateUpDownControl создается орган управления Up-Down. Функция CreateUpDownControl привязывает созданный орган управления к редактору текста hwndEdit и выполняет все необходимые инициализирующие действия. Далее функции главного окна приложения посылается сообщение WM_GETHOTKEY . Если для приложения определена комбинация клавиш активизации, то эта комбинация используется для инициализации органа управления Hot Key, расположенного в диалоговой панели Value Selection. DlgProc_OnCommandЭта функция обрабатывает сообщение WM_COMMAND , поступающее в функцию окна диалоговой панели Value Selection от органов управления, расположенных в этой диалоговой панели. Если пользователь нажимает кнопку OK, обработчик получает целое значение, соответствующее текстовой строке из редактора IDC_EDIT1. Так как последний был привязан к органу управления Up-Down, полученное значение соответствует текущему для органа Up-Down. В том случае, когда пользователь нажимает клавишу Set HotKey, обработчик считывает новую комбинацию клавиш активизации из органа управления Hot Key, посылая последнему сообщение HKM_GETHOTKEY , и записывает ее в переменную wHotKey. Далее полученная комбинация клавиш устанавливается в качестве комбинации клавиш активизации при помощи сообщения WM_SETHOTKEY . WndProc_OnSysCommandФункция WndProc_OnSysCommand обрабатывает сообщение WM_SYSCOMMAND , поступающее в главное окно приложения в том случае, если пользователь нажмет комбинацию клавиш активизации. Этот обработчик посылает главному окну приложения сообщение WM_COMMAND с кодом команды ID_FILE_OPTIONS. В результате на экране появится диалоговая панель Value Selection. |