Finding previously focused application - WinAPI
I 'answered' this in a related question - but it is more of an additional question that I having trouble with and I need more recent answers...
Basically I have an application that stays open on the screen and the user can press a button on my app once they have made an entry into one of three 3rd party applications.
When they click the button on my app, I need to determine which of the three applications they last used in order to know which database to talk to. I have gone down the route of looking at GetForeGroundWindow and GetWindow however the Window handle I get from GetWindow always refers to a window with title M. I have used the Winternal Explorer tool from the Managed Windows API tools and I can locate the M handle being returned and it is a 'child' of the process that I am after - but from this handle I cant get the process name.
I have done up a small example app using simple windows forms - and I lauch it and then make Notepad the focus and then click on my button and I get the handle - but when looking at the MainWindowHandle of all the processes, it is not listed, but using Winternal Explorer I can see that is a sub process of the notepad process.
Any suggestions on why I am only getting this subprocess handle returned instead of the actual process handle??
Sample code is below - being run on a Windows XP sp 3 machine
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestWindowsAPI
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
开发者_Python百科IntPtr thisWindow = GetForegroundWindow();
IntPtr lastWindow = GetWindow(thisWindow, 2);
tbThisWindow.Text = thisWindow.ToString();
tbLastWindow.Text = lastWindow.ToString();
}
}
}
You can use GetWindowThreadProcessId
to get the process id from the (sub)window handle:
uint lastProcess;
GetWindowThreadProcessId(lastWindow, out lastProcess);
Pent Ploompuu - that was spot on - excellent work! Cheers
For anyone else - this is what my test function ended up looking like:
private void button1_Click(object sender, EventArgs e)
{
IntPtr thisWindow = GetForegroundWindow();
IntPtr lastWindow = GetWindow(thisWindow, 2);
uint processID = 0;
var parentWindow = GetWindowThreadProcessId(lastWindow, out processID);
tbThisWindow.Text = thisWindow.ToString();
tbLastWindow.Text = lastWindow.ToString();
tbParentWindow.Text = parentWindow.ToString();
tbLastProcess.Text = processID.ToString();
var processName = from cp in Process.GetProcesses() where cp.Id == processID select cp.ProcessName;
tbParentName.Text = processName.FirstOrDefault();
}
Try overriding the WndProc (or adding an IMessageFilter) for each of the programs and returning an "app ID" when a particular message is sent. Then just use SendMessage on the window handle to get the app ID.
精彩评论