來自 乞丐中的霸主 http://blog.csdn.net/zhoujianhei/archive/2007/11/19/1891891.aspx
win32
下執行緒和視窗的資料繫結
一.寫給自己
我很懶。這是我寫的第一篇涉及到程式設計的文章,也許就是因為太懶的緣故吧。在此之前也有寫的衝動可不知為什麼沒有寫成,懶得回憶了。說道記憶,啊,去年我在陳家莊。。。暈,又來了。有些事情我確實懶得記啦,以至於過去苦心鑽研的「經--典」**,現在又得重新研究。後悔當初沒有給自己留下點什麼痕跡,蛛絲馬跡也好啊。本來很懶的我現在又得做重複勞動啊,那麼我到底懶不懶啊?唉,總得給自己留下點什麼吧,哪怕回憶也好啊。
由於本人記性不好,所以留此文章,已被後查。
二.問題的提出
最近想在win32下對視窗封裝一下。於是查閱了很多資料並分析了mfc的視窗實現,這才知道mfc的博大(有夠大)。同時也使我積累了很多知識和技術,其實經常分析mfc實現對程式的編寫和設計是大有益處,高手就在於你看了多少**。這裡不對mfc做過多評價,我們需要的僅是精華部分。
三.執行緒資料的繫結
有的時候我們需要將一些資料或控制代碼繫結到當前執行緒,以供不時只需。
執行緒本地儲存
要將資料(指標、控制代碼)繫結到執行緒,我們需要乙個全域性索引,而這個索引正是通過tlsalloc分配的。
tlsalloc
函式功能:分配乙個執行緒區域性儲存(tls)索引。該程序的任何執行緒都可以使用該索引來儲存和檢取執行緒中的值。
函式原型:dword tlsalloc(void)
引數:無。
返回值:若函式成功,則返回值為乙個tls索引。失敗則返回0xffffffff。
需要說明的是,程序可以同時分配多個索引,用於存放不同的資料。下面提供程序、執行緒、索引、儲存槽的關係圖以便更好地理解。
當越過程序邊界時,tls索引變為無效。乙個dll不能假定在乙個程序中分配的索引在另乙個程序中依然有效。
當乙個dll附加到乙個程序時,它使用tlsalloc分配乙個tls索引。然後,dll分配一些動態儲存單元,並呼叫tlssetvalue向tls槽中儲存位址。tls索引儲存在dll的全域性或靜態變數中。
有了這個索引,我們就可以通過它來取得、設定資料,然而這些資料只對當前執行緒可見。針對索引系統為每個執行緒分配乙個儲存槽,當然我們可以隨意的來使用這個槽。下面的函式用於取和設槽置。
tlsgetvalue
函式功能:檢取呼叫執行緒的執行緒區域性儲存(tls)槽的值。對於每個tls索引,程序的每個執行緒都有它自己的槽。
函式原型:lpvoid tlsgetvalue(dword dwtlsindex)
引數:dwtlsindex
:由tlsalloc分配的索引。
返回值:若函式成功,則返**用執行緒的tls槽中的值;失敗則返回0。注意,存放在tls槽中值可以為0,在這種情況下getlasterror返回no_error。
每個執行緒的tls槽被初始化為null。
tlssetvalue
函式功能:儲存呼叫執行緒的執行緒區域性儲存(tls)槽的值。
函式原型:bool tlssetvalue(dword dwtlsindex, lpvoid lptlsvalue)
引數:dwtlsindex
:由tlsalloc分配的索引。
lptlsvalue
:呼叫執行緒的執行緒區域性儲存(tls)槽的值。
返回值:若函式成功,則返回值不為0;失敗則返回0。
tlssetvalue
和tlsgetvalue實現以提高速度為目標。這些函式執行最小的引數驗證和錯誤檢查。
當資料不再有用,我們需要將索引釋放,有始有終嗎。tlsfree函式不釋放任何與tls相關的動態儲存單元。
tlsfree
函式功能:釋放呼叫執行緒區域性儲存(tls)索引。
函式原型:bool tlsfree(dword dwtlsindex)
引數:dwtlsindex
:由tlsalloc分配的索引。
返回值:若函式成功,則返回值不為0;失敗則返回0。
四.視窗資料的繫結
下面介紹視窗資料的繫結,如果在win32下經常建立視窗,那麼你一定對windowproc函式不會陌生了,所有的視窗訊息都是通過它來分配到視窗的。windowproc無非就是windows的乙個**函式,下面對該函式做下說明:
windowproc
函式功能:該函式是乙個應用程式定義的函式。它處理傳送給視窗的訊息。wndproc型別定義了乙個指向該函式的指標。
函式原型:lresult callback windowproc(hwnd hwnd, uint umsg, wparam wparam, lparam lparam)
引數:hwnd
:指向視窗的控制代碼。
umsg
:指定訊息。
wparam, lparam
:指定umsg訊息的特定資訊。
返回值:訊息的處理結果,它與傳送的訊息有關。
所有的**函式都是全域性或靜態的,然而根據上面的函式描述並沒有給我們留下什麼儲存空間的指標,那麼我們的資料如何繫結到視窗上呢?
setwindowlong
函式功能:改變指定視窗的屬性,也將指定的乙個32位值設定在視窗的額外儲存空間中。
函式原型:long setwindowlong(hwnd hwnd, int nindex, long dwnewlong)
引數:hwnd
:視窗控制代碼。
nindex
:指定大於0的偏移值。可以指定下面的值之一:
gwl_existyle
:設定乙個新的擴充套件風格。gwl_style:設定乙個新的視窗風格。
gwl_wndproc
gwl_hinstance
:設定乙個新的應用程式例項控制代碼。
gwl_userdata
:設定與視窗有關的32位值。每個視窗均有乙個由建立該視窗的應用程式使用的32位值。
當hwnd引數標識了乙個對話方塊時,也可以使用下列值:
dwl_dlgproc
dwl_msgresult
:設定對話方塊過程中處理的訊息的返回值。
dwl_user
:設定應用程式私有的額外資訊,例如乙個控制代碼或指標。
dwnewlong
:指定的替換值。
返回值:若成功返回原來的32位值,失敗則返回0。
getwindowlong
函式功能:獲取指定視窗的屬性,也將獲取視窗的額外儲存空間中的乙個32位值。
函式原型:long getwindowlong(hwnd hwnd, int nindex)
引數:hwnd
:視窗控制代碼。
nindex
:指定大於0的偏移值。可以指定下面的值之一:
gwl_existyle
:獲取擴充套件風格。gwl_style:獲取視窗風格。
gwl_wndproc
gwl_hinstance
:獲取應用程式例項控制代碼。
gwl_userdata
:獲取與視窗有關的32位值。每個視窗均有乙個由建立該視窗的應用程式使用的32位值。
當hwnd引數標識了乙個對話方塊時,也可以使用下列值:
dwl_dlgproc
dwl_msgresult
:獲取對話方塊過程中乙個處理的訊息的返回值。
dwl_user
:獲取應用程式私有的額外資訊,例如乙個控制代碼或指標。
返回值:若成功返回原來的32位值,失敗則返回0。
win32下實現透明視窗
define ws ex layered 0x00080000 define lwa colorkey 0x00000001 define lwa alpha 0x00000002 class ctransparent hinstance ctransparent m hinstance null ...
WIN32 視窗列舉和操作
下面的 包含 獲取視窗控制代碼,修改視窗標題,置頂視窗,操作子視窗,枚舉子視窗,列舉頂層視窗。這篇文章的意義就是把這些函式名記下來,以後用的時候過來看看,然後查msdn學習詳細用法。include include include include bool callback enumchildproc...
簡單的WIN32視窗封裝
封裝視窗物件。注意。有些命名我是直接複製win32api的,偷懶了 本來是想直接用虛函式來處理訊息的,但是訊息很多,寫的會很吃力,所以採用類似mfc的訊息對映,現在記憶體是很富裕的,不用擔心虛函式表會占用大量記憶體,個人建議是採用虛函式的,我這裡偷偷懶。該類主要作用 訊息處理函式呼叫該類的靜態函式w...