如何将一个应用程序的窗口提到最前面?(100分)

  • 主题发起人 主题发起人 luckmiky
  • 开始时间 开始时间
L

luckmiky

Unregistered / Unconfirmed
GUEST, unregistred user!
我想做一个只能运行一次的程序,但是遇到了困难。问2个问题。<br><br>1、我想当用户运行程序的时候,如果已有实例在运行,就把他提到最前面,做为当前窗口,就象WinAmp一样,结果怎么Application都不肯到最前面来,提MainForm倒是可以。<br><br>2、用了诸如ShwoWindow,HideWindow等API后,Form1.show,form1.hide都不起作用了,甚至连最小化按钮都不起作用了。<br><br>有没有妥善的解决办法?
 
1、那你就提MainForm好了啊,那个Application是不可见的,提它做什么?<br>2、DELPHI的事情DELPHI办,用FORM方法可以解决的问题就不要用API了嘛!
 
发个自定义消息,响应消息时自己提到最前面
 
那你就提MainForm好了啊,那个Application是不可见的,提它做什么?<br>这就是第2个问题了,因为我只能取到句饼,不用API怎么弄到最前面去?用了,有会出现诸多的问题。
 
试试<br>SetWindowPos(self.Handle ,HWND_TOPMost,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);
 
将窗体自己置前:<br>SetForegroundWindow( Handle );<br><br>MDI子窗体的置前:<br>DefMDIChildProc( ChildForm.Handle, WM_SETFOCUS, 0, 0 );<br><br>将非MDI子窗体置前:<br>SetForegroundWindow( TheForm.Handle );
 
你现在不是得到Application.handle了嘛,告诉你个简单方法<br>你给这个handle发个自定义消息,然后在Appliction.OnMessage中得到这个消息时就MailForm.show……
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=604
 
一 获取主窗体的句柄 <br>2.使用下面两个函数,参数为主窗体的句柄<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(Hd);<br>&nbsp; &nbsp; &nbsp; &nbsp; BringWindowToTop(Hd);
 
Write by :lu0<br>98/2000下,有个公开的函数SetForegroundWindow,用于切换前台窗口.但是事实上,SetForegroundWindow并不能用于和其他进程的窗口协同工作,通常情况下SetForegroundWindow会调用FlashWindowEx来闪烁目标窗口,代表已经切换了窗口,但是这不是我们需要的.网络上有一些顶尖高手使用修改窗口切换的系统规则后,用SetForegroundWindow切换到其他进程的窗口,但是现在,我们有了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>typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL); <br>PROCSWITCHTOTHISWINDOW SwitchToThisWindow; <br>HMODULE hUser32 = GetModuleHandle("user32"); <br>SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow"); <br>{ Delphi Code:<br>&nbsp; procedure SwitchToThisWindow(hWnd:HWND;bRestore:Boolean);stdcall;external 'user32.dll';<br>}<br>这样,我们的任务就完成了. <br>*******************************<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>不过最后SystemParametersInfo恢复参数:<br>SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,Pointer(timeout), SPIF_SENDCHANGE);<br>如果不去掉,在WIN2000下不灵<br>***********************<br>发现一个2000下面的方法,试一下 <br>function &nbsp;AllowSetForegroundWindow( dwProcessId:DWORD): BOOL; stdcall;<br><br>implementation<br>function AllowSetForegroundWindow; external &nbsp;'user32.dll' name 'AllowSetForegroundWindow';<br><br>****************<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>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;
 
各位试过了吗?你们的方法不用试就知道不行。
 
没看到ysai的连接,果然是好办法。
 
后退
顶部