none
如何封装ComboBox控件见内图? RRS feed

  • 问题

  • 想要充分封装ComboBox控件,以便实现下面的效果:

                          

    说明:

    1>当鼠标移动到某一个Droplist的item上的时候,该list上面:

        <1>一个图片,然后两行字符串,再一个button[这个button可以监听到鼠标是否移动到button窗口的有效区域内],

       问题1:如何封装这个复杂的droplist item?

    2>如何修改下面黑色方框内的droplist 按钮的宽度?

                         

    2012年10月29日 8:14

全部回复

  • 查了一下:

    1>需要重绘ComboBox;

    由于ComboBox由Edit,ListBox组成

    2>分别重绘Edit 和ListBox控件;

    2012年10月29日 9:48
  • 重写CComboBox类,在虚函数中WindowProc处理WM_CTLCOLORLISTBOX消息。另外您还得有个自绘的CListBox控件类。

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年10月29日 14:19
    版主
  • void CSubclassComboBox::OnEditPaint(CDC* pDC) { //绘制客户区 CDC dMemDC; dMemDC.CreateCompatibleDC(pDC); dMemDC.SetMapMode(pDC->GetMapMode()); //画动作 CBitmap mNewBmp; CRect rc; GetClientRect(&rc); mNewBmp.CreateCompatibleBitmap(pDC, rc.right - rc.left, rc.bottom - rc.top); CBitmap* pOldBmp = dMemDC.SelectObject(&mNewBmp); dMemDC.Rectangle( &rc ); CRect rcLeft; rcLeft = rc; dMemDC.SetBkMode( TRANSPARENT ); // Draw the text to Edit of ComboBox rcLeft.right = rc.right - 30; dMemDC.DrawText( _T("First Line Data"),&rcLeft,DT_VCENTER|DT_LEFT|DT_SINGLELINE ); // Draw the drop down button area of ComboBox CRect rcEnd(rc); rcEnd.left = rc.right - 30; // The Button Rect is show right!! if( m_bDropDownButtonDown ) { dMemDC.DrawFrameControl( &rcEnd,DFC_SCROLL,DFCS_SCROLLDOWN|DFCS_FLAT|DFCS_MONO|DFCS_PUSHED ); } else { dMemDC.DrawFrameControl( &rcEnd,DFC_SCROLL,DFCS_SCROLLDOWN|DFCS_FLAT|DFCS_MONO ); } // The Icon not display!!

    // Because that the rect area not correct :) oh shit! if ( m_bMouseTracked ) { ::DrawIconEx( dMemDC.m_hDC,rcEnd.left,rcEnd.top,AfxGetApp()->LoadIcon( IDR_MAINFRAME ),21,22,NULL,NULL,DI_NORMAL ); } else { ::DrawIconEx( dMemDC.m_hDC,rcEnd.left,rcEnd.top,AfxGetApp()->LoadIcon( IDR_MAINFRAME ),21,22,NULL,NULL,DI_NORMAL ); } // Draw the editor area of ComboBox: pDC->BitBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, &dMemDC, rc.left ,rc.top, SRCCOPY); //Recovery dMemDC.SelectObject(pOldBmp); pOldBmp->DeleteObject(); dMemDC.DeleteDC(); }

    Above is my code for draw the ComboBox.

    1>I want replace the orignal button[rect] with my Icon!

        But the Icon display nothing!

    2>I want display the text "First Line data" to the Edit of ComboBox in above code!

         But the Text display nothing!!

    So What' wrong with my code?


    • 已编辑 iamcxl 2012年11月1日 3:10
    2012年10月31日 8:52
  • Now I find out a stranger problem:

    I disable my OnPaint function, but there still a gray color rect on my SubclassComboBox rect area!

                          

    I guess that maybe some message do it, and I try to catch the message as below, but I still find nothing!

    PTW, CSubclassComboBox inherited from CComboBox.

    LRESULT CSubclassComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
    	if( WM_GETDLGCODE == message)  
    	{  
    		TRACE("0x0087 == message\n");
    		return TRUE;
    	}  
    	if( WM_PAINT == message)  
    	{  
    		TRACE("0x000F == message\n");
    		return TRUE;
    	}  
    	if( WM_NCPAINT == message)  
    	{  
    		TRACE("0x0085 == message\n");
    		return TRUE;
    	}  
    	if( WM_ERASEBKGND == message)  
    	{  
    		TRACE("0x0014 == message\n");
    		return TRUE;
    	}  
    	if( WM_CTLCOLOREDIT == message)  
    	{  
    		TRACE("0x0133 == message\n");
    		return TRUE;
    	}  
    	if( WM_CTLCOLORLISTBOX == message)  
    	{  
    		HWND hListBox = (HWND)lParam;  
    
    		CListBox* pListBox = (CListBox*)FromHandle(hListBox);  
    		ASSERT(pListBox);  
    		int nCount = pListBox->GetCount();  
    		TRACE("0x0134 == message\n");
    		return TRUE;
    	}  
    
    	if( 0x0019 == message)  
    	{  
    		TRACE("0x0019 == message\n");
    		return TRUE;
    	}  
    	//OutputDebugString(L"WindowProc: message \n");
    	TRACE("WindowProc: message = %d\n",message);
    	return CComboBox::WindowProc(message, wParam, lParam);
    }

    And I have disable my OnPaint as below:

    void CSubclassComboBox::OnPaint( )
    {
    	CPaintDC dc(this); // device context for painting
    	//myPaint(&dc);
    }

    2012年11月1日 7:36