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.
1976 lines
57 KiB
1976 lines
57 KiB
/*
|
|
* f m t b a r . c p p
|
|
*
|
|
* Format Bar based on IOleCommandTarget
|
|
* Owner: brettm / a-mli
|
|
*
|
|
*/
|
|
#include <pch.hxx>
|
|
#include "dllmain.h"
|
|
#include <shfusion.h>
|
|
#include "demand.h"
|
|
#include "resource.h"
|
|
#include "util.h"
|
|
#include "mshtml.h"
|
|
#include "mshtmhst.h"
|
|
#include "mshtmcid.h"
|
|
#include "docobj.h"
|
|
#include "fmtbar.h"
|
|
#include "strconst.h"
|
|
#include "comctrlp.h"
|
|
#include <shlguidp.h>
|
|
|
|
/*
|
|
* WS_EX_LAYOUTRTL ported from winuser.h
|
|
*/
|
|
#if WINVER < 0X0500
|
|
#define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring
|
|
#endif // WS_EX_LAYOUTRTL
|
|
|
|
/*
|
|
* m a c r o s
|
|
*/
|
|
#define GETINDEX(m) ((DWORD)((((m & 0xff000000) >> 24) & 0x000000ff)))
|
|
#define MAKEINDEX(b, l) (((DWORD)l & 0x00ffffff) | ((DWORD)b << 24))
|
|
|
|
/*
|
|
* c o n s t a n t s
|
|
*/
|
|
#define cxButtonSep 8
|
|
#define dxToolbarButton 16
|
|
#define COMBOBUFSIZE 64
|
|
#define dxFormatFontBitmap 20
|
|
#define dyFormatFontBitmap 12
|
|
#define NFONTSIZES 7
|
|
#define TEMPBUFSIZE 30
|
|
#define CYDROPDOWNEXPANDRATIO 8
|
|
#define SIZETEXTLIMIT 8
|
|
#define cxDUName 100
|
|
#define cyToolbarOffset 2
|
|
#define idcCoolbar 45
|
|
|
|
// FormatBar stuff
|
|
enum
|
|
{
|
|
itbFormattingTag,
|
|
itbFormattingBold,
|
|
itbFormattingItalic,
|
|
itbFormattingUnderline,
|
|
itbFormattingColor,
|
|
itbFormattingNumbers,
|
|
itbFormattingBullets,
|
|
itbFormattingDecreaseIndent,
|
|
itbFormattingIncreaseIndent,
|
|
itbFormattingLeft,
|
|
itbFormattingCenter,
|
|
itbFormattingRight,
|
|
itbFormattingJustify,
|
|
itbFormattingInsertHLine,
|
|
itbFormattingInsertLink,
|
|
itbFormattingInsertImage,
|
|
ctbFormatting
|
|
};
|
|
|
|
|
|
// FormatBar Paragraph direction stuff
|
|
enum
|
|
{
|
|
itbFormattingBlockDirLTR = ctbFormatting,
|
|
itbFormattingBlockDirRTL,
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* t y p e d e f s
|
|
*/
|
|
/*
|
|
* g l o b a l d a t a
|
|
*/
|
|
|
|
static const TCHAR c_szComboBox[] = "ComboBox",
|
|
c_szFmtBarClass[] = "MimeEdit_FormatBar",
|
|
c_szThis[] = "OE_This";
|
|
|
|
/*
|
|
* Color table for dropdown on toolbar. Matches COMMDLG colors
|
|
* exactly.
|
|
*/
|
|
|
|
static DWORD rgrgbColors[] =
|
|
{
|
|
RGB( 0, 0, 0), // "BLACK"},
|
|
RGB(128, 0, 0), // "MAROON"},
|
|
RGB( 0, 128, 0), // "GREEN"},
|
|
RGB(128, 128, 0), // "OLIVE"},
|
|
RGB( 0, 0, 128), // "NAVY"},
|
|
RGB(128, 0, 128), // "PURPLE"},
|
|
RGB( 0, 128, 128), // "TEAL"},
|
|
RGB(128, 128, 128), // "GREY"},
|
|
RGB(192, 192, 192), // "SILVER"},
|
|
RGB(255, 0, 0), // "RED"},
|
|
RGB( 0, 255, 0), // "LIME"},
|
|
RGB(255, 255, 0), // "YELLOW"},
|
|
RGB( 0, 0, 255), // "BLUE"},
|
|
RGB(255, 0, 255), // "FUSCHIA"},
|
|
RGB( 0, 255, 255), // "AQUA"},
|
|
RGB(255, 255, 255) // "WHITE"}
|
|
};
|
|
|
|
|
|
static TBBUTTON rgtbbutton[] =
|
|
{
|
|
{ itbFormattingTag, idmFmtTag,
|
|
TBSTATE_ENABLED, TBSTYLE_DROPDOWN, {0}, 0L, -1 },
|
|
{ cxButtonSep, 0L,
|
|
TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, -1 },
|
|
{ itbFormattingBold, idmFmtBold,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1 },
|
|
{ itbFormattingItalic, idmFmtItalic,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1 },
|
|
{ itbFormattingUnderline, idmFmtUnderline,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1 },
|
|
{ itbFormattingColor, idmFmtColor,
|
|
TBSTATE_ENABLED, TBSTYLE_DROPDOWN, {0}, 0L, -1 },
|
|
{ cxButtonSep, 0L,
|
|
TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, -1 },
|
|
{ itbFormattingNumbers, idmFmtNumbers,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1 },
|
|
{ itbFormattingBullets, idmFmtBullets,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, -1 },
|
|
{ itbFormattingDecreaseIndent, idmFmtDecreaseIndent,
|
|
TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, -1 },
|
|
{ itbFormattingIncreaseIndent, idmFmtIncreaseIndent,
|
|
TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, -1 },
|
|
{ cxButtonSep, 0L,
|
|
TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, -1 },
|
|
{ itbFormattingLeft, idmFmtLeft,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, {0}, 0L, -1 },
|
|
{ itbFormattingCenter, idmFmtCenter,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, {0}, 0L, -1 },
|
|
{ itbFormattingRight, idmFmtRight,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, {0}, 0L, -1 },
|
|
{ itbFormattingJustify, idmFmtJustify,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, {0}, 0L, -1 },
|
|
{ cxButtonSep, 0L,
|
|
TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, -1 },
|
|
{ itbFormattingInsertHLine, idmFmtInsertHLine,
|
|
TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, -1 },
|
|
{ itbFormattingInsertLink, idmEditLink,
|
|
TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, -1 },
|
|
{ itbFormattingInsertImage, idmInsertImage,
|
|
TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, -1 }
|
|
};
|
|
|
|
static TBBUTTON rgtbblkdirbutton[] =
|
|
{
|
|
|
|
{ itbFormattingBlockDirLTR, idmFmtBlockDirLTR,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, {0}, 0L, -1 },
|
|
{ itbFormattingBlockDirRTL, idmFmtBlockDirRTL,
|
|
TBSTATE_ENABLED, TBSTYLE_CHECKGROUP, {0}, 0L, -1 },
|
|
{ cxButtonSep, 0L,
|
|
TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, -1 }
|
|
};
|
|
|
|
#define ctbbutton (sizeof(rgtbbutton) / sizeof(TBBUTTON))
|
|
|
|
|
|
/*
|
|
* p r o t o t y p e s
|
|
*/
|
|
|
|
HRESULT ColorMenu_Show(HMENU hmenuColor, HWND hwndParent, POINT pt, COLORREF *pclrf);
|
|
void Color_WMDrawItem(HWND hwnd, LPDRAWITEMSTRUCT pdis);
|
|
void Color_WMMeasureItem(HWND hwnd, HDC hdc, LPMEASUREITEMSTRUCT pmis);
|
|
INT GetColorIndex(INT rbg);
|
|
HFONT hFontGetMenuFont(HWND hwnd);
|
|
|
|
/*
|
|
* f u n c t i o n s
|
|
*/
|
|
|
|
CFmtBar::CFmtBar(BOOL fSep)
|
|
{
|
|
m_cRef=1;
|
|
|
|
m_hwnd = NULL;
|
|
m_hwndToolbar = NULL;
|
|
m_hwndName = NULL;
|
|
m_hwndSize = NULL;
|
|
|
|
m_wndprocEdit = NULL;
|
|
m_wndprocNameComboBox = NULL;
|
|
m_wndprocSizeComboBox = NULL;
|
|
m_hbmName = NULL;
|
|
m_hmenuColor = NULL;
|
|
m_hmenuTag = NULL;
|
|
m_fDestroyTagMenu = 1;
|
|
m_pCmdTarget=0;
|
|
m_fVisible = 0;
|
|
m_fSep = !!fSep;
|
|
m_himlHot = NULL;
|
|
m_himl = NULL;
|
|
}
|
|
|
|
CFmtBar::~CFmtBar()
|
|
{
|
|
if (m_hbmName)
|
|
DeleteObject(m_hbmName);
|
|
|
|
if (m_hmenuColor)
|
|
DestroyMenu(m_hmenuColor);
|
|
|
|
if (m_hmenuTag && !!m_fDestroyTagMenu)
|
|
DestroyMenu(m_hmenuTag);
|
|
|
|
_FreeImageLists();
|
|
}
|
|
|
|
ULONG CFmtBar::AddRef()
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
ULONG CFmtBar::Release()
|
|
{
|
|
ULONG cRef=--m_cRef;
|
|
|
|
if(m_cRef==0)
|
|
delete this;
|
|
|
|
return cRef;
|
|
}
|
|
|
|
|
|
HRESULT CreateColorMenu(ULONG idmStart, HMENU* pMenu)
|
|
{
|
|
DWORD irgb;
|
|
DWORD mniColor;
|
|
|
|
if(pMenu == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
*pMenu = CreatePopupMenu();
|
|
|
|
if (*pMenu == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
// Add the COLORREF version of each entry into the menu
|
|
for (irgb = 0, mniColor=idmStart; irgb < sizeof(rgrgbColors)/sizeof(DWORD); ++irgb, ++mniColor)
|
|
AppendMenu(*pMenu, MF_ENABLED|MF_OWNERDRAW, mniColor, (LPCSTR)IntToPtr(MAKEINDEX(irgb, rgrgbColors[irgb])));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
LRESULT CALLBACK CFmtBar::ExtWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LPFORMATBAR pFmtBar=0;
|
|
|
|
if (msg==WM_NCCREATE)
|
|
{
|
|
pFmtBar=(CFmtBar *)((LPCREATESTRUCT)lParam)->lpCreateParams;
|
|
if(!pFmtBar)
|
|
return -1;
|
|
|
|
return (pFmtBar->OnNCCreate(hwnd)==S_OK);
|
|
}
|
|
|
|
pFmtBar = (LPFORMATBAR)GetWndThisPtr(hwnd);
|
|
if (pFmtBar)
|
|
return pFmtBar->WndProc(hwnd, msg, wParam, lParam);
|
|
else
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
extern BOOL g_fCanEditBiDi;
|
|
|
|
|
|
HRESULT CFmtBar::OnNCCreate(HWND hwnd)
|
|
{
|
|
RECT rc;
|
|
HFONT hfontOld,
|
|
hfontToolbar;
|
|
HWND hwndEdit,
|
|
hwndToolTips;
|
|
BOOL fRet;
|
|
HDC hdc,
|
|
hdcParent;
|
|
TEXTMETRIC tm;
|
|
INT yPos;
|
|
INT cxDownButton;
|
|
INT cxName;
|
|
INT cxSize,
|
|
cx;
|
|
INT cyToolbarButton;
|
|
INT cyDropDownRollHeight;
|
|
INT cyExpandedList;
|
|
const POINT pt = {5, 5};
|
|
LONG lstyle;
|
|
TOOLINFO ti;
|
|
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
|
m_hwnd=hwnd;
|
|
AddRef();
|
|
|
|
m_hwndRebar = CreateWindowEx(0, REBARCLASSNAME, NULL,
|
|
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN |
|
|
WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN,
|
|
0, 0, 100, 136, m_hwnd, (HMENU) idcCoolbar, g_hInst, NULL);
|
|
|
|
if (!m_hwndRebar)
|
|
return E_OUTOFMEMORY;
|
|
|
|
SendMessage(m_hwndRebar, RB_SETTEXTCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNTEXT));
|
|
SendMessage(m_hwndRebar, RB_SETBKCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
|
|
//SendMessage(m_hwndRebar, RB_SETEXTENDEDSTYLE, RBS_EX_OFFICE9, RBS_EX_OFFICE9);
|
|
SendMessage(m_hwndRebar, CCM_SETVERSION, COMCTL32_VERSION, 0);
|
|
|
|
|
|
// [a-msadek]; Fix for bug#55069
|
|
// DO NOT remove CCS_TOP from creation styles below
|
|
// It is a default style and toolbar WinProc will addit any way durin
|
|
// WM_NCCREATE processing. However, it will cause WM_STYLECHANGING to be sent
|
|
// Due to a bug in SetWindowPos() for a mirrored window, it will never return from seding
|
|
// messages calling a stack overflow
|
|
// No need to put it only for a mirrored window since it will be added any way
|
|
// Look @ comctl32\toolbar.c, functions ToolbarWndProc() and TBAutoSize();
|
|
|
|
m_hwndToolbar = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
|
|
WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|CCS_TOP|CCS_NOPARENTALIGN|CCS_NODIVIDER|
|
|
TBSTYLE_TOOLTIPS|TBSTYLE_FLAT,
|
|
0, 0, 0, 0, m_hwndRebar, NULL,
|
|
g_hInst, NULL);
|
|
|
|
|
|
if (!m_hwndToolbar)
|
|
return E_OUTOFMEMORY;
|
|
|
|
SendMessage(m_hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
|
SendMessage(m_hwndToolbar, TB_ADDBUTTONS, (WPARAM)ctbbutton, (LPARAM)rgtbbutton);
|
|
SendMessage(m_hwndToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(dxToolbarButton, dxToolbarButton));
|
|
|
|
_SetToolbarBitmaps();
|
|
|
|
// add BiDi direction buttons
|
|
if(g_fCanEditBiDi)
|
|
{
|
|
SendMessage(m_hwndToolbar, TB_INSERTBUTTON, ctbbutton - 3, (LPARAM) (LPVOID) &rgtbblkdirbutton[2]);
|
|
SendMessage(m_hwndToolbar, TB_INSERTBUTTON, ctbbutton - 3, (LPARAM) (LPVOID) &rgtbblkdirbutton[1]);
|
|
SendMessage(m_hwndToolbar, TB_INSERTBUTTON, ctbbutton - 3, (LPARAM) (LPVOID) &rgtbblkdirbutton[0]);
|
|
SendMessage(m_hwndToolbar, TB_AUTOSIZE, (WPARAM)0, (LPARAM)0);
|
|
}
|
|
|
|
hdcParent = GetDC(GetParent(hwnd));
|
|
if (!hdcParent)
|
|
return E_OUTOFMEMORY;
|
|
|
|
hdc = CreateCompatibleDC(hdcParent);
|
|
ReleaseDC(GetParent(hwnd), hdcParent);
|
|
|
|
if (!hdc)
|
|
return E_OUTOFMEMORY;
|
|
|
|
hfontToolbar = (HFONT) SendMessage(m_hwndToolbar, WM_GETFONT, 0, 0);
|
|
|
|
// Get font metrics (of System font) so that we can properly scale the
|
|
// format bar layout
|
|
hfontOld = (HFONT)SelectObject(hdc, hfontToolbar);
|
|
GetTextMetrics(hdc, &tm);
|
|
|
|
cxDownButton = GetSystemMetrics(SM_CXVSCROLL) + GetSystemMetrics(SM_CXDLGFRAME);
|
|
cxName = (cxDUName * tm.tmAveCharWidth) / 4 + cxDownButton;
|
|
cxSize = XFontSizeCombo(hdc) + cxDownButton;
|
|
SelectObject(hdc, hfontOld);
|
|
DeleteDC(hdc);
|
|
|
|
// set the size of the formatbar based on the size of the toolbar plus 2 pixels padding
|
|
GetClientRect(m_hwndToolbar, &rc);
|
|
SetWindowPos(m_hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top + (2*cyToolbarOffset) + (m_fSep?2:0), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
|
|
|
|
// Determine how tall the buttons are so we can size our other controls
|
|
// accordingly
|
|
SendMessage(m_hwndToolbar, TB_GETITEMRECT, 1, (LPARAM) &rc);
|
|
cyToolbarButton = rc.bottom - rc.top + 1;
|
|
|
|
// Figure out size of expanded dropdown lists
|
|
cyExpandedList = CYDROPDOWNEXPANDRATIO * cyToolbarButton;
|
|
|
|
// Get the ToolTips window handle
|
|
hwndToolTips = (HWND) SendMessage(m_hwndToolbar, TB_GETTOOLTIPS, 0, 0);
|
|
|
|
m_hwndName = CreateWindow(c_szComboBox, NULL,
|
|
WS_CHILD | WS_VSCROLL | CBS_DROPDOWN |
|
|
CBS_SORT | CBS_HASSTRINGS |
|
|
CBS_OWNERDRAWFIXED |WS_VISIBLE,
|
|
0, 0, cxName, cyExpandedList,
|
|
m_hwndToolbar,
|
|
(HMENU) idmFmtFont, g_hLocRes, NULL);
|
|
|
|
if (!m_hwndName)
|
|
return E_OUTOFMEMORY;
|
|
|
|
ComboBox_SetExtendedUI(m_hwndName, TRUE);
|
|
|
|
// Load up the mini-icons for TrueType or Printer font
|
|
m_hbmName = LoadDIBBitmap(idbFormatBarFont);
|
|
if (!m_hbmName)
|
|
return E_OUTOFMEMORY;
|
|
|
|
// Compute the right edge of the combobox
|
|
SetWindowFont(m_hwndName, hfontToolbar, TRUE);
|
|
|
|
// The Size
|
|
m_hwndSize = CreateWindow(c_szComboBox, NULL,
|
|
WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST |
|
|
WS_VISIBLE,
|
|
cxName + cxButtonSep, 0, cxSize, cyExpandedList,
|
|
m_hwndToolbar,
|
|
(HMENU) idmFmtSize, g_hLocRes, NULL);
|
|
|
|
if (!m_hwndSize)
|
|
return E_OUTOFMEMORY;
|
|
|
|
m_hwndTT = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, 0,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
NULL, (HMENU) NULL, g_hInst, NULL);
|
|
if (!m_hwndTT)
|
|
return E_OUTOFMEMORY;
|
|
|
|
ZeroMemory(&ti, sizeof(TOOLINFO));
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.uFlags = TTF_IDISHWND | TTF_TRANSPARENT | TTF_TRACK | TTF_ABSOLUTE;
|
|
ti.hwnd = m_hwndName;
|
|
ti.uId = (ULONG_PTR)m_hwndName;
|
|
|
|
SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM)&ti);
|
|
SendMessage(m_hwndTT, WM_SETFONT, (WPARAM)(HFONT)SendMessage(m_hwndToolbar, WM_GETFONT, 0, 0), 0);
|
|
|
|
ComboBox_SetExtendedUI(m_hwndSize, TRUE);
|
|
SetWindowFont(m_hwndSize, hfontToolbar, TRUE);
|
|
// font sizes up to 4 digits are allowed
|
|
ComboBox_LimitText(m_hwndSize, SIZETEXTLIMIT);
|
|
// The color popup menu (initially empty)
|
|
// Set the rolled-up heights of the combo boxes to all be the same
|
|
cyDropDownRollHeight = LOWORD(SendMessage(m_hwndSize, CB_GETITEMHEIGHT, (WPARAM)-1, 0));
|
|
// hwndName is ownerdrawn
|
|
SendMessage(m_hwndName, CB_SETITEMHEIGHT, (WPARAM)-1, cyDropDownRollHeight);
|
|
// Determine how tall the toolbar is so we can center the comboboxes
|
|
GetClientRect(m_hwndToolbar, &rc);
|
|
// Get size of toolbar window
|
|
yPos = rc.bottom;
|
|
// Get size of combobox
|
|
GetClientRect(m_hwndSize, &rc);
|
|
yPos = (yPos - rc.bottom) / 2;
|
|
|
|
// We have a mirroring bug in GetWindowRect
|
|
// It will give wrong cocordinates causing combos to go outside the screen
|
|
// Ignore y-positioning in this case
|
|
|
|
if(!(GetWindowLong(m_hwndToolbar, GWL_EXSTYLE) & WS_EX_LAYOUTRTL))
|
|
{
|
|
GetWindowRect(m_hwndName, &rc);
|
|
MapWindowPoints(NULL, hwnd, (LPPOINT)&rc, 2);
|
|
MoveWindow(m_hwndName, rc.left, yPos, rc.right-rc.left, rc.bottom-rc.top, FALSE);
|
|
GetWindowRect(m_hwndSize, &rc);
|
|
MapWindowPoints(NULL, hwnd, (LPPOINT)&rc, 2);
|
|
MoveWindow(m_hwndSize, rc.left, yPos, rc.right-rc.left, rc.bottom-rc.top, FALSE);
|
|
}
|
|
hwndEdit = ::GetWindow(m_hwndName, GW_CHILD);
|
|
|
|
// Add tooltips for the controls we just added
|
|
AddToolTip(hwndToolTips, m_hwndName, idsTTFormattingFont);
|
|
AddToolTip(hwndToolTips, m_hwndSize, idsTTFormattingSize);
|
|
AddToolTip(hwndToolTips, hwndEdit, idsTTFormattingFont);
|
|
|
|
// Subclass the comboboxes and their edit controls
|
|
// Do the name edit control first
|
|
m_wndprocEdit = SubclassWindow(hwndEdit, EditSubProc);
|
|
m_wndprocNameComboBox = SubclassWindow(m_hwndName, ComboBoxSubProc);
|
|
m_wndprocSizeComboBox = SubclassWindow(m_hwndSize, ComboBoxSubProc);
|
|
|
|
// give the control This pointers
|
|
SetProp(m_hwndName, c_szThis, (LPVOID)this);
|
|
SetProp(m_hwndSize, c_szThis, (LPVOID)this);
|
|
SetProp(hwndEdit, c_szThis, (LPVOID)this);
|
|
|
|
GetClientRect(m_hwndToolbar, &rc);
|
|
|
|
cx = cxName + cxSize + cxButtonSep * 2;
|
|
REBARBANDINFO rbbi;
|
|
|
|
POINT ptIdeal = {0};
|
|
SendMessage(m_hwndToolbar, TB_GETIDEALSIZE, FALSE, (LPARAM)&ptIdeal);
|
|
|
|
ZeroMemory(&rbbi, sizeof(rbbi));
|
|
rbbi.cbSize = sizeof(REBARBANDINFO);
|
|
rbbi.fMask = RBBIM_SIZE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE;
|
|
rbbi.fStyle = RBBS_USECHEVRON;
|
|
rbbi.cx = 0;
|
|
rbbi.hwndChild = m_hwndToolbar;
|
|
rbbi.cxMinChild = 0;
|
|
rbbi.cyMinChild = rc.bottom;
|
|
rbbi.cxIdeal = ptIdeal.x + cx;
|
|
|
|
SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT)-1, (LPARAM)(LPREBARBANDINFO)&rbbi);
|
|
|
|
// Indent the toolbar buttons for the comboboxes
|
|
SendMessage(m_hwndToolbar, TB_SETINDENT, cx, 0);
|
|
|
|
// Load up the names of the fonts and colors
|
|
FillFontNames();
|
|
FillSizes();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
void CFmtBar::OnNCDestroy()
|
|
{
|
|
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
|
|
m_hwnd=0;
|
|
Release();
|
|
}
|
|
|
|
LRESULT CALLBACK CFmtBar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_DESTROY:
|
|
// unsubclass the windows
|
|
if (m_wndprocEdit)
|
|
{
|
|
SubclassWindow(::GetWindow(m_hwndName, GW_CHILD), m_wndprocEdit);
|
|
RemoveProp(::GetWindow(m_hwndName, GW_CHILD), c_szThis);
|
|
}
|
|
|
|
if (m_wndprocNameComboBox)
|
|
{
|
|
SubclassWindow(m_hwndName, m_wndprocNameComboBox);
|
|
RemoveProp(m_hwndName, c_szThis);
|
|
}
|
|
|
|
if (m_wndprocSizeComboBox)
|
|
{
|
|
SubclassWindow(m_hwndSize, m_wndprocSizeComboBox);
|
|
RemoveProp(m_hwndSize, c_szThis);
|
|
}
|
|
DestroyWindow(m_hwndTT);
|
|
m_hwndTT=NULL;
|
|
break;
|
|
|
|
case WM_NCDESTROY:
|
|
OnNCDestroy();
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if(OnWMCommand(GET_WM_COMMAND_HWND(wParam, lParam),
|
|
GET_WM_COMMAND_ID(wParam, lParam),
|
|
GET_WM_COMMAND_CMD(wParam, lParam))==S_OK)
|
|
return 0;
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
if (m_fSep)
|
|
{
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
RECT rc;
|
|
|
|
hdc=BeginPaint(hwnd, &ps);
|
|
if (hdc)
|
|
{
|
|
GetClientRect(hwnd, &rc);
|
|
rc.top = rc.bottom-3;
|
|
//rc.bottom+=1;
|
|
DrawEdge(hdc, &rc, BDR_RAISEDOUTER, BF_BOTTOM);
|
|
EndPaint(hwnd, &ps);
|
|
}
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
WMNotify(wParam, (NMHDR*)lParam);
|
|
return 0;
|
|
|
|
case WM_SIZE:
|
|
{
|
|
RECT rc;
|
|
|
|
GetClientRect(m_hwndRebar, &rc);
|
|
|
|
// resize the width of the toolbar
|
|
if(rc.right != (INT)LOWORD(lParam))
|
|
SetWindowPos(m_hwndRebar, NULL, 0, cyToolbarOffset, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER|SWP_NOACTIVATE);
|
|
}
|
|
break;
|
|
|
|
case WM_DRAWITEM:
|
|
OnDrawItem((LPDRAWITEMSTRUCT)lParam);
|
|
break;
|
|
|
|
case WM_SYSCOLORCHANGE:
|
|
_SetToolbarBitmaps();
|
|
UpdateRebarBandColors(m_hwndRebar);
|
|
// fall thro'
|
|
|
|
case WM_WININICHANGE:
|
|
case WM_DISPLAYCHANGE:
|
|
case WM_QUERYNEWPALETTE:
|
|
case WM_PALETTECHANGED:
|
|
SendMessage(m_hwndRebar, msg, wParam, lParam);
|
|
break;
|
|
|
|
|
|
case WM_MEASUREITEM:
|
|
OnMeasureItem((LPMEASUREITEMSTRUCT)lParam);
|
|
break;
|
|
}
|
|
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
HRESULT CFmtBar::Init(HWND hwndParent, int idDlgItem)
|
|
{
|
|
// stuff these values. We don't create the formatbar until the first call to Show()
|
|
// to allow better perf.
|
|
m_hwndParent = hwndParent;
|
|
m_idd = idDlgItem;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
// displays the colorpopup menu at the specified point. if clrf if NULL, then no clrf is returned
|
|
// but instead the appropriate WM_COMMAND is dispatched to the parent window
|
|
HRESULT ColorMenu_Show(HMENU hmenuColor, HWND hwndParent, POINT pt, COLORREF *pclrf)
|
|
{
|
|
HRESULT hr=NOERROR;
|
|
int tpm=TPM_LEFTALIGN|TPM_LEFTBUTTON;
|
|
|
|
if(hmenuColor == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
if(pclrf)
|
|
tpm|=TPM_RETURNCMD;
|
|
|
|
int id = TrackPopupMenu(hmenuColor, tpm,pt.x, pt.y, 0, hwndParent, NULL);
|
|
|
|
switch(id)
|
|
{
|
|
case 1:
|
|
return NOERROR;
|
|
case 0:
|
|
return E_FAIL;
|
|
case -1:
|
|
return MIMEEDIT_E_USERCANCEL;
|
|
|
|
case idmFmtColor1:
|
|
case idmFmtColor2:
|
|
case idmFmtColor3:
|
|
case idmFmtColor4:
|
|
case idmFmtColor5:
|
|
case idmFmtColor6:
|
|
case idmFmtColor7:
|
|
case idmFmtColor8:
|
|
case idmFmtColor9:
|
|
case idmFmtColor10:
|
|
case idmFmtColor11:
|
|
case idmFmtColor12:
|
|
case idmFmtColor13:
|
|
case idmFmtColor14:
|
|
case idmFmtColor15:
|
|
case idmFmtColor16:
|
|
AssertSz(pclrf, "this HAS to be set to get this id back...");
|
|
*pclrf=rgrgbColors[id-idmFmtColor1];
|
|
return NOERROR;
|
|
|
|
default:
|
|
AssertSz(0, "unexpected return from TrackPopupMenu");
|
|
}
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT CFmtBar::CheckColor()
|
|
{
|
|
HRESULT hr=E_FAIL;
|
|
INT iFound = -1, irgb;
|
|
VARIANTARG va;
|
|
|
|
if (!m_pCmdTarget)
|
|
return E_FAIL;
|
|
|
|
va.vt = VT_I4;
|
|
va.lVal = -1;
|
|
hr = m_pCmdTarget->Exec(&CMDSETID_Forms3,
|
|
IDM_FORECOLOR,
|
|
MSOCMDEXECOPT_DONTPROMPTUSER,
|
|
NULL, &va);
|
|
if(FAILED(hr))
|
|
goto error;
|
|
|
|
if(va.lVal == -1)
|
|
goto error;
|
|
|
|
iFound = GetColorIndex(va.lVal);
|
|
|
|
error:
|
|
CheckMenuRadioItem(m_hmenuColor, idmFmtColor1, idmFmtColor16, idmFmtColor1+iFound, MF_BYCOMMAND);
|
|
return hr;
|
|
}
|
|
|
|
|
|
INT GetColorIndex(INT rbg)
|
|
{
|
|
INT iFound = -1;
|
|
|
|
for (int irgb = 1; irgb < sizeof(rgrgbColors)/sizeof(DWORD); ++irgb)
|
|
if ((rbg&0x00ffffff) == (LONG)rgrgbColors[irgb])
|
|
{
|
|
iFound = irgb;
|
|
break;
|
|
}
|
|
return iFound;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CFmtBar::HrInitTagMenu()
|
|
{
|
|
HRESULT hr=NOERROR;
|
|
int id;
|
|
int tpm=TPM_LEFTALIGN|TPM_LEFTBUTTON;
|
|
VARIANTARG va;
|
|
VARIANTARG *pvaIn=0;
|
|
TCHAR szBufMenu[MAX_PATH] = {0};
|
|
TCHAR szBufTag[MAX_PATH] = {0};
|
|
|
|
if (!m_pCmdTarget)
|
|
return E_FAIL;
|
|
|
|
if (!m_hmenuTag &&
|
|
FAILED(HrCreateTridentMenu(m_pCmdTarget, TM_TAGMENU, idmFmtTagFirst, idmFmtTagLast-idmFmtTagFirst, &m_hmenuTag)))
|
|
return E_FAIL;
|
|
|
|
hr = HrCheckTridentMenu(m_pCmdTarget, TM_TAGMENU, idmFmtTagFirst, idmFmtTagLast, m_hmenuTag);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CFmtBar::HrShowTagMenu(POINT pt)
|
|
{
|
|
HRESULT hr;
|
|
int tpm=TPM_LEFTALIGN|TPM_LEFTBUTTON;
|
|
|
|
hr = HrInitTagMenu();
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
TrackPopupMenu(m_hmenuTag, tpm, pt.x, pt.y, 0, m_hwnd, NULL);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HMENU CFmtBar::hmenuGetStyleTagMenu()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = HrInitTagMenu();
|
|
if(FAILED(hr))
|
|
return NULL;
|
|
|
|
m_fDestroyTagMenu = 0;
|
|
return m_hmenuTag;
|
|
}
|
|
|
|
|
|
// update toolbar buttons and font name/size combo boxes.
|
|
HRESULT CFmtBar::Update()
|
|
{
|
|
UINT uCmdID=0;
|
|
CHAR szBuf[COMBOBUFSIZE/2];
|
|
CHAR szBufbstrVal[COMBOBUFSIZE/2];
|
|
int i;
|
|
INT iPointSize=0, iHTMLSize=0;
|
|
HWND hwndEdit;
|
|
OLECMD rgCmds[]= {
|
|
{IDM_FONTNAME, 0},
|
|
{IDM_FONTSIZE, 0},
|
|
{IDM_FORECOLOR, 0},
|
|
{IDM_BOLD, 0},
|
|
{IDM_ITALIC, 0},
|
|
{IDM_UNDERLINE, 0},
|
|
{IDM_ORDERLIST, 0},
|
|
{IDM_UNORDERLIST, 0},
|
|
{IDM_JUSTIFYLEFT, 0},
|
|
{IDM_JUSTIFYRIGHT, 0},
|
|
{IDM_JUSTIFYCENTER, 0},
|
|
{IDM_JUSTIFYFULL, 0},
|
|
{IDM_BLOCKDIRLTR, 0},
|
|
{IDM_BLOCKDIRRTL, 0},
|
|
{IDM_OUTDENT, 0},
|
|
{IDM_INDENT, 0},
|
|
{IDM_HORIZONTALLINE, 0},
|
|
{IDM_HYPERLINK, 0},
|
|
{IDM_IMAGE, 0},
|
|
{IDM_BLOCKFMT, 0}};
|
|
|
|
int rgidm[] = { 0,
|
|
0,
|
|
idmFmtColor,
|
|
idmFmtBold,
|
|
idmFmtItalic,
|
|
idmFmtUnderline,
|
|
idmFmtNumbers,
|
|
idmFmtBullets,
|
|
idmFmtLeft,
|
|
idmFmtRight,
|
|
idmFmtCenter,
|
|
idmFmtJustify,
|
|
idmFmtBlockDirLTR,
|
|
idmFmtBlockDirRTL,
|
|
idmFmtDecreaseIndent,
|
|
idmFmtIncreaseIndent,
|
|
idmFmtInsertHLine,
|
|
idmEditLink,
|
|
idmInsertImage,
|
|
idmFmtTag};
|
|
|
|
ULONG uState;
|
|
BOOL fUIActive;
|
|
|
|
if (!m_hwnd) // no UI visible yet
|
|
return S_OK;
|
|
|
|
if (!m_pCmdTarget)
|
|
{
|
|
EnableWindow(m_hwndName, FALSE);
|
|
EnableWindow(m_hwndSize, FALSE);
|
|
|
|
for (i=2; i<sizeof(rgCmds)/sizeof(OLECMD); i++)
|
|
SendMessage(m_hwndToolbar, TB_SETSTATE, rgidm[i], MAKELONG(0, 0));
|
|
return S_OK;
|
|
}
|
|
|
|
HWND hwndFocus = GetFocus();
|
|
|
|
if (m_hwndToolbar == hwndFocus ||
|
|
(hwndFocus && m_hwndToolbar==GetParent(hwndFocus)) ||
|
|
(hwndFocus && GetParent(hwndFocus) && m_hwndToolbar==GetParent(GetParent(hwndFocus))) )
|
|
return S_OK;
|
|
|
|
fUIActive = FBodyHasFocus();
|
|
|
|
if (fUIActive)
|
|
m_pCmdTarget->QueryStatus(&CMDSETID_Forms3, sizeof(rgCmds)/sizeof(OLECMD), rgCmds, NULL);
|
|
|
|
EnableWindow(m_hwndName, fUIActive && (rgCmds[0].cmdf&OLECMDF_ENABLED));
|
|
EnableWindow(m_hwndSize, fUIActive && (rgCmds[1].cmdf&OLECMDF_ENABLED));
|
|
|
|
for (i=2; i<sizeof(rgCmds)/sizeof(OLECMD); i++)
|
|
{
|
|
uState=(rgCmds[i].cmdf&OLECMDF_LATCHED ? TBSTATE_PRESSED: 0)|
|
|
(rgCmds[i].cmdf&OLECMDF_ENABLED ? TBSTATE_ENABLED: 0);
|
|
SendMessage(m_hwndToolbar, TB_SETSTATE, rgidm[i], MAKELONG(uState, 0));
|
|
}
|
|
|
|
if (!fUIActive)
|
|
return S_OK;
|
|
|
|
// update font name combo box
|
|
VARIANTARG va;
|
|
va.vt = VT_BSTR;
|
|
va.bstrVal = NULL;
|
|
|
|
if (m_pCmdTarget->Exec(&CMDSETID_Forms3, IDM_FONTNAME, MSOCMDEXECOPT_DONTPROMPTUSER, NULL, &va) == S_OK)
|
|
{
|
|
hwndEdit = ::GetWindow(m_hwndName, GW_CHILD);
|
|
if (va.vt == VT_BSTR)
|
|
{
|
|
*szBuf = 0;
|
|
*szBufbstrVal = 0;
|
|
|
|
// we have a font-name, let's see if we need to update
|
|
ComboBox_GetText(hwndEdit, szBuf, COMBOBUFSIZE/2);
|
|
WideCharToMultiByte(CP_ACP, 0, (WCHAR*)va.bstrVal, -1, szBufbstrVal, COMBOBUFSIZE/2, NULL, NULL);
|
|
|
|
if (StrCmpI(szBufbstrVal, szBuf) != 0)
|
|
{
|
|
if(ComboBox_SelectString(m_hwndName, -1, szBufbstrVal) == -1)
|
|
ComboBox_SetText(hwndEdit, szBufbstrVal);
|
|
}
|
|
|
|
SafeSysFreeString(va.bstrVal);
|
|
}
|
|
else
|
|
ComboBox_SetText(hwndEdit, "");
|
|
}
|
|
|
|
|
|
// update font size combo box
|
|
va.vt = VT_I4;
|
|
va.lVal = 0;
|
|
|
|
if (m_pCmdTarget->Exec(&CMDSETID_Forms3, IDM_FONTSIZE, MSOCMDEXECOPT_DONTPROMPTUSER, NULL, &va)==S_OK &&
|
|
va.vt == VT_I4)
|
|
{
|
|
// font size if returned in the 1 to 7 range, for I4
|
|
// see if the font size has changed
|
|
*szBuf = 0;
|
|
|
|
if(ComboBox_GetText(m_hwndSize, szBuf, sizeof(szBuf)))
|
|
{
|
|
iPointSize = StrToInt(szBuf);
|
|
Assert(iPointSize>=8 && iPointSize<=36);
|
|
iHTMLSize = PointSizeToHTMLSize(iPointSize);
|
|
}
|
|
|
|
if(iHTMLSize != va.lVal)
|
|
ComboBox_SetCurSel(m_hwndSize, va.lVal-1);
|
|
}
|
|
else
|
|
ComboBox_SetCurSel(m_hwndSize, -1);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFmtBar::OnWMCommand(HWND hwnd, int id, WORD wCmd)
|
|
{
|
|
UINT uCmdID=0;
|
|
VARIANTARG va;
|
|
VARIANTARG *pvaIn=0;
|
|
HRESULT hr = S_FALSE;
|
|
DWORD dwOpt=MSOCMDEXECOPT_DONTPROMPTUSER;
|
|
TOOLINFO ti;
|
|
|
|
ZeroMemory(&va, sizeof(va));
|
|
|
|
switch(wCmd)
|
|
{
|
|
case CBN_SELENDCANCEL:
|
|
// clear the tooltip
|
|
ZeroMemory(&ti, sizeof(TOOLINFO));
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.hwnd = m_hwndName;
|
|
ti.uId = (ULONG_PTR)m_hwndName;
|
|
|
|
SendMessage(m_hwndTT, TTM_TRACKACTIVATE, FALSE, (LPARAM) &ti);
|
|
break;
|
|
|
|
case CBN_SELENDOK:
|
|
{
|
|
CHAR szBuf[COMBOBUFSIZE];
|
|
UINT uSel;
|
|
|
|
// clear the tooltip
|
|
ZeroMemory(&ti, sizeof(TOOLINFO));
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.hwnd = m_hwndName;
|
|
ti.uId = (ULONG_PTR)m_hwndName;
|
|
|
|
SendMessage(m_hwndTT, TTM_TRACKACTIVATE, FALSE, (LPARAM) &ti);
|
|
|
|
if(idmFmtFont == id)
|
|
{
|
|
uCmdID = IDM_FONTNAME;
|
|
|
|
uSel = ComboBox_GetCurSel(m_hwndName);
|
|
// if(uSel < 0)
|
|
// return hr;
|
|
|
|
ComboBox_GetLBText(m_hwndName, uSel, szBuf);
|
|
|
|
va.vt = VT_BSTR;
|
|
pvaIn = &va;
|
|
hr=HrLPSZToBSTR(szBuf, &va.bstrVal);
|
|
if (FAILED(hr))
|
|
goto Cleanup;
|
|
}
|
|
else if(idmFmtSize == id)
|
|
{
|
|
// when setting font size use:
|
|
// VT_I4: for 1 - 7 range
|
|
// VT_STRING: for -2 -> +4 range.
|
|
uCmdID = IDM_FONTSIZE;
|
|
uSel = ComboBox_GetCurSel(m_hwndSize);
|
|
if(-1 == uSel)
|
|
return hr;
|
|
va.vt = VT_I4;
|
|
va.lVal = uSel + 1;
|
|
pvaIn = &va;
|
|
}
|
|
|
|
// set focus back to Trident, call HrUIActivate() after ComboBox operations.
|
|
SetBodyFocus();
|
|
|
|
hr = ExecCommand(uCmdID, dwOpt, pvaIn);
|
|
if(FAILED(hr))
|
|
goto Cleanup;
|
|
|
|
Cleanup:
|
|
if(va.vt == VT_BSTR && va.bstrVal != NULL)
|
|
SysFreeString(va.bstrVal);
|
|
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
switch(id)
|
|
{
|
|
case idmFmtBold:
|
|
uCmdID=IDM_BOLD;
|
|
break;
|
|
|
|
case idmFmtItalic:
|
|
uCmdID=IDM_ITALIC;
|
|
break;
|
|
|
|
case idmFmtUnderline:
|
|
uCmdID=IDM_UNDERLINE;
|
|
break;
|
|
|
|
case idmAccelBullets:
|
|
case idmFmtBullets:
|
|
uCmdID=IDM_UNORDERLIST;
|
|
break;
|
|
|
|
case idmFmtNumbers:
|
|
uCmdID=IDM_ORDERLIST;
|
|
break;
|
|
|
|
case idmAccelJustify:
|
|
case idmFmtJustify:
|
|
uCmdID=IDM_JUSTIFYFULL;
|
|
break;
|
|
|
|
case idmAccelLeft:
|
|
case idmFmtLeft:
|
|
uCmdID=IDM_JUSTIFYLEFT;
|
|
break;
|
|
|
|
case idmAccelCenter:
|
|
case idmFmtCenter:
|
|
uCmdID=IDM_JUSTIFYCENTER;
|
|
break;
|
|
|
|
case idmAccelRight:
|
|
case idmFmtRight:
|
|
uCmdID=IDM_JUSTIFYRIGHT;
|
|
break;
|
|
|
|
case idmFmtBlockDirLTR:
|
|
uCmdID=IDM_BLOCKDIRLTR;
|
|
break;
|
|
|
|
case idmFmtBlockDirRTL:
|
|
uCmdID=IDM_BLOCKDIRRTL;
|
|
break;
|
|
|
|
case idmAccelDecreaseIndent:
|
|
case idmFmtDecreaseIndent:
|
|
uCmdID=IDM_OUTDENT;
|
|
|
|
break;
|
|
|
|
case idmAccelIncreaseIndent:
|
|
case idmFmtIncreaseIndent:
|
|
uCmdID=IDM_INDENT;
|
|
break;
|
|
|
|
case idmEditLink:
|
|
uCmdID=IDM_HYPERLINK;
|
|
dwOpt = MSOCMDEXECOPT_PROMPTUSER;
|
|
break;
|
|
|
|
case idmUnInsertLink:
|
|
uCmdID=IDM_UNLINK;
|
|
break;
|
|
|
|
case idmFmtInsertHLine:
|
|
uCmdID=IDM_HORIZONTALLINE;
|
|
break;
|
|
|
|
case idmInsertImage:
|
|
uCmdID=IDM_IMAGE;
|
|
dwOpt = MSOCMDEXECOPT_PROMPTUSER;
|
|
break;
|
|
|
|
case idmFmtColor1:
|
|
case idmFmtColor2:
|
|
case idmFmtColor3:
|
|
case idmFmtColor4:
|
|
case idmFmtColor5:
|
|
case idmFmtColor6:
|
|
case idmFmtColor7:
|
|
case idmFmtColor8:
|
|
case idmFmtColor9:
|
|
case idmFmtColor10:
|
|
case idmFmtColor11:
|
|
case idmFmtColor12:
|
|
case idmFmtColor13:
|
|
case idmFmtColor14:
|
|
case idmFmtColor15:
|
|
case idmFmtColor16:
|
|
{
|
|
uCmdID = IDM_FORECOLOR;
|
|
va.vt = VT_I4;
|
|
va.lVal = rgrgbColors[id-idmFmtColor1];
|
|
pvaIn = &va;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if(id >= idmFmtTagFirst && id <= idmFmtTagLast) //style tags
|
|
{
|
|
TCHAR szBuf[MAX_PATH] = {0};
|
|
GetMenuString(m_hmenuTag, id, szBuf, MAX_PATH, MF_BYCOMMAND);
|
|
Assert(*szBuf);//should not be empty
|
|
|
|
hr=HrLPSZToBSTR(szBuf, &va.bstrVal);
|
|
if (FAILED(hr))
|
|
goto error;
|
|
|
|
va.vt = VT_BSTR;
|
|
pvaIn = &va;
|
|
uCmdID = IDM_BLOCKFMT;
|
|
}
|
|
|
|
if(0 != uCmdID && m_pCmdTarget)
|
|
{
|
|
hr = ExecCommand(uCmdID, dwOpt, pvaIn);
|
|
if(FAILED(hr))
|
|
goto error;
|
|
}
|
|
|
|
error:
|
|
if(va.vt == VT_BSTR && va.bstrVal != NULL)
|
|
SysFreeString(va.bstrVal);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
HRESULT CFmtBar::ExecCommand(UINT uCmdID, DWORD dwOpt, VARIANTARG *pvaIn)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if(uCmdID && m_pCmdTarget)
|
|
hr = m_pCmdTarget->Exec(&CMDSETID_Forms3,
|
|
uCmdID,
|
|
dwOpt,
|
|
pvaIn, NULL);
|
|
return hr;
|
|
|
|
}
|
|
|
|
HRESULT CFmtBar::SetCommandTarget(LPOLECOMMANDTARGET pCmdTarget)
|
|
{
|
|
// ALERT: we don't refcount these to avoid circular counts
|
|
// as this poitner is valid during the lifetime of the formatbar
|
|
m_pCmdTarget=pCmdTarget;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT HrCreateFormatBar(HWND hwndParent, int iddlg, BOOL fSep, LPFORMATBAR *ppFmtBar)
|
|
{
|
|
LPFORMATBAR pFmtBar=0;
|
|
HRESULT hr;
|
|
|
|
if(!ppFmtBar)
|
|
return E_INVALIDARG;
|
|
|
|
*ppFmtBar=NULL;
|
|
|
|
if(!(pFmtBar=new CFmtBar(fSep)))
|
|
return E_OUTOFMEMORY;
|
|
|
|
hr=pFmtBar->Init(hwndParent, iddlg);
|
|
if(FAILED(hr))
|
|
goto error;
|
|
|
|
*ppFmtBar=pFmtBar;
|
|
pFmtBar->AddRef();
|
|
|
|
error:
|
|
ReleaseObj(pFmtBar);
|
|
return hr;
|
|
}
|
|
|
|
void CFmtBar::WMNotify(WPARAM wParam, NMHDR* pnmhdr)
|
|
{
|
|
|
|
LPNMREBARCHEVRON pnmch;
|
|
|
|
if (pnmhdr->idFrom == idcCoolbar)
|
|
{
|
|
switch (pnmhdr->code)
|
|
{
|
|
|
|
case RBN_CHEVRONPUSHED:
|
|
{
|
|
ITrackShellMenu* ptsm;
|
|
CoCreateInstance(CLSID_TrackShellMenu, NULL, CLSCTX_INPROC_SERVER, IID_ITrackShellMenu,
|
|
(LPVOID*)&ptsm);
|
|
if (!ptsm)
|
|
break;
|
|
|
|
ptsm->Initialize(0, 0, 0, SMINIT_TOPLEVEL|SMINIT_VERTICAL);
|
|
|
|
LPNMREBARCHEVRON pnmch = (LPNMREBARCHEVRON) pnmhdr;
|
|
ptsm->SetObscured(m_hwndToolbar, NULL, SMSET_TOP);
|
|
|
|
MapWindowPoints(m_hwndRebar, HWND_DESKTOP, (LPPOINT)&pnmch->rc, 2);
|
|
POINTL pt = {pnmch->rc.left, pnmch->rc.right};
|
|
ptsm->Popup(m_hwndRebar, &pt, (RECTL*)&pnmch->rc, MPPF_BOTTOM);
|
|
ptsm->Release();
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
switch(pnmhdr->code)
|
|
{
|
|
case TBN_DROPDOWN:
|
|
{
|
|
RECT rc;
|
|
POINT pt;
|
|
LPTBNOTIFY pTBN = (LPTBNOTIFY) pnmhdr;
|
|
|
|
if(pTBN->iItem == idmFmtColor)
|
|
SendMessage(m_hwndToolbar, TB_GETITEMRECT, 5, (LPARAM) &rc);
|
|
else if(pTBN->iItem == idmFmtTag)
|
|
SendMessage(m_hwndToolbar, TB_GETITEMRECT, 1, (LPARAM) &rc);
|
|
|
|
MapWindowPoints(m_hwndToolbar, NULL, (LPPOINT)&rc, 2);
|
|
pt.x=(GetWindowLong(m_hwndToolbar, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) ?rc.right : rc.left;
|
|
pt.y=rc.bottom+2;
|
|
|
|
if(pTBN->iItem == idmFmtColor)
|
|
{
|
|
CheckColor();
|
|
ColorMenu_Show(m_hmenuColor, m_hwnd, pt, NULL);
|
|
}
|
|
else
|
|
if(pTBN->iItem == idmFmtTag)
|
|
HrShowTagMenu(pt);
|
|
}
|
|
break;
|
|
|
|
case TTN_NEEDTEXT:
|
|
ProcessTooltips((LPTOOLTIPTEXTOE) pnmhdr);
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CFmtBar::OnDrawItem(LPDRAWITEMSTRUCT pdis)
|
|
{
|
|
switch(pdis->CtlType)
|
|
{
|
|
case ODT_MENU:
|
|
Color_WMDrawItem(m_hwnd, pdis);
|
|
break;
|
|
|
|
case ODT_COMBOBOX:
|
|
ComboBox_WMDrawItem(pdis);
|
|
break;
|
|
|
|
default:
|
|
AssertSz(0, "OwnerDraw type not supported");
|
|
}
|
|
}
|
|
|
|
|
|
void CFmtBar::OnMeasureItem(LPMEASUREITEMSTRUCT pmis)
|
|
{
|
|
HDC hdc;
|
|
HFONT hfontOld;
|
|
TEXTMETRIC tm;
|
|
|
|
hdc = GetDC(m_hwnd);
|
|
if(hdc)
|
|
{
|
|
switch(pmis->CtlType)
|
|
{
|
|
case ODT_MENU:
|
|
Color_WMMeasureItem(m_hwnd, hdc, pmis);
|
|
break;
|
|
|
|
case ODT_COMBOBOX:
|
|
hfontOld = (HFONT)SelectObject(hdc, (HFONT)SendMessage(m_hwndToolbar, WM_GETFONT, 0, 0));
|
|
GetTextMetrics(hdc, &tm);
|
|
SelectObject(hdc, hfontOld);
|
|
pmis->itemHeight = tm.tmHeight;
|
|
break;
|
|
|
|
default:
|
|
AssertSz(0, "OwnerDraw type not supported");
|
|
}
|
|
|
|
ReleaseDC(m_hwnd, hdc);
|
|
}
|
|
}
|
|
|
|
void Color_WMMeasureItem(HWND hwnd, HDC hdc, LPMEASUREITEMSTRUCT pmis)
|
|
{
|
|
HFONT hfontOld;
|
|
TEXTMETRIC tm;
|
|
UINT id = pmis->itemID;
|
|
TCHAR szColor[MAX_PATH]={0};
|
|
|
|
Assert (pmis->CtlType == ODT_MENU);
|
|
|
|
|
|
hfontOld = (HFONT)SelectObject(hdc, hFontGetMenuFont(hwnd));
|
|
GetTextMetrics(hdc, &tm);
|
|
SelectObject(hdc, hfontOld);
|
|
|
|
ULONG index = GETINDEX(pmis->itemData);
|
|
LoadString(g_hLocRes, index + idsColor1,
|
|
szColor, sizeof(szColor)/sizeof(TCHAR));
|
|
|
|
pmis->itemHeight = tm.tmHeight;
|
|
pmis->itemWidth = GetSystemMetrics(SM_CXMENUCHECK) +
|
|
2 * GetSystemMetrics(SM_CXBORDER) +
|
|
2 * tm.tmHeight +
|
|
(lstrlen(szColor) + 2) *tm.tmAveCharWidth;
|
|
}
|
|
|
|
// fill font name combo box
|
|
void CFmtBar::FillFontNames()
|
|
{
|
|
LOGFONT lf = {0};
|
|
HDC hdc;
|
|
|
|
// reset the contents of the combo
|
|
SendMessage(m_hwndName, CB_RESETCONTENT, 0, 0);
|
|
|
|
hdc = GetDC(NULL);
|
|
if (hdc)
|
|
{
|
|
//to enumerate all styles of all fonts for the default character set
|
|
lf.lfFaceName[0] = '\0';
|
|
lf.lfCharSet = DEFAULT_CHARSET;
|
|
|
|
EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)ExtEnumFontNamesProcEx, (LPARAM)this, 0);
|
|
ReleaseDC(NULL, hdc);
|
|
}
|
|
}
|
|
|
|
|
|
LRESULT CALLBACK CFmtBar::EditSubProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CHAR szBuf[TEMPBUFSIZE];
|
|
HWND hwndCombo = GetParent(hwnd);
|
|
LPFORMATBAR pFmtBar = NULL;
|
|
|
|
if(hwndCombo == NULL)
|
|
{
|
|
AssertSz(0, "This is bad");
|
|
return 0;
|
|
}
|
|
|
|
pFmtBar = (LPFORMATBAR)GetProp(hwnd, c_szThis);
|
|
if(pFmtBar == NULL)
|
|
{
|
|
AssertSz(0, "This is bad");
|
|
return 0;
|
|
}
|
|
|
|
*szBuf = 0;
|
|
|
|
switch (wMsg)
|
|
{
|
|
case WM_KEYDOWN:
|
|
switch(wParam)
|
|
{
|
|
case VK_ESCAPE:
|
|
pFmtBar->SetBodyFocus();
|
|
return 0;
|
|
|
|
case VK_RETURN:
|
|
if (!SendMessage(pFmtBar->m_hwndName, CB_GETDROPPEDSTATE, 0, 0))
|
|
{
|
|
ComboBox_GetText(hwnd, szBuf, sizeof(szBuf));
|
|
ComboBox_SelectString(pFmtBar->m_hwndName, -1, szBuf);
|
|
SendMessage(pFmtBar->m_hwnd, WM_COMMAND, (WPARAM)MAKELONG(idmFmtFont, CBN_SELENDOK), (LPARAM)pFmtBar->m_hwndName);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
MSG msg;
|
|
|
|
msg.lParam = lParam;
|
|
msg.wParam = wParam;
|
|
msg.message = wMsg;
|
|
msg.hwnd = hwnd;
|
|
|
|
SendMessage((HWND)SendMessage(pFmtBar->m_hwndToolbar, TB_GETTOOLTIPS, 0, 0), TTM_RELAYEVENT, 0, (LPARAM) &msg);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return CallWindowProc(pFmtBar->m_wndprocEdit, hwnd, wMsg, wParam, lParam);
|
|
}
|
|
|
|
LRESULT CALLBACK CFmtBar::ComboBoxSubProc(HWND hwnd, UINT wMsg, WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
INT nID = GetWindowID(hwnd);
|
|
WNDPROC wndprocNext;
|
|
LPFORMATBAR pFmtBar = NULL;
|
|
|
|
pFmtBar = (LPFORMATBAR)GetProp(hwnd, c_szThis);
|
|
if(pFmtBar == NULL)
|
|
{
|
|
AssertSz(0, "This is bad");
|
|
return 0;
|
|
}
|
|
|
|
|
|
switch (wMsg)
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
MSG msg;
|
|
|
|
msg.lParam = lParam;
|
|
msg.wParam = wParam;
|
|
msg.message = wMsg;
|
|
msg.hwnd = hwnd;
|
|
|
|
SendMessage((HWND)SendMessage(pFmtBar->m_hwndToolbar, TB_GETTOOLTIPS, 0, 0), TTM_RELAYEVENT, 0, (LPARAM) &msg);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (nID == idmFmtFont)
|
|
wndprocNext = pFmtBar->m_wndprocNameComboBox;
|
|
else
|
|
wndprocNext = pFmtBar->m_wndprocSizeComboBox;
|
|
return wndprocNext ? CallWindowProc(wndprocNext, hwnd, wMsg, wParam, lParam) : 0;
|
|
}
|
|
|
|
|
|
INT CALLBACK CFmtBar::ExtEnumFontNamesProcEx(ENUMLOGFONTEX *plf, NEWTEXTMETRICEX *ptm, INT nFontType, LPARAM lParam)
|
|
{
|
|
return ((CFmtBar *)lParam)->EnumFontNamesProcEx(plf, ptm, nFontType);
|
|
}
|
|
|
|
INT CFmtBar::EnumFontNamesProcEx(ENUMLOGFONTEX *plf, NEWTEXTMETRICEX *ptm, INT nFontType)
|
|
{
|
|
CFmtBar *pFmtBar;
|
|
LONG l;
|
|
|
|
// skip vertical fonts for OE
|
|
if (plf->elfLogFont.lfFaceName[0]=='@')
|
|
return TRUE;
|
|
|
|
// if the font is already listed, don't re-list it
|
|
if(ComboBox_FindStringExact(m_hwndName, -1, plf->elfLogFont.lfFaceName) != -1)
|
|
return TRUE;
|
|
|
|
l = ComboBox_AddString(m_hwndName, plf->elfLogFont.lfFaceName);
|
|
if (l!=-1)
|
|
ComboBox_SetItemData(m_hwndName, l, nFontType);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
INT CFmtBar::XFontSizeCombo(HDC hdc)
|
|
{
|
|
LONG id;
|
|
TCHAR szBuf[TEMPBUFSIZE];
|
|
*szBuf = 0;
|
|
INT iMax=0;
|
|
SIZE rSize;
|
|
|
|
for(id = idsFontSize0; id < NFONTSIZES + idsFontSize0; ++id)
|
|
{
|
|
LoadString(g_hLocRes, id, szBuf, sizeof(szBuf));
|
|
GetTextExtentPoint32 (hdc, szBuf, lstrlen(szBuf), &rSize);
|
|
if(rSize.cx > iMax)
|
|
iMax = rSize.cx;
|
|
}
|
|
return iMax + 10;
|
|
}
|
|
|
|
void CFmtBar::FillSizes()
|
|
{
|
|
LONG id;
|
|
TCHAR szBuf[TEMPBUFSIZE];
|
|
*szBuf = 0;
|
|
LRESULT lr;
|
|
|
|
// Empty the current list
|
|
SendMessage(m_hwndSize, CB_RESETCONTENT, 0, 0);
|
|
|
|
for (id = idsFontSize0; id < NFONTSIZES + idsFontSize0; ++id)
|
|
{
|
|
LoadString(g_hLocRes, id, szBuf, sizeof(szBuf));
|
|
lr = SendMessage(m_hwndSize, CB_ADDSTRING, 0, (LPARAM) szBuf);
|
|
if (lr == CB_ERR || lr == CB_ERRSPACE)
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
#define BACKGROUND 0x000000FF // bright blue
|
|
#define BACKGROUNDSEL 0x00FF00FF // bright blue
|
|
DWORD CFmtBar::FlipColor(DWORD rgb)
|
|
{
|
|
return RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb));
|
|
}
|
|
|
|
// load bitmap for true type font
|
|
HBITMAP CFmtBar::LoadDIBBitmap(int id)
|
|
{
|
|
HDC hdc;
|
|
HRSRC h;
|
|
DWORD FAR * p;
|
|
LPSTR lpBits;
|
|
HANDLE hRes;
|
|
LPBITMAPINFOHEADER lpBitmapInfo;
|
|
LPVOID lpRes;
|
|
DWORD cbRes;
|
|
int numcolors;
|
|
DWORD rgbSelected;
|
|
DWORD rgbUnselected;
|
|
HBITMAP hbm;
|
|
|
|
rgbSelected = FlipColor(GetSysColor(COLOR_HIGHLIGHT));
|
|
rgbUnselected = FlipColor(GetSysColor(COLOR_WINDOW));
|
|
|
|
h = FindResource(g_hLocRes, MAKEINTRESOURCE(id), RT_BITMAP);
|
|
hRes = LoadResource(g_hLocRes, h);
|
|
|
|
/* Lock the bitmap and get a pointer to the color table. */
|
|
lpRes = LockResource(hRes);
|
|
|
|
if (!lpRes)
|
|
return NULL;
|
|
|
|
/* Copy the resource since we shouldn't modify the original */
|
|
cbRes = SizeofResource(g_hLocRes, h);
|
|
if(!MemAlloc((LPVOID *)&lpBitmapInfo, LOWORD(cbRes)))
|
|
return NULL;
|
|
CopyMemory(lpBitmapInfo, lpRes, cbRes);
|
|
|
|
p = (DWORD FAR *)((LPSTR)(lpBitmapInfo) + lpBitmapInfo->biSize);
|
|
|
|
/* Search for the Solid Blue entry and replace it with the current
|
|
* background RGB.
|
|
*/
|
|
numcolors = 16;
|
|
|
|
while (numcolors-- > 0)
|
|
{
|
|
if (*p == BACKGROUND)
|
|
*p = rgbUnselected;
|
|
else if (*p == BACKGROUNDSEL)
|
|
*p = rgbSelected;
|
|
p++;
|
|
}
|
|
|
|
/* First skip over the header structure */
|
|
lpBits = (LPSTR)(lpBitmapInfo + 1);
|
|
|
|
/* Skip the color table entries, if any */
|
|
lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
|
|
|
|
/* Create a color bitmap compatible with the display device */
|
|
hdc = GetDC(NULL);
|
|
hbm = CreateDIBitmap(hdc, lpBitmapInfo, (DWORD)CBM_INIT, lpBits,
|
|
(LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS);
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
SafeMemFree(lpBitmapInfo);
|
|
FreeResource(hRes);
|
|
|
|
return hbm;
|
|
}
|
|
|
|
VOID CFmtBar::AddToolTip(HWND hwndToolTips, HWND hwnd, UINT idRsrc)
|
|
{
|
|
TOOLINFO ti = { 0 };
|
|
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.uFlags = TTF_IDISHWND;
|
|
|
|
ti.hwnd = hwnd;
|
|
ti.uId = (UINT_PTR) hwnd;
|
|
GetWindowRect(hwnd, &ti.rect);
|
|
ti.hinst = g_hLocRes;
|
|
ti.lpszText = (LPSTR) IntToPtr(idRsrc);
|
|
|
|
SendMessage(hwndToolTips, TTM_ADDTOOL, 0, (LPARAM) &ti);
|
|
}
|
|
|
|
|
|
HRESULT CFmtBar::TranslateAcclerator(LPMSG lpMsg)
|
|
{
|
|
HWND hwndFocus;
|
|
|
|
if (m_hwnd &&
|
|
lpMsg->message==WM_KEYDOWN &&
|
|
((lpMsg->wParam==VK_RETURN || lpMsg->wParam==VK_ESCAPE)))
|
|
{
|
|
hwndFocus=GetFocus();
|
|
|
|
// if focus is on the size combolist or in the edit of the
|
|
// name combobox, then we translate the messages to the window.
|
|
if(hwndFocus==::GetWindow(m_hwndName, GW_CHILD) ||
|
|
hwndFocus==m_hwndSize)
|
|
{
|
|
TranslateMessage(lpMsg);
|
|
DispatchMessage(lpMsg);
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
BOOL CFmtBar::FBodyHasFocus()
|
|
{
|
|
NMHDR nmhdr;
|
|
|
|
nmhdr.hwndFrom=m_hwnd;
|
|
nmhdr.idFrom=GetDlgCtrlID(m_hwnd);
|
|
nmhdr.code=FBN_BODYHASFOCUS;
|
|
|
|
return (0 != SendMessage(GetParent(m_hwnd), WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr));
|
|
}
|
|
|
|
void CFmtBar::SetBodyFocus()
|
|
{
|
|
NMHDR nmhdr;
|
|
|
|
nmhdr.hwndFrom=m_hwnd;
|
|
nmhdr.idFrom=GetDlgCtrlID(m_hwnd);
|
|
nmhdr.code=FBN_BODYSETFOCUS;
|
|
|
|
SendMessage(GetParent(m_hwnd), WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr);
|
|
}
|
|
|
|
|
|
|
|
void CFmtBar::ComboBox_WMDrawItem(LPDRAWITEMSTRUCT pdis)
|
|
{
|
|
HDC hdc,
|
|
hdcMem;
|
|
DWORD rgbBack, rgbText;
|
|
char szFace[LF_FACESIZE + 10];
|
|
HBITMAP hbmOld;
|
|
int dy,
|
|
x;
|
|
INT nFontType = (INT) pdis->itemData;
|
|
SIZE size;
|
|
TOOLINFO ti;
|
|
RECT rc;
|
|
|
|
Assert(pdis->CtlID == idmFmtFont);
|
|
hdc = pdis->hDC;
|
|
|
|
if (pdis->itemState & ODS_SELECTED)
|
|
{
|
|
rgbBack = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
|
|
rgbText = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
else
|
|
{
|
|
rgbBack = SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
|
|
rgbText = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
|
|
}
|
|
|
|
SendMessage(pdis->hwndItem, CB_GETLBTEXT, pdis->itemID,
|
|
(LPARAM)(LPSTR)szFace);
|
|
ExtTextOut(hdc, pdis->rcItem.left + dxFormatFontBitmap,
|
|
pdis->rcItem.top, ETO_OPAQUE, &pdis->rcItem,
|
|
szFace, lstrlen(szFace), NULL);
|
|
|
|
// if selected, see if it is clipped, so that we know to show a tooltip
|
|
if ((pdis->itemState & ODS_SELECTED) &&
|
|
GetTextExtentPoint32(hdc, szFace, lstrlen(szFace), &size) &&
|
|
size.cx + dxFormatFontBitmap >= pdis->rcItem.right)
|
|
{
|
|
ZeroMemory(&ti, sizeof(TOOLINFO));
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.hwnd = m_hwndName;
|
|
ti.uId = (UINT_PTR)m_hwndName;
|
|
ti.lpszText = szFace;
|
|
|
|
SendMessage(m_hwndName, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
|
|
|
|
SendMessage(m_hwndTT, TTM_UPDATETIPTEXT, 0, (LPARAM)&ti);
|
|
SendMessage(m_hwndTT, TTM_TRACKPOSITION, 0, MAKELPARAM(rc.left + pdis->rcItem.left + dxFormatFontBitmap,
|
|
rc.top + pdis->rcItem.top));
|
|
SendMessage(m_hwndTT, TTM_TRACKACTIVATE, TRUE, (LPARAM) &ti);
|
|
}
|
|
else
|
|
SendMessage(m_hwndTT, TTM_TRACKACTIVATE, FALSE, (LPARAM) &ti);
|
|
|
|
|
|
hdcMem = CreateCompatibleDC(hdc);
|
|
if (hdcMem)
|
|
{
|
|
if (m_hbmName)
|
|
{
|
|
hbmOld = (HBITMAP)SelectObject(hdcMem, m_hbmName);
|
|
|
|
x = dxFormatFontBitmap;
|
|
if (nFontType & TRUETYPE_FONTTYPE)
|
|
x = 0;
|
|
else if ((nFontType & (PRINTER_FONTTYPE | DEVICE_FONTTYPE)) ==
|
|
(PRINTER_FONTTYPE | DEVICE_FONTTYPE))
|
|
x = dxFormatFontBitmap;
|
|
else
|
|
goto SkipBlt;
|
|
|
|
dy = ((pdis->rcItem.bottom - pdis->rcItem.top) -
|
|
dyFormatFontBitmap) / 2;
|
|
|
|
BitBlt(hdc, pdis->rcItem.left, pdis->rcItem.top + dy,
|
|
dxFormatFontBitmap, dyFormatFontBitmap, hdcMem,
|
|
x, pdis->itemState & ODS_SELECTED ? dyFormatFontBitmap: 0,
|
|
SRCCOPY);
|
|
|
|
SkipBlt:
|
|
SelectObject(hdcMem, hbmOld);
|
|
}
|
|
DeleteDC(hdcMem);
|
|
}
|
|
|
|
SetTextColor(hdc, rgbText);
|
|
SetBkColor(hdc, rgbBack);
|
|
}
|
|
|
|
|
|
void Color_WMDrawItem(HWND hwnd, LPDRAWITEMSTRUCT pdis)
|
|
{
|
|
HBRUSH hbr;
|
|
WORD dx, dy, dxBorder;
|
|
RECT rc;
|
|
TCHAR szColor[MAX_PATH]={0};
|
|
DWORD rgbBack, rgbText;
|
|
UINT id = pdis->itemID;
|
|
ULONG index = 0;
|
|
|
|
Assert (pdis->CtlType == ODT_MENU);
|
|
|
|
if(pdis->itemState&ODS_SELECTED)
|
|
{
|
|
rgbBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
|
|
rgbText = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
else
|
|
{
|
|
rgbBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_MENU));
|
|
rgbText = SetTextColor(pdis->hDC, GetSysColor(COLOR_MENUTEXT));
|
|
}
|
|
|
|
// compute coordinates of color rectangle and draw it
|
|
dxBorder = (WORD) GetSystemMetrics(SM_CXBORDER);
|
|
dx = (WORD) GetSystemMetrics(SM_CXMENUCHECK);
|
|
|
|
dy = (WORD) GetSystemMetrics(SM_CYBORDER);
|
|
rc.top = pdis->rcItem.top + dy;
|
|
rc.bottom = pdis->rcItem.bottom - dy;
|
|
rc.left = pdis->rcItem.left + dx;
|
|
rc.right = rc.left + 2 * (rc.bottom - rc.top);
|
|
|
|
index = GETINDEX(pdis->itemData);
|
|
LoadString(g_hLocRes, index + idsColor1,
|
|
szColor, sizeof(szColor)/sizeof(TCHAR));
|
|
|
|
SelectObject(pdis->hDC, hFontGetMenuFont(hwnd));
|
|
|
|
ExtTextOut(pdis->hDC, rc.right + 2*dxBorder,
|
|
pdis->rcItem.top, ETO_OPAQUE, &pdis->rcItem,
|
|
szColor, lstrlen(szColor), NULL);
|
|
|
|
|
|
hbr = CreateSolidBrush((DWORD)(pdis->itemData & 0x00ffffff));
|
|
|
|
if (hbr)
|
|
{
|
|
hbr = (HBRUSH)SelectObject (pdis->hDC, hbr);
|
|
Rectangle(pdis->hDC, rc.left, rc.top, rc.right, rc.bottom);
|
|
DeleteObject(SelectObject(pdis->hDC, hbr));
|
|
}
|
|
|
|
// draw radio check.
|
|
if (pdis->itemState&ODS_CHECKED)
|
|
{
|
|
WORD left, top, radius;
|
|
|
|
if(pdis->itemState&ODS_SELECTED)
|
|
hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
else
|
|
hbr = CreateSolidBrush(GetSysColor(COLOR_MENUTEXT));
|
|
|
|
if (hbr)
|
|
{
|
|
hbr = (HBRUSH)SelectObject (pdis->hDC, hbr);
|
|
#ifndef WIN16
|
|
left = (WORD) (pdis->rcItem.left + GetSystemMetrics(SM_CXMENUCHECK) / 2);
|
|
#else
|
|
left = pdis->rcItem.left + LOWORD( GetMenuCheckMarkDimensions() ) / 2;
|
|
#endif
|
|
top = (WORD) (rc.top + (rc.bottom - rc.top) / 2);
|
|
#ifndef WIN16
|
|
radius = (WORD) (GetSystemMetrics(SM_CXMENUCHECK) / 4);
|
|
#else
|
|
radius = LOWORD( GetMenuCheckMarkDimensions() ) / 4;
|
|
#endif
|
|
Ellipse(pdis->hDC, left-radius, top-radius, left+radius, top+radius);
|
|
DeleteObject(SelectObject(pdis->hDC, hbr));
|
|
}
|
|
}
|
|
|
|
SetTextColor(pdis->hDC, rgbText);
|
|
SetBkColor(pdis->hDC, rgbBack);
|
|
}
|
|
|
|
|
|
HRESULT CFmtBar::Show()
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (m_fVisible)
|
|
return S_OK;
|
|
|
|
hr = AttachWin();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
ShowWindow(m_hwnd, SW_SHOW);
|
|
m_fVisible=1;
|
|
Update();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFmtBar::Hide()
|
|
{
|
|
if (!m_fVisible)
|
|
return S_OK;
|
|
|
|
ShowWindow(m_hwnd, SW_HIDE);
|
|
m_fVisible=0;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFmtBar::GetWindow(HWND *pHwnd)
|
|
{
|
|
*pHwnd = m_hwnd;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFmtBar::AttachWin()
|
|
{
|
|
HWND hwnd;
|
|
WNDCLASS wc;
|
|
|
|
if (m_hwnd) // already created
|
|
return S_OK;
|
|
|
|
if (FAILED(CreateColorMenu(idmFmtColor1, &m_hmenuColor)))
|
|
return E_FAIL;
|
|
|
|
if (!GetClassInfo(g_hLocRes, c_szFmtBarClass, &wc))
|
|
{
|
|
ZeroMemory(&wc, sizeof(WNDCLASS));
|
|
|
|
wc.style = CS_BYTEALIGNWINDOW;
|
|
wc.lpfnWndProc = CFmtBar::ExtWndProc;
|
|
wc.hInstance = g_hLocRes;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
|
wc.lpszClassName = c_szFmtBarClass;
|
|
if (!RegisterClass(&wc))
|
|
return E_FAIL;
|
|
}
|
|
|
|
hwnd = CreateWindowEx(WS_EX_CONTROLPARENT,
|
|
c_szFmtBarClass, NULL,
|
|
WS_CHILD|WS_CLIPCHILDREN,
|
|
0, 0, 0, 0,
|
|
m_hwndParent, (HMENU)IntToPtr(m_idd), g_hLocRes, (LPVOID)this);
|
|
|
|
if(!hwnd)
|
|
return E_OUTOFMEMORY;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HFONT hFontGetMenuFont(HWND hwnd)
|
|
{
|
|
NMHDR nmhdr;
|
|
|
|
nmhdr.hwndFrom=hwnd;
|
|
nmhdr.idFrom=GetDlgCtrlID(hwnd);
|
|
nmhdr.code=FBN_GETMENUFONT;
|
|
|
|
return (HFONT)SendMessage(GetParent(hwnd), WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT CFmtBar::_SetToolbarBitmaps()
|
|
{
|
|
// release toolbar references
|
|
SendMessage(m_hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)NULL);
|
|
SendMessage(m_hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)NULL);
|
|
|
|
_FreeImageLists();
|
|
|
|
// set the normal imagelist
|
|
m_himl = LoadMappedToolbarBitmap(g_hLocRes, idbFormatBar, dxToolbarButton);
|
|
if (!m_himl)
|
|
return E_OUTOFMEMORY;
|
|
|
|
SendMessage(m_hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)m_himl);
|
|
|
|
// the the HOT imagelist
|
|
m_himlHot = LoadMappedToolbarBitmap(g_hLocRes, idbFormatBarHot, dxToolbarButton);
|
|
if (!m_himlHot)
|
|
return E_OUTOFMEMORY;
|
|
|
|
SendMessage(m_hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)m_himlHot);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFmtBar::_FreeImageLists()
|
|
{
|
|
if (m_himlHot)
|
|
{
|
|
ImageList_Destroy(m_himlHot);
|
|
m_himlHot = NULL;
|
|
}
|
|
|
|
if (m_himl)
|
|
{
|
|
ImageList_Destroy(m_himl);
|
|
m_himl = NULL;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|