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

sinsi

QuoteWhich combobox--the "Look in" one? That one works fine for me.
Correct
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

Quote from: sinsi on April 13, 2024, 01:08:35 PM
QuoteWhich combobox--the "Look in" one? That one works fine for me.
Correct
That's weird; works here. It doesn't drop down for you the 1st time? I'll have to "look in"to that.

In the meantime, your wish is my command: check out this version:

It was a very easy add.
Assembly language programming should be fun. That's why I do it.

sinsi

QuoteThat's weird; works here. It doesn't drop down for you the 1st time? I'll have to "look in"to that.
First click, drops down then immediately closes. after that behaves normally

QuoteIn the meantime, your wish is my command
:biggrin:
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

Quote from: sinsi on April 13, 2024, 01:43:45 PM
QuoteThat's weird; works here. It doesn't drop down for you the 1st time? I'll have to "look in"to that.
First click, drops down then immediately closes. after that behaves normally
Ugh. I'm guessing that might be some kind of Windows version problem. Win 7 here; you?
Also maybe due to my subclassing/hooking of the GetOpenFile() proc ...
Assembly language programming should be fun. That's why I do it.

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.
JJ, I'm curious: what's your display resolution?
Assembly language programming should be fun. That's why I do it.


NoCforMe

New version (.exe only) attached here. Everything is implemented that I think I want except for image zooming (coming real soon now ...). And I fixed some problems that were causing extreme flakiness and crashing.

The flakiness apparently had a very simple cause. A while back sinsi advised me that I needed to close the find handle that was returned by FindFirstFile(). Well, I did that, and it solved some problems at the time. However, stupid me; I was just calling CloseFindHandle() without checking whether the handle I was trying to close was valid or not! Now I guess I have to plead guilty to being kind of careless here; a lot of Win32 CloseXXX() functions are very forgiving if you pass them a bogus handle; they just ignore it. Not CloseFindHandle()! It stands for no nonsense. Anyhow, after fixing this, no more crashes or odd behavior (like the app closing when I click on the "Choose Folder" button).

There are two remaining problems, though, neither one a show-stopper, but annoying:

1. The progress bar: For long disk scans, I put up a "Waiting:" prompt and a progress bar that's supposed to move continuously in "marquee" mode. Except that it doesn't. It just sits there.

This all has to do with my use of a separate thread for the disk-scanning code. At this point I'm not sure at all I'm doing the right thing here. Let me explain what's going on in my code.

In pseudocode:
start a new scan:
  BusyFindingFlag = TRUE    ;locks out controls while scan is in progress
  create "root" item in treeview
  PutUpProgressBar():
      show "Waiting:" (static text)
      show progress bar
      set progress bar in marquee mode (PBM_SETMARQUEE)
  CreateThread() for FillFileList():
      (everything at this level is in the new thread)
      FindAllDirsAndFiles()    ;this is the recursive routine that takes a lot of time
      Send $MSG_FillTreeview to the dialog
        which calls FillTreeview() to populate the treeview
      ExitThread()
Hopefully that makes sense. It works find so far as the application goes, but the progress bar control never moves. From reading a lot of stuff online about this (none of it on Micro$oft Learn, however!), it seems that what's happening is that the main thread of the program isn't getting enough cycles to service the progress bar. (My next move is to monitor the messages going to that control.)

Can anyone tell me from looking at this scheme whether I'm doing the right thing here so far as threading goes? The idea is to isolate the code which has to grind away at the disk scan so that the user interface doesn't go unresponsive, which is working. But if the UI is responsive, why isn't that damn progress bar moving?

2. Resizing blues: I came up with some pretty fancy resizing code; try it out. It keeps the widths of the treeview and pic-display windows proportional while maintaining the spacing between controls and the edge of the dialog; that part works great.

What's not so great is the intense flicker that results from resizing, especially if a good-sized image is being displayed. (It's not as bad with a small image or no image.) Any suggestions? Keep in mind that I'm moving or resizing 3 windows in addition to the dialog window (plus the status bar).



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

sinsi

Does your message pump use GetMessage or PeekMessage?
How do you know when the thread is finished?

Source code, source code, source code  :rolleyes:
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

No message loop in my code, I'm using a dialog as the main window, so the dialog manager is running the message loop. (Could that be part of the problem?)

The thread finishes when GetAllDirsAndFiles() finishes the disk scan.

I'm trying to avoid getting into the details of the source at this point; would like to deal with this on a conceptual level.

I will give you the complete routine that's running as a separate thread:
FillFileList PROC

INVOKE GetAllDirsAndFiles, 0 ;Start @ file entry[0] ("root").
INVOKE SendMessage, DialogHandle, $MSG_FillTreeview, 0, 0
INVOKE ExitThread, 0
RET

FillFileList ENDP
BTW, is that RET even ever reached? can I remove it?
Assembly language programming should be fun. That's why I do it.

sinsi

If FillFileList is your ThreadProc it takes one argument, you have none.
Lucky for you, you use ExitThread instead of a RET.

FillTreeView should be on the main GUI thread, it has nothing to do with the spawned thread.

Of course a dialog has a message pump, surely (DlgProc)?

Concepts are fine, it's the implementation that matters. Source code is that implementation.
Tá fuinneoga a haon déag níos fearr :biggrin:

NoCforMe

None of which explains why my progress bar doesn't marquee, does it?
Assembly language programming should be fun. That's why I do it.

sinsi

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

NoCforMe

Well hey, don't get sore there. Nobody expects you to read minds. And your advice above was good. Just doesn't seem to address my immediate problem.

Any other ideas? I'll post source later, but in the meantime, what would cause a progress bar not to animate? (And yes, I verified that it does have the PBS_MARQUEE style bit set.) Since my thread frees the UI from the computation-heavy disk scan, you'd think there'd be plenty of cycles to make that marquee thing happen.
Assembly language programming should be fun. That's why I do it.

sinsi

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

NoCforMe

All I know is what happens visually: the progress bar appears but is static.

I'm thinking of subclassing the progress bar and logging all the messages sent to it after it gets put up.

The sequence of events I wrote in pseudocode above should give you a good idea of what's happening in the program:
  • Treeview appears with "root" item
  • Progress bar and "Waiting:" text appear
  • Disk scan proceeds
  • Treeview gets populated
  • Progress bar and "Waiting:" text get taken down
During the time when the thread is still active you can click on either the "Choose Folder" button or the treeview and it'll ding at you (intentionally, using INVOKE MessageBeep, MB_ICONASTERISK), which proves that the UI is active and receptive during this time.

That's pretty much it. What else can I tell you?
Assembly language programming should be fun. That's why I do it.