Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; A DLL to subclass a window to prevent resizing.
- ; Compile as Shared DLL, x86 (PB 4.6+) ANSI
- ;- Constants - Window Property names.
- #WND_SIZE_PREVENT_PROPNAME = "WndSizePreventOldProc"
- #WND_SIZE_PREVENT_HADMAX = "WndSizePreventHadMax"
- #WND_SIZE_PREVENT_WIDTH = "WndSizePreventWidth"
- #WND_SIZE_PREVENT_HEIGHT = "WndSizePreventHeight"
- ; Window dimension helpers.
- Procedure.i GetWindowWidth(hWnd.i)
- Protected rect.RECT
- If(GetWindowRect_(hWnd, @rect))
- ProcedureReturn (rect\right - rect\left)
- EndIf
- EndProcedure
- Procedure.i GetWindowHeight(hWnd.i)
- Protected rect.RECT
- If(GetWindowRect_(hWnd, @rect))
- ProcedureReturn (rect\bottom - rect\top)
- EndIf
- EndProcedure
- ; Procedure that clears out all properties on a window and restores original style/callback.
- Procedure.i WndSizePreventClear(hWnd.i)
- ; Restore original callback function.
- SetWindowLong_(hWnd, #GWL_WNDPROC, GetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME))
- ; If the window had a maximize box, restore it.
- If(GetProp_(hWnd, #WND_SIZE_PREVENT_HADMAX))
- SetWindowLong_(hWnd, #GWL_STYLE, GetWindowLong_(hWnd, #GWL_STYLE) | #WS_MAXIMIZEBOX)
- EndIf
- ; Remove all props from hWnd, preventing unwanted behaviour.
- RemoveProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME)
- RemoveProp_(hWnd, #WND_SIZE_PREVENT_WIDTH)
- RemoveProp_(hWnd, #WND_SIZE_PREVENT_HEIGHT)
- RemoveProp_(hWnd, #WND_SIZE_PREVENT_HADMAX)
- EndProcedure
- ; Subclass callback procedure catching events for resizing.
- Procedure.i WndSizePreventProc(hWnd.i, uMsg.i, wParam.l, lParam.l)
- Protected dwOldProc.l = GetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME)
- Select uMsg
- Case #WM_NCHITTEST
- ; Call the original callback function to see the result of the NC hit test.
- Protected procRes.i = CallWindowProc_(dwOldProc, hWnd, uMsg, wParam, lParam)
- Select procRes
- ; Catch hit tests on borders and return 0, causing Windows to forget about handling a resize-cursor.
- Case #HTBORDER, #HTBOTTOM, #HTBOTTOMLEFT, #HTBOTTOMRIGHT, #HTTOP, #HTTOPLEFT, #HTTOPRIGHT, #HTLEFT, #HTRIGHT
- ProcedureReturn 0
- EndSelect
- ; Set a minimum and maximum size for the window to its original size, preventing resizing.
- Case #WM_GETMINMAXINFO
- Protected *MM.MINMAXINFO = lParam
- With *MM
- Protected x = GetProp_(hWnd, #WND_SIZE_PREVENT_WIDTH)
- Protected y = GetProp_(hWnd, #WND_SIZE_PREVENT_HEIGHT)
- \ptMaxSize\x = x
- \ptMaxSize\y = y
- \ptMaxTrackSize\x = x
- \ptMaxTrackSize\y = y
- \ptMinTrackSize\x = x
- \ptMinTrackSize\y = y
- EndWith
- ProcedureReturn 0
- ; Don't forget to remove all the props etc. if the window is closed.
- Case #WM_DESTROY
- WndSizePreventClear(hWnd)
- EndSelect
- ; If nothing else was prevented / catched and returned, call the original callback procedure to handle other events.
- ProcedureReturn CallWindowProc_(dwOldProc, hWnd, uMsg, wParam, lParam)
- EndProcedure
- Procedure.i PreventWindowSizing(hWnd.i, State.i)
- Protected oldProc.i = GetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME)
- Protected oldStyle.l = 0
- If(State)
- ; If this window already has the state set to 1, return.
- If(oldProc)
- ProcedureReturn #True
- EndIf
- ; Set a new callback function for our window and prepare all the props containing important information.
- oldProc = SetWindowLong_(hWnd, #GWL_WNDPROC, @WndSizePreventProc())
- SetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME, oldProc)
- SetProp_(hWnd, #WND_SIZE_PREVENT_WIDTH, GetWindowWidth(hWnd))
- SetProp_(hWnd, #WND_SIZE_PREVENT_HEIGHT, GetWindowHeight(hWnd))
- SetProp_(hWnd, #WND_SIZE_PREVENT_HADMAX, 0)
- ; If the window has a maximize box, we want to disable it. Remove it from the GWL_STYLE long.
- oldStyle = GetWindowLong_(hWnd, #GWL_STYLE)
- If(oldStyle & #WS_MAXIMIZEBOX)
- SetProp_(hWnd, #WND_SIZE_PREVENT_HADMAX, 1)
- SetWindowLong_(hWnd, #GWL_STYLE, oldStyle & ~#WS_MAXIMIZEBOX)
- EndIf
- ProcedureReturn #True
- Else
- If(oldProc)
- ; Don't forget to remove all the props etc. if the state is set to 0. Same as WM_DESTROY's steps.
- WndSizePreventClear(hWnd)
- ProcedureReturn #True
- EndIf
- EndIf
- EndProcedure
- ProcedureDLL.i IsValidWindow(hWnd.i)
- ; A DLL wrapper for IsWindow, so we won't have to load another DLL in AMS.
- ProcedureReturn IsWindow_(hWnd)
- EndProcedure
- ProcedureDLL.i DisableWindowResizing(hWnd.i, intDisabledState.i = 0)
- ; A DLL wrapper for PreventWindowSizing.
- ProcedureReturn PreventWindowSizing(hWnd, intDisabledState)
- EndProcedure
- ;- Example PureBasic implementation. Uncomment the next line to enable it.
- ;#WND_SIZE_PREVENT_EXAMPLE = 1
- CompilerIf Defined(WND_SIZE_PREVENT_EXAMPLE, #PB_Constant) = 1
- Global SizeableState = 0
- If(OpenWindow(0, 0, 0, 450, 350, "Size test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget))
- ButtonGadget(0, 5, 5, 100, 22, "Toggle Sizeability")
- Repeat
- ; Have PureBasic's internal WinProc catch all other events.
- Event = WaitWindowEvent()
- E_GID = EventGadget()
- Select Event
- Case #PB_Event_CloseWindow
- Quit = 1
- Case #PB_Event_Gadget
- Select E_GID
- Case 0
- SizeableState ! 1 ; If SizeableState = 0, XOR to 1, if SizeableState = 1, XOR to 0.
- PreventWindowSizing(WindowID(0), SizeableState)
- EndSelect
- EndSelect
- Until Quit
- EndIf
- CompilerEndIf
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement