PreTranslateMessage、CWND&HWND&控件ID之间的巧妙转换方法(转载 vc hwnd cwnd

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


VC的button控制只有两个事件:单击事件,双击事件。

1...关于PreTranslateMessage

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

2...关于MSG结构体
typedef struct tagMSG{// msg
HWNDhwnd;
UINTmessage;
WPARAMwParam;
LPARAMlParam;
DWORD time;
POINT pt;
} MSG;

3...控件ID--HANDLE--HWND三者之间的互相转换

控件ID-> 句柄: hWnd =::GetDlgItem(hParentWnd, IDXX);
控件ID->指针: CWnd::GetDlgItem();
句柄 -> 控件ID:id = GetWindowLong(hWnd,GWL_ID);
句柄 -> 指针: CWnd*pWnd = CWnd::FromHandle(hWnd);
指针 -> 控件ID:ID=GetWindowLong(pWnd->GetSafeHwnd, GWL_ID);
指针 -> 句柄: hWnd= pWnd->GetSafeHandle();

实例:

方法1:

BOOLXXXXX::PreTranslateMessage(MSG* pMsg)
{
UINT btnID;

//由窗口句柄获得控件ID号,GetWindowLong为获得窗口的ID号。
PreTranslateMessage、CWND&HWND&控件ID之间的巧妙转换方法(转载 vc hwnd cwnd
btnID=GetWindowLong(pMsg->hwnd,GWL_ID);


if(pMsg->message== WM_LBUTTONDOWN)
{
if( btnID==IDC_BTN_MYBUTTON) // 自定义的button被按下
{
// 在这里添加button被按下事件的处理
}
}

//
if(pMsg->message ==WM_LBUTTONUP)
{
if(btnID ==IDC_BTN_MYBUTTON)
{
//在这里添加鼠标松开事件的处理
}
}

//其他消息,我们仍然使用默认处理
returnCDialog::PreTranslateMessage(pMsg);
}

方法2:

BOOLXXXXXX::PreTranslateMessage(MSG* pMsg)
{
UINT btnID;
CWnd* pWnd =WindowFromPoint(pMsg->pt); // 获得指定点的窗体句柄
btnID=pWnd->GetDlgCtrlID(); // 获得该窗体句柄的ID


if(pMsg->message== WM_LBUTTONDOWN)

{
if(btnID==IDC_BTN_MYBUTTON) // 自定义的button被按下
{
// 在这里添加button被按下事件的处理
}
}

//
if(pMsg->message ==WM_LBUTTONUP)
{
if(btnID==IDC_BTN_MYBUTTON)
{
//在这里添加鼠标松开事件的处理
}
}

returnCDialog::PreTranslateMessage(pMsg);

}

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

VC中HWND和CWND的概念以及转换:

HWND是Windows系统中对所有窗口的一种标识,即窗口句柄。这是一个SDK概念。

CWnd是MFC类库中所有窗口类的基类。微软在MFC中将所有窗口的通用操作都封装到了这个类中,如:ShowWindow等等,同时它也封装了窗口句柄即m_hWnd成员。

由HWnd得到CWnd*:

CWndwnd;

HWndhWnd;

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。// 但是建议不要这样来使用

//建议获取方式

HWND hWnd =pWnd-> GetSafeHwnd();

CWnd* 和 HWND差别很大:

HWND 是 SDK 定义的类型,是一个无确切意义的 32-bit 值,在调用 API 时用于指代窗体。

CWnd*是一个有确切意义的指针,指向一个 MFC 窗体类 CWnd 的实例。因为 MFC 对 SDK 做了封装,大部分调用都可以用 CWnd*作为参数,所以很容易混淆。从一个 CWnd* 获取句柄的方法是 pWnd->GetSafeHwnd(),他比 pWnd->m_hWnd 更安全(因为 pWnd->GetSafeHwnd()在pWnd == NULL 的时候返回 NULL ,而 pWnd->m_hWnd会出现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对象出来。

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/56589.html

更多阅读

二进制数与十六进制数之间如何互相转换 二进制转换十六进制

二进制数与十六进制数之间如何互相转换——简介二进制与十六进制之间的转换与二进制和八进制之间的转换很类似,今天我们来详细看一下:首先,我们来看一下数学关系即24=16,即用四位二进制表示一位八进制。二进制数与十六进制数之间如何互

窗口和控件闪烁解决方案 屏幕闪烁解决办法

对于MFC程序员来说做UI开发是痛苦的事情,不过大多数情况下我们都需要做这件事情,因为MFC自带的控件实在是太简陋了。这时候我们多半会涉及到自绘控件,随之而来的很可能就是窗口和控件的闪烁问题。这篇文章希望对MFC的窗口和控件闪烁问

C#DataGridView控件清空数据完美解决方法 datagridview清空列

C# DataGridView控件绑定数据后清空数据在清除DataGridview的数据时:1.DataSource为NULL(DataGridView.DataSource=null;)这样会将DataGridView的列也删掉。2.用DataGridview.Rows.Clear();提示“不能清除此列表”!!!!!以上都不是想要的结果

IE停止安装activex控件怎么办? ie10安装activex控件

要安装activex 可是却提示:为了保护您的安全,InternetExplorer已经停止从此站点安装activex控件到您的计算机点Internet选项-安全-受限制的的站点-再点最下面的自定义级别-在下载未签名的activex选项里

声明:《PreTranslateMessage、CWND&HWND&控件ID之间的巧妙转换方法(转载 vc hwnd cwnd》为网友暗香浮动分享!如侵犯到您的合法权益请联系我们删除