MFC

roger's picture

Misleading Error: "Parent class code is read only" (Visual Studio.NET)

I just had a strange error message from Visual Studio.NET when attempting to add a handler for WM_DESTROY to a C++ dialog class. It said:

Add/Remove of the function is impossible because the parent class code is read only

Odd. There's nothing read-only about any of this stuff.

It turns out that I'd previously had an OnDestroy function in that class, and (somehow) the ON_WM_DESTROY() macro had been left in the message map. This apparently confuses Visual Studio.

Just remove the old ON_WM_DESTROY() line, and it's happy to add a new one.

roger's picture

Using a modal or modeless dialog as a main window

Using a modal dialog as a main window

If you ask the MFC AppWizard to generate a dialog-based application, it generates code that looks like this:

BOOL CModalApp::InitInstance()
{
    CModalDlg dlg;
    m_pMainWnd = &dlg;
    int nResponse = dlg.DoModal();

    // TODO: Do something, based on nResponse (IDOK or IDCANCEL)

    // Since the dialog has been closed, return FALSE so that we exit the
    //  application, rather than start the application's message pump.
    return FALSE;
}

Using a modeless dialog as a main window

Unfortunately, this doesn't work properly if you have control bars in your dialog. This is because DoModal doesn't use the standard MFC message loop. This means that OnIdle is not called. If OnIdle is not called, then WM_IDLEUPDATECMDUI is not sent, and the control bars aren't updated correctly.

roger's picture

Disabling the Cancel button in a Wizard

CPropertySheet provides the SetWizardButtons function, allowing you to enable or disable the "Back" or "Next" buttons. It doesn't, however, allow you to disable the "Cancel" button.

Here's how:

CWnd *pCancel = GetParent()->GetDlgItem(IDCANCEL);
if (pCancel)
	pCancel->EnableWindow(FALSE);

roger's picture

Displaying Progress in a Wizard

I'm adding a wizard to the program that I'm currently working on. The wizard walks the user through importing some information from a file. I'd like to be able to display the import progress as a seamless part of the wizard.

roger's picture

CPropertySheet vs CPropertySheetEx in Visual Studio .NET 2003

The program that I'm working on at the moment needs a wizard to walk the user through something. I copied over some files from a Wizard97 demo project that I wrote a while ago. It all seemed to be going well.

Except, that is, that IntelliSense in Visual Studio kept pretending that my classes were derived from CPropertySheet or CPropertyPage, rather than CPropertySheetEx or CPropertyPageEx respectively.

This was confusing.

It turns out that at some point between VC6 and VS.NET, Microsoft changed the definition of CPropertySheetEx and CPropertyPageEx in the MFC headers. They are the same -- one is a #define of the other.

roger's picture

Using ON_COMMAND_RANGE and ON_UPDATE_COMMAND_UI_RANGE

The ON_COMMAND_RANGE and ON_UPDATE_COMMAND_UI_RANGE macros are useful when you want to treat a group of commands similarly. In this case, it's the commands for changing list view style. The command IDs must be contiguous, and you must specify the lower one first.

roger's picture

Putting control bars in a dialog

There's some discussion of this in Microsoft Knowledge Base Article Q141751.

Putting control bars in a dialog

This is initially quite simple:

class CCustomDrawDlg : public CDialog
{
    // See Q141751
    CDialogToolBar m_wndToolBar;
    CStatusBar m_wndStatusBar;
    // ...
int CCustomDrawDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialog::OnCreate(lpCreateStruct) == -1)
	return -1;

    if (!m_wndToolBar.CreateEx(this) ||
	!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
	TRACE0("Failed to create toolbar\n");
	return -1;      // fail to create
    }

    if (!m_wndStatusBar.Create(this))
    {
	TRACE0("Failed to create statusbar\n");
	return -1;
    }

    return 0;
}

Syndicate content