Перетаскивание окна (client area)

Тема в разделе "WASM.BEGINNERS", создана пользователем mc black, 16 июл 2007.

  1. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    Есть окно, которое обрабатывает WM_LBUTTONUP, необходимо также перетаскивать это окно левой клавишей мыши. Нашел один способ решения, который меня не устроил, потому что перестает обрабатываться WM_LBUTTONUP, вот он:
    Код (Text):
    1. .elseif uMsg==WM_NCHITTEST
    2.     invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    3.     .if eax==HTCLIENT
    4.         mov eax,HTCAPTION
    5.     .endif
    6.     ret
    Оно и понятно, ведь если у меня всё окно ведет себя как заголовок, то щелчков по клиентской области окна мне не видать! Но как эту ситуацию исправить я так и не додумался. Подскажите, пожалуйста, как исправить, либо может есть другой подход к перетаскиванию окна?
     
  2. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    очень, очень плохо искал!
    Код (Text):
    1. ReleaseCapture();
    2. SendMessageA(hwnd, 161, 2, 0);
     
  3. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    Осознал, виноват.. буду исправляться.. :) Код оказался давно знакомым даже мне, но я что-то запамятовал. Было бы не лишним добавить, что этот код стоит в обработчике WM_LBUTTONDOWN. И остается маленькая, но загвоздка: хотелось бы, чтобы код, ранее обрабатывавшийся у меня при WM_LBUTTONUP (теперь я его выполняю в обработчике WM_LBUTTONDOWN перед ReleaseCaptureb и SendMessageA) обрабатывался бы у меня ПОСЛЕ того, как я отпускаю кнопку мыши. Может я снова что-то не так сделал?
     
  4. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    WM_LBUTTONUP

    MSDN вроде свободен... и работает...
     
  5. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    Я конечно перечитал статьи на MSDN про сообщения мыши в клиентской и неклиентской области окна, кое-что сделал, окошко у меня перетаскивается, вот только не устраивает два момента:
    1. Отловить я могу только lmbuttondown, а мне желательно lmbuttonup (действие после отпускания кнопки мыши, которое наступает сразу после перетаскивания окна программы).
    2. Нужно видеть окно программы при перетаскивании, либо хотябы рамку. Не видно же ничего..
    Подскажите, пожалуйста, решение.

    То, что я делаю с исходниками находится здесь (сорри за непрямую ссылку, т.к. это narod):
    http://mc-black.narod.ru/dzp.htm
     
  6. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    Прошу прощения, но проблемму не смог никак решить :dntknw: Нужно отловить и обрабатывать LBUTTONUP сразу после перетаскивания формы. В Win32 Programmer's Refrence в описаниях сообщений WM_LBUTTONUP и WM_NCLBUTTONUP, что "If the mouse is not captured, the message is posted to the window beneath the cursor." / "If a window has captured the mouse, this message is not posted."

    Это распространенная задача, которая имеет простое решение. Но до которого я никак не дойду - не хватает знаний. Неужели здесь никто, как и я, не знает ответа на этот относительно простой вопрос? Помогите, плс.!!!
     
  7. kero

    kero Модератор SOURCES & 2LZ

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    1) У вас наверняка есть Spy++, а он как раз и предназначен для получения знаний такого рода, без чьей либо помощи.

    2) Ну, посмотрите вот этот местный топик, с альтернативгыми перетаскиваниями.
     
  8. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    mc black
    А почему нельзя обрабатывать WM_MOUSEMOVE+WM_LBUTTONDOWN?
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    mc black
    Ну вот "на вскидку" тупой и примитивный вариант решения на масм:
    Код (Text):
    1. .data?
    2.   X0_mouse dd ?
    3.   Y0_mouse dd ?
    4.   WinRect RECT <>
    5. .data
    6.   MouseFlag dd False
    7. .code
    8.  
    9. ; ...................................
    10.  
    11. ;===========================================================================
    12.                                 ; Левая кнопка мыши
    13. __WM_LBUTTONDOWN:
    14.   mov eax, [lparam]
    15.   mov edx, eax
    16.   cwde          ; eax = ax с учётом знака
    17.   mov [Y0_mouse], eax
    18.   shr edx, 16
    19.   movsx edx, dx
    20.   mov [X0_mouse], edx
    21.   invoke SetCapture, [hwnd] ; Захватить мышь
    22.   mov [MouseFlag], True     ; Флаг нажатости мыши
    23. mov eax, True
    24. ret
    25. ;===========================================================================
    26.                                 ; Перемещение мыши
    27. __WM_MOUSEMOVE:
    28.   .if [MouseFlag]
    29.      invoke GetWindowRect, [hwnd], addr WinRect
    30.      ; --- вычисление размеров окна ---
    31.      mov eax, [WinRect.left]
    32.      sub [WinRect.right], eax
    33.      mov eax, [WinRect.top]
    34.      sub [WinRect.bottom], eax
    35.      ; --- собственно перемещение окна ---
    36.      mov eax, [lparam]
    37.      mov edx, eax
    38.      cwde           ; eax = ax с учётом знака
    39.      sub eax, [Y0_mouse]
    40.      shr edx, 16
    41.      movsx edx, dx
    42.      sub edx, [X0_mouse]
    43.      add [WinRect.left], eax
    44.      add [WinRect.top], edx
    45.      invoke MoveWindow, [hwnd], [WinRect.left], [WinRect.top], [WinRect.right], [WinRect.bottom], True
    46.   .endif
    47. mov eax, True
    48. ret
    49. ;===========================================================================
    50.                                 ; Левая кнопка мыши
    51. __WM_LBUTTONUP:
    52.   mov [MouseFlag], False    ; сбросить флаг нажатости
    53.   invoke ReleaseCapture     ; Отпустить мышь
    54.   ;
    55.   ; ЗДЕСЬ твой остальной код LBUTTONUP !!!
    56.   ;
    57. mov eax, True
    58. ret
     
  10. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    Y_Mur
    Почему тупой? Главное решить задачу. Самый прямой способ. Других тут и не нужно.
     
  11. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    kero, Mental_Mirror, Y_Mur
    Большое спасибо за помощь!!! Я представлял себе этот вариант и раньше, вот только знаний не хватало насчет того, как захватить мышь. Теперь всё ясно, яснее некуда. Ещё раз большое вам человеческое спасибо!!! :)
     
  12. kero

    kero Модератор SOURCES & 2LZ

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    mc black

    Все-таки опять о Spy++.
    Возможно, он вам подскажет, что вместо WM_LBUTTONUP сгодится и WM_EXITSIZEMOVE, с уточняющей проверкой HT-области.
    Примерно так:
    Код (Text):
    1. ...
    2.   .elseif uMsg==WM_NCHITTEST
    3.     invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    4.     .if eax==HTCLIENT
    5.       mov eax,HTCAPTION
    6.     .endif
    7.     ret
    8.   .elseif uMsg==WM_EXITSIZEMOVE
    9.     invoke GetCursorPos,addr pt
    10.     mov eax,pt.x
    11.     and eax,0ffffh
    12.     mov ecx,pt.y
    13.     shl ecx,16
    14.     or eax,ecx
    15.     invoke DefWindowProc,hWnd,WM_NCHITTEST,0,eax
    16.     .if eax==HTCLIENT
    17. ;;     <CODE>
    18.     .endif
    19.     jmp @DefProc
    20. ...
    P.S. Однако было бы интереснее и спортивнее ловить именно WM_LBUTTONUP, не правда ли ? Ловит же его Spy++, хоть оно и Posted :)