SetForegroundWindow、SetActiveWindow、SetFocus 如何將一個某個窗口提到最頂層


http://hi.baidu.com/gookings/item/2b7912ca8d5b3625a0b50aa2

 

SetForegroundWindow  函數功能:該函數將創建指定窗口的線程設置到前台,並且激活該窗口。鍵盤輸入轉向該窗口,並為用戶改各種可視的記號。系統給創建前台窗口的線程分配的權限稍高於其他線程。
  函數原型:BOOL SetForegroundWindow()
  SetForegroundWindow()函數本身是不帶參數的,具體激活某個窗口的方法可以用:
  pWnd->SetForegroundWindow();//這里的pWnd即所要激活窗口的句柄。
  返回值:如果窗口設入了前台,返回值為非零;如果窗口未被設入前台,返回值為零。
  備注:前台窗口是z序頂部的窗口,是用戶的工作窗口。在一個多任務優先搶占環境中,應讓用戶控制前台窗口。
  Windows NT 5.0:當用戶在另一個窗口中工作時,應用程序不能強行設置一個窗口到前台。相反,SetForeground函數將會激活窗口並且調用FlashWindowEx函數通知用戶。
  Windows CE:擁有窗口的線程不具有優先啟動權。

  速查:Windows NT;3.1以上版本;Windows;95以上版本;Windows CE:1.0以上版本;頭文件:winuser.h;庫文件:user32.lib。

 

SetWindowPlacement  函數功能:該函數設置指定窗口的顯示狀態和恢復,最大化,最小化位置。
  函及原型;BOOL SetWindowPlacement(HWND hWnd,CONST WINDOWPLACEMENT★lpwndpl);
  參數:
  hWnd:窗口句柄。
  lpwndpl:指向一個WINDOWPLACEMWNT結構的指針,該結構給出了新的顯示狀態和窗口位置。
  在調用函數SetWindowPlacement之前,將WINDOWPLACEMWNT結構的長度單元置為sizeof(WINDOWPLACEMENT)。如果lpwndpl->length設置不正確,函數SetWindowPlacement將失敗。
  返回值:如果函數成功,返回值為非零。如果函數失敗,返回值為零。若想獲得更多錯誤信息,請調用callGetLastErro函數。
  備注:如果在WIDNOWPLACEMENT中指定的信息使窗口完全顯示在屏幕之外,系統自動調整坐標以使窗口可見,兼顧屏幕設置和多種監視器配置。
  WINDOWPLACEMENT的長度成員信息設置為sizeof(WINDOWPLACEMENT),如果設置不正確,函數將返回FLASE。查看窗口位置坐標的信息,參看WINDOWPLACEMENT。

  速查:Windows NT:3.1以上版本;Windows;95以上版本;Windows CE:不支持;頭文件;winuser.h;庫文件:user32.lib。

 

SetForegroundWindow()

SetActiveWindow()

SetFocus()

自己的理解:每個gui線程都有自己的活動窗口,而目前被用戶點中那個線程活動窗口叫前台窗口(或叫前景窗口)。而創建前台窗口的線程叫做前台線程(或叫前景線程),前台線程擁有比其它非前景線程更高的優先級,會被windows操作系統優先處理。而所謂的焦點窗口,可以是前台窗口或者是前台窗口的子窗口(控件),如果用戶按下鍵盤按鍵,windows操作系統會將鍵盤按鍵消息發送到當前的焦點窗口。

 

-------------------------------------

如何將一個某個窗口提到最頂層?網上搜索了一些文章大致有以下幾種方法,做個備忘.

問題:有個界面,想定期讓其提前(**並顯示在用戶面前),但又不想用TOPMOST那種置頂方法.我用了SetForegroundWindow,SetActiveWindow,SHOW_WINDOW都不行:程序運行后再打開記事本,時間到我的程序只會在任務欄上閃幾下,界面根本出不來怎么辦!!(不用頂極窗口,不用鼠標模擬點擊)

方法一:
使用定時器,然后在定時器響應函數中定時調用,SetWindowPos()函數,第一個參數寫HWND_TOPMOST

方法二:
因為2000/XP改變了SetForegroundWindow的執行方式,不允許隨便把窗口提前,打擾用戶的工作。可以用附加本線程到最前面窗口的線程,從而欺騙windows。

AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(),NULL), GetCurrentThreadId(),TRUE); 
SetForegroundWindow(); 
SetFocus(); 
AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(),NULL), GetCurrentThreadId(),FALSE);


方法三:

如何激活指定的窗口事件    ●    
           我們知道,Windows    9x/2000中SetForegroundWindow函數當用戶正在操作其他窗口時是不能強制某個窗口為前景窗口的,而是激活窗口並調用FlashWindowEx函數來通知用戶。但是很多實際情況要求將激活窗口的同時將創建這個窗口的線程置為前景狀態。碰到這種情況我們可以使用USER32.DLL中的幾個未公開API函數。    
   void    SwitchToThisWindow    (    
   HWND    hWnd,        //    被激活的窗口句柄    
   BOOL    bRestore    //    如果被極小化,則恢復窗口    
   );    
   必須動態加載這個函數。    
   typedef    void    (WINAPI    *PROCSWITCHTOTHISWINDOW)    (HWND,    BOOL);    
   PROCSWITCHTOTHISWINDOW    SwitchToThisWindow;    
   HMODULE    hUser32    =    GetModuleHandle("user32");    
   SwitchToThisWindow    =    (    PROCSWITCHTOTHISWINDOW)    
   GetProcAddress(hUser32,    "SwitchToThisWindow");        
   接下來只要用任何現存窗口的句柄調用這個函數即可,第二個參數指定如果窗口極小化,是否恢復其原狀態。    
   SwitchToThisWindow(hWnd,    TRUE);   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM