Solved

how do I populate a filelistbox by creation date instead of alphabetically ?

Posted on 2011-03-24
42
1,429 Views
Last Modified: 2012-05-11
How do I populate a FileListBox by creation date instead of alphabetically ? Does creation date include seconds ?
0
Comment
Question by:ChLa
  • 19
  • 12
  • 9
  • +1
42 Comments
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
FileListBox will always read the files and sort them alphabetically (by the names of the files).
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility

You can not load in a different order unless you override the ReadFileNames method in TCustomFilelistBox
0
 

Author Comment

by:ChLa
Comment Utility
Is overriding the method a good idea ? Or is there a better way ? Often I have a folder with hundreds or thousands of image files. They have different names and numbers, and extensions. I have successfully written a program that will rename/renumber all the files in a folder, alphabetically, for another purpose. But for mass renaming a big folder of images, I need to make sure the files are listed by creation date and not alphabetically. So I am wondering how to have a filelistbox, or something like it, that has the files in order of creation date.
It would be nice to have a filelistbox with buttons allowing me to change back and forth between alphabetical and by creation date.  Is there a better way to do this ? Perhaps I should copy the filenames to some other type of list box ?
0
 
LVL 25

Expert Comment

by:epasquier
Comment Utility
You'd better create your own FileListbox, and fill it with files in the exact order you want.
If you want to go that way, just ask and I'm sure we can help
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility

You could even use a TListView, have columns for file name, create date and even file size

Then you can sort by simply clicking on the column header
0
 
LVL 25

Assisted Solution

by:epasquier
epasquier earned 83 total points
Comment Utility
you might want to have a look at this article :

http://delphi.about.com/od/vclusing/ss/custom-sorting-tshelllistview-delphi.htm

exactly what you need, I think
0
 

Author Comment

by:ChLa
Comment Utility
Hi Everyone,
I am still reviewing this information and trying to decide how to procede.I have been looking at the link from epasquier. It led me to read much more. I have also been trying to find out how to get the shell controls so I could see what they have to offer. How would I override the ReadFileNames method ?
I will be looking at a TListView and seeing if I can figure out how to add columns to it, how to populate it with filenames. If a TListView can already put files in order of date/time, that might be a best thing. I would be happy with a FileListBox that automatically puts files in order of creation date. I wanted anyone who is waiting for me to pick a best answer to know I am still working on this. I wonder if there is an aftermarket fiklelist box with a column for create date/time I could buy ?
0
 
LVL 24

Accepted Solution

by:
jimyX earned 84 total points
Comment Utility
Here is a PAQ by Erajoj for an updated FileListBox that has the ability to sort files by Date Modified, Name, Size or Type:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_10092600.html#1344577
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility

There should be a link to the Demo folder in your Start menu

Select Demos\DelphiWin32\VCLWin32\ShellControls

You will find all the controls you need so you don't need to mess around with FileListBox any more
Delphi-Demos.png
0
 

Author Comment

by:ChLa
Comment Utility
There is a link to Delphi 2010, but not to Embarcadero RAD Studio !
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility

I can send you the files compressed (zip)
Only EE will not allow some types of extensions
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
ChLa,
did you try the FileListBoxEx?
FileListBoxEx.pas
0
 

Author Comment

by:ChLa
Comment Utility
Hi Everyone,

I remembered I still have Delphi 7 on Graphics/Web Site computer for which I am writing this program. It has the ShellListView. I looked at a TShellListView and like it. I am surprised it doesn't already have sorting built in, as well as the ability to select which colums we want to include, and in which order. What I like about it is I don't need a DriveComboBox, or a DirectoryListBox. And of course it displays the other file attributes. This computer is a Sony VAIO with W2K. My laptop has W7 and Delphi 2010. My first question is, can I copy the Shell Controls from Delphi7 to Delphi 2010 ? My laptop is my preferred program writing computer as I have more oportunities to work with it.
I played with a FileListBox and see I could easily reorganize the filenames using a sort routine. But of course the filelistbox doesn't show the date/time. I could extract the creation date/time and put it into some sort of listbox or array, and sort it by date/time. But generally, this would be too time consuming for me to do and I would prefer an easier solution. It would be better for me to be able to sory by creation date instead of last modified. But it is not critical, I can live with last modified. But I think it is important to use not just the date, but the time also. This is because many of the files I will be renaming are digital stills, where I may have taken several in a minute, or rendered computer animation, were more than one file may have been created in a minute.
I didn't have much time to work on this in the last couple of days. Last night as I was discovering the shelllistview, I was thinking I would implement a solution I found on About.com for sorting a ShellListView. Now I think I will try the solution outlined in the ariticle suggested by jimyX For the FileListBox.  I see you attached the .pas file for me. Thank you. How do I use it ? Compile it as a component and then add it as a component ? Do I need to backup an existring file first ? Sorry, I am at work and distracted by many things.
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility

Exactly with the ShellListview
See how easy everything becomes
And the good thing is that it is already tested for you by Embarcadero folks

You already have all the necessary columns, hiding is pretty simple and sorting a TListView, well there are many algorithms out there
The main point is not to reinvent the wheel, you will end up with less errors and a component that is guaranteed to be maintained by Embarcadero with any new releases
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
>   "How do I use it ? Compile it as a component...?"
Yes, in Delphi 7: from the menu -> Component -> Install Component... locate that pas file and then OK and finally compile and install.
In Delphi 2010: from the menu -> File -> New -> Package - Delphi... -> from the Project manager right click on "contains" and select Add the browse and locate that pas file then right click on the package name and select compile and then install after compiling successfully.

>   "Do I need to backup an existring file first ?"
No need, it can be installed as additional component unless you have component with the same name (i.e. FileListBoxEx) but in all cases, I did test it and it works perfectly. However Delphi will prompt you if there is any conflict.

For ShellListView under Delphi 2010:
From Delphi 2010 menu -> File -> open -> Locate and load the files vclshlctrls.dproj and dclshlctrls.dproj. By default the path for those files in my Delphi 2010 is:
C:\Documents and Settings\All Users\Documents\RAD Studio\7.0\Demos\DelphiWin32\VCLWin32\ShellControls
Then compile both of them and then install dclshlctrls.dproj.

PS: to compile and install components in Delphi 2010 after loading the packages or pas files you go to package name in the Project manager then right click on the name of the package and select "Compile" and again right click and "Install".
0
 

Author Comment

by:ChLa
Comment Utility
That worked, now I have the shell components.
Thank you
0
 

Author Comment

by:ChLa
Comment Utility
Now that I have ShellListView on both my Delphi 7 and Delphi 2010, I am trying to add sorting by following the instruction on About.com. Following these instructions the first thing I did was back up Shellctrls.pas. Then I was supposed to remove the shell controls form the IDE. The only way I know to do this is to uncheck the box for "Shell Control Property and component editors" in Components>Install Packages. I did this and the shell controls dissappeared from the samples pallet. I then followed the instructions for exposing the Folder List as a public property. When I try to compile shellctrls.pas, it also wants to compile dcluser, and I get the message Error dcluser.dpk (37) Package cclshlctrls already contains unit "Shell Ctrls". I see thereference to shellcontrols in the package dclusr. What am I doing woring ? Sorry about any mispellings, I wrote down the file names early this morning and can't read my writing now.
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
>   "uncheck the box for "Shell Control Property and component editors" in Components>Install Packages"

Actually unchecking is just hiding it from the "Samples" in the Tool Palette, you should remove it, and then reinstall it from the beginning after updating it.
Remove-Shell-Control-Property.JPG
0
 

Author Comment

by:ChLa
Comment Utility
Hi,
That worked and got me a bit further. But now I find I don't really know how to compile the .pas
Do I say "New Package" or "New Component" ? Either way I end up with a file named by the filepath, and after installing it the components are not there. If I simply open and compile it, it wants to make it an MDI !  Please give me explicit instructions on how to turn Shellctrls back into components in the pallet. Thanks
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
After you removed the component from your Delphi, and updated the pas file "ShellCtrls" then you recompile the whole package as you did at the beginning:

From Delphi 2010 menu -> File -> open -> Locate and load the files vclshlctrls.dproj and dclshlctrls.dproj. By default the path for those files in my Delphi 2010 is:
C:\Documents and Settings\All Users\Documents\RAD Studio\7.0\Demos\DelphiWin32\VCLWin32\ShellControls
Then compile both of them and then install dclshlctrls.dproj.
0
 

Author Comment

by:ChLa
Comment Utility
Thank you very much JimyX. Actually, I started this at ome at night on my Graphics VAIO, which has Delphi 7.Is there any difference in the procedure for D7 as opposed to D2010 ? You know, I started by asking how to sort a filelistbox. Later I got the shellllistview and decided it was better. I feel bad I didn't use what you sent for sorting a filelist box. I found the thing on About.com and since it was the only solution for the shelllistview, decided to try it. I probably should have asked you if you have something for shelllistview, like you sent me for a filelist box. Do you already have something for it, or is it best I try the about.com solution ?
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 32

Assisted Solution

by:ewangoya
ewangoya earned 83 total points
Comment Utility

You are better off using the TShellListView and the method from About.com

Sometimes getting something to initially work may be troublesome but its worth the sweat once you get it to work.

Next time if you want to change something, you will have all the steps mapped out so just hang in there until you get it installed
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
>   "Is there any difference in the procedure for D7 as opposed to D2010 ?"
No difference, same steps.

>   "I feel bad I didn't use what you sent for sorting a filelist box"
Easy man, we are here to help. Feel free to select whatever is convenient with you.
And whatever choice you make you will get our support and all the help to accomplish it. I also vote for the ShellListView for it has more options and features than the FileListBox.
Also you might use one of them now, but look at it this way, you have the two components working and ready for future needs.

>   "I probably should have asked you if you have something for shelllistview"
I do have an advanced component which is similar to the ShellListView but with many features and capabilities, may be is going to be a bit complicated for your current requirement.
http://www.mustangpeak.net/

Did you get the ShellListView working as per about.com instructions?
Are you facing any difficulties?
0
 

Author Comment

by:ChLa
Comment Utility
Hi,
I didn't have much time to work last night, but I did get through re-compiling shell controls. Then I played with it for a while and started reviewing the rest of the procedure. I did that last night with D7/W2K. Today I plan to repeat it with D2010/W7, and to try to get the rest of it working. I will look at the link you sent.
It is interesting to be able to see the source code for shell controls. It shows me how powerful Delphi could be, if I were a more accomplished programmer.
When I compile, I get the warning that Shell controls are specific to a platform.Does this mean specific to Windows, or a specific flavor of Windows ? I generally hope and expect programs I write in any version of Delphi to work in any version of Windows from 2K to W7.
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility
That means it is specific to windows. It will work on any version of windows
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
Just make sure to use the shell controls package that came with D2010, for it was designed to support W7 as well as the previous versions.
0
 

Author Comment

by:ChLa
Comment Utility
Hi,
I copied everything from About.com and am getting just one error. I am getting E2003 Undeclared Identifier "FolderList. TShellIstView does not contain a member named FolderList.
My guess is that i declared FolderList inthe wrong place in ShellCtrls.Pas. But it looks right to me.
Here is the procedure as I copied it:

procedure TMainForm.shellListSortPopupItemClick(Sender: Tobject);
begin
    if shellListSortColumn <> TMenuItem(Sender).Tag then
      shellListSortColumn := TMenuItem(Sender).Tag
    else
      shellListSortAscending := NOT shellListSortAscending;
      ShellListView1.FolderList.Sort(@ShellCompare);
      ShellListView1.Invalidate;
end;

Here is part of ShellCtrls.Pas showing where I put the declaration. Look for the comment "//I added this"

    property OnStartDrag;
  end;

{ TCustomShellListView }

  TCustomShellListView = class(TCustomListView, IShellCommandVerb)
  private
    FOldRoot: TRoot;
    FRoot: TRoot;
    FRootFolder: TShellFolder;
    FAutoContext,
    FAutoRefresh,
    FAutoNavigate,
    FSorted,
    FUpdating: Boolean;
    FObjectTypes: TShellObjectTypes;
    FLargeImages,
    FSmallImages: Integer;
    FOnAddFolder: TAddFolderEvent;
    FFolders: TList;
    FTreeView: TCustomShellTreeView;
    FComboBox: TCustomShelLComboBox;
    FNotifier: TShellChangeNotifier;
    FOnEditing: TLVEditingEvent;
    FSettingRoot: boolean;
    FSavePath: string;
    procedure EnumColumns;
    function GetFolder(Index: Integer): TShellFolder;
    procedure SetAutoRefresh(const Value: Boolean);
    procedure SetSorted(const Value: Boolean);
    procedure SetTreeView(Value: TCustomShellTreeView);
    procedure SetComboBox(Value: TCustomShellComboBox);
    procedure TreeUpdate(NewRoot: PItemIDList);
    procedure SetPathFromID(ID: PItemIDList);
    procedure SynchPaths;
  protected
    procedure ClearItems;
    procedure CreateRoot;
    procedure CreateWnd; override;
    procedure DestroyWnd; override;
    procedure DblClick; override;
    procedure DoContextPopup(MousePos: TPoint; var Handled: Boolean); override;
    procedure EditText;
    procedure Edit(const Item: TLVItem); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    function OwnerDataFetch(Item: TListItem; Request: TItemRequest): Boolean; override;
    function OwnerDataFind(Find: TItemFind; const FindString: string;
      const FindPosition: TPoint; FindData: Pointer; StartIndex: Integer;
      Direction: TSearchDirection; Wrap: Boolean): Integer; override;
    procedure Populate; virtual;
    procedure RootChanged;
    procedure SetObjectTypes(Value: TShellObjectTypes);
    procedure SetRoot(const Value: TRoot);
    procedure SetViewStyle(Value: TViewStyle); override;
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Back;
    procedure Refresh;
    function SelectedFolder: TShellFolder;
    property FolderList: TList read FFolders;             //I added this !
    property Folders[Index: Integer]: TShellFolder read GetFolder;
    property RootFolder: TShellFolder read FRootFolder;
    property Items;
    property Columns;
    property AutoContextMenus: Boolean read FAutoContext write FAutoContext default True;
    property AutoRefresh: Boolean read FAutoRefresh write SetAutoRefresh default False;

What did I do wrong ?
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
You have done it right, it's only to remove any ShellCtrls.dcu that was compiled from the old code before the update is made. You will find it under this path:
C:\Program Files\CodeGear\RAD Studio\7.0\lib

So just remove the component first then delete all the ShellCtrls.dcu files then reinstall the package.

Make sure to add the path of the package to the library path after reinstalling.
0
 

Author Comment

by:ChLa
Comment Utility
Where do I add the path of the package to the library path ?
0
 

Author Comment

by:ChLa
Comment Utility
I found two old shellcntrls, one is in C:\ProgramFiles\Embarcadero/RAD Studio\7.0
The second is in C:\USERS\me\AppData\Local\(2D559015-4C05-4AE5-8C8B\7E13E1EAB09D)\corewin32\\8247FA69).
The new one is in C:\USERS\me\My Documents\RAD Studio\7.0\Demos\DelphiWin32\VCLWin32)
Should I delete both of the old ones ?
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility

Delete both of them.
The correct version will be recreated when you compile your project
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
Deleting the one in "C:\ProgramFiles\Embarcadero/RAD Studio\7.0" will fix it. But you can delete the other one as well, in "C:\USERS\me\AppData\Local\(2D559015-4C05-4AE5-8C8B\7E13E1EAB09D)\corewin32\\8247FA69".

To add any component path to the library path:
From Delphi menu -> Tools -> Options -> At the tree items on the left under Environment Options/Delphi Options/Library - Win32 -> at the Library path Editbox add the path: "C:\USERS\me\My Documents\RAD Studio\7.0\Demos\DelphiWin32\VCLWin32" (without the quotes). Make sure to add ; at the end before adding that path, so it looks like:
xxxxxxxx;C:\USERS\me\My Documents\RAD Studio\7.0\Demos\DelphiWin32\VCLWin32
0
 

Author Comment

by:ChLa
Comment Utility
I did all this and now I am getting just one error.
In the shellListSortPopupItemClick procedure from About.com, there is a line:
ShellListView1.FolderList.Sort(@ShellCompare);

It is causing the error message saying ShellCompare is an undeclared identifier.
What do I do ?
0
 
LVL 32

Expert Comment

by:ewangoya
Comment Utility
You need to add that function (ShellCompare) in your form
function ShellCompare(Item1, Item2: Pointer): Integer;
const
  R: array[Boolean] of Byte = (0, 1);
begin
  result := 0;

  if (Item1 = nil) or (Item2 = nil) then Exit;

  if shellListSortAscending then
  begin
    result := R[TShellFolder(Item2).IsFolder] - R[TShellFolder(Item1).IsFolder];
    if result = 0 then
      if (TShellFolder(Item1).ParentShellFolder <> nil) then
              result := Smallint( TShellFolder(Item1).ParentShellFolder.CompareIDs(
                    shellListSortColumn, //sort_type,
                    TShellFolder(Item1).RelativeID,
                    TShellFolder(Item2).RelativeID) );
    end
    else
    begin
      result := R[TShellFolder(Item1).IsFolder] - R[TShellFolder(Item2).IsFolder];
        if result = 0 then
          if (TShellFolder(Item2).ParentShellFolder <> nil) then
              result := Smallint( TShellFolder(Item2).ParentShellFolder.CompareIDs(
                    shellListSortColumn,// sort_type,
                    TShellFolder(Item2).RelativeID,
                    TShellFolder(Item1).RelativeID) );
    end;
end; (*ShellCompare*)

Open in new window

0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
What we did up to the compiling stage was only setting the ShellListView to support the Sort operation. But it's not added so you should add the sort function in your main application (as per step 4 in About's article):

You may download the complete project here:
http://delphi.about.com/library/code/shelllistview-sort.zip
0
 

Author Comment

by:ChLa
Comment Utility
I did write in the ShellCompare function. But I didn't declare it. Do I declare it after the declarations for procedures, or in public or private declarations ? Is it "Function  ShellCompare(Sender: TObject);" ?
0
 

Author Comment

by:ChLa
Comment Utility
and...
 I didn't include where it says "(*ShellCompare*)"
that's jjust a remark isn't it ?
0
 
LVL 24

Expert Comment

by:jimyX
Comment Utility
>   "But I didn't declare it. Do I declare it after the declarations..."

No need, just make sure to place the function "ShellCompare" the first on top before the other events and procedures:
implementation
{$R *.dfm}
...
function ShellCompare(Item1, Item2: Pointer): Integer;
...
procedure TShellListSortForm.FormCreate(Sender: TObject);
...
procedure TShellListSortForm.shellListSortPopupItemClick(Sender: TObject);
...

Open in new window

>   ""(*ShellCompare*)" that's just a remark isn't it ?"
Yes, you can remove that, it's just a comment.
0
 

Author Comment

by:ChLa
Comment Utility
That did it. It's working now. Thank you.

Just a few more questions.

How could I add the ability to sort by Creation Date ?

What do I need to do to have two of these sorting shelllistviews on my form ? I see some procedures refer to shelllistview1. I suppose those would have to be copied and changed to shelllistview2, or I would have a variable for which shelllistview. Such as ShellListView[ShellListViewNumber]. I guess the procedures that don't specify shelllistview1 would not need to be changed.

I read somewhere about a shell component editor in RAD studio. I don't have rad studio. When I bought Delphi2010, I didn't, and still don't know what RAD studio is, so I only downloaded Delphi2010. Would I need RAD Studio to specify which columns a shelllist view has, and in what order ? Can I use this to add creation date ? On my Delphi7/W2K graphics computer, I read something in the D7 help files about a component editor. But I couldn't find it.

I could upgrade to the full RAD Studio and Delphi 2011. Is it worth it ? Have they fixed bugs, improved or added components ?
0
 

Author Comment

by:ChLa
Comment Utility
If I use a shelllistview On Change event to display the number of objects in view (ShellListView1.GetCount) it counts the objects before the change. what event happens after the change, or, what shelllistview property lists objects, or just files, after the change ?  Where can I find a list of ShellListView properties ?
0
 

Author Comment

by:ChLa
Comment Utility
OK,
I see no one is responding to this any more. I suppose that means I have asked too many questions without rewarding points, or dragged this on beyond everyones patience. So I will close this and award points based on the basic question.

It's just that it's really nice to be able to ask a question as it comes up, without the formaiity of sticking to the original question, rules, zones, and awarding points. It's like E-Bay. It's easy and fun to buy things, and to find things not available elsewhere. But going back and leaving feedback is work.

It's also quite a challenge to be fair to everyone after I've gotten so much useful help. Even if I didn't use a specific answer, I learned from it and may use it later. I wonder if there's information telling me how to do this. All the comments werehelpful. Do I check that box first ? Does it matter if I check a specific solution, or do I only need to worry about awarding the right person(s). What is the difference between accept solution and accept solution and award points ?
0
 

Author Closing Comment

by:ChLa
Comment Utility
I want to thank everyone for their help
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This video discusses moving either the default database or any database to a new volume.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now