views:

267

answers:

1

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.

A: 

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

serge_gubenko
It almost works. Firstly I get a little popup dialog rather than a simple listbox floating - the intended use is as a auto-complete suggestion box. Secondly, the window doesn't sit on top of the dialog properly... initially it does if I step through the code, but under normal usage it virtually disappears - only the text "one" is visible, the rest is invisible.
John
Also, the listbox cannot extend beyond the dialog's boundaries, I want something that can (like how a drop-list/combobox can be wider/longer than the dialog it's on).
John
I'm little confused now, it looks like you want to make a popup window; there are tutorials on the web on how you can do it, e.g. http://www.functionx.com/visualc/applications/popupwindow.htm. Please check if the update I've made to my original reply would work for you
serge_gubenko