How do you remove the icon from the controlbar of a window?
How do you remove the icon from the controlbar of a window while leaving the min/max/close buttons intact? The ControlBox option removes everything so its not good...
Perhaps some one knows some tricks with messing the window handle.
I want it so the icon of an MDI child won't interrupt the MDI menus (Basically remove the icon altogether.)
Cheers~
(I see programs have certain windows in this state so i know its possible.)
Drazzakia... Knowlage is fresh with new data, mine is mastered with the old data. (i'm not talking about vb knowlage )
Re: How do you remove the icon from the controlbar of a window?
I noticed that in addition to no icon you also are left with no minimise or maximise buttons. I fixed that by adding the WS_MINIMIZEBOX and WS_MAXIMISEBOX styles.
There is also an ugly 1 px rectangle left from the old border which I am trying to get rid of.
Re: How do you remove the icon from the controlbar of a window?
I know this is an old topic, but I was in need for this fix.
The transparent icon is a good solution, but it will give you a large empty space on the left of the window and the title.
The BorderStyle at SizableToolWindow is also a good solution, but it will give you an ugly small X and the borders seem to be cut off at the side (at least in windows 10)
The API solution is a good option, BUT as it is shown it has a big problem, the first time you start resizing the window it will jump a few pixels to the right and to the bottom, which can be very annoying, AND in that case it will also change the actual clientrectangle.
(At least on Windows 10 and Windows 11)
So based on the API solution, I created the following procedure.
It will fix the jump when first resizing as it will change the size of the window with one pixel and restore it back to the original size after that, and then it will change the windowsize so the ClientRectangle should be the same as before the change of the border.
I did add some extra checks like only doing it when the BorderStyle is FixedDialog, as in our code it's part of a FormExtender class we wrote. You could also change it to only need a hWnd.
All you need to do is:
Put the following code into a module
Add a Form
Set BorderStyle to FixedDialog
And call function p_SetBorderStyleDialogToSizable from Form_Load or any event after that one is triggered (not from Form_Initialize as the form hasn't been created yet)
Code:
'--------------------------------------------------------------
'GetWindowLong/SetWindowLong nIndex
'Public Const GWL_EXSTYLE As Long = (-20)
'Public Const GWL_HINSTANCE As Long = (-6)
'Public Const GWL_HWNDPARENT As Long = (-8)
'Public Const GWL_ID As Long = (-12)
Public Const GWL_STYLE As Long = (-16)
'Public Const GWL_USERDATA As Long = (-21)
'Public Const GWL_WNDPROC As Long = (-4)
'Public Const DWL_DLGPROC As Long = 4 'also available if hWnd is a Dialog
'Public Const DWL_MSGRESULT As Long = 0 'also available if hWnd is a Dialog
'Public Const DWL_USER As Long = 8 'also available if hWnd is a Dialog
'--------------------------------------------------------------
'CreateWindow/CreateWindowEx dwStyle
'Public Const WS_BORDER As Long = &H800000
'Public Const WS_CAPTION As Long = &HC00000
'Public Const WS_CHILD As Long = &H40000000
'Public Const WS_CHILDWINDOW As Long = WS_CHILD
'Public Const WS_CLIPCHILDREN As Long = &H2000000
'Public Const WS_CLIPSIBLINGS As Long = &H4000000
'Public Const WS_DISABLED As Long = &H8000000
'Public Const WS_DLGFRAME As Long = &H400000
'Public Const WS_GROUP As Long = &H20000
'Public Const WS_HSCROLL As Long = &H100000
'Public Const WS_MAXIMIZE As Long = &H1000000
Public Const WS_MAXIMIZEBOX As Long = &H10000
'Public Const WS_MINIMIZE As Long = &H20000000
Public Const WS_MINIMIZEBOX As Long = &H20000
'Public Const WS_OVERLAPPED As Long = &H0&
'Public Const WS_POPUP As Long = &H80000000
'Public Const WS_SYSMENU As Long = &H80000
'Public Const WS_TABSTOP As Long = &H10000
Public Const WS_THICKFRAME As Long = &H40000
'Public Const WS_VISIBLE As Long = &H10000000
'Public Const WS_VSCROLL As Long = &H200000
'Public Const WS_ICONIC As Long = WS_MINIMIZE
'Public Const WS_OVERLAPPEDWINDOW As Long = (WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)
'Public Const WS_POPUPWINDOW As Long = (WS_POPUP Or WS_BORDER Or WS_SYSMENU)
'Public Const WS_SIZEBOX As Long = WS_THICKFRAME
'Public Const WS_TILED As Long = WS_OVERLAPPED
'Public Const WS_TILEDWINDOW As Long = WS_OVERLAPPEDWINDOW
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
'===================================================
'== USER32.DLL
'===================================================
'- G -
Public Declare Function GetClientRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long
Public Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long
'- L -
Public Declare Function LockWindowUpdate Lib "user32.dll" (ByVal hWndLock As Long) As Long
'- M -
Public Declare Function MoveWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
'- S -
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
'##############################################################################
'##
'## Sub p_SetBorderStyleDialogToSizable
'##
'##############################################################################
Public Sub p_SetBorderStyleDialogToSizable(ByVal frm As Form, _
Optional ByVal bMaximizeBox As Boolean = False, _
Optional ByVal bMinimizeBox As Boolean = False, _
Optional ByVal bKeepClientRect As Boolean = True)
Dim lReturn As Long
Dim lStyle As Long
Dim lStyleNew As Long
Dim tRectClient As RECT
Dim tRectClientAfter As RECT
Dim tRectWindow As RECT
'--------------------------------------------------------------
'Was a valid form passed?
If Not frm Is Nothing Then
'--------------------------------------------------------------
'Only change if borderstyle IS dialog
If frm.BorderStyle = vbFixedDialog Then
'--------------------------------------------------------------
'Get current Style
lStyle = GetWindowLong(frm.hWnd, GWL_STYLE)
'--------------------------------------------------------------
'Set base for new style
lStyleNew = lStyle
'--------------------------------------------------------------
'Set Resize frame
lStyleNew = lStyleNew Or WS_THICKFRAME
'--------------------------------------------------------------
'Show MaximizeBox?
If bMaximizeBox Then
lStyleNew = lStyleNew Or WS_MAXIMIZEBOX
'--------------------------------------------------------------
'Need to turn off MaximizeBox?
ElseIf (lStyleNew And WS_MAXIMIZEBOX) = WS_MAXIMIZEBOX Then
lStyleNew = lStyleNew Xor WS_MAXIMIZEBOX
End If 'ELSE [If bMaximizeBox]
'--------------------------------------------------------------
'Show MinimizeBox?
If bMinimizeBox Then
lStyleNew = lStyleNew Or WS_MINIMIZEBOX
'--------------------------------------------------------------
'Need to turn off MaxinizeBox?
ElseIf (lStyleNew And WS_MINIMIZEBOX) = WS_MINIMIZEBOX Then
lStyleNew = lStyleNew Xor WS_MINIMIZEBOX
End If 'ELSE [If bMinimizeBox]
'--------------------------------------------------------------
'Did the Style Change? if not we don't need to do anything
If lStyleNew <> lStyle Then
'Call LockWindowUpdate(frm.hWnd)
'--------------------------------------------------------------
'Get current Window rectangle
lReturn = GetWindowRect(frm.hWnd, tRectWindow)
'--------------------------------------------------------------
'Need to keep the same ClientRect? Then get current Client rectangle
If bKeepClientRect Then lReturn = GetClientRect(frm.hWnd, tRectClient)
'--------------------------------------------------------------
'Send New Style
lReturn = SetWindowLong(frm.hWnd, GWL_STYLE, lStyleNew)
'--------------------------------------------------------------
'Trigger a resize by adding 1 pixel to the height to persist the new style
lReturn = MoveWindow(frm.hWnd, _
tRectWindow.Left, _
tRectWindow.Top, _
tRectWindow.Right - tRectWindow.Left, _
tRectWindow.Bottom - tRectWindow.Top + 1, _
1)
'--------------------------------------------------------------
'Need to change windowsize to keep the same ClientRect?
If bKeepClientRect Then
'--------------------------------------------------------------
'Get new Client rectangle
lReturn = GetClientRect(frm.hWnd, tRectClientAfter)
'--------------------------------------------------------------
'Need to resize width of window to keep same ClientRect?
If tRectClient.Right <> tRectClientAfter.Right Then tRectWindow.Right = tRectWindow.Right + (tRectClient.Right - tRectClientAfter.Right)
'--------------------------------------------------------------
'Need to resize height of window to keep same ClientRect?
If tRectClient.Bottom <> tRectClientAfter.Bottom Then tRectWindow.Bottom = tRectWindow.Bottom + (tRectClient.Bottom - tRectClientAfter.Bottom)
End If 'If bKeepClientRect
'--------------------------------------------------------------
'Restore original position and (new, if clientrect was changed) size
lReturn = MoveWindow(frm.hWnd, _
tRectWindow.Left, _
tRectWindow.Top, _
tRectWindow.Right - tRectWindow.Left, _
tRectWindow.Bottom - tRectWindow.Top, _
1)
'Call LockWindowUpdate(0)
End If 'If lStyleNew<>lStyle
End If 'If frm.BorderStyle=vbFixedDialog
End If 'If fnFormAvailable
End Sub
Last edited by SuperDre; Jul 6th, 2022 at 10:13 AM.
Re: How do you remove the icon from the controlbar of a window?
Originally Posted by DaveDavis
What is it? I can't understand.
a fix for having sizable window but without the icon or minimize/maximize but keeping the close button, and normal borders, not the toolwindow with its small close button.
Re: How do you remove the icon from the controlbar of a window?
Originally Posted by SuperDre
a fix for having sizable window but without the icon or minimize/maximize but keeping the close button, and normal borders, not the toolwindow with its small close button.
Thank you explanations.
Have you studied how to park the Form at exact position considering the thickness of Aero edge?
Code:
Sub Main()
'standard code not considering Aero borders
Form2.Left = Form1.Left + Form1.Width '- 8 * 2 * Screen.TwipsPerPixelX
Form2.Top = Form1.Top
Form2.Width = Form1.Width
Form2.Height = Form1.Height
Form1.Show
Form2.Show
End Sub
Re: How do you remove the icon from the controlbar of a window?
I have some extra code for that in our FormExtender class, but when I was doing this fix I think I created it while my dev machine still was Windows 7 and it behaves differently, so I removed it from this fix (getting the window size was originally a routine that first got the windowsize through GetWindowSize and then it got the windowsize through DMW and did some logic to decide which windowsize it would return. I know it's a pain in the butt and it requires some extra API code to get the actual size of the aero borders.
Re: How do you remove the icon from the controlbar of a window?
Originally Posted by SuperDre
I have some extra code for that in our FormExtender class, but when I was doing this fix I think I created it while my dev machine still was Windows 7 and it behaves differently, so I removed it from this fix (getting the window size was originally a routine that first got the windowsize through GetWindowSize and then it got the windowsize through DMW and did some logic to decide which windowsize it would return. I know it's a pain in the butt and it requires some extra API code to get the actual size of the aero borders.
How to get GetWindowSize?
GetWindowRect can do so but... because it requires the window has been shown at least once. This is a REAL headache.
Calling GetWindowRect will have different behavior depending on whether the window has ever been shown or not. If the window has not been shown before, GetWindowRect will not include the area of the drop shadow.
To get the window bounds excluding the drop shadow, use DwmGetWindowAttribute, specifying DWMWA_EXTENDED_FRAME_BOUNDS. Note that unlike the Window Rect, the DWM Extended Frame Bounds are not adjusted for DPI. Getting the extended frame bounds can only be done after the window has been shown at least once.