none
Enable Windows + Arrow keys to snap windows for form with no title bar - VB.NET RRS feed

  • Question

  • Hi,

    I have a Windows Forms VB application with the following properties:

    • ControlBox = False
    • FormBorderStyle = Sizable
    • Text = ""

    I would like to be able to use Windows + arrow keys to snap the window to fit one side of the screen as normal, but this doesn't seem to work without the title bar.

    Is there a workaround for this in VB.NET?

    Thanks in advance.


    ---- JDS404 ---- Check out my blog at www.interlinkjds.wordpress.com!

    Monday, December 24, 2018 9:53 AM

Answers

  • Hello,

    To achieve this the solution is in short to write a good deal of code using Windows API. The following code is a starting point which requires a region, in this case a panel to focus on for permitting moving of the form which in turn allows moving the form but not resizing the form.

    The next level for resizing the form is a lot more Windows API code. Then for working with arrow keys I don't know as I've not tried this as I've never needed to do this.

    Imports System.Runtime.InteropServices
    ''' <summary>
    ''' The code will permit moving a borderless window
    ''' 
    ''' Requires a panel named Panel1
    ''' and a Button named closeButton (optional)
    ''' 
    ''' </summary>
    Public Class Form1
    #Region "Windows API code"
        Private Const WM_NCLBUTTONDOWN As Integer = &HA1
        Private Const HT_CAPTION As Integer = &H2
        Private Const WM_NCCALCSIZE As Integer = &H83
    
        <StructLayout(LayoutKind.Sequential)>
        Private Structure RECT
            Public left, top, right, bottom As Integer
            Public Sub New(ByVal rc As Rectangle)
                left = rc.Left
                top = rc.Top
                right = rc.Right
                bottom = rc.Bottom
            End Sub
            Public Function ToRectangle() As Rectangle
                Return Rectangle.FromLTRB(left, top, right, bottom)
            End Function
        End Structure
        <StructLayout(LayoutKind.Sequential)>
        Private Structure NCCALCSIZE_PARAMS
            Public rgrc0, rgrc1, rgrc2 As RECT
            Public lppos As WINDOWPOS
        End Structure
        <StructLayout(LayoutKind.Sequential)>
        Private Structure WINDOWPOS
            Public hWnd, hWndInsertAfter As IntPtr
            Public x, y, cx, cy, flags As Integer
        End Structure
        Protected Overrides Sub WndProc(ByRef message As Message)
            Select Case message.Msg
                Case WM_NCCALCSIZE
                    If message.WParam.Equals(IntPtr.Zero) Then
    
                        Dim rc = CType(message.GetLParam(GetType(RECT)), RECT)
                        Dim r = rc.ToRectangle()
                        r.Inflate(8, 8)
                        Marshal.StructureToPtr(New RECT(r), message.LParam, True)
                    Else
                        Dim csp As NCCALCSIZE_PARAMS = CType(message.
                                GetLParam(GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
    
                        Dim r = csp.rgrc0.ToRectangle()
                        r.Inflate(8, 8)
                        csp.rgrc0 = New RECT(r)
                        Marshal.StructureToPtr(csp, message.LParam, True)
                    End If
                    message.Result = IntPtr.Zero
            End Select
    
            MyBase.WndProc(message)
    
        End Sub
    #End Region
        Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) _
            Handles Panel1.MouseDown
    
            Panel1.Capture = False
    
            Dim msg As Message = Message.Create(Handle, WM_NCLBUTTONDOWN,
                                                New IntPtr(HT_CAPTION), IntPtr.Zero)
            WndProc(msg)
        End Sub
        Private Sub closeButton_Click(sender As Object, e As EventArgs) Handles closeButton.Click
            Close()
        End Sub
    End Class
    

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by JDS404 Monday, December 24, 2018 7:14 PM
    Monday, December 24, 2018 11:28 AM
    Moderator

  • I have a Windows Forms VB application with the following properties:

    • ControlBox = False
    • FormBorderStyle = Sizable
    • Text = ""

    I would like to be able to use Windows + arrow keys to snap the window to fit one side of the screen as normal, but this doesn't seem to work without the title bar.


    Seems to work. Have you tried using a new project and a simple form having your three settings?


    • Marked as answer by JDS404 Monday, December 24, 2018 7:14 PM
    Monday, December 24, 2018 6:48 PM

All replies

  • Hello,

    To achieve this the solution is in short to write a good deal of code using Windows API. The following code is a starting point which requires a region, in this case a panel to focus on for permitting moving of the form which in turn allows moving the form but not resizing the form.

    The next level for resizing the form is a lot more Windows API code. Then for working with arrow keys I don't know as I've not tried this as I've never needed to do this.

    Imports System.Runtime.InteropServices
    ''' <summary>
    ''' The code will permit moving a borderless window
    ''' 
    ''' Requires a panel named Panel1
    ''' and a Button named closeButton (optional)
    ''' 
    ''' </summary>
    Public Class Form1
    #Region "Windows API code"
        Private Const WM_NCLBUTTONDOWN As Integer = &HA1
        Private Const HT_CAPTION As Integer = &H2
        Private Const WM_NCCALCSIZE As Integer = &H83
    
        <StructLayout(LayoutKind.Sequential)>
        Private Structure RECT
            Public left, top, right, bottom As Integer
            Public Sub New(ByVal rc As Rectangle)
                left = rc.Left
                top = rc.Top
                right = rc.Right
                bottom = rc.Bottom
            End Sub
            Public Function ToRectangle() As Rectangle
                Return Rectangle.FromLTRB(left, top, right, bottom)
            End Function
        End Structure
        <StructLayout(LayoutKind.Sequential)>
        Private Structure NCCALCSIZE_PARAMS
            Public rgrc0, rgrc1, rgrc2 As RECT
            Public lppos As WINDOWPOS
        End Structure
        <StructLayout(LayoutKind.Sequential)>
        Private Structure WINDOWPOS
            Public hWnd, hWndInsertAfter As IntPtr
            Public x, y, cx, cy, flags As Integer
        End Structure
        Protected Overrides Sub WndProc(ByRef message As Message)
            Select Case message.Msg
                Case WM_NCCALCSIZE
                    If message.WParam.Equals(IntPtr.Zero) Then
    
                        Dim rc = CType(message.GetLParam(GetType(RECT)), RECT)
                        Dim r = rc.ToRectangle()
                        r.Inflate(8, 8)
                        Marshal.StructureToPtr(New RECT(r), message.LParam, True)
                    Else
                        Dim csp As NCCALCSIZE_PARAMS = CType(message.
                                GetLParam(GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
    
                        Dim r = csp.rgrc0.ToRectangle()
                        r.Inflate(8, 8)
                        csp.rgrc0 = New RECT(r)
                        Marshal.StructureToPtr(csp, message.LParam, True)
                    End If
                    message.Result = IntPtr.Zero
            End Select
    
            MyBase.WndProc(message)
    
        End Sub
    #End Region
        Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) _
            Handles Panel1.MouseDown
    
            Panel1.Capture = False
    
            Dim msg As Message = Message.Create(Handle, WM_NCLBUTTONDOWN,
                                                New IntPtr(HT_CAPTION), IntPtr.Zero)
            WndProc(msg)
        End Sub
        Private Sub closeButton_Click(sender As Object, e As EventArgs) Handles closeButton.Click
            Close()
        End Sub
    End Class
    

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by JDS404 Monday, December 24, 2018 7:14 PM
    Monday, December 24, 2018 11:28 AM
    Moderator

  • I have a Windows Forms VB application with the following properties:

    • ControlBox = False
    • FormBorderStyle = Sizable
    • Text = ""

    I would like to be able to use Windows + arrow keys to snap the window to fit one side of the screen as normal, but this doesn't seem to work without the title bar.


    Seems to work. Have you tried using a new project and a simple form having your three settings?


    • Marked as answer by JDS404 Monday, December 24, 2018 7:14 PM
    Monday, December 24, 2018 6:48 PM
  • After trying a different form, it seemed to work fine.

    Thanks to Kareninstructor for your code though!


    ---- JDS404 ---- Check out my blog at www.interlinkjds.wordpress.com!

    Monday, December 24, 2018 7:14 PM