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
Solved

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

Posted on 1998-12-29
16
305 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
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 

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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

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…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
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…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

829 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