Making ofHideReadOnly仅适用于UseLatestCommonDialogs
问题描述:
在Delphi 2007及更高版本中,全局变量UseLatestCommonDialogs
导致TOpenDialog
在Windows Vista和7上使用新的Vista风格的对话框。这很酷。Making ofHideReadOnly仅适用于UseLatestCommonDialogs
不幸的是,Vista风格的对话框似乎不支持TOpenDialog的ofHideReadOnly
选项。无论此选项设置为True还是False,只读复选框都不会显示。
如何让TOpenDialog在Vista风格的对话框中显示一个只读复选框?
因为这打破向后兼容性,我报这个bug:QC 83606德尔福2006年应用程序时无需改动用Delphi 2007,2009年或2010并编写了拥有ofHideReadOnly设置为False将失去其只读复选框在Windows Vista上运行,或7
答
我已经成功通过修改Dialogs.pas实现这个在2010年德尔福如下:
首先,声明和实现类TFileOpenDialogWrapperReadOnlyEvent
:
{ TFileOpenDialogWrapperReadOnlyEvent }
type
TFileOpenDialogWrapperReadOnlyEvent = class(TInterfacedObject, IFileDialogEvents, IFileDialogControlEvents)
private
FOpenDialog: TOpenDialog;
public
function OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT; stdcall;
function OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal; bChecked: LongBool): HRESULT; stdcall;
function OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT; stdcall;
function OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal; dwIDItem: Cardinal): HRESULT; stdcall;
function OnFileOk(const pfd: IFileDialog): HRESULT; stdcall;
function OnFolderChange(const pfd: IFileDialog): HRESULT; stdcall;
function OnFolderChanging(const pfd: IFileDialog; const psiFolder: IShellItem): HRESULT; stdcall;
function OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT; stdcall;
function OnSelectionChange(const pfd: IFileDialog): HRESULT; stdcall;
function OnShareViolation(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT; stdcall;
function OnTypeChange(const pfd: IFileDialog): HRESULT; stdcall;
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal; bChecked: LongBool): HRESULT;
begin
if bChecked then FOpenDialog.Options := FOpenDialog.Options + [ofReadOnly]
else FOpenDialog.Options := FOpenDialog.Options - [ofReadOnly];
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnFileOk(const pfd: IFileDialog): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnFolderChange(const pfd: IFileDialog): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnFolderChanging(const pfd: IFileDialog; const psiFolder: IShellItem): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl, dwIDItem: Cardinal): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnSelectionChange(const pfd: IFileDialog): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnShareViolation(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT;
begin
Result := S_OK
end;
function TFileOpenDialogWrapperReadOnlyEvent.OnTypeChange(const pfd: IFileDialog): HRESULT;
begin
Result := S_OK
end;
声明这个字符串作为资源,因此它可以是局部的(如果你在乎那):
resourcestring
SReadOnly = 'Read only';
分两步然后修改TFileOpenDialogWrapper.OnExecuteEvent
。首先,添加这些变量声明:
C: IFileDialogCustomize;
E: TFileOpenDialogWrapperReadOnlyEvent;
Cookie: Cardinal;
然后在过程结束时添加以下代码:
if not (ofHideReadOnly in FOpenDialog.Options) then begin
if FFileDialog.Dialog.QueryInterface(IFileDialogCustomize, C) = S_OK then begin
C.AddCheckButton(1, PChar(SReadOnly), ofReadOnly in FOpenDialog.Options);
E := TFileOpenDialogWrapperReadOnlyEvent.Create;
E.FOpenDialog := FOpenDialog;
FFileDialog.Dialog.Advise(E, Cookie);
end;
end;
复制新Dialogs.pas到源代码文件夹,删除或重命名这两个对话框.dcu文件在Delphi的Lib
文件夹中。重新编译你的应用程序,只有HideReadOnly将与Vista风格的对话框一起工作。
相关问题:http://stackoverflow.com/questions/1076827/file-open-dialog-with-encodings-combobox-under-vista。做任何事情,VCL不支持OOTB需要在新样式对话框中使用IFileDialogCustomize接口。 – mghie 2010-03-27 11:04:55