Solved

when I lose the focus

Posted on 1998-03-17
26
380 Views
Last Modified: 2008-02-01
I have an small aplication in Visual Basic that shows a window. This window is set to hide (or invisible) when a concrete key is pressed. Then, when another key is pressed, this window appears again. This program runs well while it has the focus. But if any user press ALT+TAB, or run another program, I lose the focus, and my program not catch the keyboard events. How can I catch the keys pressed if another program is taking now the processor? Thanks.
0
Comment
Question by:ciri
  • 13
  • 10
  • 3
26 Comments
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
You can set a keyboard hook (WH_KEYBOARD) using SetWindowsHookEx. This can be done only in VB5, because it req. a callback function:

Dim hHook as long
'Set
hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KbdProc, vbNull, 0)

Function KbdProc(code as long ,lParam as long, wParam as long) as long
'Proccess the keyboard message
end function

'Unhook
UnHookWindowsHookEx(hHook)

-----------------------------------------------------------------
Here is the referense on SetWindowsHookEx and KbdProc
-----------------------------------------------------------------
 
The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. An application installs a hook procedure to monitor the system for certain types of events. A hook procedure can monitor events associated either with a specific thread or with all threads in the system. This function supersedes the SetWindowsHook function.
HHOOK SetWindowsHookEx(
 

    int idHook,      // type of hook to install
    HOOKPROC lpfn,      // address of hook procedure
    HINSTANCE hMod,      // handle of application instance
    DWORD dwThreadId       // identity of thread to install hook for
   );      
Parameters
idHook
Specifies the type of hook procedure to be installed. This parameter can be one of the following values:
 
Value      Description

WH_CALLWNDPROC      Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more information,  the CallWndProc hook procedure.
WH_CALLWNDPROCRET      Windows 95 only: Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more information, see  the CallWndRetProc hook procedure.
WH_CBT      Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the CBTProc hook procedure.
WH_DEBUG      Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
WH_GETMESSAGE      Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
WH_JOURNALPLAYBACK      Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the JournalPlaybackProc hook procedure.
WH_JOURNALRECORD      Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the JournalRecordProc hook procedure.
WH_KEYBOARD      Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
WH_MOUSE      Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
WH_MSGFILTER      Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. For more information, see  the MessageProc hook procedure.
WH_SHELL      Installs a hook procedure that receives notifications useful to shell applications. For more information, see  the ShellProc hook procedure.
WH_SYSMSGFILTER      Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see  the SysMsgProc hook procedure.
lpfn
Points to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
hMod
Identifies the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads.
Return Values
If the function succeeds, the return value is the handle of the hook procedure.
If the function fails, the return value is NULL.
Remarks
An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process.
Chaining to the next hook procedure (that is, calling the CallNextHookEx function) is optional. An application or library can call the next hook procedure either before or after any processing in its own hook procedure.
Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.
The scope of a hook depends on the hook type. Some hooks can be set only with system scope; others can also be set for only a specific thread, as shown in the following list:
 
Hook      Scope

WH_CALLWNDPROC      Thread or system
WH_CBT      Thread or system
WH_DEBUG      Thread or system
WH_GETMESSAGE      Thread or system
WH_JOURNALPLAYBACK      System only
WH_JOURNALRECORD      System only
WH_KEYBOARD      Thread or system
WH_MOUSE      Thread or system
WH_MSGFILTER      Thread or system
WH_SHELL      Thread or system
WH_SYSMSGFILTER      System only
For a specified hook type, thread hooks are called first, then system hooks.
The system hooks are a shared resource, and installing one affects all applications. All system hook functions must be in libraries. System hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove the hook procedure.
See Also
CallNextHookEx, CallWndProc, CBTProc, DebugProc, GetMsgProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, MouseProc, MessageProc, ShellProc, SysMsgProc, UnhookWindowsHookEx

 
 
The KeyboardProc hook procedure is an application-defined or library-defined callback function the system calls whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.
LRESULT CALLBACK KeyboardProc(
 

    int code,      // hook code
    WPARAM wParam,      // virtual-key code
    LPARAM lParam       // keystroke-message information
   );      
Parameters
code
Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
 
Value      Meaning

HC_ACTION      The wParam and lParam parameters contain information about a keystroke message.
HC_NOREMOVE      The wParam and lParam parameters contain information about a keystroke message, and the keystroke message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Specifies the virtual-key code of the key that generated the keystroke message.
lParam
Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. This parameter can be a combination of the following values:
 
Value      Description

0-15      Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16-23      Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24      Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25-28      Reserved.
29      Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.
30      Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31      Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.
For more information about the lParam parameter, see Keystroke Message Flags.
Return Values
To prevent Windows from passing the message to the rest of the hook chain or to the target window procedure, the return value must be a nonzero value. To allow Windows to pass the message to the target window procedure, bypassing the remaining procedures in the chain, the return value must be zero.
Remarks
An application installs the hook procedure by specifying the WH_KEYBOARD hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.
KeyboardProc is a placeholder for the application-defined or library-defined function name.
See Also
CallNextHookEx, GetMessage, PeekMessage, SetWindowsHookEx, WM_KEYUP, WM_KEYDOWN

 

0
 
LVL 8

Accepted Solution

by:
MikeP090797 earned 90 total points
Comment Utility
Oops, I actualy mean posting it as an answer
0
 

Author Comment

by:ciri
Comment Utility
I push the line
      hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KbdProc, vbNull, 0)
when my main form loads, and when I tried to run the program, the following error ocurred
WH_KEYBOARD : variable not defined. I supose that I must load a library, perhaps using the option references in the menu project. What do you think about this error?

Ahh!!. Another questions... . When can I call the function KbdProc??. Is in this function when I study the key pressed??.

I think a small example could explain me this doubts...
Thanks.
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
Public Const WH_KEYBOARD = 2

KbdProc is called by windows each time when a key is pressed, no matter what window is active

0
 
LVL 2

Expert Comment

by:marti
Comment Utility
The topic has already been discussed, unfortunately without success in:
http://www.experts-exchange.com/topics/comp/lang/visualbasic/Q.10039526
0
 

Author Comment

by:ciri
Comment Utility
Now the error is the following:
   
        SetWindowsHookEx: Sub or Function not defined
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
You have to get all the declares from Api text viewer, but anyway:

Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Public Const WH_KEYBOARD = 2

0
 

Author Comment

by:ciri
Comment Utility
You tell me that the KbdProc function is called by Window when a key is pressed. Then, I supose that I only re-define this function, for example like a module, like this

Function KbdProc(code As Long, lParam As Long, wParam As Long) As Long
   
   If (Chr(code) = "i") Then
    Form1.Visible = False
  End If
  If (Chr(code) = "v") Then
    Form1.Visible = True
  End If
     'Proccess the keyboard message
End Function

Then, when a key was pressed, this code will be run.
But don't occurs nothing!!
What's the problem?? (I recognize that my Visual Basic is poor)

Or maybe I must have something different (like call the KbdProc in another procedure,...)

Or maybe this function shoudn't be re-defined??

Where can I push the code

   If (Chr(code) = "i") Then
    Form1.Visible = False
  End If
  If (Chr(code) = "v") Then
    Form1.Visible = True
  End If

0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
You put that code in the KbdProc, but you must call SetWindowsHookEx on startup
0
 

Author Comment

by:ciri
Comment Utility
Yes, I put the code
     hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, vbNull, 0)

in the procedure Form_Load() and I put the KbdProc function in a module (global.bas). But the aplicattion runs like the code didn't exist. Simply, I think that the KbdProc function isn't called  (I don't know why)
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
Place msgbox in KbdProc to make sure if it's called or not.
And it supposed to be AddressOf KbdProc (The same name as your function)
0
 

Author Comment

by:ciri
Comment Utility
I placed a MsgBox in KbdProc function, but didn't show it when I pressed a key.
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
that's strange. try app.ThreadID as third atg in SetWindowsHookEx.
Where do you call UnhookWindowsHookEx?
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:ciri
Comment Utility
Well, I tried with app.ThreadID, like you said me. I set a MesgBox in the KbdProc function, and when I pressed a letter, I saw the MesgBox in three times.

About the UnhookWindowsHookEx function, I call it just before the program finish (when a button is pressed). But I never can see this function, becouse it isn't stay in the user32 library. Can you say me in which library (DLL) this function is?
0
 

Author Comment

by:ciri
Comment Utility
Well, I tried with app.ThreadID, like you said me. I set a MesgBox in the KbdProc function, and when I pressed a letter, I saw the MesgBox in three times.

About the UnhookWindowsHookEx function, I call it just before the program finish (when a button is pressed). But I never can see this function, becouse it isn't stay in the user32 library (like I thougth). Can you say me in which library (DLL) this function is?
0
 

Author Comment

by:ciri
Comment Utility
If I press a key when another program is taking the processor, occurs a Windows error, and this program is closed (the mesagebox isn't displayed)
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
Declare Function UnhookWindowsHookEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal hHook As Long) As Long

0
 

Author Comment

by:ciri
Comment Utility
MikeP, the UnhookWindowsHookEx function runs O.K.
Like I told you, I see the messagebox three times (only when my aplication is active). When another aplication is active, a Windows error occurs if I press a key.
0
 
LVL 2

Expert Comment

by:marti
Comment Utility
So why you have accepted the answer if it's not working?
0
 

Author Comment

by:ciri
Comment Utility
Well, the answer isn't good. So, I'll reopen the question to another experts. On the other hand, this question don't worry me now. But, if i know the answer, I'll be happy.
0
 

Author Comment

by:ciri
Comment Utility
I can't reopen the question (i think). MikeP's answer appears like "Accepted answer". I don't understand it. I don't remember to accept this answer. I usually adds a comment like "good answer" when I accept an answer. Maybe the answer had been accepted becouse I hadn't reopen the question in 3 or 4 weeks (and I hadn't adds a comment). What can I do??
0
 
LVL 2

Expert Comment

by:marti
Comment Utility
You could ask the webmaster.
0
 

Author Comment

by:ciri
Comment Utility
How can I ask this doubt the webmaster??
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
Send me your project to michaelp@gezernet.co.ilm I'll try to figure it out, but it won't be ready til sunday, cause I won't be at home till then
0
 

Author Comment

by:ciri
Comment Utility
MikeP, I tried to send you an e-mail,but an error occurs: unknown host or domain
0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
michaelp@gezernet.co.il
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

762 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now