Results 1 to 14 of 14

Thread: [RESOLVED] Detect a Hot Key without looping

  1. #1

    Thread Starter
    Hyperactive Member TupacShakur's Avatar
    Join Date
    Mar 2002
    Location
    Da Land Of Da Heartless...
    Posts
    493

    Resolved [RESOLVED] Detect a Hot Key without looping

    Once again i find myself seaking the help of the experienced guys in here

    However, this will pose a challenge for u guys. I have searched and read more code than the average human brain can handle in a 3 hours span, but found no solution to my need:

    What i need to do is to create a system wide hot key for my app that can be detected when my app is inactive. But the crucial part is that i need to detect that key when it's pressed without using the classical DoEvents based loop (which by the way is the most inadequate commonly used programming practice in VB) !!

    I came to the conclusion that this canot be done using GetAsyncKeyState (cause this would require looping), but probably could be done using sub classing, which i have no idea about. I am not sure also if sub classing should be used with the RegisterHotKey API or not, and if there is some other way to use the HotKey API to set some kind of event that will be triggered when the hot key is pressed (an event that will be detected by the system, just like how events are set in Java or C++, and not through a loop from within my code)???

    He who helps me will be generously awarded!!!!
    Last edited by TupacShakur; Mar 23rd, 2006 at 06:51 PM.
    "And Now I'm Lika Major Threat, Cause I Remind U Of The Things U Were Made To Forget!" - (2PAC)

    "Now They Label Me a Lunatic, Couldn't Care Less, Death or Success is What I Quest, Cause I'm Fearless!" - (2PAC)

    " There's a light at the end of every tunnel, just pray it's not a train!! "



    I am 100% addicted to Tupac. What about you?
    I am 24% addicted to Counterstrike. What about you?
    The #1 Tupac Fans Web Site | The Official Tupac Web Site

  2. #2
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Detect a Hot Key without looping

    About RegisterHotKey, you can do it this way..
    This example works with CTRL-F and will process even when your program hasn't the focus. In this case the event fired will be: change between WindowState = minimized and WindowState = Normal each time you press CTRL-F.
    VB Code:
    1. Private Const MOD_ALT = &H1
    2. Private Const MOD_CONTROL = &H2
    3. Private Const MOD_SHIFT = &H4
    4. Private Const PM_REMOVE = &H1
    5. Private Const WM_HOTKEY = &H312
    6. Private Type POINTAPI
    7.     x As Long
    8.     y As Long
    9. End Type
    10. Private Type Msg
    11.     hWnd As Long
    12.     Message As Long
    13.     wParam As Long
    14.     lParam As Long
    15.     time As Long
    16.     pt As POINTAPI
    17. End Type
    18. Private Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long, _
    19.                     ByVal fsModifiers As Long, ByVal vk As Long) As Long
    20. Private Declare Function UnregisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long) As Long
    21. Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As Msg, _
    22.                     ByVal hWnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, _
    23.                     ByVal wRemoveMsg As Long) As Long
    24. Private Declare Function WaitMessage Lib "user32" () As Long
    25. Private bCancel As Boolean
    26. Private Sub ProcessMessages()
    27.     Dim Message As Msg
    28.     'loop until bCancel is set to True
    29.     Do While Not bCancel
    30.         'wait for a message
    31.         WaitMessage
    32.         'check if it's a HOTKEY-message
    33.         If PeekMessage(Message, Me.hWnd, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) Then
    34.             If WindowState = vbMinimized Then
    35.                 WindowState = vbNormal 'normal
    36.             Else
    37.                 WindowState = vbMinimized  'minimize the form
    38.             End If
    39.         End If
    40.         'let the operating system process other events
    41.         DoEvents
    42.     Loop
    43. End Sub
    44. Private Sub Form_Load()
    45.     'KPD-Team 2000
    46.     'URL: [url]http://www.allapi.net/[/url]
    47.     'E-Mail: [email][email protected][/email]
    48.     Dim ret As Long
    49.     bCancel = False
    50.     'register the Ctrl-F hotkey
    51.     ret = RegisterHotKey(Me.hWnd, &HBFFF&, MOD_CONTROL, vbKeyF)
    52.     'show some information
    53.     Me.AutoRedraw = True
    54.     Me.Print "Press CTRL-F to minimize this form"
    55.     'show the form and
    56.     Show
    57.     'process the Hotkey messages
    58.     ProcessMessages
    59. End Sub
    60. Private Sub Form_Unload(Cancel As Integer)
    61.     bCancel = True
    62.     'unregister hotkey
    63.     Call UnregisterHotKey(Me.hWnd, &HBFFF&)
    64. End Sub
    Last edited by jcis; Mar 23rd, 2006 at 08:51 PM.

  3. #3

    Thread Starter
    Hyperactive Member TupacShakur's Avatar
    Join Date
    Mar 2002
    Location
    Da Land Of Da Heartless...
    Posts
    493

    Re: Detect a Hot Key without looping

    LoL, that part, i know how to do, but thanks anyway !!

    What i'm looking for is to avoid the infinite loop when detecting the key press.. If u try the above code, u will see that its correspondant process will be taking around 50% of the CPU resources, which is a crazy thing for an application that will be running all the time. I think that DoEvents infinite loops are a very bad practice, so i'm looking for a more professional way of doing the key detection.

    One thing i tried, and which seems to work pretty well, is simply detecting the hot key press in a timer (which can be done using only GetAsyncKey, since i only need to detect an F8, F9, or F10 key strokes). I set the timer interval to 200, which means it will check for they key presses 5 times per second, while the process is not consuming any noticeable additional CPU resources..

    However, i am still looking for "THE" right way of doing it, which does not require a custom key press check but rather setting an event or sub classing or something like that.. So i hope that my problem is clearer now, and i'm waiting for ur help experts!!
    Last edited by TupacShakur; Mar 24th, 2006 at 06:14 AM.
    "And Now I'm Lika Major Threat, Cause I Remind U Of The Things U Were Made To Forget!" - (2PAC)

    "Now They Label Me a Lunatic, Couldn't Care Less, Death or Success is What I Quest, Cause I'm Fearless!" - (2PAC)

    " There's a light at the end of every tunnel, just pray it's not a train!! "



    I am 100% addicted to Tupac. What about you?
    I am 24% addicted to Counterstrike. What about you?
    The #1 Tupac Fans Web Site | The Official Tupac Web Site

  4. #4
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Detect a Hot Key without looping

    I've always considered looping an utterly braindead way of achieving it. The, as you say, proper way, is to subclass the window to which you registered the hotkey for and process the WM_HOTKEY message.

    pseudo code example (sure you can find the API function declarations )
    VB Code:
    1. ' subclass:
    2. pOldWindowProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf WndProc)
    3.  
    4. ' window proc, must be an in a standard module (.bas)
    5. Private Function WndProc( _
    6.   ByVal hWnd As Long, _
    7.   ByVal uMsg As Long, _
    8.   ByVal wParam As Long, _
    9.   ByVal lParam As Long _
    10. ) As Long
    11.   If (uMsg = WM_HOTKEY) Then
    12.     ' process your hotkey stuff here
    13.  
    14.     ' If you have multiple hotkeys do a switch on the hotkey id
    15.     ' (which you pass to RegisterHotKey) as follows.
    16.     Switch (wParam)
    17.       Case [i]x[/i] :  ' etc
    18.     End Switch
    19.   End If
    20. End Function
    21.  
    22. ' unsubclass:
    23. SetWindowLong(Me.hWnd, GWL_WNDPROC, pOldWindowProc)

  5. #5

    Thread Starter
    Hyperactive Member TupacShakur's Avatar
    Join Date
    Mar 2002
    Location
    Da Land Of Da Heartless...
    Posts
    493

    Re: Detect a Hot Key without looping

    ^^ Thx for ur help, but i'm still having some trouble using ur example. More specifically, i'm not sure where and when to subclass / unsubclass..
    Also, even after defining the API calls and the variables, i'm still naturally getting an "undefined variable" error on (pOldWindowProc), which i dont know how and where to define.. So help is still needed !!
    "And Now I'm Lika Major Threat, Cause I Remind U Of The Things U Were Made To Forget!" - (2PAC)

    "Now They Label Me a Lunatic, Couldn't Care Less, Death or Success is What I Quest, Cause I'm Fearless!" - (2PAC)

    " There's a light at the end of every tunnel, just pray it's not a train!! "



    I am 100% addicted to Tupac. What about you?
    I am 24% addicted to Counterstrike. What about you?
    The #1 Tupac Fans Web Site | The Official Tupac Web Site

  6. #6
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Detect a Hot Key without looping

    OK 'Pac:

    - Define pOldWindowProc as a Long in the form. Make it Private in the declarations section.
    - Subclass before you call RegisterHotkey(), say in Form_Load().
    - Unsubclass in the Form_QueryUnload() event, so that your app don't crash.

  7. #7
    Frenzied Member the182guy's Avatar
    Join Date
    Nov 2005
    Location
    Cheshire, UK
    Posts
    1,473

    Re: Detect a Hot Key without looping

    this wont work if your app doesnt have focus though will it? Im having the same problem.

    I want to be able to press say F9 and have my app appear (all without looping), I cant get penagates example working...is there a way to subclass so that you can process the key if your app is not in focus?
    Chris

  8. #8
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    Re: Detect a Hot Key without looping

    Use the MCLHotkey control?

  9. #9
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Detect a Hot Key without looping

    This would also be an utterly braindead way?
    http://www.vb-helper.com/howto_hotkey.html

  10. #10
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Detect a Hot Key without looping

    Quote Originally Posted by the182guy
    this wont work if your app doesnt have focus though will it? Im having the same problem.

    I want to be able to press say F9 and have my app appear (all without looping), I cant get penagates example working...is there a way to subclass so that you can process the key if your app is not in focus?
    Certain keys do not make as good hotkeys as others, in particular some of the F* keys (can't remember which ones now -MSDN says I think in the RegisterHotKey documentation). But a hotkey registered this way is global, it will work when your app is not in focus.

    I was sure I had an example of this, but couldn't find one so here's one I chucked together. Hotkey is Ctrl+Shift+F10, when it is pressed the application appears and shows a messagebox.

    - P
    Attached Files Attached Files

  11. #11
    Frenzied Member the182guy's Avatar
    Join Date
    Nov 2005
    Location
    Cheshire, UK
    Posts
    1,473

    Re: Detect a Hot Key without looping

    cheers penagate just what i needed
    Chris

  12. #12

    Thread Starter
    Hyperactive Member TupacShakur's Avatar
    Join Date
    Mar 2002
    Location
    Da Land Of Da Heartless...
    Posts
    493

    Resolved Re: Detect a Hot Key without looping

    Penagate: Cheers, your help (the pseudo code, then the additional explanation, and finally and especially the sample project ) solved my problem completely!!

    jcis: The link u posted in ur 2nd post provided a very similar, but not exactly the same approach (of Pengate's) to achieve what i needed. Your help was also appreciated!

    Merrion: Although the other guys helped me understand what i was doing, the link u posted provided the easiest and classiest solution, an OCX !! Thx for ur help !

    the182guy: I am glad that my thread provided u with the help u needed, u should be thanking me .. lool..


    Finally, i attached a small package of the various ways of doing this task (using some of the provided samples, and some other samples i did) to make life easier for future searchers of this topic. Enjoy!!


    P.S: All guys were properly credited in the samples, and ur posts were also rated .
    Attached Files Attached Files
    "And Now I'm Lika Major Threat, Cause I Remind U Of The Things U Were Made To Forget!" - (2PAC)

    "Now They Label Me a Lunatic, Couldn't Care Less, Death or Success is What I Quest, Cause I'm Fearless!" - (2PAC)

    " There's a light at the end of every tunnel, just pray it's not a train!! "



    I am 100% addicted to Tupac. What about you?
    I am 24% addicted to Counterstrike. What about you?
    The #1 Tupac Fans Web Site | The Official Tupac Web Site

  13. #13
    Addicted Member
    Join Date
    Apr 2006
    Location
    Sweden
    Posts
    173

    Re: [RESOLVED] Detect a Hot Key without looping

    how do i use pen-vb6-hotkey.zip? can anyone explain, please?

  14. #14
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: [RESOLVED] Detect a Hot Key without looping

    Use an archive extractor tool such as WinRAR, 7-Zip, WinZip etc. to extract the files to a directory, then run the .vbp project file. Should be self explanatory from there

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