Операционная система 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. |

