GetSafeHwnd()和GetSafeHandle()區別

一、GetSafeHwnd()和GetSafeHandle()的主要區別:

    1、使用者不同

        1)窗體使用

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

        2)GDI對象使用

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

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

//pDlgWnd是一個窗體指針

    if(NULL!=pDlgWnd && NULL!=pDlgWnd->GetSafeHand())

        {

                do something that you want to

         }

    二、補充知識 

      1、內存句柄與指針的相同之處

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

         2)句柄是一些表的索引也就是指向指針的指針。 句柄和指針都是地址,句柄是windows編程的一個關鍵性的概念,編寫windows應用程序總是要和各種句柄打交道。
所謂句柄,就是一個唯一的數,用以標識許多不同的對象類型,如窗口、菜單、內存、畫筆、畫刷等。在win32裏,句柄是指向一個“無類型對象”(void)的指針,也就是一個4字節長的數據。
無論它的本質是什麼,句柄並不是一個真正意義上的指針。

從構造上看,句柄是一個指針,儘管它沒有指向用於存儲某個對象的內存位置。事實上,句柄指向一個包含了對該對象進行引用的位置。

            句柄的聲明是這樣的:typedef void* HANDLE

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

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

  三、獲得窗口句柄的3種辦法

        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 EnumchidWindows(HWND hWndParent,WNDENUMPROC lpEnumFunc,LPARAM lParam)

    BOOL EnumWindows(WNDENUMPROC lpEnumFuc,LPARAM    lParam)

   BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)

四、指針和句柄之產的轉換

    1、CWND* pwnd ;
      HWND  hwnd ;
      hwnd = pwnd-> GetSafeHwnd();

    2、 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保留一塊數據結構,然後把它放在一張全局表中。句柄就是這塊數據結構在表中的索引

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