Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971

Как программно эмулировать Drag&drop файла на окно стороннего приложения

11.09.2012, 02:52. Показов 2809. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
ну собственно вопрос в названии
к окну никакого отношения не имею и оно не на net, просто найдено среди процессов

я думаю это какой нибудь PostMessage, но что туда передавать?
нашел что-то про WM_DROPFILES, но везде пишут про прием файла переданного обычным образом
не знаю даже за что зацепиться чтоб яндексить дальше

зачем
хочу сделать свою продвинутую автозагрзку внешних субтитров для видео проигрывателя, ничего кроме этого не придумал.
обычные средства не загружают из отдельных папок с левыми названиями типа группы переводчиков и т.д
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.09.2012, 02:52
Ответы с готовыми решениями:

Drag&Drop
Требуется сделать так, чтобы при перетаскивании файла в текстбокс, в этом текстбоксе появлялся полный путь этого файла, как это можно...

Drag&Drop
Уважаемые коллеги, есть такая задача, на форму кидают файл, мне нужно получить его полное имя (путь и имя файла). Как узнать что это файл,...

Drag&Drop картинки
как сделать чтобы при перетаскивании картинки (например из мозилы), она сохранялась в переменную Image?

4
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8725 / 3677 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
12.09.2012, 01:03
Лучший ответ Сообщение было отмечено как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        const uint WM_DROPFILES = 0x233;
 
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        static extern int PostMessage (
            [In] IntPtr hWnd,
            [In] uint Msg,
            [In] IntPtr wParam,
            [In] IntPtr lParam
            );
 
        const uint GHND = 0x42;
 
        [DllImport( "kernel32.dll", SetLastError = true )]
        static extern IntPtr GlobalAlloc (
            [In] uint uFlags,
            [In] int dwBytes // for x86
            // [In] long dwBytes // for x64
            );
 
        [DllImport( "kernel32.dll", SetLastError = true )]
        static extern IntPtr GlobalFree (
            [In] IntPtr hMem
            );
 
        [DllImport( "kernel32.dll", SetLastError = true )]
        static extern IntPtr GlobalLock (
            [In] IntPtr hMem
            );
 
        [DllImport( "kernel32.dll", SetLastError = true )]
        [return: MarshalAs( UnmanagedType.Bool )]
        static extern bool GlobalUnlock (
            [In] IntPtr hMem
            );
 
        [DllImport( "kernel32.dll", SetLastError = true )]
        static extern int GlobalSize (
            [In] IntPtr hMem
            );
 
        [DllImport( "Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        unsafe static extern int DragQueryFile (
            [In] IntPtr hDrop,
            [In] int iFile,
            [Out] StringBuilder lpszFile,
            [In] int cch
            );
 
        [DllImport( "ntdll.dll", CallingConvention = CallingConvention.Cdecl )]
        unsafe static extern void* memcpy (
            [In] void* destination,
            [In] void* source,
            [In] int num // for x86
            // [In] long num // for x64
            );
 
        [StructLayout( LayoutKind.Sequential, Pack = 4 /* x86 */ )]
        struct DROPFILES
        {
            public int pFiles;
            public long pt;
            public int fNC;
            public int fWide;
        }
 
        unsafe IntPtr GetDropFilesPtr ( string[] files )
        {
            int memAllocSize = 0; // in bytes
            var dropFiles    = new DROPFILES();
            var pMem         = IntPtr.Zero;
            var pLockedMem   = IntPtr.Zero;
            var ptr          = (byte*)0;
 
            dropFiles.fWide = 1;
            dropFiles.pFiles = Marshal.SizeOf( dropFiles );
 
            for ( int i = 0; i < files.Length; ++i )
                memAllocSize += (files[i].Length * 2) + 2 /* \0\0 */;
            memAllocSize += 2; // \0\0
            memAllocSize += dropFiles.pFiles;
 
            pMem = GlobalAlloc( GHND, memAllocSize );
            pLockedMem = GlobalLock( pMem );
            {
                // copy files names to unmanaged mem
                *(DROPFILES*)(void*)pLockedMem = dropFiles;
                ptr = (byte*)pLockedMem + dropFiles.pFiles;
 
                for ( int i = 0; i < files.Length; ++i )
                {
                    int count = files[i].Length * 2;
                    fixed ( char* pBuff = files[i] )
                        memcpy( ptr, pBuff, count );
                    ptr += count + 2;
                }
            }
 
            if ( !GlobalUnlock( pMem ) && Marshal.GetLastWin32Error() != 0 )
            {
                GlobalFree( pMem );
                pMem = IntPtr.Zero;
            }
 
            return pMem;
        }
 
        unsafe private void button1_Click ( object sender, EventArgs e )
        {
            var ptr = GetDropFilesPtr(
                new string[] {
                    @"E:\Downloads\Video\SomeVideoFile.mkv"
                } );
            //var pointer = GlobalLock( ptr );
            var ret = PostMessage( (IntPtr)0x000E06F0 /* Main MPC window */, WM_DROPFILES, ptr, IntPtr.Zero );
            //var sb = new StringBuilder( 256 );
            //var sz = DragQueryFile( pointer, 0, sb, sb.Capacity );
            //GlobalUnlock( pointer );
            System.Threading.Thread.Sleep( 100 );
            GlobalFree( ptr );
            ...
Проверял на MediaPlayerClassic, на x86 процессе.

Не по теме:

p.s. Во время написания кода было обнаружено странное поведение CLR при маршалинге структуры DROPFILES: если использовать тип bool (с атрибутом MarshalAs или без него) для полей fNC и fWide, то происходило некорректное изменение значений в памяти, вместо нужного 01 00 00 00 01 00 00 00 было 01 01 00 00 00 00 00 00 (под bool выделялось 4 байта), из-за этого некорректно отрабатывала DragQueryFile (строка воспринималась в ANSI кодировке).
Если кто знает причину такого поведения - прошу высказаться. (Заниматься исследованием вопроса сейчас нет ни времени, ни желания).

ADD: как вариант можно использовать FieldOffset, тогда всё ок. Если использовать просто bool тогда генерируются неправильные инструкции для данных полей, значения меняются в соседних ячейках памяти...

1
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
12.09.2012, 02:01  [ТС]
офигенно, оно работает
ток пришлось добавить CallingConvention.Cdecl для memcpy, иначе он разбалансировал стек

p/s если кто потом использовать надумает - передавайте в PostMessage хендл контрола, а не окна, взять его можно в spy++
1
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8725 / 3677 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
12.09.2012, 02:08
Цитата Сообщение от m0nax Посмотреть сообщение
ток пришлось добавить CallingConvention.Cdecl для memcpy, иначе он разбалансировал стек
Да, забыл Поправил.
0
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
12.09.2012, 02:31  [ТС]
p/s если кто потом использовать надумает - передавайте в PostMessage хендл контрола, а не окна, взять его можно в spy++
это я погорячился, передавать как раз хендл окна либо контрола, не хендл процесса главное, короче process.MainWindowHandle сработал и пока что все обошлось без поиска конкретных контролов в окне
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.09.2012, 02:31
Помогаю со студенческими работами здесь

drag&drop из внешних приложений
привет. собственно как сделать сабж? например из проводника? у меня есть imageview, как перенести туда файл? заранее спасибо.

Drag & Drop динамически созданных объектов
Научите пожалуйста как осуществить сабж, в разделе для новичков не помогли Создаю в flowLayoutPanel1, нужно выборочно перетаскивать в...

Как проверить открыто ли окно стороннего приложения?
Я не знаю как написать программу, которая бы проверяла (т.е. if окно в фокусе then), помогите, мне очень срочно это нужно, никогда раньше с...

Вывод текста в окно стороннего приложения
Подскажите есть игра и в ней нужно по координатам вывести текст или что нибудь нарисовать. Какими способами это можно сделать?

Клик в свернутое окно стороннего приложения
Вообщем, мне нужно сделать клик в форму которая свернутая. Например Skype. Он у меня свернутый а мне нужно нажать на кнопку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru