Перетащите файлы / текст на иконку в трее (C #, WindowsForms) - PullRequest
5 голосов
/ 13 октября 2010

Я пытаюсь разрешить перетаскивание на иконку в трее в моем приложении.

Я знаю, что невозможно сделать это с C # WindowsForms API более высокого уровня, так как NotifyIconне поддерживает события перетаскивания.

Итак, с небольшой помощью более опытного друга из Windows, я решил попробовать это через Win32 API.Идея заключалась в том, чтобы зарегистрировать зацепку в обработчике окна лотка (после установки DragAcceptFiles(hWnd,TRUE); в обработчике окна "SysPager").

Часть перехвата и отбрасывания работает из лотка в DLL.

LRESULT CALLBACK myHookProc (int code, WPARAM wParam, LPARAM lParam){
  if (code == HC_ACTION)
  {
    PMSG msg = (PMSG) lParam;
    switch(msg->message){
      case WM_DROPFILES:
        ::MessageBox(NULL, L"Dropped files!", L"Test", MB_OK);
        // call my app's registered hook
        break;
  }
  return CallNextHookEx(oldHookProc, code, wParam, lParam);
}

Как и ожидалось, я получаю всплывающее окно с сообщением.

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

Когда я регистрирую обратный вызов из моего приложения в DLL, я сохраняю его;но когда вызывается myHookProc, его значение равно NULL.

Оказывается, я неправильно понял, как работают библиотеки DLL;между моим приложением и областью трея нет общего экземпляра (они скопированы или у каждого есть свой «экземпляр», если можно так его назвать), поэтому я не могу использовать статические переменные или что-то подобное для храненияобратная ссылка обратная связь с моим приложением.

Потратил пару часов, исследуя это, и единственным решением, похоже, была общая память (пробовал #pragma data_seg, с которым я столкнулся на каком-то форуме, но безрезультатно), ноначинает чувствовать себя слишком излишним для такого «простого» варианта использования.

Итак, вопросы на миллион долларов:

  1. Действительно ли необходимо снять перехват подключения к DLL?
  2. Мне действительно нужно прибегать к общей памяти для достижения этой цели?
  3. (Бонусный вопрос) WM_DROPFILES работает только для файлов;как получить событие drop для текста?

Пожалуйста, имейте в виду, что это мой первый снимок с .NET, C # и Win32 (менее недели);подробные ответы, объясняющие, почему - а не просто констатация - будут с благодарностью приняты

Спасибо.

1 Ответ

3 голосов
/ 13 октября 2010

Да, вам действительно нужно делать эти вещи, потому что окно принадлежит другому процессу.Глобальные хуки требуют DLL, которая может быть введена.Полная поддержка D + D требует RegisterDragDrop и COM-кода.Icky COM code.

И нет, вам действительно не следует этого делать, потому что кто-то другой мог уже иметь ту же идею, что и вы.И его программа была отправлена ​​первой.У команды appcompat в MSFT должен быть кошмар.Осторожнее с Рэймондом Ченом, у него плохой характер.

...