Rebar Control, Problem & FIX and dress-up

new topic     » topic index » view thread      » older message » newer message

Hi Derek,

I have found a serious bug in win32lib control - Rebar. It affects all 
the routines
associated to the control, luckily very few people around use rebars. 
Matt Choose
the wrong path having to use the lParam to store the ids of the Bands in 
the 
REBARBANDINFO structure.

Reasons why:
1) Most or all of the band messages are flucky or return wrong results
  cause they require zero - based indeces of the bands and RB_IDTOINDEX
  always fails cause it relies on wID member of the REBARBANDINFO 
structure

2) The bands are unuable to support custom draw since they need wID not 
lParam

3) He has to do dirty look-ups in  AddToBand to find correct bands 
instead of
   simply using RB_IDTOINDEX

4)its a bit more compatible, as you don't fall under this restrictive if 
directive
#if (_WIN32_IE >= 0x0400) where the lParam lies

Here is the full make-up/full fix to all rebar - related routines. 
Unless the lParam
is explicitly needed in other routines associated with band, omit it and 
use wID,
i have tested wID and it works!

FIX (1)
=======
Needed constant for fMask member
constant RBBIM_ID            = #00000100

Fix for the createEX

You no longer need lParam, wID is needed. so use RBBIM_ID instead of 
RBBIM_LPARAM for fMask member and fill wID instead of lParam member.
 
 struct = struct_REBARBANDINFO(
        or_all( {RBBIM_ID,        -- changed
	        RBBIM_SIZE,
	        RBBIM_TEXT,
	        RBBIM_STYLE } ),
        or_all( {   RBBS_CHILDEDGE,
	        RBBS_GRIPPERALWAYS,
	        styleFlags }),
        0,
        0,
        caption,
        0,
        0,
        0,
        0,
        cx,
        0,
        id,                       --changed: wID member now holds the id
        0,
        0,
        0,
        0,
        0,                       --changed: lParam nolonger needed wID 
does its work
        0 )

FIX (2)
=======
Needed constant for this fix
constant RB_IDTOINDEX        = (WM_USER +  16)

In this fix, i remove the tideous look-ups using lParam, and produce 
cleaner code.
All uncommented code is by Matt. i have left it there to just show you 
'work made simple', plus i deleted unneeded declarations in the Proc.

global procedure addToBand( integer id, integer band )
    atom rb,
-- Jordah:
   bandIndex
-- End
    sequence size
    
    size = getCtlSize( id )
    bandIndex = sendMessage(window_owner[band],RB_IDTOINDEX,band,0)
 --   
 --   numbands = sendMessage( window_owner[band], RB_GETBANDCOUNT, 0, 0 
)
 --   
      rb = acquire_mem(0,  SIZEOF_REBARBANDINFO )

 --  store( rb, REBARBANDINFO_fMask, RBBIM_LPARAM )
 --   for i = 0 to numbands - 1 do
 --   VOID = sendMessage( window_owner[band], RB_GETBANDINFO, i, rb )
 --   info = fetch( rb, REBARBANDINFO_lParam )
 --   if info = band then
 --       numbands = i
 --       exit
 --   end if
 --   end for
    
    store( rb, REBARBANDINFO_hwndChild, window_handle[ id ] )
    store( rb, REBARBANDINFO_lpText, getText( id ) )-- This is needed 
but won't work 						    --until its Mask is specified.Below is a fix
	
    store( rb, REBARBANDINFO_cx, size[1] )
    store( rb, REBARBANDINFO_cyMinChild, size[2] )
    store( rb, REBARBANDINFO_fMask,
        or_all( {   RBBIM_CHILD,
	        RBBIM_CHILDSIZE,RBBIM_TEXT} ))              -- Added Mask for 
band text
    store( rb, REBARBANDINFO_cbSize, SIZEOF_REBARBANDINFO )
--    store( rb, REBARBANDINFO_hwndChild, window_handle[ id ] )-- You 
already filled 							       -- this.
    
    VOID = sendMessage( window_owner[band], RB_SETBANDINFO,bandIndex, rb 
)-- Changed
    
    release_mem( rb )
    
end procedure

Fix (3)
=======

Another historical fact of win32lib, "Some functions are denied their 
use"
Why is it that in addToBand, the REBARBANDINFO structure had to be 
filled from
scratch? Why deny struct_REBARBANDINFO() its use?

Suggestion
==========

Derek, i was just wondering is their a handler already in win32lib to 
simulate
RBN_HEIGHTCHANGE for rebars. if not please add it so that incase rebar 
bands
move and the Rebar resizes so could the clientarea of the window, just 
like 
you did 4 the status bar and Toolbar. The notification is desparately 
needed if
you have multiple resizable-Rebars bands.

It is very eazy to implement, though i'm not sure how i would elegantly 
place it in win32lib.
in API, i simply call GETRECT() for the rebar-size then i adjust 
pointers holding
the clientarea size. Then i invalidateRect() of the affected window.

Other
=====
Well, That is all for now on rebar controls. 
Actually Derek, The Rebar Control needs more routines to bring the best 
out of it.
Just cause many people don't use it, it doesn't mean that id should be 
ignored and
care about other controls. And to all win32lib users, start using this 
control to
improve your GUI(Trust me the GUI looks good esp if Multiple bands are 
used)

I'm currently looking up functions that are/or will be essential when 
users use rebars
in their programs. And seeing how i can add them to existing code.



Jordah Ferguson.

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu