2010-03-27 97 views
1

在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

+1

相關問題:http://stackoverflow.com/questions/1076827/file-open-dialog-with-encodings-combobox-under-vista。做任何事情,VCL不支持OOTB需要在新樣式對話框中使用IFileDialogCustomize接口。 – mghie 2010-03-27 11:04:55

回答

1

我已經成功通過修改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風格的對話框一起工作。