i want to check if the active window handle is password box.
this function returns me the active control handle of the active window:
Imports System.Runtime.InteropServices
Public Class FormMain
Inherits Form
Private Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal ProcessId As IntPtr) As IntPtr
Private Declare Function AttachThreadInput Lib "user32.dll" (ByVal idAttach As IntPtr, ByVal idAttachTo As IntPtr, ByVal fAttach As Boolean) As IntPtr
Private Declare Function GetFocus Lib "user32.dll" () As IntPtr
Public Sub New()
MyBase.New
InitializeComponent
End Sub
Private Sub timerUpdate_Tick(ByVal sender As Object, ByVal e As EventArgs)
labelHandle.Text = ("hWnd: " + FocusedControlInActiveWindow.ToString)
End Sub
Private Function FocusedControlInActiveWindow() As IntPtr
Dim activeWindowHandle As IntPtr = GetForegroundWindow
Dim activeWindowThread As IntPtr = GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero)
Dim thisWindowThread As IntPtr = GetWindowThreadProcessId(Me.Handle, IntPtr.Zero)
AttachThreadInput(activeWindowThread, thisWindowThread, true)
Dim focusedControlHandle As IntPtr = GetFocus
AttachThreadInput(activeWindowThread, thisWindowThread, false)
Return focusedControlHandle
End Function
End Class
now i want to do something like:
if FocusedControlInActiveWindow() <> intptr.zero then
dim IsPass as boolean = isPassword(FocusedControlInActiveWindow())
if IsPass then
msgbox("yes")
else
msgbox ("no")
end if
end if
how can i check if the foucsed control in the active window text is passwordcahr?
If you want to check if a Windows Edit Control has the ES_PASSWORD style, this is how to do it:
Public Shared Function HasPasswordStyle(ByVal hWnd As IntPtr) As Boolean
Return ((GetWindowLong(hWnd, GWL_STYLE) And ES_PASSWORD) <> 0)
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
End Function
Private Const ES_PASSWORD As Integer = 32
Private Const GWL_STYLE As Integer = -16
Related
I use the code down below to start an application and move it into a Panel on my Form. In this example I use Notepad, only as an example. Later I will use a different application.
When another application is moved in front of my Form, I can only move my Form to the foreground by clicking the title bar. If I click on the MDI child area (so the Panel where Notepad is moved into), nothing happens.
Is there a way to enable that?
Imports System.Runtime.InteropServices
Public Class Form1
Declare Auto Function SetParent Lib "user32.dll" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As Integer
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim proc As Process
proc = Process.Start("notepad.exe")
proc.WaitForInputIdle()
SetParent(proc.MainWindowHandle, Me.Panel1.Handle)
SendMessage(proc.MainWindowHandle, 274, 61488, 0)
End Sub
End Class
The problem is that a hosted (re-parented) Window, when activated, doesn't cause the hosing Form to also activate, so it's brought to the foreground.
The hosted Window is not exactly a child Window and the hosting Form doesn't receive any message from it.
A possible method to bring to the foreground the Form that hosts a foreign Window, when this Window receives the focus (you click or otherwise activate it)
It uses SetWinEventHook to install a Hook that monitors changes in state of the placement of a Window (EVENT_SYSTEM_FOREGROUND).
You specify the handle of the Window of interests, (your proc.MainWindowHandle here), plus its ProcessId and ThreadId. Note that these are not the same as your app's, a call to GetWindowThreadProcessId() is required to get this information.
When you activate the foreign Window, the Hooks calls the specified callback delegate (here, ForegrundChangedEventDelegate), which in turn executes the method that it points to (ForegroundStateChangedCallback)
When this method is called, it checks whether the object that caused the notification is OBJID_WINDOW and that the event is actually EVENT_SYSTEM_FOREGROUND. If that's the case, it calls SetWindowPos to bring the hosting Form to the foreground, but without activating it, so the hosted Window doesn't lose focus
Notes:
The SetWinEvetHook delegate is created in the Constructor (Sub New()) of the parent Form, along with a GC SafeHandle that is used to prevent the delegate from being garbage-collected at the wrong time.
It's released in the OnHandleDestroyed() override, where also the hook proc is un-hooked
see the imports statement in the Form:
Imports [Your App Namespace].NativeMethods
this means that you have to specify the namespace of your app for the import to work as intended. In VB.Net, usually the name of the app and its main NameSpace match; if your app is named, WinFormsApp1, then its Imports WinFormsApp1.NativeMethods
To activate the Hook, as soon as you have changed the Parent of that Window, use its handle to call the SetForegroundStateChangedHook() method. That's all.
When the Form closes, the hook is released
I suggest using the code in Unhook Window into its original State to set the Parent (and, possibly, set it back to the original value before closing the hosting form). You can send WM_CLOSE to the Window if needed.
Imports [Your App Namespace].NativeMethods
Public Class SomeForm
Private hForegrundChangedEventHook As IntPtr
Private ReadOnly ForegrundChangedEventDelegate As WinEventDelegate
Private Shared GCForegroundStateSafetyHandle As GCHandle
Public Sub New()
InitializeComponent()
ForegrundChangedEventDelegate = New WinEventDelegate(AddressOf ForegroundStateChangedCallback)
GCForegroundStateSafetyHandle = GCHandle.Alloc(ForegrundChangedEventDelegate)
End Sub
Protected Overrides Sub OnHandleDestroyed(e As EventArgs)
GCForegroundStateSafetyHandle.Free()
UnhookWinEvent(hForegrundChangedEventHook)
MyBase.OnHandleDestroyed(e)
End Sub
Private Sub SetForegroundStateChangedHook(hWnd As IntPtr)
Dim processId As UInteger
Dim targetThreadId = GetWindowThread(hWnd, processId)
hForegrundChangedEventHook = WinEventHookOne(SWEH_Events.EVENT_SYSTEM_FOREGROUND, ForegrundChangedEventDelegate, processId, targetThreadId)
End Sub
Friend Sub ForegroundStateChangedCallback(hWinEventHook As IntPtr, eventType As SWEH_Events, hWnd As IntPtr, idObject As SWEH_ObjectId, idChild As Long, dwEventThread As UInteger, dwmsEventTime As UInteger)
If idObject = SWEH_ObjectId.OBJID_WINDOW AndAlso eventType = SWEH_Events.EVENT_SYSTEM_FOREGROUND Then
Dim flags = SWP_Flags.SWP_ASYNCWINDOWPOS Or SWP_Flags.SWP_NOACTIVATE Or SWP_Flags.SWP_NOSIZE Or SWP_Flags.SWP_NOMOVE
SetWindowPos(Handle, IntPtr.Zero, 0, 0, 0, 0, flags)
End If
End Sub
End Class
NativeMethods class
Add this class to the Project and import in your Form as described
Imports System.Runtime.InteropServices
Public Class NativeMethods
<DllImport("user32.dll", SetLastError:=True)>
Friend Shared Function GetWindowThreadProcessId(hWnd As IntPtr, ByRef lpdwProcessId As UInteger) As UInteger
End Function
<DllImport("user32.dll", SetLastError:=True)>
Friend Shared Function SetWindowPos(hWnd As IntPtr, hWndInsertAfter As IntPtr, x As Integer, y As Integer, cx As Integer, cy As Integer, uFlags As SWP_Flags) As Boolean
End Function
Friend Delegate Sub WinEventDelegate(
hWinEventHook As IntPtr,
eventType As SWEH_Events,
hwnd As IntPtr, idObject As SWEH_ObjectId,
idChild As Long,
dwEventThread As UInteger,
dwmsEventTime As UInteger)
<DllImport("user32.dll", SetLastError:=False)>
Friend Shared Function SetWinEventHook(
eventMin As SWEH_Events,
eventMax As SWEH_Events,
hmodWinEventProc As IntPtr,
lpfnWinEventProc As WinEventDelegate,
idProcess As UInteger,
idThread As UInteger,
dwFlags As SWEH_dwFlags) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=False)>
Friend Shared Function UnhookWinEvent(hWinEventHook As IntPtr) As Boolean
End Function
Friend Shared WinEventHookInternalFlags As SWEH_dwFlags =
SWEH_dwFlags.WINEVENT_OUTOFCONTEXT Or SWEH_dwFlags.WINEVENT_SKIPOWNPROCESS
Friend Shared Function WinEventHookOne(evt As SWEH_Events, weDelegate As WinEventDelegate, idProcess As UInteger, idThread As UInteger) As IntPtr
Return SetWinEventHook(evt, evt, IntPtr.Zero, weDelegate, idProcess, idThread, WinEventHookInternalFlags)
End Function
Friend Shared Function GetWindowThread(hWnd As IntPtr, ByRef processID As UInteger) As UInteger
processID = 0
Return GetWindowThreadProcessId(hWnd, processID)
End Function
' SetWinEventHook Events
Friend Enum SWEH_Events As UInteger
EVENT_MIN = &H1
EVENT_MAX = &H7FFFFFFF
EVENT_SYSTEM_SOUND = &H1
EVENT_SYSTEM_ALERT = &H2
EVENT_SYSTEM_FOREGROUND = &H3
EVENT_SYSTEM_MENUSTART = &H4
EVENT_SYSTEM_MENUEND = &H5
EVENT_SYSTEM_MENUPOPUPSTART = &H6
EVENT_SYSTEM_MENUPOPUPEND = &H7
EVENT_SYSTEM_CAPTURESTART = &H8
EVENT_SYSTEM_CAPTUREEND = &H9
EVENT_SYSTEM_MOVESIZESTART = &HA
EVENT_SYSTEM_MOVESIZEEND = &HB
EVENT_SYSTEM_CONTEXTHELPSTART = &HC
EVENT_SYSTEM_CONTEXTHELPEND = &HD
EVENT_SYSTEM_DRAGDROPSTART = &HE
EVENT_SYSTEM_DRAGDROPEND = &HF
EVENT_SYSTEM_DIALOGSTART = &H10
EVENT_SYSTEM_DIALOGEND = &H11
EVENT_SYSTEM_SCROLLINGSTART = &H12
EVENT_SYSTEM_SCROLLINGEND = &H13
EVENT_SYSTEM_SWITCHSTART = &H14
EVENT_SYSTEM_SWITCHEND = &H15
EVENT_SYSTEM_MINIMIZESTART = &H16
EVENT_SYSTEM_MINIMIZEEND = &H17
EVENT_SYSTEM_DESKTOPSWITCH = &H20
EVENT_SYSTEM_END = &HFF
EVENT_OEM_DEFINED_START = &H101
EVENT_OEM_DEFINED_END = &H1FF
EVENT_UIA_EVENTID_START = &H4E00
EVENT_UIA_EVENTID_END = &H4EFF
EVENT_UIA_PROPID_START = &H7500
EVENT_UIA_PROPID_END = &H75FF
EVENT_CONSOLE_CARET = &H4001
EVENT_CONSOLE_UPDATE_REGION = &H4002
EVENT_CONSOLE_UPDATE_SIMPLE = &H4003
EVENT_CONSOLE_UPDATE_SCROLL = &H4004
EVENT_CONSOLE_LAYOUT = &H4005
EVENT_CONSOLE_START_APPLICATION = &H4006
EVENT_CONSOLE_END_APPLICATION = &H4007
EVENT_CONSOLE_END = &H40FF
EVENT_OBJECT_CREATE = &H8000
EVENT_OBJECT_DESTROY = &H8001
EVENT_OBJECT_SHOW = &H8002
EVENT_OBJECT_HIDE = &H8003
EVENT_OBJECT_REORDER = &H8004
EVENT_OBJECT_FOCUS = &H8005
EVENT_OBJECT_SELECTION = &H8006
EVENT_OBJECT_SELECTIONADD = &H8007
EVENT_OBJECT_SELECTIONREMOVE = &H8008
EVENT_OBJECT_SELECTIONWITHIN = &H8009
EVENT_OBJECT_STATECHANGE = &H800A
EVENT_OBJECT_LOCATIONCHANGE = &H800B
EVENT_OBJECT_NAMECHANGE = &H800C
EVENT_OBJECT_DESCRIPTIONCHANGE = &H800D
EVENT_OBJECT_VALUECHANGE = &H800E
EVENT_OBJECT_PARENTCHANGE = &H800F
EVENT_OBJECT_HELPCHANGE = &H8010
EVENT_OBJECT_DEFACTIONCHANGE = &H8011
EVENT_OBJECT_ACCELERATORCHANGE = &H8012
EVENT_OBJECT_INVOKED = &H8013
EVENT_OBJECT_TEXTSELECTIONCHANGED = &H8014
EVENT_OBJECT_CONTENTSCROLLED = &H8015
EVENT_SYSTEM_ARRANGMENTPREVIEW = &H8016
EVENT_OBJECT_END = &H80FF
EVENT_AIA_START = &HA000
EVENT_AIA_END = &HAFFF
End Enum
' SetWinEventHook Window Objects
Friend Enum SWEH_ObjectId As Long
OBJID_WINDOW = &H0
OBJID_SYSMENU = &HFFFFFFFFUI
OBJID_TITLEBAR = &HFFFFFFFEUI
OBJID_MENU = &HFFFFFFFDUI
OBJID_CLIENT = &HFFFFFFFCUI
OBJID_VSCROLL = &HFFFFFFFBUI
OBJID_HSCROLL = &HFFFFFFFAUI
OBJID_SIZEGRIP = &HFFFFFFF9UI
OBJID_CARET = &HFFFFFFF8UI
OBJID_CURSOR = &HFFFFFFF7UI
OBJID_ALERT = &HFFFFFFF6UI
OBJID_SOUND = &HFFFFFFF5UI
OBJID_QUERYCLASSNAMEIDX = &HFFFFFFF4UI
OBJID_NATIVEOM = &HFFFFFFF0UI
End Enum
' WinEventDelegate flags
Friend Enum SWEH_dwFlags As UInteger
WINEVENT_OUTOFCONTEXT = &H0 ' Events are ASYNC - No dll needed
WINEVENT_SKIPOWNTHREAD = &H1 ' Don't call back for events on installer's thread
WINEVENT_SKIPOWNPROCESS = &H2 ' Don't call back for events on installer's process
WINEVENT_INCONTEXT = &H4 ' Events are SYNC, this causes your dll to be injected into every process
End Enum
' SetWindowPos flags
<Flags>
Public Enum SWP_Flags As UInteger
SWP_NOSIZE = &H1
SWP_NOMOVE = &H2
SWP_NOZORDER = &H4
SWP_NOREDRAW = &H8
SWP_NOACTIVATE = &H10
SWP_DRAWFRAME = &H20
SWP_FRAMECHANGED = &H20
SWP_SHOWWINDOW = &H40
SWP_HIDEWINDOW = &H80
SWP_NOCOPYBITS = &H100
SWP_NOOWNERZORDER = &H200
SWP_NOREPOSITION = &H200
SWP_NOSENDCHANGING = &H400
SWP_NOCLIENTSIZE = &H800
SWP_NOCLIENTMOVE = &H1000
SWP_DEFERERASE = &H2000
SWP_ASYNCWINDOWPOS = &H4000
End Enum
End Class
Thanks to the great help of Jimi, I was able to get it work:
Add the NativeMethods class to the project, use the code from Jimi's answer above
Use the following code in the form:
Imports System.Runtime.InteropServices
Imports WindowsApp1.NativeMethods
Public Class Form1
Private ReadOnly ForegrundChangedEventDelegate As WinEventDelegate
Private Shared GCForegroundStateSafetyHandle As GCHandle
Declare Auto Function SetParent Lib "user32.dll" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As Integer
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Declare Auto Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim proc As Process
Dim ProcId As Integer = 0
proc = Process.Start("notepad.exe")
proc.WaitForInputIdle()
SetParent(proc.MainWindowHandle, Me.Panel1.Handle)
SendMessage(proc.MainWindowHandle, 274, 61488, 0)
GetWindowThreadProcessId(proc.MainWindowHandle, ProcId)
SetForegroundStateChangedHook(proc.MainWindowHandle)
End Sub
Public Sub New()
InitializeComponent()
ForegrundChangedEventDelegate = New WinEventDelegate(AddressOf ForegroundStateChangedCallback)
GCForegroundStateSafetyHandle = GCHandle.Alloc(ForegrundChangedEventDelegate)
End Sub
Protected Overrides Sub OnHandleDestroyed(e As EventArgs)
GCForegroundStateSafetyHandle.Free()
UnhookWinEvent(hForegrundChangedEventHook)
MyBase.OnHandleDestroyed(e)
End Sub
Private Sub SetForegroundStateChangedHook(hWnd As IntPtr)
Dim processId As UInteger
Dim targetThreadId = GetWindowThread(hWnd, processId)
hForegrundChangedEventHook = WinEventHookOne(SWEH_Events.EVENT_SYSTEM_FOREGROUND, ForegrundChangedEventDelegate, processId, targetThreadId)
End Sub
Friend Sub ForegroundStateChangedCallback(hWinEventHook As IntPtr, eventType As SWEH_Events, hWnd As IntPtr, idObject As SWEH_ObjectId, idChild As Long, dwEventThread As UInteger, dwmsEventTime As UInteger)
If idObject = SWEH_ObjectId.OBJID_WINDOW AndAlso eventType = SWEH_Events.EVENT_SYSTEM_FOREGROUND Then
Dim flags = SWP_Flags.SWP_ASYNCWINDOWPOS Or SWP_Flags.SWP_NOACTIVATE Or SWP_Flags.SWP_NOSIZE Or SWP_Flags.SWP_NOMOVE
SetWindowPos(Handle, IntPtr.Zero, 0, 0, 0, 0, flags)
End If
End Sub
End Class
This question is basically regarding to loop all workbooks in all excel instances!
Your main issue you are facing is you are not using any of the process's you come across. Therefore, you will not get anything that way. Inside of the loop for the process's you then create a new instance of ExcelApplication and then try to loop through the Workbooks. By default when you do this there is only 1 at that time, hence why you get only 1 Workbook and also why you will only ever see 1 Workbook.
Solution (Tried & Tested)
You need to look into Windows API calls to get what you need. A few of them are:
GetDesktopWindow()
EnumChildWindows()
GetClassName()
EnumWindowsProc()
AccessibleObjectFromWindow()
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function GetDesktopWindow Lib "user32" () As Integer
Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer
Private Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" (ByVal Hwnd As Int32, ByVal dwId As Int32, ByRef riid As Guid, <MarshalAs(UnmanagedType.IUnknown)> ByRef ppvObject As Object) As Int32
Private Const OBJID_NATIVE = &HFFFFFFF0
'Required to show the workbooks. Used in function to add to.
Private lstWorkBooks As New List(Of String)
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
lstWorkBooks.Clear()
GetExcelOpenWorkBooks()
End Sub
Private Sub GetExcelOpenWorkBooks()
Try
'Get handle to desktop
Dim WindowHandle As IntPtr = GetDesktopWindow()
'Enumerate through the windows (objects) that are open
EnumChildWindows(WindowHandle, AddressOf GetExcelWindows, 0)
'List the workbooks out if we have something
If lstWorkBooks.Count > 0 Then MsgBox(String.Join(Environment.NewLine, lstWorkBooks))
Catch ex As Exception
End Try
End Sub
Public Function GetExcelWindows(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
Dim Ret As Integer = 0
Dim className As String = Space(255) 'Return the string with some padding...
Ret = GetClassName(hwnd, className, 255)
className = className.Substring(0, Ret)
If className = "EXCEL7" Then
Dim ExcelApplication As Excel.Application
Dim ExcelObject As Object = Nothing
Dim IDispatch As Guid
AccessibleObjectFromWindow(hwnd, OBJID_NATIVE, IDispatch, ExcelObject)
'Did we get anything?
If ExcelObject IsNot Nothing Then
ExcelApplication = ExcelObject.Application
'Make sure we have the instance...
If ExcelApplication IsNot Nothing Then
'Go through the workbooks...
For Each wrk As Excel.Workbook In ExcelApplication.Workbooks
'If workbook ins't in the list then add it...
If Not lstWorkBooks.Contains(wrk.Name) Then
lstWorkBooks.Add(wrk.Name)
End If
Next
End If
End If
End If
Return True
End Function
End Class
I want to send a leftbutton-mouseclick to a (specific) program but it doesn't work. when i tried my code on several other apps it worked without any major changes.
this is my Declaration:
Public Class Win32
#Region "Methods And Functions Declaration"
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal IpClassName As String, ByVal IpWindowName As String) As Int32
Public Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hwnd As Int32) As Int32
Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Int32, ByVal hWnd2 As Int32, ByVal lpsz1 As String, ByVal lpsz2 As String) As Int32
Public Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As Int32, ByVal lpEnumFunc As Int32, ByVal lParam As Int32) As Int32
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByRef lParam As Int32) As Int32
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByRef lParam As String) As Int32
#End Region
#Region "Messages"
Public Const BM_CLICK As Int32 = &HF5
Public Const WM_NCLBUTTONDOWN As Int32 = &HA1
Public Const WM_NCHITTEST As Int32 = &H84
Public Const WM_NCLBUTTONDBLCLK As Int32 = &HA3
Public Const WM_NCLBUTTONUP As Int32 = &HA2
Public Const WM_SETFOCUS As Long = &H7
Public Const WM_SETTEXT As Long = &HC
Public Const WM_NCRBUTTONDOWN As Int32 = &HA4
#End Region
the actual code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Druck Eingeben
Dim Hwnd As Integer = Win32.FindWindow(Nothing, "V1.22 BMTS Prüfstand 2")
If (Not Hwnd = 0) Then
Dim HwndInfo As Integer = Win32.FindWindowEx(Hwnd, Nothing, "TGroupBox", "Info")
If Not HwndInfo = 0 Then
Dim ccHwnd As Integer = Win32.FindWindowEx(HwndInfo, Nothing, "TPanel", Nothing)
If Not ccHwnd = 0 Then
Dim cccHwnd As Integer = Win32.FindWindowEx(ccHwnd, Nothing, "Tedit", Nothing)
If Not cccHwnd = 0 Then
Win32.SetForegroundWindow(cccHwnd)
SendKeys.Send("990")
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Win32.SetForegroundWindow(HwndInfo)
SendKeys.Send("999")
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
'Startbutton Klicken
Dim HwndFunktion As Integer = Win32.FindWindowEx(Hwnd, Nothing, "TGroupBox", "Funktion")
If Not HwndFunktion = 0 Then
Dim cHwnd As Integer = Win32.FindWindowEx(HwndFunktion, Nothing, "TButton", "S T A R T")
If Not cHwnd = 0 Then
Win32.SetForegroundWindow(cHwnd)
Win32.SendMessage(cHwnd, Win32.WM_SETFOCUS, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_NCLBUTTONDBLCLK, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_NCLBUTTONDBLCLK, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_NCLBUTTONDOWN, 0, 0)
Win32.SendMessage(cHwnd, Win32.WM_SETTEXT, 0, "6")
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
Else
MessageBox.Show("Bitte Starte erst die Programme")
End If
End Sub
To the Program itself: It runs on an old test bench, on win 7.
I think it depends on .net 3.5 but i don't have detailed information about it.
As a test, i filled a textbox with my code and even changed the label of the button. Just the click function doesn't work.
First I tried in with mouse positioning, now directly with the handles.
It doesn't work either way.
Please remember, the code works fine on a few tested Programs (except the one I need it for).
I can't figure out how to make my ComboBox (which lists all open windows(I can see these already)) to make my form type on that selected window. I just can't make it so when screen1 is selected, it clicks on that screen.
Example:
I have 2 different forms open.
Form (1) clicks on a specified screen. (screen1)
Form (2) clicks on a different specified screen. (screen2)
The forms are the same program just opened twice.
I want my form to be able to click on a certain screen even if it's not open.
Imports System.Runtime.InteropServices
Imports System.Diagnostics
Public Class W1
Public Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As Int32) As Int32
Public Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
Public Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Int32) As Int32
Public Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As IntPtr) As Int32
Public Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As IntPtr, ByVal nIndex As Int32) As Int32
Public Declare Function GetParent Lib "user32.dll" (ByVal intptr As IntPtr) As IntPtr
Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
Public Property SelectedItem As Object
Public Const GWL_HWNDPARENT As Int32 = -8
Private newwindowlist As List(Of String)
Private newhandlelist As List(Of IntPtr)
Private Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
Public Sub New(ByVal _left As Integer, ByVal _top As Integer, ByVal _right As Integer, ByVal _bottom As Integer)
left = _left
top = _top
right = _right
bottom = _bottom
End Sub
End Structure
Private Function EnumWinProc(ByVal hwnd As IntPtr, ByVal lParam As Int32) As Boolean
If IsWindowVisible(hwnd) Then
If GetParent(hwnd) = IntPtr.Zero Then
If GetWindowLong(hwnd, GWL_HWNDPARENT) = 0 Then
Dim str As String = String.Empty.PadLeft(GetWindowTextLength(hwnd) + 1)
GetWindowText(hwnd, str, str.Length)
If Not String.IsNullOrEmpty(str.Substring(0, str.Length - 1)) Then
newwindowlist.Add(str.Substring(0, str.Length - 1))
End If
End If
End If
End If
EnumWinProc = True
End Function
Private Sub RefreshWindowList()
newwindowlist = New List(Of String)
EnumWindows(AddressOf EnumWinProc, CInt(True))
End Sub
And
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
RefreshWindowList()
For Each item As String In newwindowlist
ComboBox1.Items.Add(item)
ComboBox1.SelectedItem = Convert.ToInt64(GWL_HWNDPARENT)
Next
End Sub
I am new to VSTO VB.Net programming. and I am developing a word application level Addin and want to trap keypress event. I have tried various codes of hooking but none is working. I want to use application level hook using WH_KEYBOARD instead of WH_KEYBOARD_LL. The following code which I have tried traps just one key stroke after that it stops. Moreover I could not understand where to put trap the keystrokes. How would I use the following for handling key events.
Public Event KeyDown As KeyEventHandler
Public Event KeyPress As KeyPressEventHandler
Public Event KeyUp As KeyEventHandler
The code that I am using is
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class KeyBoardHook
Inherits Component
Dim PredictString As String
#Region " keyboardHook"
Private Declare Auto Function LoadLibrary Lib "kernel32" (ByVal lpFileName As String) As IntPtr
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hhk As IntPtr) As Boolean
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, _
ByVal lpfn As KeyboardProc, ByVal hmod As IntPtr, ByVal dwThreadId As Integer) As IntPtr
Private Delegate Function KeyboardProc(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As IntPtr
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As IntPtr, ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As IntPtr
Private Structure KBDLLHOOKSTRUCT
Public vkCode As Integer
Public scanCode As Integer
Public flags As Integer
Public time As Integer
Public dwExtraInfo As Integer
End Structure
'Keyboard Constants
Private Const HC_ACTION As Integer = 0
Private Const WM_KEYDOWN As Integer = &H100
Private Const WM_KEYUP As Integer = &H101
Private Const WM_SYSKEYDOWN As Integer = &H104
Private Const WM_SYSKEYUP As Integer = &H105
Private Const WH_KEYBOARD As Integer = 2
Public hKeyboardHook As IntPtr
Public Event KeyDown As KeyEventHandler
Public Event KeyPress As KeyPressEventHandler
Public Event KeyUp As KeyEventHandler
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Integer) As Integer
Private Const VK_ALT As Integer = &H12
Private Const VK_CONTROL As Integer = &H11
Private Const VK_SHIFT As Integer = 16
<MarshalAs(UnmanagedType.FunctionPtr)> Private callback As KeyboardProc
Public Sub HookKeyboard()
callback = New KeyboardProc(AddressOf KeyboardCallback)
Dim hInstance As IntPtr = LoadLibrary("User32")
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, callback, hInstance, 0)
CheckHooked()
End Sub
Private Function KeyboardCallback(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As IntPtr
Dim xy As System.Drawing.Point = Cursor.Position()
Try
If (Code = HC_ACTION Or Code = 3) Then
Dim CapsLock As Boolean = GetKeyState(Keys.CapsLock) = 1
Dim shifting As Boolean = False
Dim modifiers As Keys
If GetAsyncKeyState(VK_CONTROL) <> 0 Then
modifiers = modifiers Or Keys.Control
End If
If GetAsyncKeyState(VK_SHIFT) <> 0 Then
modifiers = modifiers Or Keys.Shift
shifting = True
End If
If GetAsyncKeyState(VK_ALT) <> 0 Then
modifiers = modifiers Or Keys.Alt
End If
Static lastKeys As Keys
Select Case wParam
Case WM_KEYDOWN, WM_SYSKEYDOWN
RaiseEvent KeyDown(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
If lastKeys <> (DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers) Then
lastKeys = (DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers)
If CapsLock AndAlso shifting Then
RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToLower(Chr(lParam.vkCode))))
ElseIf Not CapsLock AndAlso shifting Then
RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToUpper(Chr(lParam.vkCode))))
ElseIf Not shifting Then
If CapsLock Then
RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToUpper(Chr(lParam.vkCode))))
Else
RaiseEvent KeyPress(Me, New KeyPressEventArgs(Char.ToLower(Chr(lParam.vkCode))))
End If
End If
End If
Case WM_KEYUP, WM_SYSKEYUP
If CapsLock AndAlso shifting Then
RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
ElseIf Not CapsLock AndAlso shifting Then
RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
ElseIf Not shifting Then
If CapsLock Then
RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
Else
RaiseEvent KeyUp(Me, New KeyEventArgs(DirectCast(Asc(Chr(lParam.vkCode)), Keys) Or modifiers))
End If
End If
lastKeys = Nothing
End Select
End If
MsgBox("Keypressed is -> " & lParam.vkCode)
Return CallNextHookEx(hKeyboardHook, Code, wParam, lParam)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
Private Function keyboardHooked() As Boolean
Return hKeyboardHook <> IntPtr.Zero
End Function
Public Sub UnhookKeyboard()
If keyboardHooked() Then
UnhookWindowsHookEx(hKeyboardHook)
End If
End Sub
#End Region
Private Sub CheckHooked()
If keyboardHooked() Then
MsgBox("Keyboard hooked")
Else
MsgBox("Keyboard hook failed: " & Err.LastDllError)
End If
End Sub
End Class
Your question is a possible duplicate of:
How to get the "KeyPress" event from a Word 2010 Addin (developed in C#)?
How to raise an event on MS word Keypress
Capturing keydown event of MS Word using C#
... however, the answer remains the same: you simply can't :)
In my answer to the last of the questions listed above I explain the reason behind this in a bit more detail, and also covers a possible alternative solution involving the WindowSelectionChange event.