Page 1 of 1

Problem with window size restriction

Posted: Tue May 10, 2011 5:50 pm
by whertz
The following code is taken from an example here on the forums by netmaestro. I just changed the openwindow to open at 400x400, the same as the restriction. The problem is, 400x400 is not the real restricted size, you can still make the window a bit smaller. Changing *mminfo\ptMinTrackSize\y = 400 to *mminfo\ptMinTrackSize\y = 400+MenuHeight() does restrict the y size more but still you can make it smaller. The amount you can make the window smaller also differs from Windows XP and Windows 7 when testing. Is there a fix for this?

Code: Select all

Procedure CallBack(hWnd, Msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select Msg
    Case #WM_GETMINMAXINFO
      *mminfo.MINMAXINFO = lParam
      *mminfo\ptMinTrackSize\x = 400
      *mminfo\ptMinTrackSize\y = 400
      result=0
  EndSelect
  ProcedureReturn result
EndProcedure

OpenWindow(0,0,0,400,400,"Minimum Size = 400 x 400 Demo",$CF0001)
SetWindowCallback(@CallBack())

Repeat:Until WaitWindowEvent()=#WM_CLOSE

Re: Problem with window size restriction

Posted: Tue May 10, 2011 6:20 pm
by nco2k
the width/height of OpenWindow() is the client area. the width/height of MINMAXINFO is the area of the whole window.

c ya,
nco2k

Re: Problem with window size restriction

Posted: Tue May 10, 2011 6:25 pm
by Arctic Fox
Why don't you use WindowBounds()?

Re: Problem with window size restriction

Posted: Tue May 10, 2011 7:30 pm
by whertz
Arctic Fox wrote:Why don't you use WindowBounds()?
Thanks! I was updating one of my old programs and maybe this command wasn't in pb at the time. Which version was this introduced?

Re: Problem with window size restriction

Posted: Tue May 10, 2011 8:16 pm
by Shardik
whertz wrote:Which version was this introduced?
PB 4.30:
- Added: CatchModule(), ArraySize(), WindowBounds(), DesktopX(), DesktopY()

Re: Problem with window size restriction

Posted: Sat Sep 10, 2011 11:22 pm
by Michael Vogel
I am programming a small memory game containing 54 cards (9x6 boxes) and a status bar on a desktop. I want to allow resizing of the windows, but the aspect ratio should be kept.

I tried to calculate the height of the window, if the width has been changed and vice versa, but this does not work. So I have added a flag "sensible" and it got a little bit better, but the window size is still very unstable and even worse, the window does not get the right size (the red status box is seen within the cards).

I also wanted to have something like a snapping function, so that the width could only be changed by 9 and the height by 6 pixels (because of the 9 x 6 cards), but failed completely.

Should I give up and add some buttons for increasing/decreasing the window size?

Code: Select all

Procedure Init()

	Global WinID
	Global WinX,WinY
	Global MaxX=GetSystemMetrics_(#SM_CXFULLSCREEN)
	Global MaxY=GetSystemMetrics_(#SM_CYFULLSCREEN)

	Global CardSize,CardTotal
	Global sensible=#True

	#Space=10
	#Status=50
	#MinX=640
	#MinY=480

	WinX=640
	WinY=480

	Enumeration
		#Win
		#Desk
	EndEnumeration

	WinID=OpenWindow(#Win,0,0,WinX,WinY,"Memory",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
	WindowBounds(#Win,#MinX,#MinY,#MinX<<1,#MinY<<1)
	CanvasGadget(#Desk,0,0,WinX,WinY)

EndProcedure

Procedure Draw()

	Protected i,j,n,x,y

	CardSize=(WinX-(#Space*10))/9
	CardTotal=CardSize+#Space

	StartDrawing(CanvasOutput(#Desk))
	Box(0,0,WinX,WinY,#Yellow)

	n=0
	y=#Space
	For j=0 To 5
		x=#Space
		For i=0 To 8
			n+1
				Box(x,y,CardSize,CardSize,#Black)
			x+CardTotal
		Next i
		y+CardTotal
	Next j

	Box(#Space,WinY-50,WinX-#Space<<1,40,#Red)
	StopDrawing()


EndProcedure
Procedure NewGame()

	Draw()

EndProcedure

Procedure Main()

	Init()
	NewGame()

	Repeat

		Select WaitWindowEvent()


		Case #PB_Event_SizeWindow
			If sensible
				x=WindowWidth(0)
				y=WindowHeight(0)
				If x<>WinX
					If x<#MinX
						x=#MinX
					ElseIf x>MaxX
						x=MaxX
					EndIf
					WinX=x
					y=(x-10*#Space)/9
					y=y*6+7*#Space+#Status
					If y<>WinY
						WinY=y
						sensible=#False
						ResizeWindow(#Win,#PB_Ignore,#PB_Ignore,#PB_Ignore,WinY)
					EndIf
				ElseIf y<>WinY
					If y<#MinY
						y=#MinY
					ElseIf y>MaxY
						y=MaxY
					EndIf
					WinY=y
					x=(y-7*#Space-#Status)/6
					x=x*9+10*#Space
					If x<>WinX
						WinX=x
						sensible=#False
						ResizeWindow(#Win,#PB_Ignore,#PB_Ignore,WinX,#PB_Ignore)
					EndIf
				EndIf
				If sensible=#False
					ResizeGadget(#Desk,#PB_Ignore,#PB_Ignore,WinX,WinY)
					Draw()
				EndIf
			Else
				sensible=#True
			EndIf


		Case #WM_CHAR
			quit=#True

		EndSelect

	Until quit
EndProcedure

Main()

Re: Problem with window size restriction

Posted: Sun Sep 11, 2011 1:33 am
by netmaestro
Michael Vogel wrote:Should I give up and add some buttons for increasing/decreasing the window size?
No, I wouldn't. Give this a try:

Code: Select all

#Space  = 10
#Status = 40
#MinX   = 640
#MinY   = 480
#MinCardSize = 60

Global minx = #minx+2*GetSystemMetrics_(#SM_CXSIZEFRAME)
Global miny = #miny+2*GetSystemMetrics_(#SM_CYSIZEFRAME)+GetSystemMetrics_(#SM_CYCAPTION)
Global cardsize = #MinCardSize

Procedure Draw()
  w=WindowWidth(0):h=WindowHeight(0)
  ResizeGadget(0,0,0,w,h)
  StartDrawing(CanvasOutput(0))
  Box(0,0,w,h,#Yellow)
  drawy = #space
  For j=1 To 6
    drawx = #space
    For i=1 To 9
      Box(drawx, drawy,cardsize,cardsize,#Black)
      drawx+cardsize+#space
    Next
    drawy+cardsize+#space
  Next
  Box(#space,drawy,#space*8+9*cardsize,#status,#Red)
  DrawText(#space+5, drawy+12, "Cardsize = "+Str(cardsize), #Black, #Red)
  StopDrawing()
EndProcedure

Procedure WinProc(hwnd, msg, wparam, lparam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_WINDOWPOSCHANGING
      *winpos.WINDOWPOS = lparam
      With *winpos
        \cx - \cx%9 
        cardsize = (\cx-2*GetSystemMetrics_(#SM_CXSIZEFRAME)-10*#space)/9
        If cardsize<#MinCardSize:cardsize=#MinCardSize:EndIf
        \cy = 8*#space+6*cardsize+#status+2*GetSystemMetrics_(#SM_CYSIZEFRAME)+GetSystemMetrics_(#SM_CYCAPTION)
        If \cx<minx Or \cy<miny
          \cx=minx : \cy=miny : cardsize = #MinCardSize
        EndIf
      EndWith
      Draw()
      ProcedureReturn 0
  EndSelect
  ProcedureReturn result
EndProcedure

OpenWindow(0,0,0,640,480,"Memory Game", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)
SetWindowCallback(@WinProc())
CanvasGadget(0,0,0,640,480)
Draw()

Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Problem with window size restriction

Posted: Sun Sep 11, 2011 7:01 am
by Michael Vogel
netmaestro wrote:
Michael Vogel wrote:Should I give up and add some buttons for increasing/decreasing the window size?
No, I wouldn't.
Brilliant :D

Re: Problem with window size restriction

Posted: Sun Sep 11, 2011 10:06 am
by Michael Vogel
Michael Vogel wrote:
netmaestro wrote:
Michael Vogel wrote:Should I give up and add some buttons for increasing/decreasing the window size?
No, I wouldn't.
Brilliant :D
Hm, found a small problem, when using Alt+Tab to switch to other open windows, the program will sometimes calculate a small cardsize...
...I have added If \cx after the line With *WinPos, now it seems to be stable :?

Re: Problem with window size restriction

Posted: Sun Sep 11, 2011 9:05 pm
by netmaestro
Here's a more professional approach. The window is sizable from all directions & corners, and the alt-tab problem is not present. Also, note that you can doubleclick the frame or caption and go instantly to the original size:

Code: Select all

#Space  = 10
#Status = 40
#MinX   = 640
#MinY   = 480
#MinCardSize = 60

Global mincx = #minx+2*GetSystemMetrics_(#SM_CXSIZEFRAME)
Global mincy = #miny+2*GetSystemMetrics_(#SM_CYSIZEFRAME)+GetSystemMetrics_(#SM_CYCAPTION)
Global cardsize = #MinCardSize

Procedure Draw()
  w=WindowWidth(0):h=WindowHeight(0)
  ResizeGadget(0,0,0,w,h)
  StartDrawing(CanvasOutput(0))
  Box(0,0,w,h,#Yellow)
  drawy = #space
  For j=1 To 6
    drawx = #space
    For i=1 To 9
      Box(drawx, drawy,cardsize,cardsize,#Black)
      drawx+cardsize+#space
    Next
    drawy+cardsize+#space
  Next
  Box(#space,drawy,#space*8+9*cardsize,#status,#Red)
  DrawText(#space+5, drawy+12, "Cardsize = "+Str(cardsize), #Black, #Red)
  StopDrawing()
EndProcedure

Procedure WinProc(hwnd, msg, wparam, lparam)
  result = #PB_ProcessPureBasicEvents
  Static old.RECT
  Select msg
      
    Case #WM_NCLBUTTONDBLCLK
      cardsize = #MinCardSize
      ResizeWindow(0,#PB_Ignore,#PB_Ignore,#minx,#miny)
      Draw()
      
    Case #WM_ENTERSIZEMOVE
      GetWindowRect_(hwnd, @old.RECT)
      result = 0
      
    Case #WM_SIZING 
      
      *new.RECT = lparam
      
      Select wparam
        Case #WMSZ_BOTTOMRIGHT,#WMSZ_RIGHT 
          delta = *new\right-old\right
          delta - delta%9
          *new\right=old\right+delta
          cx = *new\right-*new\left
          cardsize = (cx-2*GetSystemMetrics_(#SM_CXSIZEFRAME)-10*#space)/9
          cy = 8*#space+6*cardsize+#status+2*GetSystemMetrics_(#SM_CYSIZEFRAME)+GetSystemMetrics_(#SM_CYCAPTION)
          *new\bottom = old\top+cy
          If cx < mincx Or cy < mincy
            *new\right = old\left+mincx : *new\bottom = old\top+mincy : cardsize = #MinCardSize
          EndIf
          
        Case #WMSZ_BOTTOMLEFT,#WMSZ_LEFT 
          delta = old\left-*new\left
          delta - delta%9
          *new\left=old\left-delta
          cx = *new\right-*new\left
          cardsize = (cx-2*GetSystemMetrics_(#SM_CXSIZEFRAME)-10*#space)/9
          cy = 8*#space+6*cardsize+#status+2*GetSystemMetrics_(#SM_CYSIZEFRAME)+GetSystemMetrics_(#SM_CYCAPTION)
          *new\bottom = old\top+cy
          If cx < mincx Or cy < mincy
            *new\left = old\right-mincx : *new\bottom = old\top+mincy : cardsize = #MinCardSize
          EndIf
         
        Case #WMSZ_TOP, #WMSZ_TOPLEFT
          delta = old\top-*new\top
          delta - delta%6
          *new\top=old\top-delta
          cy = old\bottom-*new\top
          cardsize = (cy-2*GetSystemMetrics_(#SM_CXSIZEFRAME)-8*#space-#status-GetSystemMetrics_(#SM_CYCAPTION))/6
          cx = 10*#space+9*cardsize+2*GetSystemMetrics_(#SM_CYSIZEFRAME)
          *new\left = old\right-cx
          If cx < mincx Or cy < mincy
            *new\left = old\right-mincx : *new\top = old\bottom-mincy : cardsize = #MinCardSize
          EndIf
          
        Case #WMSZ_TOPRIGHT
          delta = old\top-*new\top
          delta - delta%6
          *new\top=old\top-delta
          cy = old\bottom-*new\top
          cardsize = (cy-2*GetSystemMetrics_(#SM_CXSIZEFRAME)-8*#space-#status-GetSystemMetrics_(#SM_CYCAPTION))/6
          cx = 10*#space+9*cardsize+2*GetSystemMetrics_(#SM_CYSIZEFRAME)
          *new\right = old\left+cx
          If cx < mincx Or cy < mincy
            *new\right = old\left+mincx : *new\top = old\bottom-mincy : cardsize = #MinCardSize
          EndIf
          
        Case #WMSZ_BOTTOM
          delta = old\bottom-*new\bottom
          delta - delta%6
          *new\bottom=old\bottom-delta
          cy = *new\bottom-old\top
          cardsize = (cy-2*GetSystemMetrics_(#SM_CXSIZEFRAME)-8*#space-#status-GetSystemMetrics_(#SM_CYCAPTION))/6
          cx = 10*#space+9*cardsize+2*GetSystemMetrics_(#SM_CYSIZEFRAME)
          *new\left = old\right-cx
          If cx < mincx Or cy < mincy
            *new\left = old\right-mincx : *new\bottom = old\top+mincy : cardsize = #MinCardSize
          EndIf
          
      EndSelect
      
      Draw()
      result = #True

  EndSelect
  
  ProcedureReturn result
  
EndProcedure

OpenWindow(0,0,0,640,480,"Memory Game", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)
SetWindowCallback(@WinProc())
CanvasGadget(0,0,0,640,480)
Draw()

Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Problem with window size restriction

Posted: Sun Sep 18, 2011 9:51 am
by Michael Vogel
Haven't seen your update, will check this now (what means in the next hours, I'm actually slightly handicapped after a little accident)

Bonus question - how to set the lparam correctly, if I'd like to start the procedure by SendMessage(WinID,#WM_WINDOWPOSCHANGING,0,?)