Teamviewer stops working GetWindowText (User32.dll) Function - c#

I have developed a C# code which access to user32.dll and it is using GetWindowText function. The code is working properly when Teamviewer is uninstalled on Windows 7.
However if you install Teamviewer, the code can not retrieve the text of control in window with GetWindowText function. The code is given below. How can I solve this problem ?
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindowExW(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
string lpszWindow);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr GetWindowText(IntPtr hwndParent, StringBuilder Wintxt, int txtsize);
public void CloseWin(string param)
{
try
{
IntPtr hwnD = FindWindowExW(IntPtr.Zero, IntPtr.Zero, "CabinetWClass", null);
IntPtr hwnD2 = FindWindowExW(hwDvar, IntPtr.Zero, "WorkerW", null);
IntPtr hwnD3 = FindWindowExW(hwnD2, IntPtr.Zero, "ReBarWindow32", null);
IntPtr hwnD4 = FindWindowExW(hwnD3, IntPtr.Zero, "Address Band Root", null);
IntPtr hwnD5 = FindWindowExW(hwnD4, IntPtr.Zero, "msctls_progress32", null);
IntPtr hwnD6 = FindWindowExW(hwnD5, IntPtr.Zero, "Breadcrumb Parent", null);
IntPtr hwnD7 = FindWindowExW(hwnD6, IntPtr.Zero, "ToolbarWindow32", null);
StringBuilder sb = new StringBuilder(255);
GetWindowText(hwnD7, sb, 255);

Well I have resolved the issue. I was calling also dialog file class with the function FindWindowEx by the class name #32770.
This class type is used also by Teamviewer(TV) quick support user interface. When I run my code, there is a intervention to the interface of TV and blocks of working user32 functions.
To solve the problem I have called the FindWindow function with class name and control name so that there is no intervention to the TV and problem solved.

Related

C# SendMessage click button

Im trying to understand the SendMessage function and here's my actual code:
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
static void Main(string[] args)
{
Process test = Process.GetProcessesByName("calc")[0];
IntPtr hwndChild = FindWindowEx(test.MainWindowHandle, IntPtr.Zero, "Button", "2");
SendMessage(hwndChild, 245, IntPtr.Zero, IntPtr.Zero);
Console.ReadKey();
}
Very simple, I just want to click the calc button 2, but I'm having no success.
Error checking is never optional when you pinvoke winapi functions. It is a C api, it doesn't throw exceptions to keep you out of trouble. You'll have to do that by yourself. Proper code looks like this:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter,
string className, string windowTitle);
...
IntPtr hwndChild = FindWindowEx(test.MainWindowHandle, IntPtr.Zero, "Button", "2");
if (hwndChild == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
Now you know why your program doesn't work. Next thing you'd do is fire up the Spy++ utility and have a look-see at the calculator window. You'll discover that you have to make more FindWindowEx() calls to drill down to the nested button.
Do consider using a UI Automation library to do this.

Capture WindowClass #32770

I am new in C#, i've got some problem to capture any windows dialog show in my server. I need to know the message (caption and title) from windows dialog so i can write to my application log.
I know that i must find #32770 class windows, but i do not know how to enumwindows. In delphi 7, the code should use some functions like:
Enumwindows
EnumProcess
Enumchildwindows
Enumchildwindowsproc
Getwindowthreadprocessid
GetClassName
Getwindowtext
Is there any solution for this ?
You can use windows API in C# as well. You can find a lot information and examples of using here. And here is information about DllImport attribute.
You can try something like:
class Program
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
static void Main(string[] args)
{
var handle = IntPtr.Zero;
do
{
handle = FindWindowEx(IntPtr.Zero, handle, "#32770", null);
if (handle != IntPtr.Zero )
Console.WriteLine("Found handle: {0:X}", handle.ToInt64());
} while (handle != IntPtr.Zero);
Console.ReadLine();
}
}

How to use SendMessage to paste something to a different window

I am using the following SendMessage function to send/paste text to a different application.
But in that function I have to give the name of the window from the other application.
How can I change this to get the current active window and paste in the code there?
Code:
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
public const int WM_PASTE = 0x0302;
IntPtr windowHandle = FindWindow("NOTEPAD", null);
IntPtr editHandle = FindWindowEx(windowHandle, IntPtr.Zero, "EDIT", null);
string textToSendToFile = "Input here your text";
Clipboard.SetText("Test");
SendMessage((int)editHandle, WM_PASTE, 0, textToSendToFile);
I also got this but I do not really know how to combine this with the code above...
[DllImportAttribute("user32.dll", EntryPoint = "GetForegroundWindow")]
public static extern IntPtr GetForegroundWindow();
[DllImportAttribute("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
public static extern uint GetWindowThreadProcessId([InAttribute()] IntPtr hWnd, IntPtr lpdwProcessId);
IntPtr hWndForegroundWindow = GetForegroundWindow();
uint activeThreadID = GetWindowThreadProcessId(hWndForegroundWindow, IntPtr.Zero);
The WM_PASTE message does not use the parameters. It's just an instruction to the recipient to take the contents of the clipboard and paste them. So if you wish the recipient to do anything, you'll need to populate the clipboard first.
If you don't wish to pollute the clipboard, and you should not since it belongs to the user, then you can send an EM_REPLACESEL message passing the text in lParam.
If you want to find the window which the user is currently working on, use GetForegroundWindow.
However, rather than faking low level messages, best of all would be to use the automation API.

FindWindowEx on child dialog window

I'm trying to get the handle of a child dialog window. I've tried using FindWindowEx, but it didn't work. Instead, FindWindow did work.
I did an experiment with visual studio's options window, with the following code:
IntPtr vsHandle = Process.GetProcessById(vsProcessId).MainWindowHandle; // consistent with spy++'s parent handle of options window
IntPtr optionsHandle = FindWindowEx(vsHandle, IntPtr.Zero, "#32770", "Options"); // returns 0
IntPtr optionsHandle2 = FindWindow("#32770", "Options"); // returns correct handle
From my understanding, FindWindowEx should've worked, it is a child window.
I'm running windows xp, and have also tried using FindWindowEx(vsHandle, IntPtr.Zero, "#32770", null). Didn't work. Seems like the only way to get it is using FindWindow which isn't good enough as two parent instances with the same dialog can be open.
This is the declaration:
[DllImport("user32.dll")]
Private static extern IntPtr FindWindow(string className, string windowTitle);
[DllImport("user32.dll")]
Private static extern IntPtr FindWindowEx(IntPtr parentHWnd, IntPtr childAfterHWnd, string className, string windowTitle);
Thanks in advance.
I found a solution to this. The reason FindWindowEx didn't work was because it only works on child windows that have WS_CHILD style, and apparently dialog windows do not have this style. It is why EnumChildWindows won't work either (I've tried).
So the ugly solution is EnumWindows combined with GetParent to compare the handle and the text.
struct SearchData
{
public string WindowText;
public IntPtr ParentHandle;
public IntPtr ResultHandle;
}
delegate bool EnumWindowsCallback(IntPtr currentWindowHandle, ref SearchData searchData);
[DllImport("user32.dll")] static extern bool EnumWindows(EnumWindowsCallback callback, ref SearchData searchData);
[DllImport("user32.dll")] static extern IntPtr GetParent(IntPtr childHandle);
[DllImport("user32.dll")] static extern void GetWindowText(IntPtr handle, StringBuilder resultWindowText, int maxTextCapacity);
static bool Callback(IntPtr currentWindowHandle, ref SearchData searchData)
{
bool continueEnumeration = true;
IntPtr currentWindowParentHandle = GetParent(currentWindowHandle);
if (currentWindowParentHandle == searchData.ParentHandle)
{
var windowText = new StringBuilder(1024);
GetWindowText(currentWindowHandle, windowText, windowText.Capacity);
if (windowText.ToString() == searchData.WindowText)
{
searchData.ResultHandle = currentWindowHandle;
continueEnumeration = false;
}
}
return continueEnumeration;
}
IntPtr GetChildWindowHandle(string windowText, IntPtr parentHandle)
{
var searchData = new SearchData{ParentHandle=parentHandle, WindowText=windowText};
EnumWindows(Callback, ref searchData);
return searchData.ResultHandle;
}

Cannot use pinvoke to send WM_CLOSE to a Windows Explorer window

I have a C# application that uses the SendMessage pinvoke method to send a "close window" message (WM_CLOSE / 16) to various windows outside the application. This works great, except when the window in question is a Windows Explorer window. I do not get an exception, but the window does not close.
Here's the signature:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
internal static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
Is there a different message that I need to send to Windows Explorer windows? Or an alternate way to accomplish this?
an alternative solution would be to use PostMessage win API call instead of SendMessage, below is an example which worked fine for me (I'm using winXP sp3):
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.Dll")]
public static extern int PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);
private const UInt32 WM_CLOSE = 0x0010;
...
IntPtr hWnd = FindWindow("ExploreWClass", null);
if (hWnd.ToInt32()!=0) PostMessage(hWnd, WM_CLOSE, 0, 0);
differences between PostMessage and SendMessage api call are described here: http://msdn.microsoft.com/en-us/magazine/cc301431.aspx

Categories

Resources