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"
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
#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();
_screensvrstarted = _callBack;
_screensvrEnded = _callBack2;
a = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)CCallBack,hins,0);
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:
break;
}
}
return CallNextHookEx(a, nCode, wParam, lParam );
}
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));
InstallHook(_clbk, _clbk2,helper.Handle);
FreeLibrary(hmod);
}