在编写上下文菜单 shell 扩展时,我喜欢捕获用户右键单击的选定文件列表,然后以某种方式将它们传递给外部程序的方法。主要工作在外部程序中完成,它有自己的 GUI,并在单独的进程中运行。shell 扩展代码只是将选定文件的列表传递给外部程序。
(在我看来,其他实用程序也遵循这种方法,例如 7-zip。)
但是是否有可能直接从 shell 扩展内部、Explorer 进程内部创建一个对话框?我的理解是shell扩展中的代码应该尽量少做一些事情,并将控制权返回给资源管理器,而不是挂起资源管理器进程。
如果我在外壳扩展处理程序中创建一个对话框(例如在我的实现中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);
}
}