GetSafeHwnd()和GetSafeHandle()的主要區別

GetSafeHwnd()GetSafeHandle()的主要區別:

1.使用者不同:

1)窗體使用:

GetSafeHwnd()用於獲取窗體的安全句柄(即HWND),有了HWND我們就可以方便的對HWND指向的窗體進行所需的操作了;

2GDI對象使用:

GetSafeHandle(),用於獲取GDI對象的句柄。


注意:在使用指針時強烈建議這麼做:

// pSomeWnd 爲一個窗體的指針

if ( NULL != pSomeWnd && NULL != pSomeWnd->GetSafeHwnd())

{

  // do something.

   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

補充知識:

內存句柄與指針的區別:

1.句柄其實就是指針,但是他和指針最大的不同是:給你一個指針,你可以通過這個指針做任何事情,也許是好事,也許是通過這個指針破壞內存,幹一些搗亂的事情。這個我想大家都會碰到過,因爲亂用指針可能會導致程序崩潰。
句柄就沒有這個缺點,通過句柄,你只能幹一些windows允許你乾的事情(例如調用一些api函數等等),沒有了指針的隨意。

2.句柄是一些表的索引也就是指向指針的指針。 句柄和指針都是地址,句柄是windows編程的一個關鍵性的概念,編寫windows應用程序總是要和各種句柄打交道。
所謂句柄,就是一個唯一的數,用以標識許多不同的對象類型,如窗口、菜單、內存、畫筆、畫刷等。在win32裏,句柄是指向一個無類型對象”(void)的指針,也就是一個4字節長的數據。
無論它的本質是什麼,句柄並不是一個真正意義上的指針
從構造上看,句柄是一個指針,儘管它沒有指向用於存儲某個對象的內存位置。事實上,句柄指向一個包含了對該對象進行引用的位置。
句柄的聲明是這樣的:
typedef void handle

由於windows是一個多任務操作系統,它可以同時運行多個程序或一個程序的多個副本。這些運行的程序稱爲一個實例。爲了對同一程序的多個副本進行管理,windows引入了實例句柄。windows爲每個應用程序建立一張表,實例句柄就好象是這張表的一個索引。

 
不同之處還在於:
1
、句柄所指的可以是一個很複雜的結構,並且很有可以是與系統有關的,比如說上面所說的線程的句柄,它指向的就是一個類或者結構,他和系統有很密切的關係,當一個線程由於不可預料的原因而終止時,系統就可以回收它所佔用的資源,如cpu,內存等等。反過來想可以知道,這個句柄中的某一些項,是與系統進行交互的。由於windows系統是一個多任務的系統,它隨時都可能要分配內存,回收內存,重組內存等。 
2
、指針它也可以指向一個複雜的結構,但是通常是用戶定義的,所有的必需的工作都需用戶完成,特別是在刪除的時候。 但在vc++6.0中也有一些指針,它們都是在處理一些小問題才用的,如最常見的字符的指針 它也是需要用戶處理的,譬如你動態分配了內存;但是cstring就不要用戶處理了,它其實是vc++中的一個類,所有的操作都由成員函數完成,產生(分配)由構造函數,刪除(回收)由析構函數完成。


附註:獲得窗口句柄三種方法

1.HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName);

 

  HWND FindWindowEx( HWND hwndParent, HWND hwndChildAfter,
                        LPCTSTR lpszClass, LPCTSTR lpszWindow );

2.HWND WindowFromPoint( 
          POINT Point);//
獲得當前鼠標光標位置的窗口hwnd

3.BOOL CALLBACK EnumChildProc( HWND hwnd, LPARAM lParam);

 

BOOL EnumChildWindows( HWND hWndParent,
                       WNDENUMPROC lpEnumFunc,
                       LPARAM lParam );
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam ); 
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam );

補充知識:指針和句柄之間的轉換

a.由指針獲得句柄 
      CWND* pwnd ;
      HWND  hwnd ;
      hwnd = pwnd-> GetSafeHwnd();

b.由句柄得到指針:
      CWND* pwnd = FromeHandle(hmyhandle);
      pwnd-> SetWindowText(" hello world!" ) ;

mfc類中有的還提供了標準方法,比如window 句柄 : 
static CWND pascal FromHandle( HWND hwnd )
HWND GetSafeHwnd( ) const

對於位圖: 
static cbitmap pascal fromhandle( hbitmap hbitmap )
static cgdiobject pascal fromhandle( hgdiobj hobject )
hgdiobj getsafehandle( ) const


有人說句柄就是一個標示,一個id號,是錯誤的。一個id號可以包括多個資源,比如說單文檔中的idr_mainframe,一般是指在硬盤上的資源。但是當把硬盤上的資源調入內存以後,將有一個句柄指向它,但是句柄只能指向一個資源。而且句柄知道所指的內存有多大。而指針指向地址,它不知道分配的內存有多大。
但是如果你定義一個句柄,然後在vc裏面右擊鼠標,選擇" go to definition of handle,你會發現它的本質就是一個指針,但是它的作用不同於指針。

句柄是個指針,指向一塊內存,但至於這塊內存跟句柄所標識的對象是怎麼聯繫起來的,調用者不需要清楚,調用者只需要知道,這個句柄聯繫着一個win32對象。
    句柄是物理地址,可以跨進程傳遞,例如,handle ha進程a的一個窗口,你可以在進程b中利用一個跟ha相等的值(相等就是說它們強制轉成int32的值相等)初始化一個句柄,利用這個句柄你可以對進程a的那個對象進行操作,例如movewindow showwindow等。
句柄包含了一些引用計數之類的東西,所以我的上一點說的給句柄賦值是不安全的,windows api提供了一些函數,可以對句柄進行操作。


    句柄就是受限的指針。
它是由操作系統管理的,你不能通過它直接存取操作系統創建的數據結構(應該先獲取對應的指針)。

操作系統在創建一個對象(如gdi, file)等的時候,它會爲這個對象上下文context保留一塊數據結構,然後把它放在一張全局表中。句柄就是這塊數據結構在表中的索引。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章