При написании расширений оболочки контекстного меню мне нравится подход, состоящий в том, чтобы просто захватить список выбранных файлов, по которым пользователь щелкнул правой кнопкой мыши, и затем каким-то образом передать их внешней программе. Основная работа выполняется во внешней программе, которая имеет собственный графический интерфейс и выполняется в отдельном процессе. Код расширения оболочки просто передает список выбранных файлов во внешнюю программу.
(Мне кажется, что этому подходу следуют и другие утилиты, такие как 7-zip.)
Но можно ли создать, например, диалоговое окно непосредственно из расширения оболочки, внутри процесса Explorer? Насколько я понимаю, код в расширении оболочки должен пытаться делать как можно меньше вещей и возвращать элемент управления в Explorer, чтобы не зависать в процессе Explorer.
Если я создаю диалоговое окно внутри обработчика расширения оболочки (например, в моей реализации IContextMenu::InvokeCommand
) каков будет правильный подход?
Предполагая, что в диалоговом окне OnInitDialog()
Реализация я настраиваю GUI диалогового окна, я должен тогда вызвать что-то вроде DoMainWork()
, а внутри этого метода вставить цикл обработки сообщений?
например
// 1. Inside context-menu shell extension implementation
//
HRESULT CMyContextMenuShellExt::InvokeCommand(...)
{
...
// Build a GUI to process the selected files
CMyDialog dlg( ...pass the list of selected files to the dialog-box ... );
dlg.DoModal();
...
}
// 2. Inside CMyDialog class
//
LRESULT CMyDialog::OnInitDialog()
{
... prepare the GUI of the dialog-box
DoMainWork();
}
// 3. Inside CMyDialog::DoMainWork():
//
for (... loop to iterate over selected files ...) {
... do some processing for current file
// Process messages
// (including e.g. the pressing of a "Stop" button by the user)
MSG msg;
while (PeekMessage(&msg, m_hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Задача ещё не решена.
Других решений пока нет …