Solved

Get text from external window control

Posted on 2010-09-03
19
1,378 Views
Last Modified: 2013-12-17
Hello,

I want to get text contents from Windows Live Messager IM Window using API.
I have tried GetWindowText API, but it's not working.
0
Comment
Question by:Mohamed Abowarda
  • 6
  • 5
  • 5
  • +2
19 Comments
 
LVL 24

Expert Comment

by:alexey_gusev
Comment Utility
it won't work surely as it is different process and you can't just pass anything more complex than simple types like integers and so forth because it would involve pointers which are different in different processes' memory space.

in order to achieve what you want you could try few things. the following link briefly describes them all:

http://en.wikipedia.org/wiki/DLL_injection

there is a chapter in Windows Internals books for that usually (eg Advanced Windows by Jeffrey Richter)

Here is some tutorial, but you can google for more:

http://www.codeproject.com/kb/dll/DLL_Injection_tutorial.aspx

0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@alexey_gusev: I was not looking for DLL Injection, I just want to get the contents of a text box from another process using API.

Thanks,
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
Comment Utility
I looked at the version I have and the window is DirectHWNDUI which means the standard windows messaging won't work on these windows.
You have to use IAccessible Interface to get information about this window. I can't provide you with code just point you in the right direction.
IAccessible Interface
http://msdn.microsoft.com/en-us/library/accessibility.iaccessible.aspx
Client Functions
http://msdn.microsoft.com/en-us/library/dd742692(v=VS.85).aspx
0
 
LVL 38

Expert Comment

by:puppydogbuddy
Comment Utility
See this link:
           http://cuinl.tripod.com/Tips/wincaption.htm
I think the code provided will enable you to capture the caption and thread id of the window you have your cursor pointing at.  You might be able to adapt this code to your needs by adding code that will set focus to the live messenger window.

Hope this helps.
0
 
LVL 24

Expert Comment

by:alexey_gusev
Comment Utility
ok, if you don't want DLL injection, please enjoy reading MSDN for that:

http://msdn.microsoft.com/en-us/library/ms633520(VS.85).aspx

especially this paragraph:
======================
Remarks
To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.
======================
0
 
LVL 24

Expert Comment

by:alexey_gusev
Comment Utility
and here's the rough example of how to do it:
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;



namespace GetWndText

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }



        const uint WM_GETTEXT = 0x000D;



        [DllImport("user32.dll")]

        public static extern int SendMessage(IntPtr hWnd, uint Msg, uint wParam, IntPtr lParam);



        private void button1_Click(object sender, EventArgs e)

        {

            IntPtr buffer = Marshal.AllocHGlobal(256);

            int res = SendMessage((IntPtr)Convert.ToInt32(textBox1.Text, 16), WM_GETTEXT, 256, buffer);

            string text = Marshal.PtrToStringAnsi(buffer);

            Marshal.FreeHGlobal(buffer);

            textBox2.Text = text;

        }

    }

}

Open in new window

0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
Comment Utility
Unfortuanetley guys you can't use standard windows messages for these types of windows :(
You have to user IAccessible Interface if you have the Windows SDK or Accessible SDK you can use the Inspector (similar to Spyxxx.exe) but for IAccessible windows.
Typical location:
"C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\Inspect.exe"

msn.png
0
 
LVL 24

Expert Comment

by:alexey_gusev
Comment Utility
hence I was suggesting dll injection or hooking :)
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
I think there is way which is used by "Inspect.exe" to retrieve this information without DLL Injection.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 24

Expert Comment

by:alexey_gusev
Comment Utility
you can set a hook, without actual dll injecting
0
 
LVL 8

Expert Comment

by:Gururaj Badam
Comment Utility
--> I have tried GetWindowText API, but it's not working. <--

What's the behavior here? do you actually get any text frm GetWindowText call?
0
 
LVL 38

Expert Comment

by:puppydogbuddy
Comment Utility
see comment from alexy_gusev    09/04/10 ID#33603664
======================
Remarks
To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.
======================
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@Novice_Novice: 'GetWindowText' works well to get text from any window, not from external window control, sending WM_GETTEXT message works great to get external control text, but the problem here is that it's not working in Windows Live Messenger IM Window.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
Comment Utility
The message would only work for the caption/title of the window and nothing more than that. You need to use the IAccessible Interface if you want information from DirectUIHWND classes. http:#33603642
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@egl1044: I think it will be better if you give example.
0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 500 total points
Comment Utility
Uhh.. I didn't really want to get into this since it had to be done from scratch but I had some free time to play.
Under Projects > Add Reference > .NET Tab
   Add reference to: Accessibility
Then try something like this...

Imports System.Runtime.InteropServices



Public Class Form1

    <DllImport("user32.dll", ExactSpelling:=False, SetLastError:=True, CharSet:=CharSet.Unicode)> _

    Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, _

                                        ByVal hwndChildAfter As IntPtr, _

                                        ByVal lpszClass As String, _

                                        ByVal sWindowTitle As String) As IntPtr

    End Function



    <DllImport("oleacc.dll", ExactSpelling:=True, SetLastError:=True)> _

    Public Shared Function AccessibleObjectFromWindow(ByVal hWnd As IntPtr, _

                                                      ByVal dwObjectID As Integer, _

                                                      ByRef refID As Guid, _

                                                      ByRef ppvObject As Accessibility.IAccessible) As Integer

    End Function



    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        GetMsnInputText

    End Sub



    Public Sub GetMsnInputText()

        'egl1044

        Dim acc As Accessibility.IAccessible = Nothing

        Dim acc2 As Accessibility.IAccessible = Nothing

        Dim accMsnName As String = String.Empty

        Dim accMsnValue As String = String.Empty

        Dim msnIMWindow As IntPtr = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "IMWindowClass", Nothing)

        Dim msnIMWindowBar As IntPtr = FindWindowEx(msnIMWindow, IntPtr.Zero, "IM Window Native WindowBar Class", Nothing)

        Dim msnIMWindowClass As IntPtr = FindWindowEx(msnIMWindow, IntPtr.Zero, "IM Window Class", Nothing)

        Dim msnIMDirectUI As IntPtr = FindWindowEx(msnIMWindowClass, IntPtr.Zero, "DirectUIHWND", Nothing)

        Dim IID_IAccessible As New Guid("{618736E0-3C3D-11CF-810C-00AA00389B71}")

        If msnIMDirectUI.ToInt32 <> 0 Then

            If AccessibleObjectFromWindow(msnIMDirectUI, 0, IID_IAccessible, acc) = 0 Then

                acc = DirectCast(acc, Accessibility.IAccessible)

                For i As Integer = 1 To acc.accChildCount

                    Try

                        If acc.accChild(i) IsNot Nothing Then

                            acc2 = DirectCast(acc.accChild(i), Accessibility.IAccessible)

                            accMsnName = acc2.accName(0)

                            If accMsnName.ToLower.Equals("input") Then

                                accMsnValue = acc2.accValue(0)

                                MsgBox(accMsnValue) 'Ding

                                Exit For

                            End If

                        End If

                    Catch ex As Exception

                        'ignore COM exceptions

                    Finally

                        If acc2 IsNot Nothing Then

                            Marshal.ReleaseComObject(acc2)

                        End If

                    End Try

                Next i

                Marshal.FinalReleaseComObject(acc)

            End If

        Else

            Debug.Print("MSN IM Window doesn't exist on screen")

        End If

    End Sub



End Class

Open in new window

0
 
LVL 12

Author Closing Comment

by:Mohamed Abowarda
Comment Utility
Great work!

Thanks,
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
Comment Utility
BTW: Simply change line number 41 to "history" instead of "input" if you want the conversation(history) window.
0
 
LVL 12

Author Comment

by:Mohamed Abowarda
Comment Utility
@egl1044: I realized that while testing the code.

Thanks,
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now