MoveWindow and SetWindowPos is moving window for exact position?

SZ 21 Reputation points
2021-08-20T13:43:45.25+00:00

I tried to use MoveWindow and SetWIndowPos API

   [DllImport("user32.dll", SetLastError = true)]  
           public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);  

           [DllImport("user32.dll", EntryPoint = "SetWindowPos")]  
           public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);  

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

           [DllImport("user32.dll")]  
           public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);  

to set the window left one third, middle one third and right one third, however, it seems that the window still has some pixels on its left for my monitor. It is not exact (0,0) positon. I tried both SetWIndowPos and MoveWindow, they are the same. My monitor is Dell U3219Q 31.5 4K. Also I tried to use width / 3 as the width, but as you can see, there are still padding among them. What is the problem with MoveWindow and SetWIndowPos API?

![125028-image.png]2

![125075-image.png]3

Windows development | Windows API - Win32
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 122.6K Reputation points
    2021-08-21T08:19:26.133+00:00

    I think that the sizeable windows include borders, which are semi-transparent in Windows 10. You see these borders as gaps.

    The next example moves a window to a (0, 0, 500, 700) rectangle, taking into consideration the borders:

    [DllImport( "dwmapi" )]
    static extern int DwmGetWindowAttribute( IntPtr hwnd, Int32 dwAttribute, ref Rectangle pvAttribute, Int32 cbAttribute );
    
    [DllImport( "user32" )]
    static extern bool GetWindowRect( IntPtr hwnd, ref Rectangle lpRect );
    
    [DllImport( "user32" )]
    static extern bool PhysicalToLogicalPointForPerMonitorDPI( IntPtr hwnd, ref Point lpRect );
    
    . . .
    
    Rectangle required_rect = new Rectangle( 0, 0, 500, 700 );
    
    Rectangle wrect = new Rectangle( );
    Rectangle xrect = new Rectangle( );
    
    GetWindowRect( hwnd, ref wrect );
    DwmGetWindowAttribute( hwnd, 9, ref xrect, Marshal.SizeOf( typeof( Rectangle ) ) );
    
    Point wtl = new Point( wrect.Left, wrect.Top );
    Point wbr = new Point( wrect.Right, wrect.Bottom );
    
    Point xtl = new Point( xrect.Left, xrect.Top );
    Point xbr = new Point( xrect.Right, xrect.Bottom );
    
    PhysicalToLogicalPointForPerMonitorDPI( hwnd, ref xtl );
    PhysicalToLogicalPointForPerMonitorDPI( hwnd, ref xbr );
    
    
    Rectangle adjusted_rect = new Rectangle(
       required_rect.X - ( xtl.X - wtl.X ),
       required_rect.Y - ( xtl.Y - wtl.Y ),
       required_rect.Width + ( xtl.X - wtl.X ) + ( wbr.X - xbr.X ),
       required_rect.Height + ( xtl.Y - wtl.Y ) + ( wbr.Y - xbr.Y ) );
    
    MoveWindow( hwnd, adjusted_rect.X, adjusted_rect.Y, adjusted_rect.Width, adjusted_rect.Height, true );
    

    If it works, then use this technique for your other sizeable windows.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.