 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Vladimir Stefanovic Guest
|
Posted: Tue May 03, 2005 9:48 am Post subject: [Remy] SendMessage() from a DLL to APP |
|
|
Hi Remy,
I wanted to avoid getting HWND of some APP from my DLL
by FindWindow() because of some problems I reported before.
Then you suggested me to pass the APP HWND to a DLL directly,
and so avoid determining the APP HWND all the time by
FindWindow().
You also suggested me to store the HWND in the shared memory
because that every DLL instance can have a valid HWND, but in my
case the APP can have in fact only *one* instance, so I suppose that
is not necessary.
That concept works *almost* fine for me, but... The funy thing
is that if my APP is in tray - nothing happens, ie. my APP
KeyHook() function that should be triggered by DLL's:
// Send key information to the main window
SendMessage( hAppWnd, WM_KEYHOOK, 0, lParam );
.... simply is not executed. I placed a fake ShowMessage("?"),
but it's not reached if the APP is in tray.
If the app is on screen, it is triggered.
Whay I'm missing? Is there anything I can do to avoid FindWindow()
which indeed works if the APP is in tray?
--- DLL ---
// ...
HWND hAppWnd;
// ...
void __stdcall SetHook( HWND hWnd )
{
ghhookKB = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)CheckKey, ghInst,
NULL );
hAppWnd = hWnd;
}
// ...
DWORD __stdcall CheckKey( int nCode, WORD wParam, LONG lParam )
{
if ( ( nCode < 0 ) || ( nCode == HC_NOREMOVE ) )
return CallNextHookEx( ghhookKB, nCode, wParam, lParam );
// Skip if it's a repeat
if ( lParam & 0x40000000 )
return CallNextHookEx( ghhookKB, nCode, wParam, lParam );
// Check if Alt is pressed
if ( !( lParam & ( 1<<29 ) ) )
return CallNextHookEx( ghhookKB, nCode, wParam, lParam );
// Send key information to the main window
SendMessage( hAppWnd, WM_KEYHOOK, 0, lParam );
return CallNextHookEx( ghhookKB, nCode, wParam, lParam );
}
/************************************************************/
--
Best regards,
Vladimir Stefanovic
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Tue May 03, 2005 6:26 pm Post subject: Re: [Remy] SendMessage() from a DLL to APP |
|
|
"Vladimir Stefanovic" <antivari (AT) po (DOT) sbb.co.yu> wrote
You should always initialize your variables, especially when used globally:
HWND hAppWnd = NULL;;
| Quote: | ghhookKB = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)CheckKey, ghInst,
NULL) |
You did not specify whether the HHOOK was in shared memory or not. It must
be. Otherwise, the hook will only work in your own application and not in
others. When you place your icon in the System Tray and hide your window,
your window won't be focused anymore, and won't be the window receiving
keyboard input. If you do not set up your hook properly to begin with, then
you will not be hooking the keyboard input of other applications properly.
| Quote: | // Send key information to the main window
SendMessage( hAppWnd, WM_KEYHOOK, 0, lParam );
|
Check the HWND for NULL before calling SendMessage():
if( hAppWnd )
SendMessage( hAppWnd, WM_KEYHOOK, 0, lParam );
Gambit
|
|
| Back to top |
|
 |
Vladimir Stefanovic Guest
|
Posted: Wed May 04, 2005 11:37 am Post subject: Re: [Remy] SendMessage() from a DLL to APP |
|
|
Hi Remy,
Following your instructions I completely redesigned my DLL, and
now I have placed HWND in the shared memory, at least I think I did.
The code now works as I expect, and so far I haven't noticed crashes
of other VCL programs on their termination like it was the case when
I used FindWindow (from a DLL) to get the App HWND.
Anyway, can you please take a short look at the code and see if
I should make any (maybe code security) corrections to it.
Also, I have few questions:
1) Is there any sigifficant difference if I use SendMessage() or
PostMessage() from my DLL, in my case?
2) In the API CreateFileMapping(), I named a last argument "DiHook",
and I never used it after that. Is that OK? Should I use NULL?
3) Is that normal that I haven't any chages (because of shared memory
changes in y DLL) at my App side, except that I passed the HWND
argument to install a DLL?
--- DLL CODE ---
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#define WM_KEYHOOK (WM_USER + 1002)
HINSTANCE ghInst;
typedef struct _HookInfo
{
HHOOK ghhookKB;
HWND hAppWnd;
} HOOKINFO, *PHOOKINFO;
HANDLE hFileMapping = NULL;
PHOOKINFO pHookInfo = NULL;
#pragma argsused
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) __stdcall void SetHook(HWND);
extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
extern "C" __declspec(dllexport) __stdcall DWORD CheckKey(int, WORD,LONG);
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void
*lpReserved)
{
ghInst = hinst;
switch ( reason )
{
case DLL_PROCESS_ATTACH:
hFileMapping = CreateFileMapping( INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof(HOOKINFO),
"DiHook" );
if ( hFileMapping )
pHookInfo = (PHOOKINFO)MapViewOfFile( hFileMapping,
FILE_MAP_WRITE,
0,
0,
0 );
break;
case DLL_PROCESS_DETACH:
UnmapViewOfFile( pHookInfo );
pHookInfo = NULL;
CloseHandle( hFileMapping );
hFileMapping = NULL;
break;
}
return ( 1 );
}
void __stdcall SetHook( HWND hWnd )
{
if ( pHookInfo )
{
if( pHookInfo->ghhookKB == NULL )
pHookInfo->ghhookKB = SetWindowsHookEx( WH_KEYBOARD,
(HOOKPROC)CheckKey, ghInst, NULL );
pHookInfo->hAppWnd = hWnd;
}
}
void __stdcall RemoveHook( void )
{
if ( pHookInfo )
{
if ( pHookInfo->ghhookKB )
{
UnhookWindowsHookEx( pHookInfo->ghhookKB );
pHookInfo->ghhookKB = NULL;
}
}
}
DWORD __stdcall CheckKey( int nCode, WORD wParam, LONG lParam )
{
if ( ( nCode < 0 ) || ( nCode == HC_NOREMOVE ) )
return CallNextHookEx( pHookInfo->ghhookKB, nCode, wParam, lParam );
// Skip if it's a repeat
if ( lParam & 0x40000000 )
return CallNextHookEx( pHookInfo->ghhookKB, nCode, wParam, lParam );
// Check if Alt is pressed
if ( !( lParam & ( 1<<29 ) ) )
return CallNextHookEx( pHookInfo->ghhookKB, nCode, wParam, lParam );
// Send key information to the main window
if ( pHookInfo && pHookInfo->hAppWnd )
PostMessage( pHookInfo->hAppWnd, WM_KEYHOOK, 0, lParam );
return CallNextHookEx( pHookInfo->ghhookKB, nCode, wParam, lParam );
}
--
Best regards,
Vladimir Stefanovic
"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote
| Quote: |
"Vladimir Stefanovic" <antivari (AT) po (DOT) sbb.co.yu> wrote in message
news:427748eb (AT) newsgroups (DOT) borland.com...
HWND hAppWnd;
You should always initialize your variables, especially when used
globally:
HWND hAppWnd = NULL;;
ghhookKB = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)CheckKey, ghInst,
NULL)
You did not specify whether the HHOOK was in shared memory or not. It
must
be. Otherwise, the hook will only work in your own application and not in
others. When you place your icon in the System Tray and hide your window,
your window won't be focused anymore, and won't be the window receiving
keyboard input. If you do not set up your hook properly to begin with,
then
you will not be hooking the keyboard input of other applications properly.
// Send key information to the main window
SendMessage( hAppWnd, WM_KEYHOOK, 0, lParam );
Check the HWND for NULL before calling SendMessage():
if( hAppWnd )
SendMessage( hAppWnd, WM_KEYHOOK, 0, lParam );
Gambit
|
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Wed May 04, 2005 6:26 pm Post subject: Re: [Remy] SendMessage() from a DLL to APP |
|
|
"Vladimir Stefanovic" <antivari (AT) po (DOT) sbb.co.yu> wrote
| Quote: | Anyway, can you please take a short look at the code and see if
I should make any (maybe code security) corrections to it.
1) Is there any sigifficant difference if I use SendMessage() or
PostMessage() from my DLL, in my case?
|
That entirely depends on your actual needs. SendMessage() waits for the
message to be processed. PostMessage() does not.
| Quote: | 2) In the API CreateFileMapping(), I named a last argument
"DiHook", and I never used it after that. Is that OK? Should I use
NULL?
|
No, do not use NULL, or else the memory won't be shared at all. The name is
what makes it sharable to begin with.
| Quote: | 3) Is that normal that I haven't any chages (because of shared memory
changes in y DLL) at my App side, except that I passed the HWND
argument to install a DLL?
|
| Quote: | extern "C" __declspec(dllexport) __stdcall void SetHook(HWND);
extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
|
I would recommend adding return values to those functions so that the
application can know whether or not the hooking/unhooking actuall succeeds.
| Quote: | if ( hFileMapping )
pHookInfo = (PHOOKINFO)MapViewOfFile( hFileMapping,
FILE_MAP_WRITE,
0,
0,
0 );
|
If either CreateFileMapping() or MapViewOfFile() fail, I prefer to release
the file mapping and make DllEntryPoint() return FALSE. That way, the
application knows that the DLL was unable to initialize itself, and thus the
hooks won't work properly.
| Quote: | UnmapViewOfFile( pHookInfo );
pHookInfo = NULL;
CloseHandle( hFileMapping );
hFileMapping = NULL;
break;
|
Make sure to check for NULL pointers before calling the functions:
if( pHookInfo )
UnmapViewOfFile( pHookInfo );
if( hFileMapping )
CloseHandle( hFileMapping );
| Quote: | DWORD __stdcall CheckKey( int nCode, WORD wParam, LONG lParam )
|
You can simplify that code to the following:
DWORD __stdcall CheckKey( int nCode, WORD wParam, LONG lParam )
{
if( pHookInfo )
{
if( ((nCode >= 0) && (nCode != HC_NOREMOVE))
&& ((lParam & 0x40000000) == 0) // Skip if it's a repeat
&& (lParam & 0x20000000) ) // Check if Alt is pressed
{
// Send key information to the main window
if( pHookInfo->hAppWnd )
PostMessage(pHookInfo->hAppWnd, WM_KEYHOOK, 0, lParam);
}
return CallNextHookEx(pHookInfo->ghhookKB, nCode, wParam,
lParam);
}
return 0;
}
Gambit
|
|
| Back to top |
|
 |
Vladimir Stefanovic Guest
|
Posted: Wed May 04, 2005 6:59 pm Post subject: Re: [Remy] SendMessage() from a DLL to APP |
|
|
Thanks,
I'll implement all that tomorrow...
--
Best regards,
Vladimir Stefanovic
"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote
| Quote: |
"Vladimir Stefanovic" <antivari (AT) po (DOT) sbb.co.yu> wrote in message
news:4278b3f0 (AT) newsgroups (DOT) borland.com...
Anyway, can you please take a short look at the code and see if
I should make any (maybe code security) corrections to it.
1) Is there any sigifficant difference if I use SendMessage() or
PostMessage() from my DLL, in my case?
That entirely depends on your actual needs. SendMessage() waits for the
message to be processed. PostMessage() does not.
2) In the API CreateFileMapping(), I named a last argument
"DiHook", and I never used it after that. Is that OK? Should I use
NULL?
No, do not use NULL, or else the memory won't be shared at all. The name
is
what makes it sharable to begin with.
3) Is that normal that I haven't any chages (because of shared memory
changes in y DLL) at my App side, except that I passed the HWND
argument to install a DLL?
extern "C" __declspec(dllexport) __stdcall void SetHook(HWND);
extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
I would recommend adding return values to those functions so that the
application can know whether or not the hooking/unhooking actuall
succeeds.
if ( hFileMapping )
pHookInfo = (PHOOKINFO)MapViewOfFile( hFileMapping,
FILE_MAP_WRITE,
0,
0,
0 );
If either CreateFileMapping() or MapViewOfFile() fail, I prefer to release
the file mapping and make DllEntryPoint() return FALSE. That way, the
application knows that the DLL was unable to initialize itself, and thus
the
hooks won't work properly.
UnmapViewOfFile( pHookInfo );
pHookInfo = NULL;
CloseHandle( hFileMapping );
hFileMapping = NULL;
break;
Make sure to check for NULL pointers before calling the functions:
if( pHookInfo )
UnmapViewOfFile( pHookInfo );
if( hFileMapping )
CloseHandle( hFileMapping );
DWORD __stdcall CheckKey( int nCode, WORD wParam, LONG lParam )
You can simplify that code to the following:
DWORD __stdcall CheckKey( int nCode, WORD wParam, LONG lParam )
{
if( pHookInfo )
{
if( ((nCode >= 0) && (nCode != HC_NOREMOVE))
&& ((lParam & 0x40000000) == 0) // Skip if it's a repeat
&& (lParam & 0x20000000) ) // Check if Alt is pressed
{
// Send key information to the main window
if( pHookInfo->hAppWnd )
PostMessage(pHookInfo->hAppWnd, WM_KEYHOOK, 0, lParam);
}
return CallNextHookEx(pHookInfo->ghhookKB, nCode, wParam,
lParam);
}
return 0;
}
Gambit
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|