by Amer Al-Homsi (1 Submission)
Category: Windows API Call/Explanation
Compatability: VB 6.0
Difficulty: Unknown Difficulty
Originally Published: Sat 17th November 2001
Date Added: Mon 8th February 2021
Rating:
(1 Votes)
How to add 'Always On Top' to the system menu
API Declarations
Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Declare Function ModifyMenu Lib "user32" Alias "ModifyMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpString As Any) As Long
Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
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
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Global Const MF_SEPARATOR = &H800&
Global Const MF_STRING = &H0&
Global Const MF_CHECKED = &H8&
Global Const MF_UNCHECKED = &H0&
Global Const MF_BYPOSITION = &H400&
Global Const GWL_WNDPROC = (-4)
Global Const WM_SYSCOMMAND = &H112
Const HWND_TOPMOST = -1
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Const HWND_NOTOPMOST = -2
'Add to standard module:
Public hSysMenu As Long, OrgProc As Long, MenuChecked As Boolean
Function NewWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = WM_SYSCOMMAND And wParam = hSysMenu Then
If MenuChecked = False Then
'The system menu is not check, Check it:
ModifyMenu hSysMenu, 8, MF_BYPOSITION Or MF_CHECKED, hSysMenu, "&Always On Top"
'Make the window always on top
SetWindowPos Form1.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
Else
'The system menu is checked, Uncheck it:
ModifyMenu hSysMenu, 8, MF_BYPOSITION Or MF_UNCHECKED, hSysMenu, "&Always On Top"
'Make the window not always on top
SetWindowPos Form1.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
End If
'In both situation:
'Refresh the menu container
DrawMenuBar hSysMenu
'Invert the variable
MenuChecked = Not MenuChecked
End If
NewWindowProc = CallWindowProc(OrgProc, hwnd, Msg, wParam, lParam)
End Function
'Add to Form1 code :
Private Sub Form_Load()
'Get system menu handle
hSysMenu = GetSystemMenu(Me.hwnd, False)
'Add separator to system menu
AppendMenu hSysMenu, MF_SEPARATOR, hSysMenu, "separator"
'Add 'Always On Top' sub menu
AppendMenu hSysMenu, MF_STRING, hSysMenu, "&Always On Top"
'Capture the window procedure
OrgProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf NewWindowProc)
End Sub
Private Sub Form_Unload(Cancel As Integer)
SetWindowLong Me.hwnd, GWL_WNDPROC, OrgProc
End Sub