Blog. Just Blog

Обработка Drag'n'Drop в разные поля ввода

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
В статье об обработке перетаскивания файлов я упомянул про раздельную обработку перетаскивания файлов в разные поля. В частности про вариант с субклассированием. Теперь расскажу, как это делается. Предположим, что у нас на форме есть три поля для выбора файла, причем каждое должно работать независимо.
  1.         ; Разрешить каждому полю принимать файлы
  2.         invoke  GetDlgItem,[hwnddlg],ID_FILE1
  3.         mov     ebx,eax
  4.         invoke  DragAcceptFiles,ebx,TRUE
  5.         ; Установить наш собственный обработчик
  6.         invoke  SetWindowLong,ebx,GWL_WNDPROC,EditWindowProc
  7.         ; Сохранить хэндл предыдущего обработчика
  8.         invoke  SetWindowLong,ebx,GWL_USERDATA,eax
  9.  
  10.         invoke  GetDlgItem,[hwnddlg],ID_FILE2
  11.         mov     ebx,eax
  12.         invoke  DragAcceptFiles,ebx,TRUE
  13.         ; Установить наш собственный обработчик
  14.         invoke  SetWindowLong,ebx,GWL_WNDPROC,EditWindowProc
  15.         ; Сохранить хэндл предыдущего обработчика
  16.         invoke  SetWindowLong,ebx,GWL_USERDATA,eax
  17.  
  18.         invoke  GetDlgItem,[hwnddlg],ID_FILE3
  19.         mov     ebx,eax
  20.         invoke  DragAcceptFiles,ebx,TRUE
  21.         ; Установить наш собственный обработчик
  22.         invoke  SetWindowLong,ebx,GWL_WNDPROC,EditWindowProc
  23.         ; Сохранить хэндл предыдущего обработчика
  24.         invoke  SetWindowLong,ebx,GWL_USERDATA,eax
На этапе инициализации окна надо при помощи функции DragAcceptFiles разрешить каждому полю ввода принимать файлы, а затем субклассировать их, чтобы обрабатывать сам момент броска.

Теперь обработчик. Про субклассирование во всех вариантах на этом сайте уже есть не меньше десятка статей, эта технология должна быть вам хорошо известна. При получении сообщения WM_DROPFILES вызываем DragQueryFile и узнаем имя переданного файла, а затем освобождаем задействованные ресурсы.
  1. ;------------------------------------------------------------------------
  2. ; Субклассированный обработчик полей ввода
  3. ;------------------------------------------------------------------------
  4. proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  5.         ; Перетаскивание файла?
  6.         cmp     [uMsg],WM_DROPFILES
  7.         je      .wm_drop
  8.  
  9.         ; Получить адрес предыдущего обработчика
  10.         invoke  GetWindowLong,[hEdit],GWL_USERDATA
  11.         ; Передать управление предыдущему обработчику
  12.         invoke  CallWindowProc,eax,[hEdit],[uMsg],[wParam],[lParam]
  13.         ret
  14. .wm_drop:
  15.         ; Принять файл
  16.         invoke  DragQueryFile,[wParam],0,fname,100h
  17.         invoke  SetWindowText,[hEdit],fname
  18.  
  19.         ; Освободить дескриптор операции
  20.         invoke  DragFinish,[wParam]
  21.  
  22.         xor     eax,eax
  23.         ret
  24. endp
По просьбам трудящихся разберу еще и вариант с координатами. Тут никакого субклассирования делать не надо, разрешение принимать файлы назначается главному окну. При поступлении сообщения WM_DROPFILES поочередно проверяем вхождение точки броска на предмет принадлежности тому или иному полю выбора файла.
  1. section '.data' data readable writeable
  2.  
  3. pt       POINT
  4. pos      RECT
  5.          ...
  6.          ...
  7.  
  8. section '.code' code readable executable
  9.         ...
  10.         ; Принять файл
  11.         invoke  DragQueryFile,[wparam],0,fname,MAX_PATH
  12.  
  13.         ; Получить координаты операции
  14.         invoke  DragQueryPoint,[wparam],pt
  15.  
  16.         ; Проверить по координатам элемента окна
  17.         invoke  GetDlgItem,[hwnddlg],ID_FILE1
  18.         invoke  GetWindowRect,eax,pos
  19.         invoke  MapWindowPoints,HWND_DESKTOP,[hwnddlg],pos,2
  20.         invoke  PtInRect,pos,[pt.x],[pt.y]
  21.         or      eax,eax
  22.         jz      @f
  23.         invoke  SetDlgItemText,[hwnddlg],ID_FILE1,fname
  24.         jmp     loc_done
  25. @@:
  26.         invoke  GetDlgItem,[hwnddlg],ID_FILE2
  27.         invoke  GetWindowRect,eax,pos
  28.         invoke  MapWindowPoints,HWND_DESKTOP,[hwnddlg],pos,2
  29.         invoke  PtInRect,pos,[pt.x],[pt.y]
  30.         or      eax,eax
  31.         jz      @f
  32.         invoke  SetDlgItemText,[hwnddlg],ID_FILE2,fname
  33.         jmp     loc_done
  34. @@:
  35.         invoke  GetDlgItem,[hwnddlg],ID_FILE3
  36.         invoke  GetWindowRect,eax,pos
  37.         invoke  MapWindowPoints,HWND_DESKTOP,[hwnddlg],pos,2
  38.         invoke  PtInRect,pos,[pt.x],[pt.y]
  39.         or      eax,eax
  40.         jz      @f
  41.         invoke  SetDlgItemText,[hwnddlg],ID_FILE3,fname
  42. @@:
  43.  
  44. loc_done:
  45.         ; Освободить дескриптор операции
  46.         invoke  DragFinish,[wparam]
  47.         ...
Плюсы такого способа в том, что приемник не обязательно должен быть полем EDIT, это может быть кнопка, картинка, какой-нибудь STATIC или вообще произвольная область окна, оформленная как угодно. Существенных минусов такого способа выделить не могу, пожалуй только эстетические, что курсор меняется сразу при заходе на форму, а не на конкретное поле-приемник. Но это так, придирки.

В приложении примеры программ с исходными текстами, которые могут принимать файлы через Drag'n'Drop описанными в статье способами в три независимых поля ввода.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Multiple.Drag.n.Drop.Demo.zip (4,900 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 648 | Комментариев: 3

Метки: Assembler, окна
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Сергей Озеров (16.05.2022 в 11:59):
Только увидел Ваш ответ, огромное спасибо!
ManHunter (02.04.2022 в 16:58):
Да можно, конечно. Добавил способ с координатами, архив обновлен.
Сергей Озеров (02.04.2022 в 16:26):
Как всегда спасибо за полезный код. А можно пример с координатами?Извините я еще учусь ))

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0049 сек.) / Память: 4.5 Mb
Наверх