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.

441 lines
12 KiB

  1. /*
  2. * f o n t n s c . c p p
  3. *
  4. * Implementation of a richedit format bar
  5. *
  6. * Owner: AnthonyF
  7. * taken from Capone: brettm
  8. */
  9. #include "pch.hxx"
  10. #include "resource.h"
  11. #include "fonts.h"
  12. #include <assert.h>
  13. #ifndef WIN16
  14. #include <wchar.h>
  15. #endif
  16. #include <shlwapi.h>
  17. #include "strconst.h"
  18. #include "demand.h"
  19. #include "menures.h"
  20. #ifdef WIN16
  21. #ifdef PRINTER_FONTTYPE
  22. #undef PRINTER_FONTTYPE
  23. #endif
  24. #define PRINTER_FONTTYPE 0
  25. #endif
  26. /*
  27. * m a c r o s
  28. */
  29. #define GETINDEX(m) (DWORD) (((((m) & 0xff000000) >> 24) & 0x000000ff))
  30. #define MAKEINDEX(b, l) (((DWORD)(l) & 0x00ffffff) | ((DWORD)(b) << 24))
  31. /*
  32. * c o n s t a n t s
  33. */
  34. #define NFONTSIZES 7
  35. #define TEMPBUFSIZE 30
  36. /*
  37. * t y p e d e f s
  38. */
  39. INT CALLBACK NEnumFontNameProcEx(ENUMLOGFONTEX *plf, NEWTEXTMETRICEX *ptm, INT nFontType, LPARAM lParam);
  40. /*
  41. * g l o b a l d a t a
  42. */
  43. /*
  44. * Color table for dropdown on toolbar. Matches COMMDLG colors
  45. * exactly.
  46. */
  47. static DWORD rgrgbColors[] = {
  48. RGB_AUTOCOLOR, // "AUTO"},
  49. RGB( 0, 0, 0), // "BLACK"},
  50. RGB(128, 0, 0), // "DARK RED"},
  51. RGB( 0, 128, 0), // "DARK YELLOW"},
  52. RGB(128, 128, 0), // "DARK BLUE"},
  53. RGB( 0, 0, 128), // "DARK BLUE"},
  54. RGB(128, 0, 128), // "DARK PURPLE"},
  55. RGB( 0, 128, 128), // "DARK AQUA"},
  56. RGB(128, 128, 128), // "DARK GREY"},
  57. RGB(192, 192, 192), // "LIGHT GREY"},
  58. RGB(255, 0, 0), // "LIGHT RED"},
  59. RGB( 0, 255, 0), // "LIGHT GREEN"},
  60. RGB(255, 255, 0), // "LIGHT YELLOW"},
  61. RGB( 0, 0, 255), // "LIGHT BLUE"},
  62. RGB(255, 0, 255), // "LIGHT PURPLE"},
  63. RGB( 0, 255, 255), // "LIGHT AQUA"},
  64. RGB(255, 255, 255) // "WHITE"}
  65. };
  66. /*
  67. * p r o t o t y p e s
  68. */
  69. HRESULT HrCreateColorMenu(ULONG idmStart, HMENU* pMenu, BOOL fUseAuto)
  70. {
  71. DWORD irgb;
  72. DWORD mniColor;
  73. if(pMenu == NULL)
  74. return E_INVALIDARG;
  75. *pMenu = CreatePopupMenu();
  76. if (*pMenu == NULL)
  77. return E_OUTOFMEMORY;
  78. // Add the COLORREF version of each entry into the menu
  79. for (irgb = fUseAuto ? 0 : 1, mniColor=idmStart;
  80. irgb < sizeof(rgrgbColors)/sizeof(DWORD);
  81. ++irgb, ++mniColor)
  82. {
  83. AppendMenu(*pMenu, MF_ENABLED|MF_OWNERDRAW, mniColor, (LPCSTR)IntToPtr(MAKEINDEX(irgb, rgrgbColors[irgb])));
  84. }
  85. return NOERROR;
  86. }
  87. HRESULT HrCreateComboColor(HWND hCombo)
  88. {
  89. DWORD irgb;
  90. DWORD mniColor;
  91. LRESULT lr;
  92. if(hCombo == NULL)
  93. return E_INVALIDARG;
  94. ComboBox_SetExtendedUI(hCombo, TRUE);
  95. for (irgb = 0; irgb < sizeof(rgrgbColors)/sizeof(DWORD); ++irgb)
  96. {
  97. lr = ComboBox_AddString(hCombo, (LPCSTR)" ");
  98. if (lr == CB_ERR || lr == CB_ERRSPACE)
  99. break;
  100. ComboBox_SetItemData(hCombo, LOWORD(lr), (LPCSTR)IntToPtr(MAKEINDEX(irgb, rgrgbColors[irgb])));
  101. }
  102. return NOERROR;
  103. }
  104. void Color_WMDrawItem(LPDRAWITEMSTRUCT pdis, INT iColor, BOOL fBackground)
  105. {
  106. HBRUSH hbr;
  107. WORD dx, dy, dxBorder;
  108. RECT rc;
  109. TCHAR szColor[MAX_PATH]={0};
  110. DWORD rgbBack, rgbText;
  111. UINT id = pdis->itemID;
  112. ULONG index = 0;
  113. switch(iColor)
  114. {
  115. case iColorMenu:
  116. if(pdis->itemState&ODS_SELECTED)
  117. {
  118. rgbBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
  119. rgbText = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  120. }
  121. else
  122. {
  123. rgbBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_MENU));
  124. rgbText = SetTextColor(pdis->hDC, GetSysColor(COLOR_MENUTEXT));
  125. }
  126. break;
  127. case iColorCombo:
  128. if(pdis->itemState&ODS_SELECTED)
  129. {
  130. rgbBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
  131. rgbText = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  132. }
  133. else
  134. {
  135. rgbBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW));
  136. rgbText = SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
  137. }
  138. break;
  139. default:
  140. Assert(FALSE);
  141. }
  142. /* compute coordinates of color rectangle and draw it */
  143. dxBorder = (WORD) GetSystemMetrics(SM_CXBORDER);
  144. if(iColor == iColorMenu)
  145. dx = (WORD) GetSystemMetrics(SM_CXMENUCHECK);
  146. else
  147. dx = (WORD) GetSystemMetrics(SM_CXBORDER);
  148. dy = (WORD) GetSystemMetrics(SM_CYBORDER);
  149. rc.top = pdis->rcItem.top + dy;
  150. rc.bottom = pdis->rcItem.bottom - dy;
  151. rc.left = pdis->rcItem.left + dx;
  152. rc.right = rc.left + 2 * (rc.bottom - rc.top);
  153. index = GETINDEX(pdis->itemData);
  154. LoadString(g_hLocRes, index + idsAutoColor,
  155. szColor, sizeof(szColor)/sizeof(TCHAR));
  156. SelectObject(pdis->hDC, HGetSystemFont(FNT_SYS_MENU));
  157. ExtTextOut(pdis->hDC, rc.right + 2*dxBorder,
  158. pdis->rcItem.top, ETO_OPAQUE, &pdis->rcItem,
  159. szColor, lstrlen(szColor), NULL);
  160. switch(iColor)
  161. {
  162. case iColorMenu:
  163. if(pdis->itemID == ID_FORMAT_COLORAUTO) // auto color item
  164. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT));
  165. else if (pdis->itemID == ID_BACK_COLOR_AUTO)
  166. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  167. else
  168. hbr = CreateSolidBrush((DWORD) (pdis->itemData & 0x00ffffff));
  169. break;
  170. case iColorCombo:
  171. if (pdis->itemID == 0) // auto color item
  172. {
  173. if (fBackground)
  174. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  175. else
  176. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT));
  177. }
  178. else
  179. hbr = CreateSolidBrush((DWORD)(pdis->itemData & 0x00ffffff));
  180. break;
  181. default:
  182. Assert(FALSE);
  183. }
  184. if (hbr)
  185. {
  186. hbr = (HBRUSH)SelectObject (pdis->hDC, hbr);
  187. Rectangle(pdis->hDC, rc.left, rc.top, rc.right, rc.bottom);
  188. DeleteObject(SelectObject(pdis->hDC, hbr));
  189. }
  190. // draw radio check.
  191. if(iColor == iColorMenu && pdis->itemState&ODS_CHECKED)
  192. {
  193. WORD left, top, radius;
  194. if(pdis->itemState&ODS_SELECTED)
  195. hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHTTEXT));
  196. else
  197. hbr = CreateSolidBrush(GetSysColor(COLOR_MENUTEXT));
  198. if (hbr)
  199. {
  200. hbr = (HBRUSH)SelectObject (pdis->hDC, hbr);
  201. left = (WORD) (pdis->rcItem.left + GetSystemMetrics(SM_CXMENUCHECK) / 2);
  202. top = (WORD) (rc.top + (rc.bottom - rc.top) / 2);
  203. radius = (WORD) (GetSystemMetrics(SM_CXMENUCHECK) / 4);
  204. Ellipse(pdis->hDC, left-radius, top-radius, left+radius, top+radius);
  205. DeleteObject(SelectObject(pdis->hDC, hbr));
  206. }
  207. }
  208. SetTextColor(pdis->hDC, rgbText);
  209. SetBkColor(pdis->hDC, rgbBack);
  210. }
  211. void Color_WMMeasureItem(HDC hdc, LPMEASUREITEMSTRUCT pmis, INT iColor)
  212. {
  213. HFONT hfontOld = NULL;
  214. TEXTMETRIC tm;
  215. UINT id = pmis->itemID;
  216. TCHAR szColor[MAX_PATH]={0};
  217. switch(iColor)
  218. {
  219. case iColorMenu:
  220. hfontOld = (HFONT)SelectObject(hdc, HGetSystemFont(FNT_SYS_MENU));
  221. break;
  222. case iColorCombo:
  223. hfontOld = (HFONT)SelectObject(hdc, HGetSystemFont(FNT_SYS_ICON));
  224. break;
  225. default:
  226. Assert(FALSE);
  227. }
  228. GetTextMetrics(hdc, &tm);
  229. SelectObject(hdc, hfontOld);
  230. ULONG index = GETINDEX(pmis->itemData);
  231. LoadString(g_hLocRes, index + idsAutoColor,
  232. szColor, sizeof(szColor)/sizeof(TCHAR));
  233. pmis->itemHeight = tm.tmHeight + 2 * GetSystemMetrics(SM_CYBORDER);
  234. pmis->itemWidth = GetSystemMetrics(SM_CXMENUCHECK) +
  235. 2 * GetSystemMetrics(SM_CXBORDER) +
  236. 2 * tm.tmHeight +
  237. (lstrlen(szColor) + 2) *tm.tmAveCharWidth;
  238. }
  239. // displays the colorpopup menu at the specified point. if clrf if NULL, then no clrf is returned
  240. // but instead the appropriate WM_COMMAND is dispatched to the parent window
  241. HRESULT HrColorMenu_Show(HMENU hmenuColor, HWND hwndParent, POINT pt, COLORREF *pclrf)
  242. {
  243. HRESULT hr=NOERROR;
  244. int tpm=TPM_LEFTALIGN|TPM_LEFTBUTTON;
  245. if(hmenuColor == NULL)
  246. return E_INVALIDARG;
  247. if(pclrf)
  248. tpm|=TPM_RETURNCMD;
  249. int id = TrackPopupMenu(hmenuColor, tpm,pt.x, pt.y, 0, hwndParent, NULL);
  250. switch(id)
  251. {
  252. case 1:
  253. return NOERROR;
  254. case 0:
  255. return E_FAIL;
  256. case -1:
  257. return E_FAIL;
  258. case ID_FORMAT_COLORAUTO:
  259. case ID_FORMAT_COLOR1:
  260. case ID_FORMAT_COLOR2:
  261. case ID_FORMAT_COLOR3:
  262. case ID_FORMAT_COLOR4:
  263. case ID_FORMAT_COLOR5:
  264. case ID_FORMAT_COLOR6:
  265. case ID_FORMAT_COLOR7:
  266. case ID_FORMAT_COLOR8:
  267. case ID_FORMAT_COLOR9:
  268. case ID_FORMAT_COLOR10:
  269. case ID_FORMAT_COLOR11:
  270. case ID_FORMAT_COLOR12:
  271. case ID_FORMAT_COLOR13:
  272. case ID_FORMAT_COLOR14:
  273. case ID_FORMAT_COLOR15:
  274. case ID_FORMAT_COLOR16:
  275. AssertSz(pclrf, "this HAS to be set to get this id back...");
  276. *pclrf=rgrgbColors[id-ID_FORMAT_COLORAUTO];
  277. return NOERROR;
  278. default:
  279. AssertSz(0, "unexpected return from TrackPopupMenu");
  280. }
  281. return E_FAIL;
  282. }
  283. DWORD GetColorRGB(INT index)
  284. {
  285. return rgrgbColors[index];
  286. }
  287. INT GetColorIndex(INT rbg)
  288. {
  289. INT iFound = -1;
  290. for(int irgb = 1; irgb < sizeof(rgrgbColors)/sizeof(DWORD); ++irgb)
  291. {
  292. if((rbg&0x00ffffff) == (LONG)rgrgbColors[irgb])
  293. {
  294. iFound = irgb;
  295. break;
  296. }
  297. }
  298. return iFound;
  299. }
  300. // fill font name combo box
  301. void FillFontNames(HWND hwndCombo)
  302. {
  303. LOGFONT lf = {0};
  304. HDC hdc;
  305. // reset the contents of the combo
  306. SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
  307. hdc = GetDC(NULL);
  308. if (hdc)
  309. {
  310. //to enumerate all styles of all fonts for the default character set
  311. lf.lfFaceName[0] = '\0';
  312. lf.lfCharSet = DEFAULT_CHARSET;
  313. EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)NEnumFontNameProcEx, (LPARAM)hwndCombo, 0);
  314. ReleaseDC(NULL, hdc);
  315. }
  316. }
  317. INT CALLBACK NEnumFontNameProcEx(ENUMLOGFONTEX *plf, NEWTEXTMETRICEX *ptm, INT nFontType, LPARAM lParam)
  318. {
  319. LONG l;
  320. HWND hwndCombo = (HWND)lParam;
  321. Assert(hwndCombo);
  322. // skip vertical fonts for OE
  323. if (plf->elfLogFont.lfFaceName[0]=='@')
  324. return TRUE;
  325. // if the font is already listed, don't re-list it
  326. if(ComboBox_FindStringExact(hwndCombo, -1, plf->elfLogFont.lfFaceName) != -1)
  327. return TRUE;
  328. l = ComboBox_AddString(hwndCombo, plf->elfLogFont.lfFaceName);
  329. if (l!=-1)
  330. ComboBox_SetItemData(hwndCombo, l, nFontType);
  331. return TRUE;
  332. }
  333. void FillSizes(HWND hwndSize)
  334. {
  335. LONG id;
  336. TCHAR szBuf[TEMPBUFSIZE];
  337. *szBuf = 0;
  338. LRESULT lr;
  339. // Empty the current list
  340. SendMessage(hwndSize, CB_RESETCONTENT, 0, 0);
  341. for (id = idsFontSize0; id < NFONTSIZES + idsFontSize0; ++id)
  342. {
  343. LoadString(g_hLocRes, id, szBuf, sizeof(szBuf));
  344. lr = SendMessage(hwndSize, CB_ADDSTRING, 0, (LPARAM) szBuf);
  345. if (lr == CB_ERR || lr == CB_ERRSPACE)
  346. break;
  347. }
  348. }
  349. // size of pszColor must be bigger than 7
  350. HRESULT HrFromIDToRBG(INT id, LPWSTR pwszColor, BOOL fBkColor)
  351. {
  352. DWORD cr;
  353. if(id<0 || id>16 || !pwszColor)
  354. return E_INVALIDARG;
  355. if (id == 0)
  356. {
  357. if (fBkColor)
  358. cr = GetSysColor(COLOR_WINDOW);
  359. else
  360. cr = GetSysColor(COLOR_WINDOWTEXT);
  361. }
  362. else
  363. cr = rgrgbColors[id];
  364. return HrGetStringRBG(cr, pwszColor);
  365. }