mirror of https://github.com/buggins/dlangui.git
Add bookmarks on Windows
This commit is contained in:
parent
815a5beb3f
commit
1ae842a950
|
@ -344,6 +344,24 @@ private:
|
|||
return res;
|
||||
}
|
||||
|
||||
version(Windows)
|
||||
{
|
||||
private:
|
||||
import core.sys.windows.windows;
|
||||
import core.sys.windows.shlobj;
|
||||
import core.sys.windows.wtypes;
|
||||
import core.sys.windows.objbase;
|
||||
import core.sys.windows.objidl;
|
||||
|
||||
pragma(lib, "Ole32");
|
||||
|
||||
alias GUID KNOWNFOLDERID;
|
||||
|
||||
extern(Windows) @nogc @system HRESULT _dummy_SHGetKnownFolderPath(const(KNOWNFOLDERID)* rfid, DWORD dwFlags, HANDLE hToken, wchar** ppszPath) nothrow;
|
||||
|
||||
enum KNOWNFOLDERID FOLDERID_Links = {0xbfb9d5e0, 0xc6a9, 0x404c, [0xb2,0xb2,0xae,0x6d,0xb6,0xaf,0x49,0x68]};
|
||||
}
|
||||
|
||||
/// returns array of user bookmarked directories
|
||||
RootEntry[] getBookmarkPaths() nothrow
|
||||
{
|
||||
|
@ -386,7 +404,76 @@ RootEntry[] getBookmarkPaths() nothrow
|
|||
|
||||
}
|
||||
} else version(Windows) {
|
||||
/*
|
||||
* This will not include bookmarks of special items and virtual folders like Recent Files or Recycle bin.
|
||||
*/
|
||||
|
||||
import core.stdc.wchar_ : wcslen;
|
||||
import std.exception : enforce;
|
||||
import std.utf : toUTF8, toUTF16z;
|
||||
import std.file : dirEntries, SpanMode;
|
||||
import std.string : endsWith;
|
||||
|
||||
try {
|
||||
auto shell = enforce(LoadLibraryA("Shell32"));
|
||||
scope(exit) FreeLibrary(shell);
|
||||
|
||||
auto ptrSHGetKnownFolderPath = cast(typeof(&_dummy_SHGetKnownFolderPath))enforce(GetProcAddress(shell, "SHGetKnownFolderPath"));
|
||||
|
||||
wchar* linksFolderZ;
|
||||
const linksGuid = FOLDERID_Links;
|
||||
enforce(ptrSHGetKnownFolderPath(&linksGuid, 0, null, &linksFolderZ) == S_OK);
|
||||
scope(exit) CoTaskMemFree(linksFolderZ);
|
||||
|
||||
string linksFolder = linksFolderZ[0..wcslen(linksFolderZ)].toUTF8;
|
||||
|
||||
CoInitialize(null);
|
||||
scope(exit) CoUninitialize();
|
||||
|
||||
HRESULT hres;
|
||||
IShellLink psl;
|
||||
|
||||
auto clsidShellLink = CLSID_ShellLink;
|
||||
auto iidShellLink = IID_IShellLinkW;
|
||||
hres = CoCreateInstance(&clsidShellLink, null, CLSCTX_INPROC, &iidShellLink, cast(LPVOID*)&psl);
|
||||
enforce(SUCCEEDED(hres), "Failed to create IShellLink instance");
|
||||
scope(exit) psl.Release();
|
||||
|
||||
IPersistFile ppf;
|
||||
auto iidPersistFile = IID_IPersistFile;
|
||||
hres = psl.QueryInterface(&iidPersistFile, cast(void**)&ppf);
|
||||
enforce(SUCCEEDED(hres), "Failed to query IPersistFile interface");
|
||||
scope(exit) ppf.Release();
|
||||
|
||||
foreach(linkFile; dirEntries(linksFolder, SpanMode.shallow)) {
|
||||
if (!linkFile.name.endsWith(".lnk")) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
wchar[MAX_PATH] szGotPath;
|
||||
WIN32_FIND_DATA wfd;
|
||||
|
||||
hres = ppf.Load(linkFile.name.toUTF16z, STGM_READ);
|
||||
enforce(SUCCEEDED(hres), "Failed to load link file");
|
||||
|
||||
hres = psl.Resolve(null, 0);
|
||||
enforce(SUCCEEDED(hres), "Failed to resolve link");
|
||||
|
||||
hres = psl.GetPath(szGotPath.ptr, szGotPath.length, &wfd, 0);
|
||||
enforce(SUCCEEDED(hres), "Failed to get path of link target");
|
||||
|
||||
auto path = szGotPath[0..wcslen(szGotPath.ptr)];
|
||||
|
||||
if (path.length) {
|
||||
res ~= RootEntry(RootEntryType.BOOKMARK, path.toUTF8, linkFile.name.baseName.stripExtension.toUTF32);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue