Leaked source code of windows server 2003
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.

471 lines
14 KiB

  1. //----------------------------------------------------------------------------
  2. // Preview.cpp - image preview app for theme authoring
  3. //----------------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "resource.h"
  6. #include "shlwapip.h"
  7. #include "themeldr.h"
  8. //----------------------------------------------------------------------------
  9. #define MAX_LOADSTRING 100
  10. //----------------------------------------------------------------------------
  11. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  12. HRESULT InitDib(HINSTANCE hInstance, LPCWSTR pszFileName);
  13. void SetBackground(HWND hWnd, HINSTANCE hinst, int id, int iMenuId);
  14. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  15. void OnFileOpen(HINSTANCE hInst, HWND hWnd);
  16. void SetZoom(HWND hWnd, HINSTANCE hInstance, int iZoomPercent, int iMenuId);
  17. //----------------------------------------------------------------------------
  18. HINSTANCE hInst;
  19. HBITMAP hCenterDIB = NULL;
  20. HBITMAP hbrBackground = NULL;
  21. int iDibWidth;
  22. int iDibHeight;
  23. int iCurrentBgMenu = 0;
  24. int iCurrentZoomMenu = 0;
  25. int iZoomFactor = 100;
  26. BOOL fAlpha;
  27. //----------------------------------------------------------------------------
  28. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdShow)
  29. {
  30. MSG msg;
  31. HACCEL hAccelTable;
  32. TCHAR szWindowClass[MAX_LOADSTRING];
  33. TCHAR szTitle[MAX_LOADSTRING];
  34. //---- initialize globals from themeldr.lib ----
  35. ThemeLibStartUp(FALSE);
  36. //---- Initialize global strings ----
  37. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  38. LoadString(hInstance, IDC_PREVIEW, szWindowClass, MAX_LOADSTRING);
  39. //---- register window class ----
  40. WNDCLASSEX wcex;
  41. wcex.cbSize = sizeof(WNDCLASSEX);
  42. wcex.style = CS_HREDRAW | CS_VREDRAW;
  43. wcex.lpfnWndProc = WndProc;
  44. wcex.cbClsExtra = 0;
  45. wcex.cbWndExtra = 0;
  46. wcex.hInstance = hInstance;
  47. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PREVIEW);
  48. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  49. wcex.hbrBackground = NULL;
  50. wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PREVIEW);
  51. wcex.lpszClassName = szWindowClass;
  52. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  53. RegisterClassEx(&wcex);
  54. if (*lpCmdLine)
  55. InitDib(hInstance, lpCmdLine);
  56. //---- create the main window ----
  57. HWND hWnd;
  58. hInst = hInstance; // Store instance handle in our global variable
  59. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  60. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  61. if (!hWnd)
  62. return 1;
  63. SetBackground(hWnd, hInstance, IDB_PINKGRAY, ID_BACKGROUND_GRAYPINK);
  64. SetZoom(hWnd, hInstance, 100, ID_ZOOM_100);
  65. ShowWindow(hWnd, nCmdShow);
  66. UpdateWindow(hWnd);
  67. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PREVIEW);
  68. //---- initialize us as a drag target ----
  69. DragAcceptFiles(hWnd, TRUE);
  70. //---- main message loop ----
  71. while (GetMessage(&msg, NULL, 0, 0))
  72. {
  73. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  74. {
  75. TranslateMessage(&msg);
  76. DispatchMessage(&msg);
  77. }
  78. }
  79. return (int)msg.wParam;
  80. }
  81. //----------------------------------------------------------------------------
  82. void SetBackground(HWND hWnd, HINSTANCE hInstance, int id, int iMenuId)
  83. {
  84. if (hbrBackground)
  85. DeleteObject(hbrBackground);
  86. hbrBackground = LoadBitmap(hInstance, MAKEINTRESOURCE(id));
  87. InvalidateRect(hWnd, NULL, TRUE);
  88. //---- update menu items ----
  89. HMENU hMenu = GetMenu(hWnd);
  90. hMenu = GetSubMenu(hMenu, 1);
  91. if (iCurrentBgMenu)
  92. CheckMenuItem(hMenu, iCurrentBgMenu, MF_BYCOMMAND | MF_UNCHECKED);
  93. CheckMenuItem(hMenu, iMenuId, MF_BYCOMMAND | MF_CHECKED);
  94. iCurrentBgMenu = iMenuId;
  95. }
  96. //----------------------------------------------------------------------------
  97. HRESULT InitDib(HINSTANCE hInstance, LPCWSTR pszFileName)
  98. {
  99. if (hCenterDIB)
  100. {
  101. DeleteObject(hCenterDIB);
  102. hCenterDIB = NULL;
  103. }
  104. int iRetVal = 0;
  105. fAlpha = FALSE;
  106. WCHAR *pszOutputName = L"$temp$.bmp";
  107. HRESULT hr = S_OK;
  108. HDC hdc = NULL;
  109. DWORD *pBits = NULL;
  110. //---- ensure file exists ----
  111. if (! FileExists(pszFileName))
  112. {
  113. hr = MakeError32(STG_E_FILENOTFOUND);
  114. goto exit;
  115. }
  116. //---- convert file, if needed ----
  117. WCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szBaseName[_MAX_FNAME], szExt[_MAX_EXT];
  118. _wsplitpath(pszFileName, szDrive, szDir, szBaseName, szExt);
  119. if (lstrcmpi(szExt, L".bmp") != 0) // not a .bmp file
  120. {
  121. //---- protect ourselves from crashes ----
  122. try
  123. {
  124. hr = SHConvertGraphicsFile(pszFileName, pszOutputName, SHCGF_REPLACEFILE);
  125. }
  126. catch (...)
  127. {
  128. hr = MakeError32(E_FAIL);
  129. }
  130. if ((SUCCEEDED(hr)) && (! FileExists(pszOutputName)))
  131. hr = MakeError32(E_FAIL);
  132. if (FAILED(hr))
  133. goto exit;
  134. pszFileName = pszOutputName;
  135. }
  136. //---- load the specified center bitmap as a DIB ----
  137. hCenterDIB = (HBITMAP) LoadImage(hInstance, pszFileName, IMAGE_BITMAP,
  138. 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  139. if (! hCenterDIB)
  140. {
  141. hr = MakeErrorLast();
  142. goto exit;
  143. }
  144. BITMAP bminfo;
  145. GetObject(hCenterDIB, sizeof(bminfo), &bminfo);
  146. iDibWidth = bminfo.bmWidth;
  147. iDibHeight = bminfo.bmHeight;
  148. if (bminfo.bmBitsPixel < 32)
  149. iRetVal = 1;
  150. else
  151. {
  152. pBits = new DWORD[(iDibWidth+20)*iDibHeight];
  153. if (! pBits)
  154. {
  155. hr = MakeError32(E_OUTOFMEMORY);
  156. goto exit;
  157. }
  158. BITMAPINFOHEADER BitMapHdr = {sizeof(BITMAPINFOHEADER), iDibWidth, iDibHeight, 1, 32, BI_RGB};
  159. hdc = GetWindowDC(NULL);
  160. if (! hdc)
  161. {
  162. hr = MakeErrorLast();
  163. goto exit;
  164. }
  165. iRetVal = GetDIBits(hdc, hCenterDIB, 0, iDibHeight, pBits, (BITMAPINFO *)&BitMapHdr, DIB_RGB_COLORS);
  166. if (! iRetVal)
  167. {
  168. hr = MakeErrorLast();
  169. goto exit;
  170. }
  171. DWORD *pdw = pBits;
  172. //---- pre-multiply bits - required by AlphaBlend() API ----
  173. for (int r=0; r < iDibHeight; r++)
  174. {
  175. for (int c=0; c < iDibWidth; c++)
  176. {
  177. COLORREF cr = *pdw;
  178. int iAlpha = ALPHACHANNEL(cr);
  179. if (iAlpha)
  180. {
  181. int iRed = (RED(cr)*iAlpha)/255;
  182. int iGreen = (GREEN(cr)*iAlpha)/255;
  183. int iBlue = (BLUE(cr)*iAlpha)/255;
  184. *pdw++ = (RGB(iRed, iGreen, iBlue) | (iAlpha << 24));
  185. fAlpha = TRUE;
  186. }
  187. else
  188. *pdw++ = 0;
  189. }
  190. }
  191. if (fAlpha)
  192. {
  193. iRetVal = SetDIBits(NULL, hCenterDIB, 0, iDibHeight, pBits, (BITMAPINFO *)&BitMapHdr, DIB_RGB_COLORS);
  194. if (! iRetVal)
  195. {
  196. hr = MakeErrorLast();
  197. goto exit;
  198. }
  199. }
  200. else
  201. MessageBox(NULL, L"Alpha Channel of bitmap is all zero's", L"Warning", MB_OK);
  202. }
  203. exit:
  204. if (hdc)
  205. ReleaseDC(NULL, hdc);
  206. if (pBits)
  207. delete [] pBits;
  208. if (FAILED(hr))
  209. MessageBox(NULL, L"Error loading bitmap", L"Error", MB_OK);
  210. return hr;
  211. }
  212. //----------------------------------------------------------------------------
  213. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  214. {
  215. int wmId, wmEvent;
  216. PAINTSTRUCT ps;
  217. HDC hdc;
  218. switch (message)
  219. {
  220. case WM_DROPFILES:
  221. {
  222. HDROP hDrop = (HDROP)wParam;
  223. WCHAR szFileName[_MAX_PATH+1];
  224. int iGot = DragQueryFile(hDrop, 0, szFileName, ARRAYSIZE(szFileName));
  225. DragFinish(hDrop);
  226. if (iGot) // got a valid filename
  227. {
  228. HRESULT hr = InitDib(hInst, szFileName);
  229. if (SUCCEEDED(hr))
  230. InvalidateRect(hWnd, NULL, TRUE);
  231. }
  232. }
  233. break;
  234. case WM_COMMAND:
  235. wmId = LOWORD(wParam);
  236. wmEvent = HIWORD(wParam);
  237. // Parse the menu selections:
  238. switch (wmId)
  239. {
  240. case ID_FILE_OPEN:
  241. OnFileOpen(hInst, hWnd);
  242. break;
  243. case IDM_ABOUT:
  244. DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
  245. break;
  246. case IDM_EXIT:
  247. DestroyWindow(hWnd);
  248. break;
  249. case ID_BACKGROUND_GRAYPINK:
  250. SetBackground(hWnd, hInst, IDB_PINKGRAY, wmId);
  251. break;
  252. case ID_BACKGROUND_BLUEGRAY:
  253. SetBackground(hWnd, hInst, IDB_BLUEGRAY, wmId);
  254. break;
  255. case ID_BACKGROUND_WHITE:
  256. SetBackground(hWnd, hInst, IDB_WHITE, wmId);
  257. break;
  258. case ID_BACKGROUND_GRAY:
  259. SetBackground(hWnd, hInst, IDB_GRAY, wmId);
  260. break;
  261. case ID_ZOOM_50:
  262. SetZoom(hWnd, hInst, 50, wmId);
  263. break;
  264. case ID_ZOOM_100:
  265. SetZoom(hWnd, hInst, 100, wmId);
  266. break;
  267. case ID_ZOOM_200:
  268. SetZoom(hWnd, hInst, 200, wmId);
  269. break;
  270. case ID_ZOOM_400:
  271. SetZoom(hWnd, hInst, 400, wmId);
  272. break;
  273. default:
  274. return DefWindowProc(hWnd, message, wParam, lParam);
  275. }
  276. break;
  277. case WM_ERASEBKGND:
  278. HBRUSH hbr;
  279. hbr = CreatePatternBrush(hbrBackground);
  280. hdc = (HDC)wParam;
  281. if ((hbr) && (hdc))
  282. {
  283. RECT rect;
  284. GetClientRect(hWnd, &rect);
  285. FillRect(hdc, &rect, hbr);
  286. DeleteObject(hbr);
  287. }
  288. return 1;
  289. case WM_PAINT:
  290. hdc = BeginPaint(hWnd, &ps);
  291. XFORM xForm;
  292. xForm.eM11 = (FLOAT)(iZoomFactor/100.);
  293. xForm.eM12 = (FLOAT) 0.0;
  294. xForm.eM21 = (FLOAT) 0.0;
  295. xForm.eM22 = (FLOAT)(iZoomFactor/100.);
  296. xForm.eDx = (FLOAT) 0.0;
  297. xForm.eDy = (FLOAT) 0.0;
  298. SetGraphicsMode(hdc, GM_ADVANCED);
  299. SetWorldTransform(hdc, &xForm);
  300. //---- get scaled rect ----
  301. RECT rc;
  302. GetClientRect(hWnd, &rc);
  303. rc.right = (rc.right*100)/iZoomFactor;
  304. rc.bottom = (rc.bottom*100)/iZoomFactor;
  305. //---- paint the center bitmap ----
  306. HDC dc2;
  307. dc2 = CreateCompatibleDC(hdc);
  308. if ((dc2) && (hCenterDIB))
  309. {
  310. HBITMAP hOldBitmap2;
  311. hOldBitmap2 = (HBITMAP) SelectObject(dc2, hCenterDIB);
  312. int x = ((rc.right - rc.left) - iDibWidth)/2;
  313. int y = ((rc.bottom - rc.top) - iDibHeight)/2;
  314. BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
  315. if (fAlpha)
  316. {
  317. AlphaBlend(hdc, x, y, iDibWidth, iDibHeight,
  318. dc2, 0, 0, iDibWidth, iDibHeight, bf);
  319. }
  320. else
  321. {
  322. BitBlt(hdc, x, y, iDibWidth, iDibHeight,
  323. dc2, 0, 0, SRCCOPY);
  324. }
  325. SelectObject(dc2, hOldBitmap2);
  326. DeleteDC(dc2);
  327. }
  328. EndPaint(hWnd, &ps);
  329. break;
  330. case WM_DESTROY:
  331. PostQuitMessage(0);
  332. break;
  333. default:
  334. return DefWindowProc(hWnd, message, wParam, lParam);
  335. }
  336. return 0;
  337. }
  338. //----------------------------------------------------------------------------
  339. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  340. {
  341. switch (message)
  342. {
  343. case WM_INITDIALOG:
  344. return TRUE;
  345. case WM_COMMAND:
  346. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  347. {
  348. EndDialog(hDlg, LOWORD(wParam));
  349. return TRUE;
  350. }
  351. break;
  352. }
  353. return FALSE;
  354. }
  355. //----------------------------------------------------------------------------
  356. void OnFileOpen(HINSTANCE hInst, HWND hWnd)
  357. {
  358. const WCHAR *filter =
  359. L"Bitmap Files (*.bmp)\0*.bmp\0"
  360. L"PNG Files (*.png)\0*.png\0"
  361. L"All Files (*.*)\0*.*\0\0";
  362. OPENFILENAME ofn = {sizeof(ofn)};
  363. WCHAR szFile[_MAX_PATH+1] = {0};
  364. //---- init ofn ----
  365. ofn.hwndOwner = hWnd;
  366. ofn.hInstance = hInst;
  367. ofn.lpstrFile = szFile;
  368. ofn.nMaxFile = ARRAYSIZE(szFile);
  369. ofn.lpstrFilter = filter;
  370. ofn.nFilterIndex = 1;
  371. ofn.lpstrFileTitle = L"Select an Image File to preview";
  372. ofn.nMaxFileTitle = 0;
  373. ofn.lpstrInitialDir = NULL;
  374. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  375. // Display the Open dialog box.
  376. if (GetOpenFileName(&ofn))
  377. {
  378. HRESULT hr = InitDib(hInst, szFile);
  379. if (SUCCEEDED(hr))
  380. InvalidateRect(hWnd, NULL, TRUE);
  381. }
  382. }
  383. //----------------------------------------------------------------------------
  384. void SetZoom(HWND hWnd, HINSTANCE hInstance, int iZoomPercent, int iMenuId)
  385. {
  386. iZoomFactor = iZoomPercent;
  387. InvalidateRect(hWnd, NULL, TRUE);
  388. //---- update menu items ----
  389. HMENU hMenu = GetMenu(hWnd);
  390. hMenu = GetSubMenu(hMenu, 2);
  391. if (iCurrentZoomMenu)
  392. CheckMenuItem(hMenu, iCurrentZoomMenu, MF_BYCOMMAND | MF_UNCHECKED);
  393. CheckMenuItem(hMenu, iMenuId, MF_BYCOMMAND | MF_CHECKED);
  394. iCurrentZoomMenu = iMenuId;
  395. }
  396. //----------------------------------------------------------------------------