如何在win2000下直接弹出另一个进程的窗口(200分)

  • 主题发起人 主题发起人 huntaway
  • 开始时间 开始时间
H

huntaway

Unregistered / Unconfirmed
GUEST, unregistred user!
在win98下,可以在键盘hook函数中使用SetForegroundWindow来弹出另一个进程的窗口,但<br>是在win2000下已经不允许直接弹出,而是通过闪动窗口标题来提醒用户切换。有哪位知道如<br>何在win2000下实现这个功能?我不想用SystemParametersInfo修改系统设定,因为MSDN说这<br>个必须在setup或者patch程序中调用,而我需要在主程序中实现该功能。我猜想一个In-Process<br>的Com服务器也许可以实现这个功能,希望高手为我指点迷津。
 
SetWindowPos试过没有。
 
以下是抄的,没试过:<br>void WINAPI SwitchToThisWindow ( <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HWND hWnd, &nbsp; // Handle to the window that should be activated <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOL bRestore // Restore the window if it is minimized <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); <br>由于没有原型和库,我们在使用时通常用动态联接法. <br>typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL); <br>PROCSWITCHTOTHISWINDOW SwitchToThisWindow; <br>HMODULE hUser32 = GetModuleHandle("user32"); <br>SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow"); <br>这样,我们的任务就完成了.
 
///Copy的<br>从Win98开始,微软更改了系统代码,一般的SetForegroundWindow只能将<br>状态栏中应用按钮闪烁,并没有将应用调到最前面。请使用下列函数:<br><br>function ForceForegroundWindow(hwnd: THandle): boolean;<br>const<br>&nbsp; &nbsp;SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;<br>&nbsp; &nbsp;SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;<br>var<br>&nbsp; &nbsp;timeout: DWORD;<br>begin<br>&nbsp; &nbsp;if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion<br>&gt; 4)) or<br>&nbsp; &nbsp; &nbsp; ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and<br>&nbsp; &nbsp; &nbsp; ((Win32MajorVersion &gt; 4) or ((Win32MajorVersion = 4) and<br>(Win32MinorVersion &gt; 0)))) then begin<br>&nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout,<br>0);<br>&nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,<br>TObject(0), SPIF_SENDCHANGE);<br>&nbsp; &nbsp; &nbsp; Result := SetForegroundWindow(hWnd);<br>&nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,<br>TObject(timeout), SPIF_SENDCHANGE);<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp;else<br>&nbsp; &nbsp; &nbsp; Result := SetForegroundWindow(hWnd);<br>end; { ForceForegroundWindow }<br><br>***********************<br>发现一个2000下面的方法,试一下 <br>function &nbsp;AllowSetForegroundWindow( dwProcessId:DWORD): BOOL; stdcall;<br><br>implementation<br>function AllowSetForegroundWindow; external &nbsp;'user32.dll' name 'AllowSetForegroundWindow';
 
SetWindowPos和AllowSetForegroundWindow我试过的,没有什么用。SwitchToThisWindow和<br>ForceForegroundWindow还没有试过,我试试看。
 
都试过了,没有用的,和SetForegroundWindow一样的效果。
 
to huntaway:<br>&nbsp; 上面的 ForceForegroundWindow 试了不行,但 SwitchToThisWindow 是可以的,试试:<br><br>procedure SwitchToThisWindow(hwnd: HWND; bRestore: Bool); stdcall; external 'user32.dll';<br>...<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; hwnd: THandle;<br>begin<br>&nbsp; hwnd := FindWndow(nil, '未定标题 - 记事本');<br>&nbsp; if (hwnd &lt;&gt; 0) then<br>&nbsp; &nbsp; SwitchToThisWindow(hwnd, True); <br>end;<br>...
 
我在2000下试过了,没用的,和SetForegroundWindow效果一样。
 
to huntaway:<br>&nbsp; 喔,可能是我的 D 版 Win2k 的缘故,试试这个:<br><br>function ForceForegroundWindow(hwnd: THandle): boolean;<br>var<br>&nbsp; hCurWnd: THandle;<br>begin<br>&nbsp; hCurWnd := GetForegroundWindow;<br>&nbsp; ShowWindow(hwnd, SW_SHOWNOACTIVATE);<br>&nbsp; AttachThreadInput(GetWindowThreadProcessId(hCurWnd, nil), GetCurrentThreadId, True);<br>&nbsp; Result := SetForegroundWindow(hWnd);<br>&nbsp; AttachThreadInput(GetWindowThreadProcessId(hCurWnd, nil), GetCurrentThreadId, False);<br>end;
 
见你提到了In-Process Com服务器, 是不是说两个程序都是你自己的?<br>如果是这样的话你可以考虑使用进程间通信的办法<br>或者发送一条消息叫对方弹出自己的WINDOW。
 
补充一点,建议你看看&lt;WINDOWS核心编程&gt;的第27章:<br>微软对S e t F o r e g r o u n d Wi n d o w函数增加了更多的智能。特别规定,仅<br>当调用一个函数的线程已经连接到R I T或者当前与R I T相连接的线程在一定的时间内(这个时<br>间量由S y s t e m P a r a m e t e r s I n f o函数和S P I _ S E T F O R E G R O U N D _ L O C K T I M E O U T值来控制)没有<br>收到任何输入,这个函数才有效。另外,如果有一个菜单是活动的,这个函数就失效。<br>如果不允许S e t F o r e g r o u n d Wi n d o w将窗口移到前景,它会闪烁该窗口的标题栏和任务条上该窗<br>口的按钮。用户看到任务条按钮闪烁,就知道该窗口想得到用户的注意。用户应该手工激活这个<br>窗口,看一看要报告什么信息。还可以用S y s t e m P a r a m e t e r s I n f o函数和S P I _ S E T F O R E G R O U N D -<br>F L A S H C O U N T值来控制闪烁。<br>由于这些新的内容,系统又提供了另外一些函数。如果调用A l l o w S e t F o r e g r o u n d Wi n d o w的<br>线程能够成功调用S e t F o r e g r o u n d Wi n d o w,第一个函数(见下面所列)可使指定进程的一个线<br>程成功调用S e t F o r e g r o u n d Wi n d o w。为了使任何进程都可以在你的线程的窗口上弹出一个窗口,<br>指定A S F W _ A N Y (定义为-1 )作为d w P r o c e s s I d参数:<br>此外,线程可以锁定S e t F o r e g r o u n d Wi n d o w函数,使它总是失效的。方法是调用L o c k<br>S e t F o r e g r o u n d Wi n d o w。<br>对u L o c k C o d e参数可以指定L S F W _ L O C K或者L S F W _ U N L O C K。当一个菜单被激活时,系<br>统在内部调用这个函数,这样一个试图跳到前景的窗口就不能关闭这个菜单。Wi n d o w s<br>E x p l o r e r在显示S t a r t菜单时,需要明确地调用这些函数,因为S t a r t菜单不是一个内置菜单。当<br>用户按了A l t键或者将一个窗口拉到前景时,系统自动解锁S e t F o r e g r o u n d Wi n d o w函数。这可以<br>防止一个程序一直对S e t F o r e g r o u n d Wi n d o w函数封锁。
 
后退
顶部