Keystrokes to Windows

BlitzMax Forums/BlitzMax Programming/Keystrokes to Windows

Jay Kyburz(Posted 2005) [#1]
I was thinking today that I'd like to write a max program that automates some repditave tasks I have to do in windows.

Does anybody know if its possible for me to send keystrokes to other apps from max.

Example, send alt-tab to the system, then send a string of keystrokes, then a tab, another sting of keystrokes etc??


Tom(Posted 2005) [#2]
Hi,

I can't help with the solution, but I thought I'd drop you this link.

http://www.autohotkey.com

It's a superb free proggy

Tom


gman(Posted 2005) [#3]
here is a post where this was discussed somewhat:

http://www.blitzmax.com/Community/posts.php?topic=48863


assari(Posted 2005) [#4]
Jay,

I managed to get the AUTOIT dll to work with bmax. You need to download the free package (the dll is within the zipfile) from http://www.autoitscript.com/autoit3/downloads.php

I have not completed doing all the AUTOIT functions but have completed several. Pls feel free to continue this work. The AUTOIT_Send function is what you need.

The following is an example of what it can do

Strict
Include "incl_Autoit.bmx"

'You need to call AUTOIT_INIT() before using any of the AUTOIT functions
Local r=AutoIT_Init()

AUTOIT_ClipPut("This is text is in the Clipboard") 'Put text to clipboard
Local c$=AUTOIT_Clipget() 'Get text from clipboard

WinExec("Notepad.exe",1) 'runs notepad
AUTOIT_WinWaitActive("Untitled","",1000) 'Wait for Notepad window for 1000ms

AUTOIT_AutoItSetOption("SendKeyDelay", 10) ' Delay keypresses
AUTOIT_Send(c) 'send string to window
AUTOIT_Send("{ALTDOWN}{F4}{ALTUP}")  'send ALT-F4 to active window
'or AUTOIT_Send("!{F4})

End


The functions are described well in the help files. Note that the functions available from the dll are different from the Macro functions.

The include file (which was going to be a mod - but I dont know when I will do this) is as per below




Jay Kyburz(Posted 2005) [#5]
Thanks Guys,

I installed autohotkey last night and it looks like what I need.

I'll read up on Autoit now.

Are there any websites I can go an shop around for useful little dll like this that free to distribute with my game?


gman(Posted 2005) [#6]
Autoit does have a DLL that you can distribute free with commercial products. i confirmed that very thing today as i found it very interesting.


Curtastic(Posted 2006) [#7]
Hey assari this is really interesting, but I got the DLL and tried your code but blitz just crashes when compiling the example code.

I changed the example code to this and bcc.exe still crashes and then blitz says "Build Error: failed to compile"
Strict
Include "incl_Autoit.bmx"
End


assari(Posted 2006) [#8]
Hi,
It seems that the 1.16 compiler does not like the previous method I was using to declare the functions.

I do not have time yet to go through and change everything but this code works for me. Try it out and see what happens. Do not forget to change the dll location
Const AU_Default:Int=(-2147483647)

Extern "win32"
  Function  WinExec(lpCmdLine$z,nCmdShow:Int)
End Extern

Local path$="D:\assari\blitzmax\autoit-v3\AutoItX\"  'CHANGE THIS TO YOUR OWN LOCATION!!!
Global DLLHandle=loadlibraryA(path$+"AutoitX3.dll")
Global AutoIT_Init()"win32"=GetProcAddress(DLLHandle, "AU3_Init") 'Init(void);
Global AutoITX_ClipGet(szClip:Byte Ptr, nBufSize:Int)"win32"=GetProcAddress(DLLHandle, "AU3_ClipGet") 

Function AUTOIT_ClipGet$(nBufSize:Int=255)
Local stuff:Byte[nBufSize]
	AUTOITX_ClipGet(stuff,nBufSize)
	Local ret$=string.FromCString(stuff)
	Return ret$
End Function

Global AutoIT_ClipPut(szClip$z)"win32"=GetProcAddress(DLLHandle, "AU3_ClipPut") 'ClipPut(const char *szClip);
Global AutoIT_WinWaitActive(szTitle$z, szText$z,  nTimeOut:Long)"win32"=GetProcAddress(DLLHandle, "AU3_WinWaitActive") 
Global AutoIT_AutoItSetOption(szOption$z, nValue:Long)"win32"=GetProcAddress(DLLHandle, "AU3_AutoItSetOption") 
Global AutoITX_Send(f$z, nmode:Long)"win32"=GetProcAddress(DLLHandle,"AU3_Send")
Function AUTOIT_Send(f:String, nmode:Long=0)
   Return AUTOITX_Send(f,nmode)
End Function

Local r=AutoIT_Init()

AUTOIT_ClipPut("This text is in the Clipboard") 'Put text to clipboard
Local c$=AUTOIT_Clipget() 'Get text from clipboard

WinExec("Notepad.exe",1) 'runs notepad
AUTOIT_WinWaitActive("Untitled","",1000) 'Wait for Notepad window for 1000ms

AUTOIT_AutoItSetOption("SendKeyDelay", 10) ' Delay keypresses
AUTOIT_Send(c) 'send string to window
AUTOIT_Send("{ALTDOWN}{F4}{ALTUP}")  'send ALT-F4 to active window
'or AUTOIT_Send("!{F4})

End





Curtastic(Posted 2006) [#9]
This is awesome, thanks! But its messing with my variables. The for loop exits and go becomes some huge nember.

Strict

Const AU_Default:Int=(-2147483647)

Extern "win32"
  Function  WinExec(lpCmdLine$z,nCmdShow:Int)
End Extern

Local path$="c:\autoit-v3\AutoItX\"  'CHANGE THIS TO YOUR OWN LOCATION!!!
Global DLLHandle=loadlibraryA(path$+"AutoitX3.dll")
Global AutoIT_Init()"win32"=GetProcAddress(DLLHandle, "AU3_Init") 'Init(void);
Global AutoITX_ClipGet(szClip:Byte Ptr, nBufSize:Int)"win32"=GetProcAddress(DLLHandle, "AU3_ClipGet") 

Function AUTOIT_ClipGet$(nBufSize:Int=255)
Local stuff:Byte[nBufSize]
	AUTOITX_ClipGet(stuff,nBufSize)
	Local ret$=string.FromCString(stuff)
	Return ret$
End Function

Global AutoIT_ClipPut(szClip$z)"win32"=GetProcAddress(DLLHandle, "AU3_ClipPut") 'ClipPut(const char *szClip);
Global AutoIT_WinWaitActive(szTitle$z, szText$z,  nTimeOut:Long)"win32"=GetProcAddress(DLLHandle, "AU3_WinWaitActive") 
Global AutoIT_AutoItSetOption(szOption$z, nValue:Long)"win32"=GetProcAddress(DLLHandle, "AU3_AutoItSetOption") 
Global AutoITX_Send(f$z, nmode:Long)"win32"=GetProcAddress(DLLHandle,"AU3_Send")
Function AUTOIT_Send(f:String, nmode:Long=0)
   Return AUTOITX_Send(f,nmode)
End Function



Local r=AutoIT_Init()

Delay 1000
WinExec("Notepad.exe",1) 'runs notepad
AUTOIT_WinWaitActive("Untitled","",1000) 'Wait for Notepad window for 1000ms
AUTOIT_AutoItSetOption("SendKeyDelay", 20)

Local go
For go=1 To 5
	Print "go="+go
	AUTOIT_Send("asdf")
Next
Print "for loop exited"
Print "go="+go

End



assari(Posted 2006) [#10]
on my system go=6 on exit as expected.


Curtastic(Posted 2006) [#11]
okay it works fine with debug on.
But with debug off... I don't get how it can change my variables. Here is a simpler example

Local r=AutoIT_Init()

Delay 1000
WinExec("Notepad.exe",1) 'runs notepad
AUTOIT_WinWaitActive("Untitled","",1000) 'Wait for Notepad window for 1000ms

Local go
Print "go="+go
AUTOIT_Send("a")
Print "go="+go

End


outputs:

Building untitled3
Compiling:untitled3.bmx
flat assembler  version 1.64
3 passes, 4866 bytes.
Linking:untitled3.exe
Executing:untitled3.exe
go=0
go=10688816

Process complete



assari(Posted 2006) [#12]
Yup, I'm getting the same error. works w debug on and error w/out. Floats works but not string, byte or int
Building forum
Compiling:forum.bmx
flat assembler  version 1.64
3 passes, 12257 bytes.
Linking:forum.exe
Executing:forum.exe
go=0
go=2089893474

Process complete
WinXP SP2


Curtastic(Posted 2006) [#13]
hey, this is cool, I'm still using this stuff.
The new blitzmax update makes it not work again. It doesn't like the $z

Please fix it for me. You have to constantly maintain the code now that you made it! hahaha!


assari(Posted 2006) [#14]
According to this thread http://www.blitzmax.com/Community/posts.php?topic=57496&hl=cstring this is a BlitzMax bug and will be fixed soon.


Curtastic(Posted 2006) [#15]
okay gotcha