标题
[sdk/wince/ppc] listbox 如何响应鼠标点击 (LBUTTONDOWN 消息)
guest
浏览(0) +
2007-10-18 22:30:07 发表
编辑
关键字:
[sdk/wince/ppc] listbox 如何响应鼠标点击 (LBUTTONDOWN 消息) 在这种类 sdk 的环境下是不能在主窗体中得到这个消息的,delphi 和 mfc 都是封装了的,那么原始状态下到底为什么不能得到这个消息呢? 首先我们在sdk环境下一般习惯在窗体环境中取得子控件的消息,而windows的确也支持大部需要的子控件消息在窗体函数中处理.比如sdk帮助中的这一段 The WM_COMMAND message is sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, or when an accelerator keystroke is translated. WM_COMMAND wNotifyCode = HIWORD(wParam); // notification code wID = LOWORD(wParam); // item, control, or accelerator identifier hwndCtl = (HWND) lParam; // handle of control Parameters wNotifyCode Value of the high-order word of wParam. Specifies the notification code if the message is from a control. If the message is from an accelerator, this parameter is 1. If the message is from a menu, this parameter is 0. wID Value of the low-order word of wParam. Specifies the identifier of the menu item, control, or accelerator. hwndCtl Value of lParam. Identifies the control sending the message if the message is from a control. Otherwise, this parameter is NULL. 这一段是说系统会把子控件的某些消息包装到窗体的 WM_COMMAND 消息中.于是我们也习惯了这样的处理,但 listbox 的鼠标点击 (LBUTTONDOWN 消息) 却是不在其中的,要处理它必须让子控件有自己的处理函数,这个可以用 SetWindowLong 来做到,余下的工作就不复杂了.比如下面的例子是将消息再发给主窗体,这样就可能在同一个窗体函数中处理消息了,估计 delphi 和 mfc 也是这样处理的. 不过这里有一个要特别注意的,就是替换函数时一定要保存原来系统就有的默认处理函数的指针,对于你不处理的消息都要用这个函数指针处理,例如下例的 oldProc . //clq add WNDPROC oldProc; BOOL CALLBACK ListBoxProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { //LRESULT lResult = TRUE; LRESULT lResult = FALSE; switch (uMsg) { //clq add case WM_LBUTTONUP: { printf("\r\n"); //传递给 BOOL CALLBACK CShowDlg::DlgShowProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) PostMessage(CShowDlg::m_pThis->m_hWnd, uMsg, wParam, lParam); } break; case WM_LBUTTONDOWN: { printf("\r\n"); } break; //clq add _end; default: // lResult = DefWindowProc(hwndDlg, uMsg, wParam, lParam); break; } //一定要保存好替换函数后原来的函数指针,如果不用原来的函数处理那么 listbox 中将不绘制 return CallWindowProc(oldProc, hwndDlg, uMsg, wParam, lParam); //return lResult; } //clq add _end; void CShowDlg::InitControl() { //得到控件句柄 RECT rectWindow; GetClientRect(m_hWnd, &rectWindow); hwndListMarket = GetDlgItem(m_hWnd, IDC_LISTMENU); hwndEditMarket= GetDlgItem(m_hWnd, IDC_EDIT_TEXT); //clq add //要响应 WM_LBUTTONUP 等消息,必须自己写处理函数并替代默认的消息处理函数 oldProc=(WNDPROC)SetWindowLong(hwndListMarket,GWL_WNDPROC,(long)ListBoxProc); //SetWindowLong(hwndListMarket,GWL_WNDPROC,(long)ListBoxProc); //clq add _end;
guest
2007-10-18 22:31:34 发表
编辑
据说这个就是所谓的 "窗口子类化" 见下面这个转贴的文章. ListBox中的滚动条 也不能算是心得吧,在学习过程中掌握了一些处理ListBox的方法,所以做下记录. 在LISTBOX中如果在CreateWindow时使用的是WS_VSCROLL,则LISTBOX会有垂直的滚动条. 一般来说你可以向滚动条发送以下的消息: LB_INSERTSTRING 插入字符串 LB_ADDSTRING 添加字符串 LB_DELETESTRING 删除字符串 LB_RESETCONTENT 清空LISTBOX LB_SETCURSEL 设置当前选择项 LB_GETCURSEL 得到当前选择项 通过GetCurSel()可以获得同样的效果 LB_GETTEXT 得到字符串 LB_GETTEXTLEN 得到字符串长度 LB_GETCOUNT 得到项数 以下是LISTBOX的通知码,也就是当用户对LISTBOX进行操作时系统会发送给窗口消息队列的通知 LBN_SELCHANGE 改变选择项目时 LBN_DBLCLK 双击选项 LBN_SELCANCEL ....... LBN_SETFOCUS 得到焦点 LBN_KILLFOCUS 失去焦点 这些消息的处理都已经是定死的,如果想自己处理这些消息,就必须将窗口子类化 LRESULT CALLBACK ListBoxProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_VSCROLL: switch(LOWORD(wParam)) { case SB_LINEDOWN: MessageBox(NULL,_T("fff"),NULL,MB_OK); break; ........ } break; } return CallWindowProc(oldProc,hWnd,message,wParam,lParam); } 在主窗口CREATE的消息里加上 oldProc=(WNDPROC)SetWindowLong(hwndListBox,GWL_WNDPROC,(long)ListBoxProc); 其中oldProc是LISTBOX原来的处理函数 ; 在看下我们自己写的处理函数中的最后句.因为只处理了SB_LINEDOWN消息,所以我们必须将其他的消息交给原来的处理函数做处理 wParam=MAKELONG(SB_THUMBTRACK,iVscrollPos); SendMessage(hwndListBox,WM_VSCROLL,wParam,lParam); 你也可以这样向LISTBOX发送消息,这样原来的消息处理函数就会把LISTBOX的滚动条移动到iVscrollPos的位置
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.