0
votes

In a typical MFC C++ dialog, I want to dynamically create a floating ListBox (or other standard control) over the dialog, possible extending past the dialog's boundaries - so it can't be a simple child or it'll be clipped.

Looking at something similar that works, I tried to achieve it but the window never appears when shown.

In my .h file I have:

CListBox m_ListBox;

Then in my OnInitDialog method (based on Serge's post):

BOOL CYourDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 m_ListBox.CreateEx(WS_EX_STATICEDGE | WS_EX_TOOLWINDOW, _T("LISTBOX"), NULL, 
  WS_CHILD | WS_CAPTION | LBS_STANDARD | WS_HSCROLL | WS_SYSMENU | WS_VISIBLE,  
  CRect(50, 100, 200, 200), this, 1);

 m_ListBox.AddString(L"one");
 m_ListBox.AddString(L"two");
 m_ListBox.AddString(L"three");

 return true;
}

The problem is the list-box is rendered beneath other controls in the dialog. I tried calling BringWindowToTop but it doesn't help.

Also, the new control can't extend beyond the edge of the dialog... since it's being used similar to the drop-list in a combo-box, that would be nice.

1
I think you should put the control inside a toolbar oder dialogbar and create that. I'm sure you will find an example on codeguru.com!dwo
It's not an answer to your question but you don't want to cast the COLOR_WINDOW to an HBRUSH in the call to AfxRegisterClass - use GetSystemColorBrush(COLOR_WINDOW) instead.ReinstateMonica Larry Osterman

1 Answers

0
votes

It looks like you can't see the window created due to using GetDesktopWindow to set its parent. Check if following changes to your code would work fine for you, it should create a listbox with 3 items and you should be able to close it ot move it around the dialog.

BOOL CYourDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 m_ListBox.CreateEx(WS_EX_STATICEDGE | WS_EX_TOOLWINDOW, _T("LISTBOX"), NULL, 
  WS_CHILD | WS_CAPTION | LBS_STANDARD | WS_HSCROLL | WS_SYSMENU | WS_VISIBLE,  
  CRect(50, 100, 200, 200), this, 1);

 m_ListBox.AddString(L"one");
 m_ListBox.AddString(L"two");
 m_ListBox.AddString(L"three");

 return true;
}

Also I believe you would want to consider using control bars to implement docking\floating functinality for your window.

update0 popup window with listbox

class CPopUpTest : public CFrameWnd
{
private:
    CListBox* m_ListBox;
public:
    CPopUpTest();
protected:
    DECLARE_MESSAGE_MAP()
    afx_msg void OnSize(UINT nType, int cx, int cy);
};

CPopUpTest::CPopUpTest()
{
    m_ListBox = NULL;
    Create(NULL, L"Pop up listbox test", WS_POPUPWINDOW | WS_CAPTION | WS_SIZEBOX, 
        CRect(400, 280, 580, 520), NULL, NULL, WS_EX_TOOLWINDOW);

    CRect rect;
    GetClientRect(&rect);

    m_ListBox = new CListBox();
    m_ListBox->Create(WS_CHILD | WS_VISIBLE | LBS_NOTIFY  | LBS_NOINTEGRALHEIGHT | LBS_SORT | WS_VSCROLL, rect, this, 1);

    m_ListBox->AddString(L"one");
    m_ListBox->AddString(L"two");
    m_ListBox->AddString(L"three");
    m_ListBox->AddString(L"four");
}

BEGIN_MESSAGE_MAP(CPopUpTest, CFrameWnd)
   //{{AFX_MSG_MAP(CMainFrame)
   ON_WM_SIZE()
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CPopUpTest::OnSize(UINT nType, int cx, int cy)
{   
    CFrameWnd::OnSize(nType, cx, cy);
    if (m_ListBox!=NULL) m_ListBox->MoveWindow(0, 0, cx, cy);
}

then whenever you want to show this window do:

CPopUpTest* popUpList = new CPopUpTest();
popUpList->ShowWindow(SW_NORMAL);
popUpList->BringToTop(SW_NORMAL);

hope this helps, regards