C# WinAPI Check for Window Text from Static - c#

I am attempting to determine whether a Window with the Class Name of "Static", CONTAINS "Scan finished." via .NET/C#.
Specifically, I have automated the use of RogueKiller and would like to detect when the "Scan" is done.
I have tried numerous PInvoke methods, but nothing I can find allows me to do (pseudo) Caption.Contains("Scan finished");.
Any help would be wonderful!
The Window Structure Works as:
Parent (RogueKillerâ„¢...etc)
Windows - Class:Static, Caption:
Scan finished. Please look at the different tabs and delete items with the buttons
I need to detect "Scan finished".

I think you want to call EnumWindows and call GetWindowText in your callback. I hesitate to copy/paste another StackOverflow answer. So for a detailed example, see How can I use EnumWindows to find windows with a specific caption/title?

Related

Hiding and showing a program started by Systems.Diagnostics.Process

The following code is how I initiate the program:
System.Diagnostics.Process fooProgram;
fooProgram = System.Diagnostics.Process.Start("foo.exe");
Now I know that you can set the StartInfo parameters to have the program run hidden but is there some way to hide it and bring it back during processing as I only want to show certain screens to the user and then I want it to automatically hide itself when the information has been shown. I was hoping for something as simple as fooProgram.Show() and fooProgram.Hide() but it appears that it is not quite that simple.
Simply sending it behind the other program and bringing it back to focus would be enough as well, however this also doesn't seem to be in the list of available actions.
The program being launched is a .NET 4 form.
I don't think you can do this in .NET - you'll need to use interop.
Check out these functions:
FindWindow
ShowWindow
SetForegroundWindow
SendMessage
So you'll use FindWindow() to get the window handle and then you'll execute those other functions on that handle. In terms of exposing those functions to C# check out this awesome interop website: pinvoke.net
Also, instead of HWND use IntPtr.

Windows API getting HWND

I'm developing a piece of software to inset some text in a rich edit of another program the code goes like this:
atlfe = FindWindowEx(wtlsplitterwindow, 0, "atl:0087d7a8" , null);
This is only one line: this works fine, problem is with every release of the program number atl:0087d7a8 changes so i have to use spy++ to get the new one and change it in the code.
The question is, is there is any way I can get that number from code?
By the way I'm using C#, VS2010.
I suggest you use UI Automation instead of raw Windows API. You should start with the UI Spy tool to determine the UI hierarchy of your app, it will be more resilient to change.
See some articles on this subject on SO:
Retrieve current URL from C# windows forms application
How to get the word under the cursor in Windows?
Been a while since I messed with some of these windows API's. I think this may be of value though.
http://msdn.microsoft.com/en-us/magazine/cc163617.aspx
If the Title is always the same, use it instead of class name
atlfe = FindWindowEx(wtlsplitterwindow, 0, null, "Title");
More info on MSDN.
Clearly if the sub-window has not title and its classname is different every time you have but one method remaining.
You are first going to have to find the top level window of this app using either EnumWindows or FindWindowEx, the latter if you can identify it by class name and/or window title.
Once you have the top level window you can walk through the children to locate the sub-window that you are looking for. Presumably you already know the relationships between the top level window and the sub-window you are targetting. In any case Spy++ can tell you this.

Issue with EnumWindows

When enumerating windows using EnumWindows, I get hundreds of handles instead of one per open window on my desktop.
First of all, i am curious if this is the correct behavior.
Secondly, trying to get a difference between open windows before and after launching a process returns 15-20 new handles. I am wondering if there is a way to filter these based on some flag, i really need just the mainwindow handle.
Any ideas?
To get the main window of a process, use the Process.MainWindowHandle property.
To answer your question, you can see exactly what all of the handles are using Spy++.
In short, many applications will create hidden windows to run message loops.
You can filter within the enum callback by checking IsWindowVisible() & ignoring invisible system/message sink windows.

Get newly created window using Win32 API hooks

This may be a long short or not even possible but no harm in asking.
What I am trying to do is monitor an application for any new windows it creates in its MDI control. I have implemented hooking in C# and can capture the MDICREATE window message but because I need to get information about the window after is has been created the MDICREATE message isn't much help because at that stage the window hasn't been created in the other application yet.
Without going into to much detail I just need to be able to see when a new window has been created.
Is this possible?
Thanks
I'm not aware of another message that gets the info that you are looking for off hand. But if that message works for you, you could hook that message and then do another scan of the windows to find the one you are missing. You can enumerate the child windows of the parent window. Use Spy++ to see the exact window hierarchy.
If you can watch for a particular function call, I would use some kind of hooking library to grab that (EasyHook comes to mind).
You can hook the MDI create function (assuming there is one), watch for that, then inn your code, call the original and do any lookups using the returned value. You'll have access to the returned value and any parameters, so you should be able to get some info out of those.
Two options off the top of my head.
Hook the WM_MDIACTIVATE event, the first time the window is being activated, use a flag to determine the first time the window is being activated.
If you need to run your code after the WM_MDICREATE or WM_MDIACTIVATE, you can post a new custom message from one of these messages, which is then handled after these messages have completed. You then write your code to handle the custom message.

how to Make a program intangable with c#?

I just wanted to know, if there is someway to make a program (or part of a program) intangable with c#. I want to make it so that people can see the program is there, but if they were to click, it would click whatever is underneath it. I would also like to know if you can do that backwords. Is there someway to make an item that is invisable, clickable?
Thank you for your help!
To your vague question, I offer a vague response:
Sounds like your option one is possible. You would need to send the click event (message) that you receive to the appropriate window (the one underneath yours). I suspect that you would have to DllImport some stuff to do this from c#.
Your option two, while more difficult, is probably also possible because you can inject code into other running executables. This will be a privileged operation, and you will likely again have to use stuff from non .NET dlls to do it from c#. See Three Ways to Inject Your Code into Another Process on CodeProject.
If you want to display something to a user without it getting in the way of whatever it was they were doing at the time you could pop up your messages in bubble from the task bar perhaps?
The answer to this question covers this. Or if you're lazy here's the code project link.
Ok so it sometimes might be necessary to show something on screen and not let it be clickable (like On-Screen-Display for video playback to show volume increase, etc..)
Here's an example of how to this in C# - from codeproject: http://www.codeproject.com/KB/cs/OSDwindow.aspx
This uses the Win32 API ShowWindow(hWnd, SW_SHOWNOACTIVATE) to present the window without losing focus (can't be selected).
And here's the MSDN page for this call ShowWindow
To display a window that is invisible but clickable you can use a window with no border (FormBorderStyle=None) and set transparency to 1%.
Hope that helps!

Categories