在做DeskBand过程中,遇到了一些问题,这些问题说大可大,说小可小,不是三下两下就解决了,还是花了一些时间来解决。
1. 会导致explorer.exe挂掉
2. 通过代码显示DeskBand,去掉会弹出询问对话框
得到HINSTANCE的代码如下:
HMODULE WINAPI SdkDeskBandHook::GetCurrentModuleHandle()
{
// s_somevar must be static variable, otherwise
// the returned HMODULE is not correct
// instance of current dll.
static int s_somevar = 0;
MEMORY_BASIC_INFORMATION mbi;
if(!::VirtualQuery(&s_somevar, &mbi, sizeof(mbi)))
{
return NULL;
}
return static_cast<HMODULE>(mbi.AllocationBase);
}
BOOL WINAPI SdkCommonHelper::ShowDeskBand(BOOL fShowOrHide)
{
ITrayDeskBand *pTrayDeskBand = NULL;
HRESULT hr = CoCreateInstance(CLSID_TrayDeskBand, NULL, CLSCTX_ALL,
IID_PPV_ARGS(&pTrayDeskBand));
// Vista and higher operating system
if ( SUCCEEDED(hr) )
{
if ( TRUE == fShowOrHide )
{
hr = pTrayDeskBand->DeskBandRegistrationChanged();
if ( SUCCEEDED(hr) )
{
// If window hook is not started, starts it.
if ( FALSE == CSdkDeskBandHook::IsHookStart() )
{
CSdkDeskBandHook::StartHook();
}
hr = pTrayDeskBand->IsDeskBandShown(CLSID_SampleDeskBand);
if ( SUCCEEDED(hr) && (S_FALSE == hr) )
{
hr = pTrayDeskBand->ShowDeskBand(CLSID_SampleDeskBand);
}
}
}
else
{
hr = pTrayDeskBand->IsDeskBandShown(CLSID_SampleDeskBand);
if ( SUCCEEDED(hr) && (S_OK == hr) )
{
hr = pTrayDeskBand->HideDeskBand(CLSID_SampleDeskBand);
}
}
}
SAFE_RELEASE(pTrayDeskBand);
return (SUCCEEDED(hr)) ? TRUE : FALSE;
}
利用钩子,去钩窗体的WM_INITDIALOG消息,找到那个对话框窗体上的YES按钮,给它发送一个BN_CLICKED消息。反正就是模拟点击事件。在钩子的处理函数中加入如下代码:
// Find [Yes] button on the dialog box for prompting
// user allow desk band show in task bar.
LPCWPRETSTRUCT lpMsg = (LPCWPRETSTRUCT)lParam;
if ( (NULL != lpMsg) && (WM_INITDIALOG == lpMsg->message) )
{
// Get caption of dialog box, which is same with the
// name of sub menu item of toolbar.
WCHAR szCaption[100] = { 0 };
GetWindowText(lpMsg->hwnd, szCaption, 100);
// Get tool bar menu item name from registry,
// because the caption of dialog box is same
// with the tool bar menu item.
wstring strMenuName = GetToolbarMenuNameFromRegistry();
if ( (0 == CommonHelper::OrdinalIgnoreCaseCompareStrings(
szCaption, strMenuName.c_str()))
|| (0 == CommonHelper::OrdinalIgnoreCaseCompareStrings(
szCaption, L"explorer.exe")) )
{
HWND destHwnd = FindWindowEx(lpMsg->hwnd, NULL,
L"DirectUIHWND", NULL);
if ( destHwnd != NULL )
{
HWND sink = FindWindowEx(destHwnd, NULL ,
L"CtrlNotifySink", NULL);
int i = 0;
while ( i++ < 6 )
{
sink = FindWindowEx(destHwnd, sink, L"CtrlNotifySink", NULL);
}
HWND button = FindWindowEx(sink, NULL, L"Button", NULL);
SendMessage(sink, WM_COMMAND, BN_CLICKED, (LPARAM)button);
}
}
}