DeskBand가 실현한 문제
1. explorer를 초래할 수 있습니다.끊다
이유:이 문제가 발생한 것은 현재 DeskBand의 DLL 참조 수가 정확하지 않기 때문입니다.시스템은 현재 DLL이 시스템에서 제거될 수 있는지 확인하기 위해 일정 시간마다 DllCanUnloadNow 함수를 호출합니다.시스템은 약 15분마다 DllCanUnloadNow 함수가 S 로 되돌아올 때 검사합니다OK 시 시스템은 이 DLL을 프로세스 주소 공간에서 마운트 해제합니다. 그러면 DLL의DeskBand Window 메시지 처리 함수가 실행 중입니다. 그러나 DLL이 프로세스에서 제거되면 메시지 처리 함수의 호출이 실패하고 explorer가 발생합니다.exe 끊어.
솔루션:
1) ClassFactory 객체를 만들 때 DLL에 대한 참조 개수 glDllRefCount(전역 변수)에 1을 더하면 대상이 풀릴 때 glDllRefCount 감소 1
2)Band Object 개체를 만들 때도 이 인용 계수에 1을 더하고 놓을 때 1을 줄여야 한다. Band Object만 존재한다면 이 DLL은 반드시 존재해야 하기 때문에 Band Object가 놓으면 이 DLL은 방출될 수 있다.
2. 코드로 DeskBand를 표시하고 삭제하면 질문 대화상자가 팝업됩니다
이것은 프로그램을 통해 COM 대상이 작업 표시줄에 표시되는 것을 제어하기 때문이다. 마이크로소프트는 안전성에 대한 고려를 바탕으로 사용자에게 이 Band 대상을 표시하는지 물어보는 대화 상자를 팝업하기 때문이다. 그러면 일부 광고 프로그램이 작업 표시줄에 엉뚱하게 나타나지 않도록 하는 장점이 있다.이 대화상자를 어떻게 없애요?
갈고리를 이용하면: SetWindowsHookEx(WH CALLWNDPROCRET, (HOKPROC)HookCallWndProcRet, hCurInst, 0);
문제는 이 갈고리를 등록하는 것입니다. 프로그램이 Band를 표시하거나 숨길 때 이 갈고리를 등록해야 합니다. 따라서 일반적인 상황에서 이 DLL은 Band를 표시하거나 숨길 수 있는 내보내기 방법을 쓸 수 있습니다.
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;
}
갈고리를 이용해 창문을 갈고리로 하는 WMINITDIALOG 메시지, 대화상자 창에 있는 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);
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.