FWin32.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. /*
  2. * Copyright (C) =USTC= Fu Li
  3. *
  4. * Author : Fu Li
  5. * Create : 2005-9-29
  6. * Home : http://www.crazy-bit.com/
  7. * Mail : crazybit@263.net
  8. * History :
  9. */
  10. #ifdef WIN32
  11. #ifndef __PCL_WIN32__2005_09_29__H__
  12. #define __PCL_WIN32__2005_09_29__H__
  13. #include "ObjLayer.h"
  14. #include "ObjSelect.h"
  15. #include <shellapi.h>
  16. //=============================================================================
  17. /**
  18. * WIN32 API wrapper.
  19. */
  20. class FCWin32
  21. {
  22. public:
  23. //=============================================================================
  24. /// Test vKey downing now.
  25. static BOOL IsKeyDown (int vKey)
  26. {
  27. assert (vKey!=VK_CAPITAL && vKey!=VK_NUMLOCK && vKey!=VK_SCROLL) ;
  28. return (::GetKeyState(vKey) & 0x8000) ;
  29. }
  30. /// Open URL use default browser.
  31. static void DefaultBrowserURL (LPCTSTR strURL)
  32. {
  33. // test default browser is IE
  34. BOOL bIE = TRUE ;
  35. HKEY hKey = NULL ;
  36. LONG l = ::RegOpenKeyEx (HKEY_CLASSES_ROOT, TEXT("htmlfile\\shell\\open\\command"), 0, KEY_ALL_ACCESS, &hKey) ;
  37. if (l == ERROR_SUCCESS)
  38. {
  39. TCHAR szPath[MAX_PATH] = {0} ;
  40. DWORD dw = sizeof(TCHAR) * MAX_PATH,
  41. dwType = REG_SZ ;
  42. ::RegQueryValueEx (hKey, NULL, NULL, &dwType, (BYTE*)szPath, &dw) ;
  43. ::RegCloseKey (hKey) ;
  44. std::string s = (char*)bstr_t(szPath) ;
  45. bIE = (s.find("iexplore.exe") != std::string::npos) ;
  46. }
  47. if (bIE)
  48. ::ShellExecute (NULL, TEXT("open"), TEXT("iexplore.exe"), strURL, NULL, SW_SHOW) ;
  49. else
  50. ::ShellExecute (NULL, TEXT("open"), strURL, NULL, NULL, SW_SHOW) ;
  51. }
  52. //=============================================================================
  53. /**
  54. * Register a COM server.
  55. */
  56. static BOOL RegisterCOMServer (LPCTSTR strComDllPath)
  57. {
  58. HMODULE hModule = ::LoadLibrary(strComDllPath) ;
  59. BOOL b = FALSE ;
  60. if (hModule)
  61. {
  62. typedef HRESULT (*pDLLRegisterServer)() ;
  63. pDLLRegisterServer pfn = (pDLLRegisterServer)::GetProcAddress (hModule, "DllRegisterServer") ;
  64. if (pfn && (pfn() == S_OK))
  65. b = TRUE ;
  66. FreeLibrary(hModule) ;
  67. }
  68. return b ;
  69. }
  70. //=============================================================================
  71. /**
  72. * UnRegister a COM server.
  73. */
  74. static BOOL UnRegisterCOMServer (LPCTSTR strComDllPath)
  75. {
  76. HMODULE hModule = ::LoadLibrary(strComDllPath) ;
  77. BOOL b = FALSE ;
  78. if (hModule)
  79. {
  80. typedef HRESULT (*pDLLUnRegisterServer)() ;
  81. pDLLUnRegisterServer pfn = (pDLLUnRegisterServer)::GetProcAddress (hModule, "DllUnregisterServer") ;
  82. if (pfn && (pfn() == S_OK))
  83. b = TRUE ;
  84. FreeLibrary(hModule) ;
  85. }
  86. return b ;
  87. }
  88. /**
  89. * @name Character Set convert.
  90. */
  91. //@{
  92. //=============================================================================
  93. /**
  94. * Convert a UTF-8 string to a ASCII string.
  95. */
  96. static std::string UTF8_to_ANSI (const char* szUTF8)
  97. {
  98. if (szUTF8 == NULL)
  99. return "" ;
  100. int nLen = ::MultiByteToWideChar (CP_UTF8, 0, szUTF8, -1, NULL, 0) ;
  101. WCHAR * pWstr = new WCHAR[nLen+1] ;
  102. ZeroMemory (pWstr, sizeof(WCHAR) * (nLen+1)) ;
  103. ::MultiByteToWideChar (CP_UTF8, 0, szUTF8, -1, pWstr, nLen) ;
  104. std::string strAnsi (_bstr_t((wchar_t*)pWstr)) ;
  105. delete[] pWstr ;
  106. return strAnsi ;
  107. }
  108. //=============================================================================
  109. /**
  110. * Convert a UTF-8 string to a ASCII string.
  111. */
  112. static std::string ANSI_to_UTF8 (const char* szAnsi)
  113. {
  114. if (szAnsi == NULL)
  115. return "" ;
  116. _bstr_t bstrTmp (szAnsi) ;
  117. int nLen = ::WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)bstrTmp, -1, NULL, 0, NULL, NULL) ;
  118. char * pUTF8 = new char[nLen+1] ;
  119. ZeroMemory (pUTF8, nLen + 1) ;
  120. ::WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)bstrTmp, -1, pUTF8, nLen, NULL, NULL) ;
  121. std::string strUTF (pUTF8) ;
  122. delete[] pUTF8 ;
  123. return strUTF ;
  124. }
  125. //@}
  126. /**
  127. * @name Autorun at startup of windows.
  128. */
  129. //@{
  130. //=============================================================================
  131. /**
  132. * Get auto run value string.
  133. */
  134. static bstr_t GetAutoRunValue (LPCTSTR szValue)
  135. {
  136. HKEY hKey = NULL ;
  137. TCHAR sK[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run") ;
  138. LONG l = ::RegOpenKeyEx (uis_GetRootKey(), sK, 0, KEY_ALL_ACCESS, &hKey) ;
  139. if (l != ERROR_SUCCESS)
  140. {assert(FALSE); return "";}
  141. TCHAR szPath[MAX_PATH] = {0} ;
  142. DWORD dw = sizeof(TCHAR) * MAX_PATH,
  143. dwType = REG_SZ ;
  144. ::RegQueryValueEx (hKey, szValue, NULL, &dwType, (BYTE*)szPath, &dw) ;
  145. ::RegCloseKey (hKey) ;
  146. return szPath ;
  147. }
  148. //=============================================================================
  149. /**
  150. * Set auto run value string.
  151. */
  152. static void SetAutoRunValue (LPCTSTR szValue, LPCTSTR szString)
  153. {
  154. HKEY hKey = NULL ;
  155. TCHAR sK[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run") ;
  156. LONG l = ::RegOpenKeyEx (uis_GetRootKey(), sK, 0, KEY_ALL_ACCESS, &hKey) ;
  157. if (l != ERROR_SUCCESS)
  158. {assert(FALSE); return;}
  159. ::RegDeleteValue (hKey, szValue) ;
  160. if (lstrlen(szString))
  161. {
  162. ::RegSetValueEx (hKey, szValue, NULL, REG_SZ, (BYTE*)szString, (lstrlen(szString)+1)*sizeof(TCHAR)) ;
  163. }
  164. ::RegCloseKey (hKey) ;
  165. }
  166. //=============================================================================
  167. /**
  168. * Is autorun enable.
  169. */
  170. static BOOL IsAutoRunEnable (LPCTSTR szValue)
  171. {
  172. return GetAutoRunValue(szValue).length() ? TRUE : FALSE ;
  173. }
  174. //=============================================================================
  175. /**
  176. * Set autorun enable.
  177. */
  178. static void SetAutoRunEnable (LPCTSTR szValue, BOOL bEnable)
  179. {
  180. if (bEnable)
  181. {
  182. TCHAR szPath[MAX_PATH] = {0} ;
  183. ::GetModuleFileName (NULL, szPath, MAX_PATH) ;
  184. SetAutoRunValue (szValue, szPath) ;
  185. }
  186. else
  187. {
  188. SetAutoRunValue (szValue, NULL) ;
  189. }
  190. }
  191. //@}
  192. /**
  193. * @name IE's menu item.
  194. */
  195. //@{
  196. //=============================================================================
  197. /**
  198. * Is IE's menu item enable.
  199. */
  200. static BOOL IsIEMenuItemEnable (LPCTSTR szItemShow)
  201. {
  202. TCHAR szGroup[MAX_PATH] = TEXT("Software\\Microsoft\\Internet Explorer\\MenuExt\\") ;
  203. ::lstrcat (szGroup, szItemShow) ;
  204. HKEY hKey = NULL ;
  205. BOOL bRet = (::RegOpenKeyEx (HKEY_CURRENT_USER, szGroup, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) ;
  206. ::RegCloseKey (hKey) ;
  207. return bRet ;
  208. }
  209. //=============================================================================
  210. /**
  211. * Add/Remove IE's menu item.
  212. */
  213. static void SetIEMenuItem (BOOL bAdd, LPCTSTR szItemShow, LPCTSTR szHtmlPath)
  214. {
  215. TCHAR szKey[MAX_PATH] = TEXT("Software\\Microsoft\\Internet Explorer\\MenuExt\\") ;
  216. ::lstrcat (szKey, szItemShow) ;
  217. ::RegDeleteKey (HKEY_CURRENT_USER, szKey) ;
  218. if (bAdd)
  219. {
  220. HKEY hKey = NULL ;
  221. LONG l = ::RegCreateKeyEx (HKEY_CURRENT_USER, szKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL) ;
  222. if (l != ERROR_SUCCESS)
  223. {assert(FALSE); return;}
  224. ::RegSetValue (hKey, NULL, REG_SZ, szHtmlPath, ::lstrlen(szHtmlPath) * sizeof(TCHAR)) ;
  225. ::RegCloseKey (hKey) ;
  226. }
  227. }
  228. //@}
  229. /**
  230. * @name Window always on top.
  231. */
  232. //@{
  233. //=============================================================================
  234. /**
  235. * Test a window have WS_EX_TOPMOST property.
  236. */
  237. static BOOL IsWindowAlwaysTop (HWND hWnd)
  238. {
  239. return (GetWindowLong(hWnd,GWL_EXSTYLE) & WS_EX_TOPMOST) ;
  240. }
  241. //=============================================================================
  242. /**
  243. * Set/Clear a window's WS_EX_TOPMOST property.
  244. */
  245. static void SetWindowAlwaysTop (HWND hWnd, BOOL bTop)
  246. {
  247. if (!::IsWindow(hWnd) || (::GetDesktopWindow() == hWnd))
  248. return ;
  249. if (bTop)
  250. {
  251. if (!IsWindowAlwaysTop(hWnd))
  252. ::SetWindowPos (hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE) ;
  253. }
  254. else
  255. {
  256. if (IsWindowAlwaysTop(hWnd))
  257. ::SetWindowPos (hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE) ;
  258. }
  259. }
  260. //@}
  261. /**
  262. * @name Convert between GDI HBITMAP(DDB) and FCObjImage.
  263. */
  264. //@{
  265. //=============================================================================
  266. /**
  267. * Create DDB handle from FCObjImage object.
  268. */
  269. static HBITMAP CreateDDBHandle (const FCObjImage& img)
  270. {
  271. if (!img.IsValidImage())
  272. {assert(false); return NULL;}
  273. // prepare info
  274. PCL_array<BITMAPINFOHEADER> bmfh (img.NewImgInfoWithPalette()) ;
  275. HDC hdc = ::GetDC (NULL) ;
  276. HBITMAP hDDB = CreateDIBitmap (hdc, bmfh.get(), CBM_INIT, (VOID*)img.GetMemStart(), (BITMAPINFO*)bmfh.get(), DIB_RGB_COLORS) ;
  277. ::ReleaseDC (NULL, hdc) ;
  278. return hDDB ;
  279. }
  280. //=============================================================================
  281. /**
  282. * Create FCObjImage object from DDB handle.
  283. */
  284. static void CreateImageFromDDB (HBITMAP hBitmap, FCObjImage& img)
  285. {
  286. BITMAP bm ;
  287. ::GetObject (hBitmap, sizeof(BITMAP), &bm) ;
  288. HDC hdc = ::CreateCompatibleDC(NULL) ;
  289. HGDIOBJ hOld = ::SelectObject (hdc, hBitmap) ;
  290. RECT rc = {0, 0, bm.bmWidth, bm.bmHeight} ;
  291. CaptureDC (img, hdc, rc) ;
  292. ::SelectObject (hdc, hOld) ;
  293. ::DeleteDC(hdc) ;
  294. }
  295. //@}
  296. //=============================================================================
  297. /**
  298. * Load FCObjImage object from resource.
  299. */
  300. static void LoadImageRes (FCObjImage& img, LPCTSTR resName, LPCTSTR resType, IMAGE_TYPE imgType, HMODULE hMod=NULL)
  301. {
  302. HRSRC res = ::FindResource (hMod, resName, resType) ;
  303. BYTE * pImgData = (BYTE*)::LockResource (::LoadResource (hMod, res)) ;
  304. if (pImgData)
  305. img.Load (pImgData, ::SizeofResource (hMod, res), imgType) ;
  306. }
  307. //=============================================================================
  308. /**
  309. * Load FCObjImage object from standard Bitmap resource.
  310. */
  311. static void LoadImageBitmapRes (FCObjImage& img, LPCTSTR resName, HMODULE hMod=NULL)
  312. {
  313. HRSRC res = ::FindResource (hMod, resName, RT_BITMAP) ;
  314. BYTE * pImgData = (BYTE*)::LockResource (::LoadResource (hMod, res)) ;
  315. if (pImgData)
  316. img.LoadDIBStream (pImgData, (int)::SizeofResource(hMod, res)) ;
  317. }
  318. /**
  319. * @name Draw image.
  320. */
  321. //@{
  322. //=============================================================================
  323. /**
  324. * Draw entire image to hdc at position (x,y), no scale.
  325. */
  326. static void DrawImage (const FCObjImage& img, HDC hdc, int x, int y)
  327. {
  328. if (!img.IsValidImage())
  329. return ;
  330. // prepare info
  331. PCL_array<BITMAPINFO> bmfh (img.NewImgInfoWithPalette()) ;
  332. // start draw
  333. int nOldMode = ::SetStretchBltMode (hdc, COLORONCOLOR) ;
  334. ::SetDIBitsToDevice (hdc, x, y, img.Width(), img.Height(), 0, 0, 0, img.Height(),
  335. img.GetMemStart(), bmfh.get(), DIB_RGB_COLORS) ;
  336. ::SetStretchBltMode (hdc, nOldMode) ;
  337. }
  338. //=============================================================================
  339. /**
  340. * Draw rcImg of image to rcDrawDC of hdc.
  341. */
  342. static void DrawImage (const FCObjImage& img, HDC hdc, RECT rcDrawDC, RECT rcImg)
  343. {
  344. if (!img.IsValidImage())
  345. return ;
  346. // prepare info
  347. PCL_array<BITMAPINFO> bmfh (img.NewImgInfoWithPalette()) ;
  348. // start draw
  349. int nOldMode = ::SetStretchBltMode (hdc, COLORONCOLOR),
  350. nYStart = img.Height() - (rcImg.top + RECTHEIGHT(rcImg)) ;
  351. ::StretchDIBits (hdc, rcDrawDC.left, rcDrawDC.top, RECTWIDTH(rcDrawDC), RECTHEIGHT(rcDrawDC),
  352. rcImg.left, nYStart, RECTWIDTH(rcImg), RECTHEIGHT(rcImg),
  353. img.GetMemStart(), bmfh.get(), DIB_RGB_COLORS, SRCCOPY) ;
  354. ::SetStretchBltMode (hdc, nOldMode) ;
  355. }
  356. //=============================================================================
  357. /**
  358. * Draw entire image to rcDrawDC of hdc.
  359. */
  360. static void DrawImage (const FCObjImage& img, HDC hdc, RECT rcDrawDC)
  361. {
  362. RECT rcImg = {0, 0, img.Width(), img.Height()} ;
  363. DrawImage (img, hdc, rcDrawDC, rcImg) ;
  364. }
  365. //=============================================================================
  366. /**
  367. * Draw(aspect) entire image to center of rcDrawDC.
  368. */
  369. static void DrawImageAspect (const FCObjImage& img, HDC hdc, RECT rcDrawDC)
  370. {
  371. if (!img.IsValidImage())
  372. return ;
  373. int nNewWidth = img.Width(),
  374. nNewHeight = img.Height() ;
  375. if ((img.Width() > RECTWIDTH(rcDrawDC)) || (img.Height() > RECTHEIGHT(rcDrawDC)))
  376. {
  377. double fScaleX = RECTWIDTH(rcDrawDC) / (double)img.Width(),
  378. fScaleY = RECTHEIGHT(rcDrawDC) / (double)img.Height(),
  379. fScale = FMin (fScaleX, fScaleY) ;
  380. nNewWidth = FMax (1, (int)(img.Width() * fScale)) ;
  381. nNewHeight = FMax (1, (int)(img.Height() * fScale)) ;
  382. }
  383. RECT rcShow = {0, 0, nNewWidth, nNewHeight} ;
  384. ::OffsetRect (&rcShow, (RECTWIDTH(rcDrawDC) - nNewWidth) / 2 + rcDrawDC.left,
  385. (RECTHEIGHT(rcDrawDC) - nNewHeight) / 2 + rcDrawDC.top) ;
  386. assert ((rcShow.left >= 0) && (rcShow.top >= 0)) ;
  387. DrawImage (img, hdc, rcShow) ;
  388. }
  389. //=============================================================================
  390. /**
  391. * AlphaBlend img32 on HDC.
  392. */
  393. static void AlphaImageOnDC (const FCObjImage& img32, HDC hdc, RECT rcOnDC, int nPercent=100)
  394. {
  395. if (!img32.IsValidImage() || (img32.ColorBits() != 32))
  396. return ;
  397. FCObjImage imgDC ;
  398. CaptureDC (imgDC, hdc, rcOnDC) ;
  399. RECT rcImg = {0, 0, img32.Width(), img32.Height()},
  400. rcDCImg = {0, 0, imgDC.Width(), imgDC.Height()} ;
  401. imgDC.AlphaBlend (img32, rcDCImg, rcImg, nPercent) ;
  402. DrawImage (imgDC, hdc, rcOnDC) ;
  403. }
  404. //@}
  405. //=============================================================================
  406. /**
  407. * Capture rcCap of hdc to FCObjImage.
  408. * <B>the received image color format is 24bpp</B>
  409. */
  410. static BOOL CaptureDC (FCObjImage& img, HDC hdc, RECT rcCap)
  411. {
  412. if (IsRectEmpty(&rcCap) || (GetDeviceCaps (hdc, BITSPIXEL) <= 8)) // palette format
  413. {assert(false); return FALSE;}
  414. HDC hMemDC = CreateCompatibleDC (hdc) ;
  415. HBITMAP hDDB = CreateCompatibleBitmap (hdc, RECTWIDTH(rcCap), RECTHEIGHT(rcCap)) ;
  416. if (hDDB == NULL)
  417. {
  418. ::DeleteDC (hMemDC) ;
  419. assert(false); return FALSE;
  420. }
  421. // start capture
  422. HGDIOBJ hOldBmp = ::SelectObject (hMemDC, hDDB) ;
  423. ::BitBlt (hMemDC, 0, 0, RECTWIDTH(rcCap), RECTHEIGHT(rcCap),
  424. hdc, rcCap.left, rcCap.top, SRCCOPY) ;
  425. ::SelectObject (hMemDC, hOldBmp) ;
  426. // attach FCObjImage to DDB
  427. BITMAP bm ;
  428. GetObject (hDDB, sizeof(BITMAP), &bm) ;
  429. if (img.Create (bm.bmWidth, bm.bmHeight, 24))
  430. {
  431. // dest format
  432. PCL_array<BITMAPINFO> bmfh (img.NewImgInfoWithPalette()) ;
  433. ::GetDIBits (hdc, hDDB, 0, bm.bmHeight, img.GetMemStart(), bmfh.get(), DIB_RGB_COLORS) ;
  434. }
  435. DeleteObject (hDDB) ;
  436. DeleteDC (hMemDC) ;
  437. return img.IsValidImage() ;
  438. }
  439. //=============================================================================
  440. /**
  441. * Capture rcCap of screen to FCObjImage.
  442. * <B>the received image color format is 24bpp</B>
  443. */
  444. static BOOL CaptureScreen (FCObjImage& img, RECT rcCap)
  445. {
  446. HDC hSrcDC = ::GetDC (NULL) ;
  447. BOOL bRet = CaptureDC (img, hSrcDC, rcCap) ;
  448. ::ReleaseDC (NULL, hSrcDC) ;
  449. return bRet ;
  450. }
  451. #ifdef PCL_3RD_LIBRARY_USE_GDIPLUS
  452. //=============================================================================
  453. /**
  454. * Create text layer object via GDI+.
  455. */
  456. static void CreateTextLayer_GDIPlus (FCObjTextLayer& layer, PACK_TextLayer tp)
  457. {
  458. // calculate un-addshadow position
  459. const POINT ptOldPos = {layer.GetGraphObjPos().x + layer.m_sizeToOldPos.cx,
  460. layer.GetGraphObjPos().y + layer.m_sizeToOldPos.cy} ;
  461. // --------------------------------------------------- create text image -------
  462. // calc font's Style
  463. INT gpFontStyle = Gdiplus::FontStyleRegular ;
  464. if (tp.m_bBold && tp.m_bItalic) gpFontStyle = Gdiplus::FontStyleBoldItalic ;
  465. else if (tp.m_bBold && !tp.m_bItalic) gpFontStyle = Gdiplus::FontStyleBold ;
  466. else if (!tp.m_bBold && tp.m_bItalic) gpFontStyle = Gdiplus::FontStyleItalic ;
  467. // create GDI+ font
  468. Gdiplus::Font gpFont (&Gdiplus::FontFamily((WCHAR*)bstr_t(tp.m_strFace.c_str())),
  469. (Gdiplus::REAL)tp.m_nFontSize,
  470. gpFontStyle,
  471. Gdiplus::UnitPoint) ;
  472. Gdiplus::TextRenderingHint gpAA = tp.m_bAntiAliased ? Gdiplus::TextRenderingHintAntiAlias : Gdiplus::TextRenderingHintSingleBitPerPixel ;
  473. // calculate string's bound box
  474. const bstr_t strText16 (tp.m_strText.c_str()) ;
  475. Gdiplus::RectF gpBound ;
  476. HDC hdcScreen = CreateCompatibleDC (NULL) ;
  477. {
  478. Gdiplus::Graphics gpGra (hdcScreen) ;
  479. gpGra.SetTextRenderingHint (gpAA) ;
  480. gpGra.MeasureString ((WCHAR*)strText16, -1, &gpFont, Gdiplus::PointF(0,0), &gpBound) ;
  481. gpBound.Width++ ; gpBound.Height++ ; // avoid empty rect
  482. }
  483. DeleteObject(hdcScreen) ;
  484. // create alpha-channel, i can't use 8-bit image :-(
  485. FCObjImage imgAlpha ((int)ceil(gpBound.Width), (int)ceil(gpBound.Height), 24) ;
  486. PCL_array<BITMAPINFO> imgInfo (imgAlpha.NewImgInfoWithPalette()) ;
  487. {
  488. // GDI+ draw string
  489. Gdiplus::Bitmap gpBmpMask (imgInfo.get(), imgAlpha.GetMemStart()) ;
  490. Gdiplus::Graphics gpGra (&gpBmpMask) ;
  491. gpGra.SetTextRenderingHint (gpAA) ;
  492. gpGra.DrawString ((WCHAR*)strText16, -1, &gpFont, Gdiplus::PointF(0,0), &Gdiplus::SolidBrush(Gdiplus::Color(255,255,255))) ;
  493. }
  494. // combine
  495. layer.FCObjImage::Create (imgAlpha.Width(), imgAlpha.Height(), 32) ;
  496. for (int y=0 ; y < layer.Height() ; y++)
  497. for (int x=0 ; x < layer.Width() ; x++)
  498. {
  499. BYTE * p = layer.GetBits(x,y) ;
  500. *(RGBQUAD*)p = tp.m_crFont ; // fill color
  501. PCL_A(p) = *imgAlpha.GetBits(x,y) ; // append alpha
  502. }
  503. // add shadow to image
  504. if (tp.m_bAddShadow)
  505. {
  506. FCPixelAddShadow aCmd(tp.m_ShadowData) ;
  507. layer.SinglePixelProcessProc (aCmd) ;
  508. }
  509. // --------------------------------------------------- create text image -------
  510. // calculate layer's position
  511. if (tp.m_bAddShadow)
  512. {
  513. RECT rcLayer = {0, 0, layer.Width(), layer.Height()} ;
  514. ::OffsetRect (&rcLayer, ptOldPos.x, ptOldPos.y) ;
  515. RECT rcShadow = rcLayer ;
  516. ::OffsetRect (&rcShadow, tp.m_ShadowData.nOffsetX, tp.m_ShadowData.nOffsetY) ;
  517. ::InflateRect (&rcShadow, tp.m_ShadowData.nSmooth, tp.m_ShadowData.nSmooth) ;
  518. ::UnionRect (&rcShadow, &rcLayer, &rcShadow) ;
  519. layer.SetGraphObjPos (rcShadow.left, rcShadow.top) ;
  520. }
  521. else
  522. layer.SetGraphObjPos (ptOldPos) ;
  523. // can be edit.
  524. layer.m_TxtLayerProp = tp ;
  525. layer.ToolEditFlag() = false ;
  526. // update position offset
  527. layer.m_sizeToOldPos.cx = ptOldPos.x - layer.GetGraphObjPos().x ;
  528. layer.m_sizeToOldPos.cy = ptOldPos.y - layer.GetGraphObjPos().y ;
  529. }
  530. #endif // PCL_3RD_LIBRARY_USE_GDIPLUS
  531. //=============================================================================
  532. /**
  533. * Draw selection object.
  534. * HDC's origin must have been located at top-left of canvas. <BR>
  535. * this function calculate edge point by canvas's zoom scale
  536. * @param rcCanvas : RECT of visible canvas, it's actual coordinate.
  537. */
  538. static void DrawSelection (HDC hdc, FCObjSelect& sel, const PCL_Interface_ZoomScale& canvas, RECT rcCanvas)
  539. {
  540. static const BYTE s_ant_data[8][8] =
  541. {
  542. {
  543. 0xF0, /* ####---- */
  544. 0xE1, /* ###----# */
  545. 0xC3, /* ##----## */
  546. 0x87, /* #----### */
  547. 0x0F, /* ----#### */
  548. 0x1E, /* ---####- */
  549. 0x3C, /* --####-- */
  550. 0x78, /* -####--- */
  551. },
  552. {
  553. 0xE1, /* ###----# */
  554. 0xC3, /* ##----## */
  555. 0x87, /* #----### */
  556. 0x0F, /* ----#### */
  557. 0x1E, /* ---####- */
  558. 0x3C, /* --####-- */
  559. 0x78, /* -####--- */
  560. 0xF0, /* ####---- */
  561. },
  562. {
  563. 0xC3, /* ##----## */
  564. 0x87, /* #----### */
  565. 0x0F, /* ----#### */
  566. 0x1E, /* ---####- */
  567. 0x3C, /* --####-- */
  568. 0x78, /* -####--- */
  569. 0xF0, /* ####---- */
  570. 0xE1, /* ###----# */
  571. },
  572. {
  573. 0x87, /* #----### */
  574. 0x0F, /* ----#### */
  575. 0x1E, /* ---####- */
  576. 0x3C, /* --####-- */
  577. 0x78, /* -####--- */
  578. 0xF0, /* ####---- */
  579. 0xE1, /* ###----# */
  580. 0xC3, /* ##----## */
  581. },
  582. {
  583. 0x0F, /* ----#### */
  584. 0x1E, /* ---####- */
  585. 0x3C, /* --####-- */
  586. 0x78, /* -####--- */
  587. 0xF0, /* ####---- */
  588. 0xE1, /* ###----# */
  589. 0xC3, /* ##----## */
  590. 0x87, /* #----### */
  591. },
  592. {
  593. 0x1E, /* ---####- */
  594. 0x3C, /* --####-- */
  595. 0x78, /* -####--- */
  596. 0xF0, /* ####---- */
  597. 0xE1, /* ###----# */
  598. 0xC3, /* ##----## */
  599. 0x87, /* #----### */
  600. 0x0F, /* ----#### */
  601. },
  602. {
  603. 0x3C, /* --####-- */
  604. 0x78, /* -####--- */
  605. 0xF0, /* ####---- */
  606. 0xE1, /* ###----# */
  607. 0xC3, /* ##----## */
  608. 0x87, /* #----### */
  609. 0x0F, /* ----#### */
  610. 0x1E, /* ---####- */
  611. },
  612. {
  613. 0x78, /* -####--- */
  614. 0xF0, /* ####---- */
  615. 0xE1, /* ###----# */
  616. 0xC3, /* ##----## */
  617. 0x87, /* #----### */
  618. 0x0F, /* ----#### */
  619. 0x1E, /* ---####- */
  620. 0x3C, /* --####-- */
  621. },
  622. };
  623. static const BYTE s_ant_xmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01} ;
  624. // calculate edge points
  625. sel.RecalculateEdge (canvas.GetZoomScale(), false) ;
  626. // ==> scaled coordinate
  627. canvas.Actual_to_Scaled (rcCanvas) ;
  628. rcCanvas.right++ ; rcCanvas.bottom++ ; // ...division, float
  629. // selection object's position
  630. POINT ptPos = sel.GetGraphObjPos() ;
  631. canvas.Actual_to_Scaled (ptPos) ;
  632. sel.m_nCurAnt = ++sel.m_nCurAnt % 8 ;
  633. for (size_t i=0 ; i < sel.m_ptEdge.size() ; i++)
  634. {
  635. POINT ptDraw = {ptPos.x + sel.m_ptEdge[i].x, ptPos.y + sel.m_ptEdge[i].y} ;
  636. if (!::PtInRect(&rcCanvas, ptDraw))
  637. continue ;
  638. COLORREF crFill ;
  639. if (s_ant_data[sel.m_nCurAnt][sel.m_ptEdge[i].y % 8] & s_ant_xmask[sel.m_ptEdge[i].x % 8])
  640. crFill = RGB(255,255,255) ;
  641. else
  642. crFill = RGB(0,0,0) ;
  643. ::SetPixel (hdc, ptDraw.x, ptDraw.y, crFill) ;
  644. }
  645. }
  646. //=============================================================================
  647. /**
  648. * Create HRGN object from a 32bpp image.
  649. * alpha=0 means outter of region.
  650. */
  651. static HRGN ConvertAlphaImageToHRGN (const FCObjImage& img32)
  652. {
  653. if (!img32.IsValidImage() || (img32.ColorBits() != 32))
  654. {assert(false); return NULL;}
  655. HRGN hRgn = ::CreateRectRgn (0, 0, img32.Width(), img32.Height()) ;
  656. for (int y=0 ; y < img32.Height() ; y++)
  657. {
  658. int nLastX = 0 ;
  659. BOOL bStartCount = FALSE ;
  660. for (int x=0 ; x < img32.Width() ; x++)
  661. {
  662. if (PCL_A(img32.GetBits (x,y)))
  663. {
  664. if (bStartCount)
  665. {
  666. // erase rect
  667. HRGN hSingle = ::CreateRectRgn (nLastX, y, x, y+1) ;
  668. ::CombineRgn (hRgn, hRgn, hSingle, RGN_DIFF) ;
  669. ::DeleteObject (hSingle) ;
  670. bStartCount = FALSE ;
  671. }
  672. }
  673. else
  674. {
  675. if (!bStartCount)
  676. {
  677. bStartCount = TRUE ;
  678. nLastX = x ;
  679. }
  680. }
  681. }
  682. if (bStartCount)
  683. {
  684. // erase rect
  685. HRGN hSingle = ::CreateRectRgn (nLastX, y, img32.Width(), y+1) ;
  686. ::CombineRgn (hRgn, hRgn, hSingle, RGN_DIFF) ;
  687. ::DeleteObject (hSingle) ;
  688. }
  689. }
  690. return hRgn ;
  691. }
  692. /**
  693. * @name Clipboard.
  694. */
  695. //@{
  696. //=============================================================================
  697. /**
  698. * Whether current clipboard has a bitmap (DIB).
  699. */
  700. static bool IsPasteAvailable()
  701. {
  702. return ::IsClipboardFormatAvailable(CF_DIB) ? true : false ;
  703. }
  704. //=============================================================================
  705. /**
  706. * Copy img to clipboard (the image must >= 24bpp).
  707. */
  708. static void CopyToClipboard (const FCObjImage& img)
  709. {
  710. if (img.IsValidImage() && (img.ColorBits() >= 24))
  711. if (::OpenClipboard (NULL))
  712. {
  713. // create HGLOBAL
  714. HGLOBAL hMem = GlobalAlloc (GMEM_MOVEABLE, img.GetPitch()*img.Height() + sizeof(BITMAPINFOHEADER) + 16) ;
  715. BYTE * pClipData = (BYTE*)GlobalLock(hMem) ;
  716. // fill image's info
  717. PCL_array<BYTE> imgInfo (img.NewImgInfoWithPalette()) ;
  718. CopyMemory (pClipData, imgInfo.get(), sizeof(BITMAPINFOHEADER)) ;
  719. pClipData += sizeof(BITMAPINFOHEADER) ;
  720. CopyMemory (pClipData, img.GetMemStart(), img.GetPitch()*img.Height()) ;
  721. GlobalUnlock (hMem) ;
  722. if (::EmptyClipboard())
  723. ::SetClipboardData (CF_DIB, hMem) ;
  724. else
  725. {
  726. assert(false);
  727. GlobalFree (hMem) ;
  728. }
  729. ::CloseClipboard() ;
  730. // GlobalFree (hMem) ; // it is a nightmare :-(
  731. }
  732. }
  733. //=============================================================================
  734. /**
  735. * Get clipboard's image (the returned image is 32bpp).
  736. */
  737. static void GetClipboardImage (FCObjImage& img)
  738. {
  739. if (IsPasteAvailable())
  740. if (::OpenClipboard (NULL))
  741. {
  742. // get bitmap
  743. BITMAPINFOHEADER * bmif = (BITMAPINFOHEADER*)::GetClipboardData(CF_DIB) ;
  744. if (img.Create (bmif))
  745. {
  746. // palette
  747. BYTE * pCurr = ((BYTE*)bmif) + bmif->biSize ;
  748. if (img.ColorBits() <= 8)
  749. {
  750. int nCount = 1 << img.ColorBits() ;
  751. img.SetColorTable (0, nCount, (RGBQUAD*)pCurr) ;
  752. pCurr += (4 * nCount) ;
  753. }
  754. else if ((bmif->biCompression == BI_BITFIELDS) && (bmif->biSize == sizeof(BITMAPINFOHEADER)))
  755. pCurr += 12 ;
  756. // copy pixel
  757. CopyMemory (img.GetMemStart(), pCurr, img.GetPitch()*img.Height()) ;
  758. if (img.ColorBits() == 32)
  759. {
  760. if (bmif->biCompression == BI_BITFIELDS)
  761. img.SetAlphaChannelValue (0xFF) ;
  762. }
  763. else
  764. img.ConvertTo32Bit() ;
  765. }
  766. ::CloseClipboard() ;
  767. }
  768. }
  769. //@}
  770. //=============================================================================
  771. /**
  772. * Get a temp file path.
  773. */
  774. static bstr_t QueryTempFilePath()
  775. {
  776. TCHAR szTmpPath[MAX_PATH],
  777. szFilename[MAX_PATH] ;
  778. ::GetTempPath (MAX_PATH, szTmpPath) ;
  779. ::GetTempFileName (szTmpPath, TEXT("foo"), 0, szFilename) ;
  780. return szFilename ;
  781. }
  782. //=============================================================================
  783. /**
  784. * Get module path.
  785. */
  786. static bstr_t GetModulePath (HMODULE hModule=NULL)
  787. {
  788. TCHAR szApp[MAX_PATH],
  789. szDriver[_MAX_DRIVE],
  790. szPath[MAX_PATH] ;
  791. ::GetModuleFileName (hModule, szApp, MAX_PATH) ;
  792. #if _MSC_VER >= 1400
  793. ::_tsplitpath_s (szApp, szDriver, _MAX_DRIVE, szPath, MAX_PATH, NULL, 0, NULL, 0) ;
  794. ::_tmakepath_s (szApp, MAX_PATH, szDriver, szPath, NULL, NULL) ;
  795. #else
  796. ::_tsplitpath (szApp, szDriver, szPath, NULL, NULL) ;
  797. ::_tmakepath (szApp, szDriver, szPath, NULL, NULL) ;
  798. #endif
  799. return szApp ;
  800. }
  801. private:
  802. static HKEY uis_GetRootKey()
  803. {
  804. OSVERSIONINFO osvi = {sizeof(OSVERSIONINFO)} ;
  805. ::GetVersionEx (&osvi) ;
  806. return (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER ;
  807. }
  808. };
  809. #endif // __PCL_WIN32__2005_09_29__H__
  810. #endif// WIN32