2012-06-04 27 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