Перетаскивание окон с помощью MoveWindow
От: korggrodno  
Дата: 10.09.10 17:39
Оценка:
Хочу написать код который будет расставлять окна от одной программы (не моя программа).
Программирую я на C#.net

Вначале Я написал следующие код.

WAPI.SetCursorPos(x1,y1); // устанавливаем курсор над шапкой окна
WAPI.mouse_event((int)(WAPI.MouseEventFlags.LEFTDOWN), 0, 0, 0, 0); //надавливаем левую кнопку мыши
Thread.Sleep(100); // ждем некоторое время пока окно среагирует на клик (без этой задержки не работало)
WAPI.SetCursorPos(x2,y2); ( перемещаем курсор мыши с захваченным окном в нужное место)
WAPI.mouse_event((int)(WAPI.MouseEventFlags.LEFTUP), 0, 0, 0, 0); // отпускаем левую кнопку мыши.

И это работало.
Но у кода на лицо недостатки
1) Мышь летает по экрану во время расстановки окон
2) В коде задержка . И окна от этого видно глазом как расставляются друг за другом.

Потом я порылся по WinApi И нашел такие инструменты как SetWindowPos и MoveWindow
Переписал свой код вначале с использование SetWindowPos но были глюки и потом переписал с использованием MoveWindow
И код работал одинаково. С одним и тем же глюком.

Сейчас о глюке подробнее.

Допустим у меня есть 3 окна
посылаю всем
WAPI.MoveWindow(_handle, pX, pY, r.Width, r.Height, true);
И все окна мгновенно становятся там где нужно
Затем примерно через полминуты (в зависимости от того как прыгают динамические контролы в окнах)
То окно которому MoveWindow послано первому.
Перепрыгивает в старую позицию. (Старая позиция- та позиция у окна которая была до отправки ему MoveWindow)
Причем остальные окна после этого скачка остаются там куда их переместили. И дальше все ок.

Тот же самый глюк наблюдается со скочком первого окна .
Если закрыть второе или третье окно.

Вот лог сообщений которые окно получает во время перепрыга отловленный с помощью spy++
http://xmages.net/storage/10/1/0/b/a/upload/71504a86.jpg
Re: Перетаскивание окон с помощью MoveWindow
От: c-smile Канада http://terrainformatica.com
Дата: 10.09.10 22:51
Оценка:
Здравствуйте, korggrodno, Вы писали:


1) Не MoveWindow а http://msdn.microsoft.com/en-us/library/ms632681(VS.85).aspx со товарищи. Если у тебя несколько окон.
2) А та "одна программа" в свою оередь не делает ли MoveWindow возвращая все на круги своя?
Re[2]: Перетаскивание окон с помощью MoveWindow
От: korggrodno  
Дата: 11.09.10 03:52
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>1) Не MoveWindow а http://msdn.microsoft.com/en-us/library/ms632681(VS.85).aspx со товарищи. Если у тебя несколько окон.

Помоему DeferWindowPos тут не подоходит. У меня все окна программы я проверял спаем они не дочерние.

CS>2) А та "одна программа" в свою оередь не делает ли MoveWindow возвращая все на круги своя?

Возможно . Но я не знаю как это проверить.
И если окна таскать мышкой тогда все окна. Окна не перескакиваю не понятным образом
Re[3]: Перетаскивание окон с помощью MoveWindow
От: korggrodno  
Дата: 11.09.10 04:21
Оценка:
Засада какая то.

Почему глюк происходит только с тем окном которому MoveWindow было послано первому?

Дополнительная инфа:
Если окнам послать MoveWindow
И после этого. Первое окно схватить за шапку и чуть чуть сдвинуть. То глюк исчезает.
Если туже манипуляцию сделать со вторым или с третьим окном то глюк не исчезает.

Если не сколько раз окнам послать MoveWindow в одну позицию — это не меняет ситуацию
Если окнам послать MoveWindow в разные по зиции то глюк исчезают.
Наверно буду просто перемещать окна почти в нужную позицию а затем в нужную .

Чуть дольше и кривее код. Зато работает. Спасибо. за помощь.
Если у кого будут мысли. Полезные. Отпишите.
Буду за топиком следить еще парочку дней
Re[3]: Перетаскивание окон с помощью MoveWindow
От: Кодт Россия  
Дата: 11.09.10 06:53
Оценка:
Здравствуйте, korggrodno, Вы писали:

CS>>2) А та "одна программа" в свою оередь не делает ли MoveWindow возвращая все на круги своя?

K>Возможно . Но я не знаю как это проверить.
K>И если окна таскать мышкой тогда все окна. Окна не перескакиваю не понятным образом

Потому что, когда таскаешь мышкой, — мышиные события обрабатывает "одна программа", и у неё нет когнитивного диссонанса.
Наверно, где-то она запоминает координаты окна, а потом индусским способом пытается что-то с этим окном сделать: например, вытащить на передний план (и указывает не только z-order, но и положение).
Перекуём баги на фичи!
Re: Перетаскивание окон с помощью MoveWindow
От: CEMb  
Дата: 12.09.10 17:03
Оценка:
Здравствуйте, korggrodno, Вы писали:

K>Хочу написать код который будет расставлять окна от одной программы (не моя программа).

K>Программирую я на C#.net
Это первая ошибка при работе с окнами

K>Вначале Я написал следующие код.


K>WAPI.SetCursorPos(x1,y1); // устанавливаем курсор над шапкой окна

K>WAPI.mouse_event((int)(WAPI.MouseEventFlags.LEFTDOWN), 0, 0, 0, 0); //надавливаем левую кнопку мыши
K>Thread.Sleep(100); // ждем некоторое время пока окно среагирует на клик (без этой задержки не работало)
А на WinAPI работает!
K>WAPI.SetCursorPos(x2,y2); ( перемещаем курсор мыши с захваченным окном в нужное место)
Раз уж для нажатия используется event, то и для перемещения я бы использовал event, указывая относительные координаты как разницу (x2-x1, y2-y1)
K>WAPI.mouse_event((int)(WAPI.MouseEventFlags.LEFTUP), 0, 0, 0, 0); // отпускаем левую кнопку мыши.

K>И это работало.

K>Но у кода на лицо недостатки
K>1) Мышь летает по экрану во время расстановки окон
Мышу можно скрывать на момент перемещения.
int ShowCursor(
  BOOL bShow   // cursor visibility
);



K>2) В коде задержка . И окна от этого видно глазом как расставляются друг за другом.


K>Потом я порылся по WinApi И нашел такие инструменты как SetWindowPos и MoveWindow

no comments… Колдун! Я-то думал: цель — именно мышой окна таскать… ну, ладно, я ещё и не такое делал
K>Переписал свой код вначале с использование SetWindowPos но были глюки и потом переписал с использованием MoveWindow
K>И код работал одинаково. С одним и тем же глюком.
MoveWindow лучше не использовать, ибо окна не абдейтит.

K>Сейчас о глюке подробнее.


K>Допустим у меня есть 3 окна

K>посылаю всем
K>WAPI.MoveWindow(_handle, pX, pY, r.Width, r.Height, true);
K>И все окна мгновенно становятся там где нужно
K>Затем примерно через полминуты (в зависимости от того как прыгают динамические контролы в окнах)
K>То окно которому MoveWindow послано первому.
K>Перепрыгивает в старую позицию. (Старая позиция- та позиция у окна которая была до отправки ему MoveWindow)
K>Причем остальные окна после этого скачка остаются там куда их переместили. И дальше все ок.

K>Тот же самый глюк наблюдается со скочком первого окна .

K>Если закрыть второе или третье окно.

K>Вот лог сообщений которые окно получает во время перепрыга отловленный с помощью spy++

K>http://xmages.net/storage/10/1/0/b/a/upload/71504a86.jpg
Ну, мысли такие:
1. Только SetWindowPos, у меня с ним никогда проблем не было, даже если делать вон тем первым способом.
2. Попробовать во флагах указать SWP_FRAMECHANGED, тогда его должно "передёрнуть", и оно должно "заметить", что его сдвинули. Если не заметит, то явно послать ему WM_MOVE и WM_WINDOWPOSCHANGED
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.