API и FreeBasic. (дочерние окна-button, часть 2)
Событие нажатия на кнопки чаще всего отлавливают с помощью сообщения WM_COMMAND. При этом, в параметры Wparam и Lparam записываются важные характеристики, которые позволяют давать расширенную информацию о нажатии:
- Специфический код, который сигнализирует о нажатии на контрол либо на пункт меню. Этот код можно получить в параметр Wparam в старшем слове HIWORD . Если этот код равен 0, то сообщение поступает от одного из пунктов меню.
- Идентификатор контрола либо пункта меню. Его можно получить в параметре Wparam в младшем слове LOWORD. Отсюда можно понять , что идентификаторы контрола могут быть в диапазоне 0-65535
- Хендл контрола. Его можно получить в параметре Lparam
Кроме этого, при работе с кнопками может потребоваться получить характеристики:
- Нажата кнопка или отпущена или в случае с кнопками CheckBox и RadioButton установлены флажок или нет
- Активна кнопка или нет
Для определения первого пункта потребуется функция IsDlgButtonChecked , которая может определить:
- нажата кнопка или флажок
- отпущена кнопка или флажок
- кнопка находится в среднем положении для кнопок CheckBox
Синтаксис функции:
IsDlgButtonChecked(
hDlg, // Хендл окна родителя
кнопки
nIDButton // Идентификатор кнопки
)
Возвращаемые значения функции:
- 0 - кнопка не нажата или флажок не установлен
- 1 - кнопка нажата или флажок установлен
- 2 - среднее положение кнопки
Для того, чтобы программно установить нажатие кнопок или флажков, можно воспользоваться функцией SendMessage с сообщением BM_SETCHECK , при этом в параметре Wparam нужно передать соответствующее значение установки кнопки ( 0 или 1 или 2 ). В параметре Lparam передается ноль. Так например:
SendMessage( HButton , BM_SETCHECK , 1 , 0 )
установит флажок либо нажатие у кнопки с хендлом HButton.
Для того чтобы установить активность или неактивность контрола и в частности кнопки, можно воспользоваться функцией EnableWindow. Ее синтаксис:
BOOL EnableWindow(
HWND
hWnd, //
Хендл контрола
BOOL bEnable
// Параметр: Если 0 - неактивен. Если 1 - активен
);
Для того, чтобы узнать активен ли в данный момент контрол , можно воспользоваться функцией IsWindowEnabled. Ее синтаксис:
BOOL IsWindowEnabled(
HWND hWnd // Хендл
контрола
);
Возвращаемое значение функции:
- 0 - неактивен
- 1 - активен
И конечно общий пример для всего вышеописанного:
#INCLUDE "windows.bi" Dim msg As MSG 'структурированная переменная MSG Dim As WNDCLASSEX wc 'структурированная переменная WNDCLASSEX Dim As String NameClass="MyClass" ' переменная имени класса Dim As HINSTANCE Hinst=GetModuleHandle(0) ' хендл модуля ' функция класса Function wndproc(hwnd As HWND, msg As Uinteger,_ wparam As WPARAM, lparam As LPARAM) As Integer Static As HWND st, but , opt1, opt2 Select Case msg Case WM_CREATE but=CreateWindowEx(0,"button","Простая кнопка",WS_VISIBLE Or WS_CHILD,20,40,130,20,hwnd,Cast(HMENU,1),0,0) CreateWindowEx(0,"button","ToggleButton",WS_VISIBLE Or WS_CHILD Or BS_PUSHLIKE Or BS_AUTOCHECKBOX,20,70,130,20,hwnd,Cast(HMENU,2),0,0) opt1=CreateWindowEx(0,"button","кнопка неактивна",WS_VISIBLE Or BS_AUTORADIOBUTTON Or WS_CHILD,180,40,150,20,hwnd,Cast(HMENU,3),0,0) opt2=CreateWindowEx(0,"button","кнопка активна",WS_VISIBLE Or BS_AUTORADIOBUTTON Or WS_CHILD,180,70,150,20,hwnd,Cast(HMENU,4),0,0) CreateWindowEx(0,"button","С двумя положениями",WS_VISIBLE Or BS_AUTOCHECKBOX Or WS_CHILD,20,100,200,20,hwnd,Cast(HMENU,5),0,0) CreateWindowEx(0,"button","C тремя положениями",WS_VISIBLE Or BS_AUTO3STATE Or WS_CHILD,20,120,200,20,hwnd,Cast(HMENU,6),0,0) st=CreateWindowEx(0,"static","",WS_VISIBLE Or WS_CHILD,20,10,300,20,hwnd,Cast(HMENU,7),0,0) Case WM_COMMAND Select Case Loword(wparam) Case 1 SetWindowText(st, @"Вы нажали простую кнопку") Case 2 If IsDlgButtonChecked(hwnd,2)=1 Then SetWindowText(st, @"Кнопка-фиксатор нажата") Else SetWindowText(st, @"Кнопка-фиксатор отпущена") Endif Case 3 SetWindowText(st, @"Вы сделали кнопку неактивной") EnableWindow(but,FALSE) Case 4 SetWindowText(st, @"Вы сделали кнопку активной") EnableWindow(but,TRUE) Case 5 If IsDlgButtonChecked(hwnd,5)=1 Then SetWindowText(st, @"Вы сделали выбор2") SendMessage( opt2 , BM_SETCHECK , 1 , 0 ) SendMessage( opt1 , BM_SETCHECK , 0 , 0 ) Else SetWindowText(st, @"Вы сделали выбор1") SendMessage( opt1 , BM_SETCHECK , 1 , 0 ) SendMessage( opt2 , BM_SETCHECK , 0 , 0 ) Endif Case 6 If IsDlgButtonChecked(hwnd,6)=0 Then SetWindowText(st, @"флажок не установлен") Elseif IsDlgButtonChecked(hwnd,6)=1 Then SetWindowText(st, @"флажок установлен") Else SetWindowText(st, @"флажок установлен, но серым цветом") Endif End Select Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function ' Заполнение структуры WNDCLASSEX With wc .cbSize=SizeOf(WNDCLASSEX) .style=CS_HREDRAW Or CS_VREDRAW .lpfnWndProc=@wndproc .hInstance=Hinst .hIcon=LoadIcon(0,IDI_QUESTION) .hCursor=LoadCursor(0,IDC_ARROW) .hbrBackground=Cast(HBRUSH,COLOR_WINDOW) .lpszClassName=StrPtr(NameClass) .hIconSm=.hIcon End With ' Регистрация класса окна If RegisterClassEx(@wc)=0 Then Print "Register error, press any key" Sleep End Endif 'Создание окна CreateWindowEx(0,NameClass,"Главное окно",_ WS_VISIBLE Or WS_OVERLAPPEDWINDOW,10,10,380,200,0,0,Hinst,0) ' Цикл сообщений While GetMessage(@msg,0,0,0) TranslateMessage(@msg) DispatchMessage(@msg) Wend
Пример хоть и кажется не маленьким, но на самом деле очень простой. Если вы внимательно прочитали эту статью, то все , что помещается в блоке условия WM_COMMAND, должно быть понятно. Если где-то непонятки, спрашивайте на форуме. Всего доброго!
содержание | назад | вперед