Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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
#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 );	
}

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);
}
Posted
Updated 21-Nov-10 22:52pm
v4
Comments
LittleYellowBird 22-Nov-10 4:51am    
Hi, please do not use capitals to shout your request for help. If people want to help they will, and shouting is likely to put people off. I have removed the offending word. :)
suman@dinhy 22-Nov-10 20:26pm    
thanks for ur advice and what you have done for the capital.
I'm sorry about the bad capitals yesterday.I'll be more polite
actrually it was an urgency of my yesterday's problem.

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;


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
 
Share this answer
 
Comments
suman@dinhy 22-Nov-10 20:35pm    
thank u for ur replay,I will try ur solution today,and post the result later.
I Fixed The Problem by Using [dllimport] to load the dll instead of LoadLibrary(...)

BUT Still doubt about the MessageBox(...) magic.
 
Share this answer
 
Comments
Manfred Rudolf Bihy 22-Nov-10 7:06am    
Great if you worked it out! Would it be to much to ask of you to try that bit with the message box that never gets called, with your previous code. I'd really like to know ...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900