我正在尝试将 WinUI 最小应用程序示例 移植到 Lazarus:
var
GApplication: IApplication;
GApplicationInspectable: IInspectable;
GWindow: IWindow;
GWindowInspectable: IInspectable;
{ TMyCallback }
function TMyCallback.Invoke(p: IApplicationInitializationCallbackParams): HRESULT;
stdcall;
var
LHResult: HRESULT;
LHandle: HSTR;
begin
Writeln('CALLBACK REACHED');
//Create application
LHResult := WindowsCreateString(pwidechar(APPLICATION_CLASS),
Length(APPLICATION_CLASS), LHandle);
Writeln('WindowsCreateString HResult: ', LHResult);
LHResult := RoActivateInstance(LHandle, GApplicationInspectable);
Writeln('RoActivateInstance HResult: ', LHResult);
GApplication := GApplicationInspectable as IApplication;
Writeln('GApplicationInspectable as IApplication: ', GApplicationInspectable is
IApplication);
//Create window
LHResult := WindowsCreateString(pwidechar(WINDOW_CLASS),
Length(WINDOW_CLASS), LHandle);
Writeln('WindowsCreateString HResult: ', LHResult);
LHResult := RoActivateInstance(LHandle, GWindowInspectable);
Writeln('RoActivateInstance HResult: ', LHResult);
GWindow := GWindowInspectable as IWindow;
Writeln('GWindowInspectable as IWindow: ', GWindowInspectable is IWindow);
OutputDebugString('HEREWEGO');
LHResult := GWindow.Activate(); //ACESS VIOLATION HERE
Writeln('LWindow.Activate HResult: ', LHResult);
Result := S_OK;
end;
procedure Run;
var
LHResult: HResult;
LPackageVersion: PACKAGE_VERSION;
LPstr: PCWSTR;
LInspectable: IInspectable;
LHandle: THandle;
LApplicationStatics: IApplicationStatics;
LApplicationCallback: IApplicationInitializationCallback;
begin
LPackageVersion.Version := RUNTIME_VERSION;
LPstr := '';
LHResult := MddBootstrapInitialize2(RELEASE_MAJORMINOR, LPstr,
LPackageVersion, MddBootstrapInitializeOptions_OnNoMatch_ShowUI);
Writeln('MddBootstrapInitialize HResult: ', LHResult);
LHResult := WindowsCreateString(pwidechar(APPLICATION_CLASS),
Length(APPLICATION_CLASS), LHandle);
Writeln('WindowsCreateString HResult: ', LHResult);
LHResult := RoGetActivationFactory(LHandle, IApplicationStatics, LInspectable);
Writeln('RoGetActivationFactory HResult: ', LHResult);
LApplicationStatics := LInspectable as IApplicationStatics;
Writeln('Cast succesful');
LApplicationCallback := TMyCallback.Create;
LHResult := LApplicationStatics.Start(LApplicationCallback);
Writeln('HResult Application.Start: ', LHResult);
ReadLn;
MddBootstrapShutdown();
Writeln('Finished');
end;
begin
try
Run();
except
on E: Exception do
Writeln(E.Message);
end;
ReadLn;
end.
在 GWindow.Activate() 中,我的应用程序因访问冲突而崩溃。提供的代码产生以下输出:
MddBootstrapInitialize HResult: 0
WindowsCreateString HResult: 0
RoGetActivationFactory HResult: 0
Cast succesful
CALLBACK REACHED
WindowsCreateString HResult: 0
RoActivateInstance HResult: 0
GApplicationInspectable as IApplication: TRUE
WindowsCreateString HResult: 0
RoActivateInstance HResult: 0
GWindowInspectable as IWindow: TRUE
WinDbg 堆栈跟踪:
00 00000000`013ffb60 00007ffc`2d9c6046 Microsoft_UI_Xaml!DirectUI::DesktopWindowImpl::get_BoundsImpl+0xc0
01 00000000`013ffbe0 00000001`00001b83 Microsoft_UI_Xaml!DirectUI::WindowGenerated::get_Bounds+0x46
02 00000000`013ffc10 00007ffc`2d995e4e winui!INVOKE+0x2c3 [winui.lpr @ 164]
03 00000000`013ffc70 00007ffc`2d99586e Microsoft_UI_Xaml!DirectUI::FrameworkApplication::StartDesktop+0x9e
04 00000000`013ffd80 00000001`00001e08 Microsoft_UI_Xaml!DirectUI::FrameworkApplicationFactory::Start+0x6e
05 00000000`013ffdc0 00000001`00001f08 winui!RUN+0x1d8 [winui.lpr @ 197]
06 00000000`013ffe40 00000001`00001fc6 winui!main+0x18 [winui.lpr @ 206]
07 00000000`013ffe80 00000001`00012880 winui!P$WINUI_$$_finalize_implicit$+0x46
08 00000000`013ffeb0 00000001`00001880 winui!P$WINUI_$$_finalize_implicit$+0x10900
09 00000000`013fff00 00007ffc`6d627604 winui!public_all+0x880
0a 00000000`013fff30 00007ffc`6ee026a1 KERNEL32!BaseThreadInitThunk+0x14
0b 00000000`013fff60 00000000`00000000 ntdll!RtlUserThreadStart+0x21
完整示例(包括带有 WinDbg 符号的 x64 二进制文件)位于 my GitHub repo。除了查看 WinDbg 堆栈跟踪之外,我不知道如何调试此错误,尽管尝试过,但我的代码找不到任何问题。从输出中可以看出,所有 WinRT 调用和接口转换均成功。我还使用引导 dll 并在 WinDbg 中看到该应用程序加载了 Windows Apps SDK。我将不胜感激任何帮助。谢谢!
IWindow的定义(测试时使用Visible,调用它返回false):
IWindow = interface(IInspectable)
['{61F0EC79-5D52-56B5-86FB-40FA4AF288B0}']
function Activate: HRESULT; stdcall;
function Visible(out Visible: boolean): HRESULT; stdcall;
end;