Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2114 lines
62 KiB

  1. //--------------------------------------------------------------------------
  2. // Clipper.cpp : test out theme drawing and fast clipping
  3. //--------------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "resource.h"
  6. #define ASSERT(x)
  7. #include "uxthemep.h"
  8. #include "tmschema.h"
  9. #include "borderfill.h"
  10. #include "imagefile.h"
  11. #include "textdraw.h"
  12. #include "stdlib.h"
  13. #include "stdio.h"
  14. #include "autos.h"
  15. //--------------------------------------------------------------------------
  16. #define RECTWIDTH(rc) (rc.right - rc.left)
  17. #define RECTHEIGHT(rc) (rc.bottom - rc.top)
  18. #define CLIPPER_FONTHEIGHT 55
  19. //--------------------------------------------------------------------------
  20. HINSTANCE hInst;
  21. HWND hwndMain;
  22. HWND hwndTab;
  23. HWND hwndDisplay;
  24. TCHAR *pszMainWindowClass = L"Clipper";
  25. TCHAR *pszDisplayWindowClass = L"ClipperDisplay";
  26. //-----------------------------------------------------------------------------------
  27. enum IMAGEFILEDRAW
  28. {
  29. IF_REG,
  30. IF_TRANS,
  31. IF_ALPHA
  32. };
  33. //-----------------------------------------------------------------------------------
  34. LPCWSTR szPageNames[] =
  35. {
  36. L"BorderFill",
  37. L"BorderFill-R",
  38. L"ImageFile",
  39. L"ImageFile-R",
  40. L"Glyph",
  41. L"Glyph-R",
  42. L"MultiImage",
  43. L"MultiImage-R",
  44. L"Text",
  45. L"Text-R",
  46. L"Borders",
  47. L"Borders-R",
  48. L"SourceSizing",
  49. L"SourceSizing-R",
  50. };
  51. //-----------------------------------------------------------------------------------
  52. enum GROUPID
  53. {
  54. GID_BORDERFILL,
  55. GID_IMAGEFILE,
  56. GID_GLYPH,
  57. GID_MULTIIMAGE,
  58. GID_TEXT,
  59. GID_BORDERS,
  60. GID_SRCSIZING,
  61. };
  62. //-----------------------------------------------------------------------------------
  63. #define MAXGROUPS ((ARRAYSIZE(szPageNames))/2)
  64. #define MAXTESTITEMS 50
  65. //-----------------------------------------------------------------------------------
  66. // Foward declarations of functions included in this code module:
  67. BOOL InitInstance(HINSTANCE, int);
  68. LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
  69. LRESULT CALLBACK DisplayWndProc(HWND, UINT, WPARAM, LPARAM);
  70. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  71. void CreateDrawObjects();
  72. BOOL CreateAllWindows();
  73. void RegisterWindowClasses();
  74. //-----------------------------------------------------------------------------------
  75. HRESULT MakeErrorLast() {return E_FAIL;}
  76. //-----------------------------------------------------------------------------------
  77. BOOL CaptureBitmaps();
  78. BOOL WriteBitmapToFile(BITMAPINFOHEADER *pHdr, BYTE *pBits, LPCWSTR pszBaseName);
  79. BOOL WriteBitmapHeader(HANDLE hOutFile, BYTE *pMemoryHdr, DWORD dwTotalPixelBytes);
  80. void OnDisplayResize();
  81. void PaintObjects(HDC hdc, RECT *prc, int iGroupId);
  82. //-----------------------------------------------------------------------------------
  83. SIZE szCell = {100, 60};
  84. RECT rcDraw = {10, 10, 50, 45}; // where to draw within cell
  85. //-----------------------------------------------------------------------------------
  86. struct TESTITEM
  87. {
  88. HTHEME hTheme;
  89. DWORD dwDtbFlags;
  90. WCHAR szName[MAX_PATH];
  91. };
  92. //-----------------------------------------------------------------------------------
  93. //---- scrolling support ----
  94. int iVertOffset = 0;
  95. int iMaxVertOffset = 0; // set by WM_SIZE
  96. int iVertLineSize = 10; // # of pixels
  97. int iVertPageSize = 0; // set by WM_SIZE
  98. //-----------------------------------------------------------------------------------
  99. int iItemCount[MAXGROUPS] = {0};
  100. TESTITEM TestItems[MAXGROUPS][MAXTESTITEMS];
  101. BOOL fCapturing = FALSE;
  102. //-----------------------------------------------------------------------------------
  103. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdShow)
  104. {
  105. MSG msg;
  106. HACCEL hAccelTable;
  107. hInst = hInstance;
  108. RegisterWindowClasses();
  109. InitCommonControlsEx(NULL);
  110. if (!InitInstance (hInstance, nCmdShow))
  111. {
  112. return FALSE;
  113. }
  114. //---- parse cmdline params ----
  115. USES_CONVERSION;
  116. LPCSTR p = W2A(lpCmdLine);
  117. while (*p)
  118. {
  119. while (isspace(*p))
  120. p++;
  121. //---- parse switches ----
  122. if ((*p == '/') || (*p == '-'))
  123. {
  124. p++;
  125. if ((*p == 'c') || (*p == 'C'))
  126. {
  127. p++;
  128. fCapturing = TRUE;
  129. }
  130. }
  131. }
  132. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CLIPPER);
  133. if (fCapturing)
  134. {
  135. CaptureBitmaps();
  136. return 0;
  137. }
  138. // Main message loop:
  139. while (GetMessage(&msg, NULL, 0, 0))
  140. {
  141. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  142. {
  143. TranslateMessage(&msg);
  144. DispatchMessage(&msg);
  145. }
  146. }
  147. return static_cast<int>(msg.wParam);
  148. }
  149. //--------------------------------------------------------------------------
  150. BOOL CaptureBitmaps()
  151. {
  152. //---- paint each tab page to a memory dc & convert to a bitmap file ----
  153. HDC hdcClient = GetDC(NULL);
  154. RECT rt = {0, 0, 800, 600}; // currently captures all good info
  155. BITMAPINFOHEADER BitMapHdr = {sizeof(BITMAPINFOHEADER), WIDTH(rt), HEIGHT(rt), 1, 24, BI_RGB};
  156. //---- create a DIB to paint into ----
  157. BYTE *pBits;
  158. HBITMAP hBitmap = CreateDIBSection(hdcClient, (BITMAPINFO *)&BitMapHdr, DIB_RGB_COLORS,
  159. (void **)&pBits, NULL, 0);
  160. HDC hdcMemory = CreateCompatibleDC(hdcClient);
  161. HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmap);
  162. //---- for each tab that we can draw ----
  163. for (int iTabNum=0; iTabNum < ARRAYSIZE(szPageNames); iTabNum++)
  164. {
  165. iVertOffset = 0;
  166. iVertPageSize = RECTHEIGHT(rt);
  167. int iGroupId = iTabNum/2;
  168. //---- keep tester interested by sync. visuals ----
  169. TabCtrl_SetCurSel(hwndTab, iTabNum);
  170. OnDisplayResize();
  171. iVertPageSize = RECTHEIGHT(rt);
  172. InvalidateRect(hwndDisplay, NULL, TRUE);
  173. if (iTabNum % 2) // if its a mirrored page
  174. SetLayout(hdcMemory, LAYOUT_RTL);
  175. else
  176. SetLayout(hdcMemory, 0);
  177. //---- clear the background first ----
  178. HBRUSH hbr = CreateSolidBrush(RGB(255, 255, 255));
  179. FillRect(hdcMemory, &rt, hbr);
  180. //---- draw the objects/labels for this tab ----
  181. PaintObjects(hdcMemory, &rt, iGroupId);
  182. //---- now copy DIB bits to a bitmap file ----
  183. WriteBitmapToFile(&BitMapHdr, pBits, szPageNames[iTabNum]);
  184. }
  185. //---- clean up ----
  186. SelectObject(hdcMemory, hOldBitmap);
  187. DeleteDC(hdcMemory);
  188. DeleteObject(hBitmap);
  189. ReleaseDC(NULL, hdcClient);
  190. return TRUE;
  191. }
  192. //--------------------------------------------------------------------------
  193. BOOL WriteBitmapToFile(BITMAPINFOHEADER *pHdr, BYTE *pBits, LPCWSTR pszBaseName)
  194. {
  195. BOOL fWroteFile = FALSE;
  196. //---- get size of bitmap ----
  197. int iDibWidth = pHdr->biWidth;
  198. int iDibHeight = pHdr->biHeight;
  199. int iRawBytes = iDibWidth * 3;
  200. int iBytesPerRow = 4*((iRawBytes+3)/4);
  201. int iPixelBytesTotal = iBytesPerRow * iDibHeight;
  202. //---- create the bitmap file ----
  203. WCHAR szName[MAX_PATH];
  204. wsprintf(szName, L"%s.bmp", pszBaseName);
  205. HANDLE hFileOutput = CreateFile(szName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
  206. if (hFileOutput == INVALID_HANDLE_VALUE)
  207. {
  208. printf("\nError - could not open bitmap file for output: %s\n", szName);
  209. goto exit;
  210. }
  211. //---- write the bitmap FILE header ----
  212. if (! WriteBitmapHeader(hFileOutput, (BYTE *)pHdr, iPixelBytesTotal))
  213. goto exit;
  214. //---- write the bitmap MEMORY header ----
  215. DWORD dw;
  216. if (! WriteFile(hFileOutput, pHdr, sizeof(*pHdr), &dw, NULL))
  217. goto exit;
  218. //---- write the bitmap bits ----
  219. if (! WriteFile(hFileOutput, pBits, iPixelBytesTotal, &dw, NULL))
  220. goto exit;
  221. //---- close the file ----
  222. CloseHandle(hFileOutput);
  223. fWroteFile = TRUE;
  224. exit:
  225. return fWroteFile;
  226. }
  227. //---------------------------------------------------------------------------
  228. BOOL WriteBitmapHeader(HANDLE hOutFile, BYTE *pMemoryHdr, DWORD dwTotalPixelBytes)
  229. {
  230. BOOL fOK = FALSE;
  231. BYTE pbHdr1[] = {0x42, 0x4d};
  232. BYTE pbHdr2[] = {0x0, 0x0, 0x0, 0x0};
  233. int iFileLen;
  234. DWORD dw;
  235. //---- add bitmap hdr at front ----
  236. HRESULT hr = WriteFile(hOutFile, pbHdr1, sizeof(pbHdr1), &dw, NULL);
  237. if (FAILED(hr))
  238. goto exit;
  239. //---- add length of data ----
  240. iFileLen = dwTotalPixelBytes + sizeof(BITMAPFILEHEADER);
  241. hr = WriteFile(hOutFile, &iFileLen, sizeof(int), &dw, NULL);
  242. if (FAILED(hr))
  243. goto exit;
  244. hr = WriteFile(hOutFile, pbHdr2, sizeof(pbHdr2), &dw, NULL);
  245. if (FAILED(hr))
  246. goto exit;
  247. //---- offset to bits (who's idea was *this* field?) ----
  248. int iOffset, iColorTableSize;
  249. DWORD dwSize;
  250. iOffset = sizeof(BITMAPFILEHEADER);
  251. dwSize = *(DWORD *)pMemoryHdr;
  252. iOffset += dwSize;
  253. iColorTableSize = 0;
  254. switch (dwSize)
  255. {
  256. case sizeof(BITMAPCOREHEADER):
  257. BITMAPCOREHEADER *hdr1;
  258. hdr1 = (BITMAPCOREHEADER *)pMemoryHdr;
  259. if (hdr1->bcBitCount == 1)
  260. iColorTableSize = 2*sizeof(RGBTRIPLE);
  261. else if (hdr1->bcBitCount == 4)
  262. iColorTableSize = 16*sizeof(RGBTRIPLE);
  263. else if (hdr1->bcBitCount == 8)
  264. iColorTableSize = 256*sizeof(RGBTRIPLE);
  265. break;
  266. case sizeof(BITMAPINFOHEADER):
  267. case sizeof(BITMAPV4HEADER):
  268. case sizeof(BITMAPV5HEADER):
  269. BITMAPINFOHEADER *hdr2;
  270. hdr2 = (BITMAPINFOHEADER *)pMemoryHdr;
  271. if (hdr2->biClrUsed)
  272. iColorTableSize = hdr2->biClrUsed*sizeof(RGBQUAD);
  273. else
  274. {
  275. if (hdr2->biBitCount == 1)
  276. iColorTableSize = 2*sizeof(RGBQUAD);
  277. else if (hdr2->biBitCount == 4)
  278. iColorTableSize = 16*sizeof(RGBQUAD);
  279. else if (hdr2->biBitCount == 8)
  280. iColorTableSize = 256*sizeof(RGBQUAD);
  281. }
  282. break;
  283. }
  284. iOffset += iColorTableSize;
  285. hr = WriteFile(hOutFile, &iOffset, sizeof(int), &dw, NULL);
  286. if (FAILED(hr))
  287. goto exit;
  288. fOK = TRUE;
  289. exit:
  290. return fOK;
  291. }
  292. //--------------------------------------------------------------------------
  293. void DrawTargetRect(HDC hdc, RECT *prc, COLORREF cr)
  294. {
  295. //---- draw purple target dashed rect ----
  296. //---- prepare drawing objects ----
  297. HPEN hPen = CreatePen(PS_DOT, 1, cr);
  298. HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
  299. HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
  300. //---- draw that thing ----
  301. Rectangle(hdc, prc->left-1, prc->top-1, prc->right+1, prc->bottom+1);
  302. //---- restore DC ----
  303. SelectObject(hdc, hOldPen);
  304. SelectObject(hdc, hOldBrush);
  305. DeleteObject(hPen);
  306. }
  307. //--------------------------------------------------------------------------
  308. void DrawClip(HTHEME hTheme, HDC hdc, RECT *prc, int iRowIndex, int iColIndex,
  309. DWORD dwDtbFlags)
  310. {
  311. RECT rect, rcClip;
  312. int left = prc->left + (iColIndex+1)*szCell.cx;
  313. int top = prc->top + (iRowIndex+1)*szCell.cy;
  314. HRESULT hr = S_OK;
  315. SetRect(&rect, left + rcDraw.left, top + rcDraw.top,
  316. left + rcDraw.right, top + rcDraw.bottom);
  317. //---- draw purple target dashed rect ----
  318. DrawTargetRect(hdc, &rect, RGB(128, 128, 255));
  319. switch (iColIndex) // clipping type
  320. {
  321. case 0: // no clipping
  322. break;
  323. case 1: // over clipping
  324. rcClip = rect;
  325. rcClip.left -= 4;
  326. rcClip.right += 4;
  327. rcClip.top -= 4;
  328. rcClip.bottom += 4;
  329. break;
  330. case 2: // exact clipping
  331. rcClip = rect;
  332. break;
  333. case 3: // partial overlap
  334. rcClip = rect;
  335. rcClip.left += 8;
  336. rcClip.right -= 8;
  337. rcClip.top += 8;
  338. rcClip.bottom -= 8;
  339. break;
  340. case 4: // InOut1
  341. rcClip = rect;
  342. rcClip.left -= 3;
  343. rcClip.right = rcClip.left + 20;
  344. rcClip.top -= 3;
  345. rcClip.bottom = rcClip.top + 20;
  346. break;
  347. case 5: // InOut2
  348. rcClip = rect;
  349. rcClip.left += 20;
  350. rcClip.right += 5;
  351. rcClip.top += 15;;
  352. rcClip.bottom += 5;
  353. break;
  354. case 6: // out clip
  355. rcClip.left = rect.right + 6;
  356. rcClip.right = rcClip.left + 9;
  357. rcClip.top = rect.top - 2;
  358. rcClip.bottom = rect.bottom + 2;
  359. break;
  360. }
  361. //---- draw red clipping rect ----
  362. if (iColIndex)
  363. {
  364. HPEN hPen = CreatePen(PS_DOT, 1, RGB(255, 0, 0));
  365. HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
  366. HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
  367. Rectangle(hdc, rcClip.left-1, rcClip.top-1, rcClip.right+1, rcClip.bottom+1);
  368. SelectObject(hdc, hOldPen);
  369. SelectObject(hdc, hOldBrush);
  370. DeleteObject(hPen);
  371. }
  372. DTBGOPTS DtbOpts = {sizeof(DtbOpts)};
  373. DtbOpts.dwFlags = dwDtbFlags;
  374. if (iColIndex) // pass clipping rect
  375. {
  376. DtbOpts.dwFlags |= DTBG_CLIPRECT;
  377. DtbOpts.rcClip = rcClip;
  378. }
  379. hr = DrawThemeBackgroundEx(hTheme, hdc, 1, 2, &rect, &DtbOpts);
  380. if (FAILED(hr))
  381. {
  382. WCHAR buff[100];
  383. wsprintf(buff, L"DrawThemeBackgroundEx err: hr=0x%x, irow=%d, icol=%d",
  384. hr, iRowIndex, iColIndex);
  385. //MessageBox(NULL, buff, L"Error", MB_OK);
  386. }
  387. }
  388. //--------------------------------------------------------------------------
  389. void DrawTextObjects(HTHEME hTheme, HDC hdc, RECT *prc, int iRowIndex, LPCWSTR pszName)
  390. {
  391. int left = prc->left + 4; // some padding away from edge
  392. int top = prc->top + iRowIndex*szCell.cy + 18; // try to center
  393. //---- draw label in left cell ----
  394. TextOut(hdc, left, top, pszName, wcslen(pszName));
  395. left += szCell.cx;
  396. RECT rc = {left, top, left+szCell.cx*5, top+szCell.cy};
  397. //---- draw actual test text ----
  398. HRESULT hr = DrawThemeText(hTheme, hdc, 1, 2, L"Testing Text Drawing", -1, 0, 0, &rc);
  399. if (FAILED(hr))
  400. {
  401. WCHAR buff[100];
  402. wsprintf(buff, L"DrawThemeText err: hr=0x%x, irow=%d",
  403. hr, iRowIndex);
  404. MessageBox(NULL, buff, L"Error", MB_OK);
  405. }
  406. }
  407. //--------------------------------------------------------------------------
  408. void DrawClips(HTHEME hTheme, HDC hdc, RECT *prc, int iRowIndex, LPCWSTR pszName,
  409. DWORD dwDtbFlags)
  410. {
  411. //---- label object on left ----
  412. int left = prc->left + 4; // some padding away from edge
  413. int top = prc->top + (iRowIndex+1)*szCell.cy + 18; // try to center
  414. //---- manual page clipping ----
  415. if ((top + szCell.cy) < 0)
  416. return;
  417. if (top > iVertPageSize)
  418. return;
  419. TextOut(hdc, left, top, pszName, wcslen(pszName));
  420. //---- draw clipping variations ----
  421. for (int i=0; i <= 6; i++)
  422. {
  423. DrawClip(hTheme, hdc, prc, iRowIndex, i, dwDtbFlags);
  424. }
  425. }
  426. //--------------------------------------------------------------------------
  427. void AddItem(CDrawBase *pObject, CTextDraw *pTextObj, LPCWSTR pszName, int iGroupId,
  428. DWORD dwOtdFlags=0, DWORD dwDtbFlags=0)
  429. {
  430. HTHEME hTheme = NULL;
  431. if (iItemCount[iGroupId] >= MAXTESTITEMS)
  432. return;
  433. if (pObject)
  434. {
  435. if (pObject->_eBgType == BT_BORDERFILL)
  436. {
  437. CBorderFill *pTo = new CBorderFill;
  438. if (pTo)
  439. {
  440. memcpy(pTo, pObject, sizeof(CBorderFill));
  441. hTheme = CreateThemeDataFromObjects(pTo, NULL, dwOtdFlags);
  442. }
  443. }
  444. else // imagefile
  445. {
  446. CMaxImageFile *pFrom = (CMaxImageFile *)pObject;
  447. CMaxImageFile *pTo = new CMaxImageFile;
  448. if (pTo)
  449. {
  450. //---- transfer CImageFile object & variable number of DIBINFO's ----
  451. DWORD dwLen = sizeof(CImageFile) + sizeof(DIBINFO)*pFrom->_iMultiImageCount;
  452. memcpy(pTo, pFrom, dwLen);
  453. hTheme = CreateThemeDataFromObjects(pTo, NULL, dwOtdFlags);
  454. }
  455. }
  456. }
  457. else // text object
  458. {
  459. CTextDraw *pTo = new CTextDraw;
  460. if (pTo)
  461. {
  462. memcpy(pTo, pTextObj, sizeof(CTextDraw));
  463. hTheme = CreateThemeDataFromObjects(NULL, pTo, dwOtdFlags);
  464. }
  465. }
  466. if (hTheme)
  467. {
  468. int iIndex = iItemCount[iGroupId];
  469. TestItems[iGroupId][iIndex].hTheme = hTheme;
  470. TestItems[iGroupId][iIndex].dwDtbFlags = dwDtbFlags;
  471. lstrcpy(TestItems[iGroupId][iIndex].szName, pszName);
  472. iItemCount[iGroupId]++;
  473. }
  474. else
  475. {
  476. MessageBox(NULL, L"Error creating hTheme from obj", L"Error", MB_OK);
  477. }
  478. }
  479. //--------------------------------------------------------------------------
  480. void CreateBorderFillNoDraw()
  481. {
  482. CBorderFill bfill;
  483. memset(&bfill, 0, sizeof(bfill));
  484. //---- make a BorderFill obj with a border ----
  485. bfill._eBgType = BT_BORDERFILL;
  486. bfill._fNoDraw = TRUE;
  487. AddItem(&bfill, NULL, L"NoDraw", GID_BORDERFILL);
  488. }
  489. //--------------------------------------------------------------------------
  490. void CreateBorderFillSquare()
  491. {
  492. CBorderFill bfill;
  493. memset(&bfill, 0, sizeof(bfill));
  494. //---- make a BorderFill obj with a border ----
  495. bfill._eBgType = BT_BORDERFILL;
  496. bfill._eBorderType = BT_RECT;
  497. bfill._iBorderSize = 0;
  498. bfill._eFillType = FT_SOLID;
  499. bfill._crFill = RGB(128, 255, 255);
  500. AddItem(&bfill, NULL, L"Square", GID_BORDERFILL);
  501. }
  502. //--------------------------------------------------------------------------
  503. void CreateBorderFillBorder()
  504. {
  505. CBorderFill bfill;
  506. memset(&bfill, 0, sizeof(bfill));
  507. //---- make a BorderFill obj with a border ----
  508. bfill._eBgType = BT_BORDERFILL;
  509. bfill._eBorderType = BT_RECT;
  510. bfill._crBorder = RGB(255, 128, 128);
  511. bfill._iBorderSize = 3;
  512. bfill._eFillType = FT_SOLID;
  513. bfill._crFill = RGB(128, 255, 255);
  514. AddItem(&bfill, NULL, L"Border", GID_BORDERFILL);
  515. }
  516. //--------------------------------------------------------------------------
  517. void CreateBorderFillCircle()
  518. {
  519. CBorderFill bfill;
  520. memset(&bfill, 0, sizeof(bfill));
  521. //---- make a BorderFill obj with a border ----
  522. bfill._eBgType = BT_BORDERFILL;
  523. bfill._eBorderType = BT_ROUNDRECT;
  524. bfill._crBorder = RGB(255, 128, 128);
  525. bfill._iBorderSize = 3;
  526. bfill._iRoundCornerWidth = 80;
  527. bfill._iRoundCornerHeight = 80;
  528. bfill._eFillType = FT_SOLID;
  529. bfill._crFill = RGB(128, 255, 255);
  530. AddItem(&bfill, NULL, L"Circle", GID_BORDERFILL);
  531. }
  532. //--------------------------------------------------------------------------
  533. void CreateBorderFillGradient()
  534. {
  535. CBorderFill bfill;
  536. memset(&bfill, 0, sizeof(bfill));
  537. //---- make a BorderFill obj with a border ----
  538. bfill._eBgType = BT_BORDERFILL;
  539. bfill._eBorderType = BT_RECT;
  540. bfill._crBorder = RGB(255, 128, 128);
  541. bfill._iBorderSize = 3;
  542. bfill._eFillType = FT_HORZGRADIENT;
  543. //---- gradients ----
  544. bfill._iGradientPartCount = 2;
  545. bfill._crGradientColors[0] = RGB(0, 0, 0);
  546. bfill._crGradientColors[1] = RGB(255, 255, 255);
  547. bfill._iGradientRatios[0] = 0;
  548. bfill._iGradientRatios[1] = 255;
  549. AddItem(&bfill, NULL, L"Gradient", GID_BORDERFILL);
  550. }
  551. //--------------------------------------------------------------------------
  552. void CreateBorderFillCircleGradient()
  553. {
  554. CBorderFill bfill;
  555. memset(&bfill, 0, sizeof(bfill));
  556. //---- make a BorderFill obj with a border ----
  557. bfill._eBgType = BT_BORDERFILL;
  558. bfill._eBorderType = BT_ROUNDRECT;
  559. bfill._crBorder = RGB(255, 128, 128);
  560. bfill._iBorderSize = 3;
  561. bfill._iRoundCornerWidth = 80;
  562. bfill._iRoundCornerHeight = 80;
  563. bfill._eFillType = FT_HORZGRADIENT;
  564. //---- gradients ----
  565. bfill._iGradientPartCount = 2;
  566. bfill._crGradientColors[0] = RGB(0, 0, 0);
  567. bfill._crGradientColors[1] = RGB(255, 255, 255);
  568. bfill._iGradientRatios[0] = 0;
  569. bfill._iGradientRatios[1] = 255;
  570. AddItem(&bfill, NULL, L"CircleGradient", GID_BORDERFILL);
  571. }
  572. //--------------------------------------------------------------------------
  573. void CreateImageFileBorder(SIZINGTYPE eSizeType, BOOL fSizeBorders, BOOL fForceSizeRect)
  574. {
  575. CImageFile cif;
  576. memset(&cif, 0, sizeof(cif));
  577. cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_BORDERTEST)),
  578. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  579. //---- create a ImageFile object that sizes with STRETCH ----
  580. cif._eBgType = BT_IMAGEFILE;
  581. if (fSizeBorders)
  582. {
  583. cif._fSourceGrow = TRUE;
  584. cif._fIntegralSizing = TRUE;
  585. }
  586. cif._fMirrorImage = TRUE;
  587. cif._iImageCount = 1;
  588. cif._eImageLayout = IL_VERTICAL;
  589. cif._ImageInfo.iSingleWidth = 18;
  590. cif._ImageInfo.iSingleHeight = 17;
  591. cif._ImageInfo.eSizingType = eSizeType;
  592. cif._ImageInfo.iMinDpi = 96;
  593. cif._szNormalSize.cx = 50;
  594. cif._szNormalSize.cy = 50;
  595. SetRect((RECT *)&cif._SizingMargins, 3, 3, 3, 3);
  596. DWORD dwOtdFlags = 0;
  597. if (fForceSizeRect)
  598. {
  599. dwOtdFlags |= OTD_FORCE_RECT_SIZING;
  600. }
  601. AddItem(&cif, NULL, L"BorderTest", GID_BORDERS, dwOtdFlags);
  602. }
  603. //--------------------------------------------------------------------------
  604. void CreateImage(int iBgImageId, int iStateCount, SIZINGTYPE eSizeType, BOOL fSrcSizing, int iGroupId,
  605. LPCWSTR pszName, int lw, int rw, int th, int bh)
  606. {
  607. CMaxImageFile mif;
  608. memset(&mif, 0, sizeof(mif));
  609. if (iBgImageId)
  610. {
  611. mif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(iBgImageId)),
  612. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  613. }
  614. //---- create a ImageFile object ----
  615. mif._eBgType = BT_IMAGEFILE;
  616. mif._fMirrorImage = TRUE;
  617. mif._iImageCount = iStateCount;
  618. mif._eImageLayout = IL_VERTICAL;
  619. mif._ImageInfo.eSizingType = eSizeType;
  620. mif._ImageInfo.iMinDpi = 96;
  621. mif._szNormalSize.cx = 60;
  622. mif._szNormalSize.cy = 40;
  623. mif._eGlyphType = GT_IMAGEGLYPH;
  624. //---- set Width/Height ----
  625. BITMAP bm;
  626. GetObject(mif._ImageInfo.hProcessBitmap, sizeof bm, &bm);
  627. mif._ImageInfo.iSingleWidth = bm.bmWidth;
  628. mif._ImageInfo.iSingleHeight = bm.bmHeight/iStateCount;
  629. mif._ImageInfo.szMinSize.cx = bm.bmWidth;
  630. mif._ImageInfo.szMinSize.cy = bm.bmHeight/iStateCount;
  631. SetRect((RECT *)&mif._SizingMargins, lw, rw, th, bh);
  632. SetRect((RECT *)&mif._ContentMargins, lw, rw, th, bh);
  633. DWORD dwOtdFlags = 0;
  634. if (fSrcSizing)
  635. {
  636. dwOtdFlags |= OTD_FORCE_RECT_SIZING;
  637. }
  638. AddItem(&mif, NULL, pszName, iGroupId, dwOtdFlags);
  639. }
  640. //--------------------------------------------------------------------------
  641. void CreateProgressTrack()
  642. {
  643. CMaxImageFile mif;
  644. memset(&mif, 0, sizeof(mif));
  645. mif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_PROGRESS_TRACK)),
  646. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  647. //---- create a ImageFile object ----
  648. mif._eBgType = BT_IMAGEFILE;
  649. mif._fMirrorImage = TRUE;
  650. mif._iImageCount = 1;
  651. mif._eImageLayout = IL_VERTICAL;
  652. mif._ImageInfo.eSizingType = ST_TILE;
  653. mif._ImageInfo.iMinDpi = 96;
  654. mif._szNormalSize.cx = 60;
  655. mif._szNormalSize.cy = 40;
  656. //---- set Width/Height ----
  657. BITMAP bm;
  658. GetObject(mif._ImageInfo.hProcessBitmap, sizeof bm, &bm);
  659. mif._ImageInfo.iSingleWidth = bm.bmWidth;
  660. mif._ImageInfo.iSingleHeight = bm.bmHeight/1;
  661. mif._ImageInfo.szMinSize.cx = 10;
  662. mif._ImageInfo.szMinSize.cy = 10;
  663. mif._szNormalSize.cx = 100;
  664. mif._szNormalSize.cy = 18;
  665. mif._fSourceShrink = TRUE;
  666. SetRect((RECT *)&mif._SizingMargins, 4, 4, 3, 3);
  667. SetRect((RECT *)&mif._ContentMargins, 4, 4, 3, 3);
  668. AddItem(&mif, NULL, L"Progress", GID_SRCSIZING, 0);
  669. }
  670. //--------------------------------------------------------------------------
  671. void CreateProgressChunk()
  672. {
  673. CMaxImageFile mif;
  674. memset(&mif, 0, sizeof(mif));
  675. //---- create a ImageFile object ----
  676. mif._eBgType = BT_IMAGEFILE;
  677. mif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_PROGRESS_CHUNK)),
  678. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  679. mif._fMirrorImage = TRUE;
  680. mif._iImageCount = 1;
  681. mif._eImageLayout = IL_VERTICAL;
  682. mif._ImageInfo.eSizingType = ST_TILE;
  683. mif._ImageInfo.iMinDpi = 96;
  684. mif._szNormalSize.cx = 60;
  685. mif._szNormalSize.cy = 40;
  686. mif._eGlyphType = GT_IMAGEGLYPH;
  687. //---- set Width/Height ----
  688. BITMAP bm;
  689. GetObject(mif._ImageInfo.hProcessBitmap, sizeof bm, &bm);
  690. mif._ImageInfo.iSingleWidth = bm.bmWidth;
  691. mif._ImageInfo.iSingleHeight = bm.bmHeight/1;
  692. mif._ImageInfo.szMinSize.cx = 10;
  693. mif._ImageInfo.szMinSize.cy = 10;
  694. mif._szNormalSize.cx = 100;
  695. mif._szNormalSize.cy = 18;
  696. SetRect((RECT *)&mif._SizingMargins, 0, 0, 6, 5);
  697. SetRect((RECT *)&mif._ContentMargins, 0, 0, 6, 5);
  698. AddItem(&mif, NULL, L"Progress", GID_SRCSIZING, 0);
  699. }
  700. //--------------------------------------------------------------------------
  701. void CreateRadioImage()
  702. {
  703. CMaxImageFile mif;
  704. memset(&mif, 0, sizeof(mif));
  705. //---- create a ImageFile object ----
  706. mif._eBgType = BT_IMAGEFILE;
  707. mif._fMirrorImage = TRUE;
  708. mif._iImageCount = 8;
  709. mif._eImageLayout = IL_VERTICAL;
  710. mif._szNormalSize.cx = 60;
  711. mif._szNormalSize.cy = 40;
  712. mif._eImageSelectType = IST_DPI;
  713. mif._iMultiImageCount = 3;
  714. mif._eTrueSizeScalingType = TSST_DPI;
  715. mif._fUniformSizing = TRUE;
  716. mif._eHAlign = HA_CENTER;
  717. mif._eVAlign = VA_CENTER;
  718. int iMinDpis[] = {96, 118, 185};
  719. //---- process multiple images ----
  720. for (int i=0; i < 3; i++)
  721. {
  722. DIBINFO *pdi = &mif.MultiDibs[i];
  723. int idnum = IDB_RADIO13 + i;
  724. pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  725. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  726. pdi->iMinDpi = iMinDpis[i];
  727. //---- get bitmap width/height ----
  728. BITMAP bm;
  729. GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
  730. pdi->iSingleWidth = bm.bmWidth;
  731. pdi->iSingleHeight = bm.bmHeight/8;
  732. pdi->szMinSize.cx = pdi->iSingleWidth;
  733. pdi->szMinSize.cy = pdi->iSingleHeight;
  734. pdi->eSizingType = ST_TRUESIZE;
  735. pdi->crTransparent = RGB(255, 0, 255);
  736. pdi->fTransparent = TRUE;
  737. }
  738. //---- set primary image ----
  739. mif._ImageInfo = mif.MultiDibs[0];
  740. AddItem(&mif, NULL, L"RadioButton", GID_SRCSIZING, OTD_FORCE_RECT_SIZING);
  741. }
  742. //--------------------------------------------------------------------------
  743. void CreateCheckImage()
  744. {
  745. CMaxImageFile mif;
  746. memset(&mif, 0, sizeof(mif));
  747. //---- create a ImageFile object ----
  748. mif._eBgType = BT_IMAGEFILE;
  749. mif._fMirrorImage = TRUE;
  750. mif._iImageCount = 12;
  751. mif._eImageLayout = IL_VERTICAL;
  752. mif._szNormalSize.cx = 60;
  753. mif._szNormalSize.cy = 40;
  754. mif._eImageSelectType = IST_DPI;
  755. mif._iMultiImageCount = 3;
  756. mif._eTrueSizeScalingType = TSST_DPI;
  757. mif._fUniformSizing = TRUE;
  758. mif._eHAlign = HA_CENTER;
  759. mif._eVAlign = VA_CENTER;
  760. int iMinDpis[] = {96, 118, 185};
  761. //---- process multiple images ----
  762. for (int i=0; i < 3; i++)
  763. {
  764. DIBINFO *pdi = &mif.MultiDibs[i];
  765. int idnum = IDB_CHECK13 + i;
  766. pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  767. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  768. pdi->iMinDpi = iMinDpis[i];
  769. //---- get bitmap width/height ----
  770. BITMAP bm;
  771. GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
  772. pdi->iSingleWidth = bm.bmWidth;
  773. pdi->iSingleHeight = bm.bmHeight/12;
  774. pdi->szMinSize.cx = pdi->iSingleWidth;
  775. pdi->szMinSize.cy = pdi->iSingleHeight;
  776. pdi->eSizingType = ST_TRUESIZE;
  777. pdi->fAlphaChannel = TRUE;
  778. }
  779. //---- set primary image ----
  780. mif._ImageInfo = mif.MultiDibs[0];
  781. AddItem(&mif, NULL, L"CheckBox", GID_SRCSIZING, OTD_FORCE_RECT_SIZING);
  782. }
  783. //--------------------------------------------------------------------------
  784. void CreateScrollGlyph()
  785. {
  786. CMaxImageFile mif;
  787. memset(&mif, 0, sizeof(mif));
  788. //---- create a ImageFile object ----
  789. mif._eBgType = BT_IMAGEFILE;
  790. mif._eGlyphType = GT_IMAGEGLYPH;
  791. mif._fMirrorImage = TRUE;
  792. mif._iImageCount = 16;
  793. mif._eImageLayout = IL_VERTICAL;
  794. mif._szNormalSize.cx = 30;
  795. mif._szNormalSize.cy = 10;
  796. mif._eImageSelectType = IST_NONE;
  797. mif._fUniformSizing = TRUE;
  798. mif._eHAlign = HA_CENTER;
  799. mif._eVAlign = VA_CENTER;
  800. SetRect((RECT *)&mif._SizingMargins, 5, 5, 5, 5);
  801. SetRect((RECT *)&mif._ContentMargins, 0, 0, 3, 3);
  802. //---- background image ----
  803. DIBINFO *pdi = &mif._ImageInfo;
  804. pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_SCROLL_ARROWS)),
  805. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  806. //---- get bitmap width/height ----
  807. BITMAP bm;
  808. GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
  809. pdi->iSingleWidth = bm.bmWidth;
  810. pdi->iSingleHeight = bm.bmHeight/16;
  811. pdi->szMinSize.cx = pdi->iSingleWidth;
  812. pdi->szMinSize.cy = pdi->iSingleHeight;
  813. pdi->iMinDpi = 96;
  814. pdi->eSizingType = ST_STRETCH;
  815. //---- glyph image ----
  816. pdi = &mif._GlyphInfo;
  817. mif._GlyphInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_SCROLL_GLPYHS)),
  818. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  819. pdi->fTransparent = TRUE;
  820. pdi->crTransparent = RGB(255, 0, 255);
  821. GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
  822. pdi->iSingleWidth = bm.bmWidth;
  823. pdi->iSingleHeight = bm.bmHeight/16;
  824. pdi->szMinSize.cx = pdi->iSingleWidth;
  825. pdi->szMinSize.cy = pdi->iSingleHeight;
  826. pdi->iMinDpi = 96;
  827. pdi->eSizingType = ST_TRUESIZE;
  828. mif._fSourceShrink = TRUE;
  829. mif._fSourceGrow = TRUE;
  830. mif._eTrueSizeScalingType = TSST_SIZE;
  831. mif._iTrueSizeStretchMark = 100;
  832. //---- add it (without OTD_FORCE_RECT_SIZING) ----
  833. AddItem(&mif, NULL, L"ScrollBox", GID_SRCSIZING, 0);
  834. }
  835. //--------------------------------------------------------------------------
  836. void CreateImageFileStretch(IMAGEFILEDRAW eDraw, int iGroupId)
  837. {
  838. CImageFile cif;
  839. memset(&cif, 0, sizeof(cif));
  840. int idnum = IDB_STRETCH;
  841. if (eDraw == IF_TRANS)
  842. idnum = IDB_STRETCH_TRANS;
  843. cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  844. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  845. //---- create a ImageFile object that sizes with STRETCH ----
  846. cif._eBgType = BT_IMAGEFILE;
  847. cif._fMirrorImage = TRUE;
  848. cif._iImageCount = 5;
  849. cif._eImageLayout = IL_VERTICAL;
  850. cif._ImageInfo.iSingleWidth = 20;
  851. cif._ImageInfo.iSingleHeight = 19;
  852. cif._ImageInfo.eSizingType = ST_STRETCH;
  853. if (eDraw == IF_TRANS)
  854. {
  855. cif._ImageInfo.fTransparent = TRUE;
  856. cif._ImageInfo.crTransparent = RGB(255, 0, 255);
  857. }
  858. SetRect((RECT *)&cif._SizingMargins, 4, 4, 4, 4);
  859. LPCWSTR p = L"Stretch";
  860. if (eDraw == IF_TRANS)
  861. p = L"Stretch+Trans";
  862. AddItem(&cif, NULL, p, iGroupId);
  863. }
  864. //--------------------------------------------------------------------------
  865. void CreateImageFileTile(IMAGEFILEDRAW eDraw, int iGroupId)
  866. {
  867. CImageFile cif;
  868. memset(&cif, 0, sizeof(cif));
  869. int idnum = IDB_TILE;
  870. if (eDraw == IF_TRANS)
  871. idnum = IDB_TILE_TRANS;
  872. DIBINFO *pdi = &cif._ImageInfo;
  873. pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  874. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  875. //---- create a ImageFile object that sizes with TILE ----
  876. pdi->eSizingType = ST_TILE;
  877. cif._eBgType = BT_IMAGEFILE;
  878. cif._fMirrorImage = TRUE;
  879. cif._iImageCount = 5;
  880. cif._eImageLayout = IL_VERTICAL;
  881. cif._ImageInfo.iSingleWidth = 20;
  882. cif._ImageInfo.iSingleHeight = 19;
  883. if (eDraw == IF_TRANS)
  884. {
  885. cif._ImageInfo.fTransparent = TRUE;
  886. cif._ImageInfo.crTransparent = RGB(255, 0, 255);
  887. }
  888. SetRect((RECT *)&cif._SizingMargins, 4, 4, 9, 9);
  889. LPCWSTR p = L"Tile";
  890. if (eDraw == IF_TRANS)
  891. p = L"Tile+Trans";
  892. AddItem(&cif, NULL, p, iGroupId);
  893. }
  894. //--------------------------------------------------------------------------
  895. void CreateImageFileTrueSize(IMAGEFILEDRAW eDraw, int iGroupId)
  896. {
  897. CImageFile cif;
  898. memset(&cif, 0, sizeof(cif));
  899. int idnum = IDB_TRUE;
  900. if (eDraw == IF_TRANS)
  901. idnum = IDB_TRUE_TRANS;
  902. else if (eDraw == IF_ALPHA)
  903. idnum = IDB_TRUE_ALPHA;
  904. cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  905. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  906. //---- create a ImageFile object that sizes with STRETCH ----
  907. cif._eBgType = BT_IMAGEFILE;
  908. cif._iImageCount = 8;
  909. cif._fMirrorImage = TRUE;
  910. cif._eImageLayout = IL_HORIZONTAL;
  911. cif._ImageInfo.iSingleWidth = 16;
  912. cif._ImageInfo.iSingleHeight = 16;
  913. cif._ImageInfo.eSizingType = ST_TRUESIZE;
  914. if (eDraw == IF_TRANS)
  915. {
  916. cif._ImageInfo.fTransparent = TRUE;
  917. cif._ImageInfo.crTransparent = RGB(255, 0, 255);
  918. }
  919. else if (eDraw == IF_ALPHA)
  920. {
  921. cif._ImageInfo.fAlphaChannel = TRUE;
  922. }
  923. LPCWSTR p = L"TrueSize";
  924. if (eDraw == IF_TRANS)
  925. p = L"True+Trans";
  926. else if (eDraw == IF_ALPHA)
  927. p = L"True+Alpha";
  928. AddItem(&cif, NULL, p, iGroupId);
  929. }
  930. //--------------------------------------------------------------------------
  931. void CreateImageFileCharGlyph()
  932. {
  933. CImageFile cif;
  934. memset(&cif, 0, sizeof(cif));
  935. int idnum = IDB_GLYPHBG;
  936. cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  937. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  938. //---- specify bg info ----
  939. cif._eBgType = BT_IMAGEFILE;
  940. cif._fMirrorImage = TRUE;
  941. cif._iImageCount = 3;
  942. cif._eImageLayout = IL_HORIZONTAL;
  943. cif._ImageInfo.iSingleWidth = 16;
  944. cif._ImageInfo.iSingleHeight = 22;
  945. cif._ImageInfo.eSizingType = ST_STRETCH;
  946. SetRect((RECT *)&cif._SizingMargins, 1, 1, 1, 1);
  947. //---- specify the char/font info ----
  948. cif._eGlyphType = GT_FONTGLYPH;
  949. cif._crGlyphTextColor = RGB(0, 0, 255);
  950. cif._iGlyphIndex = 62;
  951. cif._lfGlyphFont.lfWeight = FW_NORMAL;
  952. cif._lfGlyphFont.lfHeight = CLIPPER_FONTHEIGHT;
  953. lstrcpy(cif._lfGlyphFont.lfFaceName, L"marlett");
  954. //---- specify alignment ----
  955. cif._eHAlign = HA_CENTER;
  956. cif._eVAlign = VA_CENTER;
  957. LPCWSTR p = L"FontGlyph";
  958. AddItem(&cif, NULL, p, GID_GLYPH);
  959. }
  960. //--------------------------------------------------------------------------
  961. void CreateImageFileImageGlyph(IMAGEFILEDRAW eDraw, BOOL fForceMirror)
  962. {
  963. CImageFile cif;
  964. memset(&cif, 0, sizeof(cif));
  965. int idnum = IDB_GLYPHBG;
  966. cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  967. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  968. //---- specify bg info ----
  969. cif._eBgType = BT_IMAGEFILE;
  970. cif._fMirrorImage = TRUE;
  971. cif._eGlyphType = GT_IMAGEGLYPH;
  972. cif._iImageCount = 3;
  973. cif._eImageLayout = IL_HORIZONTAL;
  974. cif._ImageInfo.iSingleWidth = 16;
  975. cif._ImageInfo.iSingleHeight = 22;
  976. cif._ImageInfo.eSizingType = ST_STRETCH;
  977. SetRect((RECT *)&cif._SizingMargins, 1, 1, 1, 1);
  978. //---- specify glyph info ----
  979. WCHAR szName[MAX_PATH];
  980. if (eDraw == IF_REG)
  981. {
  982. idnum = IDB_GLYPH;
  983. lstrcpy(szName, L"ImageGlyph");
  984. cif._GlyphInfo.iSingleWidth = 10;
  985. cif._GlyphInfo.iSingleHeight = 7;
  986. }
  987. else if (eDraw == IF_TRANS)
  988. {
  989. idnum = IDB_GLYPH_TRANS;
  990. lstrcpy(szName, L"ImageTrans");
  991. cif._GlyphInfo.fTransparent = TRUE;
  992. cif._GlyphInfo.crTransparent = RGB(255, 0, 255);
  993. cif._GlyphInfo.iSingleWidth = 10;
  994. cif._GlyphInfo.iSingleHeight = 7;
  995. }
  996. else
  997. {
  998. idnum = IDB_GLYPH_ALPHA;
  999. lstrcpy(szName, L"ImageAlpha");
  1000. cif._GlyphInfo.fAlphaChannel = TRUE;
  1001. cif._GlyphInfo.iSingleWidth = 16;
  1002. cif._GlyphInfo.iSingleHeight = 16;
  1003. }
  1004. cif._GlyphInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  1005. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  1006. //---- specify alignment ----
  1007. cif._eHAlign = HA_CENTER;
  1008. cif._eVAlign = VA_CENTER;
  1009. DWORD dwDtbFlags = 0;
  1010. if (fForceMirror)
  1011. {
  1012. dwDtbFlags |= DTBG_MIRRORDC;
  1013. lstrcat(szName, L"+M");
  1014. }
  1015. AddItem(&cif, NULL, szName, GID_GLYPH, 0, dwDtbFlags);
  1016. }
  1017. //--------------------------------------------------------------------------
  1018. void CreateMultiImage()
  1019. {
  1020. CMaxImageFile MaxIf;
  1021. memset(&MaxIf, 0, sizeof(MaxIf));
  1022. //---- specify general info ----
  1023. MaxIf._eBgType = BT_IMAGEFILE;
  1024. MaxIf._fMirrorImage = TRUE;
  1025. MaxIf._iImageCount = 8;
  1026. MaxIf._eImageLayout = IL_VERTICAL;
  1027. MaxIf._eImageSelectType = IST_SIZE;
  1028. MaxIf._iMultiImageCount = 3;
  1029. MaxIf._iTrueSizeStretchMark = 50;
  1030. MaxIf._eTrueSizeScalingType = TSST_SIZE;
  1031. MaxIf._fUniformSizing = TRUE;
  1032. MaxIf._eHAlign = HA_CENTER;
  1033. MaxIf._eVAlign = VA_CENTER;
  1034. int iUsageSizes[] = {20, 24, 32};
  1035. //---- specify alignment ----
  1036. MaxIf._eHAlign = HA_CENTER;
  1037. MaxIf._eVAlign = VA_CENTER;
  1038. for (int i=0; i < MaxIf._iMultiImageCount; i++)
  1039. {
  1040. int idnum = IDB_MULTI1 + i;
  1041. DIBINFO *pdi = &MaxIf.MultiDibs[i];
  1042. pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
  1043. IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  1044. pdi->szMinSize.cx = iUsageSizes[i];
  1045. pdi->szMinSize.cy = iUsageSizes[i];
  1046. //---- get bitmap width/height ----
  1047. BITMAP bm;
  1048. GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
  1049. pdi->iSingleWidth = bm.bmWidth;
  1050. pdi->iSingleHeight = bm.bmHeight/8;
  1051. pdi->eSizingType = ST_TRUESIZE;
  1052. pdi->fAlphaChannel = TRUE;
  1053. }
  1054. //---- set primary image ----
  1055. MaxIf._ImageInfo = MaxIf.MultiDibs[0];
  1056. AddItem(&MaxIf, NULL, L"MultiImage", GID_MULTIIMAGE);
  1057. }
  1058. //--------------------------------------------------------------------------
  1059. void CreateTextObj()
  1060. {
  1061. CTextDraw td;
  1062. memset(&td, 0, sizeof(td));
  1063. //---- text ----
  1064. td._crText = RGB(255, 128, 128); // red
  1065. //---- font ----
  1066. td._fHaveFont = TRUE;
  1067. td._lfFont.lfWeight = FW_NORMAL;
  1068. td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
  1069. td._lfFont.lfQuality = ANTIALIASED_QUALITY;
  1070. lstrcpy(td._lfFont.lfFaceName, L"arial");
  1071. AddItem(NULL, &td, L"TextObj", GID_TEXT);
  1072. }
  1073. //--------------------------------------------------------------------------
  1074. void CreateShadowTextObj()
  1075. {
  1076. CTextDraw td;
  1077. memset(&td, 0, sizeof(td));
  1078. //---- text ----
  1079. td._crText = RGB(255, 139, 139); // light red
  1080. //---- font ----
  1081. td._fHaveFont = TRUE;
  1082. td._lfFont.lfWeight = FW_NORMAL;
  1083. td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
  1084. td._lfFont.lfQuality = ANTIALIASED_QUALITY;
  1085. lstrcpy(td._lfFont.lfFaceName, L"arial");
  1086. //---- shadow ----
  1087. td._ptShadowOffset.x = 2;
  1088. td._ptShadowOffset.y = 2;
  1089. td._crShadow = RGB(149, 0, 0); // dark red
  1090. td._eShadowType = TST_SINGLE;
  1091. AddItem(NULL, &td, L"ShadowText", GID_TEXT);
  1092. }
  1093. //--------------------------------------------------------------------------
  1094. void CreateBorderTextObj()
  1095. {
  1096. CTextDraw td;
  1097. memset(&td, 0, sizeof(td));
  1098. //---- text ----
  1099. td._crText = RGB(255, 139, 139); // light red
  1100. //---- font ----
  1101. td._fHaveFont = TRUE;
  1102. td._lfFont.lfWeight = FW_NORMAL;
  1103. td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
  1104. td._lfFont.lfQuality = ANTIALIASED_QUALITY;
  1105. lstrcpy(td._lfFont.lfFaceName, L"arial");
  1106. //---- border ----
  1107. td._iBorderSize = 1;
  1108. td._crBorder = RGB(128, 128, 255); // light blue
  1109. AddItem(NULL, &td, L"BorderText", GID_TEXT);
  1110. }
  1111. //--------------------------------------------------------------------------
  1112. void CreateBorderShadowTextObj()
  1113. {
  1114. CTextDraw td;
  1115. memset(&td, 0, sizeof(td));
  1116. //---- text ----
  1117. td._crText = RGB(255, 139, 139); // light red
  1118. //---- font ----
  1119. td._fHaveFont = TRUE;
  1120. td._lfFont.lfWeight = FW_NORMAL;
  1121. td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
  1122. td._lfFont.lfQuality = ANTIALIASED_QUALITY;
  1123. lstrcpy(td._lfFont.lfFaceName, L"arial");
  1124. //---- shadow ----
  1125. td._ptShadowOffset.x = 2;
  1126. td._ptShadowOffset.y = 2;
  1127. td._crShadow = RGB(149, 0, 0); // dark red
  1128. td._eShadowType = TST_SINGLE;
  1129. //---- border ----
  1130. td._iBorderSize = 1;
  1131. td._crBorder = RGB(0, 0, 0); // black
  1132. AddItem(NULL, &td, L"BorderShadow", GID_TEXT);
  1133. }
  1134. //--------------------------------------------------------------------------
  1135. void CreateBlurShadowTextObj()
  1136. {
  1137. CTextDraw td;
  1138. memset(&td, 0, sizeof(td));
  1139. //---- text ----
  1140. td._crText = RGB(255, 139, 139); // light red
  1141. //---- font ----
  1142. td._fHaveFont = TRUE;
  1143. td._lfFont.lfWeight = FW_NORMAL;
  1144. td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
  1145. td._lfFont.lfQuality = ANTIALIASED_QUALITY;
  1146. lstrcpy(td._lfFont.lfFaceName, L"arial");
  1147. //---- shadow ----
  1148. td._ptShadowOffset.x = 2;
  1149. td._ptShadowOffset.y = 2;
  1150. td._crShadow = RGB(149, 0, 0); // dark red
  1151. td._eShadowType = TST_CONTINUOUS;
  1152. AddItem(NULL, &td, L"BlurShadow", GID_TEXT);
  1153. }
  1154. //--------------------------------------------------------------------------
  1155. void LabelClip(HDC hdc, RECT *prc, int iColIndex, LPCWSTR pszName)
  1156. {
  1157. int left = prc->left + (iColIndex+1)*szCell.cx;
  1158. int top = prc->top + 6; // some padding from very top of window
  1159. //---- manual page clipping ----
  1160. if ((top + szCell.cy) < 0)
  1161. return;
  1162. if (top > iVertPageSize)
  1163. return;
  1164. TextOut(hdc, left, top, pszName, wcslen(pszName));
  1165. }
  1166. //--------------------------------------------------------------------------
  1167. void CreateDrawObjects()
  1168. {
  1169. //---- borderfill group ----
  1170. CreateBorderFillNoDraw();
  1171. CreateBorderFillSquare();
  1172. CreateBorderFillBorder();
  1173. CreateBorderFillCircle();
  1174. CreateBorderFillGradient();
  1175. CreateBorderFillCircleGradient();
  1176. //---- imagefile group ----
  1177. CreateImageFileStretch(IF_REG, GID_IMAGEFILE);
  1178. CreateImageFileStretch(IF_TRANS, GID_IMAGEFILE);
  1179. CreateImageFileTile(IF_REG, GID_IMAGEFILE);
  1180. CreateImageFileTile(IF_TRANS, GID_IMAGEFILE);
  1181. CreateImageFileTrueSize(IF_REG, GID_IMAGEFILE);
  1182. CreateImageFileTrueSize(IF_TRANS, GID_IMAGEFILE);
  1183. CreateImageFileTrueSize(IF_ALPHA, GID_IMAGEFILE);
  1184. //---- glyph group ----
  1185. //CreateImageFileCharGlyph();
  1186. CreateImageFileImageGlyph(IF_REG, FALSE);
  1187. CreateImageFileImageGlyph(IF_TRANS, FALSE);
  1188. CreateImageFileImageGlyph(IF_TRANS, TRUE);
  1189. CreateImageFileImageGlyph(IF_ALPHA, FALSE);
  1190. //---- MultiImage group ----
  1191. CreateMultiImage();
  1192. //---- text group ----
  1193. CreateTextObj();
  1194. CreateShadowTextObj();
  1195. CreateBorderTextObj();
  1196. CreateBorderShadowTextObj();
  1197. CreateBlurShadowTextObj();
  1198. //---- borders group ----
  1199. CreateImageFileBorder(ST_TRUESIZE, FALSE, FALSE);
  1200. CreateImageFileBorder(ST_STRETCH, FALSE, FALSE);
  1201. CreateImageFileBorder(ST_STRETCH, TRUE, TRUE);
  1202. CreateImageFileBorder(ST_TILE, TRUE, TRUE);
  1203. //---- SrcSizing group ----
  1204. CreateImage(IDB_PUSHBUTTON, 5, ST_STRETCH, TRUE, GID_SRCSIZING, L"PushButton",
  1205. 8, 8, 9, 9);
  1206. CreateRadioImage();
  1207. CreateCheckImage();
  1208. CreateScrollGlyph();
  1209. CreateProgressTrack();
  1210. CreateProgressChunk();
  1211. }
  1212. //--------------------------------------------------------------------------
  1213. void CenterRect(POINT &ptCenter, int iSize, RECT *prc)
  1214. {
  1215. int iSizeA = iSize/2;
  1216. int iSizeB = iSize - iSizeA;
  1217. prc->left = ptCenter.x - iSizeA;
  1218. prc->right = ptCenter.x + iSizeB;
  1219. prc->top = ptCenter.y - iSizeA;
  1220. prc->bottom = ptCenter.y + iSizeB;
  1221. }
  1222. //--------------------------------------------------------------------------
  1223. void DrawMultiImages(HDC hdc, RECT *prc, HTHEME hTheme)
  1224. {
  1225. SIZE szMyCell = {80, 80};
  1226. int iRowIndex = 0;
  1227. int iSizes[] = {12, 16, 20, 24, 32, 48, 64};
  1228. //---- draw various sizes of image ----
  1229. for (int iIndex=0; iIndex < ARRAYSIZE(iSizes); iIndex++)
  1230. {
  1231. int iSize = iSizes[iIndex];
  1232. //---- label object on left ----
  1233. int left = prc->left + 4; // some padding away from edge
  1234. int top = prc->top + (iRowIndex)*szMyCell.cy + 18; // try to center
  1235. //---- manual page clipping ----
  1236. if ((top + szMyCell.cy) < 0)
  1237. return;
  1238. if (top > iVertPageSize)
  1239. return;
  1240. WCHAR szName[MAX_PATH];
  1241. wsprintf(szName, L"Size: %d", iSize);
  1242. TextOut(hdc, left, top+15, szName, wcslen(szName));
  1243. //---- draw image in all of its states ----
  1244. int iPartId = BP_RADIOBUTTON;
  1245. for (int iStateId=RBS_UNCHECKEDNORMAL; iStateId <= RBS_CHECKEDDISABLED; iStateId++)
  1246. {
  1247. left += szMyCell.cx;
  1248. RECT rc = {left, top, left+szMyCell.cx, top+szMyCell.cy};
  1249. //---- draw purple target dashed rect ----
  1250. DrawTargetRect(hdc, &rc, RGB(128, 128, 255));
  1251. //---- calc center pt ----
  1252. POINT ptCenter = {left + szMyCell.cx/2, top + szMyCell.cy/2};
  1253. //---- rect to draw into ----
  1254. CenterRect(ptCenter, iSize, &rc);
  1255. //---- draw red rect for "draw into" rect ----
  1256. DrawTargetRect(hdc, &rc, RGB(255, 0, 0));
  1257. HRESULT hr = DrawThemeBackground(hTheme, hdc, iPartId, iStateId, &rc, NULL);
  1258. if (FAILED(hr))
  1259. {
  1260. WCHAR buff[100];
  1261. wsprintf(buff, L"DrawThemeBackground err: hr=0x%x, irow=%d, iPartId=%d",
  1262. hr, iRowIndex, iPartId);
  1263. //MessageBox(NULL, buff, L"Error", MB_OK);
  1264. }
  1265. }
  1266. iRowIndex++;
  1267. }
  1268. }
  1269. //--------------------------------------------------------------------------
  1270. void DrawBorders(HDC hdc, RECT *prc, TESTITEM *pTestItem)
  1271. {
  1272. int top = prc->top + 4;
  1273. int left = prc->left + 6;
  1274. //---- message on top line ----
  1275. WCHAR szBuff[100];
  1276. lstrcpy(szBuff, L"Image: BorderTest.bmp, 18x17, 24 bit, Sizing Margins: 3, 3, 3, 3");
  1277. TextOut(hdc, left, top+15, szBuff, wcslen(szBuff));
  1278. top += 44;
  1279. //---- FIRST row: draw border test obj in 6 different sizes ----
  1280. SIZE szMyCell = {120, 120};
  1281. //---- manual page clipping ----
  1282. if (((top + szMyCell.cy) >= 0) && (top <= iVertPageSize))
  1283. {
  1284. LPCWSTR pszLabels [] = { L"TrueSize", L"Stretch", L"Stretch", L"Stretch",
  1285. L"Stretch", L"Stretch", L"Stretch"};
  1286. SIZE szSizes[] = { {60, 40}, {60, 40}, {6, 40}, {3, 40}, {60, 6}, {60, 2}, {2, 3} };
  1287. //---- draw various sizes of image ----
  1288. for (int iIndex=0; iIndex < ARRAYSIZE(szSizes); iIndex++)
  1289. {
  1290. SIZE sz = szSizes[iIndex];
  1291. //---- label object on top ----
  1292. left = prc->left + iIndex*szMyCell.cx + 6; // some padding away from edge
  1293. wsprintf(szBuff, L"%s (%dx%d)", pszLabels[iIndex], sz.cx, sz.cy);
  1294. TextOut(hdc, left, top+15, szBuff, wcslen(szBuff));
  1295. //---- draw image ----
  1296. RECT rc = {left, top+50, left+sz.cx, top+50+sz.cy};
  1297. int i = (iIndex==0) ? 0 : 1;
  1298. HRESULT hr = DrawThemeBackground(pTestItem[i].hTheme, hdc, 0, 0, &rc, NULL);
  1299. if (FAILED(hr))
  1300. {
  1301. WCHAR buff[100];
  1302. wsprintf(buff, L"DrawThemeBackground err in DrawBorders: hr=0x%x, iIndex=%d",
  1303. hr, iIndex);
  1304. //MessageBox(NULL, buff, L"Error", MB_OK);
  1305. }
  1306. }
  1307. }
  1308. //---- SECOND row: draw 2 other border objects real big (test border scaling) ----
  1309. top += szMyCell.cy;
  1310. szMyCell.cx = 380;
  1311. szMyCell.cy = 300;
  1312. SIZE sz = {szMyCell.cx - 30, szMyCell.cy - (50 + 10)};
  1313. //---- manual page clipping: first row ----
  1314. if (((top + szMyCell.cy) >= 0) && (top <= iVertPageSize))
  1315. {
  1316. LPCWSTR pszLabels [] = { L"Border Scaling (stretch)", L"Border Scaling (tile)"};
  1317. //---- draw various sizes of image ----
  1318. for (int iIndex=0; iIndex < ARRAYSIZE(pszLabels); iIndex++)
  1319. {
  1320. //---- label object on top ----
  1321. int left = prc->left + iIndex*szMyCell.cx + 6; // some padding away from edge
  1322. TextOut(hdc, left, top+15, pszLabels[iIndex], wcslen(pszLabels[iIndex]));
  1323. //---- draw image ----
  1324. RECT rc = {left, top+50, left+sz.cx, top+50+sz.cy};
  1325. HRESULT hr = DrawThemeBackground(pTestItem[2+iIndex].hTheme, hdc, 0, 0, &rc, NULL);
  1326. if (FAILED(hr))
  1327. {
  1328. WCHAR buff[100];
  1329. wsprintf(buff, L"DrawThemeBackground err in DrawBorders: hr=0x%x, iIndex=%d",
  1330. hr, iIndex);
  1331. //MessageBox(NULL, buff, L"Error", MB_OK);
  1332. }
  1333. }
  1334. }
  1335. }
  1336. //--------------------------------------------------------------------------
  1337. void DrawSrcSizing(HDC hdc, RECT *prc, TESTITEM *pTestItem)
  1338. {
  1339. SIZE szMyCell = {120, 110};
  1340. int top = prc->top + 4;
  1341. int left = prc->left + szMyCell.cx + 6;
  1342. //---- labels on top line ----
  1343. LPCWSTR TopLabels[] = {L"Small", L"Regular", L"Large", L"High DPI"};
  1344. SIZE szStretchSizes[] = { {50, 6}, {75, 23}, {90, 65}, {340, 100} };
  1345. SIZE szTrueSizes[] = { {10, 6}, {13, 13}, {30, 30}, {340, 100} };
  1346. int iStates[] = {5, 6, 6, 0, 0};
  1347. for (int i=0; i < ARRAYSIZE(TopLabels); i++)
  1348. {
  1349. TextOut(hdc, left, top, TopLabels[i], wcslen(TopLabels[i]));
  1350. left += szMyCell.cx;
  1351. }
  1352. top += 30;
  1353. //---- draw rows ----
  1354. for (int iRow=0; iRow < 5; iRow++)
  1355. {
  1356. //---- draw name on left ----
  1357. left = prc->left + 6;
  1358. WCHAR *pszName = pTestItem[iRow].szName;
  1359. TextOut(hdc, left, top-5, pszName, wcslen(pszName));
  1360. for (int iSize=0; iSize < ARRAYSIZE(szStretchSizes); iSize++)
  1361. {
  1362. left += szMyCell.cx;
  1363. SIZE *psz;
  1364. if ((iRow > 0) && (iRow < 4))
  1365. {
  1366. psz = &szTrueSizes[iSize];
  1367. }
  1368. else
  1369. {
  1370. psz = &szStretchSizes[iSize];
  1371. }
  1372. RECT rc = {left, top, left + psz->cx, top + psz->cy};
  1373. HTHEME hTheme = pTestItem[iRow].hTheme;
  1374. if (hTheme)
  1375. {
  1376. DrawThemeBackground(hTheme, hdc, 0, iStates[iRow], &rc, NULL);
  1377. if (iRow == 4) // progress control
  1378. {
  1379. RECT rcContent;
  1380. GetThemeBackgroundContentRect(hTheme, hdc,
  1381. 0, 0, &rc, &rcContent);
  1382. DrawThemeBackground(pTestItem[5].hTheme, hdc, 0, iStates[iRow], &rcContent, NULL);
  1383. }
  1384. }
  1385. }
  1386. top += szMyCell.cy;
  1387. }
  1388. }
  1389. //--------------------------------------------------------------------------
  1390. void PaintObjects(HDC hdc, RECT *prc, int iGroupId)
  1391. {
  1392. //---- select in a fixed size font for resolution-independent bits ----
  1393. HFONT hfFixedSize = CreateFont(18, 6, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,
  1394. 0, 0, 0, 0, L"MS Sans Serif");
  1395. HFONT hOldFont = (HFONT)SelectObject(hdc, hfFixedSize);
  1396. RECT rc = *prc;
  1397. rc.top -= iVertOffset;
  1398. rc.bottom -= iVertOffset;
  1399. if (iGroupId == GID_TEXT) // text object
  1400. {
  1401. for (int i=0; i < iItemCount[iGroupId]; i++)
  1402. {
  1403. DrawTextObjects(TestItems[iGroupId][i].hTheme, hdc, &rc, i,
  1404. TestItems[iGroupId][i].szName);
  1405. }
  1406. }
  1407. else if (iGroupId == GID_MULTIIMAGE)
  1408. {
  1409. DrawMultiImages(hdc, prc, TestItems[iGroupId][0].hTheme);
  1410. }
  1411. else if (iGroupId == GID_BORDERS)
  1412. {
  1413. DrawBorders(hdc, prc, TestItems[iGroupId]);
  1414. }
  1415. else if (iGroupId == GID_SRCSIZING)
  1416. {
  1417. DrawSrcSizing(hdc, prc, TestItems[iGroupId]);
  1418. }
  1419. else
  1420. {
  1421. LabelClip(hdc, &rc, 0, L"NoClip");
  1422. LabelClip(hdc, &rc, 1, L"OverClip");
  1423. LabelClip(hdc, &rc, 2, L"ExactClip");
  1424. LabelClip(hdc, &rc, 3, L"PartialClip");
  1425. LabelClip(hdc, &rc, 4, L"InOut1");
  1426. LabelClip(hdc, &rc, 5, L"InOut2");
  1427. LabelClip(hdc, &rc, 6, L"OutClip");
  1428. for (int i=0; i < iItemCount[iGroupId]; i++)
  1429. {
  1430. DrawClips(TestItems[iGroupId][i].hTheme, hdc, &rc, i,
  1431. TestItems[iGroupId][i].szName, TestItems[iGroupId][i].dwDtbFlags);
  1432. }
  1433. }
  1434. //---- restore the font ----
  1435. SelectObject(hdc, hOldFont);
  1436. DeleteObject(hfFixedSize);
  1437. }
  1438. //--------------------------------------------------------------------------
  1439. void RegisterWindowClasses()
  1440. {
  1441. WNDCLASSEX wcex;
  1442. wcex.cbSize = sizeof(WNDCLASSEX);
  1443. //---- register MAIN window class ----
  1444. wcex.style = 0;
  1445. wcex.lpfnWndProc = (WNDPROC)MainWndProc;
  1446. wcex.cbClsExtra = 0;
  1447. wcex.cbWndExtra = 0;
  1448. wcex.hInstance = hInst;
  1449. wcex.hIcon = LoadIcon(hInst, (LPCTSTR)IDI_CLIPPER);
  1450. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  1451. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  1452. wcex.lpszMenuName = (LPCWSTR)IDC_CLIPPER;
  1453. wcex.lpszClassName = pszMainWindowClass;
  1454. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  1455. RegisterClassEx(&wcex);
  1456. //---- register DISPLAY window class ----
  1457. wcex.style = CS_HREDRAW | CS_VREDRAW;
  1458. wcex.lpfnWndProc = (WNDPROC)DisplayWndProc;
  1459. wcex.cbClsExtra = 0;
  1460. wcex.cbWndExtra = 0;
  1461. wcex.hInstance = hInst;
  1462. wcex.hIcon = LoadIcon(hInst, (LPCTSTR)IDI_CLIPPER);
  1463. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  1464. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  1465. wcex.lpszMenuName = (LPCWSTR)IDC_CLIPPER;
  1466. wcex.lpszClassName = pszDisplayWindowClass;
  1467. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  1468. RegisterClassEx(&wcex);
  1469. }
  1470. //--------------------------------------------------------------------------
  1471. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  1472. {
  1473. hInst = hInstance; // Store instance handle in our global variable
  1474. CreateDrawObjects();
  1475. if (! CreateAllWindows())
  1476. return FALSE;
  1477. ShowWindow(hwndMain, nCmdShow);
  1478. UpdateWindow(hwndMain);
  1479. return TRUE;
  1480. }
  1481. //--------------------------------------------------------------------------
  1482. void HandleVScroll(int message, WPARAM wParam, LPARAM lParam)
  1483. {
  1484. int iOldVertOffset = iVertOffset;
  1485. if (message == WM_VSCROLL)
  1486. {
  1487. switch (LOWORD(wParam))
  1488. {
  1489. case SB_LINEUP:
  1490. iVertOffset -= iVertLineSize;
  1491. break;
  1492. case SB_LINEDOWN:
  1493. iVertOffset += iVertLineSize;
  1494. break;
  1495. case SB_PAGEUP:
  1496. iVertOffset -= iVertPageSize;
  1497. break;
  1498. case SB_PAGEDOWN:
  1499. iVertOffset += iVertPageSize;
  1500. break;
  1501. case SB_THUMBPOSITION:
  1502. iVertOffset = HIWORD(wParam);
  1503. break;
  1504. }
  1505. }
  1506. else // mouse wheel
  1507. {
  1508. iVertOffset -= (GET_WHEEL_DELTA_WPARAM(wParam)/10);
  1509. }
  1510. //---- keep in valid range ----
  1511. if (iVertOffset < 0)
  1512. {
  1513. iVertOffset = 0;
  1514. }
  1515. else if (iVertOffset > iMaxVertOffset)
  1516. {
  1517. iVertOffset = iMaxVertOffset;
  1518. }
  1519. //---- scroll or repaint, as needed ----
  1520. if (iVertOffset != iOldVertOffset)
  1521. {
  1522. SetScrollPos(hwndDisplay, SB_VERT, iVertOffset, TRUE);
  1523. int iDiff = (iVertOffset - iOldVertOffset);
  1524. if (abs(iDiff) >= iVertPageSize)
  1525. {
  1526. InvalidateRect(hwndDisplay, NULL, TRUE);
  1527. }
  1528. else
  1529. {
  1530. ScrollWindowEx(hwndDisplay, 0, -iDiff, NULL, NULL, NULL,
  1531. NULL, SW_INVALIDATE | SW_ERASE);
  1532. }
  1533. }
  1534. }
  1535. //--------------------------------------------------------------------------
  1536. void OnDisplayResize()
  1537. {
  1538. int iTabNum = TabCtrl_GetCurSel(hwndTab);
  1539. if (iTabNum < 0)
  1540. iTabNum = 0;
  1541. int iGroupId = iTabNum/2;
  1542. RECT rc;
  1543. GetClientRect(hwndDisplay, &rc);
  1544. iVertPageSize = RECTHEIGHT(rc);
  1545. iMaxVertOffset = ((iItemCount[iGroupId]+1)*szCell.cy) - iVertPageSize;
  1546. if (iMaxVertOffset < 0)
  1547. iMaxVertOffset = 0;
  1548. if (iVertOffset > iMaxVertOffset)
  1549. iVertOffset = iMaxVertOffset;
  1550. //---- set scrolling info ----
  1551. SetScrollRange(hwndDisplay, SB_VERT, 0, iMaxVertOffset, FALSE);
  1552. SetScrollPos(hwndDisplay, SB_VERT, iVertOffset, TRUE);
  1553. }
  1554. //--------------------------------------------------------------------------
  1555. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1556. {
  1557. int wmId, wmEvent;
  1558. int iWidth, iHeight;
  1559. switch (message)
  1560. {
  1561. case WM_COMMAND:
  1562. wmId = LOWORD(wParam);
  1563. wmEvent = HIWORD(wParam);
  1564. // Parse the menu selections:
  1565. switch (wmId)
  1566. {
  1567. case IDM_ABOUT:
  1568. DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  1569. break;
  1570. case IDM_EXIT:
  1571. DestroyWindow(hWnd);
  1572. break;
  1573. default:
  1574. return DefWindowProc(hWnd, message, wParam, lParam);
  1575. }
  1576. break;
  1577. case WM_NOTIFY:
  1578. NMHDR *phdr;
  1579. phdr = (NMHDR *)lParam;
  1580. if (phdr->code == TCN_SELCHANGE) // tab selection
  1581. {
  1582. iVertOffset = 0;
  1583. OnDisplayResize();
  1584. InvalidateRect(hwndDisplay, NULL, TRUE);
  1585. }
  1586. break;
  1587. case WM_SIZE:
  1588. iWidth = LOWORD(lParam);
  1589. iHeight = HIWORD(lParam);
  1590. MoveWindow(hwndTab, 0, 0, iWidth, iHeight, TRUE);
  1591. RECT rc;
  1592. SetRect(&rc, 0, 0, iWidth, iHeight);
  1593. TabCtrl_AdjustRect(hwndTab, FALSE, &rc);
  1594. MoveWindow(hwndDisplay, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), TRUE);
  1595. break;
  1596. case WM_MOUSEWHEEL:
  1597. HandleVScroll(message, wParam, lParam);
  1598. return 0;
  1599. case WM_DESTROY:
  1600. PostQuitMessage(0);
  1601. break;
  1602. default:
  1603. return DefWindowProc(hWnd, message, wParam, lParam);
  1604. }
  1605. return 0;
  1606. }
  1607. //--------------------------------------------------------------------------
  1608. LRESULT CALLBACK DisplayWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1609. {
  1610. int wmId, wmEvent;
  1611. PAINTSTRUCT ps;
  1612. HDC hdc;
  1613. int iTabNum = TabCtrl_GetCurSel(hwndTab);
  1614. if (iTabNum < 0)
  1615. iTabNum = 0;
  1616. int iGroupId = iTabNum/2;
  1617. switch (message)
  1618. {
  1619. case WM_COMMAND:
  1620. wmId = LOWORD(wParam);
  1621. wmEvent = HIWORD(wParam);
  1622. // Parse the menu selections:
  1623. switch (wmId)
  1624. {
  1625. case IDM_ABOUT:
  1626. DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  1627. break;
  1628. case IDM_EXIT:
  1629. DestroyWindow(hWnd);
  1630. break;
  1631. default:
  1632. return DefWindowProc(hWnd, message, wParam, lParam);
  1633. }
  1634. break;
  1635. case WM_PAINT:
  1636. RECT rt;
  1637. hdc = BeginPaint(hWnd, &ps);
  1638. if (iTabNum % 2) // if its a mirrored page
  1639. SetLayout(hdc, LAYOUT_RTL);
  1640. else
  1641. SetLayout(hdc, 0);
  1642. GetClientRect(hWnd, &rt);
  1643. PaintObjects(hdc, &rt, iGroupId);
  1644. EndPaint(hWnd, &ps);
  1645. break;
  1646. case WM_VSCROLL:
  1647. HandleVScroll(message, wParam, lParam);
  1648. return 0;
  1649. case WM_SIZE:
  1650. OnDisplayResize();
  1651. break;
  1652. case WM_DESTROY:
  1653. PostQuitMessage(0);
  1654. break;
  1655. default:
  1656. return DefWindowProc(hWnd, message, wParam, lParam);
  1657. }
  1658. return 0;
  1659. }
  1660. //--------------------------------------------------------------------------
  1661. BOOL CreateAllWindows()
  1662. {
  1663. TCITEM tci = {0};
  1664. BOOL fOk = FALSE;
  1665. int i;
  1666. //---- create main window ----
  1667. hwndMain = CreateWindow(pszMainWindowClass, L"Clipper", WS_OVERLAPPEDWINDOW,
  1668. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
  1669. if (! hwndMain)
  1670. goto exit;
  1671. //---- create tab control covering main client area ----
  1672. RECT rc;
  1673. GetClientRect(hwndMain, &rc);
  1674. hwndTab = CreateWindowEx(0, WC_TABCONTROL, L"",
  1675. WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TCS_MULTILINE|TCS_HOTTRACK|WS_VISIBLE,
  1676. rc.left, rc.top, (int)RECTWIDTH(&rc), (int)RECTHEIGHT(&rc), hwndMain, NULL, hInst, NULL);
  1677. if (! hwndTab)
  1678. goto exit;
  1679. //---- create the display window in the tab control "display area" ----
  1680. hwndDisplay = CreateWindow(pszDisplayWindowClass, L"", WS_CHILD|WS_VSCROLL|WS_VISIBLE,
  1681. rc.left, rc.top, (int)RECTWIDTH(&rc), (int)RECTHEIGHT(&rc), hwndTab, NULL, hInst, NULL);
  1682. if (! hwndDisplay)
  1683. goto exit;
  1684. //---- add tab pages ----
  1685. tci.mask = TCIF_TEXT;
  1686. TabCtrl_SetPadding(hwndTab, 7, 3);
  1687. for (i=0; i < ARRAYSIZE(szPageNames); i++)
  1688. {
  1689. tci.pszText = (LPWSTR)szPageNames[i];
  1690. SendMessage(hwndTab, TCM_INSERTITEM, i, (LPARAM)&tci);
  1691. }
  1692. fOk = TRUE;
  1693. exit:
  1694. return fOk;
  1695. }
  1696. //--------------------------------------------------------------------------
  1697. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1698. {
  1699. switch (message)
  1700. {
  1701. case WM_INITDIALOG:
  1702. return TRUE;
  1703. case WM_COMMAND:
  1704. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  1705. {
  1706. EndDialog(hDlg, LOWORD(wParam));
  1707. return TRUE;
  1708. }
  1709. break;
  1710. }
  1711. return FALSE;
  1712. }
  1713. //--------------------------------------------------------------------------