1 | |
---|
2 | // Copyright Eóin O'Callaghan 2006 - 2007. |
---|
3 | // Distributed under the Boost Software License, Version 1.0. |
---|
4 | // (See accompanying file LICENSE_1_0.txt or copy at |
---|
5 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
6 | |
---|
7 | #include "stdAfx.hpp" |
---|
8 | |
---|
9 | #include <boost/array.hpp> |
---|
10 | #include <boost/optional.hpp> |
---|
11 | |
---|
12 | #include "wtl_app.hpp" |
---|
13 | #include "string_conv.hpp" |
---|
14 | |
---|
15 | #include <boost/filesystem/operations.hpp> |
---|
16 | #include <boost/filesystem/fstream.hpp> |
---|
17 | |
---|
18 | #define BOOST_UTF8_BEGIN_NAMESPACE \ |
---|
19 | namespace boost { namespace filesystem { namespace detail { |
---|
20 | |
---|
21 | #define BOOST_UTF8_END_NAMESPACE }}} |
---|
22 | #define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL |
---|
23 | |
---|
24 | #include <boost/detail/utf8_codecvt_facet.hpp> |
---|
25 | |
---|
26 | #include <winstl/error/error_desc.hpp> |
---|
27 | #include <winstl/filesystem/current_directory.hpp> |
---|
28 | #include <winstl/shell/browse_for_folder.hpp> |
---|
29 | #include <winstl/shell/file_operations.hpp> |
---|
30 | #include <stlsoft/smartptr/scoped_handle.hpp> |
---|
31 | #include <winstl/shell/memory/functions.h> |
---|
32 | |
---|
33 | namespace hal |
---|
34 | { |
---|
35 | |
---|
36 | class app_impl |
---|
37 | { |
---|
38 | public: |
---|
39 | app_impl() : |
---|
40 | hmod_(NULL), |
---|
41 | instance_(_Module.GetModuleInstance()), |
---|
42 | initial_path_(boost::filesystem::initial_path<boost::filesystem::wpath>()) |
---|
43 | { |
---|
44 | LPWSTR *szArglist; int nArgs; |
---|
45 | szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); |
---|
46 | |
---|
47 | std::locale global_loc = std::locale(); |
---|
48 | std::locale loc(global_loc, new boost::filesystem::detail::utf8_codecvt_facet); |
---|
49 | boost::filesystem::wpath_traits::imbue(loc); |
---|
50 | |
---|
51 | if (NULL == szArglist) |
---|
52 | { |
---|
53 | } |
---|
54 | else |
---|
55 | { |
---|
56 | exe_string_ = szArglist[0]; |
---|
57 | exe_path_ = boost::filesystem::wpath(exe_string_); |
---|
58 | |
---|
59 | for (int i=1; i<nArgs; ++i) |
---|
60 | command_args_.push_back(szArglist[i]); |
---|
61 | |
---|
62 | working_directory_ = exe_path_.parent_path(); |
---|
63 | } |
---|
64 | LocalFree(szArglist); |
---|
65 | |
---|
66 | } |
---|
67 | |
---|
68 | friend class app_module; |
---|
69 | |
---|
70 | private: |
---|
71 | HMODULE hmod_; |
---|
72 | HINSTANCE instance_; |
---|
73 | std::wstring exe_string_; |
---|
74 | std::wstring res_dll_; |
---|
75 | |
---|
76 | boost::filesystem::wpath exe_path_; |
---|
77 | boost::filesystem::wpath initial_path_; |
---|
78 | boost::filesystem::wpath working_directory_; |
---|
79 | boost::optional<boost::filesystem::wpath> local_appdata_; |
---|
80 | |
---|
81 | std::vector<std::wstring> command_args_; |
---|
82 | }; |
---|
83 | |
---|
84 | app_module::app_module() : |
---|
85 | pimpl_(new app_impl()) |
---|
86 | {} |
---|
87 | |
---|
88 | const std::wstring& app_module::exe_string() const |
---|
89 | { |
---|
90 | return pimpl_->exe_string_; |
---|
91 | } |
---|
92 | |
---|
93 | const boost::filesystem::wpath& app_module::exe_path() const |
---|
94 | { |
---|
95 | return pimpl_->exe_path_; |
---|
96 | } |
---|
97 | |
---|
98 | const boost::filesystem::wpath& app_module::initial_path() const |
---|
99 | { |
---|
100 | return pimpl_->initial_path_; |
---|
101 | } |
---|
102 | |
---|
103 | const boost::filesystem::wpath& app_module::get_working_directory() const |
---|
104 | { |
---|
105 | return pimpl_->working_directory_; |
---|
106 | } |
---|
107 | |
---|
108 | void app_module::set_working_directory(const boost::filesystem::wpath& p) |
---|
109 | { |
---|
110 | pimpl_->working_directory_ = p; |
---|
111 | } |
---|
112 | |
---|
113 | const boost::optional<boost::filesystem::wpath>& app_module::get_local_appdata() const |
---|
114 | { |
---|
115 | if (!pimpl_->local_appdata_) |
---|
116 | { |
---|
117 | wchar_t displayName[_MAX_PATH + 1]; |
---|
118 | LPITEMIDLIST iil; |
---|
119 | HRESULT hr = ::SHGetSpecialFolderLocation(NULL, CSIDL_LOCAL_APPDATA, &iil); |
---|
120 | |
---|
121 | if(FAILED(hr)) |
---|
122 | { |
---|
123 | } |
---|
124 | else |
---|
125 | { |
---|
126 | stlsoft::scoped_handle<void*> iil_(iil, winstl::SHMemFree); |
---|
127 | |
---|
128 | ::SHGetPathFromIDList(iil, displayName); |
---|
129 | pimpl_->local_appdata_ = std::wstring(displayName); |
---|
130 | } |
---|
131 | } |
---|
132 | |
---|
133 | return pimpl_->local_appdata_; |
---|
134 | } |
---|
135 | |
---|
136 | const std::vector<std::wstring>& app_module::command_args() const |
---|
137 | { |
---|
138 | return pimpl_->command_args_; |
---|
139 | } |
---|
140 | |
---|
141 | void app_module::res_revert() |
---|
142 | { |
---|
143 | if (pimpl_->hmod_) FreeLibrary(pimpl_->hmod_); |
---|
144 | _Module.SetResourceInstance(pimpl_->instance_); |
---|
145 | } |
---|
146 | |
---|
147 | void app_module::res_set_dll(std::wstring dll) |
---|
148 | { |
---|
149 | if (pimpl_->hmod_) FreeLibrary(pimpl_->hmod_); |
---|
150 | pimpl_->res_dll_ = dll; |
---|
151 | |
---|
152 | HMODULE hmod_ = ::LoadLibraryEx(dll.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); |
---|
153 | _Module.SetResourceInstance(reinterpret_cast<HINSTANCE>(hmod_)); |
---|
154 | } |
---|
155 | |
---|
156 | std::wstring app_module::res_wstr(unsigned uID) |
---|
157 | { |
---|
158 | // The upper size limit ain't nice, but at least it's safe from buffer overflow |
---|
159 | win_c_str<std::wstring> str(2048); |
---|
160 | |
---|
161 | size_t size = ::LoadString(_Module.GetResourceInstance(), uID, str, str.size()); |
---|
162 | assert(size != 0); |
---|
163 | |
---|
164 | return str; |
---|
165 | } |
---|
166 | |
---|
167 | std::pair<void*,size_t> app_module::res_find_lock(unsigned name, unsigned type) |
---|
168 | { |
---|
169 | HRSRC rsrc = FindResource(_Module.GetResourceInstance(), (LPCTSTR)name, (LPCTSTR)type); |
---|
170 | assert(rsrc); |
---|
171 | |
---|
172 | HGLOBAL global = LoadResource(_Module.GetResourceInstance(), rsrc); |
---|
173 | assert(global); |
---|
174 | |
---|
175 | void* ptr = LockResource(global); |
---|
176 | assert(ptr); |
---|
177 | |
---|
178 | return std::pair<void*,size_t>(ptr, SizeofResource(_Module.GetResourceInstance(), rsrc)); |
---|
179 | } |
---|
180 | |
---|
181 | app_module& app() |
---|
182 | { |
---|
183 | static app_module app; |
---|
184 | return app; |
---|
185 | } |
---|
186 | |
---|
187 | } // namespace hal |
---|