标题
    
    
        [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软件下载及使用技巧. 
    但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件. 
    验证问题说明申请入群原因即可.