Rad Form Location by Code

3 posts, 0 answers
  1. David
    David avatar
    14 posts
    Member since:
    Jul 2008

    Posted 14 Jul 2009 Link to this post

    Hi:

    I'm having trouble when I try to change my rad form location. I wrote a code to calculate the new form position by limit the x an y position to the screen boundaries. If the user try to put the form out of the boundaries, the code reasign the location to make my form fully visible. Here's my code:

      private void FormPrincipal_LocationChanged(object sender, EventArgs e)
            {
                if (!movedByCode)
                {
                    movedByCode = true;
                    Point puntoActual = DeviceAuxiliar.ChangeLocationForm(this.Location, this.Right, this.Bottom);
                    this.Location = puntoActual;

                    this.Location = puntoActual;
                   movedByCode = false;
                }
            }

    The issues are:
    1- Do I have to code Fom_LocationChanged or Form_Move?
    2- When my code runs, it doesn't change the form's location. It simply does not work, but if I duplicate de line this.Location = puntoActual;  it works, but with to much flickering. I'm trying to use the movedByCode flag in order to no execute twice this metod, but this does not happen neither.

    Can you help me?

    Thanks.


  2. Deyan
    Admin
    Deyan avatar
    2041 posts

    Posted 16 Jul 2009 Link to this post

    Hello David,

    Thanks for contacting us and for your question.

    In order to implement such a behavior you will have to override the WndProc method of the form and process the WM_WINDOWPOSCHANGING nofitication. This is not that complicated actually.

    I have prepared a sample code snippet for you to demonstrate how to achieve this:

    [StructLayout(LayoutKind.Sequential)]  
        public struct WINDOWPOS  
        {  
            public IntPtr hwnd;  
            public IntPtr hwndInsertAfter;  
            public int x;  
            public int y;  
            public int cx;  
            public int cy;  
            public uint flags;  
        }  
     
        public partial class Form1 : RadForm  
        {  
            private const int WM_WINDOWPOSCHANGING = 0x46;  
     
            public Form1()  
            {  
                InitializeComponent();  
            }  
     
            protected override void WndProc(ref Message m)  
            {  
     
                if (m.Msg == WM_WINDOWPOSCHANGING)  
                {  
                    WINDOWPOS pos = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));  
     
                    if (pos.x >= Screen.PrimaryScreen.WorkingArea.Width - this.Width)  
                    {  
                        pos.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width;  
                    }  
     
                    if (pos.x <= 0)  
                    {  
                        pos.x = 0;  
                    }  
     
                    if (pos.y <= 0)  
                    {  
                        pos.y = 0; ;  
                    }  
     
                    if (pos.y >= Screen.PrimaryScreen.WorkingArea.Height - this.Height)  
                    {  
                        pos.y = Screen.PrimaryScreen.WorkingArea.Height - this.Height;  
                    }  
     
                    Marshal.StructureToPtr(pos, m.LParam, true);  
                }  
     
                base.WndProc(ref m);  
            }  
     
        } 

    What I am doing is overriding the WndProc method of the base form and checking whether the WM_WINDOWPOSCHANGING notification is sent (the code for which is 0x46). This notification is sent each time the location of a window is about to change (the ideal moment to decide whether the change will be accepted or not). If the WM_WINDOWPOSCHANGING notification is sent I check whether the form's new bounds will fit in the WorkingArea of my screen and if not, I change the X and Y coordinates accordingly so that the form remains visible on the screen.

    The tricky moment here is that you will have to use the WINDOWPOS structure in order to read the information from the WM_WINDOWPOSCHANGING notification. As you can see, I am using the Marshal class to read the information from the unmanaged pointer and cast it to the WINDOWPOS structure. At the and, by using the same class, I store the updated location of the form from the structure in the Lparam property of the Message object (which actually represents the context of the WM_WINDOWPOSCHANGING notification). In this way I directly determine the new location of the form before it is actually applied to it.

    I have created the WINDOWPOS structure for you. Please note the StructLayout attribute on the top of the declaration.

    However, we will consider integrating the above functionality in RadForm for future releases so that you can just set a property to enable it.

    I hope this is helpful.

    Do not hesitate to write back if you need further assistance.

    Sincerely yours,
    Deyan
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. David
    David avatar
    14 posts
    Member since:
    Jul 2008

    Posted 16 Jul 2009 Link to this post

    Thanks a lot, y work great! It would be very useful as a property for future releases.

    Thanks
Back to Top