Платформа Win32 - Меню и акселераторы

Предыдущая тема Следующая тема Перейти вниз

Платформа Win32 - Меню и акселераторы

Сообщение  Замабувараев в Чт Окт 09, 2008 4:50 am

Написание меню

Меню — один из краеугольных камней идеологии Win32 (Windows и ReactOS). Похожие друг на друга меню разрешают пользоваться абсолютно незнакомыми программами, не читая инструкций, и узнавать об из возможностях путём просмотра содержания различных пунктов меню. Попробуем добавить меню и в нашу программу Window.bas.
Но перед тем как перейти к программе демонстрации меню, изучим основные концепции Win32, связанные с меню.

Концепция меню

При создании меню для вашей программы нужно сгруппировать команды, выполняющие однотипные действия. Более того, следует присвоить имена этим группам, которые хорошо знакомы пользователям. Тогда, даже если пользователи впервые работают с вашей программой, они легко разыщут требуемую команду или, по крайней мере, будут знать, где её искать. Ниже приведён список некоторых стандартных названий меню, которые вы можете встретить практически в любой программе, написанной для Windows или ReactOS.

File (Файл). В данную группу помещают все команды, которые работают с файлами. Обычно в этом меню находятся такие команды как New (Создать), Open (Открыть), Close (Закрыть), Save (Сохранить), Save As (Сохранить как) и Print (Печать). Если программа предназначена для активной работы с файлами, в данное меню помещается также список нескольких последних файлов, к которым было обращение. Как правило, самой последней командой данного меню является Exit (Выход).

Edit (Правка). В данную группу помещают команды, предназначенные для редактирования объектов и текста, а также для работы с буфером обмена: Undo (Отменить), Cut (Вырезать), Copy (Копировать), Paste (Вставить), Clear (Очистить), Find (Найти) и Replace (Заменить).

View (Вид). В данную группу меню помещают команды, предназначенные для изменения режимов просмотра документа. Например, в программе текстового процессора OpenOffice Writer в этом меню находятся команды для перехода из обычного режима редактирования (предназначенного для набора текста) в режим разметки страницы, в котором выполняется вёрстка макета. Кроме того, в описываемое меню помещается команда изменения масштаба документа.

Tools (Сервис). В данную группу помещаются команды для запуска даполнительных утилит и программ настройки. Например, в программе текстового процессора в этом меню находятся команды для проверки правописания и грамматики.
Window (Окно). Данная группа меню, как правило, включается в те приложения, которые поддерживают многодокументный интерфейс (MDI). MDI-программы, такие как OpenOffice Writer или Calc, позволяют одновременно работать с несколькими документами. Кроме того, меню Window позволяет в одном месте хранить список открытых документов и быстро переключаться между ними.

Help (Справка). В данное меню включаются команды вызова справочной системы. Обычно в нём можно встретить пункты для вызова
оглавления справочной системы (команда Help Index), поиска нужной темы в справочнике (команда Search), а также вывода информации о программе (команда About), её авторах и правах собственности.

Клавиши быстрого доступа

Клавиши быстрого доступа позволяют перемещаться по системе меню без применения мыши. Если в названии меню предусмотрена клавиша быстрого доступа, то в названии меню она будет подчёркнута (например, буква F в меню File). Для создания клавиши достаточно поместить символ амперсенда (&) перед соответствующей буквой в тексте меню. (Если же нужно, чтобы в названии меню отображался символ &, то введите его дважды - &&.) Старайтесь там, где это возможно, назначать в качестве клавиши быстрого доступа первую букву в названии меню, поскольку именно её чаще всего ожидают увидеть пользователи. В то же время, не стоит использовать первую букву в том случае, если она уже назначена для другого элемента меню.

Вы можете назначить часто используемым командам программы специальные сочетания клавиш ("горячие" клавиши, или акселераторы), дабы часто не обращаться к меню для запуска нужной команды. "Грячие" клавиши позволяют запустить команду после нажатия одной (например, <Delete>) или двух (таких как <Ctrl+S>) клавиш клавиатуры. Правильно назначенные клавиатурные эквиваленты ещё больше ускоряют работу пользователя.

File->New Ctrl+N Создать новый документ
File->Open Ctrl+O Открыть новый документ
File->Save Ctrl+S Сохранить документ
File->Print Ctrl+P Распечатать документ
Edit->Cut Ctrl+X Вырезать
Edit->Copy Ctrl+C Копировать
Edit->Paste Ctrl+V Вставить
Edit->Undo Ctrl+Z Отменить
Edit->Find Ctrl+F Найти

Создание меню

Первое, что нам нужно получить, - это само меню. Его, также как значки, диалоги и другую информацию (вплоть до версии программы), записывают в файлы ресурсов. Файл ресурсов имеет расширение *.RC для текстового файла или *.RES для бинарного файла, созданного специальным компилятором ресурсов (RC, BRCC32, WRC). И те, и другие файлы ресурсов можно редактировать особыми программами, сводящими в дистрибутив C/C++, или с помощью других средств разработки для Windows, но мы не будем создавать слишком сложное меню и напишем RC-файл вручную, например, так:

Код:

// window.rc
// Файл ресурсов для программы Window.bas

// Идентификаторы сообщений от пунктов меню
#define IDM_NEW 1
#define IDM_OPEN 2
#define IDM_SAVE 3
#define IDM_SAVEAS 4
#define IDM_EXIT 5
#define IDM_ABOUT 6
#define IDM_UNDO 7
#define IDM_CUT 8
#define IDM_COPY 9
#define IDM_PASTE 10
#define IDM_CLEAR 11
#define IDM_SELECTALL 12

// Идентификаторы основных ресурсов
#define ID_MENU 13    // Наше меню
#define ID_ACCEL 14  // "Горячие" клавиши (акселераторы)

// Основное меню
ID_MENU MENU {
    POPUP "&File" {
        MENUITEM "&New\tCtrl+N", IDM_NEW
        MENUITEM "&Open...\tCtrl+O", IDM_OPEN
        MENUITEM "&Save\tCtrl+S", IDM_SAVE
        MENUITEM "Save &As...\tCtrl+Shift+S", IDM_SAVEAS
        MENUITEM SEPARATOR // Под словом SEPARATOR понимается тонкая разделительная линия между пунктами меню
        MENUITEM "E&xit\tCtrl+Q", IDM_EXIT
    }
    POPUP "&Edit" {
        MENUITEM "&Undo\tCtrl+Z", IDM_UNDO
        MENUITEM SEPARATOR
        MENUITEM "Cu&t\tCtrl+X", IDM_CUT
        MENUITEM "&Copy\tCtrl+c", IDM_COPY
        MENUITEM "&Paste\tCtrl+V", IDM_PASTE
        MENUITEM "&Delete\tDel", IDM_CLEAR
        MENUITEM SEPARATOR
        MENUITEM "Select &All\tCtrl+A",  IDM_SELECTALL
    }
    POPUP "&Help" {
        MENUITEM "About", IDM_ABOUT
    }
}

// Комбинации клавиш
ID_ACCEL ACCELERATORS {
    "N", IDM_NEW, CONTROL, VIRTKEY
    "O", IDM_OPEN, CONTROL, VIRTKEY
    "S", IDM_SAVE, CONTROL, VIRTKEY
    "S", IDM_SAVEAS, CONTROL, SHIFT, VIRTKEY
    "Q", IDM_EXIT, CONTROL, VIRTKEY
    "Z", IDM_UNDO, CONTROL, VIRTKEY
    "A", IDM_SELECTALL, CONTROL, VIRTKEY
}

Полный код программы Window.bas с меню

#Include once "windows.bi"

' Функция, в которой будет происходить
' цикл обработки сообщений
Declare Function WndProc(ByVal hWnd As HWND, ByVal wMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As LRESULT


''
'' Program Start
''

Dim hInst As HINSTANCE ' Идентификатор нашего процесса
Dim wMsg As MSG ' Сообщения, принимаемые от окна
Dim wc As WNDCLASS ' Структура нашего класса окна
Dim hWnd As HWND ' Идентификатор окна

Dim hAccel As HACCEL ' Идентификатор акселератора

' Получаем идентификатор нашего процесса
hInst = GetModuleHandle(0)

/' Функция Cast приводит выражение из правой части
к типу, указанному в левой части так что запись типа
Cast(ZString Ptr, 14)
получает нужный нам указатель на идентификатор акселератора
'/
' Загружаем "Горячие" клавиши (акселераторы)
hAccel = LoadAccelerators(hInst, Cast(ZString Ptr, 14))


' Создаём структуру класса окна
With wc
' Стиль прорисовки окна
.style = CS_HREDRAW Or CS_VREDRAW
' Адрес функции обработки сообщения, посылаемых окну
.lpfnWndProc = @WndProc
' Дополнительные данные
.cbClsExtra = 0
.cbWndExtra = 0
' Идентификатор процесса, создающего класс окна
.hInstance = hInst
' Значок окна
.hIcon = LoadIcon(0, IDI_APPLICATION)
' Курсор по умолчанию
.hCursor = LoadCursor(0, IDC_ARROW)
' Кисть по умолчанию для отрисовки фона окна
.hbrBackground = Cast(HBRUSH, COLOR_BTNFACE + 1)
' Имя нашего меню из ресурсов
.lpszMenuName = Cast(ZString Ptr, 13)


' Адрес строки с именем класса окна
.lpszClassName = @"FBWindow"
End With

' Регистрируем класс окна
RegisterClass(@wc)

' Создаём окно с именем зарегистрированного класса
hWnd = CreateWindow(@"FBWindow", _ /' Адрес строки с именем класса окна '/
"Пример простого окна с меню", _ /' Заголовок нашего окна '/
WS_OVERLAPPEDWINDOW, _ /' Стиль окна '/
CW_USEDEFAULT, _ /' X-позиция на экране, используем по умолчанию '/
CW_USEDEFAULT, _ /' Y-позиция на экране, используем по умолчанию '/
640, _ /' Ширина нашего окна '/
480, _ /' Высота нашего окна '/
0, _ /' Идентификатор родительского окна, используется если создаваемое окно является дочерним '/

0, _ /' Идентификатор меню из ресурсов программы,
так как мы определили меню в классе окна
то оставляем здесь 0 '/


hInst, _ /' Идентификатор процесса, создающего окно '/
0) /' Дополнительные данные, у нас их нет '/

' Показываем окно
ShowWindow(hWnd, SW_NORMAL)
' Обновляем содержимое окна
' При этом окну посылается сообщение WM_PAINT
UpdateWindow(hWnd)

' Цикл обработки сообщений от окна
Do While GetMessage(@wMsg, 0, 0, 0) <> 0

' Добавляем проверку на нажатие горячих клавиш
If TranslateAccelerator(hWnd, hAccel, @wMsg) = 0 Then
TranslateMessage(@wMsg)
DispatchMessage(@wMsg)
End If


Loop


''
'' Program End
''


'
' Функция для обработки сообщений от окна
'
Function WndProc(ByVal hWnd As HWND, _
ByVal wMsg As UINT, _
ByVal wParam As WPARAM, _
ByVal lParam As LPARAM) As LRESULT

Select Case(wMsg)
Case WM_CREATE
' Здесь должна происходить инициализация

Case WM_COMMAND
' Сообщения от меню
Select Case HiWord(wParam)
Case BN_CLICKED, 1
Select Case LoWord(wParam)
Case 1
' Пункт меню New (создать новый документ)
Case 2
' Пункт меню Open (открыть)
Case 3
' Пункт меню Save (сохранить)
Case 4
' Пункт меню SaveAs (сохранить под другим именем)
Case 5
' Пункт меню Exit (закрыть программу)
' Уничтожаем окно
DestroyWindow(hWnd)
Case 6
' Пункт меню About (о программе)
Case 7
' Пункт меню Undo (отменить)
Case 8
' Пункт меню Cut (вырезать в буфер обмена)
Case 9
' Пункт меню Copy (копировать в буфер обмена)
Case 10
' Пункт меню Paste (вставить из буфера обмена)
Case 11
' Пункт меню Clear (очистить текстовое поле)
Case 12
' Пункт меню SelectAll (выделить весь текст)
End Select
End Select

Case WM_CLOSE
' Сообщение о закрытии окна
' Окно нужно уничтожить
DestroyWindow(hWnd)
Case WM_DESTROY
' Окно разрушается, выходим из цикла сообщений
PostQuitMessage(0)
Case Else
' Посылаем все сообщения, которые мы не обрабатываем
' функции по умолчанию
Return DefWindowProc(hWnd, wMsg, wParam, lParam)
End Select

End Function

Компиляция

fbc -s gui "Window.bas" "Window.rc".

Жирным отмечены места, которые были изменены по сравнению с предыдущей программой (Window.bas). Из 120 строк кода новыми оказались всего 20, а сама программа, с точки зрения пользователя, стала намного сложнее. Таким образом выглядит программирование под Windows на FreeBASIC'е — берётся одна написанная раз и навсегда шаблонная программа, модифицируются ресурсы и пишутся обработчики для различных событий меню и диалогов. Фактически всё программирование оказывается сосредоточенным именно в этих процедурах-обработчиках.


Последний раз редактировалось: zamabuvaraeu (Чт Окт 09, 2008 9:43 am), всего редактировалось 2 раз(а)
avatar
Замабувараев

Сообщения : 99
Дата регистрации : 2008-08-20
Возраст : 33
Откуда : Красноярск

Посмотреть профиль http://www.freebasic.su

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  Eric-S в Чт Окт 09, 2008 5:15 am

Ага! Вот и меню. Значит ты пошел к ресурсам. Меня же больше интересовал чистый код.

Вот пример из examples, но с русскими словечками.
Код:

' демонстрация работы с меню

#include once "windows.bi"

' внутренняя структура
type TMENU
   hnd      as HMENU
end type

type TMENUITEM
   title   as string
   id      as integer
end type

' пункты меню
const MENUID_BASE   = 100

enum MENUID_ENUM
   MENUID_FILE_NEW      = MENUID_BASE
   MENUID_FILE_OPEN
   MENUID_FILE_EXIT
   MENUID_PROJECT_NEW
   MENUID_PROJECT_OPEN
   MENUID_FILE_CLOSE
    MENUID_EDIT_UNDO
    MENUID_EDIT_REDO
    MENUID_EDIT_CUT
    MENUID_EDIT_COPY
    MENUID_SEARCH_FIND
    MENUID_SEARCH_FINDNEXT
    MENUID_SEARCH_FINDPREV
    MENUID_SEARCH_REPLACE
end enum

const MAXMENUS         = 10
const MAXMENUITEMS       = 50


declare sub init_menus( byval hWnd as HWND )                                 
                                 

declare function        WinMain    ( byval hInstance as HINSTANCE, _
                                      byval hPrevInstance as HINSTANCE, _
                                      byref szCmdLine as string, _
                                      byval iCmdShow as integer ) as integer

   ' глобальные
   dim shared submenuTB(0 to MAXMENUS) as TMENU
   dim shared menuitemTB(0 to MAXMENUITEMS-1) as TMENUITEM

' точка входа
   end WinMain( GetModuleHandle( null ), null, Command, SW_NORMAL )
   
   
   


'' name: WndProc
' desc: обработка сообщений окна
function WndProc ( byval hWnd as HWND, _
                  byval message as UINT, _
                  byval wParam as WPARAM, _
                  byval lParam as LPARAM ) as LRESULT
   
    dim rct as RECT
    dim pnt as PAINTSTRUCT
    dim hDC as HDC
   
    static lastmenuid as integer
    dim wmId as integer, wmEvent as integer
    dim menu as HMENU
   
    function = 0
   
    ' обработка сообщений
    select case ( message )
     
        '' окно создано
        case WM_CREATE           
            ' создание и отображение меню
            init_menus( hWnd )
            exit function
       
       ' выбран пункт меню
      case WM_COMMAND
         wmId    = loword( wParam )
         wmEvent = hiword( wParam )
         
         menu = GetMenu( hWnd )
         
' разбираем, какой пункт меню был выбран
         select case wmId
         '' выход
         case MENUID_FILE_EXIT
            PostMessage( hWnd, WM_CLOSE, 0, 0 )
            exit function
         end select
         
         ' сохраняем последний id пункта меню
         lastmenuid = wmId
       
' вызовите перекрашивание так меню id, и название будет оттянуто
         GetClientRect( hWnd, @rct )
         InvalidateRect( hWnd, @rct, TRUE )
       
        ' окно перекрашиваеться
        case WM_PAINT
         
            hDC = BeginPaint( hWnd, @pnt )
            GetClientRect( hWnd, @rct )
           
            if( lastmenuid <> 0 ) then
               DrawText( hDC, _
                       "Last menu selected: id(" & lastmenuid & ") title(" & menuitemTB(lastmenuid-MENUID_BASE).title & ")", _
                       -1, _
                       @rct, _
                       DT_SINGLELINE or DT_CENTER or DT_VCENTER )
            end if
           
            EndPaint( hWnd, @pnt )
           
            exit function           
       
      case WM_KEYDOWN
         if( lobyte( wParam ) = 27 ) then
            PostMessage( hWnd, WM_CLOSE, 0, 0 )
         end if

' окно было закрыто
        case WM_DESTROY
            PostQuitMessage( 0 )
            exit function
    end select
   
    ' это сообщение нас не касаеться, посылаеться обработчику
    function = DefWindowProc( hWnd, message, wParam, lParam )   
   
end function


' name: WinMain
' desc: точка входа win2 gui программы
function WinMain ( byval hInstance as HINSTANCE, _
                  byval hPrevInstance as HINSTANCE, _
                  byref szCmdLine as string, _
                  byval iCmdShow as integer ) as integer   
   
    dim wMsg as MSG
    dim wcls as WNDCLASS   
    dim appName as string
    dim hWnd as HWND

    function = 0
   
    ' устанавливаем класс окна
    appName = "Menu Test"
   
    with wcls
       .style        = CS_HREDRAW or CS_VREDRAW
       .lpfnWndProc  = @WndProc
       .cbClsExtra    = 0
       .cbWndExtra    = 0
       .hInstance    = hInstance
       .hIcon        = LoadIcon( null, IDI_APPLICATION )
       .hCursor      = LoadCursor( null, IDC_ARROW )
       .hbrBackground = GetStockObject( WHITE_BRUSH )
       .lpszMenuName  = null
       .lpszClassName = strptr( appName )
    end with
   
    ' регистрируем окно
    if ( RegisterClass( @wcls ) = false ) then
      MessageBox( null, "Failed to register the window class", appName, MB_ICONERROR )
      exit function
    end if

    ' создаём и выводим окно
    hWnd = CreateWindowEx( 0, _
                      appName, _
                          "Menu test", _
                          WS_OVERLAPPEDWINDOW, _
                          CW_USEDEFAULT, _
                          CW_USEDEFAULT, _
                          CW_USEDEFAULT, _
                          CW_USEDEFAULT, _
                          null, _
                          null, _
                          hInstance, _
                          null )
                         

    ShowWindow( hWnd, iCmdShow )
    UpdateWindow( hWnd )

    ' обработка сообщений окна
    while( GetMessage( @wMsg, null, 0, 0 ) <> false )   
        TranslateMessage( @wMsg )
        DispatchMessage( @wMsg )
    wend
   
    ' программа завершаеться
    function = wMsg.wParam

end function

sub menu_insert( byval hmenu as HMENU, byval submenu as integer, byref title as string, byval flags as integer = 0 )
   
    with submenuTB(submenu)
   
       .hnd    = CreatePopupMenu( )
   
       InsertMenu( hmenu, submenu, MF_BYPOSITION Or MF_POPUP Or MF_STRING or flags, cuint( .hnd ), title )
       
    end with
   
end sub

sub menu_append( byval submenu as integer, byval id as integer, byref title as string, byval flags as integer = 0 )
   
    with menuitemTB(id-MENUID_BASE)
   
       .id = id
       .title = title
       
       AppendMenu( submenuTB(submenu).hnd, MF_STRING or flags, id, title )
       
    end with
 
end sub

sub menu_separator( byval submenu as integer )

    AppendMenu( submenuTB(submenu).hnd, MF_SEPARATOR, 0, NULL )
 
end sub

sub init_menus( byval hWnd as HWND )
   dim menu as HMENU
    
    menu = CreateMenu( )
    
    ' файл
    menu_insert( menu, 0, "&файл" )
   
    menu_append( 0, MENUID_FILE_NEW, "&новый" )
    menu_append( 0, MENUID_FILE_OPEN, "&открыть..." )

   menu_insert( submenuTB(0).hnd, 3, "&Project" )
    menu_append( 3, MENUID_PROJECT_NEW, "&новый" )
   menu_append( 3, MENUID_PROJECT_OPEN, "&открыть..." )
   
    menu_append( 0, MENUID_FILE_CLOSE, "&закрыть" )
    menu_separator( 0 )
    menu_append( 0, MENUID_FILE_EXIT, "в&ыход" )
   
   ' правка
    menu_insert( menu, 1, "&правка" )
    
    menu_append( 1, MENUID_EDIT_UNDO, "&отменить" )
    menu_append( 1, MENUID_EDIT_REDO, "&заного" )
    menu_separator( 1 )
    menu_append( 1, MENUID_EDIT_CUT, "в&ырезать" )
    menu_append( 1, MENUID_EDIT_COPY, "&копировать" )

    ' найти
    menu_insert( menu, 2, "&найти" )

    menu_append( 2, MENUID_SEARCH_FIND, "&найти" )
    menu_append( 2, MENUID_SEARCH_FINDNEXT, "найти &следующее" )
    menu_append( 2, MENUID_SEARCH_FINDPREV, "найти &предыдущее" )
    menu_append( 2, MENUID_SEARCH_REPLACE, "&заменить", MF_MENUBARBREAK )

    SetMenu( hWnd, menu )
   
    DrawMenuBar( hWnd )
   
end sub

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  electrik в Чт Окт 09, 2008 9:25 pm

zamabuvaraeu, огромное спасибо!!! вот бы все так про винды писали!!! теперь будем ждать про диалоги, хотя я их умею делать, но все же.
респект.

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  electrik в Чт Окт 09, 2008 9:51 pm

eric, я тебя уважаю зато, что ты не идеш по короткому пути, пытаясь писать менюшки, окошки менуя пресурсы, я сам люблю маленький и быстрый код, но в данном случае лучше пользовать ресурсы, расскажу почему.
меню написанное при помощи твоего способа, является прямым обращением к винде, и не как не входит в таблицу ресурсов, тоесть, в программах типа: "resource hacker", "exescope" менюшки не видятся. соответственно, наступает проблема локализаций на другие языки. конечно же можно все запехать в специальный *.lang файл, но это дополнительный код. соответственно, выигрыша по скорости нет. прелесть ресурсов в том, что прямо в бинарнике, специальными программами можно менять размеры окон, удалять или вставлять картинки, менять свойство кнопок, текст на кнопках и т.д. как-то я захотел русифицировать программу, а мне фиг. какой-то диалог, типа о программе и все. весь интерфейс программы, состоял из стандартных виндовых окон, но в ресурсах не менюшек, ни важных диалоговых окон небыло. короче, если вы хотите все скрыть, пишите на прямую, а мне, ресурсы пока по душе.

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  Eric-S в Ср Фев 04, 2009 9:03 am

Я так понимаю функция CreateMenu()
http://www.firststeps.ru/mfc/winapi/menu/r.php?62
Она может вызываться только после создания окна?
Или её всё же можно вызвать, до создания?
Я бы хотел поиметь дескриптор менюшки, ещё на стадии инициализации формы.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  Eric-S в Чт Фев 05, 2009 9:56 am

Вот я смотрю, здесь
Код:

Case WM_COMMAND
' Сообщения от меню
Select Case HiWord(wParam)
Case BN_CLICKED, 1
Select Case LoWord(wParam)
Case 1

И чего-то не пойму. LoWord(wParam) возвращает id пункта меню.
Но ведь событие WM_COMMAND, происходит и для нажатия кнопок?
Только уже проверяеться HiWord(wParam).
Так вот вопрос: как отличить команду меню, от команды кнопки? Чему будет равна HiWord(wParam) для меню?

Case BN_CLICKED, 1 это что обозначает?

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  Eric-S в Чт Фев 05, 2009 3:17 pm

Вот что я только что прочитал.


Обратите внимание, что меню тоже шлёт сообщение WM_COMMAND, чтобы уведомить окно о своем состоянии. Как мы можем провести различие между сообщениями WM_COMMAND,
исходящими от меню и контролов? Вот ответ:

Нижнее слово wParam Верхнее слово wParam lParam
ID меню 00
ID контролаКод уведомленияХэндл дочернего окна

Вы можете видеть, что вы должны проверить lParam. Если он равен нулю, текущее сообщение WM_COMMAND было послано меню. Вы не можете использовать wParam,
чтобы различать меню и контрол, так как ID меню и ID контрола могут быть идентичными и код уведомления должен быть равен нулю.

Проверил. и моя Менюшка работает. Событие отрабатывает.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Платформа Win32 - Меню и акселераторы

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения