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!! "
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:
Private Const MOD_ALT = &H1
Private Const MOD_CONTROL = &H2
Private Const MOD_SHIFT = &H4
Private Const PM_REMOVE = &H1
Private Const WM_HOTKEY = &H312
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type Msg
hWnd As Long
Message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
Private Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long, _
ByVal fsModifiers As Long, ByVal vk As Long) As Long
Private Declare Function UnregisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long) As Long
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As Msg, _
ByVal hWnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long
Private Declare Function WaitMessage Lib "user32" () As Long
Private bCancel As Boolean
Private Sub ProcessMessages()
Dim Message As Msg
'loop until bCancel is set to True
Do While Not bCancel
'wait for a message
WaitMessage
'check if it's a HOTKEY-message
If PeekMessage(Message, Me.hWnd, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) Then
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'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 )
^^ 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!! "
- 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.
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?
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.
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 .
"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!! "
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