我在做一个屏蔽Alt+Tab、Alt+Esc、Ctrl+Esc、Win键的钩子,我用隐式链接这个DLL,运行起来没有问题,我想把它做成一个VB和其它程序均可访问的DLL,于是我用显式链接这个DLL,却发现一个怪问题:当我调用禁止按键OnDisableAltTab()的时候,钩子已经被加载,但是共享变量Key_AltTab的值还是FALSE,Alt+Tab键没有被屏蔽,当我任意按一个键之后,再次调用OnDisableAltTab(),这时共享变量Key_AltTab的值变成了TRUE,Alt+Tab键可以屏蔽了。代码如下:DLL(DisableKeys.dll)的代码如下:#pragma data_seg("mysharedata")
HHOOK hook_key=NULL;
BOOL Key_AltTab=FALSE,Key_AltEsc=FALSE,Key_CtrlEsc=FALSE,Key_Win=FALSE;
#pragma data_seg()
#pragma comment (linker,"/SECTION:mysharedata,RWS")LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); BOOL bCtrl,bAlt,bEsc,bWin,bTab;
PKBDLLHOOKSTRUCT HookStruct = (PKBDLLHOOKSTRUCT) lParam; bCtrl=((GetKeyState(VK_CONTROL) & 0x8000)!=0);
bAlt=((HookStruct->flags & LLKHF_ALTDOWN)!=0);
bEsc=(HookStruct->vkCode == VK_ESCAPE);
bTab=(HookStruct->vkCode == VK_TAB);
bWin=((HookStruct->vkCode == 91)||(HookStruct->vkCode == 92)); if(nCode==HC_ACTION)
{
if((wParam==WM_KEYDOWN)||(wParam==WM_SYSKEYDOWN))
{
if(Key_AltTab==TRUE)
{
if((bAlt==TRUE)&&(bTab==TRUE))
{
return 1;
}
}
if(Key_AltEsc==TRUE)
{
if((bAlt==TRUE)&&(bEsc==TRUE))
{
return 1;
}
}
if(Key_CtrlEsc==TRUE)
{
if((bCtrl==TRUE)&&(bEsc==TRUE))
{
return 1;
}
}
if(Key_Win==TRUE)
{
if(bWin==TRUE)
{
return 1;
}
}
}
}
LRESULT Result=CallNextHookEx(hook_key,nCode,wParam,lParam);
return Result;
}__declspec(dllexport) void _stdcall DisableKey(BOOL AltTab,BOOL AltEsc,BOOL CtrlEsc,BOOL Win)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); Key_AltTab=AltTab;
Key_AltEsc=AltEsc;
Key_CtrlEsc=CtrlEsc;
Key_Win=Win; hook_key=(HHOOK)SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)KeyboardProc,theApp.m_hInstance,0);
}__declspec(dllexport) void _stdcall EnableKey()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); UnhookWindowsHookEx(hook_key);
}
主程序如下:void CMmmDlg::OnDisableAltTab() 
{
typedef void (__stdcall * _DisabledKey)(BOOL AltTab,BOOL AltEsc,BOOL CtrlEsc,BOOL Win);
HINSTANCE hDLLInst = ::LoadLibrary("D:\\MyProjects\\DisableKeys\\Debug\\DisableKeys.dll");      
_DisabledKey DisabledKey = (_DisabledKey)::GetProcAddress(hDLLInst, "DisableKey");
DisabledKey(TRUE,FALSE,FALSE,FALSE);
::FreeLibrary(hDLLInst);
}补充一点,我把“BOOL Key_AltTab=FALSE,Key_AltEsc=FALSE,Key_CtrlEsc=FALSE,Key_Win=FALSE;”放到共享段外面也还是出现一样的问题。
谁能帮我解决这个问题呀,隐式链接和显式链接为什么会有如此大的差别呀?

解决方案 »

  1.   

    隐式链接是程序运行时自动加载DLL,显式链接是动态加载DLL,这是两种方式的最大区别。
    问题应该也就出在这里。 
      

  2.   

    用 static 修饰 hDLLInst ,还是一样的问题,不行呀,急!!!!!!!!!!!!!!!
      

  3.   

    导出用extern "C" __declspec(dllexport) 去掉_stdcall
      

  4.   

    还有你LoadLibrary后马上就FreeLibrary,当然不行啊
      

  5.   

    为什么要加上extern "C",不加也一样可以的呀!
      

  6.   

    不加的话GetProcAddress(hDLLInst, "DisableKey");会失败,因为名字不是DisableKey
      

  7.   

    onestation(新手) 不会失败的,我试过了!
    谢谢了!是FreeLibrary的问题,结帖吧!