2012-06-04 25 views
2

我可以使用FileSaveDialog1.Dialog.QueryInterface創建一個按鈕,如下所示。如何設置和處理OnPushButton單擊事件,以便我可以響應按鈕單擊?添加IFileDialogCustomize PushButton事件

procedure TForm1.FileSaveDialog1Execute(Sender: TObject); 
const 
    dwVisualGroup1ID: DWORD = 1900; 
var 
    c: IFileDialogCustomize; 
    d: IFileDialogControlEvents; 
begin 
    if FileSaveDialog1.Dialog.QueryInterface(IFileDialogCustomize, c) = S_OK then 
    begin 
    // Add a Advanced Button 
    c.AddPushButton(dwVisualGroup1ID, 'Advanced'); 
    c.MakeProminent(dwVisualGroup1ID); 
    // Setup the PushButton Click event? 

    end; 

回答

7

罰款,我下面的作品XE2:

type 
    TMyFileDialogEvents = class(TInterfacedObject, IFileDialogEvents, IFileDialogControlEvents) 
    public 
    { IFileDialogEvents } 
    function OnFileOk(const pfd: IFileDialog): HResult; stdcall; 
    function OnFolderChanging(const pfd: IFileDialog; 
     const psiFolder: IShellItem): HResult; stdcall; 
    function OnFolderChange(const pfd: IFileDialog): HResult; stdcall; 
    function OnSelectionChange(const pfd: IFileDialog): HResult; stdcall; 
    function OnShareViolation(const pfd: IFileDialog; const psi: IShellItem; 
     out pResponse: DWORD): HResult; stdcall; 
    function OnTypeChange(const pfd: IFileDialog): HResult; stdcall; 
    function OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; 
     out pResponse: DWORD): HResult; stdcall; 
    { IFileDialogControlEvents } 
    function OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; 
     dwIDItem: DWORD): HResult; stdcall; 
    function OnButtonClicked(const pfdc: IFileDialogCustomize; 
     dwIDCtl: DWORD): HResult; stdcall; 
    function OnCheckButtonToggled(const pfdc: IFileDialogCustomize; 
     dwIDCtl: DWORD; bChecked: BOOL): HResult; stdcall; 
    function OnControlActivating(const pfdc: IFileDialogCustomize; 
     dwIDCtl: DWORD): HResult; stdcall; 
    end; 

const 
    dwVisualGroup1ID: DWORD = 1900; 

function TMyFileDialogEvents.OnFileOk(const pfd: IFileDialog): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnFolderChange(const pfd: IFileDialog): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnFolderChanging(const pfd: IFileDialog; 
    const psiFolder: IShellItem): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnOverwrite(const pfd: IFileDialog; 
    const psi: IShellItem; out pResponse: DWORD): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnSelectionChange(const pfd: IFileDialog): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnShareViolation(const pfd: IFileDialog; 
    const psi: IShellItem; out pResponse: DWORD): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnTypeChange(const pfd: IFileDialog): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; dwIDItem: DWORD): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult; 
begin 
    if dwIDCtl = dwVisualGroup1ID then begin 
    // ... 
    Result := S_OK; 
    end else begin 
    Result := E_NOTIMPL; 
    end; 
end; 

function TMyFileDialogEvents.OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; bChecked: BOOL): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

function TMyFileDialogEvents.OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

var 
    FileDialog: IFileDialog = nil; 
    MyEvents: IFileDialogEvents = nil; 
    MyEventsCookie: DWORD = 0; 

procedure TForm1.FileSaveDialog1Execute(Sender: TObject); 
var 
    c: IFileDialogCustomize; 
    d: IFileDialogEvents; 
    cookie: DWORD; 
begin 
    if Supports(FileSaveDialog1.Dialog, IFileDialogCustomize, c) then 
    begin 
    // Add a Advanced Button 
    c.AddPushButton(dwVisualGroup1ID, 'Advanced'); 
    c.MakeProminent(dwVisualGroup1ID); 

    // Setup the PushButton Click event 
    d := TMyFileDialogEvents.Create; 
    if Succeeded(FileSaveDialog1.Dialog.Advise(d, cookie)) then 
    begin 
     FileDialog := FileSaveDialog1.Dialog 
     MyEvents := d; 
     MyEventsCookie := cookie; 
    end; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Ok: Boolean; 
begin 
    FileDialog := nil; 
    MyEvents := nil; 
    MyEventsCookie := 0; 

    try 
    Ok := FileSaveDialog1.Execute; 
    finally 
    if (FileDialog <> nil) and (MyEventsCookie <> 0) then 
     FileDialog.Unadvise(MyEventsCookie); 
    FileDialog := nil; 
    MyEvents := nil; 
    MyEventsCookie := 0; 
    end; 

    if Ok then ... 
end; 
+0

謝謝你..事件執行得很好。我應該調用FileSaveDialog1.Dialog.Unadvise()嗎? – Bill

+0

微軟確實表示你應該調用'Unadvise()'。但是,要使用'TFileSaveDialog'來實現這一點,您必須在'OnExecute'事件中保存對'TFileSaveDialog.Dialog'接口的引用,以便在Execute()退出時不會釋放對話框。然後你可以'Unadvise()'你的處理程序並釋放你的參考來完成釋放對話。我會更新我的答案以表明這一點。 –

+0

@MasonWheeler我無法想象我爲什麼寫這些。文件很清楚。我刪除了評論。 –

2

您需要實現IFileDialogControlEvents。然後調用IFileDialog.Advise傳遞你的IFileDialogControlEvents接口。當按鈕被點擊時,你的IFileDialogControlEvents.OnButtonClicked方法將被調用。

+1

你可以顯示一些代碼來做到這一點? – Bill

+2

不,我不能。你可以自己休息。在這一點上,你有你需要的一切。你現在知道所有相關的接口和方法。使用MSDN文檔填寫詳細信息。 –

+0

你如何設置事件類? 類型 TTestEvent = class(TInterfacedObject,IFileDialogEvents,IFileDialogControlEvents) function OnButtonClicked(pfdc:cardinal; dwIDCtl:cardinal):HResult; – Bill