soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
utilities.cpp
1#include <utilities.h>
2#include <string/strcpcvt.h>
3#include <xml/SXml.h>
4#include <souicoll.h>
5#include <tchar.h>
6#ifdef _WIN32
7#include <shlwapi.h>
8#pragma comment(lib,"shlwapi.lib")
9#pragma comment(lib, "version.lib")
10#pragma warning(disable : 4996)
11#else
12#include <strapi.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
18int RectWidth(LPCRECT rc) {return rc->right-rc->left;}
19int RectHeight(LPCRECT rc) {return rc->bottom-rc->top;}
20
21#define HIMETRIC_PER_INCH 2540
22#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
23#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH)
24#ifdef _WIN32
25HANDLE WINAPI LoadImageBuf(const void* buf, UINT length, UINT type,
26 INT desiredx, INT desiredy, UINT loadflags);
27
28void SHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix)
29{
30 int nPixelsPerInchX; // Pixels per logical inch along width
31 int nPixelsPerInchY; // Pixels per logical inch along height
32
33 HDC hDCScreen = GetDC(NULL);
34 nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
35 nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
36 ReleaseDC(NULL, hDCScreen);
37
38 lpSizeInPix->cx = MAP_LOGHIM_TO_PIX(lpSizeInHiMetric->cx, nPixelsPerInchX);
39 lpSizeInPix->cy = MAP_LOGHIM_TO_PIX(lpSizeInHiMetric->cy, nPixelsPerInchY);
40}
41
42void SPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric)
43{
44 int nPixelsPerInchX; // Pixels per logical inch along width
45 int nPixelsPerInchY; // Pixels per logical inch along height
46
47 HDC hDCScreen = GetDC(NULL);
48 nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
49 nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
50 ReleaseDC(NULL, hDCScreen);
51
52 lpSizeInHiMetric->cx = MAP_PIX_TO_LOGHIM(lpSizeInPix->cx, nPixelsPerInchX);
53 lpSizeInHiMetric->cy = MAP_PIX_TO_LOGHIM(lpSizeInPix->cy, nPixelsPerInchY);
54}
55
56BOOL UpdateDIBPixmap(HBITMAP bmp, int wid, int hei, int bitsPixel, int stride, CONST VOID* pjBits) {
57 BITMAP bm = { 0 };
58 GetObject(bmp, sizeof(bm), &bm);
59 if (!bm.bmBits)
60 return FALSE;
61 if (bm.bmWidth != wid || bm.bmHeight != hei || bm.bmBitsPixel != bitsPixel)
62 return FALSE;
63 if (pjBits)
64 memcpy(bm.bmBits, pjBits, hei * stride);
65 else
66 memset(bm.bmBits, 0, hei * stride);
67 return TRUE;
68}
69#endif
70
71int Str2IntW(LPCWSTR src,BOOL supportHex)
72{
73 int nRet = 0;
74 StrToIntExW(src, supportHex?STIF_SUPPORT_HEX:STIF_DEFAULT, &nRet);
75 return nRet;
76}
77
78int Str2IntA(LPCSTR src, BOOL supportHex)
79{
80 int nRet = 0;
81 StrToIntExA(src, supportHex ? STIF_SUPPORT_HEX : STIF_DEFAULT, &nRet);
82 return nRet;
83}
84
85SNS::IStringA * CreateIStringA(LPCSTR src)
86{
87 return new SNS::SStringA(src);
88}
89
90SNS::IStringW * CreateIStringW(LPCWSTR src)
91{
92 return new SNS::SStringW(src);
93}
94
95SNS::IXmlDoc * CreateIXmlDoc()
96{
97 return new SNS::SXmlDoc();
98}
99
100#ifdef _WIN32
101
102static int getScaleOld(HWND hWnd = NULL)
103{
104 HDC screen = ::GetDC(hWnd);
105 int nScale = 100;
106 nScale = GetDeviceCaps(screen, LOGPIXELSX) * 100 / 96;
107 ReleaseDC(hWnd, screen);
108 return nScale;
109}
110
111// 获取一个PE文件的version
112static BOOL PEVersion(LPCTSTR pszFileName, WORD& wMajor, WORD& wMinor, WORD& wVer3, WORD& wVer4)
113{
114 DWORD dwResHandle;
115 void* pBuf;
116 DWORD dwVerInfoSize = GetFileVersionInfoSize(pszFileName, &dwResHandle);
117 if (!dwVerInfoSize)
118 return FALSE;
119 pBuf = malloc(dwVerInfoSize);
120 if (!pBuf)
121 return FALSE;
122 GetFileVersionInfo(pszFileName, dwResHandle, dwVerInfoSize, pBuf);
123 UINT nVersionLen;
124 VS_FIXEDFILEINFO* pstFileVersion;
125 if (VerQueryValue(pBuf, _T("\\"), (void**)&pstFileVersion, &nVersionLen) && nVersionLen >= sizeof(VS_FIXEDFILEINFO))
126 {
127 wVer4 = LOWORD(pstFileVersion->dwFileVersionLS);
128 wVer3 = HIWORD(pstFileVersion->dwFileVersionLS);
129 wMinor = LOWORD(pstFileVersion->dwFileVersionMS);
130 wMajor = HIWORD(pstFileVersion->dwFileVersionMS);
131 }
132 free(pBuf);
133 return TRUE;
134}
135
136static BOOL IsVerOrGreater(WORD wVers[4], WORD wMajor, WORD wMinor, WORD wSpBuild = 0)
137{
138 if (wVers[0] < wMajor)
139 return FALSE;
140 if (wVers[0] > wMajor)
141 return TRUE;
142 if (wVers[1] < wMinor)
143 return FALSE;
144 if (wVers[1] > wMinor)
145 return TRUE;
146
147 return wVers[2] >= wSpBuild;
148}
149
150int GetWindowScale(HWND hWnd)
151{
152 WORD wVers[4];
153 PEVersion(_T("ntdll.dll"), wVers[0], wVers[1], wVers[2], wVers[3]);
154 // win7
155 if (!IsVerOrGreater(wVers, 6, 1, 7600))
156 return 100;
157 int nScale = 100;
158 // For Win10 1607
159 if (IsVerOrGreater(wVers, 10, 0, 14955))
160 {
161 HMODULE hModule = LoadLibrary(_T("User32.dll"));
162 if (hModule)
163 {
164 typedef UINT(WINAPI* FunGetDpiForWindow)(HWND);
165
166 FunGetDpiForWindow GetDpiForWindow = (FunGetDpiForWindow)GetProcAddress(hModule, "GetDpiForWindow");
167 if (GetDpiForWindow)
168 {
169 UINT dpi = GetDpiForWindow(hWnd);
170 nScale = dpi * 100 / 96;
171 }
172 FreeLibrary(hModule);
173 }
174 }
175 // for win 8.1 or later
176 else if (IsVerOrGreater(wVers, 6, 3))
177 {
178 HMODULE hModule = LoadLibrary(_T("Shcore.dll"));
179 if (hModule)
180 {
181 RECT winrc;
182 GetWindowRect(hWnd, &winrc);
183 HMONITOR hMonitor = MonitorFromRect(&winrc, MONITOR_DEFAULTTONEAREST);
184 UINT dpiX, dpiY;
185 typedef enum _MONITOR_DPI_TYPE
186 {
187 MDT_EFFECTIVE_DPI = 0,
188 MDT_ANGULAR_DPI = 1,
189 MDT_RAW_DPI = 2,
190 MDT_DEFAULT = MDT_EFFECTIVE_DPI
191 } MONITOR_DPI_TYPE;
192 typedef HRESULT(WINAPI* FunGetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
193
194 FunGetDpiForMonitor GetDpiForMonitor = (FunGetDpiForMonitor)GetProcAddress(hModule, "GetDpiForMonitor");
195 if (GetDpiForMonitor)
196 {
197 HRESULT hr = GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
198 if (SUCCEEDED(hr))
199 {
200 nScale = dpiX * 100 / 96;
201 }
202 }
203 FreeLibrary(hModule);
204 }
205 }
206 else
207 {
208 nScale = getScaleOld(hWnd);
209 }
210 return nScale;
211}
212
213
214static int CALLBACK DefFontsEnumProc(CONST LOGFONT* lplf, // logical-font data
215 CONST TEXTMETRIC* lptm, // physical-font data
216 DWORD dwType, // font type
217 LPARAM lpData // application-defined data
218)
219{
220 BOOL* pbValidFont = (BOOL*)lpData;
221 *pbValidFont = TRUE;
222 return 0; // stop enum.
223}
224
225BOOL HasFont(LPCTSTR fontName) {
226 HDC hdc = GetDC(NULL);
227 BOOL bValidFont = FALSE;
228 EnumFonts(hdc, fontName, DefFontsEnumProc, (LPARAM)&bValidFont);
229 ReleaseDC(NULL, hdc);
230 return bValidFont;
231}
232
233BOOL IsSupportMaxMove()
234{
235 OSVERSIONINFOEX OSVerInfo;
236 BOOL bOsVersionInfoEx;
237
238 ::ZeroMemory(&OSVerInfo, sizeof(OSVERSIONINFOEX));
239
240 // Get the OS Version Information
241 OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
242 bOsVersionInfoEx = ::GetVersionEx((OSVERSIONINFO*)&OSVerInfo);
243 if (!(bOsVersionInfoEx))
244 {
245 OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
246 if (!::GetVersionEx((OSVERSIONINFO*)&OSVerInfo))
247 {
248 return FALSE;
249 }
250 }
251
252 /**
253 * Does it support Windows 8.1,Windows 8,Windows 7,Windows Vista ?
254 * I just ignore the Windows Server System
255 * if you wanna get more information, you can click the following link:
256 * http://msdn.microsoft.com/en-us/library/ms724833.aspx
257 */
258 if (OSVerInfo.wProductType == VER_NT_WORKSTATION && OSVerInfo.dwMajorVersion == 6)
259 {
260 return TRUE;
261 }
262 return FALSE;
263}
264
265long file_length_A(const char* path) {
266 WIN32_FIND_DATAA wfd;
267 HANDLE hf = FindFirstFileA(path, &wfd);
268 if (INVALID_HANDLE_VALUE == hf)
269 return 0;
270 FindClose(hf);
271 return wfd.nFileSizeLow;
272}
273
274long file_length_W(const wchar_t* path) {
275 WIN32_FIND_DATAW wfd;
276 HANDLE hf = FindFirstFileW(path, &wfd);
277 if (INVALID_HANDLE_VALUE == hf)
278 return 0;
279 FindClose(hf);
280 return wfd.nFileSizeLow;
281}
282
283#else
284
285int GetWindowScale(HWND hWnd)
286{
287 int dpi = GetDpiForWindow(hWnd);
288 return dpi*100/96;
289}
290
291BOOL HasFont(LPCTSTR fontName) {
292 return TRUE;
293}
294
295BOOL IsSupportMaxMove() {
296 return FALSE;
297}
298
299long file_length(const char* path)
300{
301 struct stat st;
302 int fd = stat(path, &st);
303 if(fd != 0)
304 return 0;
305 if (S_ISDIR(st.st_mode))
306 return 0;
307 return st.st_size;
308}
309
310#endif//_WIN32
311
312
313HANDLE LoadIconFromMemory(const void* buf, UINT cbSize, BOOL fIcon, int width, int height, UINT cFlag) {
314 UINT type = fIcon ? IMAGE_ICON : IMAGE_CURSOR;
315 return LoadImageBuf(buf, cbSize, type, width, height, cFlag);
316}
317
318
319
320HRGN CreateRegionFromBitmap(HBITMAP hBmp, COLORREF crKey,COLORREF crMask)
321{
322 BITMAP bm={0};
323 GetObject(hBmp,sizeof(bm),&bm);
324 if(bm.bmBitsPixel!=32 || bm.bmBits==0)
325 return 0;
326 // 获取图像表面的数据指针
327 const COLORREF *bits = (const COLORREF *)bm.bmBits;
328
329 SNS::SArray<RECT> lstRc;
330 for (int y = 0; y < bm.bmHeight; y++, bits += bm.bmWidth)
331 {
332 int x = 0;
333 while (x < bm.bmWidth)
334 {
335 while (x < bm.bmWidth && (bits[x] & crMask) == crKey)
336 x++;
337 int start = x;
338 while (x < bm.bmWidth && (bits[x] & crMask) != crKey)
339 x++;
340 if (start != x)
341 {
342 RECT rc = { start, y, x, y + 1 };
343 lstRc.Add(rc);
344 }
345 }
346 }
347 if (!lstRc.IsEmpty())
348 {
349 size_t len = sizeof(RGNDATAHEADER) + sizeof(RECT) * lstRc.GetCount();
350 RGNDATA *pRgn = (RGNDATA *)malloc(len);
351 pRgn->rdh.nCount = (DWORD)lstRc.GetCount();
352 pRgn->rdh.iType = RDH_RECTANGLES;
353 memcpy(pRgn->Buffer, lstRc.GetData(), sizeof(RECT) * lstRc.GetCount());
354 HRGN hRgn = ExtCreateRegion(NULL, (DWORD)len, pRgn);
355 free(pRgn);
356 return hRgn;
357 }
358 return 0;
359}
360
361BOOL IsFilePathValid(LPCTSTR strPath) {
362 DWORD dwAttr = ::GetFileAttributes(strPath);
363 if(dwAttr == INVALID_FILE_ATTRIBUTES)
364 return FALSE;
365 return (dwAttr & FILE_ATTRIBUTE_DIRECTORY)==0;
366}