Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Visual Studio Tools - Window Positioning

Status
Not open for further replies.

Borvik

Programmer
Jan 2, 2002
1,392
0
0
US
When looking for how to position a adding window using Visual Studio Tools for Dynamics GP - I came across Dave's blog: specifically the blog post But I wasn't able to find much more than that.

Sure that I could find the position of a GP window, I tried building something - and this appears to work:

Usage:
Code:
WindowHelper.PositionForm(this, "Sales Payment Entry"); // From within the Form Load event
That would center the form according to the "Sales Payment Entry" window - if it was open, and the screen if it's not open.

Here is the helper classes
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.Dexterity.Shell;
using System.Runtime.InteropServices;

namespace OurNamespace.Utilities
{
    public class ApiWindow
    {
        public string MainWindowTitle = "";
        public IntPtr hWnd;
    }

    public class WindowHelper
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr 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
        }

        public static IntPtr GetGPWindow(string name)
        {
            if (name == null || name == string.Empty || name.Trim().Length < 1) return IntPtr.Zero;

            Process[] procs = Process.GetProcessesByName("Dynamics");
            Process p = null;
            if (procs.Length == 1) p = procs[0];
            if (p == null) return IntPtr.Zero;

            WindowsEnumerator we = new WindowsEnumerator();
            List<ApiWindow> gpWindows = we.GetProcessWindows(p);
            IntPtr ret = IntPtr.Zero;
            foreach (ApiWindow win in gpWindows)
            {
                if (win.MainWindowTitle.ToLower().Contains(name.ToLower()))
                {
                    ret = win.hWnd;
                    break;
                }
            }
            return ret;
        }
        public static System.Drawing.Rectangle GetGPWindowBounds(string name)
        {
            IntPtr window = GetGPWindow(name);
            if (window == IntPtr.Zero) return Screen.PrimaryScreen.Bounds;

            RECT rct;
            if (!GetWindowRect(window, out rct)) return Screen.PrimaryScreen.Bounds;
            return new System.Drawing.Rectangle(rct.Left, rct.Top, rct.Right - rct.Left + 1, rct.Bottom - rct.Top + 1);
        }

        public static void PositionForm(DexUIForm form)
        {
            PositionForm(form, string.Empty);
        }
        public static void PositionForm(DexUIForm form, string basedOn)
        {
            System.Drawing.Rectangle rect = GetGPWindowBounds(basedOn);
            int x = (int)Math.Round((double)((rect.Width / 2) - (form.Width / 2)), 0) + rect.X;
            int y = (int)Math.Round((double)((rect.Height / 2) - (form.Height / 2)), 0) + rect.Y;
            form.SetBounds(x, y, form.Width, form.Height);
        }
    }

    public class WindowsEnumerator
    {
        private delegate bool EnumCallBackDelegate(IntPtr hwnd, int lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetShellWindow();

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern UInt32 GetWindowThreadProcessId(IntPtr hWnd, out UInt32 lpdwProcessId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool EnumWindows(EnumCallBackDelegate callback, int lParam);

        private IntPtr hShellWindow = GetShellWindow();

        private List<ApiWindow> _windows = new List<ApiWindow>();

        public List<ApiWindow> GetProcessWindows(Process p)
        {
            _windows = new List<ApiWindow>();
            EnumWindows(EnumWindowProc, p.Id);
            return _windows;
        }

        private bool EnumWindowProc(IntPtr hwnd, int lParam)
        {
            if (hwnd != hShellWindow)
            {
                if (!IsWindowVisible(hwnd)) return true;
                int length = GetWindowTextLength(hwnd);
                if (length == 0) return true;
                UInt32 windowPid;
                GetWindowThreadProcessId(hwnd, out windowPid);
                if (windowPid != lParam) return true;
                StringBuilder title = new StringBuilder(length);
                GetWindowText(hwnd, title, (length + 1));
                ApiWindow window = new ApiWindow();
                window.hWnd = hwnd;
                window.MainWindowTitle = title.ToString();
                _windows.Add(window);
            }
            return true;
        }

    }
}

I hope others find this useful.
 
Cool

I added a comment to the original post at


David Musgrave [MSFT]
Escalation Engineer - Microsoft Dynamics GP
Microsoft Dynamics Support - Asia Pacific

Microsoft Dynamics (formerly Microsoft Business Solutions)

mailto:David dot Musgrave at microsoft dot com

Any views contained within are my personal views and not necessarily Microsoft policy.
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top