News:

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

Main Menu

I invented a new type of Windows control (List/Edit)

Started by NoCforMe, August 18, 2022, 09:17:53 AM

Previous topic - Next topic

NoCforMe

@Swordfish: Wow, I guess it's back to the lab for this. For one thing, I never tried minimizing it while running. Big problems there upon reopening it. I have no idea what's going on there; might have something to do with the thread I started in the program. Other stuff warrants looking into as well.

Yes, it's not only a CPU hog but a memory hog as well (the listview here is the culprit). I'm getting about 25% CPU usage here. (Windows 7-64: what's your OS?)

@Hutch: That doesn't apply here. I'm not searching for extensions at all; I just treat the filename as a string and compare the search term against it. If there are embedded periods in the name, these will either match or not (probably not if you're looking for, say, ".jpg" files). So the current scheme works pretty well.

I can see how your advice would work well if you do want to check for extensions. As it is, my "exclude" logic can exclude any files matching the search terms entered, which may or may not be extensions.
Assembly language programming should be fun. That's why I do it.

quarantined

Quote from: NoCforMe on August 20, 2022, 08:44:02 AM
@Swordfish: Wow, I guess it's back to the lab for this. For one thing, I never tried minimizing it while running. Big problems there upon reopening it.

maybe need to process WM_PAINT messages?

I'll keep playing with it, and let you know if I find any other oddities.

NoCforMe

Quote from: swordfish on August 20, 2022, 08:47:07 AM
maybe need to process WM_PAINT messages?
Don't know where you get that; nowhere in my code do I need to process that message. The only place that does any painting is my owner-drawn listbox, and there I just use the Windows-supplied handle to a DC. So it's something else.
Assembly language programming should be fun. That's why I do it.

quarantined

Quote from: NoCforMe on August 20, 2022, 08:52:27 AM
Don't know where you get that
Because after minimize, then maximize the text display not updating but the program is still running. (As evident in taskmgr) So hmmm. Or maybe dc handle you mentioned getting corrupted somehow?

NoCforMe

No, because that code is in the "exclude" dialog which isn't even up when the rest of the program is running. For sure something's getting corrupted, though ...

Oh no, I've created a monster!
Assembly language programming should be fun. That's why I do it.

quarantined

Quote from: NoCforMe on August 20, 2022, 09:14:14 AM
No, because that code is in the "exclude" dialog which isn't even up when the rest of the program is running.

:rolleyes: oops my bad. Of course you are correct there.
How about disallow minimizing and maximizing.
Does covering the window with another program affect your programs window?  I'm on my iPad out and about can't check that myself... I'll look at that later though.



quarantined

Quote
Oh no, I've created a monster!
Oh no!!! Not really though. Just fix the small problems first, tackle the hardest problem later.

quarantined

For the 'Browse for folder' issue - you probably figured out already...

;=====================================
; Browse command
;=====================================

do_browse:
;***** Now using GetOpenFileName():  *****

could be a problem. Unless you select a file then parse the full path and retrieve the folder name from that...

I haven't seen any other problems other than those already noted.


NoCforMe

No. Believe me, I've been over this ground many, many times.

I've tried several methods to get just folders instead of files. The method I settled on involves rigging GetOpenFileName() so that it only returns folders, not files. This rigging involves

  • Subclassing the GetOpenFileName() dialog
  • Setting up a "fake" buffer that I can manipulate to get folders instead of files
  • Setting up an "impossible" "filter" for files that'll never be satisfied
Complicated but it works. Except that now, some files are creeping into my Select Folder dialog. Dunno what's up with that ...

I got this technique from an article posted on the web. Don't have it at the moment but will post a link to it later.

Back to the drawing board ...
Assembly language programming should be fun. That's why I do it.

quarantined


NoCforMe

Yes, I tried it and did not like it at all. Much more complicated, for one thing.

Here's the page on rigging GetOpenFileName() to deliver folders. Explains why this is a better method.
Assembly language programming should be fun. That's why I do it.

quarantined

What? I've never had any problems using it. From the Masm32 library - header there because part of masm32.lib

; #########################################################################

    .386
    .model flat, stdcall  ; 32 bit memory model
    option casemap :none  ; case sensitive

    include \masm32\include\windows.inc
    include \masm32\include\shell32.inc
    include \masm32\include\user32.inc
    include \masm32\include\ole32.inc

    cbBrowse  PROTO :DWORD,:DWORD,:DWORD,:DWORD

    .code

; #########################################################################

BrowseForFolder proc hParent:DWORD, lpBuffer:DWORD, lpTitle:DWORD, lpString:DWORD

  ; ------------------------------------------------------
  ; hParent  = parent window handle
  ; lpBuffer = 260 byte buffer to receive path
  ; lpTitle  = zero terminated string with dialog title
  ; lpString = zero terminated string for secondary text
  ; ------------------------------------------------------

    LOCAL lpIDList :DWORD
    LOCAL bi  :BROWSEINFO

    mov eax,                hParent         ; parent handle
    mov bi.hwndOwner,       eax
    mov bi.pidlRoot,        0
    mov bi.pszDisplayName,  0
    mov eax,                lpString        ; secondary text
    mov bi.lpszTitle,       eax
    mov bi.ulFlags,         BIF_RETURNONLYFSDIRS or BIF_DONTGOBELOWDOMAIN
    mov bi.lpfn,            offset cbBrowse
    mov eax,                lpTitle         ; main title
    mov bi.lParam,          eax
    mov bi.iImage,          0

    invoke SHBrowseForFolder,ADDR bi
    mov lpIDList, eax

    .if lpIDList == 0
      mov eax, 0      ; if CANCEL return FALSE
      push eax
      jmp @F
    .else
      invoke SHGetPathFromIDList,lpIDList,lpBuffer
      mov eax, 1        ; if OK, return TRUE
      push eax
      jmp @F
    .endif

    @@:

    invoke CoTaskMemFree,lpIDList

    pop eax
    ret

BrowseForFolder endp

; #########################################################################

cbBrowse proc hWin   :DWORD,
              uMsg   :DWORD,
              lParam :DWORD,
              lpData :DWORD

    invoke SetWindowText,hWin,lpData

    ret

cbBrowse endp

; #########################################################################


Quote from: NoCforMe on August 20, 2022, 10:18:38 AM
Much more complicated, for one thing.

Nah. C'mon you've been writing code a lot longer than me

NoCforMe

Well, I may have to go that route because guess what? my browse-for-folder thing never worked correctly anyhow. (Just downloaded the earlier .zip I posted of the program. It always showed files, after the folders: I just never noticed ...)

This is turning into a quite interesting project ...

OK, here's one thing I really really don't like about your code. As I said, I tried using this method, and ran into the same problem you have here.

You see that line in your code

    mov bi.pidlRoot,        0


Well, pidlRoot is the member of the BROWSEINFO struct you use to set the starting point from the root folder to start browsing. Except that you're not setting it to anything useful here, so every damn time you start from the root and have to drill down to where you want to be. Pain in the ass. At least with my method it starts the browse from where you left off the last time, which is what most users would expect.

I never figured out how to use this member to start where I want to. Maybe I can do that w/some more research.

Hmm; maybe just found that. On that page I linked to earlier:

QuoteIt would be nice if the browser dialog opens with the current path already selected. Here's how you do it:


int CALLBACK BrowseCallbackProc( HWND hWnd, UINT uMsg, LPARAM lParam,
  LPARAM lpData )
{
  if (uMsg == BFFM_INITIALIZED)
    SendMessage(hWnd, BFFM_SETSELECTION,TRUE, lpData);
  return 0;
}

g_SHBF_Folder=_T("C:\\Program Files");
TCHAR path[_MAX_PATH];
BROWSEINFO info={NULL,NULL,path,_T("title"),BIF_USENEWUI,BrowseCallbackProc,
   (LPARAM)g_SHBF_Folder};
SHBrowseForFolder(&info);
where g_SHBF_Folder is the starting point you want. (Probably Unicode so you have to deal w/that, but not a deal-breaker.)
Assembly language programming should be fun. That's why I do it.

quarantined

Don't give up though, it looks promising.

I would disable the minimize/maximize buttons of the window (to avoid first issue), use SHBrowseForFolderA (to fix the folder issue),  uncomment the null string handling (for the crash issue).

Then work on why the program is CPU hungry (~50%)
Well, I've been playing with this for almost 4 hours now (off and on) and I'm sure you've been at it for longer... So.....  ZZZzzzz time for a rest

quarantined

Quote from: NoCforMe on August 20, 2022, 10:30:10 AM
pidlRoot
I never figured out how to use this member to start where I want to. Maybe I can do that w/some more research.

Ask on the forum, I never minded starting from root myself though.

Upon a google search for pidlRoot:
You can use SHParseDisplayName to receive a pidl for a folder
from...

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/32da371f-d6cb-4a97-a679-da2b7fbcf468/browseinfo-how-to-initailize-pidlroot-with-a-string-not-a-special-folder-id?forum=vcgeneral

So, ok... I guess doing all of this makes it a little more complicated. But no harm in trying
I've never done that, but I might just burn the midnight oil tonite and make a test piece to try it.