|
|
|
date: Thu, 14 Aug 2008 08:04:06 -0700,
group: microsoft.public.dotnet.framework
back
Re: Get Active Desktop Window
Hi Alex,
getting the window title of a window created in a different process isnt
that easy. I dont know if it is possible within net framework (via interop
or something else) -- i dont think so, but it should be possible in C++. The
main problem would be to communicate between the different processes that
have created the top level windows (and there childs). To retrieve the title
of a window, you normally send a WM_GETTEXT message to the window. This
message contains a memory adress, where the title text should be stored.
Well, each process has its own adress range and is protected from access of
a different process. So if you send the message to another process, the
process is not able to write to your memory and you will never get the text.
To get arround this, you need to implement a DLL that create a shared memory
block. The shared memory block can then be accessed by multiple processes.
http://msdn.microsoft.com/en-us/library/ms686958(VS.85).aspx
The next step you need to do, is to create a system wide hook to load your
dll into all existing processes. (Spy++ works this way.... and you always
need administrative permissions for that). Then you can send the WM_GETTEXT
message with a shared memory adress to that process and the process is able
to write to this memory adress.
http://msdn.microsoft.com/en-us/library/ms632589(VS.85).aspx
And this could become a very difficult task...
-J-
date: Fri, 15 Aug 2008 14:02:19 +0200
author: Luthgers, John am
Re: Get Active Desktop Window
Matthias, yes, you are right. I've done something wrong with the marshaling
type and thats the reason why it wasnt working in my previous tests.
Alex, here is the code to get the title of the current selected top levels
screen. You need:
- a form
- a enabled timer
- a text box called textbox1
- a text box called textbox2
- wire the Tick-Event of timer1 to timer1_Tick
Its very easy to extend the example for child windows. Just use the
GetWindow (GW_CHILD / GW_HWNDNEXT) to iterate through all childs, subchilds
and so on. At the end you should move the instantiation of StingBuilder to
e.g. the constructor or something else, so that the object is created only
once and reused all the time.
I hope this helps.
-J-
<code>
private void timer1_Tick(object sender, EventArgs e)
{
IntPtr wnd = GetForegroundWindow();
textBox1.Text = wnd.ToInt32().ToString();
StringBuilder text = new StringBuilder(2000);
SendMessage(wnd, WM_GETTEXT, new IntPtr(2000), text);
textBox2.Text = text.ToString();
}
/// <summary>
/// The GetForegroundWindow function returns a handle to the foreground
window.
/// </summary>
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam,
[MarshalAs(UnmanagedType.LPWStr)] StringBuilder lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
const int WM_GETTEXT = 0xD;
</code>
date: Fri, 15 Aug 2008 19:28:27 +0200
author: Luthgers, John am
|
|