troubleshooting Question

PropertySheet redraw problem

Avatar of k3rv1n
k3rv1n asked on
3 Comments1 Solution605 ViewsLast Modified:

I am writing an Microsoft Outlook extension in the form of a C++ / Win32 API DLL.  The extension DLL has the ability to display a property sheet using the Win32 API function PropertySheet().

My property dialog displays fine and I am able to load the property sheet when first displayed, and store any modified controls when the user clicks 'OK'.  Great!

But I still have a problem.  Neither Outlook, the application that calls by DLL function nor my DLL's property sheet dialog redraw themselves.  If I move the dialog around over the Outlook window, the parts that had been covered by the dialog are not redrawn.  Also the dialog itself does not redraw, except for the edit controls and buttons when you click on them.

I have never used PropertySheet() or done Win32 API GUIs before, so I do not know if I am handling all the events I should.  Should I be handling WM_PAINT?  Am I missing some event or property sheet option / flag?

Any help or clues would be greatly appreciated.

The full source of my function can be found at

Except follows....

STDMETHODIMP otlkcon_config::showGui()
    HRESULT result       = S_OK;
    PROPSHEETPAGE psp[2] = {0};
    PROPSHEETHEADER psh  = {0};
    HMODULE hMod         = 0;
    hMod = GetModuleHandleW(OTLKCON_MSTORE_DLL_NAME);

    // Property Sheet Header
    psh.dwSize      = sizeof(PROPSHEETHEADER);
    psh.dwFlags     = PSH_PROPSHEETPAGE;
    psh.hwndParent  = ulUIParam;
    psh.hInstance   = hMod;
    //  psh.pszIcon =
    // psh.pszCaption    = (LPSTR) "Cell Properties";
    psh.nPages           = 2;//sizeof(psp) / sizeof(PROPSHEETPAGE);
    psh.nStartPage       = 0;
    psh.ppsp             = (LPCPROPSHEETPAGE) &psp;
    psh.pfnCallback      = NULL;//(PFNPROPSHEETCALLBACK)otlkcon_sheetCallback;

    // First Page
    psp[0].dwSize        = sizeof(PROPSHEETPAGE);
    //psp[0].hInstance   = NULL;
    psp[0].pszTemplate   = MAKEINTRESOURCE(IDD_GENERALPAGE);
    //psp[0].pszIcon     = MAKEINTRESOURCE(IDI_FONT);
    psp[0].pfnDlgProc    = (DLGPROC)otlkcon_sheet1DlgProc;
    psp[0].lParam        = (LPARAM)this;
    psp[0].pszTitle      = "General Page";
    psp[0].pfnCallback   = otlkcon_sheetCallback;
    psp[0].hInstance     = hMod;

    // Second Page
    psp[1].dwSize        = sizeof(PROPSHEETPAGE);
    //psp[1].hInstance   = NULL;
    psp[1].pszTemplate   = MAKEINTRESOURCE(IDD_DEBUGPAGE);
    //psp[1].pszIcon     = MAKEINTRESOURCE(IDI_FONT);
    psp[1].pfnDlgProc    = (DLGPROC)otlkcon_sheet2DlgProc;
    psp[1].lParam        = (LPARAM)this;
    psp[1].pszTitle      = "Debug Page";
    psp[1].pfnCallback   = otlkcon_sheetCallback;
    psp[1].hInstance     = hMod;

    // Show the sheets
    INT_PTR ret = PropertySheet(&psh);

    return result;

INT_PTR CALLBACK otlkcon_sheet1DlgProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam )
    INT_PTR result = 0;
    HRESULT res = S_OK;
    otlkcon_config *conf = NULL;
    wchar_t *tmpDbFilename = NULL;
    bool tmpXPEnable = false;

    sheet = (LPPROPSHEETPAGE)lparam;

    switch (uMsg)
          case WM_INITDIALOG:
            if( sheet )
                conf = (otlkcon_config *)sheet->lParam;
                tmpDbFilename = wcsdup( conf->dbFilename.c_str() );
                tmpXPEnable   = conf->xpEnabled;
            SetWindowLong(hwnd, GWL_USERDATA, (LONG)conf);

            // PR_PST_PATH
            if( tmpDbFilename
                    && (SetDlgItemTextW(hwnd, IDC_DATAFILE_EDIT, tmpDbFilename) == 0) )

            // PR_OTLKCON_XP_ENABLED
            if( CheckDlgButton(hwnd, IDC_ENABLE_XPP_CHECK,
                                tmpXPEnable?BST_CHECKED:BST_UNCHECKED) == 0 )

            return TRUE;

        case WM_NOTIFY:
            switch (((NMHDR*)lparam)->code)
                case PSN_APPLY:
                    conf = (otlkcon_config *)GetWindowLong(hwnd, GWL_USERDATA);
                    tmpDbFilename = (wchar_t *)calloc(1, (MAX_PATH+1)*sizeof(wchar_t));

                    // PR_PST_PATH
                    if( GetDlgItemTextW(hwnd, IDC_DATAFILE_EDIT, tmpDbFilename, MAX_PATH)
                                                == 0 )
                    conf->dbFilename = tmpDbFilename;

                    // PR_OTLKCON_XP_ENABLED
                    if( IsDlgButtonChecked(hwnd, IDC_ENABLE_XPP_CHECK )
                                                            == BST_CHECKED )
                        conf->xpEnabled = true;
                        conf->xpEnabled = false;
                    return FALSE;
            return FALSE;
    return TRUE;
Join our community to see this answer!
Unlock 1 Answer and 3 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 3 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros