Board index » delphi » TCustomListBox, horizontal scroll???

TCustomListBox, horizontal scroll???

G'day all,

        Has anyone out there been able to make some derivative of TCustomListBox
appear with a horizontal scroll bar (presuming of course, that data in the list
box appears off-screen)?  I have attempted to do this using LB_SETHORIZONTAL
EXTENTS, but I believe the window needs to be created with a specific style
(the definition of which eludes me at this point in time).  Is it possible, or
do I need to go higher in the VCL hierarchy, and develop an entire list-box???

Later,
James

--
| jrweb...@socs.uts.edu.au         | MSN != FOI |
| wo...@ftoomsh.progsoc.uts.edu.au |Win95?OS2v3?|
| The {*word*76}Net home-page, for the Oz demo scene |
|   http://ftoomsh.progsoc.uts.edu.au/~woody/   |

 

Re:TCustomListBox, horizontal scroll???


jrweb...@socs.uts.EDU.AU (James Richard Webster) wrote:

Quote
>G'day all,
>    Has anyone out there been able to make some derivative of TCustomListBox
>appear with a horizontal scroll bar (presuming of course, that data in the list
>box appears off-screen)?  I have attempted to do this using LB_SETHORIZONTAL
>EXTENTS, but I believe the window needs to be created with a specific style
>(the definition of which eludes me at this point in time).  Is it possible, or
>do I need to go higher in the VCL hierarchy, and develop an entire list-box???
>Later,
>James
>--
>| jrweb...@socs.uts.edu.au         | MSN != FOI |
>| wo...@ftoomsh.progsoc.uts.edu.au |Win95?OS2v3?|
>| The {*word*76}Net home-page, for the Oz demo scene |
>|   http://ftoomsh.progsoc.uts.edu.au/~woody/   |

If all you need is a horizontal scrollbar - like to see long lines,
you can use a regular TListBox.  Somewhere in your code after the list
box is created, send the following message:

SendMessage(MyList.handle,LB_SETHORIZONTALEXTENT,widest,0);

where  widest is a WORD var in pixels. The listbox needs to be created
with WS_HSCROLL attribute which it is in the VCL TListBox.

Re:TCustomListBox, horizontal scroll???


Quote
pshie...@csn.net (Patrick Shields) wrote:
>jrweb...@socs.uts.EDU.AU (James Richard Webster) wrote:
>>G'day all,
>>        Has anyone out there been able to make some derivative of TCustomListBox
>>appear with a horizontal scroll bar (presuming of course, that data in the list
>>box appears off-screen)?  I have attempted to do this using LB_SETHORIZONTAL
>>EXTENTS, but I believe the window needs to be created with a specific style
>>(the definition of which eludes me at this point in time).  Is it possible, or
>>do I need to go higher in the VCL hierarchy, and develop an entire list-box???
>>Later,
>>James
>>--
>>| jrweb...@socs.uts.edu.au         | MSN != FOI |
>>| wo...@ftoomsh.progsoc.uts.edu.au |Win95?OS2v3?|
>>| The {*word*76}Net home-page, for the Oz demo scene |
>>|   http://ftoomsh.progsoc.uts.edu.au/~woody/   |
>If all you need is a horizontal scrollbar - like to see long lines,
>you can use a regular TListBox.  Somewhere in your code after the list
>box is created, send the following message:
>SendMessage(MyList.handle,LB_SETHORIZONTALEXTENT,widest,0);
>where  widest is a WORD var in pixels. The listbox needs to be created
>with WS_HSCROLL attribute which it is in the VCL TListBox.

I have the same question (also posted already here) and am glad you
got a solution. However, I have no idea on how to create the lsitbox
with WS_HSCROLL. Do I need to do all thing on my self. Do you have a
code fragment for doing this stuff.
Thanks.

--
rvd...@ect.nl        
Ruud Th. van der Ham

Re:TCustomListBox, horizontal scroll???


rvd...@ect.nl (Ruud van der Ham) wrote:

Quote
>pshie...@csn.net (Patrick Shields) wrote:
>>jrweb...@socs.uts.EDU.AU (James Richard Webster) wrote:
>>>G'day all,
>>>    Has anyone out there been able to make some derivative of TCustomListBox
>>>appear with a horizontal scroll bar (presuming of course, that data in the list
>>>box appears off-screen)?  I have attempted to do this using LB_SETHORIZONTAL
>>>EXTENTS, but I believe the window needs to be created with a specific style
>>>(the definition of which eludes me at this point in time).  Is it possible, or
>>>do I need to go higher in the VCL hierarchy, and develop an entire list-box???
>>>Later,
>>>James
>>>--
>>>| jrweb...@socs.uts.edu.au         | MSN != FOI |
>>>| wo...@ftoomsh.progsoc.uts.edu.au |Win95?OS2v3?|
>>>| The {*word*76}Net home-page, for the Oz demo scene |
>>>|   http://ftoomsh.progsoc.uts.edu.au/~woody/   |
>>If all you need is a horizontal scrollbar - like to see long lines,
>>you can use a regular TListBox.  Somewhere in your code after the list
>>box is created, send the following message:
>>SendMessage(MyList.handle,LB_SETHORIZONTALEXTENT,widest,0);
>>where  widest is a WORD var in pixels. The listbox needs to be created
>>with WS_HSCROLL attribute which it is in the VCL TListBox.

*** which it is in the VCL TListBox. *** the VCL component "TListBox"
already has this attribute. I include the WS_HSCROLL info. in case you
were creating your own list box window.

Quote
>I have the same question (also posted already here) and am glad you
>got a solution. However, I have no idea on how to create the lsitbox
>with WS_HSCROLL. Do I need to do all thing on my self. Do you have a
>code fragment for doing this stuff.
>Thanks.
>--
>rvd...@ect.nl        
>Ruud Th. van der Ham

If you use a TListBox component in a form, it will be created for you
with the WS_HSCROLL attribute. In the case where I used this, I have a
resizeable form (and FormResize gets called at least once during form
creation) so I included the following code in the FormResize event,
you could call it other places too:

{ Form Template - Source and Destination Choices Lists }
{$D+,L+}
unit Choicesu;

interface

uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Buttons,
  StdCtrls, ExtCtrls, messages  ;

type
  TDualListDlg = class(TForm)
    DstList: TListBox;
    SrcList: TListBox;
    SrcLabel: TLabel;
    DstLabel: TLabel;
    OKBtn: TBitBtn;
    CancelBtn: TBitBtn;
    HelpBtn: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
   [lots of stuff left out]    
  private
    { Private declarations }
    widest:integer;
    [lots of stuff left out]
  public
    { Public declarations }

    procedure SetCols(howmany:integer);
  end;

var
  DualListDlg: TDualListDlg;

implementation

{$R *.DFM}

procedure TDualListDlg.FormCreate(Sender: TObject);

begin

  widest:=0;

end;

procedure TDualListDlg.FormResize(Sender: TObject);
var w:integer;
begin
{set new width}
  w:=dstList.width;
  DstList.width:=width-2;
  w:=(dstList.width-w) div 2;    {half the delta width}
  [snip]
  Okbtn.Left         := Okbtn.Left+w;
  CancelBtn.Left     := CancelBtn.Left+w;
  helpbtn.Left       := helpbtn.Left+w;

  SendMessage(SrcList.handle,LB_SETHORIZONTALEXTENT,widest,0);
  SendMessage(DstList.handle,LB_SETHORIZONTALEXTENT,widest,0);
end;

{gets called after srclist is populated by routine calling this form
and before showModal }
procedure TDualListDlg.SetCols(howmany:integer);
var i,w,x,y:integer;
    ss:string;
begin
  widest:=0;
  [snip]
  for x:=0 to srclist.items.count-1 do begin
     ss:=srclist.items[x];
      if srclist.canvas.textwidth(ss)>widest
        then widest:=srclist.canvas.textwidth(ss);
       [lots of stuff left out]    
   end;
end;

end.

I call this from something like this:

Procedure CallLists;
var DualListDlg:TDualListDlg;

begin
           {should have TRY & EXCEPT}
             DualListDlg:=TDualListDlg.create(nil);
             with DualListDlg do begin
               SrcList.Items.clear;
               for x:= 0 to max-1 do begin
                 SrcList.Items.add(MyTextGetterRoutine);
               end;
             [snip]
             SetCols(7);
             if ShowModal = idok then begin
          [snip]
             end;
           end; {with}
end;

Re:TCustomListBox, horizontal scroll???


rvd...@ect.nl (Ruud van der Ham) writes:

Quote
>pshie...@csn.net (Patrick Shields) wrote:
>>If all you need is a horizontal scrollbar - like to see long lines,
>>you can use a regular TListBox.  Somewhere in your code after the list
>>box is created, send the following message:
>>SendMessage(MyList.handle,LB_SETHORIZONTALEXTENT,widest,0);
>>where  widest is a WORD var in pixels. The listbox needs to be created
>>with WS_HSCROLL attribute which it is in the VCL TListBox.
>I have the same question (also posted already here) and am glad you
>got a solution. However, I have no idea on how to create the lsitbox
>with WS_HSCROLL. Do I need to do all thing on my self. Do you have a
>code fragment for doing this stuff.

Okay.  Well (being the original poster of this message), I had in fact already
tried the SendMessage solution suggested by Patrick, (I saw it in the VB
knowledgebase), but it didn't work!  I tried it again, after his reply, and
this time it did work!  The difference?  My second attempt involved a TListBox,
a TEdit, and TButton on a form.  When the user clicked the button, the event
handler did this (I think :)

        ListBox1.Add(Edit1.Text);
              if ListBox1.Canvas.TextWidth(Edit1.Text)t) > ListBox1.Wid then
              SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, ListBox1.
              Canvas.TextWidth(Edit1.Text);

Now this works (I tried it :), but my original problem was getting a CUSTOM
component (i.e. derived from TCustomListBox) to add a horizontal scroll bar
to itself when one of it's items goes over the width of the list box.  I put
this in the DrawItem method, checking the size of each item as drawing, and
setting the HorizontalExtent as necessary.  Alas, it does not work!  I am
presuming that you cannot send a message to a component from within itself???

Any suggestions :) ???

Later,
James

--
| jrweb...@socs.uts.edu.au         | MSN != FOI |
| wo...@ftoomsh.progsoc.uts.edu.au |Win95?OS2v3?|
| The {*word*76}Net home-page, for the Oz demo scene |
|   http://ftoomsh.progsoc.uts.edu.au/~woody/   |

Re:TCustomListBox, horizontal scroll???


jrweb...@socs.uts.EDU.AU (James Richard Webster) wrote:

Quote
>rvd...@ect.nl (Ruud van der Ham) writes:
>>pshie...@csn.net (Patrick Shields) wrote:
>>>If all you need is a horizontal scrollbar - like to see long lines,
>>>you can use a regular TListBox.  Somewhere in your code after the list
>>>box is created, send the following message:
>>>SendMessage(MyList.handle,LB_SETHORIZONTALEXTENT,widest,0);
>>>where  widest is a WORD var in pixels. The listbox needs to be created
>>>with WS_HSCROLL attribute which it is in the VCL TListBox.
>>I have the same question (also posted already here) and am glad you
>>got a solution. However, I have no idea on how to create the lsitbox
>>with WS_HSCROLL. Do I need to do all thing on my self. Do you have a
>>code fragment for doing this stuff.
>Okay.  Well (being the original poster of this message), I had in fact already
>tried the SendMessage solution suggested by Patrick, (I saw it in the VB
>knowledgebase), but it didn't work!  I tried it again, after his reply, and
>this time it did work!  The difference?  My second attempt involved a TListBox,
>a TEdit, and TButton on a form.  When the user clicked the button, the event
>handler did this (I think :)
>    ListBox1.Add(Edit1.Text);
>          if ListBox1.Canvas.TextWidth(Edit1.Text)t) > ListBox1.Wid then
>          SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, ListBox1.
>          Canvas.TextWidth(Edit1.Text);
>Now this works (I tried it :), but my original problem was getting a CUSTOM
>component (i.e. derived from TCustomListBox) to add a horizontal scroll bar
>to itself when one of it's items goes over the width of the list box.  I put
>this in the DrawItem method, checking the size of each item as drawing, and
>setting the HorizontalExtent as necessary.  Alas, it does not work!  I am
>presuming that you cannot send a message to a component from within itself???

There should be no problem with this:  the internals of these
components (VCL)  use SendMessage to themselves all the time to do
Windows API things. The main thing is that SendMessages(HWND....)
always needs a valid window handle which it doesn't have when it is
first created, but does by the time your drawItem method is called.
Another thing is that you may need to force a window repaint to see
the scroll bar as the SendMessage won't take effect during the
DrawItem method (of course you need to be careful how you set up the
repaint or you may get an endless loop) .

Quote
>Any suggestions :) ???
>Later,
>James
>--
>| jrweb...@socs.uts.edu.au         | MSN != FOI |
>| wo...@ftoomsh.progsoc.uts.edu.au |Win95?OS2v3?|
>| The {*word*76}Net home-page, for the Oz demo scene |
>|   http://ftoomsh.progsoc.uts.edu.au/~woody/   |

The last thing that I can think of is the WS_HSCROLL window style
requirement, the VCL source for TCustomListBox.CreateParams includes
this line:

Style := Style or (WS_HSCROLL or LBS_HASSTRINGS or
      LBS_NOTIFY) or Styles[FStyle] or Sorteds[FSorted] or
      Selects^[FMultiSelect] or IntegralHeights[FIntegralHeight] or
      MultiColumns[FColumns <> 0] or BorderStyles[FBorderStyle];

so you should be alright unless your custom control somehow overrides
this.

Hope this helps.

Other Threads