![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
работа с окнами через WinApi в Windows 2000
Greg123 © (2005-05-26 15:00:00)У меня есть программа, которая запускает другое приложение и программно нажимает в нём кнопки.
Эта прога отлично работает в Windows XP, но перестаёт работать в Windows 2000, т.е. например по активации окна функциями SetForegroundWindow или SetWindowPos вместо развёртывания окон они только мигают или запускается копия приложения.
Как это поправить???
Вот для примера кусок кода:
window_handle:=FindWindow(nil,pchar('exe Программа'));
if window_handle0 then
begin
SetForegroundWindow(window_handle);
button_handle:=FindWindowEx(window_handle,0,nil,pchar ('&Контроль'));
if(button_handle0) then
begin
SetForegroundWindow(button_handle);
keybd_event(VK_RETURN,0,0,0);
keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
//или так SendMessage(button_handle,bm_click,0,0);
i := 1;
end;
end;
Sleep(7000);
end;
Hrom005 (2005-06-13 03:37:00) [1]Всем привет! Будьте человеками, скиньте прогу - позарез надо
alpet (2005-05-27 14:50:00) [2]Очень даже может быть. Другое дело тебе надо все же посмотреть какие сообщения получает эта кнопка и само окно когда ее мышью нажимаешь.
Greg123 (2005-05-27 12:36:00) [3]Может дел в том, что класс кнопки TRzButton?
alpet (2005-05-27 11:33:00) [4]Стоит тогда проверить какие сообщения принимает окно window_handle, при нажатии кнопки мышью (с помощью Wingsight32 / Spy++). По идее сообщение WM_COMMAND используется в большинстве случаев для обработки событий от контролов и элементов меню.
Greg123 (2005-05-27 11:03:00) [5]Да я проверял дискрипторы и у окна и у кнопки находятся
button_handle - кнопка
window_handle - окно
Если можно расшифруй эту команду(3 и 4 параметры)
Может ещё дело в том, что дискриптор кнопки имеет & (кнопка имеет комбинацию горячих клавиш)???
Может у тебя есть какой-нибудь пример работы данной команды?
alpet (2005-05-27 10:53:00) [6]Greg123 (27.05.05 09:08) [25]
Кнопка конечно нажаться не должна, но окно должно обработать ее нажатие :), если это конечно кнопка. В отладчике у тебя window_handle точно не нулевое ?
Greg123 (2005-05-27 09:08:00) [7]ReliableSetForegroundWindow попробовал эту процедуру, но при смене фокуса нужное окно не выходит на передний план
Так же попробовал по старому SetForegroundWindow(window_handle) вместе с функцией PostMessage (window_handle, WM_COMMAND, BN_CLICKED shl 16, button_handle) - ничего не происходит
Если я правильно понял по этому сообщению должна нажаться кнопка даже если окно в данный момент не активно?
Greg123 (2005-05-26 21:16:00) [8]Спасибо за ответы!!!
vertal (2005-05-26 20:12:00) [9]Так в 2000 работает:
procedure ReliableSetForegroundWindow(const HWND: HWND);
var
hThreadToAttach: DWORD;
begin
hThreadToAttach := GetWindowThreadProcessId(HWND, nil);
AttachThreadInput(GetCurrentThreadId, hThreadToAttach, TRUE);
if IsIconic(HWND) then ShowWindow(HWND, SW_RESTORE);
BringWindowToTop(HWND);
SetForegroundWindow(HWND);
AttachThreadInput(GetCurrentThreadId, hThreadToAttach, FALSE);
SendMessage(GetDesktopWindow(), WM_SYSCOMMAND, WPARAM(SC_HOTKEY), LPARAM(HWND));//fatality
end;
alpet (2005-05-26 18:52:00) [10]Забыл, добавь первый параметр window_handle, или что-там у тебя это окно идентифицирует.
PostMessage (window_handle, WM_COMMAND, BN_CLICKED shl 16, button_handle);???
Greg123 (2005-05-26 18:15:00) [11]Пишет:
Not enough actual parameters
Я только начал изучать Delphi
Так что даже не знаю где здесь ошибка
???PostMessage (WM_COMMAND, BN_CLICKED shl 16, button_handle);???
Напиши пожалуйста правильно
alpet (2005-05-26 18:08:00) [12]bm_click это симуляторное сообщение :).
Лучше отправь сообщение самому окну, типа такого:
PostMessage (WM_COMMAND, BN_CLICKED shl 16, button_handle);
Greg123 (2005-05-26 17:58:00) [13]Я пробовал:
SendMessage(button_handle,bm_click,0,0);
но если окно не активно, то результат тот же
или нужно как то по другому примения эту функцию SendMessage(PostMessage)
alpet (2005-05-26 17:54:00) [14]Если не трогать приложение, то всё нормально, все кнопки нажимаются, но если во время работы программы переключаться между окнами. то теряется фокус и я не могу программно нажать кнопку на окне.
Если использовать не keybd_event, а PostMessage то сможешь, а это гораздо лучше (окно не будет всплывать в неожиданных ситуациях).
Greg123 (2005-05-26 17:52:00) [15]Окно у меня не свёрнуто а просто не активно (закрыто другим окном)
window_handle - дескриптор окна, на котором кнопка
button_handle - дескриптор самой кнопки
Суть моей проблемы:
Если не трогать приложение, то всё нормально, все кнопки нажимаются, но если во время работы программы переключаться между окнами. то теряется фокус и я не могу программно нажать кнопку на окне.
alpet (2005-05-26 17:50:00) [16]1. Тебе надо получить id потока которому принадлежит окно (id_another_thread), проще всего через GetWindowThreadProcessId
2. Получить id текущего потока (id_current_thread)
3. Вызвать AttachThreadInput (id_current_thread, id_another_thread, true)
4. Вызвать SetForegroundWindow (window_handle);
5. Вызвать AttachThreadInput (id_current_thread, id_another_thread, false), для отключения (detach) механизма обработки ввода.
ANB (2005-05-26 17:43:00) [17]SetForegroundWindow( window_handle); У тебя, кажись, button.
ANB (2005-05-26 17:42:00) [18]Так оно у тебя свернуто что ли ? Я гонял свою прогу на 2000 - все работает. Если окно не сворачивал.
Greg123 (2005-05-26 17:31:00) [19]А в Windows XP всё нормально : окно разворачивается,
проблема в том, что мне надо и Windows 2000 и XP
Greg123 (2005-05-26 17:29:00) [20]У меня в первоначальном коде используется данная функция.
Результат:
При потере фокуса окно на панели задач начинает мигать и кнопка из-за этого не нажимается