扩展你的WIndows标准控件

      扩展你的WIndows标准控件
 作者:ShellEx
 www.shellex.cn && blog.csdn.net/shellex 版权所有。

标准控件嘛,意味着他们默认的功能和表现力都是有限的.比如说,当鼠标点击Edit控件时,虽然
作为子窗体的Edit控件(Edit也是窗体)会接受到WM_LBUTTONUP和WM_LBUTTONDOWN消息,
但是它并不会向父窗体发送相关的通知。也就是说,我们在处理WM_COMMAND消息时,不会
在Edit的通知中获知Edit是否被点击了。
下列是标准Edit所支持的通知,它们将被放在wParam的高字位中,其中并没有我想要的
WM_LBUTTONUP或者类似的消息。

EN_CHANGE :The user has modified text in an edit control. Windows updates the display before sending this message (unlike EN_UPDATE).
EN_ERRSPACE :The edit control cannot allocate enough memory to meet a specific request.
EN_HSCROLL : The user has clicked the edit control's horizontal scroll bar. Windows sends this message before updating the screen.
EN_KILLFOCUS :The user has selected another control.
EN_MAXTEXT  :  While inserting text, the user has exceeded the specified number of characters for the edit control. Insertion has been truncated. This message is also sent either when an edit control does not have the ES_AUTOHSCROLL : style and the number of characters to be inserted exceeds the width of the edit control or when an edit control does not have the ES_AUTOVSCROLL style and the total number of lines to be inserted exceeds the height of the edit control.
EN_SETFOCUS  :  The user has selected this edit control.
EN_UPDATE  :  The user has altered the text in the edit control and Windows is about to display the new text. Windows sends this message after formatting the text, but before displaying it, so that the application can resize the edit control window.
EN_VSCROLL  :  The user has clicked the edit control's vertical scroll bar. Windows sends this message before updating the screen.

想实现能对Edit单击鼠标事件发出响应,有个很简单的方法,那就是只需子类化Edit,自
定义Edit的消息处理过程就可以了。有两个相关函数:
LONG GetWindowLong(

    HWND hWnd, // handle of window
    int nIndex  // offset of value to retrieve
   );
  
LONG SetWindowLong(

    HWND hWnd, // handle of window
    int nIndex, // offset of value to set
    LONG dwNewLong  // new value
   );
前者可以得到窗体的若干信息,后者可以设置窗体的若干属性。包括处理消息的回调函数。
关于函数的参数,请查阅MSDN。下面是具体实现。
我先创建一个基于对话框的Win32 GUI工程,在相应WM_INITDIALOG消息的函数
Main_OnInitDialog中写入如下代码:


//先得到原来的Edit的消息处理回调函数,最后一个参数使用GWL_WNDPROC
oldEditProcAddr = GetWindowLong(GetDlgItem(hwnd,IDC_EDIT_PROCESS),GWL_WNDPROC);
//子类化Edit,让他能发送EN_LBUTTONUP通知。
SetWindowLong(GetDlgItem(hwnd,IDC_EDIT_PROCESS),GWL_WNDPROC ,(long) _NewEditProc);

EN_LBUTTONUP是我自定义的一个常量,是WM_USER + 101,IDC_EDIT_PROCESS是一个Edit
控件的ID。hwnd是父窗体的句柄。_NewEditProc是我自己写的回调函数,以后发给Edit的
消息会被送到_NewEditProc处理。
下面是_NewEditProc函数的代码:


LRESULT CALLBACK _NewEditProc(HWND hwnd, UINT uMsg, WPARAM wParam,LPARAM lParam ) {
 //如果鼠标左键在Edit上放开
 if ( WM_LBUTTONUP == uMsg ) {
  //将本Edit的ID放到wparam的低字位,自定义的响应通知放在高字位
  WPARAM wp = MAKEWPARAM(IDC_EDIT_PROCESS, EN_LBUTTONUP);
  //lparam放着Edit的句柄
  LPARAM lp = (LPARAM)hwnd;
  把这个消息组合一下,作为WM_COMMAND发给父窗体
  SendMessage(GetParent(hwnd), WM_COMMAND, wp, lp);
 }
 //其他的消息由默认的处理函数处理
 return CallWindowProc((WNDPROC)oldEditProcAddr, hwnd, uMsg, wParam, lParam);
}

现在,我在主窗体的消息循环里就可以轻易地得到鼠标单击的通知了:


void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
    switch(id) {
  case IDC_EDIT_PROCESS:
   if (codeNotify == EN_LBUTTONUP)
    Main_OnEditProcess_Click(hwnd,id,hwndCtl,codeNotify);
  break;
        default:break;
    }
}

在函数Main_OnEditProcess_Click中可以轻松实现你希望实现的功能了。: )
    www.shellex.cn && blog.csdn.net/shellex 版权所有。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值