News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Adventures in programming: Treeviews, directory scanning, recursion

Started by NoCforMe, April 05, 2024, 10:36:19 AM

Previous topic - Next topic

NoCforMe

Quote from: sinsi on April 10, 2024, 05:05:19 AMYou can search C:\Windows and find a folder called appcompat
On your next recursive call you search C:\Windows\appcompat and will get an access denied error.
I was going to say I'll run tests on that, but I just now checked: I can view the contents of this folder (C:\Windows\AppCompat) in Explorer; there's a folder called "Programs" within it. (And I can go even deeper.) So how will I get an access denied error from my program if I can view it with Explorer? What happens if you go there w/Explorer?

I just ran PicView against C:\, and it showed me C:\Windows\AppCompat, down to the folder Programs within, which showed up as an empty folder. Is it possible I have different permissions or something set on my system?

BTW, first time I tried that I got a stack overflow. I lied; stack was not set to 64K DWORDS, but only to 64K bytes. Changed to the former and it worked OK.

Speaking of stack size: can someone tell me what a "typical" stack size is for a Win32 GUI program? (and specifically one that uses recursion). And what is the default stack size if I don't declare a size (using ML.exe)? I'm surprised I don't know these things after all these years.
Assembly language programming should be fun. That's why I do it.

sinsi


That was just an example, I couldn't remember the exact string in the [hint]debugger[/hint]
It was C:\Windows\appcompat\appraiser
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

Yargh: I was hoping to use this folder to test my dir scan, rather than post new versions and have you test them. (That game could get old fast!) My C:\Windows\AppCompat folder has 2 files: AEINV_PREVIOUS.xml and RecentFileCache.bcf, both of which I can access (and both of which have today's timestamp ???).

Any way you know of to create a folder that's "off limits" and is guaranteed to give an access-denied error?

"
Assembly language programming should be fun. That's why I do it.

sinsi

Have you tried to scan your C:\ ?

The other way would be to make a directory and change owner and permissions so that only Administrators have access.
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

OK, folks, we here at NoC Laboratories, GmbH have come up with what we think is a good solid working app, package attached below.

sinsi, I incorporated some of your suggested changes to checking results of FindXXXXFile(), but not all: I'm not bailing out of the GetAllDirsAndFiles() function if I encounter a folder with access denied, because I don't need to. I've tested this, and it turns out that I do have a folder on my D: drive, System Volume Information, which gives me an access-denied error if I try to open it, so I'm pretty sure this works OK. (You'll have to be the judge of that.)

I made another improvement: since this is now a picture viewer, I prune the treeview of any paths that don't contain pictures, so what you'll see is a truncated version of your file system.

There is one little bug which I haven't yet been able to track down: on some scans there's a leftover empty folder at the end. It's annoying but not a show-stopper, so I'm putting this out there.

I think my pruning routine is interesting. When I first coded it, it was too aggressive and ended up eliminating valid paths (those which contained pictures somewhere along the path). What I was doing was scanning my file list from the bottom up, and marking any empty folders (those without any pictures) with the flag bit $prune, meaning that the treeview-construction code would skip over them. I then followed the chain of parent folders up the tree, marking all non-picture-containing folders as $prune until finding one that did contain pictures.

Problem was, I was wrongly eliminating some paths that did contain pictures. My 2nd attempt worked, in that it included all those paths, except that now the treeview structure was flattened out, and everything was all jumbled together.

Finally figured it out: in addition to pruning empty paths, I added another flag bit, $keep. If I found a path that did contain pictures, I flagged the entire path up to the root with $keep, thus "protecting" it. In the treeview-construction code, $keep takes precedence over $prune, so everything works fine.
Assembly language programming should be fun. That's why I do it.

zedd151

At first glance, it looks good so far.
But then I selected the root of drive E:, nothing happened. Then It dawned on me to enter the directory (by double clicking), and voila. It works as advertised. :)

28,172 pictures found.  :dazzled:
Ventanas diez es el mejor.  :azn:

NoCforMe

So you're talking about what happens in the folder-selection dialog, right? Yes, it's a slightly non-standard usage of that facility: if you look at the code I had to jump through a bunch of hoops to make it select only folders, not files (had to add a hook procedure and subclass the dialog).

Thanks for checking it out!

One interesting use of this is seeing how many image files are stashed away here and there in your file system. I had no idea there were so many.
Assembly language programming should be fun. That's why I do it.

zedd151

Quote from: NoCforMe on April 13, 2024, 07:44:35 AMSo you're talking about what happens in the folder-selection dialog, right? Yes, it's a slightly non-standard usage of that facility
Yup, but it works. Might want to include a short instruction manual.  :greensml:
Ventanas diez es el mejor.  :azn:

jj2007

Quote from: NoCforMe on April 13, 2024, 07:44:35 AMSo you're talking about what happens in the folder-selection dialog, right?

The attached example uses SHBrowseForFolder. The behaviour is somewhat different.

Your version will confuse some Windows users. Besides, the picview dialog is far too high. I suspect there is a button at the bottom, but I can't see it.

zedd151

Quote from: NoCforMe on April 13, 2024, 07:44:35 AMI had to jump through a bunch of hoops to make it select only folders, not files (had to add a hook procedure and subclass the dialog).
Have you thought about using a tree for directory selection? Or would that get overly complicated?
Ventanas diez es el mejor.  :azn:

NoCforMe

Quote from: jj2007 on April 13, 2024, 08:01:09 AMBesides, the picview dialog is far too high. I suspect there is a button at the bottom, but I can't see it.
Oh, you mean the entire dialog? No, nothing on the bottom (except a status bar), but if this were production grade, then I should be determining the size of the user's screen and adjusting accordingly.

Next version.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: sudoku on April 13, 2024, 08:15:45 AM
Quote from: NoCforMe on April 13, 2024, 07:44:35 AMI had to jump through a bunch of hoops to make it select only folders, not files (had to add a hook procedure and subclass the dialog).
Have you thought about using a tree for directory selection? Or would that get overly complicated?
No, because 1) it would be extremely complicated and 2) I think the interface I chose is much more appropriate, easier for me to code and easier for the user to navigate.

My usage of the GetOpenFilename() dialog to select folders isn't original with me: I got the idea from this CodeProject article, which explains how to slightly re-jigger that function to display folders only instead of folders and files. (It's actually not really that nonstandard: I have other software that uses this same functionality.) As the article points out, this interface is actually better for this job than SHBrowseForFolder().
Assembly language programming should be fun. That's why I do it.


sinsi

Crashed :biggrin: if you try and open the tree while a search is taking place.
Put it on its own thread (hard) or disable the tree (easy)

Choose Folder, when opening the combobox for the first time it (the combobox) closes immediately

It would be nice to have an image count in the tree node's text e.g. "Images (44)" as an indication that this folder has images in it.

One more for the wish list, the ability to zoom the picture. On a 4K screen an icon is barely 1cm wide :smiley:


Good job  :thumbsup:
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

Quote from: sinsi on April 13, 2024, 11:43:12 AMCrashed :biggrin: if you try and open the tree while a search is taking place.
Put it on its own thread (hard) or disable the tree (easy)
The disk-scan code is in its own thread (not hard, ackshooly).
But the treeview-handling code isn't, hence the crash.
Easy fix, though: I just used my "busy" flag which I already had to lock out any treeview selection clicks. If you try it now you'll get a system "ding" until the treeview is safely populated. (I already do this for clicking on the "Choose Folder" button.)
I never tried clicking on the treeview while it was grinding away on folders ... gotta say you're pretty good at breaking code, sinsi (and that's a compliment).
QuoteChoose Folder, when opening the combobox for the first time it (the combobox) closes immediately
Which combobox--the "Look in" one? That one works fine for me.
QuoteIt would be nice to have an image count in the tree node's text e.g. "Images (44)" as an indication that this folder has images in it.
That would be a nice li'l feature, thanks.
QuoteOne more for the wish list, the ability to zoom the picture. On a 4K screen an icon is barely 1cm wide :smiley:
Yes, I've certainly thought of that. Version x+2?

Oh, and JJ, the dialog window is now resizeable, so you should be able to size it to your screen. (I'm not resizing the controls yet, but soon ...)

.exe only attached here
Assembly language programming should be fun. That's why I do it.