把窗口显示出来(包括最小化的窗口也能恢复最小化前大小)(50分)

  • 主题发起人 主题发起人 iamfly
  • 开始时间 开始时间
I

iamfly

Unregistered / Unconfirmed
GUEST, unregistred user!
今天在inside programming里看到一篇关于窗口切换的,恬好用在我曾经做过的程序上。<br>不敢一人独享,特拿出来,希望大家有用:)<br>原文是这样的(部分):98/2000下,有个公开的函数SetForegroundWindow,用于切换前台窗口.<br>但是事实上,SetForegroundWindow并不能用于和其他进程的窗口协同工作,通常情况下<br>SetForegroundWindow会调用FlashWindowEx来闪烁目标窗口,代表已经切换了窗口,但是这不<br>是我们需要的.网络上有一些顶尖高手使用修改窗口切换的系统规则后,用SetForegroundWindow<br>切换到其他进程的窗口,但是现在,我们有了UNDOCUMENTED的另外一个USER32函数: <br>SwitchToThisWindow(...); <br>来完成这项工作. <br>那么原型是怎么的呢? 下面就来揭晓了...... <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>我在DELPHI中试了一下,成功了:)<br>我的实现部分代码如下:<br>
代码:
<br>//首先,在你的FORM的PRIVATE里,定义相关procedure与变量:<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp;...<br>&nbsp; &nbsp;...<br>&nbsp; private<br>&nbsp; &nbsp; hooklib: thandle;<br>&nbsp; &nbsp; switchwin: procedure(hwnd:thandle;brestore:boolean);stdcall; &nbsp; <br>//第一个参数传递你要SHOW的窗口句柄,第二个参数是TRUE时如果窗口是最小化状态,就恢复最小化前状态<br>&nbsp; ...<br>&nbsp; ...<br>&nbsp; end; <br>//再在FORM的oncreate事件里写入两行代码:<br>&nbsp; hooklib:=getmodulehandle('USER32');<br>&nbsp; @switchwin := getprocaddress(hooklib, 'SwitchToThisWindow');<br><br>//最后,在你要用到的地方调用switchwin,比如这样:<br>switchwin(w_HidedWindow,true)就可以了<br>
<br>我的软件环境:98SE+DELPHI5(未打补丁)
 
我在Win2k下试过了,和Application.BringToFont的效果一样——只能闪烁目标窗口。[:(]<br><br>我是用Hook监视剪贴板,一旦发生了变化,就激活我的程序——在NT4下工作正常,2000下搞不定。
 
我另一台机中的2000暂时不能用(那台机今天下午要给领导培训)<br>我可能要今晚或是明天才能调试在2000下的了。如果你有结果了,请告诉我一声,谢了:)<br>[:)]
 
creation-zy,你的系统软件配置如何?我在一台WIN2000 PROFESSIONAL+DELPHI5下试过,<br>没问题。2000和DELPHI都尚未打任何补丁。
 
用showwindow函数如何
 
我原来用的就是showwindow函数,不行的:)
 
看看:)
 
////这是hook的实现<br>unit hooktest;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, <br>&nbsp; Dialogs,StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; HookKey: TButton;<br>&nbsp; &nbsp; UnhookKey: TButton;<br>&nbsp; &nbsp; procedure HookKeyClick(Sender: TObject);<br>&nbsp; &nbsp; procedure UnhookKeyClick(Sender: TObject);<br>&nbsp; &nbsp; procedure FormClose(Sender: TObject; var Action: TCloseAction);<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; hNextHookProc: HHook;<br>&nbsp; AppHandle &nbsp; &nbsp;: HWND;<br><br>implementation<br><br>{$R *.DFM}<br>function KeyboardHookHandler(iCode: Integer;<br>&nbsp; wPm: WPARAM;lPm: LPARAM): LRESULT; stdcall;<br>const<br>&nbsp; _KeyPressMask = $80000000;<br>begin<br>&nbsp; Result := 0;<br>&nbsp; If iCode &lt; 0 Then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := CallNextHookEx(hNextHookProc, iCode, wPm, lPm);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br>&nbsp; if ((lPm and _KeyPressMask) = 0) and<br>&nbsp; &nbsp; (GetKeyState(vk_Control) &lt; 0) and (wPm = ord('H')) then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := 1;<br>&nbsp; &nbsp; if AppHandle =0 then<br>&nbsp; &nbsp; &nbsp; AppHandle := FindWindow(nil,'Hook Demo');<br>&nbsp; &nbsp; if AppHandle &lt;&gt;0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; if IsIconic(AppHandle) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(AppHandle,sw_restore);<br>&nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForeGroundWindow(AppHandle);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.HookKeyClick(Sender: TObject);<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_KEYBOARD,<br>&nbsp; &nbsp; KeyboardHookHandler,<br>&nbsp; &nbsp; HInstance,<br>&nbsp; &nbsp; 0);<br>&nbsp; if hNextHookProc&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; &nbsp; ShowMessage('hook ok!');<br>&nbsp; end;<br>end;<br><br>procedure TForm1.UnhookKeyClick(Sender: TObject);<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowshookEx(hNextHookProc);<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; &nbsp; MessageBeep(0);<br>&nbsp; end;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; &nbsp; &nbsp;ShowMessage('unhook failed!');<br>end;<br><br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then UnhookKeyClick(nil);<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; hNextHookProc :=0;<br>&nbsp; AppHandle :=0;<br>&nbsp; Application.Title := 'Hook Demo';<br>end;<br><br>end.<br><br>
 
我的程序中并不用用到HOOK,只是用到REGISTERHOTKEY而已。而且,无论用什么都好。你<br>可以这样试试,先把一个窗口用showwindow(hWnd,sw_hide)隐藏起来,此时是没有窗口是<br>聚焦(即你看不到有窗口的最上面的标题栏是变蓝的),你用鼠标点击任一个窗口,聚焦这<br>个窗口,然后,再用showwindow(hwnd,sw_show)也好,setforegroundwindows也好,<br>setwindowpos也好,原来隐藏的窗口都是不能聚焦的。。。<br>不过,我用了SWITCHTOTHISWINDOWS后可以了,嗬嗬^_^
 
解决 Win98 and Win2000 下SetForegroundWindow()函数的问题!<br>三种解决方法!<br><br>1<br>function ForceForegroundWindow(hwnd: THandle): boolean;<br>const<br>&nbsp; SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;<br>&nbsp; SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;<br>var<br>&nbsp; ForegroundThreadID: DWORD;<br>&nbsp; ThisThreadID: DWORD;<br>&nbsp; timeout: DWORD;<br>begin<br>&nbsp; if IsIconic(hwnd) then<br>&nbsp; &nbsp; ShowWindow(hwnd, SW_RESTORE);<br>&nbsp; if GetForegroundWindow = hwnd then<br>&nbsp; &nbsp; Result := true<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion &gt; 4)) or<br>&nbsp; &nbsp; &nbsp; &nbsp;((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and ((Win32MajorVersion &gt; 4) or<br>&nbsp; &nbsp; &nbsp; &nbsp;((Win32MajorVersion = 4) and (Win32MinorVersion &gt; 0)))) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Result := false;<br>&nbsp; &nbsp; &nbsp; ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);<br>&nbsp; &nbsp; &nbsp; ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);<br>&nbsp; &nbsp; &nbsp; if AttachThreadInput(ThisThreadID, ForegroundThreadID, true) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; BringWindowToTop(hwnd); &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(hwnd);<br>&nbsp; &nbsp; &nbsp; &nbsp; AttachThreadInput(ThisThreadID, ForegroundThreadID, false);<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := (GetForegroundWindow = hwnd);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; if not Result then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0), SPIF_SENDCHANGE);<br>&nbsp; &nbsp; &nbsp; &nbsp; BringWindowToTop(hwnd); &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(hWnd);<br>&nbsp; &nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; BringWindowToTop(hwnd); &nbsp;{IE 5.5 related hack}<br>&nbsp; &nbsp; &nbsp; SetForegroundWindow(hwnd);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Result := (GetForegroundWindow = hwnd);<br>&nbsp; end;<br>end;<br><br>2<br>function ForceForegroundWindow(hWnd: THandle): BOOL;<br>var<br>&nbsp; hCurWnd: THandle;<br>begin<br>&nbsp; hCurWnd := GetForegroundWindow;<br>&nbsp; AttachThreadInput(GetWindowThreadProcessId(hCurWnd, nil), GetCurrentThreadId, True);<br>&nbsp; Result := SetForegroundWindow(hWnd);<br>&nbsp; AttachThreadInput(GetWindowThreadProcessId(hCurWnd, nil), GetCurrentThreadId, False);<br>end;<br><br>3<br>procedure ForceForegroundWindow(hwnd: THandle);<br>var<br>&nbsp; hlp: TForm;<br>begin<br>&nbsp; hlp := TForm.Create(nil);<br>&nbsp; try<br>&nbsp; &nbsp; hlp.BorderStyle := bsNone;<br>&nbsp; &nbsp; hlp.SetBounds(0, 0, 1, 1);<br>&nbsp; &nbsp; hlp.FormStyle := fsStayOnTop;<br>&nbsp; &nbsp; hlp.Show;<br>&nbsp; &nbsp; mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);<br>&nbsp; &nbsp; mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);<br>&nbsp; &nbsp; SetForegroundWindow(hwnd);<br>&nbsp; finally<br>&nbsp; &nbsp; hlp.Free;<br>&nbsp; end;<br>end;
 
yb_unique兄,麻烦了一点吧,不过,有可能switchtothiswindow这个API函数也是这样解决<br>的也说不定^_^<br>也许,creation-zy可以试试你的方法:)
 
用不着那样麻烦,这样就行:<br>[red]procedure TForm1.Button2Click(Sender: TObject);<br>var<br>&nbsp; hwnd1: HWND;<br>begin<br>&nbsp; hwnd1:= FindWindow(PChar('IEFrame'),PChar('大富翁论坛 delphibbs.com - Microsoft Internet Explorer'));<br>&nbsp; if hwnd1 &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; ShowWindow(hwnd1,SW_RESTORE);<br>&nbsp; &nbsp; SetForegroundWindow(hwnd1);<br>&nbsp; end;<br>end;[/red]
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
716
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
488
import
I
后退
顶部