在做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); } } }