Solved

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

Posted on 1998-12-29
16
308 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

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
 

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

Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

Question has a verified solution.

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

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
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…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

627 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