3

マウスとキーボードのフックを実装するプログラムを c# で作成しています。指定されたキーをクリックすると、フォアグラウンド ウィンドウが取得され、x、y、高さ、幅が xml ファイルに保存されます。

何が間違っているのかわかりませんが、間違ったサイズと間違ったパラメーターを取得し続けています。

私は今2日間苦労しているので、これについて助けていただければ幸いです。

以下は関連コードです。

標準宣言:

//rectangle for the windows size
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }


        //win API
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern bool SetForegroundWindow(IntPtr hwnd);

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);

そして、関連するコード自体

void mouseHook_MouseDown(object sender, MouseEventArgs e)
        {
            this.handle = GetForegroundWindow();   
        }

        #region keyboard pressed
        void keyboardHook_KeyDown(object sender, KeyEventArgs e)
        {            
            if (e.KeyCode == Keys.F9) //if slot selected
            {
                RECT Rect = new RECT();
                SetForegroundWindow(this.handle);
                //this.handle = GetForegroundWindow();    
                GetWindowRect(this.handle, ref Rect);

                Grid newSlot = new Grid();
                newSlot.topX = Rect.Top;
                newSlot.topY = Rect.Left;
                newSlot.width = Rect.Right - Rect.Left;
                newSlot.height = Rect.Bottom - Rect.Top;

                layoutGrid.Add(newSlot);
                lbl_slots.Text = layoutGrid.Count().ToString();
            }
            else if (e.KeyCode == Keys.F10) //if main stack slot selected
            {
                RECT Rect = new RECT();
                SetForegroundWindow(handle);
                GetWindowRect(GetForegroundWindow(), ref Rect);    
                for (int i = 0; i < layoutGrid.Count(); i++) //selecting slot for main stack
                {
                    layoutGrid[i].slot_number = i + 1; //setting slots numbers
                    if (layoutGrid[i].topX != Rect.Top && layoutGrid[i].topY != Rect.Left)
                        layoutGrid[i].is_stack = false;
                    else
                    {
                        layoutGrid[i].is_stack = true;
                        lbl_stackSlot.Text = (i + 1).ToString();

                    }
                }
            }
        }

編集: public struct RECT と Rectangle の両方を使用しようとしましたが、受け取る RECT の値はランダムに見えます。左と上、高さと幅を意味し、適切なポイントが見つかることもありますが、完全にランダムに見えることもあります. Rectangle で受け取った値は、適切な左と上を持っているようですが、間違った高さと幅を返します。

4

2 に答える 2

2

私はついに解決策を見つけました。誰かが同じ問題に遭遇した場合は、ここに投稿します。

GetWindowRectの代わりにGetWindowInfoを使用することになり、それは魅力のように機能します。

オンラインで見つけた記事とコード例を使用http://kenneththorman.blogspot.com/2010/08/c-net-active-windows-size-helper.html

助けてくれたみんなに感謝します。

于 2011-09-29T15:01:33.517 に答える
0

使い方System.Drawing.Rectangleが間違っています。フィールドが一致しません。あなたの定義RECTは正しいです。

少し推測していますが、問題はGetWindowRectMSDN トピックの下部にあるコメントに関連している可能性があります。

WINVER=6 でリンクされていない Vista の下のアプリは、Vista Aero がウィンドウに適用する「ガラス」ピクセルの余分なパディングを考慮していない、誤解を招く一連の値をここで受け取ります。これは、サイズの一貫性を維持するために、Aero Basic (Glass なし) でも発生するようです。回避策 (WINVER=6 を設定したくない場合) は、dwmapi.dll に動的にバインドし、GetProcAddress() を使用して DwmGetWindowAttribute() 関数を取得し、DWMWA_EXTENDED_FRAME_BOUNDS 引数を指定して呼び出して、正規のウィンドウを要求するようです。フレーム寸法。

于 2011-09-28T14:46:39.790 に答える