CPropertySheet - Update CListCtrl on inactive page

Hi,

I have an application which has three tabs. Each tab has a CListCtrl and when the application is started, I want to insert some items into those listboxes.  The problem I am having is that I get debug assertion errors because if I try to insert an item into a listbox located on a sheet that is not active, the hwnd pointer is NULL.  

I can think of two ways of getting around this.  One is to set the page as active everytime an item is inserted into the listbox.  This is not the way I would like to do this because I do not want the application to switch pages by itself all the time.  The second way would be to check of the page is active and if not, store the item to insert into a list.  When the page gets activated, the list would be emptied into the list box.  

I was wondering if there is any other way I can do this.

Your help is greatly appreciated.

Cheers
StanChartAsked:
Who is Participating?
 
nonubikConnect With a Mentor Commented:
If you want to do any operations on a child control (the listbox here) before OnInitDialog of its parent (the property page) has been called you'll fail because the children do not have a window.

So, in the AddRequestLog method you could check the listbox whether it has a valid handle. If yes, do as before. If not, store the data you want to insert in the list in some member variables and then you will fill the list with this data in OnInitDialog. Something like:

*****************************************
// Add the server log to the list box.
if(m_ctrlServerLog.m_hWnd)
{
  m_ctrlServerLog.InsertItem(0, logDateTime.Format("%d-%b-%y %H:%M:%S"));
  m_ctrlServerLog.SetItemData(0, 0);
  m_ctrlServerLog.SetItemText(0, SL_LOG_COLUMN, log);
  UpdateData(FALSE);
}
else
{
  m_strSomeData = logDateTime.Format("%d-%b-%y %H:%M:%S");
...
}
return TRUE;
*****************************************

OnInitDialog
{
...
  if(m_strSomeData != "")
  {
    m_ctrlServerLog.InsertItem(0, m_strSomeData);
    m_ctrlServerLog.SetItemData(0, 0);
    m_ctrlServerLog.SetItemText(0, SL_LOG_COLUMN, log);
  }
}
0
 
nonubikCommented:
>I was wondering if there is any other way I can do this.

What you should do is to initialize your listboxes in the OnInitDialog method of each of your CPropertyPages. This method is called only once when the dialog is about to be shown for the first time.

> I try to insert an item into a listbox located on a sheet that is not active, the hwnd pointer is NULL.
This is because the property page (not sheet, the sheet is the object that holds the pages/tabs) was not created yet (i.e. OnInitDialog has not been called for that page). After that, your HWND will not be NULL even if the page is inactive.
0
 
rcarlanConnect With a Mentor Commented:
The easiest way to initialise all pages when the property sheet is displayed is to derive your own class from CPropertySheet and override OnInitDialog. Call the base first, then cycle through all pages and set them active:


BOOL CMyPropertySheet::OnInitDialog()
{
    CPropertySheet::OnInitDialog();

    for (int i=0; i<GetPageCount(); ++i)
        SetActivePage(i);
    SetActivePage(0);

    return TRUE;
}

If you see any flicker (normally you shouldn't, but it depends what OnInitDialog does for each page), you can hide the property sheet just before you start cycling, and show it again after you're finished (i.e. just before returning).

Radu
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
StanChartAuthor Commented:
Hi,

Thanks for your reply.  

Here is what I am currently doing.  I derived my class from CPropertySheet and use AddPage(&myPages) to add three pages to the property sheet.  Page 1 and Page 2 have the list controls I want to update.  If I add items to the list boxes in the OnInit override, I do not get the null hwnd.  

The application I am writing is a server.  Everytime I receive a request, I want to update the list controls (might be on either page 1 or page 2 depending on the request received by the server).  The problem I have now is that I have my request handler in a separate class (created and stored inside the dialog) which has a pointer to the property sheet.  The property sheet has methods to return a pointer to each page.  Therefore when I want to update a list control after I process the request, I do something like this inside my request handler:  

m_pDialog->GetPage1()->AddRequestLog("User Logging In");
or
m_pDialog->GetPage2()->AddServerLog("Stored user login event");

The methods AddRequestLog and AddServerLog look something like this:

*****************************************
// Add the server log to the list box.
m_ctrlServerLog.InsertItem(0, logDateTime.Format("%d-%b-%y %H:%M:%S"));
m_ctrlServerLog.SetItemData(0, 0);
m_ctrlServerLog.SetItemText(0, SL_LOG_COLUMN, log);
UpdateData(FALSE);
return TRUE;
*****************************************

The only way this works is if I set the page active before I update the list box.  I do this when the GetPage1() or GetPage2() methods are called.

Is there something I am doing wrong here?

Thanks again for your help.

Cheers
0
 
StanChartAuthor Commented:
>What you should do is to initialize your listboxes in the OnInitDialog method of each of your CPropertyPages. This method is called only once when the dialog is about to be shown for the first time.

This is how I initialize the list controls on my property page's OnInit method which works.

m_ctrlServerLog.InsertColumn(SL_LOGDATETIME_COLUMN, _T("Log Date/Time"), LVCFMT_LEFT, 105);
m_ctrlServerLog.InsertColumn(SL_LOG_COLUMN, _T("Log Details"), LVCFMT_LEFT, 600);
m_ctrlServerLog.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

Cheers
0
 
StanChartAuthor Commented:
Thanks much!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.