полет окна

Тема в разделе "WASM.WIN32", создана пользователем artie, 2 апр 2007.

  1. artie

    artie New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2007
    Сообщения:
    7
    задачка: после двойного щелчка левой кнопки в рабочей области окна, окно начинает перемещаться в вертикальном направлении. нажатие любой клавиши заканчивает движение.

    в чем основные проблемы:
    1. по идее, после нажатия окно должно постоянно "лететь" вниз, но, проехав некоторое время, оно останавливается, хотя флажок нигде больше не сбрасывается
    2. нажатие любой клавиши во время полета не останавливает его

    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap: none
    4.  
    5. ;---------------------------------------------------------------------------
    6.  
    7. include windows.inc
    8. include kernel32.inc
    9. include user32.inc
    10.  
    11. includelib kernel32.lib
    12. includelib user32.lib
    13.  
    14. ;---------------------------------------------------------------------------
    15.  
    16. szText MACRO Name, Text:VARARG
    17.     LOCAL lbl
    18.     jmp lbl
    19.     Name db Text, 0
    20.     lbl:
    21. ENDM
    22.  
    23. return MACRO arg
    24.     mov eax, arg
    25.     ret
    26. ENDM
    27.  
    28. m2m MACRO arg1, arg2
    29.     push arg2
    30.     pop arg1
    31. ENDM
    32.  
    33. delay MACRO
    34.     local lp, lp2
    35.     push cx
    36.     mov cx, 30000
    37.     lp:
    38.         push cx
    39.         mov cx, 300
    40.         lp2: loop lp2
    41.         pop cx
    42.     loop lp
    43.     pop cx
    44. ENDM
    45.  
    46. ;---------------------------------------------------------------------------
    47.  
    48. WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    49. WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
    50.  
    51. ;---------------------------------------------------------------------------
    52.  
    53. .data
    54.     hWnd        dd 0
    55.     hInstance   dd 0
    56.     wFlag       dd 0
    57.     wX          dd 0
    58.     wY          dd 0
    59.     wWidth      dd 0
    60.     wHeight     dd 0
    61.  
    62. ;---------------------------------------------------------------------------
    63.  
    64. .code
    65. start:
    66.     invoke GetModuleHandle, NULL
    67.     mov hInstance, eax
    68.  
    69.     invoke WinMain, hInstance, NULL, NULL, SW_SHOWDEFAULT
    70.  
    71.     invoke ExitProcess, eax
    72.  
    73. ;---------------------------------------------------------------------------
    74.  
    75. WinMain proc hInst :DWORD, hPrevInst :DWORD, CmdLine :DWORD, CmdShow :DWORD
    76.  
    77.     LOCAL wc   :WNDCLASSEX
    78.     LOCAL msg  :MSG
    79.    
    80.     szText szClassName, "MyClass"
    81.  
    82.     mov wc.cbSize,      sizeof WNDCLASSEX
    83.     mov wc.style,       CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW or CS_DBLCLKS
    84.     mov wc.lpfnWndProc, offset WndProc
    85.     mov wc.cbClsExtra,  NULL
    86.     mov wc.cbWndExtra,  NULL
    87.     m2m wc.hInstance,   hInst
    88.     mov wc.hbrBackground,   COLOR_BTNFACE+1
    89.     mov wc.lpszMenuName,    NULL
    90.     mov wc.lpszClassName,   offset szClassName
    91.     mov wc.hIcon,       NULL
    92.       invoke LoadCursor, NULL, IDC_ARROW
    93.     mov wc.hCursor,     eax
    94.     mov wc.hIconSm,     NULL
    95.  
    96.     invoke RegisterClassEx, ADDR wc
    97.  
    98.     mov wX, 100
    99.     mov wY, 200
    100.     mov wWidth, 500
    101.     mov wHeight, 300
    102.  
    103.     invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW,
    104.                 ADDR szClassName,
    105.                 ADDR szClassName,
    106.                 WS_OVERLAPPEDWINDOW,
    107.                 wX, wY, wWidth, wHeight,
    108.                 NULL, NULL, hInst, NULL
    109.  
    110.     mov hWnd, eax
    111.  
    112.     invoke ShowWindow, hWnd, SW_SHOWNORMAL
    113.  
    114.     StartLoop:
    115.         invoke GetMessage, ADDR msg, NULL, 0, 0
    116.         cmp eax, 0
    117.         je ExitLoop
    118.         invoke TranslateMessage, ADDR msg
    119.         invoke DispatchMessage, ADDR msg
    120.         jmp StartLoop
    121.     ExitLoop:
    122.  
    123.     return msg.wParam
    124.  
    125. WinMain endp
    126.  
    127. ;---------------------------------------------------------------------------
    128.  
    129. WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD
    130.  
    131.     LOCAL r :RECT
    132.     LOCAL x :DWORD
    133.     LOCAL y :DWORD
    134.  
    135.     .if uMsg == WM_DESTROY
    136.  
    137.         invoke PostQuitMessage, NULL
    138.         return 0
    139.  
    140.     .elseif uMsg == WM_LBUTTONDBLCLK
    141.  
    142.         cmp wFlag, 1
    143.         je mexit
    144.         mov wFlag, 1
    145.         inc wY
    146.         invoke MoveWindow, hWin, wX, wY, wWidth, wHeight, 1
    147.        
    148.     .elseif uMsg == WM_CHAR
    149.  
    150.         mov wFlag, 0
    151.  
    152.     .elseif uMsg == WM_MOVE
    153.  
    154.         cmp wFlag, 0
    155.         je mexit
    156.         inc wY
    157.         mov wFlag, 1
    158.         delay
    159.         invoke MoveWindow, hWin, wX, wY, wWidth, wHeight, 1
    160.        
    161.     .endif
    162.  
    163.     mexit:
    164.  
    165.     invoke DefWindowProc, hWin, uMsg, wParam, lParam
    166.  
    167.     ret
    168.  
    169. WndProc endp
    170.  
    171. ;---------------------------------------------------------------------------
    172. end start
     
  2. Bohdan200

    Bohdan200 New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2005
    Сообщения:
    134
    Адрес:
    Lviv
    Нажатие клавиш не срабатывает так как процедура обраб. сообщений зафлужена сообщениями WM_MOVE. Лучше создай таймер и двигай окно по WM_TIMER
     
  3. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    только недавно такой вопрос был... юзайте поеск
     
  4. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Ну, например сделать так:

    Код (Text):
    1. ;---------------------------------------------------------------------------
    2.  
    3. WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD
    4.  
    5.     LOCAL r :RECT
    6.     LOCAL x :DWORD
    7.     LOCAL y :DWORD
    8.  
    9.     .if uMsg == WM_DESTROY
    10.  
    11.         invoke PostQuitMessage, NULL
    12.         return 0
    13.  
    14. .const
    15.     MY_TIMER_ID equ 12345
    16. .code
    17.  
    18.     .elseif uMsg == WM_LBUTTONDBLCLK
    19.         .if wFlag == 0
    20.             invoke SetTimer,
    21.                           hWin,         ;хэндл окна
    22.                           MY_TIMER_ID,  ;ID таймера
    23.                           50,           ;задержка (в миллисекундах)
    24.                           0             ;указатель на обработчик
    25.                                         ;(0 - обработчик не используется)
    26.             .if eax != 0
    27.                 mov     wFlag, 1
    28.             ;.else  - не удалось создать таймер
    29.             .endif
    30.         .endif
    31.  
    32.     .elseif uMsg == WM_CHAR
    33.             invoke KillTimer,
    34.                         hWin,           ;handle to window
    35.                         MY_TIMER_ID     ;timer identifier
    36.             .if eax != 0
    37.                 mov     wFlag, 0
    38.             ;.else - не удалось удалить таймер
    39.             .endif
    40.  
    41.     .elseif uMsg == WM_TIMER
    42.         .if wParam == MY_TIMER_ID
    43.             inc     wY
    44.             invoke MoveWindow, hWin, wX, wY, wWidth, wHeight, 1
    45.         .endif
    46.     .endif
    47.  
    48.     invoke DefWindowProc, hWin, uMsg, wParam, lParam
    49.  
    50.     ret
    51.  
    52. WndProc endp
    53.  
    54. ;---------------------------------------------------------------------------
     
  5. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    artie
    В аттаче сорц и exe, написанные по мотивам твоей программы. Падение по нажатию на любую клавишу, остановка - нажатие на любую клавишу. Что интересно, падает пока курсор мыши находится в пределах клиентской части окна, стоит мышь отвести в сторону, падение прекращается. Почему, не пойму :dntknw:
     
  6. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    artie
    Ура! Заработало!!! Сорц и ехе в аттаче
     
  7. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Стиль, кнечно, красивый, но зачем засыпать в таймере?
    и почему
    Код (Text):
    1. start:  xchg eax,ebx
    гарантивовано вернёт 0 (нуль) в ebx? (это для всей линейки win гарантровано?) и в чём преимущество такого вида процедуры окна перед простым cmp?
    [added]
    и ещё я бы добавил крестик всё-таки alt+f4 неохота жать, и обработку WM_MOVE также.
     
  8. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    asmfan
    для 2k, XP в EAX при старте гарантированно 0, для 9Х мои ехе не заработают, так как при сборке я устанавливаю ALIGN=4, да и кому это старье нужно. Процедуру окна я еще и через REP SCASD делал, и через JMP DWORD Table[EAX*4], а через DEC и SUB -- это я в BORLAND BUILDER нашел
     
  9. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    А где об этом можно прочитать? Это официальная инфа? С Вистой также?
    ну у них там ветвления присутствовали (как на бинарных деревьях), а здесь просто cmp прокатывает.
     
  10. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    asmfan
    1) через SoftIce 2k, XP все сервиспаки, в Vista не знаю
    2) был у меня и вариант последовательного приближения, если много сообщений, (100 сообщений за 7 проверок), но если не более 10 сообщений (обычно так и бывает), то дополнительные проверки себя не оправдывают. Преимущества реализации через SUB/DEC в отличие от CMP
    cmp eax,WM_CREATE (83F801h) 3 байта dec eax (48h) 1 байт
    или для рядом расположенных сообщений, например WM_LBUTTONDOWN=201h и WM_LBUTTONUP=202h
    cmp eax,WM_LBUTTONDOWN (3D01020000h) - 5 байт
    je WMLBUTTONDOWN (7411h) 2 байта
    cmp eax,WM_LBUTTONUP (3D02020000h) 5 байт
    je WMLBUTTONUP (7418h) 2 байта - итого 14 байт
    сравните с
    sub eax,WM_LBUTTONDOWN (2D01020000h) 5 байт
    je WMLBUTTONDOWN (7403h) 2 байта
    dec eax (48h) 1 байт
    je WMLBUTTONUP (740E) 2 байта - итого 10 байт
    Разве не дзенно? Кроме того DEC/SUB дают мне EAX=0, и по-моему они быстрее (хотя для процедуры окна это не актуально). Вообще стараюсь оптимизировать по размеру.
     
  11. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    asmfan
    Если интересно, в аттаче глава из книги.
    [add]
    Упс! Не аттачится :dntknw:
     
  12. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Mikl__, извращенец...

    Есс-но, какая обработка исключений, если главное - Дзен… И Гейтс с ним, с 9х, этим старьём ведь уже никто не пользуется…
     
  13. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Mikl__, пожалуй, для оптимизации по размеру это хороший способ, по скорости не самый, т.к. всё-равно присутствует полный перебор сообщений. /и, кстати, что это за источник, если не секрет? занятно поглядеть/
     
  14. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    asmfan
    Это я :)
    G13
    конкретнее... в чем изврат?
     
  15. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Уже написал - страдает совместимость и эксепшены %))
     
  16. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Mikl__, пишешь книгу? браво!!
     
  17. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    G13
    какие эксепшены в учебном примере?!! А насчет совместимости, почему никто не требует поддержки Win3.11, DOS и *nix, я же не виря написал;)
     
  18. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Mikl__, валяешь меня под столом просто! %)

    “Даёшь совместимость Win32PE приложений с NIX/BSD системами к концу третьего квартала!” %))))))))))))
     
  19. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    G13
    Есть же в PE DOS-stub, почему бы туда еще и ELF'а не впихнуть?
     
  20. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Mikl__, можно, конечно.

    Тот же HiEW, например. Но ИМХО - сие изврат, по сути ты пишешь две программы сразу. Проще уж сделать отдельно ELF и Win32 версию.