Page 1 of 3
Resizing third-party window that has a minimum
Posted: Mon Feb 11, 2013 4:16 pm
by MachineCode
I'm trying to resize a third-party app's window with SetWindowPos_(), basically to just its title bar, but it won't let me set it that small. It's obviously got some minimum size restriction. Can that be overridden with some API call? I've searched but cannot find. Thanks for any tips.
Re: Resizing third-party window that has a minimum
Posted: Mon Feb 11, 2013 6:52 pm
by RASHAD
I am not sure if it works with your case
But it works with Calculator
Code: Select all
RunProgram("Calc.exe")
Repeat
hWnd = FindWindow_(0,"Calculator")
Until hWnd
SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE) |#WS_SIZEBOX)
Delay(200)
MoveWindow_(hWnd,10,10,300,50,1)
Re: Resizing third-party window that has a minimum
Posted: Mon Feb 11, 2013 7:51 pm
by netmaestro
In PureBasic we have the WindowBounds() command which sets limits on the window size. If a PB programmer set window bounds on a window I doubt that a third party program could size it outside those limits, as it will refuse even a native ResizeWindow() that is out of bounds. That being the case, the window you are trying to resize may be using the same technique for enforcing size limits and if it is I don't think there's going to be a way to overcome it.
Re: Resizing third-party window that has a minimum
Posted: Mon Feb 11, 2013 8:43 pm
by Danilo
PB program with WindowBounds():
Code: Select all
If OpenWindow(0, 0, 0, 300, 300, "Resize me !", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
WindowBounds(0, 200, 200, 400, 400)
StickyWindow(0,1)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Resizing program:
Code: Select all
Repeat
hWnd = FindWindow_(0,"Resize me !")
Until hWnd
GetWindowRect_(hWnd,@r.RECT)
SetWindowPos_(hWnd,0,r\left,r\top,r\right-r\left,35,#SWP_NOSENDCHANGING|#SWP_NOACTIVATE)
MessageRequester("INFO","OK")
Works here. The target window does not know it got resized with #SWP_NOSENDCHANGING.
Re: Resizing third-party window that has a minimum
Posted: Mon Feb 11, 2013 9:09 pm
by RASHAD
@Danilo Fantastic
It works even with
Code: Select all
Global wr.RECT
Procedure WinProc(hwnd, msg, wparam, lparam)
result=#PB_ProcessPureBasicEvents
Select msg
Case #WM_WINDOWPOSCHANGING
*wp.WINDOWPOS = lparam
With *wp
\x=wr\left
\y=wr\top
\cx = wr\right-wr\left
\cy = wr\bottom-wr\top
EndWith
result=0
EndSelect
ProcedureReturn result
EndProcedure
OpenWindow(0,400,400,320,240,"TEST",#PB_Window_SizeGadget|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
SetWindowCallback(@WinProc())
GetWindowRect_(WindowID(0), wr)
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
Re: Resizing third-party window that has a minimum
Posted: Mon Feb 11, 2013 9:13 pm
by ts-soft
Windows Bounds is more like this API:
Code: Select all
EnableExplicit
Procedure wincb(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected mm.MINMAXINFO
Select uMsg
Case #WM_GETMINMAXINFO
mm\ptMinTrackSize\x = 100
mm\ptMinTrackSize\y = 100
mm\ptMaxTrackSize\x = 700
mm\ptMaxTrackSize\y = 500
CopyMemory(@mm, lParam, SizeOf(MINMAXINFO))
Result = 0
EndSelect
ProcedureReturn Result
EndProcedure
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Resize me !", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
SetWindowCallback(@wincb())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
Resizing works a bit.
Re: Resizing third-party window that has a minimum
Posted: Tue Feb 12, 2013 9:02 am
by MachineCode
Rashad, your code doesn't work with an app called "Star Downloader", but Danilo's does, do Danilo wins!

Thanks, Dan. (I also prefer Danilo's because it doesn't alter the style of the target window).
Re: Resizing third-party window that has a minimum
Posted: Tue Feb 12, 2013 9:31 am
by Danilo
MachineCode wrote:Rashad, your code doesn't work with an app called "Star Downloader", but Danilo's does, do Danilo wins!

Thanks, Dan. (I also prefer Danilo's because it doesn't alter the style of the target window).
Thank you very much!
Just wanted to say something about the window height. I had hard-coded it to height 35,
because GetSystemMetrics_(#SM_CYCAPTION) did not return the correct height for WinXP styled windows.
It may be better to calculate the size from the window rectangle and the window client rectangle:
Code: Select all
GetWindowRect_(hWnd,@r.RECT) ; get window outer rectangle/bounds
GetClientRect_(hWnd,@cr.RECT) ; get size of window client area (inner width, where the 'gadgets' are located)
SetWindowPos_(hWnd,0,r\left,r\top,r\right-r\left,r\bottom-r\top-cr\bottom+MenuHeight(),#SWP_NOSENDCHANGING|#SWP_NOACTIVATE)
Remove "+MenuHeight()" (it is just an example) and you should get a window that is always the size of the border and titlebar only (XP style enabled or disabled, all Windows versions).
Re: Resizing third-party window that has a minimum
Posted: Tue Feb 12, 2013 11:40 am
by MachineCode
Danilo wrote:GetSystemMetrics_(#SM_CYCAPTION) did not return the correct height for WinXP styled windows
What about GetSystemMetrics_(#SM_CYMIN) instead? Seems to work fine on Win 7, but I can't test on XP. It's what I'm using now.
Re: Resizing third-party window that has a minimum
Posted: Sun Apr 03, 2022 11:00 am
by SharkyEXE
Hello
Please, help me, how resize this window?
Code: Select all
Define dir.BROWSEINFO
dir\ulFlags = #BIF_EDITBOX
SHBrowseForFolder_(@dir)
Thank You!
Re: Resizing third-party window that has a minimum
Posted: Mon Apr 04, 2022 10:17 pm
by breeze4me
SharkyEXE wrote: Sun Apr 03, 2022 11:00 am
Hello
Please, help me, how resize this window?
Code: Select all
Define dir.BROWSEINFO
dir\ulFlags = #BIF_EDITBOX
SHBrowseForFolder_(@dir)
Thank You!
This is a simple example of using a thread. Alternatively, you may use message hook.
Code: Select all
Structure FolderNewPos
x.l
y.l
w.l
h.l
EndStructure
Procedure ResizeFolderWnd(*pos.FolderNewPos)
Protected hWnd, i
If *pos
For i = 1 To 2000
hWnd = FindWindow_("#32770", 0)
If hWnd
If GetForegroundWindow_() = hWnd
MoveWindow_(hWnd, *pos\x, *pos\y, *pos\w, *pos\h, 1)
;SetWindowPos_(hWnd, 0, *pos\x, *pos\y, *pos\w, *pos\h, #SWP_NOZORDER | #SWP_FRAMECHANGED)
Break
EndIf
EndIf
Delay(1)
Next
EndIf
EndProcedure
Define newpos.FolderNewPos
newpos\x = 10
newpos\y = 10
newpos\w = 500
newpos\h = 700
CreateThread(@ResizeFolderWnd(), newpos)
Define dir.BROWSEINFO
dir\ulFlags = #BIF_EDITBOX | #BIF_NEWDIALOGSTYLE ; #BIF_NEWDIALOGSTYLE flag is essential. Without the flag, child controls cannot be rearranged.
SHBrowseForFolder_(@dir)
Re: Resizing third-party window that has a minimum
Posted: Tue Apr 05, 2022 8:13 pm
by SharkyEXE
breeze4me wrote: Mon Apr 04, 2022 10:17 pm
Hello
Your script if i click on folder - expand tree
I do not have, if i click on folder - expand tree
I my exapmle
Define dir.BROWSEINFO
dir\ulFlags = #BIF_EDITBOX
SHBrowseForFolder_(@dir)
if i click on folder - NOT expand tree
Please, write, how make in your script, if i click on folder - NOT expand tree
Re: Resizing third-party window that has a minimum
Posted: Tue Apr 05, 2022 11:24 pm
by breeze4me
SharkyEXE wrote: Tue Apr 05, 2022 8:13 pm
Hello
Your script if i click on folder - expand tree
I do not have, if i click on folder - expand tree
I my exapmle
Define dir.BROWSEINFO
dir\ulFlags = #BIF_EDITBOX
SHBrowseForFolder_(@dir)
if i click on folder - NOT expand tree
Please, write, how make in your script, if i click on folder - NOT expand tree
Try this.
Code: Select all
#BFFM_INITIALIZED = 1
Structure FolderNewPos
hMutex.i
hWnd.i
x.l
y.l
w.l
h.l
EndStructure
Procedure ResizeFolderWnd(*pos.FolderNewPos)
Protected i
For i = 0 To 1000
If TryLockMutex(*pos\hMutex)
FreeMutex(*pos\hMutex)
If *pos\hWnd
SetWindowPos_(*pos\hWnd, 0, *pos\x, *pos\y, *pos\w, *pos\h, #SWP_NOZORDER | #SWP_NOOWNERZORDER | #SWP_FRAMECHANGED | #SWP_SHOWWINDOW)
EndIf
Break
EndIf
Delay(50)
Next
EndProcedure
; Procedure EnumChildProc(hwnd, lParam)
; Protected Buffer.s{64}
;
; If GetClassName_(hwnd, @Buffer, 63)
; If FindString(Buffer, "treeview", 1, #PB_String_NoCase)
; SetWindowLong_(hwnd, #GWL_STYLE, GetWindowLong_(hwnd, #GWL_STYLE) & ~#TVS_SINGLEEXPAND)
; ProcedureReturn 0
; EndIf
; EndIf
;
; ProcedureReturn 1
; EndProcedure
Procedure BrowseCallbackProc(hwnd, uMsg, lParam, *lpData.FolderNewPos)
Protected Buffer.s, hShell, hTree
If uMsg = #BFFM_INITIALIZED
SetWindowPos_(hWnd, 0, -30000, -30000, 0, 0, #SWP_NOZORDER | #SWP_NOOWNERZORDER | #SWP_NOSIZE | #SWP_HIDEWINDOW)
Repeat
hShell = GetDlgItem_(hwnd, 0)
If hShell
hTree = GetDlgItem_(hShell, 100)
If hTree
Buffer = Space(64)
If GetClassName_(hTree, @Buffer, 63)
If FindString(Buffer, "treeview", 1, #PB_String_NoCase)
SetWindowLong_(hTree, #GWL_STYLE, GetWindowLong_(hTree, #GWL_STYLE) & ~#TVS_SINGLEEXPAND)
Break
EndIf
EndIf
EndIf
EndIf
;EnumChildWindows_(hwnd, @EnumChildProc(), 0) ;If the above attempt fails, try again here.
Break
ForEver
;;MoveWindow_(hwnd, *lpData\x, *lpData\y, *lpData\w, *lpData\h, 1) ;It does not work properly, so do the following.
*lpData\hWnd = hwnd
UnlockMutex(*lpData\hMutex)
EndIf
ProcedureReturn 0
EndProcedure
Define newpos.FolderNewPos
newpos\x = 50
newpos\y = 50
newpos\w = 400
newpos\h = 500
newpos\hMutex = CreateMutex()
If newpos\hMutex
LockMutex(newpos\hMutex)
CreateThread(@ResizeFolderWnd(), newpos)
Define dir.BROWSEINFO
dir\lpfn = @BrowseCallbackProc()
dir\lParam = @newpos
dir\ulFlags = #BIF_EDITBOX | #BIF_NEWDIALOGSTYLE ; #BIF_NEWDIALOGSTYLE flag is essential. Without the flag, child controls cannot be rearranged.
SHBrowseForFolder_(@dir)
EndIf
A better way.
Code: Select all
#BFFM_INITIALIZED = 1
Structure FolderNewPos
x.l
y.l
w.l
h.l
EndStructure
#App_WndProcString = "AppOldWndProc"
Global newpos.FolderNewPos
Procedure FolderWndProc(hWnd, Message, wParam, lParam)
Protected old = GetProp_(hWnd, #App_WndProcString)
If Message = #WM_ACTIVATE
SetWindowPos_(hWnd, 0, newpos\x, newpos\y, newpos\w, newpos\h, #SWP_NOZORDER | #SWP_NOOWNERZORDER | #SWP_FRAMECHANGED)
SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, old)
RemoveProp_(hWnd, #App_WndProcString)
EndIf
ProcedureReturn CallWindowProc_(old, hWnd, Message, wParam, lParam)
EndProcedure
; Procedure EnumChildProc(hwnd, lParam)
; Protected Buffer.s{64}
;
; If GetClassName_(hwnd, @Buffer, 63)
; If FindString(Buffer, "treeview", 1, #PB_String_NoCase)
; SetWindowLong_(hwnd, #GWL_STYLE, GetWindowLong_(hwnd, #GWL_STYLE) & ~#TVS_SINGLEEXPAND)
; ProcedureReturn 0
; EndIf
; EndIf
;
; ProcedureReturn 1
; EndProcedure
Procedure BrowseCallbackProc(hwnd, uMsg, lParam, lpData)
Protected Buffer.s, hShell, hTree, old
If uMsg = #BFFM_INITIALIZED
Repeat
hShell = GetDlgItem_(hwnd, 0)
If hShell
hTree = GetDlgItem_(hShell, 100)
If hTree
Buffer = Space(64)
If GetClassName_(hTree, @Buffer, 63)
If FindString(Buffer, "treeview", 1, #PB_String_NoCase)
SetWindowLong_(hTree, #GWL_STYLE, GetWindowLong_(hTree, #GWL_STYLE) & ~#TVS_SINGLEEXPAND)
Break
EndIf
EndIf
EndIf
EndIf
;EnumChildWindows_(hwnd, @EnumChildProc(), 0) ;If the above attempt fails, try again here.
Break
ForEver
old = SetWindowLongPtr_(hwnd, #GWLP_WNDPROC, @FolderWndProc())
SetProp_(hwnd, #App_WndProcString, old)
EndIf
ProcedureReturn 0
EndProcedure
newpos\x = 50
newpos\y = 50
newpos\w = 400
newpos\h = 500
Define dir.BROWSEINFO
dir\lpfn = @BrowseCallbackProc()
dir\ulFlags = #BIF_EDITBOX | #BIF_NEWDIALOGSTYLE ; #BIF_NEWDIALOGSTYLE flag is essential. Without the flag, child controls cannot be rearranged.
SHBrowseForFolder_(@dir)
Re: Resizing third-party window that has a minimum
Posted: Wed Apr 06, 2022 3:09 pm
by SharkyEXE
breeze4me
Hello
Very-very thank You!
Your 2 code work perfectly - if i click on folder - NOT expand tree
Little question - what different on two code, whats code is better or in work two code work 100 percent identically or not?
Re: Resizing third-party window that has a minimum
Posted: Wed Apr 06, 2022 5:52 pm
by breeze4me
SharkyEXE wrote: Wed Apr 06, 2022 3:09 pm
breeze4me
Hello
Very-very thank You!
Your 2 code work perfectly - if i click on folder - NOT expand tree
Little question - what different on two code, whats code is better or in work two code work 100 percent identically or not?
Both do the same thing, but the second code is lighter and more efficient. The first one is somewhat inefficient because it uses a mutex and a thread.
So I recommend the second one.