HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
path_location_win32_impl.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
8
9#include "path_location_intf.hpp"
10#include "../metadata/metadata.hpp"
11#include "../telemetry/telemetry.hpp"
12#include "../utility/utility.hpp"
13#include "../macros.hpp"
14#include <filesystem>
15#include <string>
16
17hi_export_module(hikogui.path.path_location : impl);
18
19hi_export namespace hi::inline v1 {
20
28[[nodiscard]] inline std::filesystem::path get_path_by_id(const KNOWNFOLDERID& folder_id) noexcept
29{
30 PWSTR wpath = nullptr;
31 if (SHGetKnownFolderPath(folder_id, 0, nullptr, &wpath) != S_OK) {
32 hi_log_fatal("Could not get known folder path.");
33 }
34 hilet d = defer{[&] {
36 }};
37
38 return std::filesystem::path{wpath} / "";
39}
40
41[[nodiscard]] inline std::filesystem::path get_module_path(HMODULE module_handle) noexcept
42{
44 auto buffer_size = MAX_PATH; // initial default value = 256
45
46 // iterative buffer resizing to max value of 32768 (256*2^7)
47 for (std::size_t i = 0; i < 7; ++i) {
50 if (chars < module_path.length()) {
51 module_path.resize(chars);
52 return std::filesystem::path{module_path};
53
54 } else {
55 buffer_size *= 2;
56 }
57 }
58 hi_log_fatal("Could not get executable path. It exceeds the buffer length of 32768 chars.");
59}
60
61[[nodiscard]] inline std::filesystem::path get_executable_path() noexcept
62{
63 return get_module_path(nullptr);
64}
65
66[[nodiscard]] hi_no_inline inline std::filesystem::path get_library_path() noexcept
67{
68 HMODULE module_handle = nullptr;
70 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<LPCTSTR>(get_library_path), &module_handle)) {
71 hi_log_fatal("Could not get a handle to the current module.");
72 }
73 hilet d = defer{[&] {
75 }};
76
77 return get_module_path(module_handle);
78}
79
81{
82 using enum path_location;
83
84 switch (location) {
85 case executable_file:
86 co_yield get_executable_path();
87 break;
88
89 case executable_dir:
90 co_yield get_path(executable_file).remove_filename();
91 break;
92
93 case library_file:
94 co_yield get_library_path();
95 break;
96
97 case library_dir:
98 co_yield get_path(library_file).remove_filename();
99 break;
100
101 case resource_dirs:
102 {
103 hilet executable_path = get_path(path_location::executable_dir);
104 hilet library_path = get_path(path_location::library_dir);
105 co_yield executable_path / "resources" / "";
107 // XXX use the system-library resource path instead.
108 co_yield library_path / "resources" / "";
109 }
110 }
111 break;
112
113 case data_dir:
114 // "%LOCALAPPDATA%<Application Vendor><Application Name>\"
115 {
116 // FOLDERID_LocalAppData has the default path: %LOCALAPPDATA% (%USERPROFILE%\AppData\Local)
118 co_yield local_app_data / get_application_vendor() / get_application_name() / "";
119 }
120 break;
121
122 case log_dir:
123 // "%LOCALAPPDATA%<Application Vendor><Application Name>\Log\"
124 co_yield get_path(data_dir) / "Log" / "";
125 break;
126
127 case preferences_file:
128 co_yield get_path(data_dir) / "preferences.json";
129 break;
130
131 case system_font_dirs:
132 // FOLDERID_Fonts has the default path: %windir%\Fonts
134 break;
135
136 case font_dirs:
137 // Sorted from global to local.
138 for (hilet& path : get_paths(resource_dirs)) {
139 co_yield path / "fonts" / "";
140 }
141 for (hilet& path : get_paths(system_font_dirs)) {
142 co_yield path;
143 }
144 break;
145
146 case theme_dirs:
147 for (hilet& path : get_paths(resource_dirs)) {
148 co_yield path / "themes" / "";
149 }
150 break;
151
152 default:
153 hi_no_default();
154 }
155}
156
157} // namespace hi::inline v1
Rules for working with win32 headers.
path_location
File and Directory locations.
Definition path_location_intf.hpp:24
generator< std::filesystem::path > get_paths(path_location location)
Get a set of paths.
std::filesystem::path get_path(path_location location)
Get the single and only path.
Definition path_location_intf.hpp:112
@ data_dir
The single directory where the data for the application is stored for the current user account.
@ resource_dirs
The location of application resources.
@ executable_file
A single file where the current running executable is located.
@ theme_dirs
The directories where the themes are located.
@ library_dir
The single directory where the HikoGUI shared library is located.
@ preferences_file
A single file where to store or load the application preferences file for the current user account.
@ executable_dir
The directory where the executable is located.
@ library_file
A single file where the current running HikoGUI shared library is located.
@ log_dir
The single directory where to store the log files.
@ system_font_dirs
The directories where the system fonts are stored.
@ font_dirs
The directories where the fonts for the system and resource fonts are located.
DOXYGEN BUG.
Definition algorithm.hpp:16
std::filesystem::path get_path_by_id(const KNOWNFOLDERID &folder_id) noexcept
Convenience function for SHGetKnownFolderPath().
Definition path_location_win32_impl.hpp:28
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
T resize(T... args)