I am trying to use some property sheets using C++ and the winapi. I am creating it 'modelessly' from a plug-in dll, and this has given rise to some funny problems trying to close/deal with the sheets properly. So basically, I create a thread with a message loop, and also create the property sheets. I do something like this
Code:
DWORD WINAPI ThreadProc(LPVOID t)
{
BOOST_LOGL(app, info) << __FUNCTION__;
PROPSHEETHEADER m_PropSheet = {0};
PROPSHEETPAGE m_psp[2] = {0};
m_psp[0].dwSize = sizeof(PROPSHEETPAGE);
m_psp[0].dwFlags = PSP_DEFAULT | PSP_USETITLE;
m_psp[0].hInstance = ::GetModuleHandle(TEXT("Itunesplugin.dll"));
m_psp[0].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG_SUBONE);
m_psp[0].pszTitle = TEXT("Page 1");
m_psp[1].pfnDlgProc = &DlgSubOne;
m_psp[1].dwSize = sizeof(PROPSHEETPAGE);
m_psp[1].dwFlags = PSP_USETITLE;
m_psp[1].hInstance = ::GetModuleHandle(TEXT("Itunesplugin.dll"));
m_psp[1].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG_SUBTWO);
m_psp[1].pszTitle = TEXT("Page 2");
m_psp[1].pfnDlgProc = &DlgSubTwo;
m_PropSheet.dwSize = sizeof(PROPSHEETHEADER);
m_PropSheet.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_MODELESS;
m_PropSheet.hInstance = ::GetModuleHandle(TEXT("Itunesplugin.dll"));
m_PropSheet.pszCaption = TEXT("Cell Properties");
m_PropSheet.nPages = 2;
m_PropSheet.nStartPage = 0;
m_PropSheet.ppsp = m_psp;
m_PropSheet.pfnCallback = &SheetProc;
HWND properties = reinterpret_cast<HWND>(PropertySheet(&m_PropSheet));
MSG msg;
while(::GetMessage(&msg, 0, 0, 0) > 0)
{
if(!::SendMessage(properties, PSM_ISDIALOGMESSAGE, 0, LPARAM(&msg)))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if(properties && ::SendMessage(properties, PSM_GETCURRENTPAGEHWND, 0, 0))
{
BOOST_LOG(app) << "Destroyableed";
::DestroyWindow(properties);
properties = 0;
}
}
VisualPluginHandler(0x4337, 0, t);
return 0;
}
And basically, the PSM_GETCURRENTPAGEHWND test seems to be wierd (http://msdn2.microsoft.com/en-us/library/ms670339.aspx)
Code:
SymTDI: ProcTrack: CalculateSignatureForModule : Module doesn't seem to have DOS header?
[3072] 18:14:48 VisualPluginHandler: Initialization
[3072] 18:15:32 VisualPluginHandler: Configure
[3072] 18:15:32 ThreadProc
[3072] 18:15:32 SheetProc
[3072] 18:15:32 SheetProc
[3072] 18:15:32 Destroyableed
My callback routines are just templates, they do nothing really, and the page sheet callbacks are never called if I have the PSM_GETCURRENTPAGEHWND test in place.
Code:
int CALLBACK SheetProc(HWND hDlg, UINT message, LPARAM lParam)
{
BOOST_LOGL(app, info) << __FUNCTION__;
switch(message)
{
case PSCB_PRECREATE:
{
LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam;
if(!(lpTemplate->style & WS_SYSMENU))
{
lpTemplate->style |= WS_SYSMENU;
}
}
break;
case PSCB_INITIALIZED:
break;
}
return 1;
}
BOOL CALLBACK DlgSubOne(HWND dlg, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOST_LOGL(app, info) << __FUNCTION__;
switch(message)
{
case WM_COMMAND:
PropSheet_Changed(GetParent(dlg), dlg);
break;
case WM_NOTIFY:
switch(LPNMHDR(lParam)->code)
{
default:
break;
}
break;
default:
break;
}
return FALSE;
}
BOOL CALLBACK DlgSubTwo(HWND dlg, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOST_LOGL(app, info) << __FUNCTION__;
switch(message)
{
case WM_COMMAND:
PropSheet_Changed(GetParent(dlg), dlg);
break;
case WM_NOTIFY:
switch(LPNMHDR(lParam)->code)
{
default:
break;
}
break;
default:
break;
}
return FALSE;
}
And here's how it's created and destroyed
Code:
static OSStatus VisualPluginHandler(
OSType message,
VisualPluginMessageInfo * messageInfo,
void * refCon
)
{
VisualPluginData * vpd = static_cast<VisualPluginData *>(refCon);
switch (message)
{
case 0x4337:
{
BOOST_LOGL(app, info) << __FUNCTION__
<< ": Killin' Threadz";
CloseHandle(vpd->threadHandle);
}
break;
case kVisualPluginConfigureMessage:
{
BOOST_LOGL(app, info) << __FUNCTION__
<< ": Configure";
vpd->threadHandle = CreateThread(0, 0, &ThreadProc, LPVOID(vpd), 0, &vpd->threadId);
}
break;
case kVisualPluginInitMessage:
{
BOOST_LOGL(app, info) << __FUNCTION__
<< ": Initialization";
INITCOMMONCONTROLSEX icx;
icx.dwSize = sizeof(INITCOMMONCONTROLSEX);
icx.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icx);
}
break;
...
}