2010-01-19 42 views
3

我在一個相關的問題「回答」這個 - 但它更多的是具有麻煩,我需要更近的答案我一個額外的問題...查找以前集中應用 - WinAPI的

基本上我有一個應用程序在屏幕上保持打開狀態,用戶在進入三個第三方應用程序之一後,可以按下我應用程序上的按鈕。

當他們點擊我應用程序上的按鈕時,我需要確定他們上次使用的三個應用程序中的哪一個,以便知道要與哪個數據庫進行通信。我沿着查看GetForeGroundWindow和GetWindow的路線走了,但是我從GetWindow得到的Window句柄總是指向一個標題爲M的窗口。我使用了Managed Windows API工具中的Winternal Explorer工具,並且可以找到M句柄返回並且它是我以後的過程的'孩子' - 但是從這個句柄我不能得到進程名稱。

我已經完成了一個小例子應用程序使用簡單的窗體形式 - 我讚美它,然後使記事本的焦點,然後單擊我的按鈕,我得到的句柄 - 但當看到所有進程的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(); 
     } 
    } 
} 

回答

2

您可以使用GetWindowThreadProcessId從(子)窗口句柄得到進程ID:

uint lastProcess; 
GetWindowThreadProcessId(lastWindow, out lastProcess); 
0

嘗試覆蓋每個程序的WndProc(或添加一個IMessageFilter),並在發送特定消息時返回「應用程序ID」。然後只需在窗口句柄上使用SendMessage即可獲取應用程序ID。

2

Pent Ploompuu - 那真是太棒了 - 出色的工作!乾杯

爲別人 - 這是我的測試功能結束什麼看起來像:

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(); 
    }