Results 1 to 2 of 2

Thread: Get Form's Frame Size + Bonus (remove frame)

  1. #1

    Thread Starter
    New Member
    Join Date
    Nov 2024
    Location
    Canada (Province of Quebec)
    Posts
    4

    Lightbulb Get Form's Frame Size + Bonus (remove frame)

    In my attempt to Windows11ify my app taking into account the current theme, I cam accross a need for most VB6 programmers out there trying to change the appearance of their forms. That is: Get the size of the current windows frame OUTSIDE the working client area. Yes, there's a bunch of API calls and a bunch of other methods. Here's my method which I think works best and does an EXCELLENT job at giving everything you need so you can work with the re-arangment of your form.

    1 - The calls:
    Code:
    Private Const WS_EX_WINDOWEDGE As Long = &H100
    Private Const WS_EX_CLIENTEDGE As Long = &H200
    Private Const WS_EX_STATICEDGE As Long = &H20000
    Private Const WS_THICKFRAME As Long = &H40000
    Private Const WS_EX_LAYERED As Long = &H80000
    Private Const WS_DLGFRAME As Long = &H400000
    Private Const WS_BORDER As Long = &H800000
    
    Private Const GWL_STYLE As Long = (-16)
    Private Const GWL_EXSTYLE As Long = (-20)
    
    Private Const SWP_NOSIZE As Long = &H1
    Private Const SWP_NOMOVE As Long = &H2
    Private Const SWP_NOZORDER = &H4
    Private Const SWP_FRAMECHANGED As Long = &H20
    Private Const SWP_NOOWNERZORDER = &H200
    
    Private Type POINTAPI
      X As Long
      Y As Long
    End Type
    
    Private Type RECT
      Left As Long
      Top As Long
      Right As Long
      Bottom As Long
    End Type
    
    Private Type RECTW
      Left As Long
      Top As Long
      Right As Long
      Bottom As Long
      Width As Long
      Height As Long
    End Type
    
    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Declare Function GetClientRect Lib "user32.dll" (ByVal hwnd As Long, ByRef lpRect As RECT) As Long
    Private Declare Function SetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
    2 - The custom functions
    Code:
    ' Gets the size of each border of the frame and the size of the client area that is the actual size of the form without a frame
    ' Returns size in pixels as RECTW
    Public Function GetFormBorderSize(ByVal oForm As Form) As RECTW
    
      Dim oRect As RECT
      Dim oPoint As POINTAPI
      Dim ocRect As RECT
      Dim oRetVal As RECTW
      
      ClientToScreen oForm.hwnd, oPoint
      GetWindowRect oForm.hwnd, oRect
      GetClientRect oForm.hwnd, ocRect
      
      ' Get the size of each sides of the frame
      oRetVal.Top = oPoint.Y - oRect.Top
      oRetVal.Left = oPoint.X - oRect.Left
      oRetVal.Bottom = ((oRect.Bottom - oRect.Top) - ocRect.Bottom) - oRetVal.Top
      oRetVal.Right = ((oRect.Right - oRect.Left) - ocRect.Right) - oRetVal.Left
      oRetVal.Height = ocRect.Bottom
      oRetVal.Width = ocRect.Right
      
      GetFormBorderSize = oRetVal
    
    End Function
    
    ' Removes the borders from controls and forms (usually for ListBoxes since they keep their borders even when flat but works for forms too)
    Public Sub RemoveBorder(ByRef oObject As Object)
      
      Dim lWin As Long
    
      lWin = GetWindowLongA(oObject.hwnd, GWL_STYLE)
      lWin = lWin And (Not WS_BORDER) And (Not WS_DLGFRAME) And (Not WS_THICKFRAME)
      
      SetWindowLongA oObject.hwnd, GWL_STYLE, lWin
      
      lWin = GetWindowLongA(oObject.hwnd, GWL_EXSTYLE)
      lWin = lWin And (Not WS_EX_WINDOWEDGE) And (Not WS_EX_CLIENTEDGE) And (Not WS_EX_STATICEDGE)
      
      SetWindowLongA oObject.hwnd, GWL_EXSTYLE, lWin
      
      SetWindowPos oObject.hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOOWNERZORDER Or SWP_NOZORDER Or SWP_FRAMECHANGED
    
    End Sub
    I needed to remove the borders of my listboxes since I put them in pictureboxes to add some style, the only big annoyance was the fact that the border stayed there which pushed me into figuring out how to remove those borders. It also turns out that I needed to remove the frame around my form since I am extending the client aread using DWM calls (which are FAR from working for now) but the forms actually work too.

    Now to put this into practice, the code to remove the border of the form is as folllows:
    Code:
    Dim oRect As RECT
    Dim ofRect As RECTW
    
    ' First, get the position and sizes of the form and frame
    ofRect = GetFormBorderSize(Me)
    GetWindowRect Me.hWnd, oRect
    
    ' Remove the windows borders
    RemoveBorder Me
    ' Resize the form to accomodate the shifting that occures when removing the border
    SetWindowPos Me.hWnd, vbNull, oRect.Left, oRect.Top, ofRect.Width, ofRect.Height, SWP_FRAMECHANGED
    And to remove the frame of a list box:
    Code:
    RemoveBorder List1
    And there you have it. I also wanted to make sure you people have all the const variables because getting the values of some of them is quite challengin, maybe not THESE ones but in my run for Windows11ifying, there's lots of undoccumented API and lots of const variables that I need to dig deep in Google to find their values since Microsoft does not make it easy to get those on their website.

    As always, well, this is my second post, but as usual for me, please feel free to comment or offer alternatives.

  2. #2
    Fanatic Member BenJones's Avatar
    Join Date
    Mar 2010
    Location
    Wales UK
    Posts
    780

    Re: Get Form's Frame Size + Bonus (remove frame)

    Thanks I add this code to my tips collection.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width