Author Topic: Autosizing reworked  (Read 811 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Hero Member
  • *****
  • Posts: 825
Autosizing reworked
« on: February 27, 2019, 08:11:16 AM »
Hello,

after a little pause for thought, I redesigned the autosize project, which I started here:

https://www.oxygenbasic.org/forum/index.php?topic=1747.msg18936#msg18936

To avoid name conflicts, I have now used strings for the placement factors. The code of the procedures has been simplified, it should now be easier to read. I call the new include file autosizing.inc and I applied these name changes:

pinControl -> pinCtl
unpinControl -> unpinCtl

For resizing / moving the controls with sub resizeControls I used SetWindowPos in combination with SWP_NOZORDER | SWP_DEFERERASE. If this is not sufficient to minimize flickering then perhaps End/Begin/DeferWindowPos must be considered, but this would be a bit more complicated.

At the moment I am quite happy with the code in its current form. Attached is the zip file with autosizing.inc and seven examples which demonstrate some of the possible uses.

Edit: I had to do a small modification for modpinCtl (see reply #12). I also replaced autosizing.zip with five demos which should show the possible uses of the include file. 

This is the autosizing.inc:
Code: OxygenBasic
  1. ' Helper routines for resizing and moving / stretching controls
  2. ' in a window and setting the minimum size of a window
  3.  
  4. 'factors for placement, used as string:
  5. '  "TL" or "0.0, 0.0"  = Top left
  6. '  "TM" or "0.5, 0.0"  = Top middle
  7. '  "TR" or "1.0, 0.0"  = Top right
  8. '  "ML" or "0.0, 0.5"  = Middle left
  9. '  "MM" or "0.5, 0.5"  = Middle middle (Centre)
  10. '  "MR" or "1.0, 0.5"  = Middle right
  11. '  "BL" or "0.0, 1.0"  = Bottom left
  12. '  "BM" or "0.5, 1.0"  = Bottom middle
  13. '  "BR" or "1.0, 1.0"  = Bottom right
  14.  
  15. '
  16. 'Examples:
  17. '
  18. 'Pin control on the bottom-right-hand side of the window
  19. 'pinCtl(hCtl, hWin, "BR")
  20. 'pinCtl(hCtl, hWin, "1.0, 1.0")
  21.  
  22. 'Move / Stretch control if window is resized, from offset 1 to offset 2
  23. 'pinCtl(hCtl, hWin, "TL", "BR" )
  24. 'pinCtl(hCtl, hWin, "0.0, 0.0", "1.0, 1.0")
  25.  
  26. 'Stop resizing and moving control if the window falls below a certain size (pixels)
  27. 'unpinCtl(hCtl, hWin, 450, 350)
  28.  
  29. 'Move / Resize the controls when WM_SIZE message of parent window is handled:
  30. 'resizeControls(hWin)
  31.  
  32. 'Limit the minimum permitted size of a window to width and height (pixels),
  33. 'can be used with the WM_GETMINMAXINFO message:
  34. 'setMinSize(450, 350)
  35.  
  36. ===================================================================================
  37.  
  38. uses corewin
  39.  
  40. % HWND_DESKTOP=0
  41. % WM_SIZING=532
  42. % WM_GETMINMAXINFO=36
  43. % SWP_NOZORDER=4
  44. % SWP_DEFERERASE=0x2000
  45.  
  46. type Sizel
  47.    int cx    'width
  48.   int cy    'height
  49. end type
  50.  
  51. type PFactor
  52.    double fx
  53.    double fy
  54. end type
  55.      
  56. type sizing_data
  57.    int index
  58.    sys hParent
  59.    sys hCtl
  60.    PFactor pf1                    'placement factors
  61.   PFactor pf2                    'placement factors
  62.   RECT ofs                       'offset Left, Top, Right, Bottom
  63.   int unpinned                   '0=pinned, 1=unpinned
  64.   int w, h                       'width and height of parent
  65. end type
  66.  
  67. 'bounds for record data
  68. type MaxPinnedCtls
  69.    int count
  70. end type
  71.  
  72. MaxPinnedCtls MaxPinned = {10}  
  73. redim sizing_data PinCtl_Rec[MaxPinned.count]
  74.  
  75.  
  76. 'Attach position of the Control relative to the Parent window
  77. sub pinCtl(sys hCtl, sys hParent, string placement1, optional string placement2="NONE_")
  78.     PFactor pf1, pf2
  79.  
  80.     string place1=lcase(ltrim rtrim(placement1))
  81.     string place2=lcase(ltrim rtrim(placement2))
  82.  
  83.     'Method 1: Static attachment
  84.    while 1
  85.        if place1="tl" then pf1.fx=0.0 : pf1.fy=0.0 : exit while
  86.        if place1="tm" then pf1.fx=0.5 : pf1.fy=0.0 : exit while
  87.        if place1="tr" then pf1.fx=1.0 : pf1.fy=0.0 : exit while
  88.        if place1="ml" then pf1.fx=0.0 : pf1.fy=0.5 : exit while
  89.        if place1="mm" then pf1.fx=0.5 : pf1.fy=0.5 : exit while
  90.        if place1="mr" then pf1.fx=1.0 : pf1.fy=0.5 : exit while
  91.        if place1="bl" then pf1.fx=0.0 : pf1.fy=1.0 : exit while
  92.        if place1="bm" then pf1.fx=0.5 : pf1.fy=1.0 : exit while
  93.        if place1="br" then pf1.fx=1.0 : pf1.fy=1.0 : exit while              
  94.        'factors as values?
  95.       int pos=instr(place1,",")
  96.        if pos then pf1.fx=val(left(place1,pos-1)) : pf1.fy=val(mid(place1,pos+1)) : exit while
  97.        mbox "Error: wrong placement 1 in pinCtl function" : exit while
  98.     wend
  99.     if place2="none_" then pf2.fx=pf1.fx : pf2.fy=pf1.fy
  100.        
  101.     'Method 2: Stretchy attachment?
  102.    while 1
  103.        if place2="none_" then exit while
  104.        if place2="tl" then pf2.fx=0.0 : pf2.fy=0.0 : exit while
  105.        if place2="tm" then pf2.fx=0.5 : pf2.fy=0.0 : exit while
  106.        if place2="tr" then pf2.fx=1.0 : pf2.fy=0.0 : exit while
  107.        if place2="ml" then pf2.fx=0.0 : pf2.fy=0.5 : exit while
  108.        if place2="mm" then pf2.fx=0.5 : pf2.fy=0.5 : exit while
  109.        if place2="mr" then pf2.fx=1.0 : pf2.fy=0.5 : exit while
  110.        if place2="bl" then pf2.fx=0.0 : pf2.fy=1.0 : exit while
  111.        if place2="bm" then pf2.fx=0.5 : pf2.fy=1.0 : exit while
  112.        if place2="br" then pf2.fx=1.0 : pf2.fy=1.0 : exit while              
  113.        'factors as values?
  114.       pos=instr(place2,",")
  115.        if pos then pf2.fx=val(left(place2,pos-1)) : pf2.fy=val(mid(place2,pos+1)) : exit while
  116.        mbox "Error: wrong placement 2 in pinCtl function" : exit while
  117.     wend  
  118.  
  119.     Sizel ctlSize
  120.     RECT pRect, cRect
  121.     RECT ofs
  122.      
  123.     'Get the size of the hParent window to be able to calculate offsets
  124.    GetClientRect(hParent, &pRect)
  125.     ctlSize.cx = pRect.right : ctlSize.cy = pRect.bottom
  126.     GetWindowRect(hCtl, &cRect)
  127.        
  128.     'Calculate the offsets of the left, top, bottom, and right of the control.
  129.    MapWindowPoints(HWND_DESKTOP, GetParent(hCtl),  &cRect, 2)
  130.     ofs.left=  cRect.left   - ctlSize.cx*pf1.fx
  131.     ofs.top=   cRect.top    - ctlSize.cy*pf1.fy
  132.     ofs.right= cRect.right  - ctlSize.cx*pf2.fx
  133.     ofs.bottom=cRect.bottom - ctlSize.cy*pf2.fy
  134.  
  135.     'Add entry to the data records
  136.    static int idx
  137.     'does hCtl already exist?
  138.    int i
  139.     for i=1 to idx
  140.       if PinCtl_Rec[i].hCtl=hCtl then
  141.         idx=i-1
  142.         exit for
  143.       end if
  144.     next i              
  145.     idx+=1
  146.     if idx>MaxPinned.count then
  147.       MaxPinned.count+=10
  148.       redim sizing_data PinCtl_Rec[MaxPinned.count]
  149.     end if  
  150.     PinCtl_Rec[idx].index=idx
  151.     PinCtl_Rec[idx].hParent=hParent
  152.     PinCtl_Rec[idx].hCtl=hCtl
  153.     PinCtl_Rec[idx].pf1.fx=pf1.fx
  154.     PinCtl_Rec[idx].pf1.fy=pf1.fy
  155.     PinCtl_Rec[idx].pf2.fx=pf2.fx
  156.     PinCtl_Rec[idx].pf2.fy=pf2.fy
  157.     PinCtl_Rec[idx].ofs.left=ofs.left
  158.     PinCtl_Rec[idx].ofs.top=ofs.top
  159.     PinCtl_Rec[idx].ofs.right=ofs.right
  160.     PinCtl_Rec[idx].ofs.bottom=ofs.bottom    
  161. end sub
  162.  
  163. 'Mark control to stop resizing / moving at certain size of window (pixels)
  164. sub unpinCtl(sys hCtl, sys hParent, int width, height)
  165.     int ix
  166.     bool found=false
  167.     for ix=1 to MaxPinned.count
  168.        if PinCtl_Rec[ix].hCtl=hCtl then
  169.          PinCtl_Rec[ix].unpinned=1
  170.          PinCtl_Rec[ix].w=width
  171.          PinCtl_Rec[ix].h=height
  172.          found=true : exit for
  173.        end if  
  174.     next ix
  175.     if found=false then mbox "Error: Cannot find hCtl: " hCtl "in PinCtl_Rec"
  176. end sub
  177.  
  178. 'Procedure for resizing attached controls when WM_SIZE message is handled
  179. sub resizeControls(sys hWin)
  180.     PFactor pf1, pf2
  181.     RECT ofs  
  182.     Sizel ctlSize  
  183.     RECT pRect, cRect   'parent, control
  184.  
  185.     'Get the new size of the window
  186.    GetClientRect(hWin, &pRect)
  187.     ctlSize.cx = pRect.right : ctlSize.cy = pRect.bottom  
  188.  
  189.     int ix
  190.     'Go through each element in the data entries to see if it needs to be moved.
  191.    for ix = 1 to MaxPinned.count
  192.         if PinCtl_Rec[ix].index=0 then exit for
  193.         'If the element was inside the window that was resized, it needs to move.
  194.        if hWin = PinCtl_Rec[ix].hParent then
  195.             'Get the data out of the data entries for that record
  196.            pf1.fx=PinCtl_Rec[ix].pf1.fx : pf1.fy=PinCtl_Rec[ix].pf1.fy : pf2.fx=PinCtl_Rec[ix].pf2.fx : pf2.fy=PinCtl_Rec[ix].pf2.fy            
  197.             ofs.left=PinCtl_Rec[ix].ofs.left : ofs.top=PinCtl_Rec[ix].ofs.top : ofs.right=PinCtl_Rec[ix].ofs.right : ofs.bottom=PinCtl_Rec[ix].ofs.bottom            
  198.  
  199.             'Stop resizing / moving if hParent falls below a certain size (pixels)?
  200.            if PinCtl_Rec[ix].unpinned=1 then
  201.               if ctlSize.cx < PinCtl_Rec[ix].w then ctlSize.cx=PinCtl_Rec[ix].w
  202.               if ctlSize.cy < PinCtl_Rec[ix].h then ctlSize.cy=PinCtl_Rec[ix].h                            
  203.             end if
  204.  
  205.             'Calculate the new position and size of the control
  206.            ofs.left+=ctlSize.cx*pf1.fx : ofs.top+=ctlSize.cy*pf1.fy : ofs.right+=ctlSize.cx*pf2.fx : ofs.bottom+=ctlSize.cy*pf2.fy
  207.             SetWindowPos(PinCtl_Rec[ix].hCtl, 0, ofs.left, ofs.top, (ofs.right-ofs.left), (ofs.bottom-ofs.top), SWP_NOZORDER|SWP_DEFERERASE)                                                    
  208.         end if
  209.     next ix
  210. end sub
  211.  
  212. 'Can be combined with WM_GETMINMAXINFO message
  213. macro setMinSize(xMin, yMin)
  214.    MINMAXINFO *mm
  215.    @mm = lParam
  216.  
  217.    mm.ptMinTrackSize.x = xMin
  218.    mm.ptMinTrackSize.y = yMin
  219. end macro
  220.  
  221. =============================================================================
  222. 'Adapt offsets of an existing control, using the given factors
  223. 'Optional add delta to position
  224. sub modpinCtl(sys hCtl, optional int dx=0,dy=0,dcx=0,dcy=0)
  225.     Sizel ctlSize  
  226.     RECT pRect, cRect   'parent, control
  227.    RECT ofs
  228.    
  229.     int i
  230.     for i=1 to MaxPinned.count
  231.       if PinCtl_Rec[i].hCtl=hCtl then
  232.         exit for
  233.       end if
  234.     next i
  235.     if PinCtl_Rec[i].hCtl != hCtl then exit sub              
  236.  
  237.     'Get the size of the hParent window to be able to calculate offsets
  238.    GetClientRect(PinCtl_Rec[i].hParent, &pRect)
  239.     ctlSize.cx = pRect.right : ctlSize.cy = pRect.bottom
  240.     GetWindowRect(hCtl, &cRect)
  241.  
  242.     'Calculate the offsets of the left, top, bottom, and right of the control.
  243.    MapWindowPoints(HWND_DESKTOP, GetParent(hCtl),  &cRect, 2)
  244.     ofs.left=  cRect.left   + dx  - ctlSize.cx*PinCtl_Rec[i].pf1.fx
  245.     ofs.top=   cRect.top    + dy  - ctlSize.cy*PinCtl_Rec[i].pf1.fy
  246.     ofs.right= cRect.right  + dcx - ctlSize.cx*PinCtl_Rec[i].pf2.fx
  247.     ofs.bottom=cRect.bottom + dcy - ctlSize.cy*PinCtl_Rec[i].pf2.fy
  248.  
  249.     PinCtl_Rec[i].ofs.left=ofs.left
  250.     PinCtl_Rec[i].ofs.top=ofs.top
  251.     PinCtl_Rec[i].ofs.right=ofs.right
  252.     PinCtl_Rec[i].ofs.bottom=ofs.bottom    
  253. end sub
  254.  
« Last Edit: April 10, 2019, 04:26:33 AM by Arnold »

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #1 on: February 27, 2019, 08:13:20 AM »
The autosizing routines use a simple but effective system. After creating the layout of a Window with the controls in the desired positions, the controls are pinned / attached using either predefined factors ("TL","TM","TB" etc) or own factors e.g. "0.0, 0.33" etc for the relative offsets.

For stopping the resizing of the controls at a certain size of the parent window (in pixels) the sub unpinCtl can be used. To stop resizing at all at a certain size of the window, the macro setMinSize can be helpful. The macro must be used in case of the WM_GETMINMAXINFO message.

Resizing happens in case of WM_SIZE using the routine resizeControls(ParentWindow).

If I have done everything right, the routines should save a lot of complex calculations and create apps with an appealing look.


jack

  • Full Member
  • ***
  • Posts: 120
Re: Autosizing reworked
« Reply #2 on: February 28, 2019, 02:34:44 AM »
thank you Arnold :)

John

  • Hero Member
  • *****
  • Posts: 3599
Re: Autosizing reworked
« Reply #3 on: February 28, 2019, 11:32:05 AM »
Arnold,

I'm spoiled with UltraEdit's ability to split edit widows, drag tabs to create new windows and more. I would like to see this working in IUP.

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #4 on: March 01, 2019, 07:03:22 AM »
Maybe I should mention that I do not yet consider the autosizing project complete. There are still the items Menu, Toolbar and Statusbar, which need to be examined more closely. But I am working on this topic.



Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4096
    • Oxygen Basic
Re: Autosizing reworked
« Reply #5 on: March 03, 2019, 02:21:50 AM »
Thanks, Roland.

I'll include Autosizing in examples/WinGui, replacing the previous Autosizer.

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #6 on: March 08, 2019, 06:57:04 AM »
Hi Charles,

I am trying this too: adding a splitting mechanism without creating a custom splitter control. I used Demo2.o2bas for experimenting. Moving the mouse to the gap between the two edit controls will change the shape of the cursor. Pressing the left mouse button down and moving it to left or right will change the dimensions of the edit controls after releasing the mouse. It is only a simple mechanism, the main thing happens in case of WM_MOUSEMOVE, WM_LBUTTONDOWN and WM_LBUTTONUP. Perhaps there is a better or nicer way to achieve the results. Splitterbars usually are shown visually but I did not apply this effect.

I am curious if splitting can be implemented in autosizing.inc in some way. This would be interesting if some more controls are involved. But first I have to do some experiments with horizontal splitting.

Roland

Edit:
There were some small bugs in the app. I replaced the code with the modifications.

Demo2V.o2bas:
Code: OxygenBasic
  1. $ filename "Demo2V.exe"
  2.  
  3. 'uses rtl32
  4. 'uses rtl64
  5.  
  6. uses WinUtil
  7. uses autosizing
  8.  
  9. % SIZE_MAXIMIZED=2
  10. % GCL_HCURSOR= -12
  11. % IDC_SIZENESW=32643
  12. % IDC_SIZEWE=32644
  13.  
  14.  
  15. bool dragMouse = false    'for splitter
  16. bool maydragMouse=false   'for splitter
  17.  
  18. bool fullScreen           'prevent splitter in fullScreen mode
  19.  
  20.  
  21. sys Button_TR, Button_BL, Button_BLBR, Button_BR, MleText_TLBM, MleText_TMBR
  22.  
  23. enum  Control_ids
  24.    ID_Button_TR=1001
  25.    ID_Button_BL
  26.    ID_Button_BLBR
  27.    ID_Button_BR
  28.    ID_MleText_TLBM
  29.    ID_MleText_TMBR  
  30. end enum
  31.  
  32. % Btn_Style    = WS_CHILD|WS_VISIBLE|WS_TABSTOP
  33. % Btn_ExtStyle = WS_EX_STATICEDGE
  34. % Mle_Style    = WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE
  35. % Mle_ExtStyle = WS_EX_CLIENTEDGE
  36.  
  37.  
  38. sys hInstance=inst
  39. MainWindow 410,340,WS_OVERLAPPEDWINDOW
  40.  
  41. function createControl(string ctlclass, string Text, sys hwnd, int id, x,y,w,h, int Style, optional ExStyle=0) as sys
  42.     sys hCtrl
  43.     hCtrl=CreateWindowEx(ExStyle, ctlclass, Text, Style, x,y,w,h,  hWnd, id, hInstance, null)
  44.     if hCtrl=null then mbox "Error: Cannot create " ctlclass
  45.     return hCtrl
  46. end function
  47.  
  48. function WndProc(sys hwnd, uint uMsg, sys wParam, lParam) as sys callback
  49.     static RECT rcEL, rcER
  50.     static int horzDiff    'x position
  51.    static short horzPos   'must be short because of negative values
  52.    
  53.     select uMsg
  54.  
  55.         case WM_CREATE
  56.            SetWindowText(hwnd, "Autosize Demo 2 with vertical Splitting")
  57.            Button_TR = CreateControl("Button","TR - Exit",hwnd,ID_Button_TR, 296, 8, 88, 24, Btn_Style, Btn_ExtStyle)
  58.            Button_BL = CreateControl("Button","BL",hwnd,ID_Button_BL, 8, 272, 88, 24, Btn_Style, Btn_ExtStyle)
  59.            Button_BLBR = CreateControl("Button","BLBR",hwnd,ID_Button_BLBR, 152, 272, 88, 24, Btn_Style, Btn_ExtStyle)
  60.            Button_BR = CreateControl("Button","BR",hwnd,ID_Button_BR, 296, 272, 88, 24, Btn_Style, Btn_ExtStyle)
  61.            MleText_TLBM = CreateControl("Edit","Top left attached to top left corner, bottom right attached to bottom middle (TL, BM)",hwnd,ID_MleText_TLBM, 8, 48, 232, 216, Mle_Style, Mle_ExtStyle)
  62.            MleText_TMBR = CreateControl("Edit","Top left attached to top middle, bottom right attached to bottom right corner (TM, BR)",hwnd,ID_MleText_TMBR, 248, 48, 136, 216, Mle_Style, Mle_ExtStyle)
  63.                      
  64.            pinCtl(Button_TR, hwnd, "TR")
  65.            pinCtl(Button_BL, hwnd, "BL")
  66.            pinCtl(Button_BLBR, hwnd, "BL","BR")
  67.            pinCtl(Button_BR, hwnd, "BR")
  68.            pinCtl(MleText_TLBM, hwnd, "TL","BM" )
  69.            pinCtl(MleText_TMBR, hwnd, "TM","BR" )
  70.            
  71.            
  72.         case WM_COMMAND
  73.            if loword(wParam)=ID_Button_TR then SendMessage(hWnd, WM_CLOSE, 0,0)
  74.  
  75.         case WM_GETMINMAXINFO
  76.            setMinSize 360,180
  77.    
  78.         case WM_SIZE
  79.            resizeControls(hwnd)
  80.            if wParam=SIZE_MAXIMIZED then fullScreen=true else fullScreen=false
  81.  
  82.         case WM_MOUSEMOVE                
  83.            horzPos=loword(lParam )
  84.                      
  85.            GetWindowRect(MleText_TLBM,&rcEL)
  86.            MapWindowPoints(HWND_DESKTOP, GetParent(MleText_TLBM),  &rcEL, 2)          
  87.            GetWindowRect(MleText_TMBR,&rcER)
  88.            MapWindowPoints(HWND_DESKTOP, GetParent(MleText_TLBM),  &rcER, 2)
  89.  
  90.            if horzPos>rcEL.right and horzPos<rcER.left and fullScreen=false then
  91.              maydragMouse=true
  92.              SetClassLongPtr(hwnd, GCL_HCURSOR, LoadCursor(null, IDC_SIZENESW))
  93.            else
  94.              maydragMouse=false
  95.              SetClassLongPtr(hwnd, GCL_HCURSOR, LoadCursor(null, IDC_ARROW))        
  96.            end if
  97.  
  98.         case WM_LBUTTONDOWN
  99.            if maydragMouse then
  100.              SetCapture(hWnd)
  101.              dragMouse = true
  102.            end if  
  103.  
  104.         case WM_LBUTTONUP        
  105.            if dragMouse then            
  106.              ReleaseCapture()
  107.              dragMouse = false
  108.              maydragMouse=false
  109.              
  110.              if horzPos < (rcER.left-rcEL.right) then
  111.                 horzPos=rcER.left-rcEL.right            
  112.              elseif horzPos > rcER.right then
  113.                 horzPos=rcER.right-8
  114.              end if  
  115.              horzDiff=horzPos-rcEL.right  
  116.  
  117.              SetWindowPos(MleText_TLBM, 0, rcEL.left, rcEL.top, (rcEL.right +horzDiff -rcEL.left), (rcEL.bottom-rcEL.top), SWP_NOZORDER|SWP_DEFERERASE)
  118.              SetWindowPos(MleText_TMBR, 0, (rcER.left +horzDiff), rcER.top, (rcER.right-rcER.left -horzDiff), (rcER.bottom-rcER.top), SWP_NOZORDER|SWP_DEFERERASE)    
  119.  
  120.              'Attach controls to new position
  121.             pinCtl(MleText_TLBM, hwnd, "TL", "BM" )
  122.              pinCtl(MleText_TMBR, hwnd, "TM","BR" )
  123.  
  124.            end if
  125.                
  126.         case WM_CLOSE
  127.            DestroyWindow(hwnd)
  128.  
  129.         case WM_DESTROY
  130.            PostQuitMessage(0)
  131.  
  132.         case else
  133.            return DefWindowProc(hwnd, uMsg, wParam, lParam)
  134.            
  135.     end select
  136.  
  137.     return 0
  138. end function
  139.  
« Last Edit: March 12, 2019, 05:59:04 AM by Arnold »

John

  • Hero Member
  • *****
  • Posts: 3599
Re: Autosizing reworked
« Reply #7 on: March 08, 2019, 08:00:18 PM »
Here is a goal to shoot for.

Ultra Edit Split Drag Window Clip

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #8 on: March 09, 2019, 02:30:45 AM »
Hi John,

it seems that Ultra Edit applies Scintilla and that this is resizing of MLEs in a MDI app. This is not the goal of the autosizing project. I want to use Oxygenbasic with WinApi functions to size / move different controls.

Roland

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #9 on: March 09, 2019, 02:35:14 AM »
This morning I had the enlightenment that I must be careful if I use pinCtl repeatedly. But this would be only a small modification in autosizing.inc:

Code: [Select]
...
    'Add entry to the data records
    static int idx
    'does hCtl already exist?
    int i
    for i=1 to idx
      if PinCtl_Rec[i].hCtl=hCtl then
        idx=i-1
        exit for
      end if
    next i               
    idx+=1
...

I modified autosizing.inc in my first message. (not yet in the attached zip file)

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #10 on: March 12, 2019, 06:01:54 AM »
Perhaps the demo above is not the best example, but it is good for learning. It seems to me that I do not split controls, but anchor, link, connect, merge, join, combine them or something like this. What would be an appropriate term for this operation? Sometimes I regret my lack of English language skills.

Reading the documention of MSDN I also learned that I need the type short to determine the coordinates in WM_MOUSEMOVE. I also noticed that using autosizing and splitting in FullScreen mode can be very problematic, so in FullScreen mode I disabled splitting. I also changed the cursor to IDC_SIZENESW in order to prevent confusion with IDC_SIZEWE. These are all such small details that are not obvious at first glance.

I modified the code of the example in reply #6.

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #11 on: March 19, 2019, 01:34:50 PM »
Hi Charles,

although I have created some procedures for connecting / anchoring controls, I have given up on this intent for the moment. There should be a better strategy than mine. And since it is possible to apply the WS_THICKFRAME (WS_SIZEBOX) style with controls, there is a simple and flexible way to resize controls anyway.

Probably autosizing.inc can be helpful in some cases. I added two small changes to the include file: in sub pinCtl I added a check for an already existing entry of a control. This can be useful, if the placement factors should be changed at some time. I also added the function modpinCtl, which only changes the offsets and keeps the placement factors. This can be applied e.g. in case of WM_SIZING or WM_GETMINMAXINFO. The different behaviour can be tested in demo2.o2bas and demo8.o2bas.

Demo7Dlg.o2bas is a more extended test of autosizing, I wanted to see the interaction of Menu, Toolbar and Statusbar. This works better than I expected, so I am confident that the approach is applicable.

I replaced autosizing.inc and the attached .zip file in my first post.

Roland
« Last Edit: April 10, 2019, 10:36:21 PM by Arnold »

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #12 on: April 10, 2019, 04:31:58 AM »
Hello,

this is a small app which I created for a final test of autosizing inc. These are the additional features:

Hide / show Toolbar / Statusbar
Add images to Toolbar / Menu which can be enabled / disabled
Tooltips for Toolbar
Accelerators
Autosizing
Open the HelpFile of Oxygenbasic (recommended)
Splitterbar for horizontal moving Listbox / Editbox. It will get visible when the mouse is positioned between Listbox and Edit control and the Left Mouse Button is pressed down.

The program can be run in 32-bit and 64-bit mode. It depends on some resources of Oxygen so the path must perhaps be adapted at the beginning:

Code: [Select]
$ filename "SmallApp.exe"

'uses rtl32
'uses rtl64

'Get path of Oxygenbasic
string o2dir = "d:\oxygenbasic\"
...
...

To achieve the functionality of SmallApp.o2bas I had to add a small modification for function modpinCtl to add optional intervals to the offsets. To realize a splitter I used a label with state SW_HIDE / SW_SHOW. The code could be modified for a vertical splitter, but perhaps it could be improved a bit before doing this?

I added the small modification of autosizing.inc in my first message of this thread and also attached a modified autosizing.zip file with the five demos which I like most. The code for Smallapp.o2bas is included there too.

Roland
« Last Edit: April 16, 2019, 09:36:42 AM by Arnold »

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4096
    • Oxygen Basic
Re: Autosizing reworked
« Reply #13 on: April 16, 2019, 02:25:19 AM »
Thanks, Roland.

I will include this update.

Small mod: relative path:

Code: [Select]
'Get path of Oxygenbasic
string o2dir = "..\..\..\"

Arnold

  • Hero Member
  • *****
  • Posts: 825
Re: Autosizing reworked
« Reply #14 on: April 17, 2019, 07:28:42 AM »
Hi Charles,

it is an honor for me. Autosizing.inc should be relatively complete now and universally applicable. Maybe some small adjustments are still needed. The idea for using placement factors I found in a small library written in Euphoria (autosize.ew by Patrick Barnes), but the implementation is quite different and the Oxygenbasic functions will work in Win64 too.

One of my future goals will be to apply a more general way to handle splitterbar functionality, perhaps realized as a custom control. Combined with autosizing this could result in very flexible design of the layouts.

Roland