January 22, 2020, 12:34:36 PM

Author Topic: Overriding WinProc to keep window Bottom Most  (Read 122 times)

Offline Foolish

  • Jr. Member
  • **
  • Posts: 8
Overriding WinProc to keep window Bottom Most
« on: December 30, 2019, 09:00:23 PM »
Hi folks.

I would like to be able to create a window that overlays the Desktop but remains beneath all other windows. 
I use SetWindowLong to set various window properties to make it full screen and borderless.
I use SetWindowPos to place the window at the bottom of the ZORDER.
I then set the window to be a child of the Desktop window using SetParent.
This successfully places the window beneath other windows.  However, to keep it from popping to the front when clicked on, I believe I need to intercept WinProc messages such as WM_ACTIVATE and WM_POSITIONCHANGING in order to keep the Window BOTTOM MOST. 
So I have attempted to hook into WinProc, but it doesn't seem to be working.  My WinProc never seems to get called.  What am I doing wrong that my WinProc is not being called.  Isnt it supposed to be called automatically once hooked in?

Code: [Select]
Strict
 
' Used by FindWindow; set to name of your app!
 
AppTitle = "MY GAME"
 
' Open window at full size, depth = 0 for windowed mode...
 
Graphics DesktopWidth (), DesktopHeight (), 0


' Win32 monitor info structure...
 
Type MONITORINFO
 
        Field cbSize:Int
 
        Field rcMonitorLeft:Int
        Field rcMonitorTop:Int
        Field rcMonitorRight:Int
        Field rcMonitorBottom:Int
 
        Field rcWorkLeft:Int
        Field rcWorkTop:Int
        Field rcWorkRight:Int
        Field rcWorkBottom:Int
 
        Field dwFlags:Int
 
End Type
 
' Win32 constants...
 
Const MONITOR_DEFAULTTONEAREST:Int      = 2
 
Const GWL_STYLE:Int                                     = -16
Const GWL_EXSTYLE:Int                           = -20

Const GWL_WNDPROC:Int = -4
 
Const HWND_TOP:Int                                      = 0
Const HWND_BOTTOM:Int                                      = 1
Const SWP_FRAMECHANGED:Int                      = $20
 
Const WS_POPUP:Int                                      = $80000000
Const WS_VISIBLE:Int                            = $10000000
Const WS_CAPTION:Int                            = $C00000
Const WS_THICKFRAME:Int                         = $00040000
Const WS_MINIMIZE:Int                           = $20000000
Const WS_MAXIMIZE:Int                           = $01000000
Const WS_SYSMENU:Int                            = $80000
 
Const WS_EX_DLGMODALFRAME:Int           = $00000001
Const WS_EX_CLIENTEDGE:Int                      = $200
Const WS_EX_STATICEDGE:Int                      = $20000

Const WM_WINDOWPOSCHANGING% = $46
Const WM_ACTIVATE% = $6
 
' Win32 function pointers...
 
Global FindWindow (lpClassName:Byte Ptr, lpWindowName:Byte Ptr) "win32"
Global MonitorFromWindow (hwnd:Int, dwFlags:Int)                                "win32"
Global GetMonitorInfo (hMonitor:Int, lpmi:Byte Ptr)                             "win32"
Global GetWindowLong (hwnd:Int, nIndex:Int)                                             "win32"
Global SetWindowLong (hwnd:Int, nIndex:Int, dwNewLong:Int)              "win32"
Global SetWindowLongPtrA (hwnd:Int, nIndex:Int, dwNewLong:Byte Ptr)              "win32"
Global SetWindowPos (hWnd:Int, hWndInsertAfter:Int, X:Int, Y:Int, cx:Int, cy:Int, uFlags:Int)
Global SetParent(hWndChild:Int,hWndNewParent:Int)
Global GetDesktopWindow()
Global CallWindowProc(prevwndproc:Byte Ptr, hwnd:Int, msg:Int, WParam:Int, LParam:Int)

' Set up function pointers...
 
Local user32:Byte Ptr = LoadLibraryA ("user32.dll")
 
If user32
 
        FindWindow              = GetProcAddress (user32, "FindWindowA")
        MonitorFromWindow       = GetProcAddress (user32, "MonitorFromWindow")
        GetMonitorInfo          = GetProcAddress (user32, "GetMonitorInfoA")
        GetWindowLong           = GetProcAddress (user32, "GetWindowLongA")
        SetWindowLong           = GetProcAddress (user32, "SetWindowLongA")
SetWindowLongPtrA = GetProcAddress (user32, "SetWindowLongPtrA")
        SetWindowPos            = GetProcAddress (user32, "SetWindowPos")
SetParent = GetProcAddress (user32, "SetParent")
GetDesktopWindow = GetProcAddress (user32, "GetDesktopWindow")
CallWindowProc = GetProcAddress (user32, "CallWindowProc")
       
        If Not (FindWindow And MonitorFromWindow And GetMonitorInfo And GetWindowLong And SetWindowPos And SetParent And GetDesktopWindow And CallWindowProc)
                'Print "Missing function!"
                'End
        EndIf
       
EndIf


Global OldWinProc:Int
 
' AppTitle allocated as C-string...
 
Local cbytes:Byte Ptr = AppTitle.ToCString ()
 
' Find app window...
 
Local appwindow:Int = FindWindow (Null, cbytes)
Print "App Window = "+appwindow



'Find DesktopWindow
Local DTWindow = GetDesktopWindow()
Print "DTWindow = "+DTWIndow

Local hWnd:Int
 


' Free C-string memory...
 
'MemFree cbytes
 
' Find which monitor the app window is on...
 
Local monitor:Int = MonitorFromWindow (appwindow, MONITOR_DEFAULTTONEAREST)
 
' Monitor info...
 
Global mi:MONITORINFO = New MONITORINFO
mi.cbSize = SizeOf (MONITORINFO)
 
GetMonitorInfo monitor, mi
 
' Read window style/extended style...
 
Local style:Int         = GetWindowLong (appwindow, GWL_STYLE)
Local exstyle:Int       = GetWindowLong (appwindow, GWL_EXSTYLE)
 
' Prepare to remove unwanted styles...
 
style   = style And Not (WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU)
exstyle = exstyle And Not (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)
 
' Remove unwanted styles...
 
SetWindowLong (appwindow, GWL_STYLE, style | WS_POPUP | WS_VISIBLE | SWP_FRAMECHANGED)
SetWindowLong (appwindow, GWL_EXSTYLE, exstyle)
SetWindowPos appwindow, HWND_BOTTOM, mi.rcMonitorLeft, mi.rcMonitorTop, mi.rcMonitorRight - mi.rcMonitorLeft, mi.rcMonitorBottom - mi.rcMonitorTop-32, 0
SetParent(appwindow,DTWIndow)

HookWinProc(appwindow)

' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
' hWnd is the pointer to your window.  hWnd is not the gadget pointer!
' You can get hWnd with hWnd = GetActiveWindow(), or with hWnd = QueryGadget(Window, QUERY_HWND), where Window is your window's gadget pointer.
' ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



Repeat

        Cls
     
'DrawRect 100,100,3000,500
        DrawRect MouseX (), MouseY (), 32, 32



        Flip
       
Until KeyHit (KEY_ESCAPE)

 

End

Function HookWinProc(hWnd:Int)
Print ("HookInProc")
Local GWL_WNDPROC:Int = -4
OldWinProc = SetWindowLong(hWnd, GWL_WNDPROC, Int Byte Ptr(WinProc))
End Function 

Function WinProc:Int(hWnd:Int, Msg:Int, WParam:Int, LParam:Int) "win32"


Print "Message = " + Msg

Select Msg

    Case  WM_ACTIVATE

Print ("Case selected")

'Default
' DebugLog Msg

End Select

'If OldWinProc <> 0 Then Return CallWindowProc(Byte Ptr(OldWinProc), hWnd, Msg, WParam, LParam) 

End Function


Offline fielder

  • Jr. Member
  • **
  • Posts: 84
Re: Overriding WinProc to keep window Bottom Most
« Reply #1 on: December 30, 2019, 10:01:44 PM »
i tried to make a Windows GUI (like explorer.exe) some years ago.. and i tried everything to make the Window like a background (killing original explorer.exe) ... (last on Z order) but nothing... i hope someone can answer and solve the mistery.,