Типы данных Windows
HWND
HBRUSH
MSG – код сообщения.
HINSTANCE – дескриптор приложения
WinMain – аналог main языка C++
WM_SIZE – поступает в момент изменения размера окна.
lParam – новые параметры окна. Чтобы получить эти параметры нужно применить 2 макроса Windows. int cx = LOWORD(lParam) – ширина int cy = HIWORD(lParam) – высота нового окна
WM_MOVE – это сообщение поступает в момент перемещения окна, при этом параметр lParam хранит координаты левого верхнего угла.
int left = LOWORD(lParam);
int top = HIWORD(lParam);
case WM_SIZE:{
cx = LOWORD(lParam);
cy = HIWORD(lParam);
return 0;
}
case WM_MOVE:{
mx = LOWORD(lParam);
my = HIWORD(lParam);
return 0;
}
WM_LBUTTONDOWN (WM_RBUTTONDOWN) - нажатие
WM_LBUTTONUP (WM_RBUTTONUP) – поднятие
WM_MOUSEMOVE – перемещение по рабочей области
При поступлении любого сообщения от мыши параметр lParam хранит координаты мыши в момент щелчка. int mx = LOWORD(lParam);
Int my = HIWORD(lParam);
WM_CREATE – в момент создания окна. Обычно в этом сообщении создаются элементы управления, меню, строка состояния, выполняется первоначальная прорисовка окна.
WM_KEYDOWN – нажатие на клавишу клавиатуры
WM_KEYUP – поднятие
При это параметр wParam хранит виртуальный код нажатой клавиши.
WM_CHAR – поступает при нажатии клавиши, при этом wParam хранит код клавиши в кодировки ASCII.
ShowWindow (wa, SW_SHOW);
MoveWindow (wa, left, top, cx, cy, TRUE);
MessageBox(hwnd,”текст_сообщения”,”текст_заголовка”, MB_OKCANCEL); if (ID_OK) …; else …;
int x = GetSystemMetrics(SM_CXSCREEN); - количество пиксeлей по оси Ox
Задача: после нажатия на левую клавишу мыши над рабочей областью главного окна приложения в левом верхнем углу области отобразить временное окно, размером в четверть главного. Временное окно скрыть, после отжатия левой клавиши мыши.
int cx, cy, left, top; WinMain(…){ … HWND hwnd, pop; hwnd = CreateWindow(Name, ”Главное”, WS_OVERLAPPEDWINDOW| WS_VISIBLE, CW_VISEDEFAULT, …,…,…,0,0,hInst,NULL); pop = CreateWindow (Name, “Временное”, WS_POPUP|WS_CAPTION|WS_BORDER,left,top+16, cx/2, cy/2,0,0,hInst,NULL); … } MainProc (HWND hwnd, MSG msg, WPARAM wParam, Lparam){ switch(msg){ case WM_SIZE:{ cx = LOWORD(lParam); cy = HIWORD(lParam); return = 0;
} case WM_MOVE:{ left = LOWORD(lPAram); top = HIWORD(lParam); return = 0; } case WM_LBUTTONDOWN:{ ShowWindow(pop,SW_SHOW) return = 0; }
case WM_LBUTTONUP:{ ShowWindow(pop,SW_HIDE) return = 0; } … } }
_Элементу управления
ОС сама описывает несколько классов стандартных окон. Такие классы называются органами упралвения.
Отличительные черты органов управления:
-
Для них уже описаны классы окон.
-
Все они дочерние
-
Для них всегда необходимо описывать идентификаторы
-
Для них описаны дополнительные стили и списки, получаемых и обрабатываемых сообщений
Стандартные классы:
-
“button” - описывает нажимающиеся кнопки, переключатели и флажки. Родительское окно получает сообщение WM_COMMAND
-
“static” – описывает элементы оформления.
-
“scrollbar” – описывает вертикальные и горизонтальные полосы прокрутки. Родительское окно получает сообщение WM_HSCROLL или WM_VSCROLL
-
“edit” – описывает строку ввода или текстовый редактор. Родительское окно получает сообщение WM_COMMAND
-
“listbox” – описывает список текстовых строк. При выборе строки информация о ней передаётся родительскому окну сообщением WM_COMMAND/
-
“combobox” – создаёт элемент управления, состоящий из списка и поля выбора. Список может быть раскрыт или свёрнут. Если список раскрыт, то при вводе символа в поле выбора, курсор устанавливается на первую строку наиболее похожую на вводимые символы. К родительскому окну посылает сообщение WM_COMMAND.
Алгоритм создания элементов управления:
-
Описать идентификатор #define ID_BUTTON 3000
-
Описать дескриптор дочернего окна static HWND hButton; // перед switch в оконной функции
-
Создать элемент управления nButton = CreateWindow(“button”, ”OK”, WS_CHILD|BS_DEFPUSHBUTTON|WS_VISIBLE, 10, 10, 200, 100, hwnd, (HMENU)ID_BUTTON, hinst, NULL). Все элементы управление рекомендуется создавать в сообщении WM_CREATE
Передача\получение сообщений от элементов управления.
LRESULT CALLBACK WndProc (HWND hwnd, MSG msg, WPARAM wParam, LPARAM, lParam)
Пусть функция родительского окна получила от элемента управления сообщение:
Msg = WM_COMMAND
При этом младшее слово параметра WPARAM содержит идентификатор элемента управления:
LOWORD(wParam)=ID_Button
Старшее слово этого параметра равно коду извещения. По нему судят о том какое сообщение пришло от элемента управления. Например, при нажатии на кнопку из предыдущего примера:
HIWORD(lParam) = BN_CLICKED
Параметр lParam содержит дескриптор элемента управления:
lParam = (HWND)hButton
Для управления элементами управления приложение посылает сообщение. Для этого вызывается функция:
SendMessage (HWND hwnd, MSG msg, WPARAM wParam, LPARAM, lParam).
Кнопки могут находиться в двух состояних – нажатом и отжатом. Для изменения состояния кнопки передают сообщение BM_SETSTATE. Если параметр lParam=0, а wParam = TRUE, то кнопка переводится в нажатое состояние. Если lParam=0, a wParam = FALSE, то кнопка переводится в отжатое состояние.
SendMessage(hButton, BM_SETSTATE, TRUE, 0);
Пример: В рабочей области окна создать список, редактор и кнопку. Помещать строку, выбранную в списке в редактор. После редактирования по нажатию кнопки помещать строку в список.
#include <windows.h> #include <string.h> #define DLIST 3000 #define ID_BUTTON 3001 #define ID_EDIT 3002 … WinMain(…){ … while (GetMessage(&msg,0,0,0)){ DispathMessage(&msg); TranslateMessage(&msg); } } … WndProc(…) { static HWND hButton, hList, hEdit; // объявление дескрипторов элементов управления char str[10]; int n; switch (msg) { case WM_CREATE:{ hList=CreateWindow(“listbox”,NULL,WS_CHILD|LBS_STANDART|WS_VISIBLE, 10, 10, 100, 200, (HWND)ID_LIST, hinst, NULL);
hEdit = CreateWindow (“edit”, NULL, WS_CHILDE| WS_VISIBLE| ES_LEFT| WS_BORDER, 10, 210, 200, 50, hwnd, (HMENU)ID_EDIT, hinst, NULL);
hButton = CreateWindow (“button”, “Переместить”, WS_CHILDE| WS_VISIBLE| BS_DEFPUSHBUTTON, 10, 240, 100, 20, hwnd, (HMENU)ID_BUTTON, hinst, NULL);
strcopy(str,”Вася”);
SendMessage(hList,LB_ADDSTRING, 0, (LPARAM)str);
return 0;
}
case WM_COMMAND:{
switch(LOWORD(wParam)){
case ID_LIST:{
if (HIWORD(wParam)==LBN_DBLCLK){
n = SendMessage(hList,LB_GETCURSEL,0,0);
SendMessage(hList, LB_GETTEXT, (WPARAM)n, (LPARAM)str); //копирование в буфер
SetWindowText(hEdit,str); //меняет заголовки
SendMessage(hList,LB_DELETESTRING,(WPARAM)n,(LPARAM)str); //удаление из списка
}
return 0;
case ID_BUTTON:{
SendMessage(hEdit,WM_GETLINE, 0, (LPARAM)str);
SetWindowText(hEdit,” “);
SendMessage(hList,LB_ADDSTRING, 0, (LPARAM)str);
Return 0;
}
Return 0;
}
…
}
Таймер
Таймер является устройством ввода информации, которое периодически извещает приложение о том, что истёк заданный интервал времени. По истечении интервала, таймер посылает сообщение WM_TIMER.
Создать таймер можно функцией SetTimer(hwnd, номер_таймера, интервал, NULL);
Удалить можно функцией KillTimer(hwnd,номер_таймера);
Пример: в центре главного окна приложения создать временное окно, которое начинает мигать по нажатию левой клавиши мыши и прекращать мигание по нажатию правой. Продублировать лействия клавиш мыши кнопками + и -.
#define ID_TIMER 1;
…WinMain(…){ //создать два окна, принадлежащие разным классам}
… WndProc(…){
switch(msg){
case WM_LBUTTONDOWN:{
SetTimer(hwnd,1,1000,NULL);
return 0; } case WMRBUTTONDOWN:{ KillTimer(hwnd,1); return 0; } case WM_TIMER:{ if (ShowWindow(popup,SW_SHOW)) //если == 1, то ShowWindow(popup,SW_HIDE); return 0; } case WM_KEYDOWN:{ if (wParam == VK_ADD) SetTimer(…); if (wParam == VK_SUBTRACK) KillTimer(hwnd,1); return 0; }
… }