im a complet noob in vb . i have been trying to figure out how to send keystrokes back to my own application , while minimized/ Or focused on an other window.
i think i need to use PostMessageA . i read about it on forums. But its like chinese for me.
my goal is to run these little programs by the 100's on 1 pc. and they just press a key in their own application , over and over.
can someone help me out please.
thanks
i was thinking something like this
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_CHAR As Long = &H102
PostMessage("notepad", WM_CHAR, "T", 1)
as a test. what am i doing wrong
A few things, for one you have found your code in a VB6 Forum. The size of integers has changed since then. A Long in VB6 is equivalant to an Integer in VB.Net(see this Msdn link). The second issue is that you are supplying a String to PostMessage where it is expecting the handle to your window. I would suggest that you look at this CodeProject article about how to Send strings to another application by using Windows messages
Your PostMessage declaration should look like this.
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Related
From VB .Net, I'm trying to send a string to a textbox of another application but I cannot make it work. I'm able to get the handle and even set the focus to the textbox but my SendMessage function doesn't seem to be correct as I get the error message "SendMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."
Here is my code:
Module Module1
Private Const WM_SETTEXT As Int32 = &HC
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long
Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function FindWindowEx Lib "user32" (ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As IntPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As IntPtr
Sub Main()
Dim AppHwnd As IntPtr = FindWindow(vbNullString, "Test Application"
Dim WinHwnd1 As IntPtr = FindWindowEx(AppHwnd, 0&, "SWT_Window0", vbNullString)
Dim WinHwnd2 As IntPtr = FindWindowEx(WinHwnd1, 0&, "SWT_Window0", vbNullString)
Dim WinHwnd3 As IntPtr = FindWindowEx(WinHwnd2, 0&, "SWT_Window0", vbNullString)
Dim TextBoxHwnd1 As IntPtr = FindWindowEx(WinHwnd3, 0&, "Edit", vbNullString)
Dim TextBoxHwnd2 As IntPtr = FindWindowEx(WinHwnd3, TextBoxHwnd1, "Edit", vbNullString)
MsgBox(TextBoxHwnd2)
SetForegroundWindow(TextBoxHwnd2)
SendMessage(TextBoxHwnd2, WM_SETTEXT, 0&, "text")
End Sub
End Module
The line "MsgBox(TextBoxHwnd2)" returns the handle number I found using Window Detective so I'm assuming the code is correct up to this point. Also, I tested "SetForegroundWindow(TextBoxHwnd1)" and the cursor is on the first textbox whereas "SetForegroundWindow(TextBoxHwnd1) sets the cursor on the second textbox.
Your declaration looks like it might have been migrated from legacy VB code, where Long was a 32-bit integer and Integer was only 16-bit (dating to legacy VB's origination in 16-bit Windows). The length of the data types changed in .NET which was created after the shift to universal 32-bit Windows, so Integer is 32-bit and Long is 64-bit.
Moreover, the Windows API itself needed to be updated for 64-bit Windows. SendMessage is one of the functions that has some parameters that are longer in 64-bit because they are expected to hold pointers.
I checked on the native header file declaration of SendMessage and found that:
The parameter Msg is declared as UINT which would correspond to Integer in VB. This needs to be changed regardless of whether you have a 32-bit or 64-bit build.
The parameter wParam is declared as UINT_PTR so it should in fact be Long for a 64-bit build, but Integer for a 32-bit build; if it's possible to declare it as IntPtr and then pass 0 to it, that would probably be best, because it should automatically adjust the length depending on whether you're building for 32-bit or 64-bit.
I'm trying to make a Net IME keyboard application. This app will suggest me relevant topics when typing or searching. But I can't get the location of an active textbox control from other applications.
The FindWindowEx function works though, but I'm looking for the location of an active textbox so i can change the location of the suggestion control to that textbox. Thanks!
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String,
ByVal lpsz2 As String) As Integer
We have been using MS Access database (Office 2007, 32bit) in Windows 7 for a long time but recently we switched into Office 2016, 64 bit.
Now every form is displaying the following message and it's really irritating:
Moreover, the Access window is not getting minimized. I'm not an expert in VBA and don't know what to do. I'm pasting the codes. Please don't suggest any article or documentation provided by Microsoft. I have tried to understand those a lot and failed.
The code being used is:
Option Compare Database
Private Declare Function SetWindowPos Lib "user32.dll" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
And:
Private Sub Form_Load()
Application.RunCommand (acCmdAppRestore)
SetWindowPos Application.hWndAccessApp, 0, 0, 0, 0, 0, 0
Application.DoCmd.MoveSize 0, 0
End Sub
Previously (in 32-bit office) the Access window used to be hidden on form load but now in 64-bit it's wide open. Please help me to hide the MS Access window in 64-bit version.
Upgrading companies software without extensive test is amateurish!
But if that error message is the only problem you are lucky. You need to convert the api arguments declaration to x64, what usually means change allLongdeclarations of handles and pointers to LongPtrand add PtrSafe after Declare.
With the conditional compiler (#If VBA7 Then) Office 2010 and later use the first part, as they support VBA7 (LongPtr), Office 2007 and earlier use the else part with the old declaration.
#If VBA7 Then
Private Declare PtrSafe Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As LongPtr, ByVal hWndInsertAfter As LongPtr, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
#Else
Private Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
#End If
This can be found at Declaring API Functions In 64 Bit Office.
Seems like you do not use x86 ActiveX controls or ODBC connections, because they cause trouble too.
You should read the Compatibility Inspector user's guide to get prepared for more trouble;)
I agree with ComputerVersteher for the first part, so I'll address the second part of your question. You can make the form invisible by doing this:
Private Sub Form_Load()
'this turns the forms timer event on every 1 milisecond
Me.TimerInterval = 1
End Sub
Private Sub Form_Timer()
Me.Visible = False
'this turns the timer event off so you don't waste CPU power
Me.TimerInterval = 0
End Sub
Hey all, i am trying to send some text to a console box (dos box) from my vb program but i can not seem to get it working.
Here is my current code:
Dim blah As Long
Private Const WM_GETTEXT As Integer = &HD
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
blah = FindWindow1(vbNullString, "Form1")
blah = FindWindowEx(blah, vbNullString, "ConsoleWindowClass", vbNullString)
Debug.Print(blah)
SendMessage(blah, WM_SETTEXT, 200, "A")
Though that does work, it only puts a A for the title bar and not within the console.
Any help would be great! :o)
David
I've not tried it but I think you might want to look at AttachConsole to attach your process to the console of the command line process. Then you should be able to use the Console.WriteLine and similar methods I'd assume.
You can find a sample (in C#, but should be easy to convert to VB using one of the online converters) on the PInvoke page.
I have developed some code which creates excel macros and each time after creation of new macro I want to digitally sign the macro programmatically. Can you let me know if there is any way using which I can create new digital certificates and assign those to macro programmatically. Thanks.
It is not possible to do this with VBA code. I think the best you could hope to do it would be by making Win32 API calls to simulate all the needed steps to make this happen. It would be sloppy but you could make it work. Basically, you would have open the needed windows and applications leveraging shortcut keys on the keyboard and for selecting the correct certs.
Some example code would be
Public Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Sub SetFocusFormulaBar()
SetFocus FindWindowEx(FindWindow("XLMAIN", Application.Caption), _
0&, "EXCEL<", vbNullString)
End Sub
http://www.cpearson.com/excel/FormulaBarShortcut.htm