how to display the images of CcomboboxEx items at right side instead of the left side of text?

bingbing457 40 Reputation points
2023-08-19T05:07:44.82+00:00

The MFC control CcomboBoxEx always show images at the left side of text of each item, but my client requires the icon or image to show up at the right side of the text of each item in CcomboBoxEx control, how to do it?

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,912 questions
{count} votes

Accepted answer
  1. Minxin Yu 13,501 Reputation points Microsoft External Staff
    2023-08-21T07:05:21.3466667+00:00

    Hi, @bingbing457
    As RLWA32 said, you need to handle OwnerDraw.

    Below is a quick test. Using Drop List type:

    User's image

    Header:

    class MyBox : public CComboBoxEx {
     DECLARE_DYNAMIC(MyBox)
    public: MyBox(); 
    virtual ~MyBox(); 
    protected: 
    afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
    afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct); 
    protected: DECLARE_MESSAGE_MAP() };
    

    Cpp:

    // MyBox.cpp : implementation file
    //
    
    #include "pch.h"
    #include "MFCApplication1.h"
    #include "MyBox.h"
    
    
    // MyBox
    
    IMPLEMENT_DYNAMIC(MyBox, CComboBoxEx)
    
    MyBox::MyBox()
    {
    
    }
    
    MyBox::~MyBox()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(MyBox, CComboBoxEx)
    	ON_WM_DRAWITEM()
    	ON_WM_MEASUREITEM()
    END_MESSAGE_MAP()
    
    
    
    // MyBox message handlers
    
    
    void MyBox::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
        if (nIDCtl == GetDlgCtrlID())
        {
            CDC dc;
            dc.Attach(lpDrawItemStruct->hDC);
    
            CString strText;
            GetLBText(lpDrawItemStruct->itemID, strText);
    
            CRect rectText = lpDrawItemStruct->rcItem;
            CRect rectImage = rectText;
            int iconWidth = 16; 
            int iconHeight = 16; 
            rectImage.left = rectText.right - iconWidth;
    
            COMBOBOXEXITEM item;
            item.mask = CBEIF_IMAGE;
            item.iItem = lpDrawItemStruct->itemID;
            GetItem(&item); 
    
            int imageIndex = item.iImage;
            CImageList* pImageList = GetImageList();
    
            if (pImageList && imageIndex >= 0)
            {
                CPoint ptImage(rectImage.left, rectImage.top + (rectImage.Height() - iconHeight) / 2);
                pImageList->Draw(&dc, imageIndex, ptImage, ILD_TRANSPARENT);
                rectText.right -= iconWidth; 
            }
    
            dc.DrawText(strText, rectText, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
    
            dc.Detach();
        }
    }
    
    
    void MyBox::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
    {
        if (nIDCtl == GetDlgCtrlID())
        {
           
            lpMeasureItemStruct->itemHeight = 20; 
        }
    }
    

    User's image

    Best regards,

    Minxin Yu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. RLWA32 48,236 Reputation points
    2023-08-20T15:15:14.0766667+00:00

    The ComboBoxEx common control does not have built-in support for drawing the image to the right side of the text. Additionally, it uses owner draw with a child ComboBox control.

    So to achieve your objective it seems to me that you can handle owner draw with a ComboBox control or subclass a ComboBoxEx control to handle WM_DRAWITEM.

    I know that its not the desired answer but I don't see another way.

    1 person found this answer helpful.

  2. Castorix31 88,461 Reputation points
    2023-08-21T07:08:35.2633333+00:00

    You could use WS_EX_LAYOUTRTL (but text also on right...)

    In Control Spy :

    User's image


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.