Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.08.14;
Скачать: [xml.tar.bz2];

Вниз

Окно на передний план !   Найти похожие ветки 

 
gdaujk ©   (2005-06-13 13:50) [0]

Столкнулся со следующей проблеммой. Мне надо, что бы при получении окошком моей программы сообщения WM_XXX, оно(окошко)  показалось пользователю на глаза. В оконной процедуре пишу:

if Msg = WM_XXX then
   begin
     ShowWindow(MainWnd, SW_SHOWNORMAL);
     SetForegroundWindow(MainWnd);
   end;


Если моё окошко было свёрнуто до получения WM_XXX, то оно восстанавливается и выходит на передний план, как и задумывалось.

Но  если окно свёрнуто не было, а просто находилось на заднем плане, то на передний  оно не выходит, а начинает мигать на панели задач. Нехорошо :-).

PS: Eсли те же две функции вызвать из другого приложения, передав им хендл моего окошка, то всё работает отлично -  окно показывается в любом случае.

Подскажите, как сделать, что бы оконце выходила на передний план в любом случае?


 
gdaujk ©   (2005-06-13 15:33) [1]

Ну и...


 
Ученик   (2005-06-13 19:47) [2]

>gdaujk ©   (13.06.05 13:50)  

Возможно, поможет

var
hForeGround : HWnd;
begin
hForeGround := GetForegroundWindow;
AttachThreadInput(GetWindowThreadProcessId(hForeGround, nil),
                  GetWindowThreadProcessId(Handle, nil), True);
SetForegroundWindow(Handle);
end;


 
gdaujk ©   (2005-06-14 07:49) [3]

Неа, AttachThreadInput не помог.

Попробую поставить проблему шире. Использую мьютексы для избежания повтороного запуска приложения. Так вот второй экземпляр в самом начале узнаёт, что но не первый :-) Ему конечно можно просто вырубиться, но лучше чтоб он перед этим передал управление первому экземпляру. Для эого он и посылает первому (да и всем остальным окнам) сообщение WM_XXX. А тот  при получении сообщения, по моему замыслу, показывает себя пользователю. Вот последний пункт и не выходит :-(

PS: Видел вариант, при котором первый экземпляр после получения WM_XXX слал второму ответное сообщение - WM_YYY, в котором передавал хендал своего окна, а тот уже занимался выводом первого на глаза ползователю. Но там у обоих экземпляров приложения уже были созданы окна. У меня же окно только у первого. Как же ему передать хендал?


 
dmitry501 ©   (2005-06-14 08:45) [4]

gdaujk ©   (14.06.05 7:49) [3]

Мигание кнопки на панели задач

Время, отведенное на мигание
Когда программа требует ввода данных, она может либо выскочить на передний план, либо начать мигать кнопкой на панели задач. Вы можете установить время,в течении которого программа будет сигнализировать перед этим выходом. Для этого нужно в разделе
HKEY_CURRENT_USER\Control Panel\Desktop создать или изменить параметр ForegroundLockTimeout типа DWORD и установить его значение на время задержки до "перехвата" фокуса в миллисекундах: 0 — окно сразу выскакивает вперед, 200 000 — значение по умолчанию.
Количество миганий
Также вы можете установить число миганий кнопки. Для этого надо в этом же разделе создать или изменить DWORD-параметр ForegroundFlashCount и установить его значение на нужное число миганий для привлечения внимания пользователя. Значения устанавливаются в десятичной системе: 0 заставит кнопку мигать бесконечно, по умолчанию значение равно 3


 
Ботвин Дмитрий   (2005-06-14 08:51) [5]

Попробуй BringWindowToTop(Handle)


 
DVM ©   (2005-06-14 10:06) [6]

Windows 98/2000 doesn"t want to foreground a window when
 some other window has the keyboard focus.
 ForceForegroundWindow is an enhanced SetForeGroundWindow/bringtofront
 function to bring a window to the front.
}

{
 Manchmal funktioniert die SetForeGroundWindow Funktion
 nicht so, wie sie sollte; besonders unter Windows 98/2000,
 wenn ein anderes Fenster den Fokus hat.
 ForceForegroundWindow ist eine "verbesserte" Version von
 der SetForeGroundWindow API-Funktion, um ein Fenster in
 den Vordergrund zu bringen.
}

function ForceForegroundWindow(hwnd: THandle): Boolean;
const
 SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
 SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
 ForegroundThreadID: DWORD;
 ThisThreadID: DWORD;
 timeout: DWORD;
begin
 if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);

 if GetForegroundWindow = hwnd then Result := True
 else
 begin
   // Windows 98/2000 doesn"t want to foreground a window when some other
   // window has keyboard focus

   if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion > 4)) or
     ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
     ((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and
     (Win32MinorVersion > 0)))) then
   begin
     // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm
     // Converted to Delphi by Ray Lischner
     // Published in The Delphi Magazine 55, page 16

     Result := False;
     ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);
     ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);
     if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then
     begin
       BringWindowToTop(hwnd); // IE 5.5 related hack
       SetForegroundWindow(hwnd);
       AttachThreadInput(ThisThreadID, ForegroundThreadID, False);
       Result := (GetForegroundWindow = hwnd);
     end;
     if not Result then
     begin
       // Code by Daniel P. Stasinski
       SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);
       SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),
         SPIF_SENDCHANGE);
       BringWindowToTop(hwnd); // IE 5.5 related hack
       SetForegroundWindow(hWnd);
       SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);
     end;
   end
   else
   begin
     BringWindowToTop(hwnd); // IE 5.5 related hack
     SetForegroundWindow(hwnd);
   end;

   Result := (GetForegroundWindow = hwnd);
 end;
end; { ForceForegroundWindow }

// 2. Way:
//**********************************************

procedure ForceForegroundWindow(hwnd: THandle);
 // (W) 2001 Daniel Rolf
 // http://www.finecode.de
 // rolf@finecode.de
var
 hlp: TForm;
begin
 hlp := TForm.Create(nil);
 try
   hlp.BorderStyle := bsNone;
   hlp.SetBounds(0, 0, 1, 1);
   hlp.FormStyle := fsStayOnTop;
   hlp.Show;
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
   SetForegroundWindow(hwnd);
 finally
   hlp.Free;
 end;
end;

// 3. Way:
//**********************************************
// by Thomas Stutz

{
 As far as you know the SetForegroundWindow function on Windows 98/2000 can
 not force a window to the foreground while the user is working with another window.
 Instead, SetForegroundWindow will activate the window and call the FlashWindowEx
 function to notify the user. However in some kind of applications it is necessary
 to make another window active and put the thread that created this window into the
 foreground and of course, you can do it using one more undocumented function from
 the USER32.DLL.

 void SwitchToThisWindow (HWND hWnd,  // Handle to the window that should be activated
 BOOL bRestore // Restore the window if it is minimized
);

}

procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall;
 external user32 Name "SwitchToThisWindow";
        {x = false: Size unchanged, x = true: normal size}

procedure TForm1.Button2Click(Sender: TObject);
begin
 SwitchToThisWindow(FindWindow("notepad", nil), True);
end;


 
gdaujk ©   (2005-06-14 12:00) [7]

>>Ботвин Дмитрий

Не помогает, но спасибо :-)

>>DVM

Щас попробую, только с учёбы пришёл :-) Спасибо...


 
gdaujk ©   (2005-06-14 12:34) [8]

SwitchToThisWindow - делает то же самое, поэтому наверное и не документированна.

А вот вариант один, правда урезанный мной до:


if IsIconic(MainWnd)
then ShowWindow(MainWnd, SW_RESTORE)
else
 begin
   AttachThreadInput(
            GetWindowThreadProcessId(GetForegroundWindow, nil),
            GetWindowThreadProcessId(MainWnd, nil), True);

   SetForegroundWindow(MainWnd);
   AttachThreadInput(
            GetWindowThreadProcessId(GetForegroundWindow, nil),
            GetWindowThreadProcessId(MainWnd, nil), False);
 end;


в XP работет замечательно.

Только можно объяснить, зачем

BringWindowToTop(hwnd); // IE 5.5 related hack

и зачем проверка номера Винды, если

Windows 98/2000 doesn"t want...???


 
gdaujk ©   (2005-06-14 12:39) [9]

Вариант два совсем не пойдёт, ибо:
1. Я не создаю окно второго экземпляра, не буду создавать и второе окно у первого, это слишком долго...
2. VCL, а я пишу на API...



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.08.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.012 c
1-1122426473
Vasian
2005-07-27 05:07
2005.08.14
Проблема с работой с канвой объекта TPrinter


4-1118679326
ATarget
2005-06-13 20:15
2005.08.14
драйвер


3-1120734264
Kreyl
2005-07-07 15:04
2005.08.14
Еще один чайницкий: как вызнать max и min значения


1-1122042824
Mx
2005-07-22 18:33
2005.08.14
Как глобально отлавливать исключения?


14-1121764709
reticon
2005-07-19 13:18
2005.08.14
Загрузка процессора и svchost.exe





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский