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.
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
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
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.
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
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.
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".
Is this true for TSpeedButtons?
D
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