ID--HANDLE--HWND三者之間的互相轉換

利用PreTranslateMessage,響應按鈕控件的按下(WM_LBUTTONDOWN)和鬆開(WM_LBUTTONUP)安全

 
VC的button控制只有兩個事件,一個是單擊事件,一個事雙擊事件。在這個方面VB就方便多了。可是咱們有其餘辦法解決。首先咱們先學一些基礎知識。
 

1...關於PreTranslateMessageide

PreTranslateMessage是消息在送給TranslateMessage函數以前被調用的,絕大多數本窗口的消息都要經過這裏,比較經常使用,當你須要在MFC以前處理某些消息時,經常要在這裏添加代碼.
函數

2...關於MSG結構體
typedef struct tagMSG { // msg
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;
post

Members
hwnd
Handle to the window whose window procedure receives the message.
message
Specifies the message identifier. Applications can only use the low word; the high word is reserved by the system.
wParam
Specifies additional information about the message. The exact meaning depends on the value of the message member.
lParam
Specifies additional information about the message. The exact meaning depends on the value of the message member.
time
Specifies the time at which the message was posted.
pt
Specifies the cursor position, in screen coordinates, when the message was posted.
spa

3...ID--HANDLE--HWND三者之間的互相轉換
id->句柄、、、、、hWnd = ::GetDlgItem(hParentWnd,id);
id->指針、、、、、CWnd::GetDlgItem();
句柄->id、、、、、id = GetWindowLong(hWnd,GWL_ID);
句柄->指針、、、、CWnd *pWnd=CWnd::FromHandle(hWnd);
指針->ID、、、、、id = GetWindowLong(pWnd->GetSafeHwnd,GWL_ID);
指針->句柄、、、、hWnd=cWnd.GetSafeHandle() or mywnd->m_hWnd;
指針

例程:orm

方法1:對象

BOOL AcameraCT::PreTranslateMessage(MSG* pMsg)
{
int buID;
buID= GetWindowLong(pMsg->hwnd,GWL_ID);//由窗口句柄得到ID號,GetWindowLong爲得到窗口的ID號。
if(pMsg->message==WM_LBUTTONDOWN)
{
if(buID==IDC_BUTTON_CT1) //按下
{
//在這裏添加單擊按下事件的程序
}
}
if(pMsg->message==WM_LBUTTONUP)
{
if(buID==IDC_BUTTON_CT1)
{
//在這裏添加單擊鬆開事件的程序
}
}
return CDialog::PreTranslateMessage(pMsg);
}
接口

方法2:事件

BOOL AcameraCT::PreTranslateMessage(MSG* pMsg)
{
int buID;
CWnd* pWnd=WindowFromPoint(pMsg->pt); //得到指定點句柄
buID=pWnd->GetDlgCtrlID();//得到該句柄的ID號。
if(pMsg->message==WM_LBUTTONDOWN)
{
if(buID==IDC_BUTTON_CT1) //按下
{
//在這裏添加單擊按下事件的程序
}
}
if(pMsg->message==WM_LBUTTONUP)
{
if(buID==IDC_BUTTON_CT1)
{
//在這裏添加單擊鬆開事件的程序
}
}
return CDialog::PreTranslateMessage(pMsg);

}

VC_HWND和CWND的概念以及轉換

下面先說下HWMD的概念,我也不是很理解,應該是SDK接口的概念,並無實際對象操做的地址空間。

它只是一個32bit的無符號整型數值,表明了句柄號handle

摘自網上的理論:

HWND是Windows系統中對全部窗口的一種標識,即窗口句柄。這是一個SDK概念。

CWnd是MFC類庫中全部窗口類的基類。微軟在MFC中將全部窗口的通用操做都封裝到了這個類中,如:ShowWindow等等,同時它也封裝了窗口句柄即m_hWnd成員。

 

由HWnd獲得CWnd*:

CWnd wnd;

HWnd hWnd;

wnd.Attach(hWnd);

一般一個窗口資源已經和一個CWnd類的對象關聯起來的,因爲通常來講這個類是本身建立的,因此天然知道怎麼獲得指向這個類的指針。若是沒有就建立一個CWnd對象,將這個對象與窗口資源的hWnd句柄關聯起來。(如上邊的語句)。若是用

static CWnd* CWnd::FromHandle(HWND hWnd) ;

則返回值是一個暫時的CWnd對象,而且咱們確保返回值爲非空,也就是hWnd是有效的。

static CWnd* CWnd::FromHandlePermanent(HWND hWnd) ;

返回的是一個永久的對象。只有在返回的CWnd在類表裏已經存在是返回值爲非空。

 

由CWnd獲取HWnd就容易多了,由於它的一個成員m_hWnd就是所對應窗口的句柄。

wnd->m_hWnd。

——————————————————————————————————————————————————————————

 

CWnd* 和 HWND 差異很大

 

HWND 是 SDK 定義的類型, 是一個無確切意義的 32-bit 值,在調用 API 時用於指代窗體。

 

CWnd* 是一個有確切意義的指針,指向一個 MFC 窗體類 CWnd 的實例。由於 MFC 對 SDK 作了封裝,大部分調用均可以用 CWnd* 做爲參數,因此很容易混淆。從一個 CWnd* 獲取句柄的方法是 pWnd->GetSafeHwnd(), 他比 pWnd->m_hWnd 安全,由於前者在 pWnd == NULL 的時候返回 NULL 然後者出現 access violation

 

從 hWnd 轉換到 CWnd * 一個可使用的方法是 CWnd::FromHandle

CWnd *pTempWnd = CWnd::FromHandle(hWnd); // 若是 hWnd 存在對應的 CWnd* ,則返回其指針,不然,建立一個 MFC 臨時窗體並返回其指針。

注意這個函數會返回臨時窗體的指針,若是須要更安全,調用 CWnd::FromHandlePermanent ,他在不存在對應的 CWnd* 時返回 NULL。

 

——————————————————————————————————————————————————————————

 

CWnd是MFC的窗口基類。 HWND是Windows窗口句柄。前者是一個C++對象,後者是一個相似於指針地址的數字型對象。

CWnd能夠當作是對Windows窗口操做的封裝,而封裝的核心就是使用Windows窗口句柄(即HWND)來操做窗口.

 

CWnd能夠經過CWnd::GetSafeHwnd()或成員變量m_hWnd來得到該窗口對象的HWND窗口句柄。

HWND能夠經過CWnd的靜態函數:CWnd::FromHandle()由句柄實例化一個CWnd對象出來。

 

如下是本身VC6.0上編譯的狀況,驗證了以上的理論

CWnd* mark1;mark1=FindWindow(NULL,"TEST");//TEST是個人當前實例窗口的title

 

//從CWND*轉換成HWND

 

HWND tmp=mark1->GetSafeHwnd(); //獲得它的HWND

相關文章
相關標籤/搜索