利用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

ID--HANDLE--HWND三者之间的互相转换的更多相关文章

  1. org.Hs.eg.db包简介(转换NCBI、ensemble等数据库中基因ID,symbol等之间的转换)

    1)安装载入 ------------------------------------------- if("org.Hs.eg.db" %in% rownames(install ...

  2. RDD、DataFrame、Dataset三者三者之间转换

    转化: RDD.DataFrame.Dataset三者有许多共性,有各自适用的场景常常需要在三者之间转换 DataFrame/Dataset转RDD: 这个转换很简单 val rdd1=testDF. ...

  3. 做筛选遍历时遇到的json字符串、json对象、json数组 三者之间的转换问题

    这个是后台对登录用户以及筛选条件的操作 @Override public List<SdSdPer> listResults(String sidx, String sord) { try ...

  4. [转]ExtJs基础--Html DOM、Ext Element及Component三者之间的区别

    要学习及应用好Ext框架,必须需要理解Html DOM.Ext Element及Component三者之间的区别. 每一个HTML页面都有一个层次分明的DOM树模型,浏览器中的所有内容都有相应的DOM ...

  5. keydown,keypress,keyup三者之间的区别

    最近看了Javascript高级教程中对过滤输入的介绍,想实现比如电话号码中不能包好非数值的字符,而相应文本中插入字符的操作是keypress事件,所以就想通过阻止这个事件的默认事件行为来阻止这个事件 ...

  6. CString string char* char 之间的字符转换(多种方法)

    在写程序的时候,我们经常遇到各种各样的类型转换,比如 char* CString string 之间的互相转换.首先解释下三者的含义. CString 是一种很有用的数据类型.它们很大程度上简化了MF ...

  7. <%@page include%>、<%@include%>、<jsp:include>三者之间的本质区别

    <%@page include%>.<%@include%>.<jsp:include>三者之间的本质区别 先从它的几个内置对象说起. application和se ...

  8. xsd与xml和类(class)对象之间的互相转换

    xsd与xml和类(class)对象之间的互相转换 . 第一:通过现有的已经写好的xsd来生成class(.cs)文件. 在您Visual Studio的安装目录下的SDKv2.0Bin中有个应用程序 ...

  9. JSP、servlet、SQL三者之间的数据传递

    JSP.servlet.SQL三者之间的数据传递 博客分类: web开发 JSPservletSQL数据库连接池web开发  前言: 最近一直在做WEB开发,现总结一下这一段时间的体会和感触. 切记, ...

随机推荐

  1. Leetcode 385.字典序排序

    字典序排序 给定一个整数 n, 返回从 1 到 n 的字典顺序. 例如, 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] . 请尽可能的优化算法的时间复杂度和 ...

  2. OMS数据库调整1

    一.增加2T存储空间 1.  对磁盘进行分区并格式化 [root@oms-db01 ~]# fdisk -l Disk /dev/sda: 322.1 GB, 322122547200 bytes 2 ...

  3. cell展开的几种方式

    一.插入新的cell 原理: (1)定义是否展开,和展开的cell的下标 @property (assign, nonatomic) BOOL isExpand; //是否展开 @property ( ...

  4. php 学习随笔

    ---恢复内容开始--- round进行格式化数值(进位规则遵守“四舍六入五双”,即前一位是奇数,则进一,前一位是偶数则舍入,因此,rount(1.5)=2,round(2.5)=2,round(0. ...

  5. Sql Server 中的 @@ERROR

    @@ERROR:当前一个语句遇到错误,则返回错误号,否则返回0.需要注意的是@ERROR在每一条语句执行后会被立刻重置,因此应该在要验证的语句执行后检查数值或者是将它保存到局部变量中以备将来使用. D ...

  6. Scrapy学习-2-xpath&css使用

    xpath使用 简介 xpath使用路径表达式在xml和html中进行导航   语法 body # 选取所有body元素的所有子节点 /html # 选取根元素 body/a # 选取所有属于body ...

  7. es6 递归 tree

    function loop(data) { let office = data.map(item => { if(item.type == '1' ||item.type == '2') { i ...

  8. 数字IC设计入门必备——VIM自定义模板调用与VCS基本仿真操作示例

    一.前言 毕业论文答辩结束,闲下来写篇文章.芯片研发人员都在Linux系统下借助各种EDA工具和代码语言完成工作,因此提高代码开发效率,熟练运用开发工具是十分必要的.本文讲述VIM编辑神器的veril ...

  9. 计算机操作系统处理机调度读后感—–关于进程概念的剖析。从RING3到RING0(32位操作系统)

    计算机操作系统处理机调度读后感: 笔者在看操作系统西安电子科技大学那本书的时候,初次感觉本科教的不会太难,所以没有认真的看,但是随后这本书讲的刷新了我的世界观.这本书居然是ring0级别的,这时不禁吐 ...

  10. 解决树莓派8G的SD卡只能识别3.3G,SD卡扩容

    8GB microSD在Windows下使用Win32 Disk Imager下载映像后,在RPi中只能识别出3.3GB.而本身还有很多容量没有释放出来. 使用sudo raspi-config工具可 ...