我正在开发一个Windows 7应用程序,它必须阻止WinDVD在插入时触发新的磁盘可用性(即插入DVD)。
背景资料:
我正在为一家公司制作这个小应用程序,该公司必须同时比较两个电影播放器同时播放来自不同驱动器的相同DVD。
他们正在进行启发式质量测试,以确定目前最好的DVD播放器将其捆绑到新的PC系列中。
目前他们的最佳选择似乎是WinDVD,因此必须对其进行所有其他测试。问题是,当他们插入第一张DVD时,默认播放器WinDVD就可以了。
然后当他们插入第二张光盘时,默认播放器首先响应,因此他们被迫关闭窗口并打开他们正在测试的其他播放器。
这是针对许多电影所做的,这些电影代表了它们的参考,以发现颜色渲染和图像质量。用户在显示时关闭附加窗口变得乏味,因为此操作将每周重复数百次。
我的程序试图禁止默认播放器的第二次响应
我想拦截WM_DEVICECHANGE消息以某种方式为它创建一个全局钩子。
问题是,拦截WM_DEVICECHANGE非常有效,但它不会阻止WinDVD触发新单元插入的能力,显然让消息无论如何都要传递。因此我开始考虑如何防止在拦截后调度该消息。
为了实现这个我想到的全局钩子,我正在使用这行代码:
CurrentHook:=setwindowshookex(WH_CALLWNDPROC,HookProcAdd,LibHandle,0);
链接到我的DLL中包含的回调,我可以看到WM_DEVICECHANGE被正确拦截,但正如我所说,消息仍然被分派到整个系统。
任何建议都表示赞赏。
@TOndrej: 我尝试过以下内容:
var
rlen : DWORD;
pRelen : ^DWORD;
h : THandle;
val : Boolean;
pVal: ^Boolean;
res : Boolean;
begin
rlen := 0;
val := True;
pVal := @val;
pRelen := @val;
h := CreateFile(PChar('\\.\d:'), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
OPEN_EXISTING, 0, 0);
if h <> INVALID_HANDLE_VALUE then
begin
res:= DeviceIoControl(h,
IOCTL_STORAGE_MCN_CONTROL,
pVal,
SizeOf(val),
nil,
0,
rlen,
nil);
if not res then
begin
ShowMessage('Error');
end;
CloseHandle(h);
end;
end;
但每次res都是假的。我错过了什么?
答案 0 :(得分:2)
对于IOCTL_STORAGE_MCN_CONTROL控制代码,必须使用FILE_READ_ATTRIBUTES访问权限打开文件:
var
rlen: DWORD;
pVal: PBOOL;
res: BOOL;
begin
rlen := 0;
GetMem(PVal,SizeOf(BOOL));
pVal^ := TRUE;
h := CreateFile(PChar('\\.\D:'),
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ OR FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
if h <> INVALID_HANDLE_VALUE then
begin
res:= DeviceIoControl(h,
IOCTL_STORAGE_MCN_CONTROL,
pVal,
SizeOf(BOOL),
nil,
0,
rlen,
nil);
if not res then
begin
ShowMessage('Error');
end else
begin
ShowMessage('Device Notification Disabled');
end;
// close file handle
CloseHandle(h);
// After CloseHandle, file notification is restored...
end;
end;
在我的测试中,在CloseHandle之后,设备通知已恢复...
答案 1 :(得分:1)
处理此问题的正确,官方和记录的方法是suppress AutoRun programmably。如果您的应用不在前台接收"QueryCancelAutoPlay"
消息,则您的全局挂钩应该能够在不发送消息的情况下响应消息。
答案 2 :(得分:0)
为什么不通过设置注册表项HKLM\System\CurrentControlSet\Services\CDRom
来禁用CD自动运行功能,并将键Autorun
设置为0
而不是1
?
客户必须单独启动每个应用程序,或者选择“open with ...”选项,但这应该非常适合基准测试。根据您的描述,他们正在测试运行时性能和播放质量,而不是自动运行功能。