?
Solved

WH_JOURNALRECORD Hook callback before take action

Posted on 2003-03-14
20
Medium Priority
?
1,037 Views
Last Modified: 2007-12-19
It look like that WH_JOURNALRECORD Hook callback before keyboard or mouse
take action.

Ex.1
I couldn't get the correct character index in edit control.
When typing "abcde", at 5th callback loop the EM_LINELENGTH = 4
and "e" will display in edit control after exit the callback function.

Ex.2
When playing with Tmemo, I click mouse at some line.
The callback processing when I click mouse but before
the mouse take action into Tmemo. So I couldn't get any
info in Tmemo at that loop.

Do u have any Idea ?
I would like it callback after keyboard or mouse take action.

0
Comment
Question by:tong111797
[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
  • 11
  • 6
  • 2
  • +1
20 Comments
 
LVL 34

Expert Comment

by:Slick812
ID: 8137819
hello tong, I've used the WH_JOURNALRECORD hook alot, , , and I don't remember that it gets the mouse and keyboard events, , before the focused control??, but that never seemed to matter,
I could get the mouse and keyboard events just fine, and record them or do something if certian keys were pressed or mouse click. . . . . . . You can see some code for a Journal Hook at -


http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20330305.html

I can not understand what you are talking about in -

"The callback processing when I click mouse but before
the mouse take action into Tmemo. So I couldn't get any
info in Tmemo at that loop."

maybe if you show some code?
0
 

Author Comment

by:tong111797
ID: 8138290
Yes, it does work but it callback before keyboard or mouse
take action.

When you press keyboard "A" in notepad, the callback goto your function JHookFunc() until you exit function then
OS print "A" in notepad.

Well, now your press "Hello", you can get only "Hell" from
notepad while function running "o" loop.

So in JHookFunc() we can't get a valid information from any windows handle.

I tried to get cursor position in any Edit Control but fail especially multiline Edit Control.

Sorry for my poor english.


 
0
 

Author Comment

by:tong111797
ID: 8138474
When you click mouse in some Edit Control, example
in the middle of word "http://www.experts-exchange.com"
the caret still doesn't goes into word but now it callback to JHookFunc()

It look like callback to JHookFunc()
before the OS do the real job.

From MSDN about WH_JOURNALRECORD Hook
--
The JournalRecordProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The function records messages the system removes from the system message queue.
--

Are these the steps of OS ?
1. add message to system queue.
2. process queue one by one in order.
3. Remove from message queue.
4. callback to function JHookFunc()
5. take real action
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:tong111797
ID: 8138529
Some note for you.
These two codes prevent the application freeze.

HC_SYSMODALOFF
A system-modal dialog box has been destroyed. The hook procedure must resume recording.

HC_SYSMODALON
A system-modal dialog box is being displayed. Until the dialog box is destroyed, the hook procedure must stop recording.

...
...
Var
  SysModalOn : bool = False;
...
...
...
function JHookFunc( Code: integer; wParam: Longint; var lParam: TEVENTMSG):LRESULT; stdcall;
begin
  Result := CallNextHookEx(JHook, Code, wParam, Integer(@lParam));

  if ( Code = HC_SYSMODALON ) then
  begin
     SysModalOn := True;
     exit;
  end;

  if ( Code = HC_SYSMODALOFF ) then
  begin
     SysModalOn := False;
     exit;
  end;

  if ( Code <> HC_ACTION ) or SysModalOn then
  begin
     exit;
  end;

  ...
  ...

end;
0
 

Author Comment

by:tong111797
ID: 8138728
1.keyboard
2.scancode
3.keyboard device driver
4.message
5.system message queue
6.message   <---JOURNALRECORD callback here!
7.thread message queue
8.thread message loop
9.windows procedure  <---take action in notepad

0
 
LVL 17

Expert Comment

by:geobul
ID: 8140329
Hi tong,

Yes, that's right. WH_JOURNALRECORD type hook works that way. Its purpose is to record keyboard and mouse messages as they come.

Perhaps you need WH_CALLWNDPROCRET type hook which gets called after the receiving window has processed the message.

Regards, Geo
0
 
LVL 34

Expert Comment

by:Slick812
ID: 8141375
I begin to see what you mean, I can suggest that you might try what I call a "Hop Out" windows message (using a WM_USER message), in your JHookFunc use a PostMessage to your own app so the JHookFunc can return and the HopOut procedure will be executed and you can do any messages to the External edit


procedure HopOut(var Msg: TMessage); message WM_TIMER{WM_USER + 324};


procedure TForm1.HopOut(var Msg: TMessage);
begin
// you might use the Lparam and Wparam for Char or Pos
CharPos := SendMessage(EditHandle, EM_CHARFROMPOS,0, Pos);
end;


unction JHookFunc( Code: integer; wParam: Longint; var lParam: TEVENTMSG):LRESULT; stdcall;
begin
 Result := CallNextHookEx(JHook, Code, wParam, Integer(@lParam));
// some JHook code

if EventStrut.message = WM_KEYDOWN then
  begin
  // do recording code here
  PostMessage(Handle, WM_USER + 324, 0, SomeValue);
//use a Sendmessage to Hop Out of this function and start
// the HopOut procedure
  end;
end;
0
 

Author Comment

by:tong111797
ID: 8142181
Very thanks you all.

geobul,
I forgot to read about WH_CALLWNDPROCRET at MSDN.
By the way WH_CALLWNDPROCRET require library-defined
for system-wide hook. It is very good.


Slick812,
You code work well.
procedure HopOut(var Msg: TMessage); message WM_USER + $324;

procedure TForm1.HopOut(var Msg: TMessage);
begin
//
end;


function JHookFunc(Code: integer; wParam: Longint; var lParam: TEVENTMSG):LRESULT; stdcall;
begin
  Result := CallNextHookEx(JHook, Code, wParam, Integer(@lParam));
  PostMessage(Form1.Handle, WM_USER + $324, wParam, integer(@lParam));
end;
0
 
LVL 17

Expert Comment

by:geobul
ID: 8142243
Hi,

Slick, I don't think that it's absolutely guaranteed that the VM_USER message will be processed by the recording app after the hooked message has been processed, if the hooked message is addressed to another app's window. I may be wrong, of course. I don't have deep knowledge of Windows messaging system.

Regards, Geo
0
 

Author Comment

by:tong111797
ID: 8142426
Hello,

Yes geobul I mistook. It didn't work.
Maybe I have to use WH_CALLWNDPROCRET in the DLL to hook
system-wide.


0
 

Author Comment

by:tong111797
ID: 8142439
It look like WM_USER jump to "thread message queue".
So it is still faster.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 8146669
OK, I was trying to do this from memory, but my head is wack from code, :-)  
. . . . I left out the important Sleep(2);


procedure TForm1.HopOut(var Msg : TMessage);
var
Do3: Integer;
begin
Sleep(2);
{Sleep(1);
whenever you call sleep, the system will stop
processing in theis thread and allow the other threads
to have their proceesing time,}
Do3 := SendMessage(hEdit, EM_GETSEL, Start1, End1);
Form1.Label2.Caption := IntToStr(LOWORD(Do3));
end;


and if I remember right, I used the WH_CALLWNDPROCRET some and it will get the SendMessage( ) ,,, but I do not think the system uses any SendMessage for it's system messages, like WM_KEYDOWN  ??
0
 

Author Comment

by:tong111797
ID: 8151517
Yes, I tried hard for last 3 days. ;)

1. WH_CALLWNDPROCRET can't trap WM_KEYDOWN and WM_LBUTTONDOWN
2. So I tried WH_KEYBOARD and WH_MOUSE in the DLL for
system-wide hook. Archhhhhhh it can't GetFocus()
in my application when receive message from DLL.
3. Then I GetFocus() within the KeyboardProc function
and send message return value to my application.
The problem is GetFocus() don't work in the MouseProc function.
4. Well I trap WM_SETFOCUS in WH_CBT hook. And send
message return WHND value to my application.


Now I trap 3 hooks for my application.
WH_KEYBOARD for keydown
WH_MOUSE for mousedown
WH_CBT for getfocus ( WM_SETFOCUS )



0
 
LVL 34

Expert Comment

by:Slick812
ID: 8155761
if you are using the Computer Based Training Hook, WH_CBT, you probally do not need the WH_KEYBOARD or WH_MOUSE, since those messages are also handled by the WH_CBT hook. Did the Sleep(10) do anything to help? it seemed to work for me?
0
 

Author Comment

by:tong111797
ID: 8158322
I doesn't try sleep 10ms.
I afraid that it has side effect?
Make the system lag ?


How I find a list of messages that each hook type can trap?
I couldn't find in win32.hlp and in google.com

WH_CBT can trap message WM_KEYDOWN and WM_LMOUSEUP ?



0
 
LVL 34

Expert Comment

by:Slick812
ID: 8160080
what do you mean "Make the system lag". .  a Sleep(2);  will make your apps thread NOT get processor time for at least 2 milliseconds, but it does not effect the system and other threads should not be effected except to get a slot of processor time. . . .

and the WH_CBT hook can get the

HCBT_CLICKSKIPPED
for mousee clicks


HCBT_KEYSKIPPED
for Keyboard


you might look at the API Help for Index  "CBTProc"
0
 

Author Comment

by:tong111797
ID: 8274438
I would like to close and move to PAQ. ok ?

I still using these 3 hooks to get the Lparam and Wparam data.

WH_KEYBOARD for keydown
WH_MOUSE for mousedown
WH_CBT for getfocus ( WM_SETFOCUS )
0
 
LVL 34

Expert Comment

by:Slick812
ID: 8276141
Sure it's ok for me,
I guess you got it to work for you?
you might post your code here to help others
0
 

Author Comment

by:tong111797
ID: 8278898
The code just simple hook. I use WH_KEYBOARD, WH_MOUSE and WH_CBT instead of WH_JOURNALRECORD.

---
As MS said WH_JOURNALRECORD trap the msg while leave the system message queue.




0
 
LVL 6

Accepted Solution

by:
Mindphaser earned 0 total points
ID: 8306964
Points refunded and moved to PAQ

** Mindphaser - Community Support Moderator **
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses
Course of the Month10 days, 18 hours left to enroll

770 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