Results 1 to 35 of 35

Thread: detecting keystrokes even when minimized/hidden =(

  1. #1

    Thread Starter
    New Member
    Join Date
    Jul 2001
    Location
    Mayaguez, PR
    Posts
    7

    detecting keystrokes even when minimized/hidden =(

    I'm making a program that raises/lowers sound volume, but I can't manage to make it detect when I hold down the Ctrl+Alt+Up Arrow Key

    I need it to know when I press Cntrl+Alt+ArrowKeys even when the form is hidden or minimized as a system tray icon. Any ideas? I'm noy very good with API, but I guess that's where the solution's at.

    Any help will be greatly appreciated!
    (And please don't refer me to the keylogger example also in this forum, I'm looking for another possibility)

  2. #2
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    You need a system-wide hook. Search msdn.microsoft.com for "system hook" and see what turns up.
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  3. #3
    Megatron
    Guest
    Some people use GetAsyncKeyState(), but personally, I don't like it too much.

    Regarding the keyboard hook, you'll need to use C++ or Delphi to create it, because VB cannot create a standard DLL. You will, however, have to load the library and install the hook in VB. The only think that goes in the DLL is the hook procedure.

  4. #4
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    Megatron: can't you use AddressOf to do the hook callback in VB? I've read about doing that sort of thing...
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  5. #5
    Lively Member
    Join Date
    Aug 2001
    Posts
    109
    Originally posted by mlewis
    Megatron: can't you use AddressOf to do the hook callback in VB? I've read about doing that sort of thing...
    yes, you can do that.

    the easiest thing to do would be to use the getkeystate or getasynckeystate api's...

  6. #6
    Lively Member ice & fire's Avatar
    Join Date
    Oct 2001
    Location
    Land of ice & fire
    Posts
    110
    It works, yes!

  7. #7
    Megatron
    Guest
    Originally posted by mlewis
    Megatron: can't you use AddressOf to do the hook callback in VB? I've read about doing that sort of thing...
    No. AddressOf can only retrieve the address of a function within the current module. And even if it could get functions from a DLL, it still wont work, because in order for the DLL to be loaded in the address space of all processes, the procedure needs to be in a DLL.

    To retrieve the address of a procedure, use GetProcAddress

  8. #8
    Lively Member ice & fire's Avatar
    Join Date
    Oct 2001
    Location
    Land of ice & fire
    Posts
    110
    Sure, i meant that.
    I wanted to say, that it is possible to use a system wide keyboard hook with some DLL.
    They are precompiled on the web.

  9. #9
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    Urhm, Megatron, a callback is in the current module, by definition...
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  10. #10
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    Ok, it is possible. For testing purposes, lets move our form when the focus is on some other window.

    Module Code
    VB Code:
    1. Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
    2. Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    3. Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    4. Public 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
    5. Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
    6. Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
    7. Public Const HC_ACTION = 0
    8. Public Const WM_KEYDOWN = &H100
    9. Public Const WM_KEYUP = &H101
    10. Public Const WM_SYSKEYDOWN = &H104
    11. Public Const WM_SYSKEYUP = &H105
    12. Public Const VK_CONTROL = &H11
    13. Private Const VK_RSHIFT = &HA1
    14. Public Const VK_MENU = &H12
    15. Private Const VK_LEFT = &H25
    16. Private Const VK_RIGHT = &H27
    17. Public Const VK_UP = &H26
    18. Public Const VK_DOWN = &H28
    19. Public Const WH_KEYBOARD_LL = 13
    20. Public Const LLKHF_ALTDOWN = &H20
    21.  
    22.  
    23. Public Function KeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    24.     Dim intFFN As Integer
    25.    
    26.     If (nCode = HC_ACTION) Then
    27.         If wParam = WM_KEYDOWN Or wParam = WM_SYSKEYDOWN Then
    28.             If (GetKeyState(VK_CONTROL) And &H8000) <> 0 Then
    29.                 If (GetKeyState(VK_MENU) And &H8000) <> 0 Then
    30.                     If (GetKeyState(VK_UP) And &H8000) <> 0 Then
    31.                         With Form1
    32.                             .Move .Left, .Top - 100
    33.                         End With
    34.                     ElseIf (GetKeyState(VK_DOWN) And &H8000) <> 0 Then
    35.                         With Form1
    36.                             .Move .Left, .Top + 100
    37.                         End With
    38.                     ElseIf (GetKeyState(VK_LEFT) And &H8000) <> 0 Then
    39.                         With Form1
    40.                             .Move .Left - 100, .Top
    41.                         End With
    42.                     ElseIf (GetKeyState(VK_RIGHT) And &H8000) <> 0 Then
    43.                         With Form1
    44.                             .Move .Left + 100, .Top
    45.                         End With
    46.                     End If
    47.                 End If
    48.             End If
    49.         End If
    50.     End If
    51.     KeyboardProc = CallNextHookEx(0, nCode, wParam, ByVal lParam)
    52. End Function
    Form Code
    VB Code:
    1. Dim m_lngKeyboad As Long
    2.  
    3. Private Sub Form_Unload(Cancel As Integer)
    4.     If m_lngKeyboad <> 0 Then UnhookWindowsHookEx m_lngKeyboad
    5. End Sub
    6.  
    7. Private Sub Form_Load()
    8.     m_lngKeyboad = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf KeyboardProc, App.hInstance, 0)
    9. End Sub
    By pressing CTRL+ALT+UP, CTRL+ALT+DOWN, CTRL+ALT+LEFT, CTRL+ALT+RIGHT - the form will be moved accordingly even if you have the focus on some other window.

  11. #11
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    That didn't work for me

  12. #12
    Megatron
    Guest
    Originally posted by mlewis
    Megatron: can't you use AddressOf to do the hook callback in VB? I've read about doing that sort of thing...
    Yes, you can do it in VB, but it will not respong globally (as shown by Serge).

  13. #13
    Megatron
    Guest
    Originally posted by mlewis
    Urhm, Megatron, a callback is in the current module, by definition...
    Windows will load the procedure in the address space of all running threads.

  14. #14
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    responds globally for me; I can be in a totally different app and press CTL+ALT+Left/right/etc and it moves just great. You do have to hold the key down for about a second for it to activate, but thats no big deal.

    Megatron, what are you talking about? AddressOf gets the address of a function (or sub if you want to be picky) Windows calls into that memory space, it doesn't load a separate copy of the function for each process! If it loaded a new copy of your code in every process, it would either have to load the whole EXE/DLL (otherwise global variables etc. would be lost) or it would crash every time you tried it.
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  15. #15
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    So now you're arguing with one of the best people on the forums

    http://msdn.microsoft.com/library/de...hooks_7vaw.asp

    [in] Handle to 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.

  16. #16
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    I am sorry but I still do not understand that quote to mean that the procedure is loaded into all other process's memory space.

    If I am incorrect please point out where and list some clear examples. I do not mind being wrong.
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  17. #17
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    It means that if you want to install a system wide hook, that you need a DLL containing the hook procedure to be loaded into the memory i think

    Megatron will have a good answer i think though

  18. #18
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    Originally posted by da_silvy
    It means that if you want to install a system wide hook, that you need a DLL containing the hook procedure to be loaded into the memory i think

    Megatron will have a good answer i think though
    Hmmm...thats what I thought; musta misunderstood something above (do that a lot nowdays, blegh)
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  19. #19
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    hehhehe

    I have to read some posts several times to pick up what people are actually trying to ask now.

    It's like they're asking questions in some secret langauge

  20. #20
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    Well there's a lot of people from non-english speaking countries (or at least, countries that don't speak english as main language) so that's probably got a lot to do with it.

    Then of course there's those annoying people who always talk in l4m3r...0h w311 wh0 c4r3z?
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  21. #21
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    Then there's ali g

    Who is hard to understand - whether he is complimenting you or paying you out

  22. #22
    Megatron
    Guest
    Originally posted by mlewis
    Megatron, what are you talking about? AddressOf gets the address of a function (or sub if you want to be picky)...
    I'm not talking about AddressOf here. I'm talking about global hooks with SetWindowsHookEx.

  23. #23
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    Right out of MSDN docs on SetWindowsHookEx:

    lpfn
    Pointer 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.
    I read the whole artice through, and it mentions nothing about loading your code into all process's memory space (as you said above)
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  24. #24
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    meh

    There's some reason, a guru will most likely tell you...

  25. #25
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333
    I'd like to step back to the original poster of this thread. A while ago, enriquein asked:
    Where did ya guys learn the API in the fisrt place?

    Most of us learned from trial and error, experience, and playing around with making API calls that we saw in magazines or books. This is a great site to get a head start. Another VERY good site is http://www.allapi.net/ - This site also offers a free API Viewer which you can down load. Unlike the API viewer that comes with VB, this one actually has examples of how to use the APIs, and has some explanation on what they do and are used for. Don't be discouraged if you have an API blow up in your face. I would venture to say that that has happened to everyone at some point or other.

  26. #26
    Frenzied Member Skitchen8's Avatar
    Join Date
    Feb 2001
    Location
    Binghamotn, NY
    Posts
    1,943
    yes, all programmers will make huge mistakes that blow up in their face, but you debug, find the mistake, and end up w/ a half decent program (sometimes)... im still learnin the api though, i think im gunna start making graphs based upon how many times a day i have to restart because i made a mistake w/ the api...
    Government is another way to say better…than…you.
    It’s like ice but no pick, a murder charge that won’t stick,
    it’s like a whole other world where you can smell the food,
    but you can’t touch the silverware.
    Huh, what luck. Fascism you can vote for.
    Humph, isn’t that sweet?
    And we’re all gonna die some day, because that’s the American way
    -Stone Sour

  27. #27
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    There are problems with that though skitchen.

    When you subclass you can't debug so it really is a pain in the a$$.

    That means you have to be careful, or not mind restarting vb every time there is a problem

  28. #28
    Frenzied Member Skitchen8's Avatar
    Join Date
    Feb 2001
    Location
    Binghamotn, NY
    Posts
    1,943
    well, you can end the subclassing through your programming, you just have to call the event to close the hook (can't remember it off hand)
    Government is another way to say better…than…you.
    It’s like ice but no pick, a murder charge that won’t stick,
    it’s like a whole other world where you can smell the food,
    but you can’t touch the silverware.
    Huh, what luck. Fascism you can vote for.
    Humph, isn’t that sweet?
    And we’re all gonna die some day, because that’s the American way
    -Stone Sour

  29. #29
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    If your code has a fatal error it will never call the close hook code, is the point I think.

    Try it:

    'set subclass hook here
    ...
    Dim A
    A= 1/0


    Now watch the chain of events : subclass hook never removed, PC goes down...
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  30. #30
    Megatron
    Guest
    Originally posted by mlewis
    Right out of MSDN docs on SetWindowsHookEx:

    I read the whole artice through, and it mentions nothing about loading your code into all process's memory space (as you said above)
    In order for a process to have access to the functions in the DLL, it must load the DLL first (how can you retrieve functions from nothing ?). So essentially, each process will load the library, and keep the library loaded even after you uninstall the hook, hence keeping the OS in it's state of slow-processing. This is why global hooks are a big no-no.

  31. #31
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    Originally posted by mlewis
    If your code has a fatal error it will never call the close hook code, is the point I think.

    Try it:

    'set subclass hook here
    ...
    Dim A
    A= 1/0


    Now watch the chain of events : subclass hook never removed, PC goes down...
    that's only if it's compiled i think

    If you do it in vb dev, it just closes the vb ide...

  32. #32

    Thread Starter
    New Member
    Join Date
    Jul 2001
    Location
    Mayaguez, PR
    Posts
    7
    Yep, did it to me. VB Closed wiithoot even giving an error.

    But some dude sent me a URL of a web page that has a ActiveX COntrol that detects the keys, it's pretty damn good!

    Cant remember the name or website thou!

    And thanx for the advice on API, know about any good books? I tried the allapi.net program and its pretty good, but I'd like some more reference.

  33. #33
    Frenzied Member mlewis's Avatar
    Join Date
    Sep 2000
    Posts
    1,226
    Originally posted by Megatron

    In order for a process to have access to the functions in the DLL, it must load the DLL first (how can you retrieve functions from nothing ?). So essentially, each process will load the library, and keep the library loaded even after you uninstall the hook, hence keeping the OS in it's state of slow-processing. This is why global hooks are a big no-no.
    The way DLLs work is they load into 1 memory space (except certain types, or DLLs which expose in-process COM objects) then all programs share that RAM space. That was the idea behind creating DLLs in the first place.

    DLLs only load into each process if they expose Inprocess ActiveX servers.
    M. Lewis
    Pi-Q Software
    How many mouse clicks does it take to cook breakfast?

    Blargh! I am dead!

  34. #34
    Fanatic Member crispin's Avatar
    Join Date
    Aug 2000
    Location
    2 clicks west of a Quirkafleeg...Cornwall, England
    Posts
    754
    da_silvy

    you can debug when subclassed mate, get the DLL from MS that enables you to do this, then use some conditional compilation and you're away - I use Bryan Staffords classes they work great for me, and you can do all sorts of cool stuff with them, which includes debugging.....

    www.mvps.org/vbvision

    and

    http://www.mvps.org/vbvision/dbugproc_dll.htm
    Crispin
    VB6 ENT SP5
    VB.NET
    W2K ADV SVR SP3
    WWW.BLOCKSOFT.CO.UK

    [Microsoft Basic: 1976-2001, RIP]

  35. #35
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    thanks for that insight mate, i will check it out

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width