Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Selecting all in TOpenDialog

0 views
Skip to first unread message

dvd8n

unread,
Apr 4, 2002, 7:53:28 AM4/4/02
to
I want to add a 'select all' button to a TOpenDialog. I can add the button
itself to the dialog in a class descended from TOpenDialog easily enough,
but then what?

The obvious thing to do is to send a 'ctrl-a' key combination, but how? And
send it to what? Or am I barking up the wrong tree - is there a better way?

Thanks

David.


Timothy H. Buchman

unread,
Apr 4, 2002, 11:26:50 AM4/4/02
to
dvd8n <dvd8n> wrote in message news:3cac4c69_1@dnews...

I haven't tried this, but I'll give you a suggestion and a warning.

The only ways to obtain the handle of the listview window with the
files are indirect. One way is to enumerate the child windows of the
GetParent(Handle) result for the TOpenDialog. The correct window has
the classname "syslistview32". This is pretty straightforward.
Another is to install an Explorer Hook for the dialog (which has to
call the VCL's explorer hook as well) and intercept a message intended
for the listview, which include its' handle. There's an example of the
latter here: http://www.codeguru.com/dialog/QuickLaunch.shtml .

Since typing [Ctrl][a] while the listview has focus works, you should
be able to send the keystroke to the window in code. However...

You should read my earlier message about expanding the lpszFileName
buffer for multi-select TOpenDialogs. Read the whole thread to learn
about VCL buffer-size restrictions. It's not on the MERS site yet,
but it's here:

http://groups.google.com/groups?selm=3c671669_1%40dnews&output=gplain
(long link-repaste if word-wrapped)

I'm still working on that, because I think that under Win9x, there is
another limitation. Since the list of file names is updated to an
Edit control in the dialog with each selection, that text insertion
fails when the list is longer than 32K characters. I think that makes
the Win9x dialog return fail. You should also know that the
verification of the *entire list* of filenames (as real files) upon
pressing "Open" can take a very long time when there are hundreds of
files.

Please report back on your research here.

--
Timothy H. Buchman
========================================
City Center Theater, New York NY
mail address tbuchmanPLEASE(at sign)REMOVEcitycenter.org
Search .borland message archive on http://www.mers.com/searchsite.html

dvd8n

unread,
Apr 8, 2002, 6:55:17 AM4/8/02
to
I used the code :


HWND FileListHWnd;

BOOL CALLBACK EnumChildWinProc (HWND hwnd, LPARAM lParam)
{
char name [256];
int c;
c = GetClassName (hwnd, name, sizeof (name));
name [c] = 0;
if (stricmp (name, "syslistview32") == 0)
{
FileListHWnd = hwnd;
return (FALSE);
}
return true;
}

void TOpenAllDialog::LocateFileList (void)
{
FileListHWnd = NULL;
EnumChildWindows (GetParent (Handle), (WNDENUMPROC) EnumChildWinProc, 0);
}


to locate the window handle - it did give me a result - although funnily
enough it didn't work on the DoShow, but was fine when called on the button
click itself.

Then to send the control-a I did a

SendMessage (FileListHWnd, WM_CHAR, 1, 0);

1 being a control-a I believe. Nothing happened. Any ideas?

Thanks

David


dvd8n

unread,
Apr 8, 2002, 7:37:54 AM4/8/02
to

dvd8n

unread,
Apr 8, 2002, 10:49:34 AM4/8/02
to
And the FileListHWnd window handle seems to be ok as I can see the contents
of the list using ListView_GetItem and they are correct.

David

PS I also tried sending

SendMessage(FileListHWnd, WM_KEYDOWN, VK_CONTROL, 0);
SendMessage(FileListHWnd, WM_KEYDOWN, 'a', 0);
SendMessage(FileListHWnd, WM_KEYUP, 'a', 0);
SendMessage(FileListHWnd, WM_KEYUP, VK_CONTROL, 0);

and that didn't appear to work either.


dvd8n

unread,
Apr 8, 2002, 5:22:36 PM4/8/02
to
I think I've found a better way anyway; I do this instead:

int count = ListView_GetItemCount(FileListHWnd);
for(int i = 0; i < count; i++)
{
item.mask = LVIF_TEXT | LVIF_PARAM;
item.iItem = i;
item.iSubItem = 0;
item.pszText = szItemName;
item.cchTextMax = 256;
ListView_GetItem(FileListHWnd, &item);
if ((GetFileAttributes (szItemName) & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
ListView_SetItemState (FileListHWnd, i, LVIS_SELECTED, LVIS_SELECTED);
}
}


David


Timothy H. Buchman

unread,
Apr 9, 2002, 7:36:09 AM4/9/02
to
dvd8n <dvd8n> wrote in message news:3cb209bd_2@dnews...

> int count = ListView_GetItemCount(FileListHWnd);
> for(int i = 0; i < count; i++)
> {
> item.mask = LVIF_TEXT | LVIF_PARAM;
> item.iItem = i;
> item.iSubItem = 0;
> item.pszText = szItemName;
> item.cchTextMax = 256;
> ListView_GetItem(FileListHWnd, &item);
> if ((GetFileAttributes (szItemName) & FILE_ATTRIBUTE_DIRECTORY)
== 0)
> {
> ListView_SetItemState (FileListHWnd, i, LVIS_SELECTED,
LVIS_SELECTED);

That does look very nice. I feel some doubt about whether the WM_CHAR
message will work, because that would naturally occur after Windows'
translation of the accelerator key. It doesn't require focusing the
listview, however. Note that "pressing" your button moves focus away
from the listview. Even better than _KEYDOWN etc. would be
keybd_event, since we're in the same process, and thus free to write
::SetFocus(FileListHWnd); before the events. However, I haven't
gotten that to work myself yet! Your new idea has only one possible
drawback, which is that it may cause an OnSelectionChange event for
each item's state change. The [Cntrl][A] only causes a single event.

Timothy H. Buchman

unread,
Apr 9, 2002, 9:52:10 AM4/9/02
to
Timothy H. Buchman <tbuchmanPLEASE(at sign)REMOVEcitycenter.org> wrote
in message news:3cb2d22a$1_2@dnews...

> dvd8n <dvd8n> wrote in message news:3cb209bd_2@dnews...
> > int count = ListView_GetItemCount(FileListHWnd);

This code works:

::SetFocus(FileListHWnd);
keybd_event(VK_CONTROL,0,0,0);
keybd_event('A',0,0,0);
keybd_event('A',0,KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);

and your WM_KEYDOWN etc. code might work with 'A' instead of 'a'.
That's because VK_A (the un-translated keystroke) is 0x41, or 'A'.
Your last posted code is visually superior, because it does not show
directories as selected. However, the system dialog code does not
parse selected directories into the list of returned filenames from
the dialog, even though [CNTRL][A] makes them show "selected".

dvd8n

unread,
Apr 9, 2002, 9:14:20 AM4/9/02
to
> listview, however. Note that "pressing" your button moves focus away
> from the listview.

Is this true for TSpeedButtons?

D

Timothy H. Buchman

unread,
Apr 10, 2002, 9:31:25 AM4/10/02
to

dvd8n <dv...@BigFoot.com> wrote in message news:3cb31677_1@dnews...

No, no, usually when people say "button", they mean TButton. Are you
placing the speedbutton so it looks like it's part of the dialog's
toolbar? You might want to check your app with Win2K, I think that
may have more or different buttons in the toolbar at the top right of
the dialog.

dvd8n

unread,
Apr 10, 2002, 5:44:38 PM4/10/02
to

> No, no, usually when people say "button", they mean TButton. Are you
> placing the speedbutton so it looks like it's part of the dialog's
> toolbar? You might want to check your app with Win2K, I think that
> may have more or different buttons in the toolbar at the top right of
> the dialog.

I started off intending to put it there but had second thoughts and put it
beside go & cancel. I had a feeling that Bill might make the toolbar bigger
at some point to screw me up. But I left it as a speedbutton so that it
wouldn't interfere with focus.

Thanks for the thought though.

D


0 new messages