델파이/Components

TlistBox, TComboBox, TCheckBox, ToutLine, TTreeView

지병철 2012. 2. 13. 15:39


TlistBox, TComboBox, TCheckBox, ToutLine, TTreeView  델파이 팁_강좌

2007/03/05 22:06

복사http://blog.naver.com/janginco/35121379

 

■ TlistBox, TComboBox, TCheckBox, ToutLine, TTreeView

● 여러개의 CheckBox가 동일한 Event Handler를 사용할 때 각각의 Checkbox에 대해 별개의 작업을 하게 하려면?

 TGroupBox 내에 여러 개의 Checkbox를 위치시킨다. 설계 또는 실행시에 Checkbox의 Click Event Handler를 동일하게 지정한 후에 그 Event Handler에서는 다음과 같이 프로그램하면 된다.


 for I := 0 to GroupBox1.ControlCount -1 do

    if (GroupBox1.Controls[i] as TCheckBox).checked then

      begin

        if (GroupBox1.Controls[i] as TComponent).name = 'CheckBox1' then

             {do something}

        else if (GroupBox1.Comtrols[i] as TComponent).name = 'CheckBox2' then

               {do something}

        end;


●실행시에 ComboBox 컴포넌트가 초기값을 갖도록 하려면?

 ComboBox의 Items에 여러 항목을 추가한 후에 실행 중에 ComboBox1.ItemIndex를 원하는 Index 번호로 지정하면 된다.


●콤보박스가 드롭다운되기 전에 드롭다운되었을 때의 크기를 알 수 있는 방법은?

 FormShow 이벤트에서 콤보박스로 CB_SHOWDROPDOWN  메시지를 두 번 보낸다. 이렇게 하면 첫 번째 메시지에서 콤보박스가 드롭다운되고 두 번째 메시지에서 콤보박스가 원상태가 된다. 그리고 CB_GETDROPREDCONTROLRECT 메시지를 TRect의 주소와 함게 보내면 TRect가 반환되면서 콤보박스가 드롭다운되었을 때의 크기가 갖게 된다. 이제 ScreenToClient 메소드를 호출하여 폼의 클라이언트 영역에 대응시킬 수 있다.


var

 R : TRect;


procedure TForm1.FormShow(Sender : TObject);

var

 T : TPoint;

begin

 SendMessage(ComboBox1.Handle,CB_SHOWDROPDOWN, 1, 0);

 SendMessage(ComboBox1.Handle,CB_SHOWDROPDOWN, 0, 0);

 SendMessage(ComboBox1.Handle,CB_GETDROPPEDCONTROLRECT, 0, Longint(@r));

 t := ScreenToClient(Point(r.Left, r.Top));

 r.Left := t.x;

 r.Top := t.y;

 t := ScreenToClient(Point(r.Right , r.Bottom));

 r.Right := t.x;

 r.Bottom := t.y;

end;


procedure TForm1.Button1Click(Sender : TObject);

begin

  Form1.Canvas.Rectangle(r.Left, r.Top, r.Right, r.Bottom);

end;


●Add 메소드를 사용하여 ListBox에 새로운 아이템을 추가할 때, Item 이 화면에 보이는 것보다 더 많이 있다면 추가된 아이켐은 보이지 않는다. Add와 동시에 추가된 항목을 보려면?

 다음과 같이 설정하면 된다.


 ListBoxName.Item.ADD('XXX');

 ListBoxName.ItemIndex := ListBoxName.Items.Count - 1


●ListBox에서 오른쪽으로 문자를 정렬하려면?

 Property로 제공되는 것은 없다. 스트링의 앞쪽으로 공백을 채우는 형태로 사용할 수 있다.


●TListBox에서 항상 마지막에 입력한 값에 포커스를 주려면?

 새로운 아이템을 추가하는 부분에 다음과 같이 ItemIndex 값을 지정해 주면 된다.


ListBox1.Items.Add(Edit1.Text);

ListBox1.ItemIndex := ListBox1.Items.Count-1;


●TListBox 컨트롤에 사용자 정의 탭 간격을 설정하는 방법은?

 ListBox로 LB_SETTABSTOPS 메시지를 보내서 처리할 수 있다.


※참고

  ListBox tabwidth 속성은 작업할 LB_SETTABSTOPS 메시지를 위해 0 값이 아닌 다른 수로 설정되어야 한다.


procedure TForm1.FormCreate(Sender : TObject);

begin

 ListBox1.TabWidth := 1;

 ListBox1.Items.Add('one'+#9+'one');

 ListBox1.Items.Add('two'+#9+'two');

 ListBox1.Items.Add('three'+#9+'three');

end;


procedure TForm1.Button1Click(Sender : TObject);

var

 DialogUnitsX : Longint;

 PixelsX : Longint;

 i : integer;

 TabArray : array[0..4] of integer;

begin

 DialigUnitsX := LoWord(GetDialogBaseUnits);

 PixelsX := SpinEdit1.Value;

 for I := 1 to 5 do begin

    TabArray[i - 1] := ((PixelsX * I) * 4) div DialogUnitsX;

 end;

 if SendMessage(ListBox1.Handle, LB_SETTABSTOPS, 5, Longint(@TabArray)) = 0  

    then ShowMessage('Tabs Not Set');

 ListBox1.Refresh;

end;


●Multi-Column Listbox를 만드는 방법은?


일반적으로 Listbox에는 하나의 Column에 대한 Data를 나타낼 수 있다. 그러나 ListBox의 Cancas Property 와 onDrawItem Event를 이용하여 여러 Column으로 Data를 보이게 할 수 있다. onDrawItem Event procedure에 구현된 대로 Data가 Display 되도록 하기 위해서는 Listbox의 Style Property를 lbOwnerDrawFiexed 나 lbOwnerDrawVariable로 설정해야 한다.

 Listbox의 각 Column의 기본 너비를 결정하기 위해 Header Component의 각 SectionWidth 값을 Form의 onCreate Event에 정의한다.


procedure TForm1.FormCreate(Sender : TObject);

begin

 Header1.SectionWidth[0] := 80;

 Header1.SectionWidth[1] := 100;

 Header1.SectionWidth[2] := 100;

end;


다음과 같은 방법으로 Listbox에 Data를 입력한다. Column은 3개이며 각 Column의 구별자는 #9(VK_TAB)를 이용한다.


ListBox1.Items.Add('1000'+#9+'홍길동‘+#9+’연구소‘);


ListBox의 onDrawItem Event에서는 주어진 Header Component의 SectionWidth만큼 rect를 구하여 #9 구분자를 이용하여 Data를 Parsing한 다음, Listbox Canvas에 해당 Data를 Display한다.


procedure TForm1.ListBox1DrawItem(Control : TWinControl; Index : integer; Rect : TRect; State : TOwnerDrawstate);

var r1,r2,r3 : TRect;

    tmp : string;

    ind : byte;

begin

 r1 := Rect;

 r1.Right := Header1.SectionWidth[0];

 r2 := Rect;

 r2.Left := r1.right + 1;

 r2.right := r2.Left + Header1.SectionWidth[1];

 r3 := Rect;

 r3.Left := r2.right + 1;

 tmp := TlistBox(Control).Items[Index];

 with TlistBox(Control).Canvas do begin

      FillRect(Rect);

     ind := Pos(#9, tmp);

     TextRect(r1, r1.left, r1.top, copy(tmp,1, ind-1));

     tmp := copy(tmp, ind+1, length(tmp)-ind+1);

     ind := Pos(#9, tmp);

     TextRect(r2, r2.left, r2.top, copy(tmp, 1, ind-1));

     tmp := Copy(tmp, ind+1, Length(tmp)-ind+1));

     TextRect(r3, r3.left, r3.top, tmp);

  end;

end;


Listbox의 각 Column이 Resizing 될 수 있도록 Header Component를 Resize했을 경우에는 Listbox를 다시 그릴 수 있도록 한다.


procedure TForm1.Header1Sized(Sender : TObject; ASection,AWidth : integer);

begin

 Listbox1.Invalidate;

end;


●Listbox에 Bitmap(또는 Icon)을 Display 하는 방법은?

 이것 역시 Listbox의 Canvas Property와 onDrawItem Event를 이용한다.


Style Property도 역시 lbOwnerDrawFixed 나 lbOwnerDrawVariable로 설정해야 한다. Listbox에 Bitmap 또는 Icon Data를 추가하는 방법은 AddObject 메소드를 이용한다.


ListBox1.Items.AddObject('Bitmap', Image1.Picture.Bitmap);

ListBox1.Items.AddObject('Icon', Image2.Picture);


procedure TForm1.ListBox1DrawItem(Control:TwinControl; Index:intger; Rect: TRect;

                                    State: TOwnerDrawState);

var

 Bitmap : TBitmap;

begin

 with Listbox1.Canvas do begin

      FillRect(Rect);

     Bitmap := TBitmap(Listbox1.Items.Objects[index]);

     BrushCopy(Bounds(Rect.Left + 2,Rect.Top, Bitmap.Width, Bitmap.Height), Bitmap,

                 Bounds(0, 0, Bitmap.Width, Bitmap.Height), clRed);

     TextOut(Rect.Left+50, Rect.Top, Listbox1.Items[Index]);

  end;

end;


procedure TForm1.ListBox2DrawItem(Control:TWinControl; index:Integer; Rect:Trect;

                                    State : TOwnerDrawState);

var

 Pic : TPicture;

begin

  with Listbox2.Canvas do begin

      FillRect(Rect);

      Pic := TPicture(Listbox2.Items.objects[index]);

      Draw(Rect.left, Rect.Top, Pic.Graphic);

      TextOut(Rect.Left+50, Rect.Top, Listbox2.Items[Index]);

   end;

end;


●Listbox에서 특정 Index의 Font/Background Color를 바꾸려면?

 Canvas Property와 onDrawItem Event를 이용한다.


procedure TForm1.ListBox1DrawItem(Control:TWinControl; Index:integer; Rect:TRect;

                                   State : TOwnerDrawState);

begin

 with TlistBox(Control).Canvas do begin

     if Index = 2 then begin

       Brush.Color := clYellow;

       Font.Color := clBlue;

     end;

     FillRect(Rect);

     TextRect(Rect, Rect.left, Rect.top, Listbox1.Items[Index]);

  end;

end;


●Listbox에서 수평 스크롤바를 표시하려면?

 Listbox의 윈도우를 조작하기 위해 LB_SetHorizontalExtent 메시지를 보낸다.예를 들어 폼의 onCreate에서 메시지를 보낼 수 있다.


procedure TForm1.FormCreate(Sender : TObject);

begin

 SendMessage(Listbox1.Handle, LB_SetHorizonalExtent, 1000, Longint(0));

end;


●Listbox에서 선택한 item의 속성을 변경하려면?

 만약 선택한 item에 대한 글꼴의 색상을 변경하고 싶다면 Listbox의 style 속성을 lbOwnerDrawFixed, lbOwnerDrawVariable로 지정한 후 onDrawItem 이벤트에 다음과 같이 작성하면 된다.


procedure TForm1.Listbox1DrawItem(Control : TwinControl; Index : Integer;

                                  Rect: Trect ; State: TOwnerDrawState);

begin

 with ListBox1.Canvas do

  begin

   if (odselected in state) then

     font.color := ClRed;

   textrect(Rect, Rect.left, Rect,Top,  Listbox1.items[index]);

  end;//with

 end;

end;


●TListBox에서 수평 스크롤바를 추가하려면?

 델파이의 TListBox는 아이템의 개수가 늘어날 경우 자동적으로 수직 스크롤바를 생성해 준다.그러나 한 아이템의 길이가 길다고 하더라도 자동으로 수평 스크롤바를 생성해 주지는 않는다.따라서 한 아이템의 길이가 긴 경우 수평 스크롤바를 보이게 하기 위해서는 다음과 같이 해야 한다.


procedure TForm1.FormCreate(Sender : TObject);

var

 i,MaxWidth : integer;

begin

 MaxWidth := 0;

 for I = 0 to ListBox1.Items.Count-1 do

  if MaxWidth < ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i]) then

    MaxWidth := ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i]);

 SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, MaxWidth+2, 0);

end;


●TOutLine에서 선택한 노드의 parent 이름 가져 오려면?

 사용자가 선택한 노드는 outline1.SelectedItem 이라는 속성을 이용해서 가져 오고 Parent 노드는 Parent라는 속성을 이용하면 된다. 따라서 다음과 같이 해서 얻어올 수 있다.


procedure TForm1.Button5Click(Sender : TObject);

var

 cnode : TOutlineNode;

begin

 cnode := Outline1.Items[Outline1.SelectedItem].parent;

 edit2.text := cnode.text;

end;


●TTreeView에서 선택된 아이템이 child를 가지고 있는지 알려면?

 선택된 아이템에 대한 정보는 selected라는 속성을 가지고 있다. 따라서 선택된 아이템이 child를 가지고 있는지 알기 위해서는 다음과 같이 하면 된다.


TreeView1.selected.hasChildren


●TTreeView에서 선택된 아이템의 인덱스를 얻는 방법은?

 사용자가 선택한 아이템과 인덱스를 얻기 위해서는 먼저 Selected라는 속성을 참조 해야 한다. 그 이유는 모든 선택된 아이템에 대한 정보를 담고 있기 때문이다. 따라서 다음과 같이 얻어올 수 있다.


//선택된 아이템

TreeView1.Selected.text;

//선택된 아이템 인덱스

TreeView1.Selected.Index;


●TTreeView에서 Item.Text 값으로 위치를 아는 방법은?

 CurItem이라는 속성을 이용하면 된다.사용 방법은 다음의 예제를 참조하기 바란다.


procedure TForm1.Button1Click(Sender : TObject);

var

 CurItem : TTreeNode;

begin

 CurItem := TreeView1.Items.GetFirstNode;

 while CurItem <> nil do

   begin

    if CurItem.Text = Edit1.text then break;

    CurItem := CurItem.GetNext;

   end;

 TreeView1.Selected := CurItem;

 TreeView1.Setfocus;

 TreeView1.Items.Addchild(TreeView1.Selected, 'Child'); //선택된 Item의 sub Item 추가

end;


'델파이 > Components' 카테고리의 다른 글

델파이 컴포너트 만들기  (0) 2012.02.14
new component 에 ListBox 와 EditBox 두개 Control 넣기  (0) 2012.02.06
Component 에 TStringList 넣기  (0) 2012.02.06
델파이 TComboBox 오른쪽 정렬  (0) 2011.11.19
QuickReport  (0) 2007.03.21