CreateAcceleratorTable

Discussion in 'WASM.BEGINNERS' started by JAPH, Jul 17, 2007.

  1. JAPH

    JAPH New Member

    Blog Posts:
    0
    Рабочий вариант:
    Code (Text):
    1. //---------------------RC---------------------
    2. #include    "\masm32\include\resource.h"
    3. 136 ACCELERATORS
    4. BEGIN
    5.     VK_F5, 100, ALT, VIRTKEY
    6. END
    7. ;--------------------ASM---------------------
    8.         .486
    9.         .model  flat, stdcall
    10.         option  casemap: none
    11.         .nolist
    12. include     \masm32\include\windows.inc
    13. include     \masm32\include\kernel32.inc
    14. include     \masm32\include\user32.inc
    15.         .listall
    16. includelib  \masm32\lib\kernel32.lib
    17. includelib  \masm32\lib\user32.lib
    18.         .data?
    19. ha      HACCEL      ?
    20. hwMain      HWND        ?
    21. mes     MSG     <?>
    22.         .data
    23. wcx     WNDCLASSEX  <sizeof wcx, 0, offset mwp, 0, 0, ?, ?, ?, COLOR_APPWORKSPACE + 1, 0, offset mwcn, ?>
    24. mwcn        db      'MainWinClass', 0
    25. qn      db      '&Quit', 0
    26.         .code
    27. mwp     proc    hw: HWND, ms: UINT, wp: WPARAM, lp: LPARAM
    28.         .if ms == WM_DESTROY
    29.             invoke  PostQuitMessage, 0
    30.             xor eax, eax
    31.         .elseif ms == WM_CREATE
    32.             push    ebx
    33.             invoke  CreateMenu
    34.             mov ebx, eax
    35.             invoke  AppendMenu, ebx, MF_STRING, 100, offset qn
    36.             invoke  SetMenu, hw, ebx
    37.             pop ebx
    38.         .elseif ms == WM_COMMAND
    39.             movzx   eax, word ptr wp + 2
    40.             dec eax
    41.             jz  @F
    42.             inc eax
    43.             jnz @def
    44. @@:         movzx   eax, word ptr wp
    45.             .if eax == 100
    46.                 invoke  PostQuitMessage, 0
    47.             .endif
    48.             xor eax, eax
    49.         .else
    50. @def:           invoke  DefWindowProc, hw, ms, wp, lp
    51.         .endif
    52.         ret
    53. mwp     endp
    54. @:      invoke  GetModuleHandle, 0
    55.         mov wcx.hInstance, eax
    56.         invoke  LoadAccelerators, eax, 136
    57.         mov ha, eax
    58.         invoke  LoadIcon, 0, IDI_APPLICATION
    59.         mov wcx.hIcon, eax
    60.         mov wcx.hIconSm, eax
    61.         invoke  LoadCursor, 0, IDC_ARROW
    62.         mov wcx.hCursor, eax
    63.         invoke  RegisterClassEx, offset wcx
    64.         invoke  CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, offset mwcn, offset mwcn, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, wcx.hInstance, 0
    65.         test    eax, eax
    66.         jz  @quit
    67.         mov hwMain, eax
    68.         invoke  ShowWindow, eax, SW_SHOWDEFAULT
    69. @@:     invoke  GetMessage, offset mes, 0, 0, 0
    70.         inc eax
    71.         jz  @quit
    72.         dec eax
    73.         jz  @quit
    74.         invoke  TranslateAccelerator, hwMain, ha, offset mes
    75.         test    eax, eax
    76.         jnz @B
    77.         invoke  TranslateMessage, offset mes
    78.         invoke  DispatchMessage, offset mes
    79.         jmp @B
    80. @quit:      invoke  ExitProcess, 0
    81.         end @
    Нерабочий:
    Code (Text):
    1. ;--------------------ASM---------------------
    2.         .486
    3.         .model  flat, stdcall
    4.         option  casemap: none
    5.         .nolist
    6. include     \masm32\include\windows.inc
    7. include     \masm32\include\kernel32.inc
    8. include     \masm32\include\user32.inc
    9.         .listall
    10. includelib  \masm32\lib\kernel32.lib
    11. includelib  \masm32\lib\user32.lib
    12.         .data?
    13. ha      HACCEL      ?
    14. hwMain      HWND        ?
    15. mes     MSG     <?>
    16.         .data
    17. wcx     WNDCLASSEX  <sizeof wcx, 0, offset mwp, 0, 0, ?, ?, ?, COLOR_APPWORKSPACE + 1, 0, offset mwcn, ?>
    18. accs        ACCEL       <FALT or FVIRTKEY, VK_F5, 100>
    19. mwcn        db      'MainWinClass', 0
    20. qn      db      '&Quit', 0
    21.         .code
    22. mwp     proc    hw: HWND, ms: UINT, wp: WPARAM, lp: LPARAM
    23.         .if ms == WM_DESTROY
    24.             invoke  PostQuitMessage, 0
    25.             xor eax, eax
    26.         .elseif ms == WM_CREATE
    27.             push    ebx
    28.             invoke  CreateMenu
    29.             mov ebx, eax
    30.             invoke  AppendMenu, ebx, MF_STRING, 100, offset qn
    31.             invoke  SetMenu, hw, ebx
    32.             pop ebx
    33.         .elseif ms == WM_COMMAND
    34.             movzx   eax, word ptr wp + 2
    35.             dec eax
    36.             jz  @F
    37.             inc eax
    38.             jnz @def
    39. @@:         movzx   eax, word ptr wp
    40.             .if eax == 100
    41.                 invoke  PostQuitMessage, 0
    42.             .endif
    43.             xor eax, eax
    44.         .else
    45. @def:           invoke  DefWindowProc, hw, ms, wp, lp
    46.         .endif
    47.         ret
    48. mwp     endp
    49. @:      invoke  GetModuleHandle, 0
    50.         mov wcx.hInstance, eax
    51.         invoke  CreateAcceleratorTable, offset accs, 1
    52.         mov ha, eax
    53.         invoke  LoadIcon, 0, IDI_APPLICATION
    54.         mov wcx.hIcon, eax
    55.         mov wcx.hIconSm, eax
    56.         invoke  LoadCursor, 0, IDC_ARROW
    57.         mov wcx.hCursor, eax
    58.         invoke  RegisterClassEx, offset wcx
    59.         invoke  CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, offset mwcn, offset mwcn, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, wcx.hInstance, 0
    60.         test    eax, eax
    61.         jz  @quit
    62.         mov hwMain, eax
    63.         invoke  ShowWindow, eax, SW_SHOWDEFAULT
    64. @@:     invoke  GetMessage, offset mes, 0, 0, 0
    65.         inc eax
    66.         jz  @quit
    67.         dec eax
    68.         jz  @quit
    69.         invoke  TranslateAccelerator, hwMain, ha, offset mes
    70.         test    eax, eax
    71.         jnz @B
    72.         invoke  TranslateMessage, offset mes
    73.         invoke  DispatchMessage, offset mes
    74.         jmp @B
    75. @quit:      invoke  DestroyAcceleratorTable, ha
    76.         invoke  ExitProcess, 0
    77.         end @
    CreateAcceleratorTable вызывается успешно, даже DestroyAcceleratorTable возвращает 1, но нужного WM_COMMAND никак не дождаться, если только не через меню. Где налажал?
     
  2. shoo

    shoo New Member

    Blog Posts:
    0
    Code (Text):
    1. msg_loop:
    2.     invoke GetMessage,msg,NULL,0,0
    3.     or  eax,eax
    4.     jz  exit
    5.     invoke TranslateAccelerator,[hMain],[hAcc],msg
    6.     or  eax,eax
    7.     jnz @F
    8.     invoke TranslateMessage,msg
    9. @@:
    10.     invoke DispatchMessage,msg
    11.     jmp msg_loop
    12. exit:
    13.     invoke ExitProcess,[msg.wParam]
    если TranslateAccelerator было успешным, то нужно пропустить TranslateMessage, а DispatchMessage выполнить всё равно, а у тебя во втором варианте идет возврат назад к GetMessage
     
  3. JAPH

    JAPH New Member

    Blog Posts:
    0
    shoo
    Не-а, не сработало. Да и наверняка проблема не в этом, ибо первый вариант работает и без довыполнения DispatchMessage.

    Если во втором варианте поставить брейк на команду после TranslateAccelerator по условию eax != 0, он не сработает. Почему?
     
  4. shoo

    shoo New Member

    Blog Posts:
    0
    1.
    Code (Text):
    1. ;accs  ACCEL <FALT or FVIRTKEY, VK_F5, 100>
    2. accs    dw FALT or FVIRTKEY
    3.         dw VK_F5
    4.         dw 100
    2.
    Code (Text):
    1.         invoke  TranslateAccelerator, hwMain, ha, offset mes
    2.         test    eax, eax
    3.         jnz dispatch
    4.         invoke  TranslateMessage, offset mes
    5. dispatch:
    6.         invoke  DispatchMessage, offset mes
     
  5. JAPH

    JAPH New Member

    Blog Posts:
    0
    Ура! Спасибо! Заработало!

    "1." помогло, "2." ignored :) since: у Iczeliona см. тут. 34
    Code (Text):
    1. invoke TranslateAccelerator, ...
    2. .if eax == 0
    3.     invoke TranslateMessage, ...
    4.     invoke DispatchMesage, ...
    5. .endif
    Хотя с "2." тоже работает. Судя по доке, ваше предложение правильное. Однако учат другому :)

    По поводу "1.": странно, как в доке, так и в windows.inc
    ACCEL struct
    fVirt BYTE ?
    key WORD ?
    cmd WORD ?
    ACCEL ends
    Это смело можно исправлять? Откуда такая погрешность? Есть ещё подобные подвохи?
     
  6. n0name

    n0name New Member

    Blog Posts:
    0
    JAPH
    выравнивание.
     
  7. shoo

    shoo New Member

    Blog Posts:
    0
    1.масм (как и фасм) не выравнивает члены структур по их размеру, но это делают компиляторы Си. т.е. правильно это выглядит так:
    Code (Text):
    1. ACCEL struct
    2.   fVirt BYTE ?
    3.   align 2               ;<-- это неявно подразумевается
    4.   key   WORD ?
    5.   cmd   WORD ?
    6. ACCEL ends
    2.личное дело ;)