【转载】PreTranslateMessage 、CWND & HWND & 控件ID之间的巧妙转换方法

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

 

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

 

 

1...关于PreTranslateMessage

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

2...关于MSG结构体
typedef struct tagMSG {     // msg 
    HWND   hwnd;     
    UINT   message; 
    WPARAM wParam; 
    LPARAM lParam; 
    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();

 

实例:PreTranslateMessage获取相对应的控件ID的消息

方法1:

BOOL XXXXX::PreTranslateMessage(MSG* pMsg) 
{
  UINT btnID;

  //由窗口句柄获得控件ID号,GetWindowLong为获得窗口的ID号。 
  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)
   {  
     //  在这里添加鼠标松开事件的处理
   }  
 }

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

 

方法2:

BOOL XXXXXX::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)
   {  
     //  在这里添加鼠标松开事件的处理
   }  
 }

 return CDialog::PreTranslateMessage(pMsg);

}

 

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

 

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

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

// 建议获取方式

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对象出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值