Не работает WM_MOVING

Тема в разделе "WASM.WIN32", создана пользователем honomer, 20 дек 2010.

  1. honomer

    honomer New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    6
    Здраствуйте! Тут такая проблемка образовалась: пытаюсь переместить окно при помощи сообщений. Отправляю ему сообщение WM_MOVING, а его потом даже в Spy++ не видно. Что я не так делаю?
    Код (Text):
    1. procedure TfmMain.btMoveClick(Sender: TObject);
    2. var x, y : integer;
    3.     h : THandle;
    4.     pos : WINDOWPOS;
    5.     mm : MINMAXINFO;
    6.     co : cardinal;
    7.     p : TPoint;
    8.     r : TRect;
    9. begin
    10.   try
    11.     x:=StrToInt(Trim(edX.Text));
    12.     y:=StrToInt(Trim(edY.Text));
    13.   except
    14.     ShowMessage('Координаты введены неверно!');
    15.     Exit;
    16.   end;
    17.  
    18.   h:=FindWindow(nil, PWideChar(cbWnd.Items[cbWnd.ItemIndex]));
    19.  
    20.   r.Top:=y; r.Left:=x; r.Right:=x+500; r.Bottom:=y+400;
    21.   PostMessage(h, WM_MOVING, WMSZ_LEFT or WMSZ_BOTTOMRIGHT, Integer(@r));
    22.  
    23. end;
     
  2. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    WM_MOVING лишь сообщает окну что его собираются передвинуть. Это сообщение посылается by Windows и не должно отправляться напрямую. Используйте WM_MOVE/MoveWindow/SetWindowPlacement.
     
  3. honomer

    honomer New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    6
    Сделал вот так. Сообщение отправляется, но окно остается на месте. Пытаюсь двигать Paint.
    Код (Text):
    1. co:= (y shl 16) or (x and $0000FFFF);
    2.   SendMessage(h, WM_MOVE, 0, co);
     
  4. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Да, ошибся на пьяную голову))) WM_MOVE присылается после того, как окно было изменено в размерах/положении. Следует использовать специализированные функции MoveWindow/SetWindowPlacement etc.
     
  5. honomer

    honomer New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    6
    Да я бы так и делал, вот только преподу уперлось чтобы окно двигалось сообщением. Причем его способ, как уже выяснилось, не работает. Что делать то? Кстати, кто-нибудь знает зачем функция MoveWindow отправляет сообщения WM_WINDOWPOSCHANGING и WM_GETMINMAXINFO перед отправкой WM_MOVING/WM_MOVE? Причем делается это иногда по несколько раз подряд. Что-то мне подсказывает, что это какой-то протокол согласования параметров. Вот только в MSDN я так ничего по этому поводу и не нашел.
     
  6. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Все они так же описаны в мсдн.
    Какой еще протокол согласования параметров))
     
  7. honomer

    honomer New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    6
    Они, конечно, описаны. Сами по себе. Вот только с какой целью они используются?
    Обычный. Ведь не каждое окно может быть перемещено. А еще с помощью сообщений для мува можно изменять размеры окна. Ну так в MSDN написано. В том, что возвращает Spy++ для вызова MoveWindow, на каждое сообщение отправляется ответ. Причем в ответе фигурирует тот же самый адрес структуры, что и в сообщении, на которое пришел этот ответ. Причем некоторые поля структуры изменили свои первоначальные значения. Вот я и подумал, что оконная процедура того окна, что я собираюсь двигать, корректирует эти значения. Вопроса - зачем это делается? Может быть окно не перемещается, потому что я задаю недопустимые значения для координат и размера? Я думаю, что факт переговоров двух окон может иметь место.
     
  8. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Большинство из них — просто оповещения. Отличить тех от этих можно по наличию реакции, т.е. по обработке возвращаемых значений, буде таковые присутствуют. В том, что Spy++ говорит о равенстве адресов переданной и возвращённой структуры, нет ничего странного: stdcall. Даже если обработчик сменит адрес структуры в стэке, он же её адрес из стэка и вытолкнет. А вот содержимое…
     
  9. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    А вы пробовали читать? Итак начнем с первого.
    Тут вам и про WM_GETMINMAXINFO написано и зачем оно отправляется. Дальше потрудитесь почитать сами)

    С чего вы взяли? Модель оконная одна для всех, разные только оконные процедуры которые обрабатывают сообщения :)
     
  10. honomer

    honomer New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    6
    Читал я все это. Судя по описанию я могу вообще на ответные сообщения не обращать никакого внимания.
    Код (Text):
    1. procedure TfmMain.btMoveClick(Sender: TObject);
    2. var x, y : integer;
    3.     h : THandle;
    4.     pos : WINDOWPOS;
    5.     mm : MINMAXINFO;
    6.     co : cardinal;
    7.     p : TPoint;
    8.     r : TRect;
    9. begin
    10.   try
    11.     x:=StrToInt(Trim(edX.Text));
    12.     y:=StrToInt(Trim(edY.Text));
    13.   except
    14.     ShowMessage('Координаты введены неверно!');
    15.     Exit;
    16.   end;
    17.   h:=FindWindow(nil, PWideChar(cbWnd.Items[cbWnd.ItemIndex]));
    18.   pos.hwnd:=h;
    19.   pos.x:=x;
    20.   pos.y:=y;
    21.   pos.flags:=SWP_DRAWFRAME or SWP_NOOWNERZORDER or SWP_NOACTIVATE or SWP_NOSIZE
    22.               or SWP_NOZORDER;
    23.   SendMessage(h, WM_WINDOWPOSCHANGING, 0, Integer(@Pos));
    24.  
    25.   p.X:=1032; p.Y:=776;
    26.   mm.ptMaxSize:=p;
    27.   p.X:=-4; p.Y:=-4;
    28.   mm.ptMaxPosition:=p;
    29.   p.x:=123; p.Y:=34;
    30.   mm.ptMinTrackSize:=p;
    31.   p.X:=1036; p.Y:=780;
    32.   mm.ptMaxTrackSize:=p;
    33.   SendMessage(h, WM_GETMINMAXINFO, 0, integer(@mm));
    34.  
    35.   r.Top:=y; r.Left:=x; r.Right:=x+500; r.Bottom:=y+400;
    36.   PostMessage(h, WM_MOVING, WMSZ_LEFT or WMSZ_BOTTOMRIGHT, Integer(@r));
    37.  
    38.   SendMessage(h, WM_WINDOWPOSCHANGED, 0, Integer(@Pos));
    39. end;
    Только все равно глухо... ((
     
  11. paralvic

    paralvic Пархоменко Александр Викторович

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    294
    Адрес:
    Нижний Новгород
    Присоединюсь к кружку столоверчения ;)
    Код (Text):
    1. ; Меняем положение и размер окна.
    2.     invoke BeginDeferWindowPos, 1
    3.     .if eax != 0
    4.     invoke DeferWindowPos, eax, hWnd, 0, Wtx, Wty, Wwd, Wht, SWP_NOSIZE ;SWP_NOMOVE
    5.     invoke EndDeferWindowPos, eax
    6.     .endif
    Код проще некуда. Комментировать, думаю излишне.
     
  12. honomer

    honomer New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    6
    Спасибо! Я уже разобрался. )