TIA,
Mark
var
MHook: HHOOK;
BtnHnd : hwnd;
fBuf : array[0..255] of char;
CB : TCallback;
function MyMouseHook(nCode: Integer; wParam: longint; lParam : longint):
longint; stdcall;
begin
Result := CallNextHookEx(MHook, nCode, wParam, lparam);
if (nCode = HC_ACTION) then
with PMouseHookStruct(lParam)^ do
begin
if hwnd = btnHnd then
begin
CodeSite.SendMsg('Mouse');
end;
end;
end;
procedure InstallHook(const aHandle : hwnd); stdcall;
var
thd : dword;
begin
btnHnd := aHandle;
GetWindowText(aHandle, fBuf, sizeof(fBuf));
thd := GetWindowThreadProcessId(aHandle, nil);
CodeSite.SendFmtMsg('%s - %d', [fBuf, thd]);
MHook :=
SetWindowsHookEx(WH_MOUSE, @MyMouseHook, hInstance, thd);
end;
Russ
Mark Erbaugh <ma...@nospam.microenh.com> wrote in message
news:8uot53$e1...@bornews.inprise.com...
By passing "thd" you are telling windows that the hook is only valid for that
process, ie it is in the context of that thread, , which is not even yours! It
no wonder it is choking. For a global hook you have to pass 0 to tell windows
to hook all threads and put your callback procedure in the chain.
Also save youself a lot of grief and put
initialialization
DisableThreadLibraryCalls;
in any dll that will be used in any thread but your own.
Jim
I'm not sure I understand global hooks. I don't want to get mouse messages
going to every app in the system, just messages going to a particular window
in a particular app. Is this not possible? If not, I guess I can filter them
in my event handler.
Thanks for the tip on DisableThreadLibraryCalls. I hadn't seen that before.
Mark
"Jim Kueneman" <ji...@azstarnet00.com> wrote in message
news:3A104186...@azstarnet00.com...
Mark Erbaugh wrote:
> Jim,
>
> I'm not sure I understand global hooks. I don't want to get mouse messages
> going to every app in the system, just messages going to a particular window
> in a particular app. Is this not possible? If not, I guess I can filter them
> in my event handler.
You may try what Russell Holcomb suggested, memory mapped files. That way the
memory is shared between apps. I have never tried to pass a handle to a window
that my process did not own in a hook.
>
> Thanks for the tip on DisableThreadLibraryCalls. I hadn't seen that before.
>
This was "discovered" several months ago here on this list by a few who where
have a hard time keeping global CBT hooks from crashing in a networking
enviroment (dialup as well). Actually it was Russell Holcomb who started it all
if I remember right.
Jim Kueneman
Thanks,
Mark
"Russell E. Holcomb" <reho...@earthlink.net> wrote in message
news:3a103df1$1_1@dnews...
Mark Erbaugh wrote:
> Can you give me more information on memory mapped files? I'm not sure what
> you mean. Are they documented in the Delphi or Windows help files? Can you
> point me to some sample code?
>
Memory Mapped Files are the windows way for apps to share memory. You look
them like files. You create them, CreateFileMapping, then open them to map the
memory to your threads memory space to read the information, MapViewOfFile,
then close close it UnMapViewOfFile(Shared). These are all API calls.
What you have to remember is the dll is loaded into the memory address space of
the thread who owns the window you passed in the SetWindowsHook call. Although
you wrote that block of code it is the other program that will be executing it
so it only can access memory in its address space, which is why you are having
problems. By using a memory mapped file you can allow the other program to
store information in the memory mapped file then within a function in your
program open this file and read the contents to pass the infomation across
programs. The question is how to let you program know when hooked program has
put new information in the mapped file. One way is to possibly create a mapped
file with the handle of the of the window you use to show the results then in
the hook procedure open this file and send that window a user defined message
to signal it. It may be possible to us an Event or Mutex that is signaled when
the mapped file changes. In you program have a thread with a thread loop that
uses WaitForSingleObject to listen for the mapped file to change. These are
just a few thoughts that came to mind.
I uploaded the example going around when trying to solve the global hook
crashing problem, which I mentioned elsewhere, to the
borland.public.attachments group. It uses memory mapped files. I would like to
give credit to the individual who supplied this but his name escapes me, Paul
?????.
Jim
Apparently Borland knows about this too since it appears in the hook
demo. I've never been able to find it documented anywhere, however,
despite spending some time searching Borland and MSDN.
From what I found on MSDN, it does seem that the notifications are
usually unnecessary and add significant overhead to the hook anyway,
which would seem to indicate that turning them off is a good idea for
global hooks even if there wasn't a stability issue.
FWIW,
-Craig
--
Craig Stuntz Vertex Systems Corporation
Senior Developer http://www.vertexsoftware.com
Delphi/InterBase weblog: http://delphi.weblogs.com
If the data that needs to be passed from the hooked app to the other app is
small, can it just be passed as the lparam and wparam members of an event
record without the need for a memory mapped file? In my case, all I need to
know is that the user clicked on a button in the hooked app. A simple
integer could tell me which button.
Thanks for the explanation and the upload. I've got it and will take a look.
Mark
"Jim Kueneman" <ji...@azstarnet00.com> wrote in message
news:3A114040...@azstarnet00.com...
>
>
> Mark Erbaugh wrote:
>
> > Can you give me more information on memory mapped files? I'm not sure
what
> > you mean. Are they documented in the Delphi or Windows help files? Can
you
> > point me to some sample code?
> >
>
Mark Erbaugh wrote:
> If the data that needs to be passed from the hooked app to the other app is
> small, can it just be passed as the lparam and wparam members of an event
> record without the need for a memory mapped file? In my case, all I need to
> know is that the user clicked on a button in the hooked app. A simple
> integer could tell me which button.
>
That may work. Give it a try.
Jim
Windows has a message for this sole purpose: WM_COPYDATA.
HTH,