PC Review
Forums
Newsgroups
Microsoft DotNet
Microsoft Dot NET Framework Forms
Title bar of Windows form is stuck in resize state when x coordinates and top y coordinate of form are negative
Forums
Newsgroups
Microsoft DotNet
Microsoft Dot NET Framework Forms
Title bar of Windows form is stuck in resize state when x coordinates and top y coordinate of form are negative
![]() |
Title bar of Windows form is stuck in resize state when x coordinates and top y coordinate of form are negative |
|
|
Thread Tools | Rate Thread |
|
|
#1 |
|
Guest
Posts: n/a
|
Hello,
I think I found a bug in the Windows forms engine related to multiple monitors and I wonder if anyone saw that too. If yes, any workaround? Steps to reproduce: 1. connect two monitors to your PC, extend your desktop to both monitors 2. In the monitor settings dialog, drag monitor 2 so that it is to the left of monitor 1. This makes x screen coordinates of monitor 2 negative. Also make sure monitor 2 extends above monitor 1, so that top y coordinate is negative as well. This happens to be my default setup, I have a larger monitor to the left of my laptop screen. 3. Open a sizeable modal dialog in a dotnet 1.1 Windows forms application. 4. Click and hold the left mouse button on the title bar of the dialog, move it to monitor 2. 5. Now release the mouse. 6. Move the mouse over the title bar area, notice what happens. What I see: - If the window is on the left screen and its top is above the top border of monitor 1, mouse cursor is always NW-SE resize cursor over the title bar unless the dialog is maximized. If the title bar is partially above the y=0 coordinate, the strange behavior is only apparent for the part where y is negative. - it is no longer possible to move the dialog by dragging the title bar. Attempting to do so resizes the window rather than moving it - it is not possible to use the [x] button to close the window unless it is maximized - normal behavior will only resume after you manage to move the window back to monitor 1 by resizing it. This will not be possible at all unless the "show in taskbar" property of the Window is set and maximize is allowed. |
|
|
|
#2 |
|
Guest
Posts: n/a
|
I did some more testing, my problem only happens in very specific
circumstances. Dotnet 1.1 or 2.0 does not make any difference in the behaviour. Problem seems to be related to these circumstances: - host application is non-dotnet and opens the form through COM interop - form is opened using ShowDialog I have made a test project demonstrating the problem: http://support.decos.nl/TestModal2003.zip (dotnet 1.1) http://support.decos.nl/TestModal2005.zip (dotnet 2.0) Full source code is included in the zip file. Usage: - start TestHost\Project1.exe - click [ShowDialog]: has problem - click [Show]: does not have problem ShowDialog eventually does this: dlg.ShowDialog(new WindowWrapper(m_iHwnd)); It passes the hwnd of the external owner window as m_iHwnd. To make things even more interesting the software first creates a new STA thread in which the dialog object is created. This is required because the form hosts an Acrobat ActiveX control and that needs a STA thread. The real host application is multithreaded so that the calling thread would usually be MTA. Show does this: dlg.Show(); while(dlg.Visible) { Application.DoEvents(); Thread.Sleep(100); } When this is called, the problem wiht the title bar does not happen. Show also waits for the window to close (simulating one property of a modal dialog), but what I miss is a method to make the external non-dotnet application window the owner. I tried this: dlg.Owner = (Form)Control.FromHandle((IntPtr)m_iHwnd); dlg.Show(); It does show the dialog, but it does not behave as if the host application window is the owner (e.g., the "modal" window does not stay on top of the application window). The host application varies, it can be an old MFC C++ application or a Microsoft Office applcation (we have to support all Office versions from Office 97 onward), so we do prefer the real ShowDialog method for the sake of stability. Best regards, Berend Ciaran O''''Donnell schreef: > Doesnt happen to me in .NET 2 so try upgrading > > -- > Ciaran O''''Donnell > http://wannabedeveloper.spaces.live.com > > > "b.engelbrecht@gmail.com" wrote: > > > Hello, > > > > I think I found a bug in the Windows forms engine related to multiple > > monitors and I wonder if anyone saw that too. If yes, any workaround? > > > > Steps to reproduce: > > 1. connect two monitors to your PC, extend your desktop to both > > monitors > > 2. In the monitor settings dialog, drag monitor 2 so that it is to the > > left of monitor 1. This makes x screen coordinates of monitor 2 > > negative. Also make sure monitor 2 extends above monitor 1, so that top > > y coordinate is negative as well. This happens to be my default setup, > > I have a larger monitor to the left of my laptop screen. > > 3. Open a sizeable modal dialog in a dotnet 1.1 Windows forms > > application. > > 4. Click and hold the left mouse button on the title bar of the dialog, > > move it to monitor 2. > > 5. Now release the mouse. > > 6. Move the mouse over the title bar area, notice what happens. > > > > What I see: > > - If the window is on the left screen and its top is above the top > > border of monitor 1, mouse cursor is always NW-SE resize cursor over > > the title bar unless the dialog is maximized. If the title bar is > > partially above the y=0 coordinate, the strange behavior is only > > apparent for the part where y is negative. > > - it is no longer possible to move the dialog by dragging the title > > bar. Attempting to do so resizes the window rather than moving it > > - it is not possible to use the [x] button to close the window unless > > it is maximized > > - normal behavior will only resume after you manage to move the window > > back to monitor 1 by resizing it. This will not be possible at all > > unless the "show in taskbar" property of the Window is set and maximize > > is allowed. > > > > |
|
|
|
#3 |
|
Guest
Posts: n/a
|
By the way, the test project of course needs to be registered for COM
interop before the test host works. Just recompile it once with your preferred version of Visual Studio, or use regasm. |
|
|
|
#4 |
|
Guest
Posts: n/a
|
Hello,
Since I did not get a useful response, I have looked into the implementation of System.Windows.Forms.Form myself, aided by Lutz Roeder's .NET Reflector. I found a bug in the framework implementation of WmNCHitTest, which I think may be related to the problem that I have. The implementation in System.Windows.Forms.dll v1.0.5000.0 is the following: private void WmNCHitTest(ref Message m) { bool flag1 = true; if (this.formState[Form.FormStateRenderSizeGrip] != 0) { int num1 = NativeMethods.Util.LOWORD(m.LParam); int num2 = NativeMethods.Util.HIWORD(m.LParam); Rectangle rectangle1 = base.Bounds; if (((num1 >= ((rectangle1.X + rectangle1.Width) - 0x10)) && (num1 <= (rectangle1.X + rectangle1.Width))) && ((num2 >= ((rectangle1.Y + rectangle1.Height) - 0x10)) && (num2 <= (rectangle1.Y + rectangle1.Height)))) { m.Result = (IntPtr) 0x11; flag1 = false; } } if (flag1) { base.WndProc(ref m); } } The bug is in these two lines, that will always result in positive numbers: int num1 = NativeMethods.Util.LOWORD(m.LParam); int num2 = NativeMethods.Util.HIWORD(m.LParam); However, the documentation of WM_NCHITTEST in the Win32 library specified the following: lParam: The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the screen. The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the screen. Actually, the coordinate is relative to the upper left coordinate of the *primary* screen. This means that in a multiple screen setup, LOWORD and HIWORD may signify negative numbers. The documentation of WM_NCHITTEST tells you how this should be handled: Use the following code to obtain the horizontal and vertical position: xPos = GET_X_LPARAM(lParam); yPos = GET_Y_LPARAM(lParam); The GET_X_LPARAM and GET_Y_LPARAM macros are defined as follows: #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) >From this it follows that the indicated lines in the framework should have been: int num1 = NativeMethods.Util.SignedLOWORD(m.LParam); int num2 = NativeMethods.Util.SignedHIWORD(m.LParam); The same bug is present in v2.0.0.0 of the assembly. Of course it is not feasible to correct the framework for an obscure bug like this, but would there be any way to allow me to use a private implementation of the hit test to correct the behavior in my software? Best regards, Berend b.engelbrecht@gmail.com schreef: > I did some more testing, my problem only happens in very specific > circumstances. Dotnet 1.1 or 2.0 does not make any difference in the > behaviour. > > Problem seems to be related to these circumstances: > - host application is non-dotnet and opens the form through COM interop > - form is opened using ShowDialog > > I have made a test project demonstrating the problem: > http://support.decos.nl/TestModal2003.zip (dotnet 1.1) > http://support.decos.nl/TestModal2005.zip (dotnet 2.0) > > Full source code is included in the zip file. > > Usage: > - start TestHost\Project1.exe > - click [ShowDialog]: has problem > - click [Show]: does not have problem > > ShowDialog eventually does this: > > dlg.ShowDialog(new WindowWrapper(m_iHwnd)); > > It passes the hwnd of the external owner window as m_iHwnd. To make > things even more interesting the software first creates a new STA > thread in which the dialog object is created. This is required because > the form hosts an Acrobat ActiveX control and that needs a STA thread. > The real host application is multithreaded so that the calling thread > would usually be MTA. > > Show does this: > dlg.Show(); > while(dlg.Visible) > { > Application.DoEvents(); > Thread.Sleep(100); > } > > When this is called, the problem wiht the title bar does not happen. > Show also waits for the window to close (simulating one property of a > modal dialog), but what I miss is a method to make the external > non-dotnet application window the owner. I tried this: > > dlg.Owner = (Form)Control.FromHandle((IntPtr)m_iHwnd); > dlg.Show(); > > It does show the dialog, but it does not behave as if the host > application window is the owner (e.g., the "modal" window does not stay > on top of the application window). The host application varies, it can > be an old MFC C++ application or a Microsoft Office applcation (we have > to support all Office versions from Office 97 onward), so we do prefer > the real ShowDialog method for the sake of stability. > > Best regards, > > Berend > > > > Ciaran O''''Donnell schreef: > > > Doesnt happen to me in .NET 2 so try upgrading > > > > -- > > Ciaran O''''Donnell > > http://wannabedeveloper.spaces.live.com > > > > > > "b.engelbrecht@gmail.com" wrote: > > > > > Hello, > > > > > > I think I found a bug in the Windows forms engine related to multiple > > > monitors and I wonder if anyone saw that too. If yes, any workaround? > > > > > > Steps to reproduce: > > > 1. connect two monitors to your PC, extend your desktop to both > > > monitors > > > 2. In the monitor settings dialog, drag monitor 2 so that it is to the > > > left of monitor 1. This makes x screen coordinates of monitor 2 > > > negative. Also make sure monitor 2 extends above monitor 1, so that top > > > y coordinate is negative as well. This happens to be my default setup, > > > I have a larger monitor to the left of my laptop screen. > > > 3. Open a sizeable modal dialog in a dotnet 1.1 Windows forms > > > application. > > > 4. Click and hold the left mouse button on the title bar of the dialog, > > > move it to monitor 2. > > > 5. Now release the mouse. > > > 6. Move the mouse over the title bar area, notice what happens. > > > > > > What I see: > > > - If the window is on the left screen and its top is above the top > > > border of monitor 1, mouse cursor is always NW-SE resize cursor over > > > the title bar unless the dialog is maximized. If the title bar is > > > partially above the y=0 coordinate, the strange behavior is only > > > apparent for the part where y is negative. > > > - it is no longer possible to move the dialog by dragging the title > > > bar. Attempting to do so resizes the window rather than moving it > > > - it is not possible to use the [x] button to close the window unless > > > it is maximized > > > - normal behavior will only resume after you manage to move the window > > > back to monitor 1 by resizing it. This will not be possible at all > > > unless the "show in taskbar" property of the Window is set and maximize > > > is allowed. > > > > > > |
|
![]() |
|
| Thread Tools | |
| Rate This Thread | |
|
|

Main Page 

