Выборочный выбор множества папок и множества файлов в OpenFileDialog. Как это возможно?


#1


#2

Там есть 2 свойства которые рядом по точке отображаются. 1 даёт 1 файл, а другое все файлы.

Пройдитесь по всех свойствам и методам перед тем как вопросы задавать. Ну не сложно же описания прочитать.


#3

вы видимо картинку не смотрели. я понимаю такие вопросы затрагивают ваше самолюбие, не хочу вас обижать, но то о чем вы говорите ушь слишком примитивно, для этого существует свойство Multiselect. Я, же привел пример результата множественного (при этом выборочного) выбора ПАПОК, ПОВТОРЯЮ ПАПОК. НО, есть загвоздка, когда я выбираю ПАПКИ то файлов нет, а когда выбираю ФАЙЛЫ, папок нет в диалоговом окне, в смысле они не отображаются.


#4

А, я подумал у вас проблема с получением имён выбранных файлов… А то что вам надо - я никогда не видел и найти сейчас не могу.

Попробуйте наследовать от 1 из предков OpenFileDialog, или, если не получится - то только писать полностью велосипедный класс-диалог.


#5

у меня возникла мысль, отправить выделенное из одного диалога (который позволяет выделять и папки и файлы но открывает только файлы) в диалог (который открывает папки). Вот только не пойму как выдернуть выделенную область из OptyFileDialog, но точно знаю что он дает перегружать свои методы.

Подскажите, как выдернуть выделенную область из одного стандартного OpenFileDialog и присвоить ее в точно такой же другой OpenFileDialog.


#6

Я вам говорю, попробуйте наследовать от FileDialog. Если там не выйдет - то только инъекциями кода, потому что OpenFileDialog это только оболочка для WinAPI, то есть рефлекция не поможет. Но я в этом не разбираюсь, и сомневаюсь что это возможно, потому что инъекции кода в стандартные неуправляемые библиотеки звучит как что то что бы нарушало безопасность.


#7
    во нарыл Структура BROWSEINFOA
    Содержит параметры для SHBrowseForFolder функцию и получает информацию о папке, 
   выбранной пользователем.
    Тип: hwnd элемента
    Дескриптор окна владельца для диалогового окна.

https://docs.microsoft.com/ru-ru/windows/desktop/api/shlobj_core/ns-shlobj_core-_browseinfoa


#8

Ну, это же то, поверх чего строится System.Windows.Forms.FolderBrowserDialog. Я не увидел среди параметров того, что может разрешить выбирать файлы… А структура эта, вроде, только для создания этого диалога. Ну, попробуйте через тамшнюю возможность валидации имён сделать.


#9

А, как перед закрытием диалогового окна OpenFileDialog, скопировать выделенную область, к примеру имитацией нажатия клавиш (Ctrl + C) = SendKeys.Send("^{c}"); или SendKeys.SendWait("^{c}");


#10

Если пользователь не нажал ok - то, поидее, только имитацией нажатия клавишь. Только SendKeys кривовато работает часто, а в большинстве случаев не работает вообще. Лучше использовать keybd_event.

Но для начала попробуйте считывать результат переменной OpenFileDialog до того как он закрылся, в отдельном потоке.


#11

Ну с нажатием я разобрался

//..............................................................................................
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
        public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int extraInfo);

        [DllImport("user32.dll")]
        static extern short MapVirtualKey(int wCode, int wMapType);
        //..............................................................................................

        keybd_event((int)Keys.ControlKey, (byte)MapVirtualKey((int)Keys.ControlKey, 0), 0, 0); // Control Down

        keybd_event((int)Keys.С, (byte)MapVirtualKey((int)Keys.C, 0), 0, 0); // С Down
        keybd_event((int)Keys.С, (byte)MapVirtualKey((int)Keys.C, 0), 2, 0); // С Up

        keybd_event((int)Keys.ControlKey, (byte)MapVirtualKey((int)Keys.ControlKey, 0), 2, 0); // Control Up       
            //...........................................

Но как отработать, если фокус переносится на кнопку ??? как оставить фокус в окне выбора файлов?


#12

Ну так винда же не даст перевести фокус с окна выбора файла. А если вы про перенос фокуса на другую программу - через WinAPI можно как то получить дескриптор любого окна, в том числе окна выбора файла, и проверять, только если сейчас фокус на этом окне - только тогда посылать Ctrl+C.


#13

функция API DefWindowProc передает сообщения диалоговым окнам

  [DllImport("user32.dll")]
            static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);

Вопрос, как получить hWnd OpenFileDialog ?


#14

Есть какая то функция получающая дескриптор сфокусированного окна. И ещё 1, получающая дескриптор по заголовку окна. Но вообще пройдитесь лучше по всем, может что то ещё найдёте. Я находил когда то на msdn страницу со всеми WinAPI для окон.


#15
   точно!  

Для сравнения получения хендлов? ** Вариант_1: (хендл под курсором)**

//----------------------------------------

1) получаю любой хендл под курсором через: 
     Point p;//структура координат точек.
       if (GetCursorPos(out p))//возвращаю координаты курсора.
       {
        //узнать хендл по координатам курсора, под курсором.
         IntPtr ptr = WindowFromPoint(p);
//возвращаю хендлe контрола-элемента на форме ДАЖЕ на OpenFileDialog.
        return ptr;
        }

//---------------------------------------

То что сделал кроме сравнения на хендл:

  1. получаю хендл OpenDialoga через WinEventProc
  2. далее в хуке мыши отслеживаю нажатие и хендл контрола где находятся файлы в OpenFileDialog и по отпусканию кнопки произвожу имитацию нажатия (Cntrl+C).
  3. по нажатию на кнопку отпарвляю сообщение на закрытие окна и вставляю из буфера то что нужно. более того сообщением через SendMessage можно даже выделенные файлы с папками вставить в контрол выбранных файлов в самом OpenFileDialog еще при выделении до нажатия на кнопку ОК.

//---------------------------------------------------------------------

Вариант_2:(список хендлов контролов по хендлу окна контейнера этих контролов)

Дело в том, что бы произвести сравнение на хендл контрола из OpenFileDialog нужно иметь список всех хендлов. Так вот!, по координатам курсора хендлы отслеживаются все, очень хорошо!, а вот чтоб получить список хендлов я использовал FindWindowExW и по другому еще EnumChildWindows

НО! ни один из них не выдает все хендлы, так как выдает их WindowFromPoint, а именно хендл контрола в котором находятся файлы.

(кнопки, текстовые поля - выдают, а вот дерево и лист где файлы НЕТ!).

Думаю делаю что то не так, пока не выходит.

НО, сам принцип как это сделать я уже понял, без всякой противозаконной рефлексии по отношению к OpenFileDialog.

Если не отслеживать контрол где отображаются файлы, то по хуку мыши копирование производится везде и не всегда получается вставить из буфера обмена имена папок и файлов.

Нужно обязательно отслеживать область отображения файлов и папок и по хендлу это сделать легче всего, но нужен список хендлов для точного определения контрола.

Короче осталось дело за списком хендлов, для отслеживания контрола отображающего файлы и папки.

Не пойму почему FindWindowExW и EnumChildWindows выдают не полный список хендлов,

при этом WindowFromPoint выдает все как надо но он нужен по нажатию когда ужу происходит проверка.

Может кто знает как правильно получить целый список дочерних хендлов по хендлу диалогового окна…


#16

По вашему вызовы неуправляемых методов и особенно симуляция Ctrl+C - более законны?)) Но в любом случае

потому что

а рефлекцией можно доставать только управляемые значения.


Насчёт вопросов - вы явно уже далеко откопали, я тут уже не помогу. Но что я могу подсказать - так это то что для WinAPI на StackOverflow даже легче найти информацию чем для любой другой области в программировании. По крайней мере в англ версии.


#17

Есть еще вариант, выставить при открытии диалога курсор мыши строго по середине диалога, далее использовать выше упомянутую функцию WindowFromPoint() - считать хендел контрола содержащего файлы, а затем уже делать проверку. Но хотелось бы весь список, чтоб поменьше мышиной возни…)))


#18

немного втупил, не верно определил функцию в делегате(лишний параметр), и она каким то образом выдавала не все. доковырял я это дело…жуть…)))