Здраствуйте! Тут такая проблемка образовалась: пытаюсь переместить окно при помощи сообщений. Отправляю ему сообщение WM_MOVING, а его потом даже в Spy++ не видно. Что я не так делаю? Код (Text): procedure TfmMain.btMoveClick(Sender: TObject); var x, y : integer; h : THandle; pos : WINDOWPOS; mm : MINMAXINFO; co : cardinal; p : TPoint; r : TRect; begin try x:=StrToInt(Trim(edX.Text)); y:=StrToInt(Trim(edY.Text)); except ShowMessage('Координаты введены неверно!'); Exit; end; h:=FindWindow(nil, PWideChar(cbWnd.Items[cbWnd.ItemIndex])); r.Top:=y; r.Left:=x; r.Right:=x+500; r.Bottom:=y+400; PostMessage(h, WM_MOVING, WMSZ_LEFT or WMSZ_BOTTOMRIGHT, Integer(@r)); end;
WM_MOVING лишь сообщает окну что его собираются передвинуть. Это сообщение посылается by Windows и не должно отправляться напрямую. Используйте WM_MOVE/MoveWindow/SetWindowPlacement.
Сделал вот так. Сообщение отправляется, но окно остается на месте. Пытаюсь двигать Paint. Код (Text): co:= (y shl 16) or (x and $0000FFFF); SendMessage(h, WM_MOVE, 0, co);
Да, ошибся на пьяную голову))) WM_MOVE присылается после того, как окно было изменено в размерах/положении. Следует использовать специализированные функции MoveWindow/SetWindowPlacement etc.
Да я бы так и делал, вот только преподу уперлось чтобы окно двигалось сообщением. Причем его способ, как уже выяснилось, не работает. Что делать то? Кстати, кто-нибудь знает зачем функция MoveWindow отправляет сообщения WM_WINDOWPOSCHANGING и WM_GETMINMAXINFO перед отправкой WM_MOVING/WM_MOVE? Причем делается это иногда по несколько раз подряд. Что-то мне подсказывает, что это какой-то протокол согласования параметров. Вот только в MSDN я так ничего по этому поводу и не нашел.
Они, конечно, описаны. Сами по себе. Вот только с какой целью они используются? Обычный. Ведь не каждое окно может быть перемещено. А еще с помощью сообщений для мува можно изменять размеры окна. Ну так в MSDN написано. В том, что возвращает Spy++ для вызова MoveWindow, на каждое сообщение отправляется ответ. Причем в ответе фигурирует тот же самый адрес структуры, что и в сообщении, на которое пришел этот ответ. Причем некоторые поля структуры изменили свои первоначальные значения. Вот я и подумал, что оконная процедура того окна, что я собираюсь двигать, корректирует эти значения. Вопроса - зачем это делается? Может быть окно не перемещается, потому что я задаю недопустимые значения для координат и размера? Я думаю, что факт переговоров двух окон может иметь место.
Большинство из них — просто оповещения. Отличить тех от этих можно по наличию реакции, т.е. по обработке возвращаемых значений, буде таковые присутствуют. В том, что Spy++ говорит о равенстве адресов переданной и возвращённой структуры, нет ничего странного: stdcall. Даже если обработчик сменит адрес структуры в стэке, он же её адрес из стэка и вытолкнет. А вот содержимое…
А вы пробовали читать? Итак начнем с первого. Тут вам и про WM_GETMINMAXINFO написано и зачем оно отправляется. Дальше потрудитесь почитать сами) С чего вы взяли? Модель оконная одна для всех, разные только оконные процедуры которые обрабатывают сообщения
Читал я все это. Судя по описанию я могу вообще на ответные сообщения не обращать никакого внимания. Код (Text): procedure TfmMain.btMoveClick(Sender: TObject); var x, y : integer; h : THandle; pos : WINDOWPOS; mm : MINMAXINFO; co : cardinal; p : TPoint; r : TRect; begin try x:=StrToInt(Trim(edX.Text)); y:=StrToInt(Trim(edY.Text)); except ShowMessage('Координаты введены неверно!'); Exit; end; h:=FindWindow(nil, PWideChar(cbWnd.Items[cbWnd.ItemIndex])); pos.hwnd:=h; pos.x:=x; pos.y:=y; pos.flags:=SWP_DRAWFRAME or SWP_NOOWNERZORDER or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER; SendMessage(h, WM_WINDOWPOSCHANGING, 0, Integer(@Pos)); p.X:=1032; p.Y:=776; mm.ptMaxSize:=p; p.X:=-4; p.Y:=-4; mm.ptMaxPosition:=p; p.x:=123; p.Y:=34; mm.ptMinTrackSize:=p; p.X:=1036; p.Y:=780; mm.ptMaxTrackSize:=p; SendMessage(h, WM_GETMINMAXINFO, 0, integer(@mm)); r.Top:=y; r.Left:=x; r.Right:=x+500; r.Bottom:=y+400; PostMessage(h, WM_MOVING, WMSZ_LEFT or WMSZ_BOTTOMRIGHT, Integer(@r)); SendMessage(h, WM_WINDOWPOSCHANGED, 0, Integer(@Pos)); end; Только все равно глухо... ((
Присоединюсь к кружку столоверчения Код (Text): ; Меняем положение и размер окна. invoke BeginDeferWindowPos, 1 .if eax != 0 invoke DeferWindowPos, eax, hWnd, 0, Wtx, Wty, Wwd, Wht, SWP_NOSIZE ;SWP_NOMOVE invoke EndDeferWindowPos, eax .endif Код проще некуда. Комментировать, думаю излишне.