Advertisement
xoru

dwr.pb

Nov 13th, 2012
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; A DLL to subclass a window to prevent resizing.
  2. ; Compile as Shared DLL, x86 (PB 4.6+) ANSI
  3.  
  4. ;- Constants - Window Property names.
  5. #WND_SIZE_PREVENT_PROPNAME    = "WndSizePreventOldProc"
  6. #WND_SIZE_PREVENT_HADMAX      = "WndSizePreventHadMax"
  7. #WND_SIZE_PREVENT_WIDTH       = "WndSizePreventWidth"
  8. #WND_SIZE_PREVENT_HEIGHT      = "WndSizePreventHeight"
  9.  
  10. ; Window dimension helpers.
  11. Procedure.i GetWindowWidth(hWnd.i)
  12.   Protected rect.RECT
  13.   If(GetWindowRect_(hWnd, @rect))
  14.     ProcedureReturn (rect\right - rect\left)
  15.   EndIf
  16. EndProcedure
  17. Procedure.i GetWindowHeight(hWnd.i)
  18.   Protected rect.RECT
  19.   If(GetWindowRect_(hWnd, @rect))
  20.     ProcedureReturn (rect\bottom - rect\top)
  21.   EndIf
  22. EndProcedure
  23.  
  24. ; Procedure that clears out all properties on a window and restores original style/callback.
  25. Procedure.i WndSizePreventClear(hWnd.i)
  26.   ; Restore original callback function.
  27.   SetWindowLong_(hWnd, #GWL_WNDPROC, GetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME))
  28.  
  29.   ; If the window had a maximize box, restore it.
  30.   If(GetProp_(hWnd, #WND_SIZE_PREVENT_HADMAX))
  31.     SetWindowLong_(hWnd, #GWL_STYLE, GetWindowLong_(hWnd, #GWL_STYLE) | #WS_MAXIMIZEBOX)
  32.   EndIf
  33.  
  34.   ; Remove all props from hWnd, preventing unwanted behaviour.
  35.   RemoveProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME)
  36.   RemoveProp_(hWnd, #WND_SIZE_PREVENT_WIDTH)
  37.   RemoveProp_(hWnd, #WND_SIZE_PREVENT_HEIGHT)
  38.   RemoveProp_(hWnd, #WND_SIZE_PREVENT_HADMAX)
  39. EndProcedure
  40.  
  41. ; Subclass callback procedure catching events for resizing.
  42. Procedure.i WndSizePreventProc(hWnd.i, uMsg.i, wParam.l, lParam.l)
  43.   Protected dwOldProc.l = GetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME)
  44.   Select uMsg
  45.     Case #WM_NCHITTEST
  46.       ; Call the original callback function to see the result of the NC hit test.
  47.       Protected procRes.i = CallWindowProc_(dwOldProc, hWnd, uMsg, wParam, lParam)
  48.       Select procRes
  49.         ; Catch hit tests on borders and return 0, causing Windows to forget about handling a resize-cursor.
  50.         Case #HTBORDER, #HTBOTTOM, #HTBOTTOMLEFT, #HTBOTTOMRIGHT, #HTTOP, #HTTOPLEFT, #HTTOPRIGHT, #HTLEFT, #HTRIGHT
  51.           ProcedureReturn 0
  52.       EndSelect
  53.      
  54.     ; Set a minimum and maximum size for the window to its original size, preventing resizing.
  55.     Case #WM_GETMINMAXINFO
  56.       Protected *MM.MINMAXINFO = lParam
  57.      
  58.       With *MM
  59.         Protected x       = GetProp_(hWnd, #WND_SIZE_PREVENT_WIDTH)
  60.         Protected y       = GetProp_(hWnd, #WND_SIZE_PREVENT_HEIGHT)
  61.         \ptMaxSize\x      = x
  62.         \ptMaxSize\y      = y
  63.         \ptMaxTrackSize\x = x
  64.         \ptMaxTrackSize\y = y
  65.         \ptMinTrackSize\x = x
  66.         \ptMinTrackSize\y = y
  67.       EndWith
  68.      
  69.       ProcedureReturn 0
  70.      
  71.     ; Don't forget to remove all the props etc. if the window is closed.
  72.     Case #WM_DESTROY    
  73.       WndSizePreventClear(hWnd)
  74.   EndSelect
  75.  
  76.   ; If nothing else was prevented / catched and returned, call the original callback procedure to handle other events.
  77.   ProcedureReturn CallWindowProc_(dwOldProc, hWnd, uMsg, wParam, lParam)
  78. EndProcedure  
  79.  
  80. Procedure.i PreventWindowSizing(hWnd.i, State.i)
  81.   Protected oldProc.i   = GetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME)
  82.   Protected oldStyle.l  = 0
  83.   If(State)
  84.     ; If this window already has the state set to 1, return.
  85.     If(oldProc)
  86.       ProcedureReturn #True
  87.     EndIf
  88.    
  89.     ; Set a new callback function for our window and prepare all the props containing important information.
  90.     oldProc = SetWindowLong_(hWnd, #GWL_WNDPROC, @WndSizePreventProc())
  91.     SetProp_(hWnd, #WND_SIZE_PREVENT_PROPNAME, oldProc)
  92.     SetProp_(hWnd, #WND_SIZE_PREVENT_WIDTH, GetWindowWidth(hWnd))
  93.     SetProp_(hWnd, #WND_SIZE_PREVENT_HEIGHT, GetWindowHeight(hWnd))
  94.     SetProp_(hWnd, #WND_SIZE_PREVENT_HADMAX, 0)
  95.    
  96.     ; If the window has a maximize box, we want to disable it. Remove it from the GWL_STYLE long.
  97.     oldStyle = GetWindowLong_(hWnd, #GWL_STYLE)
  98.     If(oldStyle & #WS_MAXIMIZEBOX)
  99.       SetProp_(hWnd, #WND_SIZE_PREVENT_HADMAX, 1)
  100.       SetWindowLong_(hWnd, #GWL_STYLE, oldStyle & ~#WS_MAXIMIZEBOX)
  101.     EndIf
  102.  
  103.     ProcedureReturn #True
  104.   Else
  105.     If(oldProc)
  106.       ; Don't forget to remove all the props etc. if the state is set to 0. Same as WM_DESTROY's steps.
  107.       WndSizePreventClear(hWnd)
  108.       ProcedureReturn #True
  109.     EndIf
  110.   EndIf
  111. EndProcedure
  112.  
  113. ProcedureDLL.i IsValidWindow(hWnd.i)
  114.   ; A DLL wrapper for IsWindow, so we won't have to load another DLL in AMS.
  115.   ProcedureReturn IsWindow_(hWnd)
  116. EndProcedure
  117. ProcedureDLL.i DisableWindowResizing(hWnd.i, intDisabledState.i = 0)
  118.   ; A DLL wrapper for PreventWindowSizing.
  119.   ProcedureReturn PreventWindowSizing(hWnd, intDisabledState)
  120. EndProcedure
  121.  
  122. ;- Example PureBasic implementation. Uncomment the next line to enable it.
  123. ;#WND_SIZE_PREVENT_EXAMPLE = 1
  124. CompilerIf Defined(WND_SIZE_PREVENT_EXAMPLE, #PB_Constant) = 1
  125.   Global SizeableState = 0
  126.   If(OpenWindow(0, 0, 0, 450, 350, "Size test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget))
  127.     ButtonGadget(0, 5, 5, 100, 22, "Toggle Sizeability")
  128.  
  129.     Repeat
  130.       ; Have PureBasic's internal WinProc catch all other events.
  131.       Event = WaitWindowEvent()
  132.       E_GID = EventGadget()
  133.      
  134.       Select Event
  135.         Case #PB_Event_CloseWindow
  136.           Quit = 1
  137.         Case #PB_Event_Gadget
  138.           Select E_GID
  139.             Case 0
  140.               SizeableState ! 1 ; If SizeableState = 0, XOR to 1, if SizeableState = 1, XOR to 0.
  141.               PreventWindowSizing(WindowID(0), SizeableState)
  142.           EndSelect
  143.       EndSelect
  144.     Until Quit
  145.   EndIf
  146. CompilerEndIf
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement