-
Nov 12th, 2024, 11:36 PM
#1
Thread Starter
New Member
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:
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.
-
Nov 13th, 2024, 09:15 AM
#2
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|