Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > SetForegroundWindow неправильно раб. в W7


Автор: Alexeyt 14.10.2010, 14:51
SetForеgroundWindow(Self.HAndle) - при работе в W7 пара раз работает
(окно появляется), потом перестает (окно мигает в taskbar, но
не появляется). что можно сделать? В XP - работает нормально.

Автор: CodeMonkey 14.10.2010, 18:27
http://www.transl-gunsmoker.ru/2010/10/blog-post_07.html.

Автор: Illusion Dolphin 25.10.2010, 17:06
Код

procedure ActivateBackgroundApplication(hWnd : THandle);
var
  hCurWnd, dwThreadID, dwCurThreadID: THandle;
  OldTimeOut: Cardinal;
  AResult: Boolean;
begin
  Application.Restore;
  ShowWindow(hWnd,SW_RESTORE);
  hWnd := Application.Handle;
  SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @OldTimeOut, 0);
  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(0), 0);
  SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
  hCurWnd := GetForegroundWindow;
  AResult := False;
  while not AResult do
  begin
    dwThreadID := GetCurrentThreadId;
    dwCurThreadID := GetWindowThreadProcessId(hCurWnd);
    AttachThreadInput(dwThreadID, dwCurThreadID, True);
    AResult := SetForegroundWindow(hWnd);
    AttachThreadInput(dwThreadID, dwCurThreadID, False);
  end;
  SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(OldTimeOut), 0);
  ShowWindow(Application.MainForm.Handle,SW_HIDE);
  ShowWindow(Application.Handle,SW_HIDE);
end;


CodeMonkey, иногда это всё же надо smile Пример - программа уже запущена, свёрнута. Пользователь берёт и нажимает на раб. столе на иконку и запускает вторую копию. А хорошо бы старую развернуть. 
P.S. Главное - не злоупотреблять!

Автор: Alexeyt 25.10.2010, 21:09
Можно и так, но я через Application.Minimize/Restore сделал.


Автор: CodeMonkey 26.10.2010, 00:18
Цитата(Illusion Dolphin @  25.10.2010,  18:06 Найти цитируемый пост)
иногда это всё же надо


И для указанного вами случая есть волшебная функция http://msdn.microsoft.com/en-us/library/ms632668(VS.85).aspx. http://www.transl-gunsmoker.ru/2010/10/blog-post_25.html (http://www.transl-gunsmoker.ru/2010/10/blog-post_26.html).

Всё. Одна функция - и никаких хаков, полностью документированное и работоспособное решение.

Добавлено @ 00:31
В коде 

Код
AttachThreadInput(dwCurrentThread, dwFGThread, TRUE);
SetForegroundWindow(hwnd); 
AttachThreadInput(dwCurrentThread, dwFGThread, FALSE);


http://www.transl-gunsmoker.ru/2010/10/blog-post_24.html. Ваше домашнее задание - объяснить почему.

Автор: robt 26.10.2010, 12:47
кстати в винде есть опция которая включает именно мигание кнопки а не всплывание окна
и тогда "иногда это всё же надо" уже идет лесом

Автор: Illusion Dolphin 28.10.2010, 14:38
CodeMonkey, Очень элегантное решение! Странно, что функция не определена в делфи (видимо это связано с совместимостью?). Кстати, обе ссылки идут за 2009\2010 год, а решения с "хаками" датируются на несколькими годами раньше. 

На счёт "домешнего задания" smile Предположу что дело в потенциальном несоответствии потоков (вызывающего процедуру и foreground - как пример - http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo.aspx ). Если это не так - буду рад хотя бы за ссылкус разъяснением  smile 

Автор: Alexeyt 28.10.2010, 14:52
Цитата(robt @  26.10.2010,  12:47 Найти цитируемый пост)
кстати в винде есть опция которая включает именно мигание кнопки а не всплывание окна


Просьба пользовать запятые. если опция включена, то поль-ль сам так захотел, и ничего тут делать не надо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)