Постоянно неправильный размер окна переднего плана

Я пишу программу на С#, которая реализует хуки мыши и клавиатуры, и после нажатия указанной клавиши она пойдет и захватит окно переднего плана и сохранит его x, y, высоту и ширину в xml файл.

Я не уверен, что не так, но я продолжаю получать неправильные размеры и неправильные параметры.

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

Ниже приведен соответствующий код.

Стандартные декларации:

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

                    }
                }
            }
        }

EDIT: я пытался использовать как общедоступную структуру RECT, так и Rectangle, значения с RECT, которые я получаю, кажутся случайными, я имею в виду слева и сверху, а также высоту и ширину, иногда он находит правильные точки, но иногда кажутся совершенно случайными. Значения, которые я получаю с помощью Rectangle, кажется, имеют правильные значения слева и сверху, но возвращают неправильную высоту и ширину.


person Dmitris    schedule 28.09.2011    source источник
comment
Каким образом возвращаемые значения неверны? Почему не проверяете на ошибки?   -  person David Heffernan    schedule 28.09.2011
comment
Он просто возвращает неправильные значения, как бы странно это ни звучало. Я не уверен, как это можно проверить на ошибки, я просто получаю неправильные значения.   -  person Dmitris    schedule 28.09.2011
comment
Дайте нам нечто большее. Все значения равны нулю? Они все отстают на 2 или 3? Они все -666? Помогите.   -  person David Heffernan    schedule 28.09.2011
comment
Я добавил правку в конец темы.   -  person Dmitris    schedule 28.09.2011


Ответы (2)


Я наконец нашел решение. Выяснилось, что опубликую это здесь, если кто-нибудь когда-нибудь столкнется с такой же проблемой.

В итоге я использовал GetWindowInfo вместо GetWindowRect, и это работает как шарм.

Взял пример кода и статью, которую нашел в Интернете http://kenneththorman.blogspot.com/2010/08/c-net-active-windows-size-helper.html

Спасибо всем, кто пытался помочь.

person Dmitris    schedule 29.09.2011

Использование System.Drawing.Rectangle неверно. Поля не совпадают. Ваше определение RECT верно.

Я немного предполагаю, но ваша проблема может быть связана с комментарием внизу файла GetWindowRect раздел MSDN.

Приложения под Vista, которые не связаны с WINVER=6, получат здесь вводящий в заблуждение набор значений, которые не учитывают дополнительные отступы из «стеклянных» пикселей, которые Vista Aero применяет к окну. Похоже, это происходит даже в Aero Basic (без Glass), чтобы сохранить постоянство размеров. Обходной путь (если вы не хотите устанавливать WINVER = 6), похоже, заключается в динамической привязке к dwmapi.dll и использовании GetProcAddress() для получения функции DwmGetWindowAttribute() и вызове ее с аргументом DWMWA_EXTENDED_FRAME_BOUNDS для запроса подлинного окна. размеры рамы.

person David Heffernan    schedule 28.09.2011
comment
Я использую Win7, но я думаю, что это то же самое, что и Vista. Не могли бы вы предоставить пример кода (просто то, что я могу посмотреть и понять) или ссылку на какой-нибудь пример. Спасибо. - person Dmitris; 28.09.2011
comment
Что ж, я думаю, на вас лежит обязанность в первую очередь проверить, правдоподобно ли это объяснение. Я не хочу тратить свое время, если возвращаемые неправильные значения оказываются чем-то другим. Кроме того, вы должны иметь возможность довольно легко p/invoke к этому API. - person David Heffernan; 28.09.2011
comment
Ты прав! Я просто выключил aero и переключился на основную тему окна, которая выглядит как старая XP, и проблема все еще существует. Я думаю, это где-то в моем коде. - person Dmitris; 28.09.2011