1

これは難しい質問ではありませんが、質問をググってアイデアを理解するのは困難です。

問題は単純です。ユーザーがボタンを押すと、ユーザーが別のウィンドウをクリックするのを待つウィンドウフォームがあります。後で操作するために、選択したウィンドウ情報 (具体的には寸法) を保存します。

ボタンが押された後、ユーザーが次にクリックしたアクティブなウィンドウを取得するにはどうすればよいですか?

ありがとう

4

2 に答える 2

1

前景ウィンドウを取得する必要があります。

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, out Rectangle lpRect); 


Rect rect = new Rect ();
GetWindowRect(GetForegroundWindow(), out rect);

//calculate width and height from rect

using (Bitmap bitmap = new Bitmap(width, height))
{
    using (Graphics g = Graphics.FromImage(bitmap))
    {
        Size size = new System.Drawing.Size(width, height);
        g.CopyFromScreen(new Point(rect.Left, rect.Top), Point.Empty, size);
    }
    bitmap.Save("C://test.jpg", ImageFormat.Jpeg);
}

[StructLayout(LayoutKind.Sequential)]
public struct Rect {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

SOに関するこれら2つの回答でほとんどのコードを見つけました。質問に合わせて修正しました

キャプチャーウィンドウ

ウィンドウの幅と高さを見つける

于 2012-07-17T03:46:12.993 に答える
0

あなたの質問に興味があります私はこの小さな画面キャプチャアプリを作成しました。

奇妙な回避策があります:

  1. WinFormの外側でマウスの位置をキャプチャするために使用されるタイマーは奇妙ですが、グローバルシステムフックを使用するよりも実装が簡単でした。リンクからlibを使用するか、自分で実装してみてください。タイマーを使用するよりも必要はありません。さらに重要なことは、このフォームの継続的な再アクティブ化を削除できることです。
  2. CreateParamsのオーバーライドに関するSE情報のどこかで見つけましたが、それへのリンクが見つかりません。トラフフォームをクリックできます(追加されたパラメーターのすべてが必要なわけではないと思いますが、私が言ったようにリンクを失いました:))。
  3. ウィンドウの表示されている部分のみがキャプチャされ、それに重なっているすべてのウィンドウがキャプチャされます(おそらく、windowHandleを取得したため、何らかの方法で表示/アクティブ化しようとする可能性があります)。
  4. 一部のウィンドウでは、ウィンドウ内のコントロールを取得します。
  5. 提供されたアプリはおそらく非常に専門的ではなく安全ではなく、コンピュータを爆破する可能性があるので注意してください; P

    使用されるフォームは、不透明度が80%に設定されたボーダレスです。

使用形態

システムを使用する;
System.Collections.Genericを使用します。
System.ComponentModelを使用します。
System.Dataを使用します。
System.Drawingを使用します。
System.Linqを使用します。
System.Textを使用します。
System.Windows.Formsを使用します。
System.Runtime.InteropServicesを使用します。

名前空間WindowInfo {{ パブリック部分クラスCurrentWindow:フォーム {{ Rectangle GDIrect = new Rectangle(0、0、100、100); [DllImport( "user32.dll")] public static extern IntPtr WindowFromPoint(Point lpPoint); [DllImport( "user32.dll")] public static extern bool GetCursorPos(out Point lpPoint); [DllImport( "user32.dll")] private static extern IntPtr GetWindowRect(IntPtr hWnd、ref Rect rect); [DllImport( "user32.dll")] static extern IntPtr GetForegroundWindow(); [StructLayout(LayoutKind.Sequential)] public struct Rect {{ publicint左; public int Top; public int Right; public int Bottom; } public CurrentWindow() {{ InitializeComponent(); } 保護されたオーバーライドCreateParamsCreateParams {{ 得る {{ CreateParams baseParams = base.CreateParams; baseParams.ExStyle | =(int)( 0x00080000 | 0x08000000 | 0x00000080 | 0x00000020 ); baseParamsを返します。 } } public static IntPtr GetWindowUnderCursor() {{ ポイントptCursor=new Point(); GetCursorPos(out ptCursor); WindowFromPoint(ptCursor);を返します。 } public Bitmap CaptureScreen() {{ var result = new Bitmap(this.DisplayRectangle.Width、this.DisplayRectangle.Height); using(var g = Graphics.FromImage(result)) {{ g.CopyFromScreen(this.Location.X、this.Location.Y、0、0、this.DisplayRectangle.Size); } 結果を返します。 } private void timer1_Tick(オブジェクト送信者、EventArgs e) {{ IntPtr windowHandle = GetWindowUnderCursor(); Rect rect = new Rect(); GetWindowRect(windowHandle、ref rect); GDIrect = new Rectangle(rect.Left、rect.Top、rect.Right-rect.Left、rect.Bottom-rect.Top);

this.Location = new Point(GDIrect.Left, GDIrect.Top); this.Size = GDIrect.Size; this.Activate(); } private void CurrentWindow_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == 'c') { this.Visible = false; Bitmap bmp = CaptureScreen(); bmp.Save(Application.StartupPath + "\\example.png"); this.Visible = true; } else if (e.KeyChar == 'x') { this.Close(); } } } }

Uはそれをアプリに追加し、ボタンをクリックした後に実行する可能性があります。動作するはずですが、個別にテストしただけです。幸運を :)。

于 2012-07-17T19:00:55.457 に答える