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, должно быть понятно. Если где-то непонятки, спрашивайте на форуме. Всего доброго!

содержание | назад | вперед