ID--HANDLE--HWND三者之间的互相转换

利用PreTranslateMessage,响应按钮控件的按下(WM_LBUTTONDOWN)和松开(WM_LBUTTONUP)

 
VC的button控制只有两个事件,一个是单击事件,一个事双击事件。在这个方面VB就方便多了。但是我们有其他办法解决。首先我们先学一些基础知识。
 

1...关于PreTranslateMessage

PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用,当你需要在MFC之前处理某些消息时,常常要在这里添加代码.

2...关于MSG结构体
typedef struct tagMSG { // msg
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;

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.

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;

例程:

方法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

posted @ 2014-02-19 16:52  FREE小宝  阅读(640)  评论(0编辑  收藏  举报