안녕하세요
리스트 뷰에 버튼을 추가하려고 알아보던 중에 델파이로 작성된 코드가 있어서
C++builder 버전으로 컨버팅 해서 만들어봤습니다.
여기에는 자세한 내용을 찾기 힘들어서 올려봅니다.
본 코드는 XE8버전에서 작성되었습니다.
우선 델파이 코드에 출처는 :
http://gomsun2.tistory.com/entry/TListView%EC%97%90-TButton-%EB%84%A3%EA%B8%B0 입니다
간단한 예제는 아래와 같습니다.
실력이 미천하여 변경하는데 조금 어려웠네요..
혹시 잘못된 점 지적 좀 해주시면 감사하겠습니다.
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;
type
TForm2 = class(TForm)
ButtonAdd: TButton;
ButtonDelete: TButton;
ListView: TListView;
procedure ButtonAddClick(Sender: TObject);
procedure ButtonDeleteClick(Sender: TObject);
procedure ListViewCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
private
procedure do_MoveListViewControls(IdxOfDeleted: Integer);
procedure on_ButtonClick(Sender: TObject);
procedure do_ControlsAddListView(ListView: TListView; ListItem: TListItem;
Control: TControl; ColumnIndex: Integer);
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
const
ColumOfButton = 1;
{$R *.dfm}
procedure TForm2.do_ControlsAddListView(ListView: TListView;
ListItem: TListItem; Control: TControl; ColumnIndex: Integer);
var
Rect: TRect;
begin
ListItem.Data := Control;
Rect := ListItem.DisplayRect(drBounds);
Rect.Left := Rect.Left + ListView.Columns[ColumnIndex - 1].Width;
Rect.Right := Rect.Left + ListView.Columns[ColumnIndex].Width;
Control.BoundsRect := Rect;
end;
procedure TForm2.ButtonAddClick(Sender: TObject);
var
ListItem: TListItem;
Button: TButton;
begin
ListItem := ListView.Items.Add;
ListItem.Caption := Format('%d Button', [ListView.Items.Count]);
Button := TButton.Create(Self);
Button.OnClick := on_ButtonClick;
Button.Caption := IntToStr(ListView.Items.Count);
Button.Parent := ListView;
do_ControlsAddListView(ListView, ListItem, Button, ColumOfButton);
end;
procedure TForm2.do_MoveListViewControls(IdxOfDeleted: Integer);
var
Control: TControl;
i: Integer;
begin
// Todo: 삭제 리스트의 개방형 배열을 만들어 루프 말고 한번에 처리하게
for i := IdxOfDeleted to ListView.Items.Count - 1 do
begin
Control := TControl(ListView.Items.Item[i].Data);
Control.Top := Control.Top - (Control.BoundsRect.Bottom - Control.BoundsRect.Top);
end;
end;
procedure TForm2.ButtonDeleteClick(Sender: TObject);
var
i: Integer;
begin
if ListView.Selected = nil then Exit;
ListView.Items.BeginUpdate;
try
for i := ListView.Items.Count - 1 downto 0 do
begin
if not ListView.Items[i].Selected then Continue;
TControl(ListView.Items[i].Data).Free;
ListView.Items[i].Delete;
do_MoveListViewControls(i);
end;
finally
ListView.Items.EndUpdate;
end;
end;
procedure TForm2.on_ButtonClick(Sender: TObject);
begin
Caption := Format('%s Button OnClickEvent :)', [TButton(Sender).Caption]);
end;
procedure TForm2.ListViewCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
var
Control: TControl;
Rect: TRect;
begin
Control := TControl(Item.Data);
Rect := Item.DisplayRect(drBounds);
Rect.Left := Rect.Left + ListView.Columns[ColumOfButton - 1].Width;
Rect.Right := Rect.Left + ListView.Columns[ColumOfButton].Width;
Control.BoundsRect := Rect;
end;
end.
// ---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit2.h"
// ---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
const ColumOfButton = 1;
__fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner) {
}
// ---------------------------------------------------------------------------
void __fastcall TForm2::ButtonAddClick(TObject *Sender) {
TListItem *ListItem;
TButton *Button;
ListItem = ListView->Items->Add();
ListItem->Caption = Format("%d Button", ARRAYOFCONST((ListView->Items->Count)));
Button = new TButton(this);
Button->OnClick = ButtonONClick;
Button->Caption = IntToStr(ListView->Items->Count);
Button->Parent = ListView;
do_ControlsAddListView(ListView, ListItem, Button, ColumOfButton);
}
void __fastcall TForm2::ButtonONClick(TObject *Sender) {
TButton* btn = dynamic_cast(Sender);
Caption = Format("%s Button OnClickEvent :)", ARRAYOFCONST((btn->Caption)));
}
void __fastcall TForm2::do_ControlsAddListView(TListView *ListView, TListItem *ListItem, TControl *Control, int ColumnIndex) {
TRect Rect;
ListItem->Data = Control;
Rect = ListItem->DisplayRect(drBounds);
Rect.Left = Rect.Left + ListView->Column[ColumnIndex - 1]->Width;
Rect.Right = Rect.Left + ListView->Column[ColumnIndex]->Width;
Control->BoundsRect = Rect;
}
void __fastcall TForm2::ListViewCustomDrawSubItem(TCustomListView *Sender, TListItem *Item, int SubItem, TCustomDrawState State, bool &DefaultDraw) {
TRect R;
TControl *Control;
Item->Data = Control;
R = Item->DisplayRect(drBounds);
R.Left = R.Left + ListView->Column[ColumOfButton - 1]->Width;
R.Right = R.Left + ListView->Column[ColumOfButton]->Width;
Control->BoundsRect = R;
}
void __fastcall TForm2::do_MoveListViewControls(int IdxOfDeleted) {
// 삭제 리스트의 개방형 배열을 만들어 루프 말고 한번에 처리하게
TControl *Control;
for (int i = IdxOfDeleted; i < ListView->Items->Count; i++) {
Control = (TControl*) ListView->Items->Item[i]->Data;
Control->Top = Control->Top - (Control->BoundsRect.Bottom - Control->BoundsRect.Top);
}
}
void __fastcall TForm2::ButtonDeleteClick(TObject *Sender) {
TControl *Control;
if (ListView->Selected == NULL)
return;
ListView->Items->BeginUpdate();
try {
for (int i = 0; i < ListView->Items->Count; i++) {
if (!ListView->Items->Item[i]->Selected)
continue;
delete(TControl *) ListView->Items->Item[i]->Data;
ListView->Items->Item[i]->Delete();
do_MoveListViewControls(i);
}
}
__finally {
ListView->Items->EndUpdate();
}
}
void __fastcall TForm2::Button1Click(TObject *Sender) {
for (int i = 0; i < ListView->Items->Count; i++) {
if (ListView->Items->Item[i]->Selected) {
ListView->Items->Item[i]->Delete();
}
}
}