Declare Function Excel Vba using shell32.dll - shell

Can someone tell me what is going on with the code below:
'Variables at top of module or some function/sub here
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
'some function or sub routine here
This code shows the position of the function declare. I am not familiar with what the declare keyword is doing, nor do i understand why this is not compiling.
I got this when I was looking up ways to open tabs in internet explorer through vba, but I can't seem to get it to work.
It seems as though the compiler does not recognize this as a function, but I have seen several forum posts that use this code without it having any problems (this one included).
It seems as though I may be missing a reference, or possibly the dll, but i don't see the library as a reference in the tools menu, and i don't know how to check if i have this on my machine.
If someone could point me in the right direction that would be great.

An API declaration is like a regular variable declaration: it must be at the top of the module, before any Subs/Functions.

Related

Generate .REG file from within VB6 app?

Is it possible to export a branch of the registry and generate a .REG file from within a VB6 app?
The pages Michael linked to in the comments are certainly useful and informative regarding general registry access techniques from VB 6, but they don't really answer your question.
What you want is the Win32 RegSaveKeyEx function, which will save the information from the specified registry key out to a file. Presumably, this is the same function used by the Registry Editor utility to export the selected key to a .reg file.
To call this function from VB 6, all you need to do is add a declaration to your project:
Public Declare Function RegSaveKeyEx Lib "advapi32.dll" Alias "RegSaveKeyExA" ( _
ByVal hKey As Long, _
ByVal lpFile As String, _
ByRef lpSecurityAttributes As Any, _
ByVal flags As Long) As Long

VB6 dll call to win32 C function

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

VB Script Set Cursor position

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 & ")"

Import WinAPI Function in *.VBS File

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

How to use dll's in the same directory as an excel file

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)

Resources