Solved

System-wide hook works well in Win16 but doesn't work in Win32

Posted on 1998-12-29
16
303 Views
Last Modified: 2013-12-03
Hi,

I have a system-wide hook function in DLL (Win16-based). That function sends all WM_CHAR messages to the main window of my .EXE program (Win16-based too). It works well. It sends WM_CHAR whenever I type in any application.

Yesterday, I want it supports taskbar icon notification so I change my project target (both .DLL and .EXE) to Win32 and they didn't work as before. The hook function didn't receive message when my window lost focus. In another word, it seems that hook associates only to one task (my .EXE).

For simple, I change my system-wide hook function to:
//------------------------------------------------------------------------------
LRESULT CALLBACK __export HookProc( int nCode, WPARAM Param, LPARAM lParam )
   {
            if ( nCode >= 0 ){
                  msg = * ( MSG far * ) lParam;
                  if( ((MSG far *)lParam)->message == WM_CHAR )
                        MessageBox( 0, "WM_CHAR", "Receive", MB_OK );
            }

            return CallNextHookEx( hhook, nCode, wParam, lParam);
      }

but I couldn't receive any message box when I type in other application.

Please help me. Thanks.

I have only 30 points and many questions now, please understand me! :-)
0
Comment
Question by:toannds
  • 10
  • 4
  • 2
16 Comments
 

Author Comment

by:toannds
ID: 1417841
Edited text of question
0
 

Author Comment

by:toannds
ID: 1417842
Edited text of question
0
 
LVL 12

Expert Comment

by:migel
ID: 1417843
Do you use SetWindowsHook ? If it`s true just call SetWindowsHookEx instead.
set  DWORD  dwThreadID parameter to the 0 to set system wide hook.

0
 

Author Comment

by:toannds
ID: 1417844
I already used
HHOOK SetWindowsHookEx(idHook, hkprc, hinst, htask) in my program with htask = 0.

I didn't tell you another strange:

The Win32.hlp said that we don't need to use MakeProcInstance in Win32 version, we can pass directly function address to hkprc.
But if I do what it said, SetWindowsHookEx return NULL (an error) and of course, I don't receive any message at all. By the way, can you show me which function I can use to get error in this case?

0
 
LVL 12

Expert Comment

by:migel
ID: 1417845
GetLastError
0
 
LVL 11

Expert Comment

by:alexo
ID: 1417846
toannds, a systemwide hook in win32 MUST reside in a DLL.
0
 

Author Comment

by:toannds
ID: 1417847
That's what I did: my system-wide hook resides in my DLL, it posts message to my main window.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1417848
OK, we have progress...  :-)
I have answered several hook-related questions in the past.  Here are URLs to two of them.  Please read the whole discussion (including the comments) and look at the sample code.
    http://www.experts-exchange.com/Q.10063288 (5 points)
    http://www.experts-exchange.com/Q.10069661 (4 points)

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:toannds
ID: 1417849
My already used SetWindowHooksEx in my DLL.
0
 

Author Comment

by:toannds
ID: 1417850
I'm so sorry. I wasn't intend to post previous message. That was a mistake. I'm reading alexo's answers in the past...
0
 

Author Comment

by:toannds
ID: 1417851
alexo, thank you for your answers (and I lost 9 points :-) ). Now I know hhook must be the shared data for difference tasks. I use Borland C++ 4.5 so there're some differences from your answers. My DLL project includes 3 files:

sysdata.cpp
syshook.cpp
syshook.def

The sysdata.cpp contains variables in shared data segment.
The syshook.cpp set up system-wide hook and contains hook proc.
//--------------------------------------------------------------
// sysdata.cpp
// All variables in this file are in another shared data segment besides the default DLL segment.
//--------------------------------------------------------------
#pragma option -zRSHAREDATA     //   Sets the name of the initialized data segment.
#pragma option -zSSHAREGROUP      // Sets the name of the initialized data segment group.
#pragma option -zTSHARECLASS      // Sets the name of the initialized data segment class.

#include <windows.h>

HHOOK hhook = 0;
HWND __export hwndHookReport = 0;
UINT __export wm_hookreport = 0;
MSG __export msg = {0};
//--------------------------------------------------------------
// syshook.cpp
//--------------------------------------------------------------
#include <windows.h>

HINSTANCE hInstance;
// these variables are in the shared segment
extern HHOOK hhook;
extern HWND hwndHookReport;
extern UINT wm_hookreport;
//------------------------------------------------------------------------------
LRESULT CALLBACK __export HookProc( int nCode, WPARAM Param, LPARAM lParam )
    {
        if ( nCode >= 0 ){
             if( ((MSG far *)lParam)->message == WM_CHAR )
                  MessageBox( 0, "WM_CHAR", "Receive", MB_OK );
        }
        return CallNextHookEx( hhook, nCode, wParam, lParam);
    }
//------------------------------------------------------------------------------
int far __export InstallSystemHook( HWND hwnd, UINT wm_report, int idHook )
//
//    hwnd: The window that receive wm_report every time HookProc get a message
//
    {
        FARPROC lpFunc;

        hwndHookReport = hwnd;
        wm_hookreport = wm_report;
        lpFunc = MakeProcInstance( (FARPROC) HookProc, hInstance );
        hhook = SetWindowsHookEx( idHook, (HOOKPROC) lpFunc, hInstance, 0 );
        return (int) hhook;
    }
//------------------------------------------------------------------------------
int far __export UninstallSystemHook()
    {
        return UnhookWindowsHookEx( hhook );
    }
//------------------------------------------------------------------------------
int CALLBACK LibMain( HINSTANCE hinst, WORD wDataSeg, WORD cbHeap, LPSTR lpszCmdLine )
    {
        hInstance = hinst;
        return 1;
    }
//--------------------------------------------------------------
// syshook.dll
//--------------------------------------------------------------
LIBRARY            SYSHOOK
DATA            MULTIPLE NONSHARED
SEGMENTS      SHAREDATA CLASS 'SHARECLASS' SHARED
//--------------------------------------------------------------

This .DLL is used only by one .EXE at a time. After sharing hhook and some other variables I couldn't resolve anything. You see: I write the line MessageBox(..) immediately after HookProc recieves WM_CHAR but the message box is showed only when the main window of my .EXE (that uses DLL) yields focus. It's likely not a system-wide hook manner but thread hook although the last parameter of SetWIndowsHookEx is NULL.

Ok, I'll try more research...

0
 

Author Comment

by:toannds
ID: 1417852
Alexo,

Thank you very much. I change to VC++ 5 and work well. However I need to change your code. I couldn't understand why I need to export functions & definition of share data section in .DEF, otherwise (use dllexport at function prototype) my hook function didn't work! Do you have any idea?
I want to give you points, please post your answer instead of comment :-) ...

0
 
LVL 11

Accepted Solution

by:
alexo earned 10 total points
ID: 1417853
>> Do you have any idea?
Possibly C++ name mangling.  Did you try declaring the funcs as extern "C"?
0
 

Author Comment

by:toannds
ID: 1417854
Alexo, you're right! Now my DLL catch any WM_CHAR.
I want to ask you more :-)

I declare a variable of MSG type in shared section and export it in EXPORTS section of .DEF of my .DLL. Every time when my hook function receives a message it copies message to this shared variable and informs my .EXE by SendMessage(). My .EXE receive message and check the share variable. However my .EXE always receives correct wParam, lParam but not *(MSG far *)lParam.




0
 

Author Comment

by:toannds
ID: 1417855
Alexo, you're right! Now my DLL catch any WM_CHAR.
I want to ask you more :-)

I declare a variable of MSG type in shared section and export it in EXPORTS section of .DEF of my .DLL. Every time when my hook function receives a message it copies message to this shared variable and informs my .EXE by SendMessage(). My .EXE receive message and check the share variable. However my .EXE always receives correct wParam, lParam but not *(MSG far *)lParam.




0
 
LVL 11

Expert Comment

by:alexo
ID: 1417856
>> my .EXE always receives correct wParam, lParam but not *(MSG far *)lParam.
Huh???
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now