I'm looking for a simple way of setting the cursor position by script, after computer start.
I've found :
Private Declare Sub SetCursorPos Lib "User32" (ByVal X As Long, ByVal Y As Long)
SetCursorPos 4, 52
But can't manage to use them in a VBScript for example...
Is there a better solution ? How can I do this without having to compile an application ?
Thanks in advance for your help !
No, unfortunately you cannot call Windows API functions directly from VBScript. Given the security implications of a scripting language calling down to native code directly, and the lack of any data types other than Variant, there's no way this can work.
One way to do it is to create some kind of helper automation object to call the API, which you can then use from VBScript.
But that's an awful lot of work for a one-off task. I'd suggest just compiling an application in whatever language you're comfortable in. If you can write in VBScript, you can write in VB 6...if you can still find a copy of the compiler/IDE.
You need to define setCursorPos
VBS-Helper
(Posted at 15:09 GMT)
This is a excel code, this is working. Try it in vbscript only!
Dim Excel: Set Excel = WScript.CreateObject("Excel.Application")
Excel.ExecuteExcel4Macro "CALL(""user32"",""SetCursorPos"",""JJJ""," & 320 & "," & 2 & ")"
Related
I need to write some functions in C for someone else's VB6 project (that being outdated is beyond the scope of this question).
During initial tests, I could not get the calls to work. I have supplied a .def file, I tried to use __declspec(dllexport), stdcall and WINAPI calling conventions. Each call I get an error message in VB6 saying "bad dll calling convention."
Win32 C function prototypes:
long WINAPI BitmapFile_Open(char *pszFileName);
void WINAPI BitmapFile_Close(long bmf);
note in the above I have tried several other calling conventions, including __declspec(dllexport) and stdcall, and neither work.
Def file:
LIBRARY ImageLib
EXPORTS
BitmapFile_Open #1
BitmapFile_Open #2
VB Global Module:
Declare Function BitmapFile_Open Lib "ImageLib.dll" (ByVal fileName As String) As Long
Declare Function BitmapFile_Close Lib "ImageLib.dll" (ByVal bmFile As Long)
VB Code:
Dim myFile As Long
myFile = BitmapFile_Open("test.bmp")
BitmapFile_Close (myFile)
Also note that in the original functions, the bmFile is actually an address (pointer to a structure) but in VB it will be represented as long. However, since VB6 doesn't support pointers, I am casting from long in the C code. I hope you can understand what I'm trying to get at here. It has nothing to do with the error that is occurring. Any help is appreciated.
Edit: I have used a dependency walker to determine that the functions are indeed being exported. VB6 is just not calling them without error.
BitmapFile_Close should be declared as a Sub in the VB6. I can't see anything else wrong.
Look at the Microsoft advice on writing C DLLs to be called from VB. Originally released with VB5 but still relevant to VB6.
Try removing the ByVal from the arguments in question (inside the declaration section) one by one, then test and try removing for all arguments then test again. Do the incremental tests and report back if you can. That should do the trick!
Use MIDL to generate a type library for your DLL, then VB6 can use its type information instead of Declare Function routines.
For global functions, I seem to recall that you want a library and module defined.
See VB - Linking a DLL in implicit way
I have a loop procedure in VB6 which explores all the folders from a specified file path.
I then need to know if each detected folder contains MP3 files.
I don't want to use the dir command because it takes up a lot of resources.
I've tried doing this using FSO, APIs, etc, but I can't find a solution.
Thanks for any help.
VB6's Dir$() function is a pretty light wrapper on FindFirstFile and friends. I'm not sure why you think the FSO would be any lighter or faster.
The biggest serious limitations of Dir$() are that it is an ANSI function and it cannot be "interrupted" by a second search while one is already in progress without resetting the state of the first search.
What does "takes up a lot of resources" mean anyway?
I posted a Class wrapping the process at DirLister lightweight Dir() wrapper.
Have you tried the FindFirstFile API function? It should be your best shot. There's a C# example at codeproject A Faster Directory Enumerator
The VB signature goes like this:
<DllImport("kernel32.dll", CharSet := CharSet.Auto)> _
Private Shared Function FindFirstFile(ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As IntPtr
End Function
Here's a sample VB implementation http://www.ask-4it.com/how-to-use-findfirstfile-win32-api-from-visual-basic-code-2-ca.html
You can also find a nice microsoft article on usage of the API here.
I need to write some vbscripts in my new project. I was told by other people that vbscripting is easy, but seems to me, it is not. For example, in the following example (provided by microsoft), these functions: CreateObject, CreateShortcut, as well as these property names: TargetPath, WindowStyle, Hotkey, etc, are used, but I just cannot find the corresponding API documentation about how to use them. In other words, how do you know you need to call these functions in your vbscripts? Visual Studio 2008/2010 do not have templates for vbscript either. Could anybody tell me what I am missing, and what the best way is to do vbscripting?
set WshShell = WScript.CreateObject("WScript.Shell")
strDesktop = WshShell.SpecialFolders("Desktop")
set oShellLink = WshShell.CreateShortcut(strDesktop _
& "\MyExcel.lnk")
oShellLink.TargetPath = _
"C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE"
oShellLink.WindowStyle = 1
oShellLink.Hotkey = "CTRL+SHIFT+F"
oShellLink.IconLocation = _
"C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE, 0"
oShellLink.Description = "My Excel Shortcut"
oShellLink.WorkingDirectory = strDesktop
oShellLink.Save
Take a look here (MSDN).
The objects you are working with are documented there (of course, it's MSDN documentation so it's not ideal, but it's documented nevertheless).
Specifically the WshShortcut Object and the WshShell etc.
I don't think VBScript is a very easy language, especially if you need to write larger scripts.
If you don't specifically need to write a script but it would be ok with an executable I'd look at using VB.Net instead, where you have a good development environment that makes everything much easier since you have Intellisense and you can just press F1 for the documentation. And since it's a typed language with a large framework it gets easier to avoid mistakes and many operations you need you can just call a method in the framework rather than writing your own code.
However, if you do need to do it in VBScript, I'd suggest trying to find some kind of IDE for it. I haven't used any, but at least this one seems worth looking at.
The language of VBScript is relatively easy. It's a subset of Visual Basic and VBA and simplifies some things from those environments (eg you don't need to declare variable types).
What you are dealing with above is working with the methods and properties of a given object, WshShell. There are many many objects out there, each with their own set of methods and properties to know about, many with common usage conventions, and many more with "unique" (ie idiosyncratic) usage requirements. This is where the complexity comes in, but it's not part of VBScript itself. You will run into this with any other language (JScript, Python, Delphi) that works with the myriad objects and APIs that are out there for Windows system management.
The plus side is that once you get used to the language of VBScript and the process of looking up object API references and examples on MSDN and other sites, it does become very easy to put together complicated and powerful scripts.
Like I frequently tell users, computers often make things faster the second time you do something. The first time usually requires some learning.
A great set of resources for learning VBScript and how you need to approach things is the
TechNet Script Center, their Hey, Scripting Guy! series, and the Script Repository.
Using visual basic in say Excel, I am able to declare WinAPI functions using the DECLARE keyword - e.g.
Declare Function SetLocaleInfo Lib "kernel32" Alias "SetLocaleInfoA" ( _
ByVal Locale As Long,
ByVal LCType As Long,
ByVal lpLCData As String
) As Boolean
However when using this syntax in a *.VBS file - it fails with a compile error.
Can anyone tell me what I need to do to run WinAPI functions from *.VBS files?
You can't run WinAPI functions from VBScript without some extra third-party support.
I believe there used to be vendor of a COM component which allowed VBScript to call into a standard dll but I can't remember what it was called and its quite possible that my imagination is playing tricks on me.
Plenty of forum posts mention 'dynacall' as the wrapper I think you're talking about however the two main links they post seem defunct
For what it's worth HTA may be worth looking at as an easy to use substitute
http://www.microsoft.com/downloads/en/details.aspx?FamilyId=231D8143-F21B-4707-B583-AE7B9152E6D9&displaylang=en
This is somewhat related to my other question.
I've been using a dll to acompany an excel spreadsheet. Everything is currently working with the dll and excel is using it just fine. But is it possible to specify that a dll resides in the same directory as the excel file when declaring functions?
Declare Sub FortranCall Lib "Fcall.dll" (r1 As Long, ByVal num As String)
Unfortunetly this doesn't work, I have to use something like:
Declare Sub FortranCall Lib "C:\temp\Fcall.dll" (r1 As Long, ByVal num As String)
This works, but is going to cause headaches when distributing to my office mates. Placing the dll in c:\windows\system32 etc. is not really an option either.
Here are three possibilities for dynamically loading/calling into DLLs from VBA, including links to relevant info and some sample code. Can't say I've ever had to use any of the solutions described there, but it seems like a reasonable exploration of the options in light of VBA's need for a static path.
Create a new module at runtime (you could import a .bas file from disk, no need to hard-code the module with string literals), using the VBIDE Extensibility API. Drawback: no compile-time validation; you'll need to use stringly-typed Application.Run calls to invoke it. Requires trusted programmatic access to the VBIDE API (i.e. you allow VBA to execute code that generates code that is then executed... like macro viruses do).
Use the LoadLibrary Win32 API... and now you've got pointers and addresses: this scary code (.zip download) is essentially a huge unmaintainable hack that uses assembly language to enable invoking the API functions by name. Looks like it only works for a subset of supported Win32 API functions though.
Change the DLL search path, but then that also requires dynamic code added at run-time, so might as well go with the above.
Here's another potential solution that suggests programmatically updating the PATH environment variable prior to calling into your DLL. Not a bad idea, if it works, as you could add this to you workbook open event.
Good luck!
The way I generally take care of this is by adding:
Dim CurrentPath As String
CurrentPath = CurDir()
ChDir (ThisWorkbook.Path)
To: Private Sub Workbook_Open()
ChDir() should do the trick. It might not work on network folders though.
Declare Sub FortranCall Lib "Fcall.dll" (r1 As Long, ByVal num As String)
...
Dim CurrentPath As String
CurrentPath = CurDir()
ChDir (ThisWorkbook.Path)
Call FortranCall(r, n)
ChDir (CurrentPath) ' Change back to original directory
Now keep your .dll in the same folder as your workbook.
You can put the DLL in some directory and add it to the path EnVar.
ActiveWorkbook.Path gives you the full path to the folder containing the currently-active workbook. So try this:
Declare Sub FortranCall Lib ActiveWorkbook.Path & "\Fcall.dll" (r1 As Long, ByVal num As String)