I've managed to implement this in Delphi 2010 by modifying Dialogs.pas as follows:
First, declare and implement the class 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;
Declare this string as a resource so it can be localized (if you care about that):
resourcestring
SReadOnly = 'Read only';
Then modify TFileOpenDialogWrapper.OnExecuteEvent
in two steps. First, add these variable declarations:
C: IFileDialogCustomize;
E: TFileOpenDialogWrapperReadOnlyEvent;
Cookie: Cardinal;
Then add this code at the end of the procedure:
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;
Copy the new Dialogs.pas to your source code folder and delete or rename the two Dialogs.dcu files in Delphi's Lib
folder. Recompile your app an ofHideReadOnly will work with Vista-style dialogs.
IFileDialogCustomize
interface on the new style dialogs. – mghie