Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/src/win32.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (show annotations) (download) (as text)
Tue Jan 8 07:04:36 2013 UTC (11 years, 3 months ago) by z0rac
File MIME type: text/x-c++src
File size: 7162 byte(s)


1 /*
2 * Copyright (C) 2009-2013 TSUBAKIMOTO Hiroya <z0rac@users.sourceforge.jp>
3 *
4 * This software comes with ABSOLUTELY NO WARRANTY; for details of
5 * the license terms, see the LICENSE.txt file included with the program.
6 */
7 #include "win32.h"
8 #include <cassert>
9 #include <shlwapi.h>
10 #include <process.h>
11
12 #ifdef _DEBUG
13 #include <iostream>
14 #define DBG(s) s
15 #define LOG(s) (cout << s)
16 #else
17 #define DBG(s)
18 #define LOG(s)
19 #endif
20
21 /*
22 * Functions of the class win32
23 */
24 win32::win32(LPCSTR mutex)
25 {
26 if (mutex &&
27 (!CreateMutex(NULL, TRUE, mutex) ||
28 GetLastError() == ERROR_ALREADY_EXISTS)) throw error();
29 }
30
31 string
32 win32::profile(LPCSTR section, LPCSTR key, LPCSTR file)
33 {
34 if (!file) return string();
35 textbuf<char> buf;
36 DWORD size = 0;
37 for (DWORD n = 0; n <= size + 2;) {
38 n += 256;
39 size = GetPrivateProfileString(section, key, "", buf(n), n, file);
40 }
41 size_t i = size && key ? strspn(buf.data, " \t") : 0;
42 return string(buf.data + i, size - i);
43 }
44
45 void
46 win32::profile(LPCSTR section, LPCSTR key, LPCSTR value, LPCSTR file)
47 {
48 file && WritePrivateProfileString(section, key, value, file);
49 }
50
51 string
52 win32::xenv(const string& s)
53 {
54 textbuf<char> buf;
55 DWORD n = static_cast<DWORD>(s.size() + 1);
56 n = ExpandEnvironmentStrings(s.c_str(), buf(n), n);
57 if (n > s.size() + 1) ExpandEnvironmentStrings(s.c_str(), buf(n), n);
58 return buf.data;
59 }
60
61 string
62 win32::_datetime(time_t utc, DWORD flags, _dtfn fn)
63 {
64 SYSTEMTIME st;
65 { // convert a time_t value to SYSTEMTIME format.
66 LONGLONG ll = Int32x32To64(utc, 10000000) + 116444736000000000LL;
67 FILETIME ft = { DWORD(ll), DWORD(ll >> 32) }, lt;
68 FileTimeToLocalFileTime(&ft, &lt);
69 FileTimeToSystemTime(&lt, &st);
70 }
71 textbuf<char> buf;
72 int n = fn(LOCALE_USER_DEFAULT, flags, &st, NULL, NULL, 0);
73 return n && fn(LOCALE_USER_DEFAULT, flags, &st, NULL, buf(n), n) ?
74 string(buf.data, n - 1) : string();
75 }
76
77 HANDLE
78 win32::shell(const string& cmd, unsigned flags)
79 {
80 assert(!(flags & ~(SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
81 SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS)));
82 textbuf<char> tmp(cmd.size() + 1);
83 lstrcpyA(tmp.data, cmd.c_str());
84 PathRemoveArgs(tmp.data);
85 string::size_type i = lstrlen(tmp.data);
86 if (i < cmd.size()) i = cmd.find_first_not_of(" \t", i + 1);
87 SHELLEXECUTEINFO info = {
88 sizeof(SHELLEXECUTEINFO), flags, NULL, "open",
89 tmp.data, i < cmd.size() ? tmp.data + i : NULL, NULL, SW_SHOWNORMAL
90 };
91 return !ShellExecuteEx(&info) ? NULL :
92 (flags & SEE_MASK_NOCLOSEPROCESS) ? info.hProcess : INVALID_HANDLE_VALUE;
93 }
94
95 #ifdef _MT
96 HANDLE
97 win32::thread(void (*func)(void*), void* param)
98 {
99 class _thread {
100 void (*_func)(void*);
101 void* _param;
102 HANDLE _event;
103 static unsigned __stdcall _routine(void* param)
104 {
105 _thread th = *reinterpret_cast<_thread*>(param);
106 SetEvent(th._event);
107 try { th._func(th._param); } catch (...) {}
108 return 0;
109 }
110 public:
111 _thread(void (*func)(void*)) : _func(func) {}
112 HANDLE operator()(void* param)
113 {
114 _param = param;
115 _event = valid(CreateEvent(NULL, FALSE, FALSE, NULL));
116 uintptr_t p = _beginthreadex(NULL, 0, _routine, (void*)this, 0, NULL);
117 if (p) WaitForSingleObject(_event, INFINITE);
118 CloseHandle(_event);
119 return HANDLE(p);
120 }
121 };
122
123 return valid(_thread(func)(param));
124 }
125 #endif
126
127 #ifdef _DEBUG
128 #include <tlhelp32.h>
129 #include <malloc.h>
130
131 size_t
132 win32::cheapsize()
133 {
134 _heapmin();
135 size_t size = 0;
136 _HEAPINFO hi = { NULL };
137 for (;;) {
138 switch (_heapwalk(&hi)) {
139 case _HEAPOK:
140 if (hi._useflag == _USEDENTRY) size += hi._size;
141 break;
142 case _HEAPEND:
143 return size;
144 default:
145 LOG("cheapsize: BAD HEAP!" << endl);
146 return size;
147 }
148 }
149 }
150
151 size_t
152 win32::heapsize()
153 {
154 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, 0);
155 if (h == HANDLE(-1)) return 0;
156 size_t size = 0;
157 HEAPLIST32 hl = { sizeof(HEAPLIST32) };
158 if (Heap32ListFirst(h, &hl)) {
159 do {
160 HEAPENTRY32 he = { sizeof(HEAPENTRY32) };
161 if (Heap32First(&he, hl.th32ProcessID, hl.th32HeapID)) {
162 do {
163 if (!(he.dwFlags & LF32_FREE)) size += he.dwBlockSize;
164 } while (Heap32Next(&he));
165 }
166 } while (Heap32ListNext(h, &hl));
167 }
168 CloseHandle(h);
169 return size;
170 }
171 #endif
172
173 /*
174 * Functions of the class win32::module
175 */
176 FARPROC
177 win32::module::operator()(LPCSTR name) const
178 {
179 return valid(GetProcAddress(_h, name));
180 }
181
182 FARPROC
183 win32::module::operator()(LPCSTR name, FARPROC def) const
184 {
185 FARPROC proc = GetProcAddress(_h, name);
186 return proc ? proc : def;
187 }
188
189 string
190 win32::module::text(UINT id) const
191 {
192 textbuf<char> buf;
193 int size = 0;
194 for (int n = 0; n <= size + 1;) {
195 n += 256;
196 size = LoadString(_h, id, buf(n * 2), n * 2);
197 }
198 return string(buf.data, size);
199 }
200
201 string
202 win32::module::textf(UINT id, ...) const
203 {
204 string s = text(id);
205 textbuf<char> buf;
206 int size = 0;
207 for (int n = 0; n <= size + 1;) {
208 n += 512;
209 va_list arg;
210 va_start(arg, id);
211 size = wvnsprintf(buf(n), n, s.c_str(), arg);
212 va_end(arg);
213 }
214 return size > 0 ? string(buf.data, size) : s;
215 }
216
217 list<string>
218 win32::module::texts(UINT id) const
219 {
220 list<string> result;
221 string t = text(id);
222 if (t.size() > 1) {
223 char delim = *t.rbegin();
224 for (string::size_type i = 0; i < t.size();) {
225 string::size_type n = t.find_first_of(delim, i);
226 result.push_back(t.substr(i, n - i));
227 i = n + 1;
228 }
229 }
230 return result;
231 }
232
233 void*
234 win32::module::resource(LPCSTR type, LPCSTR name) const
235 {
236 HRSRC h = FindResource(_h, name, type);
237 return h ? LockResource(LoadResource(_h, h)) : NULL;
238 }
239
240 const win32::module win32::exe(GetModuleHandle(NULL));
241
242 /*
243 * Functions of the class win32::wstr
244 */
245 LPWSTR
246 win32::wstr::_new(LPCSTR s, UINT cp)
247 {
248 int size = MultiByteToWideChar(cp, 0, s, -1, NULL, 0);
249 if (!size) return NULL;
250 LPWSTR ws = new WCHAR[size];
251 MultiByteToWideChar(cp, 0, s, -1, ws, size);
252 return ws;
253 }
254
255 win32::wstr&
256 win32::wstr::operator=(LPCWSTR ws)
257 {
258 LPWSTR data = ws ? lstrcpyW(new WCHAR[lstrlenW(ws) + 1], ws) : NULL;
259 delete [] _data;
260 _data = data;
261 return *this;
262 }
263
264 win32::wstr&
265 win32::wstr::operator+=(LPCWSTR ws)
266 {
267 size_t n = ws ? lstrlenW(ws) : 0;
268 if (!n) return *this;
269 size_t l = _data ? lstrlenW(_data) : 0;
270 LPWSTR data = new WCHAR[l + n + 1];
271 if (l) lstrcpyW(data, _data);
272 lstrcpyW(data + l, ws);
273 delete [] _data;
274 _data = data;
275 return *this;
276 }
277
278 string
279 win32::wstr::mbstr(LPCWSTR ws, UINT cp)
280 {
281 if (!ws) return string();
282 textbuf<char> buf;
283 int n = WideCharToMultiByte(cp, 0, ws, -1, NULL, 0, NULL, NULL);
284 return n && WideCharToMultiByte(cp, 0, ws, -1, buf(n), n, NULL, NULL) ?
285 string(buf.data, n - 1) : string();
286 }
287
288 /*
289 * Functions of the class win32::error
290 */
291 string
292 win32::error::emsg()
293 {
294 char s[35];
295 return string("WinAPI error #") + _ultoa(GetLastError(), s, 10);
296 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26