From 8ec71a8b460ad99b7977e263b4dfe0b916e68c47 Mon Sep 17 00:00:00 2001 From: blob1807 <12388588+blob1807@users.noreply.github.com> Date: Tue, 7 Apr 2026 23:36:38 +1000 Subject: [PATCH] [win32 api] Add Reg Association API --- core/sys/windows/shlwapi.odin | 8 ++ core/sys/windows/types.odin | 158 +++++++++++++++++++++++++++++++--- 2 files changed, 156 insertions(+), 10 deletions(-) diff --git a/core/sys/windows/shlwapi.odin b/core/sys/windows/shlwapi.odin index 095fff304..5b90e97dc 100644 --- a/core/sys/windows/shlwapi.odin +++ b/core/sys/windows/shlwapi.odin @@ -9,4 +9,12 @@ foreign shlwapi { PathFindExtensionW :: proc(pszPath: wstring) -> wstring --- PathFindFileNameW :: proc(pszPath: wstring) -> wstring --- SHAutoComplete :: proc(hwndEdit: HWND, dwFlags: DWORD) -> LWSTDAPI --- + + AssocCreate :: proc(clsid: CLSID, riid: REFIID, ppv: ^rawptr) -> HRESULT --- + SHGetAssocKeys :: proc(pqa: ^IQueryAssociations, rgKeys: ^HKEY, cKeys: DWORD) -> HRESULT --- + AssocQueryStringW :: proc(flags: ASSOCF, str: ASSOCSTR, pszAssoc: LPCWSTR, pszExtra: LPCWSTR, pszOut: LPWSTR, pcchOut: ^DWORD) -> LWSTDAPI --- + AssocQueryStringByKeyW :: proc(flags: ASSOCF, str: ASSOCSTR, hkAssoc: HKEY, pszExtra: LPCWSTR, pszOut: LPWSTR, pcchOut: ^DWORD) -> HRESULT --- + AssocQueryKeyW :: proc(flags: ASSOCF, key: ASSOCKEY, pszAssoc: LPCWSTR, pszExtra: LPCWSTR, phkeyOut: ^HKEY) -> HRESULT --- + AssocIsDangerous :: proc(pszAssoc: PCWSTR) -> HRESULT --- + AssocGetPerceivedType :: proc(pszExt: PCWSTR, ptype: ^PERCEIVED, pflag: ^PERCEIVEDFLAG, ppszType: ^PWSTR) -> HRESULT --- } diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 54ebd9481..9b4e92a3f 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -4196,6 +4196,34 @@ COMDLG_FILTERSPEC :: struct { pszName, pszSpec: LPCWSTR, } +PERCEIVED :: enum c_int { + TYPE_FIRST = -3, + TYPE_CUSTOM = -3, + TYPE_UNSPECIFIED = -2, + TYPE_FOLDER = -1, + TYPE_UNKNOWN = 0, + TYPE_TEXT = 1, + TYPE_IMAGE = 2, + TYPE_AUDIO = 3, + TYPE_VIDEO = 4, + TYPE_COMPRESSED = 5, + TYPE_DOCUMENT = 6, + TYPE_SYSTEM = 7, + TYPE_APPLICATION = 8, + TYPE_GAMEMEDIA = 9, + TYPE_CONTACTS = 10, + TYPE_LAST = 10, +} + +PERCEIVEDFLAG :: DWORD +PERCEIVEDFLAG_UNDEFINED :: 0x0000 +PERCEIVEDFLAG_SOFTCODED :: 0x0001 +PERCEIVEDFLAG_HARDCODED :: 0x0002 +PERCEIVEDFLAG_NATIVESUPPORT :: 0x0004 +PERCEIVEDFLAG_GDIPLUS :: 0x0010 +PERCEIVEDFLAG_WMSDK :: 0x0020 +PERCEIVEDFLAG_ZIPFOLDER :: 0x0040 + DECIMAL :: struct { wReserved: USHORT, using _: struct #raw_union { @@ -4277,17 +4305,19 @@ SHACF_AUTOAPPEND_FORCE_OFF :: 0x80000000 // Ignore the registry default and fo LWSTDAPI :: HRESULT -CLSID_FileOpenDialog := &GUID{0xDC1C5A9C, 0xE88A, 0x4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}} -CLSID_FileSaveDialog := &GUID{0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}} -CLSID_TaskbarList := &GUID{0x56FDF344, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}} +CLSID_FileOpenDialog := &GUID{0xDC1C5A9C, 0xE88A, 0x4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}} +CLSID_FileSaveDialog := &GUID{0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}} +CLSID_TaskbarList := &GUID{0x56FDF344, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}} +CLSID_QueryAssociations := GUID{0xa07034fd, 0x6caa, 0x4954, {0xac, 0x3f, 0x97, 0xa2, 0x72, 0x16, 0xf9, 0x8a}} -IID_IShellItem := &GUID{0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe}} -IID_IFileDialog := &GUID{0x42F85136, 0xDB7E, 0x439C, {0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8}} -IID_IFileSaveDialog := &GUID{0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}} -IID_IFileOpenDialog := &GUID{0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}} -IID_ITaskbarList := &GUID{0x56FDF342, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}} -IID_ITaskbarList2 := &GUID{0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}} -IID_ITaskbarList3 := &GUID{0xea1afb91, 0x9e28, 0x4b86, {0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf}} +IID_IShellItem := &GUID{0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe}} +IID_IFileDialog := &GUID{0x42F85136, 0xDB7E, 0x439C, {0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8}} +IID_IFileSaveDialog := &GUID{0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}} +IID_IFileOpenDialog := &GUID{0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}} +IID_ITaskbarList := &GUID{0x56FDF342, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}} +IID_ITaskbarList2 := &GUID{0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}} +IID_ITaskbarList3 := &GUID{0xea1afb91, 0x9e28, 0x4b86, {0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf}} +IID_IQueryAssociations := &GUID{0xc46ca590, 0x3c3f, 0x11d2, {0xbe, 0xe6, 0x00, 0x00, 0xf8, 0x05, 0xca, 0x57}} IModalWindow :: struct #raw_union { #subtype IUnknown: IUnknown, @@ -4670,6 +4700,91 @@ ITaskbarList3Vtbl :: struct { SetThumbnailClip: proc "system" (this: ^ITaskbarList3, hwnd: HWND, prcClip: ^RECT) -> HRESULT, } +ASSOCF_Bits :: enum c_int { + INIT_NOREMAPCLSID = 0, + INIT_BYEXENAME = 1, + OPEN_BYEXENAME = 1, + INIT_DEFAULTTOSTAR = 2, + INIT_DEFAULTTOFOLDER = 3, + NOUSERSETTINGS = 4, + NOTRUNCATE = 5, + VERIFY = 6, + REMAPRUNDLL = 7, + NOFIXUPS = 8, + IGNOREBASECLASS = 9, + INIT_IGNOREUNKNOWN = 10, + INIT_FIXED_PROGID = 11, + IS_PROTOCOL = 12, + INIT_FOR_FILE = 13, + IS_FULL_URI = 14, + PER_MACHINE_ONLY = 15, + APP_TO_APP = 16, +} +ASSOCF :: bit_set[ASSOCF_Bits; c_int] + +ASSOCSTR :: enum c_int { + COMMAND = 1, + EXECUTABLE, + FRIENDLYDOCNAME, + FRIENDLYAPPNAME, + NOOPEN, + SHELLNEWVALUE, + DDECOMMAND, + DDEIFEXEC, + DDEAPPLICATION, + DDETOPIC, + INFOTIP, + QUICKTIP, + TILEINFO, + CONTENTTYPE, + DEFAULTICON, + SHELLEXTENSION, + DROPTARGET, + DELEGATEEXECUTE, + SUPPORTED_URI_PROTOCOLS, + PROGID, + APPID, + APPPUBLISHER, + APPICONREFERENCE, + MAX, +} + +ASSOCKEY :: enum c_int { + SHELLEXECCLASS = 1, + APP, + CLASS, + BASECLASS, + MAX, +} + +ASSOCDATA :: enum c_int { + MSIDESCRIPTOR = 1, + NOACTIVATEHANDLER, + UNUSED1, + HASPERUSERASSOC, + EDITFLAGS, + VALUE, + MAX, +} + +ASSOCENUM :: enum c_int { + NONE, +} + +IQueryAssociations :: struct #raw_union { + #subtype IUnknown: IUnknown, + using Vtbl: ^IQueryAssociationsVtbl, +} + +IQueryAssociationsVtbl :: struct { + using IUnknownVtbl: IUnknownVtbl, + Init: proc "system" (this: ^IQueryAssociations, flags: ASSOCF, pszAssoc: LPCWSTR, hkProgid: HKEY, hwnd: HWND) -> HRESULT, + GetString: proc "system" (this: ^IQueryAssociations, flags: ASSOCF, str: ASSOCSTR, pszExtra: LPCWSTR, pszOut: LPWSTR, pcchOut: ^DWORD) -> HRESULT, + GetKey: proc "system" (this: ^IQueryAssociations, flags: ASSOCF, key: ASSOCKEY, pszExtra: LPCWSTR, phkeyOut: ^HKEY) -> HRESULT, + GetData: proc "system" (this: ^IQueryAssociations, flags: ASSOCF, data: ASSOCDATA, pszExtra: LPCWSTR, pvOut: rawptr, pcbOut: ^DWORD) -> HRESULT, + GetEnum: proc "system" (this: ^IQueryAssociations, flags: ASSOCF, assocenum: ASSOCENUM, pszExtra: LPCWSTR, riid: REFIID, ppvOut: ^rawptr) -> HRESULT, +} + MEMORYSTATUSEX :: struct { dwLength: DWORD, dwMemoryLoad: DWORD, @@ -5254,3 +5369,26 @@ Com_Error_Bits :: enum DWORD { } Com_Error :: distinct bit_set[Com_Error_Bits; DWORD] +FILETYPEATTRIBUTEFLAGS_Bits :: enum DWORD { + Exclude = 0, + Show = 1, + HasExtension = 2, + NoEdit = 3, + NoRemove = 4, + NoNewVerb = 5, + NoEditVerb = 6, + NoRemoveVerb = 7, + NoEditDesc = 8, + NoEditIcon = 9, + NoEditDflt = 10, + NoEditVerbCmd = 11, + NoEditVerbExe = 12, + NoDDE = 13, + NoEditMIME = 15, + OpenIsSafe = 16, + AlwaysUnsafe = 17, + NoRecentDocs = 20, + SafeForElevation = 21, + AlwaysUseDirectInvoke = 22, +} +FILETYPEATTRIBUTEFLAGS :: bit_set[FILETYPEATTRIBUTEFLAGS_Bits; DWORD]