SMHTB.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:24k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  *  S M H T B . C
  3.  *
  4.  *  Sample mail handling hook configuration toolbar
  5.  *  Copyright 1992-95 Microsoft Corporation.  All Rights Reserved.
  6.  */
  7. #include "_pch.h"
  8. #include <richedit.h>
  9. #ifndef WIN16
  10. #include <commctrl.h>
  11. #endif
  12. /*  Maximum number of font digits */
  13. #define cchSizeMax  16
  14. /*  Enumeration of button bitmaps if toolbar bitmap */
  15. enum {
  16.     itbBold,
  17.     itbItalic,
  18.     itbUnderline,
  19.     itbColor,
  20.     ctbMax
  21. };
  22. /*  Gap sizes for format bar */
  23. #define cxDownButton    16
  24. #define cxName          (125 + cxDownButton)
  25. #define cxSize          (40 + cxDownButton)
  26. #define cxPlaceHolder   (cxName + 8 + cxSize + 8)
  27. #define cxIndent        (1440 / 4)
  28. /*  Button descriptions for format bar */
  29. static const TBBUTTON rgtbbChar[] =
  30. {
  31.     { cxPlaceHolder, 0L, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, -1},
  32.     { itbColor, ID_Color, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, -1 },
  33.     { itbBold, ID_Bold, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1},
  34.     { itbItalic, ID_Italic, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1},
  35.     { itbUnderline, ID_Underline, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1},
  36. };
  37. #define ctbbChar   (sizeof(rgtbbChar) / sizeof(TBBUTTON))
  38. /*  Color descriptions for dropdown color list */
  39. DWORD rgrgb[] = {
  40.     RGB(  0,   0,   0), /* Auto         */
  41.     RGB(  0,   0,   0), /* Black        */
  42.     RGB(128,   0,   0), /* Dark red     */
  43.     RGB(  0, 128,   0), /* Dark green   */
  44.     RGB(128, 128,   0), /* Dark yellow  */
  45.     RGB(  0,   0, 128), /* Dark blue    */
  46.     RGB(128,   0, 128), /* Dark purple  */
  47.     RGB(  0, 128, 128), /* Dark aqua    */
  48.     RGB(128, 128, 128), /* Dark grey    */
  49.     RGB(192, 192, 192), /* Light grey   */
  50.     RGB(255,   0,   0), /* Light red    */
  51.     RGB(  0, 255,   0), /* Light green  */
  52.     RGB(255, 255,   0), /* Light yellow */
  53.     RGB(  0,   0, 255), /* Light blue   */
  54.     RGB(255,   0, 255), /* Light purple */
  55.     RGB(  0, 255, 255), /* Light aqua   */
  56.     RGB(255, 255, 255), /* White        */
  57. };
  58. #define crgb    (sizeof(rgrgb) / sizeof(rgrgb[0]))
  59. const LPTSTR rgszColor[] = {
  60.     "Auto", "Black", "Maroon",
  61.     "Green", "Olive", "Navy",
  62.     "Purple", "Teal", "Gray",
  63.     "Silver", "Red", "Lime",
  64.     "Yellow", "Blue", "Fuchia",
  65.     "Aqua", "White"
  66. };
  67. /*  Font and paragraph effects */
  68.     
  69. static const DWORD rgdwEffect[] = { CFE_BOLD, CFE_ITALIC, CFE_UNDERLINE };
  70. static const WORD rgwAlign[] = { PFA_LEFT, PFA_CENTER, PFA_RIGHT };
  71. static const UINT rglFontSize[] =
  72. {
  73.      8,  9, 10, 11,
  74.     12, 14, 16, 18,
  75.     20, 22, 24, 26,
  76.     28, 36, 48, 72
  77. };
  78. #define FontSize(_y)    MulDiv((int)(_y), 72, 1440)
  79. /*  Toolbar and combobox class names */
  80. static const TCHAR rgchTBClass[] = "SMHToolbar";
  81. static const TCHAR rgchComboBox[] = "ComboBox";
  82. #ifdef  WIN16
  83. #define GWL_USERDATA 0
  84. #endif
  85. /*
  86.  *  Font, font size, and color dropdown and listing functions -----------------
  87.  *
  88.  *  These functions are used to fill in and display the character formats
  89.  *  for the format bar.  The font listbox gets filled once and only once
  90.  *  on format bar creation.  The font size listbox will get filled up each
  91.  *  and everytime the font list gets dropped down.  The font color menu
  92.  *  will get filled once at startup.
  93.  */
  94. INT CALLBACK EXPORT
  95. EnumFontNames (LPVOID lpvLogFont,
  96.     NEWTEXTMETRIC FAR * lpntm,
  97.     INT nFontType,
  98.     LPARAM lParam)
  99. {
  100.     UINT i;
  101.     DWORD dw = 0;
  102.     LOGFONT FAR * lplf = FWin4Shell()
  103.                             ? &((ENUMLOGFONTEX FAR *)lpvLogFont)->elfLogFont
  104.                             : (LOGFONT FAR *)lpvLogFont;
  105.     /*  Add the face name into the listbox */
  106.     DebugTrace ("SMH: adding font: %s%sn", lplf->lfFaceName,
  107.         (lpntm->tmPitchAndFamily & TMPF_TRUETYPE)
  108.             ? " (TrueType)"
  109.             : "");
  110.     i = ComboBox_AddString ((HWND)lParam, lplf->lfFaceName);
  111.     if ((i != CB_ERR) || (i != CB_ERRSPACE))
  112.     {
  113.         Assert (!(lplf->lfCharSet & 0xFFFFFF00));
  114.         Assert (!(lplf->lfPitchAndFamily & 0xFFFFFF00));
  115.         Assert (!(nFontType & 0xFFFF0000));
  116.         dw = lplf->lfCharSet & 0xFF;
  117.         dw <<= 8;
  118.         dw |= lplf->lfPitchAndFamily & 0xFF;
  119.         dw <<= 16;
  120.         dw |= nFontType & 0xFFFF;
  121.         ComboBox_SetItemData ((HWND)lParam, i, dw);
  122.     }
  123.     return TRUE;
  124. }
  125. void
  126. FillFontNames (HWND hwnd)
  127. {
  128.     HDC hdc;
  129.     /*  Empty the contents of the listbox and enumerate the fonts */
  130.     
  131.     ComboBox_ResetContent (hwnd);
  132.     if (hdc = GetDC(NULL))
  133.     {
  134.         EnumFontFamilies (hdc,
  135.             (LPTSTR)NULL,
  136.             (FONTENUMPROC)EnumFontNames,
  137.             (LPARAM)(LPVOID)hwnd);
  138.         ReleaseDC (NULL, hdc);
  139.     }
  140. }
  141. INT CALLBACK EXPORT
  142. EnumFontSizes (LPVOID lpvLogFont,
  143.     NEWTEXTMETRIC FAR * lpntm,
  144.     INT nFontType,
  145.     LPARAM lParam)
  146. {
  147.     TCHAR rgch[cchSizeMax];
  148.     UINT i;
  149.     if (lpntm->tmPitchAndFamily & TMPF_TRUETYPE)
  150.     {
  151.         /*  If the font is TrueType, then just fillin random sizes */
  152.         
  153.         for (i = 0; i < (sizeof(rglFontSize) / sizeof(UINT)); i++)
  154.         {
  155.             wsprintf (rgch, "%d", rglFontSize[i]);
  156.             DebugTrace ("SMH: adding font size: %sn", rgch);
  157.             ComboBox_AddString (((LPFORMATBAR)lParam)->hwndSize, rgch);
  158.         }
  159.         return FALSE;
  160.     }
  161.     else
  162.     {
  163.         /*  Calculate the size of the current instance */
  164.         wsprintf (rgch, "%d", MulDiv ((INT)lpntm->tmHeight - lpntm->tmInternalLeading, 72,
  165.             GetDeviceCaps (((LPFORMATBAR)lParam)->hdc, LOGPIXELSY)));
  166.         if (ComboBox_FindStringExact (((LPFORMATBAR)lParam)->hwndSize, -1, rgch) == CB_ERR)
  167.         {
  168.             DebugTrace ("SMH: font height: %dn", lpntm->tmHeight - lpntm->tmInternalLeading);
  169.             DebugTrace ("SMH: adding font size: %sn", rgch);
  170.             ComboBox_AddString (((LPFORMATBAR)lParam)->hwndSize, rgch);
  171.             ((LPFORMATBAR)lParam)->cSize++;
  172.         }
  173.         return TRUE;
  174.     }
  175. }
  176. void
  177. FillSizes (LPFORMATBAR lpfb)
  178. {
  179.     TCHAR rgch[30];
  180.     /*  Empty the contents of the listbox and enumerate the fonts */
  181.     
  182.     ComboBox_ResetContent (lpfb->hwndSize);
  183.     ComboBox_GetText (lpfb->hwndFont, rgch, sizeof(rgch) - 1);
  184.     if (lpfb->hdc = GetDC (lpfb->hwndSize))
  185.     {
  186.         lpfb->cSize = 0;
  187.         EnumFontFamilies (lpfb->hdc, rgch, (FONTENUMPROC)EnumFontSizes, (LPARAM)lpfb);
  188.         ReleaseDC (lpfb->hwndSize, lpfb->hdc);
  189.     }
  190. }
  191. void CALLBACK
  192. ColorMenu_MeasureItem (HWND hwnd, MEASUREITEMSTRUCT FAR * lpmis)
  193. {
  194.     LPFORMATBAR lpfb = (LPFORMATBAR)GetWindowLong (hwnd, GWL_USERDATA);
  195.     HFONT hfnt;
  196.     TEXTMETRIC tm;
  197.     hfnt = SelectObject (lpfb->hdc, lpfb->hfnt);
  198.     GetTextMetrics (lpfb->hdc, &tm);
  199.     SelectObject (lpfb->hdc, hfnt);
  200.     lpmis->itemHeight = tm.tmHeight;
  201.     lpmis->itemWidth = 14 * tm.tmAveCharWidth;
  202.     return;
  203. }
  204. void CALLBACK EXPORT
  205. ColorMenu_DrawItem (HWND hwnd, DRAWITEMSTRUCT FAR * lpdis)
  206. {
  207.     LPFORMATBAR lpfb = (LPFORMATBAR)(GetWindowLong (hwnd, GWL_USERDATA));
  208.     HBRUSH hbr;
  209.     WORD dx;
  210.     WORD dy;
  211.     RECT rc;
  212.     DWORD rgbBack;
  213.     DWORD rgbText;
  214.     if (lpdis->itemState & ODS_SELECTED)
  215.     {
  216.         rgbBack = SetBkColor (lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
  217.         rgbText = SetTextColor (lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
  218.     }
  219.     else
  220.     {
  221.         rgbBack = SetBkColor (lpdis->hDC, GetSysColor(COLOR_WINDOW));
  222.         rgbText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
  223.     }
  224.     ExtTextOut (lpdis->hDC,
  225.             lpdis->rcItem.left,
  226.             lpdis->rcItem.top,
  227.             ETO_OPAQUE,
  228.             &lpdis->rcItem,
  229.             NULL, 0, NULL);
  230.     dx = GetSystemMetrics(SM_CXBORDER);
  231.     dy = GetSystemMetrics(SM_CYBORDER);
  232.     rc.top = lpdis->rcItem.top + dy;
  233.     rc.bottom = lpdis->rcItem.bottom - dy;
  234.     rc.left = lpdis->rcItem.left + dx;
  235.     rc.right = rc.left + 2 * (rc.bottom - rc.top);
  236.     if (hbr = CreateSolidBrush (lpdis->itemData))
  237.     {
  238.         hbr = SelectObject (lpdis->hDC, hbr);
  239.         Rectangle (lpdis->hDC, rc.left, rc.top, rc.right, rc.bottom);
  240.         DeleteObject (SelectObject (lpdis->hDC, hbr));
  241.     }
  242.     DebugTrace ("SMH: color menu: painting item: %sn",
  243.         (LPCSTR)rgszColor[lpdis->itemID - ID_Color - 1]);
  244.     SelectObject (lpdis->hDC, lpfb->hfnt);
  245.     TextOut (lpdis->hDC,
  246.         2 * dx + rc.right,
  247.         lpdis->rcItem.top,
  248.         rgszColor[lpdis->itemID - ID_Color - 1],
  249.         lstrlen ((LPCSTR)rgszColor[lpdis->itemID - ID_Color - 1]));
  250.     SetTextColor (lpdis->hDC, rgbText);
  251.     SetBkColor (lpdis->hDC, rgbBack);
  252.     return;
  253. }
  254. void
  255. FillColors (LPFORMATBAR lpfb)
  256. {
  257.     UINT irgb;
  258.     /*  Setup the auto color */
  259.     rgrgb[0] = GetSysColor (COLOR_WINDOWTEXT);
  260.     for (irgb = 0; irgb < crgb; irgb++)
  261.     {
  262.         DebugTrace ("SMH: color menu: adding item: %s (0x%08lX)n",
  263.             (LPCSTR)rgszColor[irgb], rgrgb[irgb]);
  264.         AppendMenu (lpfb->hmnuColor,
  265.             MF_ENABLED | MF_OWNERDRAW,
  266.             ID_Color + irgb + 1,
  267.             (LPCSTR)rgrgb[irgb]);
  268.     }
  269. }
  270. /*
  271.  *  FormatBar window proc -----------------------------------------------------
  272.  *
  273.  *  The formatbar window proc intercepts several window messages and
  274.  *  processes them as needed.  The primary messages we operate on are the
  275.  *  messages that will cause items to be redrawn or shown.
  276.  *
  277.  *  Additionally, WM_DESTROY is processed as for cleanup of all the
  278.  *  formatbar components
  279.  */
  280. LRESULT CALLBACK EXPORT
  281. FormatBarWndProc (HWND hwnd,
  282.     UINT msg,
  283.     WPARAM wParam,
  284.     LPARAM lParam)
  285. {
  286.     LPFORMATBAR lpfb = (LPFORMATBAR)GetWindowLong (hwnd, GWL_USERDATA);
  287.     switch (msg)
  288.     {
  289.       case WM_COMMAND:
  290.         
  291.         if ((GET_WM_COMMAND_CMD (wParam, lParam) == CBN_DROPDOWN) &&
  292.             (GET_WM_COMMAND_ID (wParam, lParam) == ID_FontSize))
  293.             FillSizes (lpfb);
  294.         SendMessage (GetParent(hwnd), WM_COMMAND, wParam, lParam);
  295.         return TRUE;
  296.       case WM_SHOWWINDOW:
  297.         
  298.         SendMessage (lpfb->hwndTb, msg, wParam, lParam);
  299.         break;
  300.       case WM_DRAWITEM:
  301.         
  302.         ColorMenu_DrawItem (hwnd, (DRAWITEMSTRUCT FAR *)lParam);
  303.         return TRUE;
  304.       case WM_MEASUREITEM:
  305.         
  306.         ColorMenu_MeasureItem (hwnd, (MEASUREITEMSTRUCT FAR *)lParam);
  307.         return TRUE;
  308.       case WM_DESTROY:
  309.         
  310.         DebugTrace ("SMH: destroying format barn");
  311.         DestroyWindow (lpfb->hwndTb);
  312.         DestroyWindow (lpfb->hwndFont);
  313.         DestroyWindow (lpfb->hwndSize);
  314.         DeleteObject (lpfb->hbrBtnFace);
  315.         DestroyMenu (lpfb->hmnuColor);
  316.         UlRelease (lpfb->lpreoc);
  317.         (*lpfb->lpscd->lpfnFree) (lpfb);
  318.         break;
  319.     }
  320.     return DefWindowProc (hwnd, msg, wParam, lParam);
  321. }
  322. /*
  323.  *  Toolbar subclass proc -----------------------------------------------------
  324.  *
  325.  *  The subclassing of the toolbar is done so that the listboxes added to
  326.  *  the toolbar will be drawn with the correct control color.
  327.  */
  328. LRESULT CALLBACK EXPORT
  329. ToolbarSubclassProc (HWND hwnd,
  330.     UINT msg,
  331.     WPARAM wParam,
  332.     LPARAM lParam)
  333. {
  334.     LPFORMATBAR lpfb = (LPFORMATBAR)GetWindowLong (GetParent (hwnd), GWL_USERDATA);
  335.     switch (msg)
  336.     {
  337. #ifdef _WIN32
  338.       case WM_CTLCOLORLISTBOX:
  339. #else
  340.       case WM_CTLCOLOR:
  341.   
  342.         switch (HIWORD (lParam))
  343.         {
  344.           case CTLCOLOR_LISTBOX:
  345. #endif
  346.             if (!lpfb->hbrBtnFace)
  347.             {
  348.                 lpfb->hbrBtnFace = CreateSolidBrush (FWin4Shell()
  349.                                                         ? GetSysColor (COLOR_WINDOW)
  350.                                                         : GetSysColor (COLOR_BTNFACE));
  351.             }
  352.             return (LRESULT)(LPVOID)lpfb->hbrBtnFace;
  353. #ifdef _WIN32
  354.             break;
  355. #else
  356.             break;
  357.         }
  358.         break;
  359. #endif
  360.     }
  361.     return CallWindowProc (lpfb->lpfnToolbar, hwnd, msg, wParam, lParam);
  362. }
  363. STDMETHODIMP_(SCODE)
  364. ScCreateToolbar (LPSCD lpscd,
  365.     HWND hwnd,
  366.     UINT idPeg,
  367.     BOOL fPropsheet,
  368.     LPFORMATBAR FAR * lppfb)
  369. {
  370.     SCODE sc;
  371.     RECT rc;
  372.     RECT rcId;
  373.     RECT rcTb;
  374.     RECT rcCli;
  375.     UINT x;
  376.     UINT y;
  377.     WNDCLASS wc = {0};
  378.     LPFORMATBAR lpfb = NULL;
  379.     sc = (*lpscd->lpfnAlloc) (sizeof(FORMATBAR), &lpfb);
  380.     if (!FAILED (sc))
  381.     {
  382.         memset (lpfb, 0, sizeof(FORMATBAR));
  383.         lpfb->hwndEdit = GetDlgItem (hwnd, idPeg);
  384.         lpfb->cf.cbSize = sizeof(CHARFORMAT);
  385.         SendMessage (lpfb->hwndEdit, EM_GETCHARFORMAT, TRUE, (LPARAM)(LPVOID)&lpfb->cf);
  386.         lpfb->pf.cbSize = sizeof(PARAFORMAT);
  387.         SendMessage (lpfb->hwndEdit, EM_GETPARAFORMAT, 0, (LPARAM)(LPVOID)&lpfb->pf);
  388.         SendMessage (lpfb->hwndEdit, EM_SETEVENTMASK, 0, ENM_SELCHANGE | ENM_CHANGE);
  389.         lpfb->cf.dwMask = CFM_FACE | CFM_SIZE | CFE_BOLD | CFE_ITALIC | CFE_UNDERLINE | CFM_COLOR;
  390.         lpfb->cf.dwEffects = CFE_AUTOCOLOR;
  391.         lstrcpy (lpfb->cf.szFaceName, "Arial");
  392.         lpfb->cf.yHeight = 200;
  393.         SendMessage (lpfb->hwndEdit, EM_SETCHARFORMAT, 0, (LPARAM)(LPVOID)&lpfb->cf);
  394.         if (!GetClassInfo (lpscd->hinst, rgchTBClass, &wc))
  395.         {
  396.             wc.style = CS_HREDRAW | CS_VREDRAW;
  397.             wc.lpfnWndProc = FormatBarWndProc;
  398.             wc.cbWndExtra = sizeof(LPVOID);
  399.             wc.hInstance = lpscd->hinst;
  400.             wc.hCursor = LoadCursor (NULL, IDC_ARROW);
  401.             wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  402.             wc.lpszClassName = (LPCTSTR)rgchTBClass;
  403.             SideAssert (RegisterClass (&wc));
  404.         }
  405.         Assert (IsWindow (hwnd));
  406.         GetWindowRect (lpfb->hwndEdit, &rcId);
  407.         if (lpfb->hwndFrame = CreateWindow ((LPCTSTR)rgchTBClass,
  408.                                         "SMH",
  409.                                         WS_CHILD,
  410.                                         0, 0, rcId.right, 30,
  411.                                         hwnd,
  412.                                         (HMENU)ID_Frame,
  413.                                         lpscd->hinst,
  414.                                         NULL))
  415.         {
  416.             CTL3D_SubclassCtl (lpCtl3D, lpfb->hwndFrame);
  417.             lpfb->hmnuColor = CreatePopupMenu();
  418.             FillColors (lpfb);
  419.             if (lpfb->hwndTb = CreateToolbarEx (lpfb->hwndFrame,
  420.                                         CCS_TOP | WS_CHILD,
  421.                                         0,
  422.                                         ctbMax,
  423.                                         lpscd->hinst,
  424.                                         ID_Toolbar,
  425.                                         rgtbbChar,
  426.                                         ctbbChar,
  427.                                         16, 16, 16, 16,
  428.                                         sizeof(TBBUTTON)))
  429.             {
  430.                 lpfb->lpscd = lpscd;
  431.                 SetWindowLong (lpfb->hwndFrame, GWL_USERDATA, (ULONG)lpfb);
  432.                 /*  Move the window to where it belongs */
  433.                 GetWindowRect (hwnd, &rc);
  434.                 GetClientRect (lpfb->hwndTb, &rcTb);
  435.                 x = rcId.left - rc.left;
  436.                 y = rcId.top - rc.top - rcTb.bottom - 2;
  437.                 /*  Adjust y by any title bars and framing */
  438.                 if (!fPropsheet)
  439.                 {
  440.                     GetClientRect (hwnd, &rcCli);
  441.                     y -= rc.bottom - rc.top - rcCli.bottom;
  442.                     x -= (rc.right - rc.left - rcCli.right) / 2;
  443.                     y += (rc.right - rc.left - rcCli.right) / 2;
  444.                 }
  445.                 MoveWindow (lpfb->hwndFrame, x, y, rcId.right - rcId.left, rcTb.bottom, FALSE);
  446.                 lpfb->hfnt = (HFONT) SendMessage (lpfb->hwndTb, WM_GETFONT, 0, 0);
  447.                 lpfb->lpfnToolbar = (WNDPROC)SetWindowLong (lpfb->hwndTb,
  448.                                         GWL_WNDPROC,
  449.                                         (LONG)ToolbarSubclassProc);
  450.                 lpfb->hwndFont = CreateWindow ((LPCTSTR)rgchComboBox,
  451.                                         NULL,
  452.                                         WS_CHILD | WS_VSCROLL | CBS_DROPDOWN | CBS_SORT | WS_VISIBLE,
  453.                                         0, 3, cxName, rcTb.bottom * 5,
  454.                                         lpfb->hwndTb,
  455.                                         (HMENU) ID_Font,
  456.                                         lpscd->hinst,
  457.                                         NULL);
  458.                 CTL3D_SubclassCtl (lpCtl3D, lpfb->hwndFont);
  459.                 SetWindowFont (lpfb->hwndFont, lpfb->hfnt, TRUE);
  460.                 ComboBox_SetExtendedUI (lpfb->hwndFont, TRUE);
  461.                 FillFontNames (lpfb->hwndFont);
  462.                 lpfb->hwndSize = CreateWindow ((LPCTSTR)rgchComboBox,
  463.                                         NULL,
  464.                                         WS_CHILD | WS_VSCROLL | CBS_DROPDOWN | WS_VISIBLE,
  465.                                         cxName + 8, 3, cxSize, rcTb.bottom * 5,
  466.                                         lpfb->hwndTb,
  467.                                         (HMENU) ID_FontSize,
  468.                                         lpscd->hinst,
  469.                                         NULL);
  470.                 CTL3D_SubclassCtl (lpCtl3D, lpfb->hwndSize);
  471.                 SetWindowFont (lpfb->hwndSize, lpfb->hfnt, TRUE);
  472.                 ComboBox_SetExtendedUI (lpfb->hwndSize, TRUE);
  473.                 ComboBox_LimitText (lpfb->hwndSize, cchSizeMax);
  474.                 FillSizes (lpfb);
  475.                 UpdateFormatBar (lpfb->hwndFrame);
  476.                 ShowWindow (lpfb->hwndFrame, SW_SHOW);
  477.                 ShowWindow (lpfb->hwndTb, SW_SHOW);
  478.             }
  479.         }
  480.     }
  481.     *lppfb = lpfb;
  482.     DebugTraceSc (ScCreateToolbar(), (lpfb->hwndFrame ? S_OK : MAPI_E_CALL_FAILED));
  483.     return (lpfb->hwndFrame ? S_OK : MAPI_E_CALL_FAILED);
  484. }
  485. STDMETHODIMP_(BOOL)
  486. FDoRTFCommand (HWND hwnd, UINT id, UINT code)
  487. {
  488.     LPFORMATBAR lpfb = (LPFORMATBAR)(GetWindowLong (hwnd, GWL_USERDATA));
  489.     DWORD dw;
  490.     RECT rc;
  491.     UINT iSel;
  492.     switch (id)
  493.     {
  494.       case ID_Font:
  495.         if (code == CBN_SELENDOK)
  496.         {
  497.             FillSizes (lpfb);
  498.             iSel = ComboBox_GetCurSel (lpfb->hwndFont);
  499.             lpfb->cf.dwMask = CFM_FACE | CFM_CHARSET;
  500.             ComboBox_GetLBText (lpfb->hwndFont, iSel, lpfb->cf.szFaceName);
  501.             dw = ComboBox_GetItemData (lpfb->hwndFont, iSel);
  502.             lpfb->cf.bPitchAndFamily = (BYTE)(dw >>= 16) & 0xFF;
  503.             lpfb->cf.bCharSet = (BYTE)(dw >>= 8) & 0xFF;
  504.             SendMessage (lpfb->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)(LPVOID)&lpfb->cf);
  505.             UpdateFormatBar (lpfb->hwndFrame);
  506.             SetFocus (lpfb->hwndEdit);
  507.         }
  508.         break;
  509.       case ID_FontSize:
  510.         if (code == CBN_SELENDOK)
  511.         {
  512.             UINT i;
  513.             TCHAR rgch[cchSizeMax];
  514.             rgch[0] = 0;
  515.             lpfb->cf.dwMask = CFM_SIZE;
  516.             ComboBox_GetLBText (lpfb->hwndSize,
  517.                         ComboBox_GetCurSel (lpfb->hwndSize),
  518.                         rgch);
  519.             for (lpfb->cf.yHeight = 0, i = 0; rgch[i]; i++)
  520.                 lpfb->cf.yHeight = (lpfb->cf.yHeight * 10) + (rgch[i] - '0');
  521.             lpfb->cf.yHeight *= 20;
  522.             SendMessage (lpfb->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)(LPVOID)&lpfb->cf);
  523.             UpdateFormatBar (lpfb->hwndFrame);
  524.             SetFocus (lpfb->hwndEdit);
  525.         }
  526.         break;
  527.         break;
  528.       case ID_Color:
  529.         if (lpfb->hdc = GetDC (lpfb->hwndTb))
  530.         {
  531.             SendMessage (lpfb->hwndTb, TB_GETITEMRECT, 1, (LPARAM) &rc);
  532.             MapWindowPoints (lpfb->hwndTb, NULL, (LPPOINT)&rc, 2);
  533.             TrackPopupMenu (lpfb->hmnuColor, TPM_LEFTALIGN | TPM_LEFTBUTTON,
  534.                     rc.left, rc.bottom + 2, 0, hwnd, NULL);
  535.             ReleaseDC (lpfb->hwndTb, lpfb->hdc);
  536.         }
  537.         break;
  538.       case ID_ColorAuto:
  539.       case ID_ColorBlack:
  540.       case ID_ColorMaroon:
  541.       case ID_ColorGreen:
  542.       case ID_ColorOlive:
  543.       case ID_ColorBlue:
  544.       case ID_ColorPurple:
  545.       case ID_ColorTeal:
  546.       case ID_ColorGray:
  547.       case ID_ColorSilver:
  548.       case ID_ColorRed:
  549.       case ID_ColorLime:
  550.       case ID_ColorYellow:
  551.       case ID_ColorNavy:
  552.       case ID_ColorFuchia:
  553.       case ID_ColorAqua:
  554.       case ID_ColorWhite:
  555.         lpfb->cf.dwMask = CFM_COLOR;
  556.         lpfb->cf.dwEffects &= ~CFE_AUTOCOLOR;
  557.         lpfb->cf.dwEffects |= (id == ID_ColorAuto) ? CFE_AUTOCOLOR : 0;
  558.         lpfb->cf.crTextColor = (COLORREF)rgrgb[id - ID_Color - 1];
  559.         SendMessage (lpfb->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)(LPVOID)&lpfb->cf);
  560.         break;
  561.       case ID_Bold:
  562.       case ID_Italic:
  563.       case ID_Underline:
  564.         DebugTrace ("dwMask before: 0x%08lXn", lpfb->cf.dwMask);
  565.         DebugTrace ("dwEffects before: 0x%08lXn", lpfb->cf.dwEffects);
  566.         lpfb->cf.dwMask = rgdwEffect[id - ID_Bold];
  567.         lpfb->cf.dwEffects ^= rgdwEffect[id - ID_Bold];
  568.         DebugTrace ("dwMask after: 0x%08lXn", lpfb->cf.dwMask);
  569.         DebugTrace ("dwEffects after: 0x%08lXn", lpfb->cf.dwEffects);
  570.         SendMessage (lpfb->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)(LPVOID)&lpfb->cf);
  571.         break;
  572.       case ID_Indent:
  573.       case ID_Collapse:
  574.         lpfb->pf.dwMask = PFM_STARTINDENT;
  575.         lpfb->pf.dxStartIndent += ((id == ID_Indent) ? cxIndent : -cxIndent);
  576.         SendMessage (lpfb->hwndEdit, EM_SETPARAFORMAT, 0, (LPARAM)(LPVOID)&lpfb->pf);
  577.         break;
  578.       case ID_Left:
  579.       case ID_Center:
  580.       case ID_Right:
  581.         lpfb->pf.dwMask = PFM_ALIGNMENT;
  582.         lpfb->pf.wAlignment = rgwAlign[id - ID_Left];
  583.         SendMessage (lpfb->hwndEdit, EM_SETPARAFORMAT, 0, (LPARAM)(LPVOID)&lpfb->pf);
  584.         break;
  585.       case ID_Bullet:
  586.         lpfb->pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
  587.         if (lpfb->pf.wNumbering != PFN_BULLET)
  588.         {
  589.             lpfb->pf.wNumbering = PFN_BULLET;
  590.             lpfb->pf.dxOffset = cxIndent;
  591.         }
  592.         else
  593.         {
  594.             lpfb->pf.wNumbering = 0;
  595.             lpfb->pf.dxOffset = 0;
  596.         }
  597.         SendMessage (lpfb->hwndEdit, EM_SETPARAFORMAT, 0, (LPARAM)(LPVOID)&lpfb->pf);
  598.         break;
  599.       default:
  600.         return FALSE;
  601.     }
  602.     return TRUE;
  603. }
  604. void
  605. UpdateFormatBar (HWND hwnd)
  606. {
  607.     LPFORMATBAR lpfb = (LPFORMATBAR)(GetWindowLong (hwnd, GWL_USERDATA));
  608.     TCHAR rgch[cchSizeMax];
  609.     UINT i;
  610.     SendMessage (lpfb->hwndEdit, EM_GETCHARFORMAT, TRUE, (LPARAM)(LPVOID)&lpfb->cf);
  611.     DebugTrace ("SMH: updating formatbar: format: %s%s%sn",
  612.         (lpfb->cf.dwEffects & rgdwEffect[0]) ? "BOLD, " : "",
  613.         (lpfb->cf.dwEffects & rgdwEffect[1]) ? "ITALIC, " : "",
  614.         (lpfb->cf.dwEffects & rgdwEffect[2]) ? "UNDERLINED" : "");
  615.     DebugTrace ("SMH: updating formatbar: current font: %sn", lpfb->cf.szFaceName);
  616.     DebugTrace ("SMH: updating formatbar: current font height: %dn", lpfb->cf.yHeight);
  617.     DebugTrace ("SMH: updating formatbar: current font size: %dn", FontSize (lpfb->cf.yHeight));
  618.     DebugTrace ("SMH: updating formatbar: color: 0x%2X (r), 0x%2X (g), 0x%2x (b)n",
  619.         GetRValue (lpfb->cf.crTextColor),
  620.         GetGValue (lpfb->cf.crTextColor),
  621.         GetBValue (lpfb->cf.crTextColor));
  622.         
  623.     for (i = ID_Bold; i <= ID_Underline; i++)
  624.         SendMessage (lpfb->hwndTb, TB_CHECKBUTTON, i,
  625.             MAKELONG (lpfb->cf.dwEffects & rgdwEffect[i - ID_Bold], 0));
  626.     i = ComboBox_FindString (lpfb->hwndFont, -1, lpfb->cf.szFaceName);
  627.     if (i != (UINT)ComboBox_GetCurSel (lpfb->hwndFont))
  628.     {
  629.         ComboBox_SetCurSel (lpfb->hwndFont, i);
  630.         ComboBox_SetText (lpfb->hwndFont, lpfb->cf.szFaceName);
  631.     }
  632.     wsprintf (rgch, "%d", FontSize (lpfb->cf.yHeight));
  633.     i = (UINT)ComboBox_FindStringExact (lpfb->hwndSize, -1, rgch);
  634.     if ((i != CB_ERR) || (i != (UINT)ComboBox_GetCurSel (lpfb->hwndSize)))
  635.         ComboBox_SetCurSel (lpfb->hwndSize, i);
  636.     ComboBox_SetText (lpfb->hwndSize, rgch);
  637.     return;
  638. }