开发者

Getting foreground window size wrong all the time

I am writing a program on c# that implements mouse and keyboard hooks and once a specified key clicked it will go and grab foreground window and save it's x,y, height and width into xml file.

I am not sure what is wrong, but I keep getting wrong sizes and wrong parameters.

I would appreciate a help on this one as I been struggling for two days with it now.

Bellow is relevant code.

Standard declarations:

//rectangle for the windows size
        [StructLayout(Layout开发者_StackOverflowKind.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);

And the relevant code itself

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: I have tried to use both public struct RECT and Rectangle, the values with RECT I receive seems to be random, I mean left and top and height and width, sometimes it will find the proper points , but sometimes it seems completely random ones. The values I receive with Rectangle seems to have proper left and top but return wrong height and width.


I finally found a solution. Figured out will post it here if anyone ever runs into same problem.

I ended up using GetWindowInfo instead of GetWindowRect and it is worked like charm.

Took the code example from and article I found online http://kenneththorman.blogspot.com/2010/08/c-net-active-windows-size-helper.html

Thanks to everyone who tried to help.


Using System.Drawing.Rectangle is incorrect. The fields do not match. Your definition of RECT is correct.

I'm guessing a little, but your problem could be related to the comment at the bottom of the GetWindowRect MSDN topic.

Apps under Vista that are not linked with WINVER=6 will receive a misleading set of values here, that do not account for the extra padding of "glass" pixels Vista Aero applies to the window. This appears to happen even in Aero Basic (without Glass) to retain sizing consistency. The workaround (if you don't want to set WINVER=6) seems to be to dynamically bind to dwmapi.dll and use GetProcAddress() to obtain the DwmGetWindowAttribute() function, and call it with the DWMWA_EXTENDED_FRAME_BOUNDS argument to request the genuine window frame dimensions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜