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

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

11.09.2012, 02:52. Показов 2834. Ответов 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
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru