c++ - 以编程方式从没有 UI 对话框的 Windows 回收站中删除项目
问题描述
我正在使用IContextMenu
with"delete"
动词从回收站中删除项目,但即使我使用CMIC_MASK_FLAG_NO_UI
标志,它也会显示 UI 对话框。是否有另一种方法可以在不显示对话框的情况下从回收站中删除文件?
IContextMenu* contextMenu;
recycleBin->GetUIObjectOf(0, 1, (LPCITEMIDLIST*)(&pidl), IID_IContextMenu, 0, (LPVOID *)&contextMenu);
CMINVOKECOMMANDINFO ci;
memset(&ci, 0, sizeof(ci));
ci.fMask = CMIC_MASK_FLAG_NO_UI;
ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
ci.lpVerb = "delete";
contextMenu->InvokeCommand(&ci);
contextMenu->Release();
包括回收站对象初始化和项目枚举的完整代码在要点上
解决方案
您可以安装WH_CBT挂钩,并在其回调中监视HCBT_CREATEWND
. 如果你得到一个匹配的类名('#32770 (Dialog)' ?)和一个匹配的标题或者从回调中返回一个非零值,你可以发送BM_CLICK到单击Yes
按钮,对话框将自动关闭。
代码示例:
主文件
#include <iostream>
#include <windows.h>
#include <Ole2.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <string>
#pragma comment(lib,"Shlwapi.lib")
HHOOK g_hhook;
int main()
{
OleInitialize(0);
HINSTANCE hinstDLL = LoadLibrary(TEXT("D:\\xxx\\Dll_WH_CBT\\Debug\\Dll_WH_CBT.dll"));
HHOOK(*AttachHookProc)(DWORD);
AttachHookProc = (HHOOK(*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook");
void(*RemoveHooks)(DWORD);
RemoveHooks = (void(*)(DWORD))GetProcAddress(hinstDLL, "RemoveHooks");
IShellFolder* desktop;
if (FAILED(SHGetDesktopFolder(&desktop))) {
std::cerr << "Failed to get desktop fodler" << std::endl;
return -1;
}
...
IEnumIDList* enumFiles;
if (FAILED(recycleBin->EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS |
SHCONTF_INCLUDEHIDDEN, &enumFiles)))
{
std::cerr << "Could not enumerate recycle bin objects" << std::endl;
recycleBin->Release();
return -1;
}
AttachHookProc(0);
...
RemoveHooks(0);
enumFiles->Release();
recycleBin->Release();
OleUninitialize();
return 0;
}
DLL:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
HMODULE thisModule;
HHOOK g_hhook;
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
switch (nCode)
{
case HCBT_CREATEWND:
{
HWND File_Window = FindWindow(L"#32770", L"Delete File");
HWND Folder_Window = FindWindow(L"#32770", L"Delete Folder");
if (File_Window)
{
HWND yes = FindWindowEx(File_Window, NULL, L"Button", L"&Yes");
SendMessage(yes, BM_CLICK, 0, 0);
SendMessage(yes, BM_CLICK, 0, 0);
}
if (Folder_Window)
{
HWND yes = FindWindowEx(Folder_Window, NULL, L"Button", L"&Yes");
SendMessage(yes, BM_CLICK, 0, 0);
SendMessage(yes, BM_CLICK, 0, 0);
}
break;
}
default:
break;
}
return CallNextHookEx(g_hhook, nCode, wParam, lParam);
}
#ifdef __cplusplus //If used by C++ code.
extern "C" { //we need to export the C interface
#endif
_declspec(dllexport) HHOOK AttachHook(DWORD threadID) {
g_hhook = SetWindowsHookEx(WH_CBT, CBTProc, thisModule, threadID);
return g_hhook;
}
#ifdef __cplusplus
}
#endif
extern "C" { //we need to export the C interface
__declspec(dllexport) void RemoveHooks(DWORD)
{
UnhookWindowsHookEx(g_hhook);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
thisModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
推荐阅读
- react-select - react-select:如何将 optionRenderer 属性与 Async 组件一起使用?
- android - 我们可以构建 Kotin 和 Java Mix 应用程序吗?
- javascript - 如何在angularjs中连接api输入
- javascript - 在对函数的调用中调用函数
- scala - 如何在 Spark Scala 的 UDF 中将列作为值传递以检查条件
- spring-boot - Spring Boot 的应用程序洞察配置不起作用
- angularjs - 如何使用 Angular.js 在 Web 浏览器中检索指纹设备的数据
- linear-programming - Lpsolve 矩阵中的舍入
- html - 输入类型=“文本”默认值不能在 reactjs 中更改
- powershell - 随 foreach 的每个循环递增的动态变量名称