I'm using the following code to force the RichTextBox to scroll to the real bottom
Private Const WM_VSCROLL As Integer = 277
Private Const SB_PAGEBOTTOM As Integer = 7
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Friend Shared Sub ScrollToBottom(ByVal richTextBox As RichTextBox)
SendMessage(richTextBox.Handle, WM_VSCROLL, CType(SB_PAGEBOTTOM, IntPtr), IntPtr.Zero)
richTextBox.SelectionStart = richTextBox.Text.Length
End Sub
' to call it
ScrollToBottom(RichTextBox1)
Is there a way to reverse this code so I can force it to to always scroll up?
I am not looking to append text solutions.
Thanks
This Should do it:
Private Const WM_VSCROLL As Integer = &H115
Private Const SB_TOP As Integer = 6
Private Const SB_BOTTOM As Integer = 7
<DllImport("user32.dll")> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
' scroll RichTextBox
Friend Shared Sub ScrollRichTextBox(ByVal richTextBox As RichTextBox, Direction as integer)
SendMessage(richTextBox.Handle, WM_VSCROLL, Direction, 0)
End Sub
' to call it
ScrollRichTextBox(RichTextBox1, SB_TOP) 'Scrolls to top
ScrollRichTextBox(RichTextBox1, SB_BOTTOM) 'Scrolls to bottom
Related
The Goal:
I am trying to create a Visual Basic program that will execute some code whenever any new program window is displayed on screen. Just for an easy to understand example: When I launch a program like File Explorer, I want a message box to be displayed when the window for File Explorer is displayed on screen.
The Problem:
Using the code I provided below, my desired outcome works correctly. However, it will also display a message box whenever something like a context menu is displayed as well. I do not want this. I only want a message box to be displayed whenever an actual program window is displayed. I've tried adding checks for checking if the window has 'minimize', 'maximize', and 'close' buttons. But after adding those checks, a message box no longer gets displayed at all, even with a window that has caption buttons, like File Explorer.
This is my code:
Private Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
Declare Auto Function SetWinEventHook Lib "user32.dll" (ByVal eventMin As Integer, ByVal eventMax As Integer, ByVal hmodWinEventProc As IntPtr, ByVal lpfnWinEventProc As WinEventDelegate, ByVal idProcess As Integer, ByVal idThread As Integer, ByVal dwflags As Integer) As IntPtr
Declare Auto Function UnhookWinEvent Lib "user32.dll" (ByVal hWinEventHook As IntPtr) As Boolean
Delegate Sub WinEventDelegate(ByVal hWinEventHook As IntPtr, ByVal eventType As Integer, ByVal hwnd As IntPtr, ByVal idObject As Integer, ByVal idChild As Integer, ByVal dwEventThread As Integer, ByVal dwmsEventTime As Integer)
Const WINEVENT_OUTOFCONTEXT As Integer = 0
Const EVENT_OBJECT_CREATE As Integer = &H8000
Private hook As IntPtr = IntPtr.Zero
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
hook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, IntPtr.Zero, AddressOf WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT)
End Sub
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
UnhookWinEvent(hook)
End Sub
Private Sub WinEventProc(ByVal hWinEventHook As IntPtr, ByVal eventType As Integer, ByVal hwnd As IntPtr, ByVal idObject As Integer, ByVal idChild As Integer, ByVal dwEventThread As Integer, ByVal dwmsEventTime As Integer)
Dim windowTitle As String = GetWindowText(hwnd)
If windowTitle <> "" AndAlso IsPopupWindow(hwnd) Then
msgbox("New Window Detected")
End If
End Sub
Private Function IsPopupWindow(ByVal hwnd As IntPtr) As Boolean
Dim style As Long = GetWindowLong(hwnd, GWL_STYLE)
Return (style And WS_POPUP) = WS_POPUP
End Function
Declare Auto Function GetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
Private Const GWL_STYLE As Integer = -16
Private Const WS_POPUP As Long = &H80000000
Private Function GetWindowText(ByVal hwnd As IntPtr) As String
Dim textLength As Integer = GetWindowTextLength(hwnd) + 1
Dim text As String = New String(" "c, textLength)
GetWindowText(hwnd, text, textLength)
Return text.Trim()
End Function
Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
Declare Auto Function GetWindowTextLength Lib "user32.dll" (ByVal hWnd As IntPtr) As Integer
What approach could I use to better listen for the creation of new program windows? Or, how could I fix my code?
EVENT_OBJECT_CREATE gets triggered for all kinds of objects, not just windows. You will have to retrieve the created object's window class name via GetClassName() and ignore whichever classes you don't want to process. Menus have a standard class name of #32768.
I am trying to make a class which will detect what mouse button was pressed each time, but I'm getting 2 errors in the Hookmouse() sub which regards to delegates. Could someone help me understand what am I doing wrong ? I would really aprreciate if someone could explain me more about delegates except from correcting this piece of code.
The 2 errors I get:
Method 'Private Function MouseProc(nCode As Integer, wParam As IntPtr, ByRef lParam As MouseHook.MouseHookStruct) As Integer' does not have a signature compatible with delegate 'Delegate Function MouseHook.MouseProcDelegate(nCode As Integer, wParam As IntPtr, lParam As MouseHook.MouseHookStruct) As Integer'.
Value of type 'MouseHook.MouseProcDelegate' cannot be converted to 'MouseHook.CallBack'.
Imports System.Runtime.InteropServices
Public Class MouseHook
Public Delegate Function CallBack(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As MouseHookStruct) As Integer
'Declare the mouse hook constant.
'For other hook types, obtain these values from Winuser.h in Microsoft SDK.
Dim WH_MOUSE As Integer = 7
Shared hHook As Integer = 0
'Keep the reference so that the delegate is not garbage collected.
Private hookproc As CallBack
'Import for the SetWindowsHookEx function.
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
Public Overloads Shared Function SetWindowsHookEx _
(ByVal idHook As Integer, ByVal HookProc As CallBack,
ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
End Function
'Import for the CallNextHookEx function.
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
Public Overloads Shared Function CallNextHookEx _
(ByVal idHook As Integer, ByVal nCode As Integer,
ByVal wParam As IntPtr, ByVal lParam As MouseHookStruct) As Integer
End Function
'Import for the UnhookWindowsHookEx function.
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)>
Public Overloads Shared Function UnhookWindowsHookEx _
(ByVal idHook As Integer) As Boolean
End Function
Private Delegate Function MouseProcDelegate(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As MouseHookStruct) As Integer
'Point structure declaration.
<StructLayout(LayoutKind.Sequential)> Public Structure Point
Public x As Integer
Public y As Integer
End Structure
'MouseHookStruct structure declaration.
<StructLayout(LayoutKind.Sequential)> Public Structure MouseHookStruct
Public pt As Point
Public hwnd As Integer
Public wHitTestCode As Integer
Public dwExtraInfo As Integer
End Structure
Private Const HC_ACTION As Integer = 0
Private Const WH_MOUSE_LL As Integer = 14
Private Const WM_MOUSEMOVE As Integer = &H200
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_LBUTTONUP As Integer = &H202
Private Const WM_LBUTTONDBLCLK As Integer = &H203
Private Const WM_RBUTTONDOWN As Integer = &H204
Private Const WM_RBUTTONUP As Integer = &H205
Private Const WM_RBUTTONDBLCLK As Integer = &H206
Private Const WM_MBUTTONDOWN As Integer = &H207
Private Const WM_MBUTTONUP As Integer = &H208
Private Const WM_MBUTTONDBLCLK As Integer = &H209
Private Const WM_MOUSEWHEEL As Integer = &H20A
Private MouseHook As Integer
Private MouseHookDelegate As MouseProcDelegate
Public Event Mouse_Move(ByVal ptLocat As Point)
Public Event Mouse_Left_Down(ByVal ptLocat As Point)
Public Event Mouse_Left_Up(ByVal ptLocat As Point)
Public Event Mouse_Left_DoubleClick(ByVal ptLocat As Point)
Public Event Mouse_Right_Down(ByVal ptLocat As Point)
Public Event Mouse_Right_Up(ByVal ptLocat As Point)
Public Event Mouse_Right_DoubleClick(ByVal ptLocat As Point)
Public Event Mouse_Middle_Down(ByVal ptLocat As Point)
Public Event Mouse_Middle_Up(ByVal ptLocat As Point)
Public Event Mouse_Middle_DoubleClick(ByVal ptLocat As Point)
Public Event Mouse_Wheel(ByVal ptLocat As Point, ByVal Direction As Wheel_Direction)
Public Enum Wheel_Direction
WheelUp
WheelDown
End Enum
Private Function MouseProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByRef lParam As MouseHookStruct) As Integer
If (nCode = HC_ACTION) Then
Select Case wParam
Case WM_MOUSEMOVE
RaiseEvent Mouse_Move(lParam.pt)
Case WM_LBUTTONDOWN
RaiseEvent Mouse_Left_Down(lParam.pt)
Case WM_LBUTTONUP
RaiseEvent Mouse_Left_Up(lParam.pt)
Case WM_LBUTTONDBLCLK
RaiseEvent Mouse_Left_DoubleClick(lParam.pt)
Case WM_RBUTTONDOWN
RaiseEvent Mouse_Right_Down(lParam.pt)
Case WM_RBUTTONUP
RaiseEvent Mouse_Right_Up(lParam.pt)
Case WM_RBUTTONDBLCLK
RaiseEvent Mouse_Right_DoubleClick(lParam.pt)
Case WM_MBUTTONDOWN
RaiseEvent Mouse_Middle_Down(lParam.pt)
Case WM_MBUTTONUP
RaiseEvent Mouse_Middle_Up(lParam.pt)
Case WM_MBUTTONDBLCLK
RaiseEvent Mouse_Middle_DoubleClick(lParam.pt)
Case WM_MOUSEWHEEL
Dim wDirection As Wheel_Direction
If lParam.hwnd < 0 Then
wDirection = Wheel_Direction.WheelDown
Else
wDirection = Wheel_Direction.WheelUp
End If
RaiseEvent Mouse_Wheel(lParam.pt, wDirection)
End Select
End If
Return CallNextHookEx(MouseHook, nCode, wParam, lParam)
End Function
Protected Overrides Sub Finalize()
UnhookWindowsHookEx(MouseHook)
MyBase.Finalize()
End Sub
Public Sub HookMouse()
MouseHookDelegate = New MouseProcDelegate(AddressOf MouseProc)
MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
End Sub
Public Sub UnhookMouse()
UnhookWindowsHookEx(MouseHook)
End Sub
End Class
In my VB.Net application, I've got the following code which allows me to use the app's taskbar icon as a progress bar.
Public Sub setTaskbarProgress(ByVal upTo As Integer, ByVal outOfTotal As Integer, ByVal stateType As TaskbarProgressBarState)
If TaskbarManager.IsPlatformSupported Then
If stateType = Nothing Then stateType = TaskbarProgressBarState.Normal
Dim tbm As TaskbarManager = TaskbarManager.Instance
tbm.SetProgressValue(upTo, outOfTotal)
If upTo = 0 And outOfTotal = 100 Then
tbm.SetProgressState(TaskbarProgressBarState.NoProgress)
Else
tbm.SetProgressState(stateType)
End If
End If
End Sub
I want to expand that function, ideally so it had a fourth parameter, e.g.
Public Sub setTaskbarProgress(ByVal upTo As Integer,
ByVal outOfTotal As Integer, ByVal stateType As TaskbarProgressBarState, _
ByRef target As Form)
so that the progress bar (Taskbar.SetProgressValue and TaskBar.SetProgressState) were applied to a specific sub-form or dialogue box in my project, rather than always being applied to the main form.
Is there a way I can specify which window "TaskbarManager" is actually going to apply to? I can't see how I would feed it a 'target'? Does Windows allow this? Any points would be welcome.
Well, In any case, yes, you can do it, but the code that you've provided lacks of necessary details of who and how wrapped it to know its behavior, because is not the same if you have full access to the source code to perform any required modification or not, It's not clear whether it is a VB.NET translation of the official WindowsAPICodePack C# code, or a custom wrapper by other person.
Anyways, the code you can have, particullary the TaskbarManager.Instance member should implement one of the ITaskbarList interfaces, probablly ITaskbarList4 (all), and this means you should be able to rework the wrapper to call the ITaskbarList::SetProgressValue method passing the target window handle of your dialog.
If for some reason you could need the ITaskbarList definition, I translated it time ago to VB.NET (ignoring some methods named as "Fake" that I don't wanted to use)
''' <remarks>
''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd562040(v=vs.85).aspx"/>
''' </remarks>
<ComImport>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<Guid("C43DC798-95D1-4BEA-9030-BB99E2983A1A")>
Public Interface ITaskbarList4
#Region " ITaskbarList "
<PreserveSig>
Sub HrInit()
<PreserveSig>
Sub AddTab(ByVal hwnd As IntPtr)
<PreserveSig>
Sub DeleteTab(ByVal hwnd As IntPtr)
<PreserveSig>
Sub ActivateTab(ByVal hwnd As IntPtr)
<PreserveSig>
Sub SetActiveAlt(ByVal hwnd As IntPtr)
#End Region
#Region " ITaskbarList2 "
<PreserveSig>
Sub MarkFullscreenWindow(ByVal hwnd As IntPtr, <MarshalAs(UnmanagedType.Bool)> ByVal fFullscreen As Boolean)
#End Region
#Region " ITaskbarList3 "
<PreserveSig>
Sub SetProgressValue(ByVal hwnd As IntPtr, ByVal ullCompleted As UInt64, ByVal ullTotal As UInt64)
<PreserveSig>
Sub SetProgressState(ByVal hwnd As IntPtr, ByVal tbpFlags As TaskbarProgressBarState)
<PreserveSig>
Sub RegisterTab(ByVal hwndTab As IntPtr, ByVal hwndMdi As IntPtr)
<PreserveSig>
Sub UnregisterTab(ByVal hwndTab As IntPtr)
<PreserveSig>
Sub SetTabOrder(ByVal hwndTab As IntPtr, ByVal hwndInsertBefore As IntPtr)
<PreserveSig>
Sub SetTabActive(ByVal hwndTab As IntPtr, ByVal hwndInsertBefore As IntPtr, ByVal dwReserved As UInteger)
<PreserveSig>
Function Fake1() As HResult
' Function ThumbBarAddButtons(byval hwnd As IntPtr, byval cButtons As UInteger, <MarshalAs(UnmanagedType.LPArray)> byval pButtons As ThumbButton()) As HResult
<PreserveSig>
Function Fake2() As HResult
' Function ThumbBarUpdateButtons(byval hwnd As IntPtr, byval cButtons As UInteger, <MarshalAs(UnmanagedType.LPArray)> byval pButtons As ThumbButton()) As HResult
<PreserveSig>
Sub Fake3()
' Sub ThumbBarSetImageList(byval hwnd As IntPtr, byval himl As IntPtr)
<PreserveSig>
Sub SetOverlayIcon(ByVal hwnd As IntPtr, ByVal hIcon As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> ByVal pszDescription As String)
<PreserveSig>
Sub SetThumbnailTooltip(ByVal hwnd As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> ByVal pszTip As String)
<PreserveSig>
Sub SetThumbnailClip(ByVal hwnd As IntPtr, ByVal prcClip As IntPtr)
#End Region
#Region " ITaskbarList4 "
Sub Fake4()
' Sub SetTabProperties(byval hwndTab As IntPtr, byval stpFlags As SetTabPropertiesOption)
#End Region
End Interface
Additionaly this enumeration:
''' <remarks>
''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd391697%28v=vs.85%29.aspx"/>
''' </remarks>
Public Enum TaskbarProgressBarState
NoProgress = 0
Indeterminate = &H1
Normal = &H2
[Error] = &H4
Paused = &H8
End Enum
I have a WinForm application developed in Framework 2.0 with VB.Net which was using the event MouseMove on all the ListView objects to display ToolTip text on the first row of the ListViews - as it's not possible to have ToolTips on ColumnHeader, as far as I know, without third part tools.
The problem is that since I converted the application to Framework 4.0 this "trick" is not working and the ToolTips are not displayed anymore.
Does anyone know a solution or, even better, a way to display ToolTips on ListView ColumnHeaders?
Here's my code snippet:
Private Sub ShowTooltip(ByVal sender As Object, ByVal e As MouseEventArgs)
Handles myListView.MouseMove
Dim iColumn As System.Int32 = FindListViewColumnHeader(e.X, e.Y)
If Me.myListView.Columns.Count > 0 AndAlso iColumn >= 0 AndAlso
iColumn <= Me.myListView.Columns.Count - 1 Then
Me.myToolTip.Active = True
Me.myToolTip.UseAnimation = True
Me.myToolTip.UseFading = True
Me.myToolTip.AutomaticDelay = 10000
Me.myToolTip.AutoPopDelay = 10000
Me.myToolTip.InitialDelay = 0
Me.myToolTip.ReshowDelay = 2000
Dim sTooltipText As System.String = SomeText(...)
If sTooltipText <> DirectCast(Me.myToolTip.Tag, System.String) Then
Me.myToolTip.Tag = sTooltipText
Me.myToolTip.SetToolTip(Me.myListView, sTooltipText)
End If
Else
Me.myToolTip.Active = False
End If
End Sub
Protected Overridable Function FindListViewColumnHeader(ByVal X As System.Int32,
ByVal Y As System.Int32) As System.Int32
If Y > 20 And Y < 40 Then
Dim iCount As System.Int32
Dim iLeft As System.Int32
For iCount = 0 To myListView.Columns.Count - 1
iLeft = iLeft + myListView.Columns(iCount).Width
If X <= iLeft Then
Return iCount
Exit For
End If
Next
Return iCount
Else
Return -1
End If
End Function
Note: myToolTip is
Friend WithEvents myToolTip As System.Windows.Forms.ToolTip
and myListView is
Protected WithEvents myListView As System.Windows.Forms.ListView
Please notice that, as suggested in the question:
How to set tooltip for a ListviewItem, ShowItemToolTips is already set to True.
You can get the handle of the header column and subclass it:
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function CallWindowProc(lpPrevWndFunc As IntPtr, hWnd As IntPtr, Msg As UInteger, wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function
Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const GWL_WNDPROC As Integer = -4
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_MOUSEMOVE As Integer = &H200
Private oldWndProc As IntPtr = IntPtr.Zero
Private newWndProc As Win32WndProc = Nothing
Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
'hWnd is the window you want to subclass...,
'create a new delegate for the new wndproc
newWndProc = New Win32WndProc(AddressOf MyWndProc)
'subclass
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
End Sub
Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Select Case Msg
Case WM_LBUTTONDOWN
'The lower 2 bytes of lParam are the x coordinate
'and the higher 2 bytes the y.
ToolTip1.Show("My tooltip", ListView1, lParam And &HFFFF, (lParam >> 16) And &HFF, 2000)
Exit Select
Case Else
Exit Select
End Select
Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
End Function
To subclass the header use:
'LVM_GETHEADER = &H101F
Dim hwndHeader As IntPtr = SendMessage(ListView1.Handle, &H101F, 0, 0)
SubclassHWnd(hwndHeader)
I used the WM_LBUTTONDOWN event for convenience. You can use the WM_MOUSEMOVE event and check which column the mouse is etc... and show the tooltip
The code for subclassing: Subclass an Unmanged Window in C#
I can get text from external application text box but now I want to get text from my desired text box from external application.
My English is not so good that's why see Image Below.
The Below Code Return The First Text Box Value Only.
Imports System.Runtime.InteropServices
Public Class Form1
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 IntPtr) As IntPtr
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, _
ByVal childAfter As IntPtr, _
ByVal lclassName As String, _
ByVal windowTitle As String) As IntPtr
End Function
Declare Auto Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Find the running notepad window
Dim Hwnd As IntPtr = FindWindow(Nothing, TextBox1.Text)
'Alloc memory for the buffer that recieves the text
Dim Handle As IntPtr = Marshal.AllocHGlobal(100)
'send WM_GWTTEXT message to the notepad window
Dim NumText As Integer = SendMessage(Hwnd, WM_GETTEXT, 50, Handle)
'copy the characters from the unmanaged memory to a managed string
Dim Text As String = Marshal.PtrToStringUni(Handle)
'Display the string using a label
Label1.Text = Text
'Find the Edit control of the Running Notepad
Dim ChildHandle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, "Edit", Nothing)
'Alloc memory for the buffer that recieves the text
Dim Hndl As IntPtr = Marshal.AllocHGlobal(200)
'Send The WM_GETTEXT Message
NumText = SendMessage(ChildHandle, WM_GETTEXT, 200, Hndl)
'copy the characters from the unmanaged memory to a managed string
Text = Marshal.PtrToStringUni(Hndl)
'Display the string using a label
Label2.Text = Text
End Sub
End Class
You'll have to loop through children of the main window (External Application) and get their properties.
You'll use the following:
<DllImport("User32.dll")> _
Public Function EnumChildWindows _
(ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
ByVal lParam As IntPtr) As Boolean
End Function
Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Public Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Try
EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return ChildrenList.ToArray
End Function
For for details, check this How can I get properties of controls contained in a popup message box using VB.Net
' try this on excel vbe
External_application_handle=findwindow(vbNullString,"External_application")
textbox_1_handle=findwindowex(External_application_handle,0&,"Edit",vbNullString)
next_handle=textbox_1_handle
textbox_2_handle=findwindowex(External_application_handle,next_handle,"Edit",vbNullString")
Length = SendMessage(textbox_2_handle, WM_GETTEXTLENGTH, 0,0)
buffer$=space(Length)
call sendmessage(textbox_2_handle,Length+1,buffer$)
msgbox buffer