win32api and getting hotkeys problem? ideas? soja, james, tracer?
Blitz3D Forums/Blitz3D Programming/win32api and getting hotkeys problem? ideas? soja, james, tracer?
| ||
the previous coding with win32api where we accessed another program's data addresses (memory) worked like a charm. thanks to those who helped me learn the process and get to the successful conclusion. currently i am trying to find a way with blitz3d that i can monitor "hotkeys". specifically, i want to be able to have the blitz program detect when certain keys (or key combinations) are being pressed, even if i a am in another window or other program. for instance, with the trainers i hope to create, i want to be able to be playing the game and then press a certain key on the keyboard which will activate the trainer or features of the trainer. of course the trainer is the blitz3d program which is also running at the same time. i dont think that the normal blitz3d commands will let me do it this way. i am assuming that win32api calls will be needed again (perhaps the getasynchkeystate and a timer event or something or another that ensures blitz3d is working and checking things even in the background?) anyways, looking for ideas and of course code is always welcome, especially if it involves win32api calls which i am still learning. i hope someone can help! best, mike |
| ||
Hi Mike, Yes as far as I know you would normally use the WinAPI by calling SetWindowsHookEx (User32.dll), but it requires a callback function, and since Blitz doesn't have function pointers, you can't specify a callback function, so you can't use it. =( So essentially you'd have to write your own DLL wrapper (in another language) for SetWindowsHookEx (and all the other Keyboard/Mouse Hook functions you wanted) which you could call with Blitz. Or, you could find one that someone else wrote, perhaps. I remember seeing a file called "nhook.dll" in one of the programs I use which I assume was something like this (I examined the exported functions), but I can't remember what program that came from, and whether it was freely distributable, etc. Perhaps someone else knows some other tips. |
| ||
soja, thanks for the reply. i am curious if this type of thing would be easy to do and would work with blitzplus (instead of blitz3d)? also are there any others reading this thread with ideas or with info to the .dll soja mentioned? best, mike |
| ||
BlitzPlus has a built-in hotkey event handler, but it only works when the program is active, so you're in the same boat there. I looked around and found this article: The Code Project - KeyBoard Hooks There a whole section of articles to read on hooks. This particular one is about creating a DLL in C for hooking the keyboard. You might also check this out: NASM Keyboard hook DLL example I've never used NASM, but if I remember right, it's a free assembler. I figure with minimal fuss you could probably replace the MessageBox function (from within HookProc:) with SendMessage, so that everytim a key is pressed on the keyboard, it sends a message to your Blitz program. |
| ||
There are/where examples on this forum to set a keyboard hook. http://www.google.com/search?q=keyboard+hook+site%3Awww.blitzbasic.com&ie=UTF-8&oe=UTF-8&hl=da&btnG=Google-s%C3%B8gning&meta= In the code archives: http://www.blitzbasic.com/codearcs/codearcs.php?code=366 |
| ||
peter i have looked and didn't see any examples for that using those links. i am hoping that someone reading this can provide an example or maybe point me to where some example code would be. i have very little win32api experience and even less c++ experience so i don't see me writing my own dll.... there's got to be a way to do this! also, if tracer or anyone with purebasic is reading this, i am curious if purebasic can do this sort of thing? lastly, i found this link about hooks. anyone know how to do these hooks with blitz3d? http://help.madshi.net/madCodeHook.htm thanks, mike |
| ||
Sorry, you are right. That code archive entry is not what I thought it was, and the keyboard hook functions seems to have been deleted from this forum. This is what I've done (following a tip in these forums) to install a keyboard hook, to use normal windows controls in a Blitz3D window. In the KeyboardHookProc, I guess you could put your code, to get custom keypresses. You have to add the code to copy to the bank passed. Powerbasic dll: #Compile Dll "C:\blitz3d\userlibs\bbhook.dll" #Include "WIN32API.INC" Global gKBHook As Long Function LibMain(ByVal hInstance As Long, _ ByVal Reason As Long, _ ByVal Reserved As Long) _ Export As Long Select Case Reason Case %DLL_PROCESS_ATTACH LibMain = 1 Exit Function Case %DLL_PROCESS_DETACH Exit Function Case %DLL_THREAD_ATTACH Exit Function Case %DLL_THREAD_DETACH ' Exit Function End Select LibMain = 0 'failure! End Function Function KeyboardHookProc(ByVal code As Long,ByVal wParam As Dword ,lParam As tagmsg) As Dword 'Static Msg As tagMsg If code<0 Then Function= CallNextHookEx(gKBHook,code,wParam,lParam) Exit Function Else ' Call getMessage( lParam, %NULL, 0, 0 ) '= %FALSE 'Then If lParam.message=%WM_KEYDOWN Then TranslateMessage lParam DispatchMessage lParam End If End If End Function Function hook Alias "hook" (bank1 As Dword) Export As Long MsgBox "Hooked " & Str$(gKBHook) gKBHook=SetWindowsHookEx(%WH_GETMESSAGE,CodePtr(KeyboardHookProc),0,GetCurrentThreadID()) End Function Function unhook Alias "unhook" (bank1 As Dword) Export As Long UnhookWindowsHookEx gKBHook MsgBox "unhooked" End Function Blitz hookdll userlib: .lib "bbhook.dll" hook%(bank*):"hook" unhook%(bank*):"unhook" Blitz3D code and User32.decls: ;-User32.decls Begin ------------------------------------------------------- ;.lib "User32.dll" ;User32_CreateWindowEx%(dwExStyle,lpClassName$,lpWindowName$,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam):"CreateWindowExA" ;User32_GetWindowLong%(hWnd,nIndex):"GetWindowLongA" ;User32_SetWindowLong%(hWnd,nIndex,dwNewLong):"SetWindowLongA" ;User32_FindWindow%(lpClassName$,lpWindowName$):"FindWindowA" ;-User32.decls End ------------------------------------------------------- Const WS_CHILD = $40000000 Const WS_MINIMIZE = $20000000 Const WS_VISIBLE = $10000000 Const WS_CLIPCHILDREN = $2000000 Const WS_BORDER = $800000 Const WS_TABSTOP = $10000 Const GWL_STYLE = -16 Const WS_EX_CLIENTEDGE = $200 Const WS_EX_LEFT = $00000000 Const ES_LEFT = 0 Const ES_CENTER = 1 Const ES_RIGHT = 2 Graphics3D 800,600,0,2 title$="My title" AppTitle title$ ; find blitz window handle bbHwnd= User32_FindWindow("Blitz Runtime Class",title$) ; get blitz window style style=User32_GetWindowLong(bbHwnd,GWL_STYLE) ; add clip children style, so that controls are not blitted over ret= User32_SetWindowLong(bbHwnd,GWL_STYLE,style Or WS_CLIPCHILDREN) ; Create a button: ret=User32_CreateWindowEx(0,"Button","I am a button",WS_CHILD Or WS_VISIBLE,10,10,100,20,bbHwnd,101,0,0) style=WS_BORDER Or ES_LEFT Or WS_CHILD Or WS_TABSTOP Or WS_VISIBLE exStyle=WS_EX_CLIENTEDGE Or WS_EX_LEFT ; Create a edit box: ret=User32_CreateWindowEx(exStyle,"Edit","The edit box",WS_CHILD Or WS_VISIBLE,10,40,400,20,bbHwnd,101,0,0) cam=CreateCamera() CameraViewport cam ,100,100,400,400 Viewport 100,100,400,400 PositionEntity cam ,0,0,-4 light=CreateLight() RotateEntity light,10,30,0 cube =CreateCube() mybank=CreateBank(40) hook mybank While Not KeyHit(1) TurnEntity cube,1,2,3 UpdateWorld() RenderWorld() Text 100,100,"hello " Flip Wend unhook mybank End |
| ||
wow! thanks peter. i appreciate your time and effort on this. this forum is an awesome place because of people like you and some of the others who have helped people like myself. unfortunately i don't have powerbasic. is there a copy of the .dll that i can download or something that is freeware that will compile .dll's with powerbasic code? if i do download it, where do i put it so that things compile (do .dlls also go into userlibs dir with the .decls?) also, i suppose that the .dll has to have all of the keypress decisions in it or something or at least the checks for the specific keys you are using or does that go into the .bb program itself? what does the blitz3d program do specifically, does it draw a spinning cube in a windowed mode window and then end when you press ESC? can you have another program running as the focus and hitting the ESC ends the program with the spinning cube even though it doesn't have the focus? or is it simply turning the cube when you press the key down only (even if the focus is in another program)(or is WM_KEYDOWN literally any key pressed down)? What if i needed 6 or 10 different keypresses to do 10 different things when pressed? would the code for checking that go into the code in the blitz3d .bb which is between the hook and unhook calls? explain why the bank has to have a size of 40. would that number have to increase? where would i put the actual keypress checks, do i put it within the hook and unhook area? will the blitz program (the .exe generated) then check for keypresses even if that program is not the focus? like i said, i don't have powerbasic so i can't create the actual hookbb.dll and would have no way to test this in action. plus, then i need to learn the syntax for powerbasic which may or may not be like blitz3d and costs another $199.00 for a licensed version. i almost feel guilty that you put this time into this and yet i can't even try to use it. i apologize and hope that we can try this again somehow and also i am still looking for other methods as well. also, i am wondering if someone else has put together a blitz3d hook .dll like peter that is already compiled and ready for download. this has been quite the learning experience the last couple weeks. best, mike |
| ||
Yes, WM_KEYDOWN is any key. You'll have to take it from here yourself. The above dll is does not copy the keystrokes to a bank. Copying the keystokes the bank(buffer), passed in the hook function would be an easy way to do it. If you want to make your dll safe to use with multiple Blitz3D apps running at a time, you should look into SetWindows long, and store a pointer to your apps buffer. Using global or static variables in a dll, will not make it thread safe. Good luck. I see that some people are using Purebasic for this kind of stuff. It's a lot cheaper than PowerBasic, but you can do the same thing with a free C compiler like lcc or similar. |
| ||
thanks again peter. any more ideas from others? bump for more viewers and ideas. best, mike |
| ||
Uh, why use a DLL if you just need the GetAsyncKeyState winapi command to catch any keys no matter what window they're from? Tracer |
| ||
I hadn't thought of that, Tracer. Two disadvantages I can see right off: 1) You use (possibly much) more CPU time (depending on what keys and how often you check) 2) It won't work with some applications or on other desktops But it works generally, and might be exactly what Mike needs. ...I tried it, it works dandily. ;.lib "user32.dll" ;GetAsyncKeyState%(vKey%):"GetAsyncKeyState" Repeat Print GetAsyncKeyState(1) Forever (Just go clicking the left mouse button and see what happens.) For a complete list of the Virtual Key values, look the function up on MSDN. |
| ||
GetAsyncKeyState might work, but make sure you have some heavy rendering going on at the same time you test this stuff. Due to it's messagepump setup, Blitz3D does not behave exactly like a normal Windows app with mouse and keyboard input. The hook posted above, is the only way I have found to get keystrokes through in a stable manner. |
| ||
thanks for all of the info guys! this forum is the best i have ever experienced with any software. tracer, the getasynckeystate was elegant and simple. however, peter is right and it only works in the "windowed" environment. unfortunately, when i try this in my trainer (test it with an actual game which is rendering 80 fps) the blitz3d program does not register the keystrokes. it's very easy to test and i did test it with "windowed" apps (changing the focus to another windowed program and the keystrokes were registered, but with a full blown game running in fullscreen mode with directx or whatever, it doesn't work, darn it...) i was so excited and thought we had found a simple answer to this! creating some sort of hook seems to be an answer but i cannot even test it. also, i have no way of making the .dll's necessary. it seems i am going to have to move to another language to do this. arghh.... i have EVERYTHING in place to do the programs i want except the ability to detect system-wide keypresses while utilizing blitz. any more ideas or help? best, mike |
| ||
bump for more readers and ideas- |
| ||
bump for more ideas on how to hook this or a different approach to gather system wide hotkeys- |