ADD: Open images in the Microsoft Photos application using WinRT APIs

(cherry picked from commit d0c00d792e)
This commit is contained in:
Alexander Koblov 2024-05-01 16:32:25 +03:00
commit f4bda829bc
4 changed files with 724 additions and 9 deletions

View file

@ -44,7 +44,7 @@
</Target>
<SearchPaths>
<IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder;platform\win\winrt"/>
<UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
<SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
</SearchPaths>
@ -87,7 +87,7 @@
</Target>
<SearchPaths>
<IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder;platform\win\winrt"/>
<UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
<SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
</SearchPaths>
@ -126,7 +126,7 @@
</Target>
<SearchPaths>
<IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder;platform\win\winrt"/>
<UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
<SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
</SearchPaths>
@ -200,7 +200,7 @@ end;"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;..\components\DDetours\Source;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;..\components\DDetours\Source;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder;platform\win\winrt"/>
<UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
<SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
</SearchPaths>
@ -2001,7 +2001,7 @@ end;"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(LazarusDir)\ide;$(ProjOutDir);..\sdk;..\units"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder"/>
<OtherUnitFiles Value="platform;platform\$(SrcOS);platform\$(SrcOS)\$(TargetOS);..\sdk;frames;fileviews;filesources;filesources\filesystem;filesources\multiarchive;filesources\multilist;filesources\searchresult;filesources\tempfilesystem;filesources\vfs;filesources\wcxarchive;filesources\wfxplugin;filesources\winnet;platform\unix\glib;platform\unix\mime;filesources\gio;rpc;rpc\sys\$(SrcOS);rpc\sys;filesources\recyclebin;filesources\gio\trash;filesources\winnet\wsl;filesources\shellfolder;platform\win\winrt"/>
<UnitOutputDirectory Value="..\units\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
<SrcPath Value="$(LazarusDir)\lcl;$(LazarusDir)\lcl\interfaces\$(LCLWidgetType);$(fpcsrcdir)\packages\fcl-base\src"/>
</SearchPaths>

View file

@ -189,7 +189,7 @@ uses
StrUtils, uFileProcs, FileUtil, uDCUtils, DCOSUtils, DCStrUtils, uGlobs, uLng,
fConfirmCommandLine, uLog, DCConvertEncoding, LazUTF8, uSysFolders
{$IF DEFINED(MSWINDOWS)}
, Windows, uMyWindows, JwaWinNetWk,
, Windows, Shlwapi, WinRT.Classes, uMyWindows, JwaWinNetWk,
uShlObjAdditional, DCWindows, uNetworkThread
{$ENDIF}
{$IF DEFINED(UNIX)}
@ -372,18 +372,40 @@ end;
function ShellExecute(URL: String): Boolean;
{$IF DEFINED(MSWINDOWS)}
var
cchOut: DWORD;
Return: HINST;
wsFileName: UnicodeString;
wsStartPath: UnicodeString;
AppID, FileExt: UnicodeString;
begin
URL:= NormalizePathDelimiters(URL);
cchOut:= MAX_PATH;
SetLength(AppID, cchOut);
URL:= NormalizePathDelimiters(URL);
FileExt:= CeUtf8ToUtf16(ExtractFileExt(URL));
if (AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_APPID,
PWideChar(FileExt), nil, PWideChar(AppID), @cchOut) = S_OK) then
begin
if cchOut > 0 then
begin
SetLength(AppID, cchOut - 1);
// Special case Microsoft Photos
if (AppID = 'Microsoft.Windows.Photos_8wekyb3d8bbwe!App') then
begin
TLauncherThread.LaunchFileAsync(URL);
Exit(True);
end;
end;
end;
wsFileName:= CeUtf8ToUtf16(QuoteDouble(URL));
wsStartPath:= CeUtf8ToUtf16(mbGetCurrentDir());
Return:= ShellExecuteW(0, nil, PWideChar(wsFileName), nil, PWideChar(wsStartPath), SW_SHOWNORMAL);
if Return = SE_ERR_NOASSOC then
Result:= ExecCmdFork('rundll32 shell32.dll OpenAs_RunDLL ' + URL)
else
else begin
Result:= Return > 32;
end;
end;
{$ELSEIF DEFINED(DARWIN)}
var

View file

@ -0,0 +1,502 @@
unit WinRT.Classes;
{$mode delphi}
interface
uses
Classes, SysUtils, Types, WinRT.Core;
const
Windows_System_Launcher = UnicodeString('Windows.System.Launcher');
Windows_Storage_StorageFile = UnicodeString('Windows.Storage.StorageFile');
Windows_Storage_StorageFolder = UnicodeString('Windows.Storage.StorageFolder');
Windows_System_LauncherOptions = UnicodeString('Windows.System.LauncherOptions');
type
// Windows.Foundation.AsyncStatus
AsyncStatus = (
Started = 0,
Completed = 1,
Canceled = 2,
Error = 3
);
// Windows.Storage.Search.FolderDepth
FolderDepth =
(
Shallow = 0,
Deep = 1
);
// Windows.Storage.Search.IndexerOption
IndexerOption =
(
UseIndexerWhenAvailable = 0,
OnlyUseIndexer = 1,
DoNotUseIndexer = 2,
OnlyUseIndexerAndOptimizeForIndexedProperties = 3
);
// Windows.Storage.Search.DateStackOption
DateStackOption =
(
None = 0,
Year = 1,
Month = 2
);
// Windows.Storage.Search.CommonFileQuery
CommonFileQuery =
(
DefaultQuery = 0,
OrderByName = 1,
OrderByTitle = 2,
OrderByMusicProperties = 3,
OrderBySearchRank = 4,
OrderByDate = 5
);
// Windows.Storage.FileAccessMode
FileAccessMode = (
Read = 0,
ReadWrite = 1
);
// Windows.Storage.NameCollisionOption
NameCollisionOption = (
GenerateUniqueName = 0,
ReplaceExisting = 1,
FailIfExists = 2
);
// Windows.Storage.CreationCollisionOption
CreationCollisionOption = (
GenerateUniqueNamez = 0,
ReplaceExistingz = 1,
FailIfExistsz = 2,
OpenIfExists = 3
);
// Forward declarations
IStorageFolder = interface;
IAsyncOperation_1_Boolean = interface;
IAsyncOperation_1_IStorageFile = interface;
IAsyncOperation_1_IStorageFolder = interface;
// Windows.Foundation.AsyncOperationCompletedHandler`1<Windows.Storage.StorageFolder>
IAsyncOperationCompletedHandler_1_IStorageFolder = interface(IUnknown)
['{C211026E-9E63-5452-BA54-3A07D6A96874}']
procedure Invoke(asyncInfo: IAsyncOperation_1_IStorageFolder; asyncStatus: AsyncStatus); safecall;
end;
// Windows.Foundation.IAsyncOperation`1<Windows.Storage.IStorageFolder>
IAsyncOperation_1_IStorageFolder = interface(IInspectable)
['{6BE9E7D7-E83A-5CBC-802C-1768960B52C3}']
procedure Set_Completed(handler: IAsyncOperationCompletedHandler_1_IStorageFolder); safecall;
function Get_Completed: IAsyncOperationCompletedHandler_1_IStorageFolder; safecall;
function GetResults: IStorageFolder; safecall;
property Completed: IAsyncOperationCompletedHandler_1_IStorageFolder read Get_Completed write Set_Completed;
end;
IStorageFolder = interface(IInspectable)
['{72D1CB78-B3EF-4F75-A80B-6FD9DAE2944B}']
function CreateFileAsync(desiredName: HSTRING): IAsyncOperation_1_IStorageFile; safecall; overload;
function CreateFileAsync(desiredName: HSTRING; options: CreationCollisionOption): IAsyncOperation_1_IStorageFile; safecall; overload;
function CreateFolderAsync(desiredName: HSTRING): IAsyncOperation_1_IStorageFolder; safecall; overload;
function CreateFolderAsync(desiredName: HSTRING; options: CreationCollisionOption): IAsyncOperation_1_IStorageFolder; safecall; overload;
function GetFileAsync(name: HSTRING): IAsyncOperation_1_IStorageFile; safecall;
function GetFolderAsync(name: HSTRING): IAsyncOperation_1_IStorageFolder; safecall;
function GetItemAsync(name: HSTRING): IInspectable; safecall;
function GetFilesAsync: IInspectable; safecall;
function GetFoldersAsync: IInspectable; safecall;
function GetItemsAsync: IInspectable; safecall;
end;
IStorageFile = interface(IInspectable)
['{FA3F6186-4214-428C-A64C-14C9AC7315EA}']
function Get_FileType: HSTRING; safecall;
function Get_ContentType: HSTRING; safecall;
function OpenAsync(accessMode: FileAccessMode): IInspectable; safecall;
function OpenTransactedWriteAsync: IInspectable; safecall;
function CopyAsync(destinationFolder: IStorageFolder): IAsyncOperation_1_IStorageFile; safecall; overload;
function CopyAsync(destinationFolder: IStorageFolder; desiredNewName: HSTRING): IAsyncOperation_1_IStorageFile; safecall; overload;
function CopyAsync(destinationFolder: IStorageFolder; desiredNewName: HSTRING; option: NameCollisionOption): IAsyncOperation_1_IStorageFile; safecall; overload;
function CopyAndReplaceAsync(fileToReplace: IStorageFile): IInspectable; safecall;
function MoveAsync(destinationFolder: IStorageFolder): IInspectable; safecall; overload;
function MoveAsync(destinationFolder: IStorageFolder; desiredNewName: HSTRING): IInspectable; safecall; overload;
function MoveAsync(destinationFolder: IStorageFolder; desiredNewName: HSTRING; option: NameCollisionOption): IInspectable; safecall; overload;
function MoveAndReplaceAsync(fileToReplace: IStorageFile): IInspectable; safecall;
property ContentType: HSTRING read Get_ContentType;
property FileType: HSTRING read Get_FileType;
end;
// Windows.Foundation.AsyncOperationCompletedHandler`1<Windows.Storage.IStorageFile>
IAsyncOperationCompletedHandler_1_IStorageFile = interface(IUnknown)
['{E521C894-2C26-5946-9E61-2B5E188D01ED}']
procedure Invoke(asyncInfo: IAsyncOperation_1_IStorageFile; asyncStatus: AsyncStatus); safecall;
end;
// Windows.Foundation.IAsyncOperation`1<Windows.Storage.IStorageFile>
IAsyncOperation_1_IStorageFile = interface(IInspectable)
['{5E52F8CE-ACED-5A42-95B4-F674DD84885E}']
procedure Set_Completed(handler: IAsyncOperationCompletedHandler_1_IStorageFile); safecall;
function Get_Completed: IAsyncOperationCompletedHandler_1_IStorageFile; safecall;
function GetResults: IStorageFile; safecall;
property Completed: IAsyncOperationCompletedHandler_1_IStorageFile read Get_Completed write Set_Completed;
end;
// Windows.Storage.StorageFile
IStorageFileStatics = interface(IInspectable)
['{5984C710-DAF2-43C8-8BB4-A4D3EACFD03F}']
function GetFileFromPathAsync(path: HSTRING): IAsyncOperation_1_IStorageFile; safecall;
function GetFileFromApplicationUriAsync(uri: IInspectable): IAsyncOperation_1_IStorageFile; safecall;
function CreateStreamedFileAsync(displayNameWithExtension: HSTRING; dataRequested: IUnknown; thumbnail: IInspectable): IAsyncOperation_1_IStorageFile; safecall;
function ReplaceWithStreamedFileAsync(fileToReplace: IStorageFile; dataRequested: IUnknown; thumbnail: IInspectable): IAsyncOperation_1_IStorageFile; safecall;
function CreateStreamedFileFromUriAsync(displayNameWithExtension: HSTRING; uri: IInspectable; thumbnail: IInspectable): IAsyncOperation_1_IStorageFile; safecall;
function ReplaceWithStreamedFileFromUriAsync(fileToReplace: IStorageFile; uri: IInspectable; thumbnail: IInspectable): IAsyncOperation_1_IStorageFile; safecall;
end;
// Windows.Storage.Search.StorageFileQueryResult
IStorageFileQueryResult = interface(IInspectable)
['{52FDA447-2BAA-412C-B29F-D4B1778EFA1E}']
function GetFilesAsync(startIndex: UINT32; maxNumberOfItems: UINT32; out operation: IInspectable): HRESULT; stdcall;
function GetFilesAsyncDefaultStartAndCount(out operation: IInspectable): HRESULT; stdcall;
end;
// Windows.Storage.Search.QueryOptions
IQueryOptions = interface(IInspectable)
['{1E5E46EE-0F45-4838-A8E9-D0479D446C30}']
function Get_FileTypeFilter(out value: IUnknown): HRESULT; stdcall;
function Get_FolderDepth(out value: FolderDepth): HRESULT; stdcall;
function Put_FolderDepth(value: FolderDepth): HRESULT; stdcall;
function Get_ApplicationSearchFilter(out value: HSTRING): HRESULT; stdcall;
function Put_ApplicationSearchFilter(value: HSTRING): HRESULT; stdcall;
function Get_UserSearchFilter(out value: HSTRING): HRESULT; stdcall;
function Put_UserSearchFilter(value: HSTRING): HRESULT; stdcall;
function Get_Language(out value: HSTRING): HRESULT; stdcall;
function Put_Language(value: HSTRING): HRESULT; stdcall;
function Get_IndexerOption(out value: IndexerOption): HRESULT; stdcall;
function Put_IndexerOption(value: IndexerOption): HRESULT; stdcall;
function Get_SortOrder(out value: IUnknown): HRESULT; stdcall;
function Get_GroupPropertyName(out value: HSTRING): HRESULT; stdcall;
function Get_DateStackOption(out value: DateStackOption): HRESULT; stdcall;
function SaveToString(out value: HSTRING): HRESULT; stdcall;
function LoadFromString(value: HSTRING): HRESULT; stdcall;
function SetThumbnailPrefetch(mode: DWORD; requestedSize: UINT32; options: DWORD): HRESULT; stdcall;
function SetPropertyPrefetch(options: DWORD; propertiesToRetrieve: IUnknown): HRESULT; stdcall;
end;
// Windows.Storage.Search.QueryOptions
IQueryOptionsFactory = interface(IInspectable)
['{032E1F8C-A9C1-4E71-8011-0DEE9D4811A3}']
function CreateCommonFileQuery(query: CommonFileQuery; fileTypeFilter: IInspectable; out queryOptions: IQueryOptions): HRESULT; stdcall;
function CreateCommonFolderQuery(query: DWORD; out queryOptions: IQueryOptions): HRESULT; stdcall;
end;
IStorageFolderQueryOperations = interface(IInspectable)
['{CB43CCC9-446B-4A4F-BE97-757771BE5203}']
function GetIndexedStateAsync(out operation: IUnknown): HRESULT; stdcall;
function CreateFileQueryOverloadDefault(out value: IStorageFileQueryResult): HRESULT; stdcall;
function CreateFileQuery(query: CommonFileQuery; out value: IStorageFileQueryResult): HRESULT; stdcall;
function CreateFileQueryWithOptions(queryOptions: IQueryOptions; out value: IStorageFileQueryResult): HRESULT; stdcall;
function CreateFolderQueryOverloadDefault(out value: IInspectable): HRESULT; stdcall;
function CreateFolderQuery(query: DWORD; out value: IInspectable): HRESULT; stdcall;
function CreateFolderQueryWithOptions(queryOptions: IQueryOptions; out value: IInspectable): HRESULT; stdcall;
function CreateItemQuery(out value: IInspectable): HRESULT; stdcall;
function CreateItemQueryWithOptions(queryOptions: IQueryOptions; out value: IInspectable): HRESULT; stdcall;
function GetFilesAsync(query: CommonFileQuery; startIndex: UINT32; maxItemsToRetrieve: UINT32; out operation: IUnknown): HRESULT; stdcall;
function GetFilesAsyncOverloadDefaultStartAndCount(query: CommonFileQuery; out operation: IInspectable): HRESULT; stdcall;
function GetFoldersAsync(query: DWORD; startIndex: UINT32; maxItemsToRetrieve: UINT32; out operation: IInspectable): HRESULT; stdcall;
function GetFoldersAsyncOverloadDefaultStartAndCount(query: DWORD; out operation: IInspectable): HRESULT; stdcall;
function GetItemsAsync(startIndex: UINT32; maxItemsToRetrieve: UINT32; out operation: IInspectable): HRESULT; stdcall;
function AreQueryOptionsSupported(queryOptions: IQueryOptions; out value: LongBool): HRESULT; stdcall;
function IsCommonFolderQuerySupported(query: DWORD; out value: LongBool): HRESULT; stdcall;
function IsCommonFileQuerySupported(query: CommonFileQuery; out value: LongBool): HRESULT; stdcall;
end;
// Windows.Storage.StorageFolder
IStorageFolderStatics = interface(IInspectable)
['{08F327FF-85D5-48B9-AEE9-28511E339F9F}']
function GetFolderFromPathAsync(path: HSTRING): IAsyncOperation_1_IStorageFolder; safecall;
end;
// Windows.System.LauncherOptions
ILauncherOptions = interface(IInspectable)
['{BAFA21D8-B071-4CD8-853E-341203E557D3}']
function Get_TreatAsUntrusted(value: PLongBool): HRESULT; stdcall;
function Set_TreatAsUntrusted(value: LongBool): HRESULT; stdcall;
function Get_DisplayApplicationPicker(value: PLongBool): HRESULT; stdcall;
function Set_DisplayApplicationPicker(value: LongBool): HRESULT; stdcall;
function UI(out value: IInspectable): HRESULT; stdcall;
function Get_PreferredApplicationPackageFamilyName(out value: HSTRING): HRESULT; stdcall;
function Set_PreferredApplicationPackageFamilyName(value: HSTRING): HRESULT; stdcall;
function Get_PreferredApplicationDisplayName(out value: HSTRING): HRESULT; stdcall;
function Set_PreferredApplicationDisplayName(value: HSTRING): HRESULT; stdcall;
function Get_FallbackUri(out value: IUnknown): HRESULT; stdcall;
function Set_FallbackUri(value: IUnknown): HRESULT; stdcall;
function Get_ContentType(out value: HSTRING): HRESULT; stdcall;
function Set_ContentType(value: HSTRING): HRESULT; stdcall;
end;
// Windows.System.LauncherOptions
ILauncherOptions2 = interface(IInspectable)
['{3BA08EB4-6E40-4DCE-A1A3-2F53950AFB49}']
function Get_TargetApplicationPackageFamilyName: HSTRING; safecall;
procedure Set_TargetApplicationPackageFamilyName(value: HSTRING); safecall;
function Get_NeighboringFilesQuery: IStorageFileQueryResult; safecall;
procedure Set_NeighboringFilesQuery(value: IStorageFileQueryResult); safecall;
property NeighboringFilesQuery: IStorageFileQueryResult read Get_NeighboringFilesQuery write Set_NeighboringFilesQuery;
property TargetApplicationPackageFamilyName: HSTRING read Get_TargetApplicationPackageFamilyName write Set_TargetApplicationPackageFamilyName;
end;
// Windows.Foundation.AsyncOperationCompletedHandler`1<Boolean>
IAsyncOperationCompletedHandler_1_Boolean = interface(IUnknown)
['{C1D3D1A2-AE17-5A5F-B5A2-BDCC8844889A}']
procedure Invoke(asyncInfo: IAsyncOperation_1_Boolean; asyncStatus: AsyncStatus); safecall;
end;
// Windows.Foundation.IAsyncOperation`1<Boolean>
IAsyncOperation_1_Boolean = interface(IInspectable)
['{CDB5EFB3-5788-509D-9BE1-71CCB8A3362A}']
procedure Set_Completed(handler: IAsyncOperationCompletedHandler_1_Boolean); safecall;
function Get_Completed: IAsyncOperationCompletedHandler_1_Boolean; safecall;
function GetResults: Boolean; safecall;
property Completed: IAsyncOperationCompletedHandler_1_Boolean read Get_Completed write Set_Completed;
end;
// Windows.System.Launcher
ILauncherStatics = interface(IInspectable)
['{277151C3-9E3E-42F6-91A4-5DFDEB232451}']
function LaunchFileAsync(AFile: IStorageFile): IAsyncOperation_1_Boolean; safecall;
function LaunchFileWithOptionsAsync(AFile: IStorageFile; options: ILauncherOptions): IAsyncOperation_1_Boolean; safecall;
function LaunchUriAsync(uri: IUnknown): IAsyncOperation_1_Boolean; safecall;
function LaunchUriWithOptionsAsync(uri: IUnknown; options: ILauncherOptions): IAsyncOperation_1_Boolean; safecall;
end;
{ TStorageFile }
TStorageFile = class
private
FInstance: IStorageFileStatics; static;
class function Instance: IStorageFileStatics;
public
class function GetFileFromPathAsync(const APath: String): IAsyncOperation_1_IStorageFile;
end;
{ TStorageFolder }
TStorageFolder = class
private
FInstance: IStorageFolderStatics; static;
class function Instance: IStorageFolderStatics;
public
class function GetFolderFromPathAsync(const APath: String): IAsyncOperation_1_IStorageFolder;
end;
{ TLauncher }
TLauncher = class
private
FInstance: ILauncherStatics; static;
class function Instance: ILauncherStatics;
public
class function LaunchFileAsync(AFile: IStorageFile): IAsyncOperation_1_Boolean;
class function LaunchFileWithOptionsAsync(AFile: IStorageFile; options: ILauncherOptions): IAsyncOperation_1_Boolean;
end;
{ TLauncherThread }
TLauncherThread = class(TThread)
private
FEvent: THandle;
FFileName: String;
FStorageFile: IStorageFile;
FStorageFolder: IStorageFolder;
protected
procedure Execute; override;
public
constructor Create(const FileName: String);
destructor Destroy; override;
class procedure LaunchFileAsync(const FileName: String);
end;
{ TAsyncOperationCompletedHandler_1_IStorageFile }
TAsyncOperationCompletedHandler_1_IStorageFile = class(TInterfacedObject, IAsyncOperationCompletedHandler_1_IStorageFile)
private
FLauncher: TLauncherThread;
protected
procedure Invoke(asyncInfo: IAsyncOperation_1_IStorageFile; asyncStatus: AsyncStatus); safecall;
public
constructor Create(ALauncher: TLauncherThread);
end;
{ TAsyncOperationCompletedHandler_1_IStorageFolder }
TAsyncOperationCompletedHandler_1_IStorageFolder = class(TInterfacedObject, IAsyncOperationCompletedHandler_1_IStorageFolder)
private
FLauncher: TLauncherThread;
protected
procedure Invoke(asyncInfo: IAsyncOperation_1_IStorageFolder; asyncStatus: AsyncStatus); safecall;
public
constructor Create(ALauncher: TLauncherThread);
end;
implementation
uses
ComObj, Windows;
{ TStorageFile }
class function TStorageFile.Instance: IStorageFileStatics;
begin
if (FInstance = nil) then
begin
OleCheck(RoCreateInstance(Windows_Storage_StorageFile, IStorageFileStatics, FInstance));
end;
Result:= FInstance;
end;
class function TStorageFile.GetFileFromPathAsync(const APath: String): IAsyncOperation_1_IStorageFile;
begin
with TWindowsString.Create(APath) do
try
Result:= Instance.GetFileFromPathAsync(Handle);
finally
Free;
end;
end;
{ TStorageFolder }
class function TStorageFolder.Instance: IStorageFolderStatics;
begin
if (FInstance = nil) then
begin
OleCheck(RoCreateInstance(Windows_Storage_StorageFolder, IStorageFolderStatics, FInstance));
end;
Result:= FInstance;
end;
class function TStorageFolder.GetFolderFromPathAsync(const APath: String): IAsyncOperation_1_IStorageFolder;
begin
with TWindowsString.Create(APath) do
try
Result:= Instance.GetFolderFromPathAsync(Handle);
finally
Free;
end;
end;
{ TLauncher }
class function TLauncher.Instance: ILauncherStatics;
begin
if (FInstance = nil) then
begin
OleCheck(RoCreateInstance(Windows_System_Launcher, ILauncherStatics, FInstance));
end;
Result:= FInstance;
end;
class function TLauncher.LaunchFileAsync(AFile: IStorageFile): IAsyncOperation_1_Boolean;
begin
Result:= Instance.LaunchFileAsync(AFile);
end;
class function TLauncher.LaunchFileWithOptionsAsync(AFile: IStorageFile; options: ILauncherOptions): IAsyncOperation_1_Boolean;
begin
Result:= Instance.LaunchFileWithOptionsAsync(AFile, options);
end;
{ TLauncherThread }
procedure TLauncherThread.Execute;
var
AOptions: ILauncherOptions;
AOptions2: ILauncherOptions2;
AQuery: IStorageFileQueryResult;
AFolderQuery: IStorageFolderQueryOperations;
FileOperation: IAsyncOperation_1_IStorageFile;
FolderOperation: IAsyncOperation_1_IStorageFolder;
FileHandler: TAsyncOperationCompletedHandler_1_IStorageFile;
FolderHandler: TAsyncOperationCompletedHandler_1_IStorageFolder;
begin
try
FileHandler:= TAsyncOperationCompletedHandler_1_IStorageFile.Create(Self);
FileOperation:= TStorageFile.GetFileFromPathAsync(FFileName);
FileOperation.Completed:= FileHandler;
WaitForSingleObject(FEvent, INFINITE);
ResetEvent(FEvent);
FolderHandler:= TAsyncOperationCompletedHandler_1_IStorageFolder.Create(Self);
FolderOperation:= TStorageFolder.GetFolderFromPathAsync(ExtractFileDir(FFileName));
FolderOperation.Completed:= FolderHandler;
WaitForSingleObject(FEvent, INFINITE);
OleCheck(RtActivateInstance(Windows_System_LauncherOptions, AOptions));
OleCheck(AOptions.QueryInterface(ILauncherOptions2, AOptions2));
OleCheck(FStorageFolder.QueryInterface(IStorageFolderQueryOperations, AFolderQuery));
OleCheck(AFolderQuery.CreateFileQuery(DefaultQuery, AQuery));
AOptions2.NeighboringFilesQuery:= AQuery;
TLauncher.LaunchFileWithOptionsAsync(FStorageFile, AOptions);
except
on E: Exception do
begin
MessageBoxW(0, PWideChar(UTF8Decode(E.Message)), nil, MB_OK or MB_ICONERROR);
end;
end;
end;
constructor TLauncherThread.Create(const FileName: String);
begin
FFileName:= FileName;
inherited Create(True);
FreeOnTerminate:= True;
FEvent:= CreateEventW(nil, True, False, nil);
end;
destructor TLauncherThread.Destroy;
begin
CloseHandle(FEvent);
inherited Destroy;
end;
class procedure TLauncherThread.LaunchFileAsync(const FileName: String);
begin
with TLauncherThread.Create(FileName) do Start;
end;
{ TAsyncOperationCompletedHandler_1_IStorageFolder }
procedure TAsyncOperationCompletedHandler_1_IStorageFolder.Invoke(
asyncInfo: IAsyncOperation_1_IStorageFolder; asyncStatus: AsyncStatus);
safecall;
begin
FLauncher.FStorageFolder:= asyncInfo.GetResults;
SetEvent(FLauncher.FEvent);
end;
constructor TAsyncOperationCompletedHandler_1_IStorageFolder.Create(
ALauncher: TLauncherThread);
begin
FLauncher:= ALauncher;
end;
{ TAsyncOperationCompletedHandler_1_IStorageFile }
procedure TAsyncOperationCompletedHandler_1_IStorageFile.Invoke(
asyncInfo: IAsyncOperation_1_IStorageFile; asyncStatus: AsyncStatus);
safecall;
begin
FLauncher.FStorageFile:= asyncInfo.GetResults;
SetEvent(FLauncher.FEvent);
end;
constructor TAsyncOperationCompletedHandler_1_IStorageFile.Create(
ALauncher: TLauncherThread);
begin
FLauncher:= ALauncher;
end;
end.

View file

@ -0,0 +1,191 @@
unit WinRT.Core;
{$mode delphi}
interface
uses
Classes, SysUtils, Windows;
type
HSTRING = HANDLE;
PCNZWCH = PWideChar;
TrustLevel = (
BaseTrust = 0,
PartialTrust = (BaseTrust + 1),
FullTrust = (PartialTrust + 1)
);
IInspectable = interface(IUnknown)
['{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}']
function GetIids(out iidCount: ULONG; out iids: PIID): HRESULT; stdcall;
function GetRuntimeClassName(out className: HSTRING): HRESULT; stdcall;
function GetTrustLevel(out trustLevel: TrustLevel): HRESULT; stdcall;
end;
{ TWindowsString }
TWindowsString = class
private
FHandle: HSTRING;
public
constructor Create(AHandle: HSTRING); overload;
constructor Create(const AString: String); overload;
constructor Create(const AString: UnicodeString); overload;
destructor Destroy; override;
function ToString: AnsiString; override;
property Handle: HSTRING read FHandle;
end;
function RtActivateInstance(const AClassName: UnicodeString; out AInstance): HRESULT;
function RoCreateInstance(const AClassName: UnicodeString; constref AClassID: TIID; out AInstance): HRESULT;
implementation
uses
ComObj;
type
RO_INIT_TYPE = (
RO_INIT_SINGLETHREADED = 0,
RO_INIT_MULTITHREADED = 1
);
var
RoInitialize: function(initType: RO_INIT_TYPE): HRESULT; stdcall;
RoUninitialize: procedure(); stdcall;
RoActivateInstance: function(activatableClassId: HSTRING;
out instance): HRESULT; stdcall;
RoGetActivationFactory: function(activatableClassId: HSTRING;
constref iid: TIID;
out factory: IInspectable): HRESULT; stdcall;
var
WindowsCreateString: function(sourceString: PCNZWCH; length: UINT32;
out str: HSTRING): HRESULT; stdcall;
WindowsDeleteString: function(str: HSTRING): HRESULT; stdcall;
WindowsGetStringRawBuffer: function(str: HSTRING; length: PUINT32): PCWSTR; stdcall;
const
libwinrt = 'api-ms-win-core-winrt-l1-1-0.dll';
libwinrt_string = 'api-ms-win-core-winrt-string-l1-1-0.dll';
var
hWinRT: TLibHandle;
hWinRTString: TLibHandle;
procedure Initialize;
begin
if CheckWin32Version(10) then
begin
hWinRT:= LoadLibrary(libwinrt);
if (hWinRT <> NilHandle) then
try
@RoInitialize:= GetProcAddress(hWinRT, 'RoInitialize');
@RoUninitialize:= GetProcAddress(hWinRT, 'RoUninitialize');
@RoActivateInstance:= GetProcAddress(hWinRT, 'RoActivateInstance');
@RoGetActivationFactory:= GetProcAddress(hWinRT, 'RoGetActivationFactory');
RoInitialize(RO_INIT_MULTITHREADED);
except
FreeLibrary(hWinRT);
hWinRT:= NilHandle;
end;
hWinRTString:= LoadLibrary(libwinrt_string);
if (hWinRTString <> NilHandle) then
try
@WindowsCreateString:= GetProcAddress(hWinRTString, 'WindowsCreateString');
@WindowsDeleteString:= GetProcAddress(hWinRTString, 'WindowsDeleteString');
@WindowsGetStringRawBuffer:= GetProcAddress(hWinRTString, 'WindowsGetStringRawBuffer');
except
FreeLibrary(hWinRTString);
hWinRTString:= NilHandle;
end;
end;
end;
procedure Finalize;
begin
if (hWinRT <> NilHandle) then
begin
RoUninitialize;
FreeLibrary(hWinRT);
end;
if (hWinRTString <> NilHandle) then
begin
FreeLibrary(hWinRTString);
end;
end;
function RtActivateInstance(const AClassName: UnicodeString; out AInstance): HRESULT;
var
AName: TWindowsString;
begin
AName:= TWindowsString.Create(AClassName);
try
Result:= RoActivateInstance(AName.FHandle, AInstance);
finally
AName.Free;
end;
end;
function RoCreateInstance(const AClassName: UnicodeString; constref AClassID: TIID; out AInstance): HRESULT;
var
AName: TWindowsString;
AFactory: IInspectable;
begin
AName:= TWindowsString.Create(AClassName);
try
Result:= RoGetActivationFactory(AName.FHandle, AClassID, AFactory);
if Succeeded(Result) then begin
Result:= AFactory.QueryInterface(AClassID, AInstance);
end;
finally
AName.Free;
end;
end;
{ TWindowsString }
constructor TWindowsString.Create(const AString: String);
begin
Create(UTF8Decode(AString));
end;
constructor TWindowsString.Create(AHandle: HSTRING);
begin
FHandle:= AHandle;
end;
constructor TWindowsString.Create(const AString: UnicodeString);
begin
OleCheck(WindowsCreateString(PWideChar(AString), Length(AString), FHandle));
end;
destructor TWindowsString.Destroy;
begin
inherited Destroy;
if (FHandle <> 0) then WindowsDeleteString(FHandle);
end;
function TWindowsString.ToString: AnsiString;
var
P: PWideChar;
L: UINT32 = 0;
usString: UnicodeString;
begin
P:= WindowsGetStringRawBuffer(FHandle, @L);
SetString(usString, P, L);
Result:= UTF8Encode(usString);
end;
initialization
Initialize;
finalization
Finalize;
end.