Поиск ранее сфокусированного приложения - WinAPI - PullRequest
3 голосов
/ 19 января 2010

Я «ответил» на этот вопрос в связанном вопросе, но это скорее дополнительный вопрос, с которым у меня возникли проблемы, и мне нужны более свежие ответы ...

По сути, у меня есть приложение, которое остается открытым на экране, и пользователь может нажать кнопку в моем приложении, как только они войдут в одно из трех сторонних приложений.

Когда они нажимают кнопку в моем приложении, мне нужно определить, какое из трех приложений они использовали в последний раз, чтобы узнать, с какой базой данных можно общаться. Я пошел по пути просмотра GetForeGroundWindow и GetWindow, однако дескриптор окна, который я получаю из GetWindow, всегда ссылается на окно с заголовком M. Я использовал инструмент Winternal Explorer из инструментов Managed Windows API и могу найти, что дескриптор M возвращается, и это «потомок» процесса, за которым я следую, но из этого дескриптора я не могу получить имя процесса.

Я создал небольшой пример приложения с использованием простых форм Windows - и я запускаю его, затем фокусирую Блокнот, затем нажимаю на мою кнопку, и я получаю ручку - но, глядя на MainWindowHandle всех процессов, он отсутствует в списке, но с помощью Winternal Explorer я вижу, что это подпроцесс процесса блокнота.

Любые предложения о том, почему я получаю только этот дескриптор подпроцесса вместо фактического дескриптора процесса ??

Пример кода приведен ниже - выполняется на компьютере с Windows XP sp 3

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)
        {
            IntPtr thisWindow = GetForegroundWindow();
            IntPtr lastWindow = GetWindow(thisWindow, 2);

            tbThisWindow.Text = thisWindow.ToString();
            tbLastWindow.Text = lastWindow.ToString();
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 19 января 2010

Pent Ploompuu - это было замечательно - отличная работа! * Приветствия * 1001

Для кого-то еще - вот как моя тестовая функция выглядела так:

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();
    }
2 голосов
/ 19 января 2010

Вы можете использовать GetWindowThreadProcessId, чтобы получить идентификатор процесса из (под) дескриптора окна:

uint lastProcess;
GetWindowThreadProcessId(lastWindow, out lastProcess);
0 голосов
/ 19 января 2010

Попробуйте переопределить WndProc (или добавить IMessageFilter) для каждой из программ и вернуть «идентификатор приложения» при отправке определенного сообщения. Затем просто используйте SendMessage в дескрипторе окна, чтобы получить идентификатор приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...