Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sending hotkeys via SendMessage

Status
Not open for further replies.

Sweetve13

MIS
May 25, 2006
5
US
I need some guidance! I'm using sendmessage to send keystrokes to another application that is not active. This part works just great. But I am not able to send hotkeys. Say for example. I'm sending keystrokes to notepad and I want the date. One can do this by clicking Edit>Time/Date or sending Alt then E then D. How could I achieve this? Thanks!

p.s. I've tried using WM_KEYDOWN, WM_KEYUP, WM_COMMAND to no avail. I'm sent the commands both to the handle for the specific control and the application itself (hwnd and x) and still no success.

This is what I'm using to send the keys so far (sending keys works, just not hotkeys):

Code:VB.net:
--------------------------------------------------------------------------------
Private Declare Ansi Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
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
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer

Public Const WM_CHAR = &H102

System.Diagnostics.Process.Start("C:WINNTsystem32notepad.exe")
Dim hwnd As Integer = FindWindow(vbNullString, "Untitled - NotePad")
Dim x As Integer = FindWindowEx(hwnd, 0, "Edit", vbNullString)
SendMessage(x, WM_CHAR, Keys.C, 0)
SendMessage(x, WM_CHAR, Keys.L, 0)
 
Hi
It seems logical what you are doing but
you are on the wrong path.

In order to do this sucessfully you need to

1) Avoid a FORMS VB.NET application
use Module
sub main()
end sub
end Module

If U dont do this VB.net will screw up at runtime
with an exception with SetWindowText()

How to send a 'keystroke' chg text

1. Identify the app you want to mess with
2. Use SPY and observe the PARENT window or
drill down the CHILD window and SPY the
messages to that window

3. Filter to only allow
WM_LBUTTONDOWN (left mousedown)
WM_LBUTTONUP

4. Note down the 2 parameters , these are
the X,Y coordinates relative to the window

5. USE POSTMESSAGE to send them.

eg:
PostMessage(syslistview, WM_LBUTTONDOWN, 1,&H70032 )
PostMessage(syslistview, WM_LBUTTONUP, 0, &H70032)

If you DONT use postmessage , the VB.net DEBUGGER will
hold up the sendmessage() and you will stumped.

6. If you wish to change the text, use
SetWindowText(hwnd, "the text") to change the text
of the edit control.

use
GetWindow() with ,GW_HWNDNEXT,GW_CHILD to move up
and down the parent tree of the application with
the parent handle you got with findwindow()

Aprivate



 
To send hot keys you get the application
or the window in FOCUS by using
Setforegroundwindow and Setfocus then
use the KEYBD_EVENT function to send your
key.

This is the Lowest level function and it
is called when you press the letters on the
keyboard.

Aprivate
 
Just a correction to my comment:
To use POSTMESSAGE/Setwindow text in a forms
application, I found that if I wrap
the functions in a separate class file
and I call it using my own function in
the class, it works.

 
So is there no way to send a hotkey command while the window is NOT in focus? Application will be running in the background (user logged out) so I can't bring the application forward and use sendkeys nor keybd_event. I basically just need a way to click on say File>Open while the application is NOT in focus.

I'll try the other suggestions. Thanks.
 
Yes You can send the WM_LBUTTONDOWN postmessages
to do the File Open.

If the application is running under a LOCKED
windows screen , you MAY be able to do it.

There are other VB commands like app.activate("window name") that you can use and also the SENDKEYS command.

For the logged out test::
Just keybd_event() that on notepad.exe with a locked windows screen , open some file , then play a .wav file to
ensure you know its finished. Log back on and check
to see if it works.

If it does not, the only way is to use the WM_LBUTTONDOWN postmessages.

Please add a few DOEVENTS and thread.sleeps(500) to
ensure that the windows system has time to process
the request. Some PCs are very slow or busy processing
something else.
Aprivate

 
You May want to monitor the window of the
application with SPY on the following
messages.

WM_KEYDOWN
WM_KEYUP
Post this message to the target window with
allthe same parameters copied when you spy on
it. I think this should work..

It is the equilvalent to the mouse message
that would work.

WM_CHAR is only a notification message and the
window may not respond to it.. However you
can try, ensure that you copy the same parameters
found by SPY to the window.

I have written mostly mouse control apps in VB and C++ to
control other applications on the PocketPC and
Win32.. They work.

Aprivate
 
Thanks for the tips. I wasn't able to get the WM_KEYDOWN/WM_KEYUP but found another way. I was able to get the handle of the menu item and click down that way using GetMenu, GetSubMenu, GetMenuItemID. Here's the code for those struggling with this as well (Notepad is sample app. Code assumes it to be running):


Code:
Private Declare Ansi Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
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
Private Declare Function GetMenu Lib "user32" Alias "GetMenu" (ByVal hwnd As Integer) As Integer
Private Declare Function GetSubMenu Lib "user32" Alias "GetSubMenu" (ByVal hMenu As Integer, ByVal nPos As Integer) As Integer
Private Declare Function GetMenuItemID Lib "user32" Alias "GetMenuItemID" (ByVal hMenu As Integer, ByVal nPos As Integer) As Integer

Private Const WM_COMMAND = &H111

Dim hwnd, hWndMenu, hWndSubMenu, MenuItem As Integer
hwnd = FindWindow(vbNullString, "Untitled - Notepad")
hWndMenu = GetMenu(hwnd)                    ' Get handle to Menu Items
hWndSubMenu = GetSubMenu(hWndMenu, 0)      ' Get handle to ‘File’ submenu
MenuItem = GetMenuItemID(hWndSubMenu, 1)    ' Get menuID for the ‘Open’
SendMessage(hwnd, WM_COMMAND, MenuItem, vbNullString)     ' Click ‘Open’ menuitem
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top