2011-02-24 19 views
2
[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect); 

[StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int Left;  // x position of upper-left corner 
    public int Top;   // y position of upper-left corner 
    public int Right;  // x position of lower-right corner 
    public int Bottom;  // y position of lower-right corner 
} 

foreach (Process pr in Process.GetProcesses()) 
{ 
    RECT rc; 
    GetWindowRect(???, out rc); 

"???"にはどうすればよいですか? 。それはHandleRefオブジェクトを置く必要があると私に伝えますが、ProcessメソッドからHandleRefオブジェクトを取得する方法はわかりません。C# - user32.dll - GetWindowRectの問題

+1

あなたがステップをスキップしました。最初にウィンドウからネイティブハンドルを取得する必要があります。たとえば、ウィンドウがアプリケーション内のC#メインフォーム(WinFormsアプリケーションを前提としている)であれば、新しい 'HandleRef(this、this.Handle); 'を使用します;まず、問題のウィンドウへのハンドルを取得する必要があります.Handleはそうでない可能性が高い)。 –

答えて

0

プロセスハンドルは必要ありませんが、ウィンドウのハンドルです。あなたは窓があなたのプロセスですでにウィンドウの座標が必要な場合

あなたがPInvokeのhttp://pinvoke.net/default.aspx/user32/GetWindowRect.html

+0

私のアプリケーションだけでなく、すべてのプロセスのハンドルを知る必要があります。 – xoromer

+1

@ Sergey:もしあなたがそのドキュメントを読んでいれば、それはここでは当てはまりません。これはプロセスハンドルであり、ウィンドウハンドルではありません。 –

+0

あなたのリンクはOPを助けません(明らかにすでにそれを見つけた人)。アプリケーション内のフォームのウィンドウハンドルを取得する方法のみを示します。これがユースケースだった場合は、GetWindowRectをまったく使用する必要はありません。 .NETフォームはすでにあなたにその情報を与えることができます。 -1 –

10

上のいくつかの例を使用することができ、プロセスを列挙する必要はありませんウィンドウハンドルを取得するための他の方法があります。

WinFormsウィンドウでは、Handleプロパティを使用します。 WPFアプリケーションの場合

System.Windows.Forms.Control ... Handle Property @ MSDN

、あなたは.NETから直接アクセスすることはできませんウィンドウを列挙しようとしている場合WindowInteropHelper

System.Windows.Interop ... WindowInteropHelper Class @ MSDN

を使用します。あなたのコードの範囲外のトップレベルウィンドウを作成するサードパーティのコントロールから、win32 EnumWindows関数を使って列挙することができます。 EnumWindowsのためのP /呼び出し用

EnumWindows (Win32) @ MSDN

署名はここに用意されています

User32.dll EnumWindows @ pinvoke.net

を追加しました:あなたはすべてのウィンドウに&関連するプロセスを列挙したいよう

が見えます。 EnumWindowsを使用し、GetWindowThreadProcessIdを呼び出して、各ウィンドウに関連するプロセス&管理されていないスレッドIDを取得します。

GetWindowThreadProcessId (Win32) @ MSDN

P /呼び出しの署名がここにあります:

User32.dll GetWindowThreadProcessId @ pinvoke.net

最後に、あなたは静的メソッドGetProcessByIdを介してプロセスオブジェクトを取得することができます。

Process.GetProcessById @ MSDN

を追加しました(#2):

ここでウィンドウを列挙することができ、短いコンソールプログラム、プロセス&スレッドIDです。あなたのスニペットとはいくつか違いがあります。

  1. 私はHandleRefではなくIntPtrを使用します。他の人が指摘しているように、これはあなたのために混乱するかもしれません。
  2. return属性を指定しませんでした。これが必要な場合は、再度追加することができます。
  3. 私は管理者として実行しています。ユーザーレベルの権限で実行している場合は、動作が異なる場合があります。働くかもしれない新しいHandleRef(PR、pr.MainWindowHandle)を使用して

C# Source Code Example @ gist.github

+0

唯一の有益な答え+1 –

+0

ありがとう!私は混乱しています。うん、それは私の別のプロセスのウィンドウのプロパティにアクセスすることができないように見える。 – xoromer

+0

私はサンプルを得ることができた。私は自分のマシン上で管理者として実行しています。あなたの環境のテストプロジェクトで試してみるために、ソースコードへのリンクを投稿します。 – meklarian

2

。あなたのプログラムには実際にメインウィンドウがあると仮定します。この情報を取得する方法は間違いありません。

あなたのforeachループは、Process.GetCurrentProcess()でコンパイルされずに動作する必要があります。すべてのプロセスを反復しようとするとコードが爆発するので、情報を共有することについてあまり気にしない特権システムプロセスが得られます。あなたがこれをやろうとしている理由を推測することは不可能です。 EnumWindowsを使用して、デスクトップ上のすべてのトップレベルウィンドウを列挙します。

+0

HandleRef(pr、pr.MainWindowHandle)が機能しません。 ありがとうございますProcess.GetCurrentProcess()。私はそれをfix'd。 – xoromer

+2

さて、GetWindowRect()の引数をIntPtrに変更してください。とにかくHandleRefはまったく必要ありません。 –

+0

Didnt work。 。 。 。 – xoromer

1

これは動作しますが、最初にあなたはFindWindowExようWINAPI関数を使用して、ウィンドウのHWNDのIntPtrを見つける必要がある:

[DllImport("user32.dll")] 
public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); 

Rect r = new Rect(); 
GetWindowRect(hwnd, ref r);