Inside Windows, applications use "Windows". You can only access these Windows using API's and lots and lots of documentation.
I implemented all useful and working Window API's into a single class. You can do the following with it:
- Return all active Windows on the OS
- Get the process of a Window (handle)
- Set/Get text, location, size, enabled, visible, exstyles, font, window order
- Perform commands: cut, copy, close, destroy, bringtofront,sendtoback etc.
- Capture the Window into a bitmap
- Set transperancy
- Get window parent and children using a built-in Enumerator
Code is in the attachment. It consists of 2 files:
- API.vb: contains direct SendMessage, DefWindowProc, SendInput and key API's
- Window.vb: the main class to use for windows. Contains API's that are used internally
The Window class only holds a pointer (hwnd), it is not storing any background information about Children or states.
When using the same Property more than once at the same time, it is wise to store it in a new Variable:
Code:
Dim w As New Window("Form1")
'Good:
Dim s As Size = w.Size
w.Location = New Point(s.Width, s.Height)
'Bad:
w.Location = New Point(w.Size.Width, w.Size.Height)
Note: a window is not a form, a window is everything you see. This includes textboxes, buttons, pictureboxes, labels, everything.
It is pretty cool to enable a disabled button and move on in an app while you are actually not allowed to.
Simple usage examples:
Getting a window
vb Code:
'Get the Foreground window
Dim w As Window = Window.GetForeGround
'Find a window or child:
Dim w As Window = Window.Find("notepad")
Dim c As Window = w.FindChild("edit")
'Window children
Dim children() As Window = w.Children()
Dim childbyname As Window = w.Children("name")
Dim childbypoint As Window = w.Children(Cursor.Position)
Dim childbyindex As Window = w.Children(2)
'Get all windows on the current Desktop (OS):
Dim windows() As Window = Window.All
'Get all windows on the current Desktop (OS) using the running Processes:
Dim windows() As Window = Window.AllFromProcessList()
'Get all windows belonging to a certain process:
Dim p As Process = Process.GetProcessesByName("notepad").First
Dim windows() As Window = Window.All(p)
'Get the Window of one of your own Controls or Forms:
Dim MyWindow As Window = Window.FromControl(Me)
'Get the Next sibling Window above this Window:
Dim nextwindow As Window = w.NextSibling
'Get the Desktop Window on which all other Windows are drawn:
Dim desktop As Window = Window.GetDesktop()
'Get the currently focused window control:
Dim focusedwindow As Window = Window.GetFocused()
'Get the currently focused window inside another Window:
'Note that it uses the Thread ID, only one control is focused in each program.
Dim focusedwindow As Window = w.FocusedWindow
Window manipulation
vb Code:
'Change the text:
w.Text &= vbNewLine & "New line"
'Kill the process owner:
Dim p As Process = w.Process
If Not IsNothing(p) Then p.Kill()
'Toggle the enabled state:
w.Enabled = w.Enabled = False
'Move it around and resize
w.Location = New Point(100, 100)
w.Size = New Size(300, 200)
w.Bounds = New Rectangle(100, 100, 300, 200)
'Set the Window outside of the screen:
w.Location = New Point(-w.Size.Width - 50, -w.Size.Height - 50)
w.SendKey(Keys.Control And Keys.A, Window.KeyCommand.KeyEvent.Down)
w.SendKey(Keys.Control And Keys.A, Window.KeyCommand.KeyEvent.Up)
w.SendChars("All text is now this")
w.SendChar(".")
Changelog:
<15th March 2011>
Had to update Window.vb, ExStyle enum was set on Integer while it should've been Long. Also, made sure the handle was passed as HandleRef to either 32 or 64 version of GetWindowLongPtr.
Note: This class has been in development and is still under development, so it *could* contain some bugs here and there.
<19th March 2011>
Got "TransparencyKey" and "Opacity" with internal "AWL" style setting working. Also added "Name" property.
Updated the files, no additional functions are used. They are replaced by shared functions inside the Window class. (GetWindows => Window.All)
Might get rid of the API class as well, just keeping it since it holds non-window related messages.
Good news: I managed to send keys, characters and Control + commands to an external minimized window using PostMessage. Only two arguments will be needed: the key code and the key state (down/up).
<23th March 2011>
Added "SendKey", "SendChar" and "SendString" functions to send input to other windows. Also added "Find" functions for children and all windows on the OS. API now contains an INPUT structure as well that uses SendInput.
<28th March 2011>
Added GetPixel, Client capture and Client bounds, plus the functions "Next/Previous/Top/BottomChild" for returning Window siblings in the Z-order.
<3th April 2011>
Added Input attaching, Focus functions, a DC class for handling Device Context operations, both a Window and Client DC attribute and simply added a lot of classes/functions inside the API class.
Last edited by bergerkiller; Apr 6th, 2011 at 11:43 AM.
Nice I made a similar thing a while ago, a Windows API library for .NET, though I didn't have quite as many Window specific functions as you so I'm sure your class will be useful to a lot of people. You can check my API library out here if you are interested: http://cjwdev.wordpress.com/2010/07/...2-1-available/
haha yeah well I went for the same strategy as you originally - just including things that are not very straight forward or that there are not already lots of examples of on the web. But then I started to just add anything I found that looked like it could be vaguely useful and wasn't already in the .NET Framework :P There's still loads more I want to add to it but just haven't had chance
HELP!
Right off the bat, I got numerous errors when adding Window.vb and API.vb to my project.
It says that "Count" is not a member of System.Array.
I'm using VB 2005 if that make a difference.
Anyone who does not wonder, is either omnipotent or a fool. Amerigoware <<<My Projects
Count on an Array is a LINQ method, which means you need 2008 or greater. I'm sure this can be converted to 2005 and below, but that is a LINQ statement.
Count on an Array is a LINQ method, which means you need 2008 or greater. I'm sure this can be converted to 2005 and below, but that is a LINQ statement.
Just to be technically correct, I think it is an Extension method not a LINQ method (although I guess it may use LINQ internally)
Maybe we are talking about two different things... This is what I'm talking about (see screenshot)
and I'm pretty sure its what the guy who mentioned the error was talking about too, as that is the exact error you get if I change that project to target .NET 2.0
Maybe we are talking about two different things... This is what I'm talking about (see screenshot)
and I'm pretty sure its what the guy who mentioned the error was talking about too, as that is the exact error you get if I change that project to target .NET 2.0
No, that's what I'm talking about. I guess it is an extension.
W.Location works with all apps expect with the one I need it to work It says Object reference not set to an instance of an object. .. ONLY for that 1 app? How can I fix it.