hush021299
asked on
Thumbnail browser based on TListView: DoubleClick event
I did this component.
Now I want this listview derivat to react on my mouseclicks and give me the possibilitie to
getselected file
select all files
=>
unit ThumbListView;
interface
uses
SysUtils, Classes, Controls, Graphics, jpeg, ComCtrls;
type
TThumbListView = class(TListView)
private
{ Private declarations }
sl:tstringlist;
FSelFile:string;
IL:TImagelist;
procedure LoadAndConvert(B: TBitmap; FileName: string);
procedure ListFiles(F: string);
procedure ListView1DblClick(Sender: TObject);
function getSelFile: String;
procedure setSelFile(const Value: String);
procedure ListView1Change(Sender: TObject; Item: TListItem;
Change: TItemChange);
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ Public declarations }
published
{ Published declarations }
property OnClick;
property OnDblClick;
property SelectedFile:String read getSelFile write setSelFile;
procedure ListThumbItems(Dir:String) ;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Hushpa ge', [TThumbListView]);
end;
{ tlistview1 }
constructor TThumbListView.Create(AOwn er: TComponent);
begin
inherited Create(AOwner);
IL:=TImagelist.create(self );
SL:=TStringlist.create;
LargeImages:=IL;
il.Width:=96;
il.height:=96;
end;
destructor TThumbListView.Destroy;
begin
// sl.free;
//IL.Free;
inherited;
end;
procedure TThumbListView.ListView1Db lClick(Sen der: TObject);
begin
end;
procedure TThumbListView.ListView1Ch ange(Sende r: TObject; Item: TListItem;
Change: TItemChange);
begin inherited;
if SelCount>0 then
FSelFile:=Selected.SubItem s[0];
setSelFile(FSelFile);
end;
procedure TThumbListView.ListFiles(F : string);
var
sr: TSearchRec;
path, fullpath: string;
begin
path :=includetrailingbackslash (f);
fullpath := path + '*.*';
if findfirst(fullpath, faAnyFile, sr) = 0 then
repeat
begin
if (lowercase(extractfileext( path + '\' + sr.Name)) =
'.jpg') or
(lowercase(extractfileext( path + '\' + sr.Name)) =
'.bmp')
then
sl.add(path + sr.Name);
end;
until FindNext(sr) <> 0;
FindClose(sr);
end;
procedure TThumbListView.ListThumbIt ems(Dir: String);
var x: integer; s: string;
b, k: string; BM, TBM: TBitmap; LI: TListitem;
begin
bm := tbitmap.create;
Tbm := tbitmap.create;
sl := TStringlist.create;
Items.BeginUpdate;
try
Clear;
il.Clear;
ListFiles(Dir);
for x := 0 to sl.count - 1 do
begin
k:=sl.strings[x];
if fileexists(k) then
begin
LoadAndConvert(bm, k);
tbm.Width := 96;
tbm.Height := 96;
tbm.Canvas.StretchDraw(rec t(0, 0, tbm.Width, tbm.height), bm);
il.Add(Tbm, nil);
//add to listview
li := items.add;
li.caption:=extractfilenam e(k);
LI.SubItems.Add(k);
LI.ImageIndex := x;
end;
end;
finally
sl.free;
bm.free; tbm.free;
Items.EndUpdate;
end;
end;
procedure TThumbListView.LoadAndConv ert(B: TBitmap; FileName: string);
var ex: string; J: TJPEGImage;
//load file and if jpge then convert to bitmap
begin
ex := uppercase(extractfileext(f ilename));
if ex = '.BMP' then
B.LoadFromFile(filename) else
if ex = '.JPG' then
begin
j := TJpegimage.Create;
try
j.LoadFromFile(filename);
B.Assign(j);
finally
j.Free;
end;
end;
end;
function TThumbListView.getSelFile: String;
begin
result:=FselFile;
end;
procedure TThumbListView.setSelFile( const Value: String);
begin
fSelFile:=Value;
end;
end.
Now I want this listview derivat to react on my mouseclicks and give me the possibilitie to
getselected file
select all files
=>
unit ThumbListView;
interface
uses
SysUtils, Classes, Controls, Graphics, jpeg, ComCtrls;
type
TThumbListView = class(TListView)
private
{ Private declarations }
sl:tstringlist;
FSelFile:string;
IL:TImagelist;
procedure LoadAndConvert(B: TBitmap; FileName: string);
procedure ListFiles(F: string);
procedure ListView1DblClick(Sender: TObject);
function getSelFile: String;
procedure setSelFile(const Value: String);
procedure ListView1Change(Sender: TObject; Item: TListItem;
Change: TItemChange);
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ Public declarations }
published
{ Published declarations }
property OnClick;
property OnDblClick;
property SelectedFile:String read getSelFile write setSelFile;
procedure ListThumbItems(Dir:String)
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Hushpa
end;
{ tlistview1 }
constructor TThumbListView.Create(AOwn
begin
inherited Create(AOwner);
IL:=TImagelist.create(self
SL:=TStringlist.create;
LargeImages:=IL;
il.Width:=96;
il.height:=96;
end;
destructor TThumbListView.Destroy;
begin
// sl.free;
//IL.Free;
inherited;
end;
procedure TThumbListView.ListView1Db
begin
end;
procedure TThumbListView.ListView1Ch
Change: TItemChange);
begin inherited;
if SelCount>0 then
FSelFile:=Selected.SubItem
setSelFile(FSelFile);
end;
procedure TThumbListView.ListFiles(F
var
sr: TSearchRec;
path, fullpath: string;
begin
path :=includetrailingbackslash
fullpath := path + '*.*';
if findfirst(fullpath, faAnyFile, sr) = 0 then
repeat
begin
if (lowercase(extractfileext(
'.jpg') or
(lowercase(extractfileext(
'.bmp')
then
sl.add(path + sr.Name);
end;
until FindNext(sr) <> 0;
FindClose(sr);
end;
procedure TThumbListView.ListThumbIt
var x: integer; s: string;
b, k: string; BM, TBM: TBitmap; LI: TListitem;
begin
bm := tbitmap.create;
Tbm := tbitmap.create;
sl := TStringlist.create;
Items.BeginUpdate;
try
Clear;
il.Clear;
ListFiles(Dir);
for x := 0 to sl.count - 1 do
begin
k:=sl.strings[x];
if fileexists(k) then
begin
LoadAndConvert(bm, k);
tbm.Width := 96;
tbm.Height := 96;
tbm.Canvas.StretchDraw(rec
il.Add(Tbm, nil);
//add to listview
li := items.add;
li.caption:=extractfilenam
LI.SubItems.Add(k);
LI.ImageIndex := x;
end;
end;
finally
sl.free;
bm.free; tbm.free;
Items.EndUpdate;
end;
end;
procedure TThumbListView.LoadAndConv
var ex: string; J: TJPEGImage;
//load file and if jpge then convert to bitmap
begin
ex := uppercase(extractfileext(f
if ex = '.BMP' then
B.LoadFromFile(filename) else
if ex = '.JPG' then
begin
j := TJpegimage.Create;
try
j.LoadFromFile(filename);
B.Assign(j);
finally
j.Free;
end;
end;
end;
function TThumbListView.getSelFile:
begin
result:=FselFile;
end;
procedure TThumbListView.setSelFile(
begin
fSelFile:=Value;
end;
end.
ASKER
The thing is
I put the thumblistview on the form and give him a directory and it shows the images.
Now I want to click on an image and get the loacation of the selected image in the form.
Therefore I store the full path in listitem.subitems[0] and I have a property named selectedFile.
I would think I select ondbclck of the component when on the form and should be able to write
showmessage(thumblist.sele ctedfile);
The problems i have here is related to the events. With the component I have it now I dont get anything back. I get the ondblclick but no processing of the commands there.
I put the thumblistview on the form and give him a directory and it shows the images.
Now I want to click on an image and get the loacation of the selected image in the form.
Therefore I store the full path in listitem.subitems[0] and I have a property named selectedFile.
I would think I select ondbclck of the component when on the form and should be able to write
showmessage(thumblist.sele
The problems i have here is related to the events. With the component I have it now I dont get anything back. I get the ondblclick but no processing of the commands there.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you that works fine. I'll give you the points.
Before please help me to understand better how this component acts.
What does it mean:
if tthumblistview.assigned(th umblistvie w.selected ) ?!
is it the same like if selectedcount=1 then..
When will the getSelFile procedure be called!!!?
In on create? or activate? Sometimes I had a problem when assigning values in oncreate. When usually do I assign those values in a component?
I have not freed up the sl and the IL in destroy. If I do this a failure happens. Why is that so?
and finally
I have deleted the ondblclick property. What does this property do in this code?
Before please help me to understand better how this component acts.
What does it mean:
if tthumblistview.assigned(th
is it the same like if selectedcount=1 then..
When will the getSelFile procedure be called!!!?
In on create? or activate? Sometimes I had a problem when assigning values in oncreate. When usually do I assign those values in a component?
I have not freed up the sl and the IL in destroy. If I do this a failure happens. Why is that so?
and finally
I have deleted the ondblclick property. What does this property do in this code?
Wow, that's a lot of questions to ask ;-)
1. Well, I used Assigned in this case because if you are enabling MultiSelect, then SelectedCount = 1 doesn't work if the user has selected more than 1 item. Of course, you can also use if SelectedCount > 0
2. getSelFile will be called whenever the user reads the value of your SelectedFile property.
3. a quick look at your code seems to show no reason why freeing up sl and IL would raise an exception. What exactly is the error message when you free them?
4. OnDblClick property is not necessary in your case because it is already published by the ancestor, TListView.
DragonSlayer.
1. Well, I used Assigned in this case because if you are enabling MultiSelect, then SelectedCount = 1 doesn't work if the user has selected more than 1 item. Of course, you can also use if SelectedCount > 0
2. getSelFile will be called whenever the user reads the value of your SelectedFile property.
3. a quick look at your code seems to show no reason why freeing up sl and IL would raise an exception. What exactly is the error message when you free them?
4. OnDblClick property is not necessary in your case because it is already published by the ancestor, TListView.
DragonSlayer.
ASKER
Thanks
I've got it all so far.
Unless the error when freeing up sl and iL
If I do not comment out this commands, I 've got an address error when executing a program running this component on destroy.
Why!?
I've got it all so far.
Unless the error when freeing up sl and iL
If I do not comment out this commands, I 've got an address error when executing a program running this component on destroy.
Why!?
A few things to try:
1. change to IL := TImageList.Create(nil);
2. try to comment out IL.Free; then test and see if the problem still occurs with sl.Free, if it does, reverse the process, comment out sl.Free and uncomment IL.Free so that we can find out the culprit?
3. If you installed this component in the Component Tab and you put this control onto your Form manually, then you do not need to Free this ListView in your form's OnDestroy.
1. change to IL := TImageList.Create(nil);
2. try to comment out IL.Free; then test and see if the problem still occurs with sl.Free, if it does, reverse the process, comment out sl.Free and uncomment IL.Free so that we can find out the culprit?
3. If you installed this component in the Component Tab and you put this control onto your Form manually, then you do not need to Free this ListView in your form's OnDestroy.
> and you put this control onto your Form manually
I meant to say, "and you put this control onto your Form visually"
I meant to say, "and you put this control onto your Form visually"
And to select all, well, all you need to do is to ensure that MultiSelect is True, and then:
procedure TThumbListView.SelectAll;
var
i: Integer;
begin
MultiSelect := True; // better put in constructor
for i := 0 to Items.Count - 1 do
Items[i].Selected := True;
end;
and similarly:
procedure TThumbListView.DeSelectAll
var
i: Integer;
begin
for i := 0 to Items.Count - 1 do
Items[i].Selected := False;
end;