GLOBAL HOOK CALLBACK非托管代码! [英] GLOBAL HOOK CALLBACK unmanaged code!

查看:102
本文介绍了GLOBAL HOOK CALLBACK非托管代码!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我需要你的帮助.

我写了一个WPF APP,它需要在Win7上捕获ScreenSaver事件.
我首先用C ++编写了DLL.
加载dll时,我通过调用InstallHook(HOOKPROC _callBack,HOOKPROC _callBack2,HWND _mainwin)将两个委托回调设置为HOOK dll,但是回调不起作用!

神奇的是,当我取消对InstallHook函数中的MessageBox(...)行的注释时,它运行得很好!
但是MessageBox(...)对于该APP是不可接受的.
对于我的问题,有没有解释或解决的方法,谢谢!!

像这样的dll代码:
glblhc.h

Hi all,
I need your help.

I''ve wrote a WPF APP which need to catch the ScreenSaver event on Win7.
I first wrote DLL in C++.
When the dll is loaded,I set two delegate callbacks to the HOOK dll by call InstallHook(HOOKPROC _callBack,HOOKPROC _callBack2,HWND _mainwin), but the callbacks does''nt work!

What made a magic is that when I uncomment the MessageBox(...) line in the InstallHook function.It WORKS WELL!
but the MessageBox(...) is unacceptable for the APP.
Is there an explanation or solution for my question,Thanks IN Advance!

the dll code like this:
glblhc.h

#pragma once
#ifndef __AFXWIN_H__
	#error "include ''stdafx.h'' before including this file for PCH"
#endif
#include "resource.h"		// main symbols
// CglblhcApp
// See glblhc.cpp for the implementation of this class
//
EXTERN_C BOOL __declspec(dllexport)__stdcall  InstallHook(HOOKPROC _callBack,HOOKPROC _callBack2,HWND _mainwin);
LRESULT __declspec(dllexport)__stdcall  CALLBACK CCallBack(
                            int nCode, 
                            WPARAM wParam, 
                            LPARAM lParam);


glblhc.cpp


glblhc.cpp

#include "stdafx.h"
#include "glblhc.h"
HHOOK a = NULL;
BOOL IsInSleep = false;
HOOKPROC _screensvrstarted = NULL; 
HOOKPROC _screensvrEnded =NULL;
HINSTANCE hins = NULL;
BOOL __declspec(dllexport)__stdcall InstallHook(HOOKPROC _callBack,HOOKPROC _callBack2,HWND _mainwin)
{ 
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	hins=AfxGetInstanceHandle();
	//DWORD threadId = ::GetWindowThreadProcessId(_mainwin,0);
	_screensvrstarted = _callBack;
	_screensvrEnded = _callBack2;
	a = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)CCallBack,hins,0);
	//MessageBox(0,_T("hooked!"),_T("note"),1);
	return TRUE;
}
LRESULT   CALLBACK CCallBack( int nCode, WPARAM wParam, LPARAM lParam)
{
	MSG *msg;
	if(nCode >=0 && nCode == HC_ACTION)
	{
		msg = (MSG*)lParam;
		switch (msg->message)
		{
		     case WM_SYSCOMMAND:
			{
			if (msg->wParam == SC_SCREENSAVE){
			  if(!IsInSleep){						                     IsInSleep = true;							    _screensvrstarted( nCode, wParam, lParam);
				}
			}
			break;
			}
		     default:
			//TODO...
			break;
             }
	}
return CallNextHookEx(a, nCode, wParam, lParam );	
}


然后我从wpf窗口的window_loaded事件加载dll,如下所示:


Then I load the dll from window_loaded event of an wpf window,like this:

        [DllImport("kernel32.dll")]
        internal static extern IntPtr LoadLibrary(string lpLibFileName);
        [DllImport("kernel32.dll")]
        internal static extern bool FreeLibrary(IntPtr hLibModule);
        [DllImport("kernel32.dll")]
        internal static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
        IntPtr hmod;
        public ScreenSvrStarted_callback _clbk = new ScreenSvrStarted_callback(ScreenSvrStarted);
        public ScreenSvrEnded_callback _clbk2 = new ScreenSvrEnded_callback(ScreenSvrEnded);

        public delegate int HookProc(
            [MarshalAs(UnmanagedType.FunctionPtr)]ScreenSvrStarted_callback _callback,
            [MarshalAs(UnmanagedType.FunctionPtr)]ScreenSvrEnded_callback _callback2,IntPtr _mainWin);
        public delegate int ScreenSvrStarted_callback(int nCode, IntPtr wParam, IntPtr lParam);
        public delegate int ScreenSvrEnded_callback(int nCode, IntPtr wParam, IntPtr lParam);

        public static int ScreenSvrStarted(int nCode, IntPtr wParam, IntPtr lParam)
        {
            Console.Beep();
            return 0;
        }
        public static int ScreenSvrEnded(int nCode, IntPtr wParam, IntPtr lParam)
        {
            Console.Beep();
            Console.Beep();
            return 0;
        }
private void Window_Loaded(object sender, RoutedEventArgs e)
     {
            WindowInteropHelper helper = new WindowInteropHelper(this);
            hmod = LoadLibrary("glblhc.dll");
            IntPtr fn = GetProcAddress(hmod, "InstallHook");
            HookProc InstallHook = (HookProc)Marshal.GetDelegateForFunctionPointer(fn, typeof(HookProc));
            //hook!
            InstallHook(_clbk, _clbk2,helper.Handle);
            FreeLibrary(hmod);
}

推荐答案

我知道我可能为此受到打击,但是...
您能否尝试将其添加到您的InstallHook函数:

I know I might get hit for this, but ...
would you please try to add this to your InstallHook function:

if(myVolatile == 42)
{
    MessageBox(0,_T("hooked!"),_T("note"),1);
}



并全局声明:



and globally declare:

volatile int myVolatile = 0;



我只是好奇,如果它与链接的消息框有关系,并且可以正常工作,尽管MessageBox函数永远不会被调用(但由于myVolatile易失性,编译器无法删除if语句:-D)

干杯

Manfred



I''m just curios if it has something to do with the message box being linked in and if it works then eventhough the MessageBox function never gets called (but the compiler cant drop the if statement because of myVolatile being volatile :-D )

Cheers

Manfred


我通过使用[dllimport]加载dll而不是LoadLibrary(...)
解决了该问题
但是仍然对MessageBox(...)的魔力仍然存疑.
I Fixed The Problem by Using [dllimport] to load the dll instead of LoadLibrary(...)

BUT Still doubt about the MessageBox(...) magic.


这篇关于GLOBAL HOOK CALLBACK非托管代码!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆