gpt4 book ai didi

Delphi 7 和 Vista/Windows 7 通用对话框 - 事件不起作用

转载 作者:行者123 更新时间:2023-12-03 14:41:48 26 4
gpt4 key购买 nike

我正在尝试修改 Delphi 7 Dialogs.pas 以访问较新的 Windows 7 打开/保存对话框(请参阅使用 Delphi 创建 Windows Vista 就绪应用程序)。我可以使用建议的修改来显示对话框;但是,OnFolderChange 和 OnCanClose 等事件不再起作用。

这似乎与将 Flags:= OFN_ENABLEHOOK 更改为 Flags:=0 有关。当 Flags 设置为 0 时,TOpenDialog.Wndproc 将被绕过,并且不会捕获相应的 CDN_xxxxxxx 消息。

任何人都可以建议对 D7 Dialogs.pas 进行进一步的代码修改,以显示较新的通用对话框并保留原始控件的事件功能吗?

谢谢...

最佳答案

您应该使用IFileDialog Interface并使用 IFileDialogEvents Interface 的实现调用其 Advise() 方法。 Delphi 7 Windows header 单元不会包含必要的声明,因此必须从 SDK header 文件复制(并翻译)它们(或者可能已经有另一个可用的 header 翻译?),但除了额外的工作之外,不应该有从 Delphi 7(甚至更早的 Delphi 版本)调用它不会有任何问题。

编辑:

好的,既然您对答案没有任何反应,我将添加更多信息。关于如何使用接口(interface)的 C 示例可以在 here 中找到。 。只要您有必要的导入单元,就可以轻松地将其转换为 Delphi 代码。

我在 Delphi 4 中拼凑了一个小示例。为了简单起见,我创建了一个 TOpenDialog 后代(您可能会修改原始类)并直接在其上实现 IFileDialogEvents :

type
TVistaOpenDialog = class(TOpenDialog, IFileDialogEvents)
private
// IFileDialogEvents implementation
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;
public
function Execute: Boolean; override;
end;

function TVistaOpenDialog.Execute: Boolean;
var
guid: TGUID;
Ifd: IFileDialog;
hr: HRESULT;
Cookie: Cardinal;
Isi: IShellItem;
pWc: PWideChar;
s: WideString;
begin
CLSIDFromString(SID_IFileDialog, guid);
hr := CoCreateInstance(CLSID_FileOpenDialog, nil, CLSCTX_INPROC_SERVER,
guid, Ifd);
if Succeeded(hr) then begin
Ifd.Advise(Self, Cookie);
// call DisableTaskWindows() etc.
// see implementation of Application.MessageBox()
try
hr := Ifd.Show(Application.Handle);
finally
// call EnableTaskWindows() etc.
// see implementation of Application.MessageBox()
end;
Ifd.Unadvise(Cookie);
if Succeeded(hr) then begin
hr := Ifd.GetResult(Isi);
if Succeeded(hr) then begin
Assert(Isi <> nil);
// TODO: just for testing, needs to be implemented properly
if Succeeded(Isi.GetDisplayName(SIGDN_NORMALDISPLAY, pWc))
and (pWc <> nil)
then begin
s := pWc;
FileName := s;
end;
end;
end;
Result := Succeeded(hr);
exit;
end;
Result := inherited Execute;
end;

function TVistaOpenDialog.OnFileOk(const pfd: IFileDialog): HResult;
var
pszName: PWideChar;
s: WideString;
begin
if Succeeded(pfd.GetFileName(pszName)) and (pszName <> nil) then begin
s := pszName;
if AnsiCompareText(ExtractFileExt(s), '.txt') = 0 then begin
Result := S_OK;
exit;
end;
end;
Result := S_FALSE;
end;

function TVistaOpenDialog.OnFolderChange(const pfd: IFileDialog): HResult;
begin
Result := S_OK;
end;

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

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

function TVistaOpenDialog.OnSelectionChange(
const pfd: IFileDialog): HResult;
begin
Result := S_OK;
end;

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

function TVistaOpenDialog.OnTypeChange(const pfd: IFileDialog): HResult;
begin
Result := S_OK;
end;

如果您在 Windows 7 上运行此程序,它将显示新对话框并仅接受扩展名为 txt 的文件。这是硬编码的,需要通过对话框的OnClose事件来实现。还有很多工作要做,但提供的代码应该足以作为起点。

关于Delphi 7 和 Vista/Windows 7 通用对话框 - 事件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1894318/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com