WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Dialog Editor version 6.X
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Bitmap Resizing in Dialog


Question:

When a preview of an image is displayed, using the pixie extender, on a picturebutton, is there a way of either resizing the button or not stretching the image to fit the button?

I am trying to create a dialog which will display an image preview, which can be clicked to edit in the default editor, but some of the photographs are not the same dimensions as the button, while others are.

Any help would be appreciated...

Answer:

It sounds to me like you need to preserve the "aspect ratio" of the image. Basically you need the button to be the exact same shape of the image, but not necessarily the exact same size. Then, when WinBatch fits the image to the button, it still looks like it is suppsoed to.

So first you have to get the dimensions of the bitmap

bmp="C:\AsstDocs\mmdata\WallPaper\beachcliffs.bmp"

bb=BinaryAlloc(30)
BinaryReadEx(bb,0,bmp,0,30)
height=BinaryPeek4(bb,18)
width=BinaryPeek4(bb,22)
BinaryFree(bb)
Message(bmp,"%height% x %width%")
So then compute the aspect ratio
; using floating point math here
aspect=(height+0.0)/width
Now... you must figure out the maximum button size you can use. Basically the button cannot exceed that size in either dimension. So lets say the buttonsize is 80x80 dialog units. We will either have to adjust the width or the height of the button, depending on whether the image is landscape or portrait format
;Undebugged
dlgwidth=80
dlgheight=80

if bmpheight;>bmpwidth
	;its gonna be a portrait format
	; so adjust width
	dlgwidth=int(dlgwidth/aspect)
else
	;landscape
	dlgHeight=int(dlgheight/aspect)
endif
Now we have the desired shape of the button.

If using simple dialogs with no callbacks, you now have to re-manufacture the dialog cntrol definition line.

If using a dialog with callbacks, you have to get the handle to the control and call some API function to resize the control.

Users Sample Code:

This uses a 6.1 dialog and has the disadvantage that WB insists on resizing the image if it doesn't fit. There are two solutions. One is to set up a nominal grid for the button then scale the image to the grid, preserving the aspect ratio. The other is to scale the button to fit the image.

If you want to maintain the button grid and scale the image to fit then you have to use BoxesUp() but that gets messy.

#definesubroutine zMain(hDlg, zMsg, zID, zRsvd1, zRsvd2)
   select zMsg
      case 0
         hBtn = dllcall(user32, long:"GetDlgItem", long:hDlg, long:100)
         if Tip==0
            Rect = Arrayize(udfGetWinRect(hBtn, 0), ',')
            cxP  = Rect[2] - Rect[0]
            x2   = cxP
            cyP  = Rect[3] - Rect[1]
         endif
         dialogprocoptions(hDlg, 2, 1)

         return -1
         
      case 2
         if zID==2 then return 0
         dialogcontrolstate(hDlg, 1, 3, 1)
         Tip = Tip+1
         select Tip
            case 1
               Image = 'Owl.bmp'
               break
            case 2
               Image = 'WBOwl.bmp'
               break
            case 3
               Image = 'Opus.bmp'
               break
            case 4
               Image = 'Meg.jpg'
               break
            case 5
               Image = 'Owl.bmp'
               break
            case 6
               Image = 'WBOwl.bmp'
               break
            case 7
               Image = 'Opus.bmp'
               break
            case 8
               Image = 'Meg.jpg'
               break
            case 9
               return -1
         endselect
         
         Ary = arrayize(ImgInfo(Image), @tab)
         Size = strcat(Ary[0], ' x ', Ary[1])
         if Tip;<=4
            Title = 'Scaling Images to 160 x 160 Grid.  %Image% (%Size%)'
            xP    = cxP
            yP    = cyP
            Scale = 1
         
         else   
            Title = 'Scaling Button to %Image% (%Size%)'
            Scale = 0
            xP = Ary[0]
            yP = Ary[1]
         endif
         
         SetImage()
         if Tip==8 then Title = 'That''s my puppy!'
         wintitle('~Scaling', Title)

         dialogcontrolset(hDlg, 1, 12, 'default.bmp')
         dialogcontrolstate(hDlg, 1, 4, 1)

         return -2

   endselect
   return -1
   
#endsubroutine

#definesubroutine SetImage()   
   if !ImgIsValid(Image)
      message('ERROR!', Blurb)
      return 0
   endif

   sImage = strlower(Image)
   if strlower(fileextension(sImage))=='bmp'
      filecopy(sImage, 'default.bmp', 0)
      Out = 'default.bmp'
   else      
      Out = strreplace(strreplace(sImage, fileextension(sImage), 'bmp'), fileroot(sImage), 'default')
      IC = imgconvert(sImage, Out)
   endif   
   
   if Scale
      Ary = arrayize(ImgInfo(Image), @tab)
      Rat1 = xP*1.0/Ary[0]
      Rat2 = yP*1.0/Ary[1]
      if Rat1;<Rat2
         yP = int(Rat1*Ary[1])
      else
         xP = int(Rat2*Ary[0])
      endif
      ImgScale(Out,Out,XX, YY)   
   endif
   if yP;<YY then yAdj = 8 + (YY-yp)/2
      else yAdj = 8
   udfSetWinPos(hBtn, 0, (360-xP)/2, yAdj, xP, yP, 4)
   return
#endsubroutine

#definefunction udfGetWinRect(WndName, Rqst)
   Rtn = 0
   Rect = binaryalloc(16)
   if isnumber(WndName)
      hWnd = WndName
   else
      hWnd = dllhwnd(WndName)
   endif
   if hWnd==0 || hWnd==-1 then goto Free

   select Rqst
      case 0
         DllCall(strcat(DirWindows(1), 'User32.dll'), long:"GetWindowRect", long:hWnd, lpbinary:Rect)
         break
      case 1
         DllCall(strcat(DirWindows(1), 'User32.dll'), long:"GetClientRect", long:hWnd, lpbinary:Rect)
         break
      case Rqst
         goto Free
   endselect

   Rtn = ''
   for cnt = 0 to 3
      Rtn =  iteminsert(binarypeek4(Rect, cnt*4), -1, Rtn, ',')
   next

:Free
   binaryfree(Rect)
   return Rtn

#endfunction

#definefunction udfSetWinPos(hWnd, hZOrder, xP, yP, cxP, cyP, uFlags)
   User32   = StrCat(DirWindows(1), 'User32.DLL')
   Entry = 'word:"SetWindowPos"'

   Args = StrCat(`long:hWnd`)
   Args = StrCat(Args, `,long:hZOrder`)
   Args = StrCat(Args, `,word:xP`)
   Args = StrCat(Args, `,word:yP`)
   Args = StrCat(Args, `,word:cxP`)
   Args = StrCat(Args, `,word:cyP`)
   Args = StrCat(Args, `,word:uFlags`)

   rtn = dllcall(User32, %Entry%, %Args%)
   return rtn
#endfunction

AddExtender("WWIMG34I.DLL")
AddExtender("wwctl34i.dll")

Intcontrol(12,5,0,0,0)        ; Quiet termination.
IntControl(54,"",1,0,0)       ; On Top! 

User32 = strcat(dirwindows(1), "User32.DLL")
WbtDir = filepath(IntControl(1004, 0, 0, 0, 0))
dirchange(WbtDir)
if fileexist('default.bmp') then filedelete('default.bmp')

Tip = 0
XX  = 160    ; ROT 2 pixels per dialog unit.
YY  = 160

zFormat=`WWWDLGED,6.1`
zCaption=`Scaling Images to 160 x 160 Button Grid.`
zX=-1
zY=-1
zWidth=180
zHeight=184
zNumControls=002
zProcedure=`zMain`
zFont=`DEFAULT`
zTextColor=`DEFAULT`
zBackground=`DEFAULT,DEFAULT`
zConfig=0

z001=`050,004,80,80,PICTUREBUTTON,DEFAULT,"Button 160 x 160",1,1,128,DEFAULT,DEFAULT,"default.bmp"`
z002=`050,164,80,012,PUSHBUTTON,DEFAULT,"OK",2,2,DEFAULT,DEFAULT,DEFAULT,DEFAULT`

Btn=Dialog("z")

Article ID:   W16403
File Created: 2005:11:01:11:17:02
Last Updated: 2005:11:01:11:17:02