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.
1480 lines
40 KiB
1480 lines
40 KiB
/******************************************************************************/
|
|
/* */
|
|
/* Class Implementations in this file */
|
|
/* CFloatImgToolWnd */
|
|
/* CImgToolWnd */
|
|
/* CToolboxWnd */
|
|
/* CTool */
|
|
/* */
|
|
/******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
#include "global.h"
|
|
#include "pbrush.h"
|
|
#include "pbrusfrm.h"
|
|
#include "pbrusvw.h"
|
|
#include "ipframe.h"
|
|
#include "minifwnd.h"
|
|
#include "bmobject.h"
|
|
#include "imgsuprt.h"
|
|
#include "imgwnd.h"
|
|
#include "imgwell.h"
|
|
#include "imgtools.h"
|
|
#include "toolbox.h"
|
|
#include "imgcolor.h"
|
|
#include "docking.h"
|
|
#include "t_Text.h"
|
|
|
|
#define TRYANYTHING
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static CHAR BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(CToolboxWnd, CControlBar)
|
|
|
|
#include "memtrace.h"
|
|
|
|
CImgToolWnd* NEAR g_pImgToolWnd = NULL;
|
|
|
|
#define BPR(br, rop) \
|
|
{ dc.SelectObject((br)); \
|
|
dc.PatBlt(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, rop); }
|
|
|
|
#define iidmMac ( sizeof (rgidm) / sizeof (rgidm[0]) )
|
|
|
|
static UINT NEAR rgidm [] =
|
|
{
|
|
IDMB_PICKRGNTOOL,
|
|
IDMB_PICKTOOL,
|
|
|
|
IDMB_ERASERTOOL,
|
|
IDMB_FILLTOOL,
|
|
|
|
IDMY_PICKCOLOR,
|
|
IDMB_ZOOMTOOL,
|
|
|
|
IDMB_PENCILTOOL,
|
|
IDMB_CBRUSHTOOL,
|
|
|
|
IDMB_AIRBSHTOOL,
|
|
IDMX_TEXTTOOL,
|
|
|
|
IDMB_LINETOOL,
|
|
IDMB_CURVETOOL,
|
|
|
|
IDMB_RECTTOOL,
|
|
IDMB_POLYGONTOOL,
|
|
|
|
IDMB_ELLIPSETOOL,
|
|
IDMB_RNDRECTTOOL
|
|
};
|
|
|
|
/******************************************************************************/
|
|
|
|
BEGIN_MESSAGE_MAP(CImgToolWnd, CToolboxWnd)
|
|
ON_WM_SYSCOLORCHANGE()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_PAINT()
|
|
ON_WM_KEYDOWN()
|
|
ON_WM_KEYUP()
|
|
ON_WM_CHAR()
|
|
ON_WM_NCHITTEST()
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
HTHEME SafeOpenThemeData(HWND hwnd, LPCWSTR pszClassList)
|
|
{
|
|
__try
|
|
{
|
|
return OpenThemeData(hwnd, pszClassList);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CImgToolWnd::Create(const TCHAR* pWindowName, DWORD dwStyle,
|
|
const RECT& rect, const POINT& btnSize, WORD wWide,
|
|
CWnd* pParentWnd, BOOL bDkRegister)
|
|
{
|
|
if (! CToolboxWnd::Create( pWindowName, dwStyle, rect,
|
|
btnSize, NUM_TOOLS_WIDE, pParentWnd, IDB_IMGTOOLS ))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for (int iidm = 0; iidm < iidmMac; iidm += 1)
|
|
{
|
|
CTool* pTool = new CTool(this, (WORD)rgidm[iidm], iidm, TS_CMD | TS_STICKY,
|
|
rgidm[iidm] == CImgTool::GetCurrentID() ? TF_DOWN : 0);
|
|
|
|
if (pTool == NULL)
|
|
{
|
|
DestroyWindow();
|
|
return FALSE;
|
|
}
|
|
AddTool(pTool);
|
|
|
|
}
|
|
|
|
|
|
m_nOffsetX = m_btnsize.x / 5;
|
|
m_nOffsetY = m_btnsize.y / 5;
|
|
|
|
CSize size = GetSize();
|
|
|
|
MoveWindow( rect.left, rect.top, size.cx, size.cy );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
//
|
|
|
|
void CImgToolWnd::OnSysColorChange()
|
|
{
|
|
CToolboxWnd::OnSysColorChange();
|
|
InvalidateRect(NULL, FALSE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int CImgToolWnd::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
|
|
{
|
|
CRect rect;
|
|
|
|
CTool* pTool = ToolFromPoint( &rect, &point );
|
|
|
|
if (pTool != NULL)
|
|
{
|
|
int nHit = pTool->m_wID;
|
|
|
|
if (pTI != NULL)
|
|
{
|
|
pTI->hwnd = m_hWnd;
|
|
pTI->uId = nHit;
|
|
pTI->rect = rect;
|
|
pTI->lpszText = LPSTR_TEXTCALLBACK;
|
|
}
|
|
|
|
return nHit;
|
|
}
|
|
|
|
return -1; // not found
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CImgToolWnd::OnUpdateCmdUI( CFrameWnd* pTarget, BOOL bDisableIfNoHndler )
|
|
{
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
CSize CImgToolWnd::CalcFixedLayout( BOOL bStretch, BOOL bHorz )
|
|
{
|
|
#ifdef TRYANYTHING
|
|
return GetSize();
|
|
#else
|
|
CSize size = CControlBar::CalcFixedLayout( bStretch, bHorz );
|
|
|
|
CSize sizeBar = GetSize();
|
|
|
|
size.cx = sizeBar.cx;
|
|
return size;
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
UINT CImgToolWnd::OnNcHitTest(CPoint point)
|
|
{
|
|
return CToolboxWnd::OnNcHitTest(point);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
CSize CImgToolWnd::GetSize()
|
|
{
|
|
// Leave room in the toolbox for the brushes...
|
|
CRect clientRect;
|
|
CRect windowRect;
|
|
CSize sizeDiff;
|
|
|
|
GetWindowRect( &windowRect );
|
|
GetClientRect( &clientRect );
|
|
|
|
sizeDiff = windowRect.Size() - clientRect.Size();
|
|
int nTools = GetToolCount();
|
|
|
|
clientRect.right = m_btnsize.x * NUM_TOOLS_WIDE + m_nOffsetX * 2;
|
|
clientRect.bottom = (nTools / NUM_TOOLS_WIDE + (!!(nTools % NUM_TOOLS_WIDE)))
|
|
* m_btnsize.y + m_nOffsetY * 2;
|
|
|
|
m_rcTools.left = m_nOffsetX;
|
|
m_rcTools.top = m_nOffsetY;
|
|
m_rcTools.right = clientRect.right - m_nOffsetX;
|
|
m_rcTools.bottom = clientRect.bottom - m_nOffsetY;
|
|
|
|
m_rcBrushes.left = clientRect.left + (4 + m_nOffsetX);
|
|
m_rcBrushes.top = clientRect.bottom;
|
|
m_rcBrushes.right = clientRect.right - (4 + m_nOffsetX);
|
|
m_rcBrushes.bottom = clientRect.bottom + 66;
|
|
|
|
clientRect.bottom += m_rcBrushes.Height() + m_nOffsetY;
|
|
|
|
return clientRect.Size() + sizeDiff;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CImgToolWnd::OnLButtonDown(UINT nFlags, CPoint pt)
|
|
{
|
|
BOOL bInBrushes = m_rcBrushes.PtInRect(pt);
|
|
|
|
if (bInBrushes)
|
|
{
|
|
CRect optionsRect = m_rcBrushes;
|
|
|
|
optionsRect.InflateRect(-1, -1);
|
|
pt -= (CSize)optionsRect.TopLeft();
|
|
|
|
CImgTool::GetCurrent()->OnClickOptions(this, optionsRect, pt);
|
|
}
|
|
else
|
|
CToolboxWnd::OnLButtonDown(nFlags, pt);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CImgToolWnd::InvalidateOptions(BOOL bErase)
|
|
{
|
|
// NOTE: bErase is now ignored since we do drawing off-screen and
|
|
// blt the whole thing...
|
|
|
|
CRect optionsRect = m_rcBrushes;
|
|
optionsRect.InflateRect(-1, -1);
|
|
|
|
InvalidateRect(&optionsRect, FALSE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CImgToolWnd::OnLButtonDblClk(UINT nFlags, CPoint pt)
|
|
{
|
|
CToolboxWnd::OnLButtonDblClk(nFlags, pt);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CImgToolWnd::OnRButtonDown(UINT nFlags, CPoint pt)
|
|
{
|
|
CToolboxWnd::OnRButtonDown(nFlags, pt);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CImgToolWnd::OnEraseBkgnd( CDC* pDC )
|
|
{
|
|
CRect rect;
|
|
GetClientRect( rect );
|
|
pDC->FillRect( rect, GetSysBrush( COLOR_BTNFACE ) );
|
|
|
|
return CControlBar::OnEraseBkgnd( pDC );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CImgToolWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
|
|
if (dc.m_hDC == NULL)
|
|
{
|
|
theApp.SetGdiEmergency();
|
|
return;
|
|
}
|
|
|
|
if (CImgWnd::c_pImgWndCur == NULL)
|
|
{
|
|
// Chances are, we're are going to be hidden soon, so don't
|
|
// bother painting...
|
|
return;
|
|
}
|
|
|
|
DrawButtons(dc, &dc.m_ps.rcPaint);
|
|
|
|
ASSERT(CImgWnd::c_pImgWndCur->m_pImg != NULL);
|
|
|
|
// Brush Shapes
|
|
if (!(m_rcBrushes & dc.m_ps.rcPaint).IsRectEmpty())
|
|
{
|
|
Draw3dRect(dc.m_hDC, &m_rcBrushes );
|
|
CRect optionsRect = m_rcBrushes;
|
|
optionsRect.InflateRect(-1, -1);
|
|
|
|
CRect rc(0, 0, optionsRect.Width(), optionsRect.Height());
|
|
CDC memDC;
|
|
CBitmap memBM;
|
|
|
|
if (!memDC.CreateCompatibleDC(&dc) ||
|
|
!memBM.CreateCompatibleBitmap(&dc, rc.right, rc.bottom))
|
|
{
|
|
theApp.SetGdiEmergency();
|
|
return;
|
|
}
|
|
CBitmap* pOldBitmap = memDC.SelectObject(&memBM);
|
|
|
|
CBrush* pOldBrush = memDC.SelectObject(GetSysBrush( COLOR_BTNFACE ));
|
|
|
|
memDC.PatBlt(0, 0, rc.right, rc.bottom, PATCOPY);
|
|
|
|
CRect rcPaint = dc.m_ps.rcPaint;
|
|
rcPaint.OffsetRect(-optionsRect.left, -optionsRect.top);
|
|
|
|
CImgTool::GetCurrent()->OnPaintOptions(&memDC, rcPaint, rc);
|
|
|
|
dc.BitBlt(optionsRect.left, optionsRect.top, optionsRect.Width(),
|
|
optionsRect.Height(), &memDC, 0, 0, SRCCOPY);
|
|
|
|
memDC.SelectObject(pOldBitmap);
|
|
memDC.SelectObject(pOldBrush);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CImgToolWnd::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
switch (pMsg->message)
|
|
{
|
|
case WM_KEYDOWN:
|
|
case WM_KEYUP:
|
|
case WM_CHAR:
|
|
if (CImgWnd::c_pImgWndCur != NULL)
|
|
{
|
|
pMsg->hwnd = CImgWnd::c_pImgWndCur->m_hWnd;
|
|
return CImgWnd::c_pImgWndCur->PreTranslateMessage(pMsg);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
return CToolboxWnd::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// default button size
|
|
|
|
const POINT NEAR CToolboxWnd::ptDefButton = { 26, 26 };
|
|
|
|
/*DK*/
|
|
BEGIN_MESSAGE_MAP(CToolboxWnd, CControlBar)
|
|
ON_WM_SYSCOLORCHANGE()
|
|
ON_WM_PAINT()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_CLOSE()
|
|
ON_WM_DESTROY()
|
|
ON_WM_WININICHANGE()
|
|
ON_WM_KEYDOWN()
|
|
ON_MESSAGE(TM_TOOLDOWN, OnToolDown)
|
|
ON_MESSAGE(TM_TOOLUP, OnToolUp)
|
|
ON_MESSAGE(WM_THEMECHANGED, OnThemeChanged)
|
|
/*DK*/
|
|
// ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
|
|
END_MESSAGE_MAP()
|
|
|
|
/******************************************************************************/
|
|
|
|
CToolboxWnd::CToolboxWnd()
|
|
{
|
|
m_Tools = new CObArray;
|
|
m_bmStuck = NULL;
|
|
m_bmPushed = NULL;
|
|
m_bmPopped = NULL;
|
|
m_tCapture = NULL;
|
|
m_bInside = FALSE;
|
|
m_nOffsetX = 0;
|
|
m_nOffsetY = 0;
|
|
m_pLastHot = 0;
|
|
m_hTheme = 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
CToolboxWnd::~CToolboxWnd()
|
|
{
|
|
if (m_bmStuck != NULL)
|
|
delete m_bmStuck;
|
|
|
|
if (m_bmPushed != NULL)
|
|
delete m_bmPushed;
|
|
|
|
if (m_bmPopped != NULL)
|
|
delete m_bmPopped;
|
|
|
|
if (m_Tools != NULL)
|
|
{
|
|
int nTools = (int)m_Tools->GetSize();
|
|
|
|
for (int iTool = 0; iTool < nTools; iTool += 1)
|
|
{
|
|
CTool* pTool = (CTool*)m_Tools->GetAt(iTool);
|
|
delete pTool;
|
|
}
|
|
|
|
delete m_Tools;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CToolboxWnd::Create(const TCHAR FAR* lpWindowName,
|
|
DWORD dwStyle, const RECT& rect,
|
|
const POINT& btnsize /* = ptDefButton */, WORD wWide /* = 1 */,
|
|
CWnd* pParentWnd /* = NULL */, int nImageWellID /* = 0 */)
|
|
{
|
|
// This routine is a lot more complicated than the typical Create, so
|
|
// because (1) we aren't a built-in Windows window type, and (2) we
|
|
// want to specify the client size with the btnsize and wWide parameters.
|
|
// (We ignore the width, height of the rect parameter.)
|
|
|
|
if (nImageWellID != 0 && !m_imageWell.Load(nImageWellID, CSize(16, 16)))
|
|
return FALSE;
|
|
|
|
// save the style
|
|
m_dwStyle = (UINT)dwStyle | CBRS_TOOLTIPS | CBRS_FLYBY;
|
|
|
|
DWORD dwS = (m_dwStyle & ~WS_VISIBLE);
|
|
|
|
CRect t = rect;
|
|
|
|
t.right = t.left + 20;
|
|
t.bottom = t.top + 20;
|
|
|
|
BOOL bRet = CControlBar::Create( NULL, lpWindowName, dwS, t, pParentWnd,
|
|
ID_VIEW_TOOL_BOX );
|
|
if (! bRet)
|
|
return FALSE;
|
|
|
|
m_wWide = wWide;
|
|
m_btnsize = btnsize;
|
|
|
|
#ifdef TRYANYTHING
|
|
SizeByButtons( -1, TRUE );
|
|
#else
|
|
SizeByButtons( 0 );
|
|
#endif
|
|
|
|
m_hTheme = SafeOpenThemeData(GetSafeHwnd(), L"toolbar");
|
|
|
|
if (! DrawStockBitmaps())
|
|
{
|
|
DestroyWindow();
|
|
return FALSE;
|
|
}
|
|
|
|
if (dwStyle & WS_VISIBLE)
|
|
{
|
|
ShowWindow(SW_SHOW);
|
|
UpdateWindow();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// private DrawStockBitmaps:
|
|
// Draws the three states of button, given the desired button size of this
|
|
// CToolboxWnd. These have no graphic on them; the buttons have bitmap
|
|
// glyphs to be added to these blank forms.
|
|
//
|
|
// The three states:
|
|
// m_bmPopped This is the normal look of a button. Note that this is
|
|
// also used as the basis of a grayed (disabled) button, by
|
|
// changing how the button's glyph is drawn on it.
|
|
// m_bmPushed This is the button-down state for non-sticky tools (tools
|
|
// that pop back out as soon as you let go.
|
|
// m_bmStuck This is the button-down state for sticky tools. This has
|
|
// a distinct look that is more easily visible, per UISG.
|
|
//
|
|
|
|
BOOL CToolboxWnd::DrawStockBitmaps()
|
|
{
|
|
CWindowDC wdc(this);
|
|
if (wdc.m_hDC == NULL)
|
|
{
|
|
theApp.SetGdiEmergency(TRUE);
|
|
return FALSE;
|
|
}
|
|
|
|
CBitmap* obm;
|
|
CBrush* obr;
|
|
CRect rc;
|
|
CDC dc;
|
|
|
|
if (!dc.CreateCompatibleDC(&wdc))
|
|
{
|
|
theApp.SetGdiEmergency(TRUE);
|
|
return FALSE;
|
|
}
|
|
|
|
obr = dc.SelectObject(GetSysBrush(COLOR_WINDOWFRAME));
|
|
|
|
// bmPopped:
|
|
//
|
|
if (m_bmPopped)
|
|
delete m_bmPopped;
|
|
m_bmPopped = new CBitmap;
|
|
if (!m_bmPopped->CreateCompatibleBitmap(&wdc, m_btnsize.x, m_btnsize.y))
|
|
{
|
|
theApp.SetMemoryEmergency(TRUE);
|
|
return FALSE;
|
|
}
|
|
obm = dc.SelectObject(m_bmPopped);
|
|
rc = CRect(0, 0, m_btnsize.x, m_btnsize.y);
|
|
BPR(GetSysBrush(COLOR_WINDOWFRAME), PATCOPY);
|
|
#ifdef OLDBUTTONS
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNSHADOW), PATCOPY);
|
|
#endif
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNHIGHLIGHT), PATCOPY);
|
|
rc.left++; rc.top++;
|
|
BPR(GetSysBrush(COLOR_BTNSHADOW), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNFACE), PATCOPY);
|
|
|
|
// bmPushed:
|
|
//
|
|
if (m_bmPushed)
|
|
delete m_bmPushed;
|
|
m_bmPushed = new CBitmap;
|
|
if (!m_bmPushed->CreateCompatibleBitmap(&wdc, m_btnsize.x, m_btnsize.y))
|
|
{
|
|
theApp.SetMemoryEmergency(TRUE);
|
|
return FALSE;
|
|
}
|
|
dc.SelectObject(m_bmPushed);
|
|
rc = CRect(0, 0, m_btnsize.x, m_btnsize.y);
|
|
#ifndef OLDBUTTONS
|
|
BPR(GetSysBrush(COLOR_BTNHIGHLIGHT), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_WINDOWFRAME), PATCOPY);
|
|
rc.left++; rc.top++;
|
|
BPR(GetSysBrush(COLOR_BTNFACE), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNSHADOW), PATCOPY);
|
|
rc.left++; rc.top++;
|
|
BPR(GetSysBrush(COLOR_BTNFACE), PATCOPY);
|
|
#else
|
|
BPR(GetSysBrush(COLOR_WINDOWFRAME), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNSHADOW), PATCOPY);
|
|
rc.left += 2; rc.top += 2;
|
|
BPR(GetSysBrush(COLOR_BTNFACE), PATCOPY);
|
|
#endif
|
|
|
|
// bmStuck:
|
|
//
|
|
if (m_bmStuck)
|
|
delete m_bmStuck;
|
|
m_bmStuck = new CBitmap;
|
|
if (!m_bmStuck->CreateCompatibleBitmap(&wdc, m_btnsize.x, m_btnsize.y))
|
|
{
|
|
theApp.SetMemoryEmergency(TRUE);
|
|
return FALSE;
|
|
}
|
|
dc.SelectObject(m_bmStuck);
|
|
rc = CRect(0, 0, m_btnsize.x, m_btnsize.y);
|
|
#ifndef OLDBUTTONS
|
|
BPR(GetSysBrush(COLOR_BTNHIGHLIGHT), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_WINDOWFRAME), PATCOPY);
|
|
rc.left++; rc.top++;
|
|
BPR(GetSysBrush(COLOR_BTNFACE), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNSHADOW), PATCOPY);
|
|
rc.left++; rc.top++;
|
|
#else
|
|
BPR(GetSysBrush(COLOR_WINDOWFRAME), PATCOPY);
|
|
rc.right--; rc.bottom--;
|
|
BPR(GetSysBrush(COLOR_BTNSHADOW), PATCOPY);
|
|
rc.left += 2; rc.top += 2;
|
|
#endif
|
|
|
|
dc.SelectObject(GetHalftoneBrush());
|
|
#ifdef OLDBUTTONS
|
|
dc.SetTextColor(RGB(255, 255, 255));
|
|
dc.SetBkColor(RGB(192, 192, 192));
|
|
#else
|
|
dc.SetTextColor(GetSysColor(COLOR_BTNFACE));
|
|
dc.SetBkColor(GetSysColor(COLOR_BTNHIGHLIGHT));
|
|
#endif
|
|
dc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY);
|
|
|
|
dc.SelectObject(obm);
|
|
dc.SelectObject(obr);
|
|
dc.DeleteDC();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
//
|
|
|
|
afx_msg void CToolboxWnd::OnSysColorChange()
|
|
{
|
|
CControlBar::OnSysColorChange();
|
|
DrawStockBitmaps();
|
|
InvalidateRect(NULL, FALSE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
//
|
|
// SizeByButtons
|
|
//
|
|
// Sizes the window according to the current (or a specified) number of
|
|
// buttons. If there are no buttons, the window makes room for one button.
|
|
// Unfilled button slots show through to the background.
|
|
//
|
|
|
|
void CToolboxWnd::SizeByButtons(int nButtons /* = -1 */,
|
|
BOOL bRepaint /* = FALSE */)
|
|
{
|
|
if (nButtons == -1)
|
|
nButtons = (int)m_Tools->GetSize();
|
|
if (nButtons == 0)
|
|
nButtons = 1;
|
|
|
|
// Can't use the hokey Windows' AdjustWindowRect() to work this out,
|
|
// so we do it ourselves by adapting the window based on the difference
|
|
// between GetWindowRect and ClientRect results.
|
|
//
|
|
CRect w, c;
|
|
GetWindowRect(&w);
|
|
w.right -= w.left;
|
|
w.bottom -= w.top;
|
|
GetClientRect(&c);
|
|
|
|
if (bRepaint)
|
|
Invalidate(TRUE);
|
|
|
|
MoveWindow(w.left, w.top,
|
|
m_btnsize.x * m_wWide + (w.right - c.right) - 1,
|
|
m_btnsize.y * ((nButtons / m_wWide) + (!!(nButtons % m_wWide)))
|
|
+ (w.bottom-c.bottom) - 1,
|
|
bRepaint);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnWinIniChange:
|
|
//
|
|
void CToolboxWnd::OnWinIniChange(LPCTSTR lpSection)
|
|
|
|
{
|
|
lpSection;
|
|
#ifdef TRYANYTHING
|
|
CControlBar::OnWinIniChange( lpSection );
|
|
#endif
|
|
DrawStockBitmaps();
|
|
Invalidate(TRUE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
//
|
|
// OnKeyDown
|
|
//
|
|
// Implements keyboard handling for the toolbox window.. this allows
|
|
// trapping of the ESC key, for moving the selected to back to the
|
|
// arrow.
|
|
//
|
|
void CToolboxWnd::OnKeyDown(UINT nKey, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
if (nKey == VK_ESCAPE && m_tCapture)
|
|
CancelDrag();
|
|
else
|
|
CControlBar::OnKeyDown(nKey, nRepCnt, nFlags);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CToolboxWnd::CancelDrag()
|
|
{
|
|
#if 0
|
|
// this is bogus as dragging is presently disabled
|
|
if (m_tCapture != NULL)
|
|
m_tCapture->m_wState |= TF_DRAG; // so select will cancel it
|
|
#endif
|
|
|
|
m_bInside = FALSE;
|
|
|
|
#if 0
|
|
// whoever tries to make drag/drop work will have to handle the fact
|
|
// that our client does not get notified by SelectTool
|
|
SelectTool( IDMB_ARROW );
|
|
#endif
|
|
|
|
m_tCapture = NULL;
|
|
ReleaseCapture();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// AddTool:
|
|
//
|
|
void CToolboxWnd::AddTool(CTool* tool)
|
|
{
|
|
m_Tools->Add((CObject*)tool);
|
|
|
|
if ((m_Tools->GetSize() + m_wWide - 1) / m_wWide > 11) // only have 11 high if more increase the width
|
|
m_wWide += 1;
|
|
|
|
SizeByButtons(-1, TRUE);
|
|
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
// RemoveTool:
|
|
//
|
|
void CToolboxWnd::RemoveTool(CTool* tool)
|
|
{
|
|
for (int nTool = GetToolCount() - 1; GetToolAt(nTool) != tool; nTool -= 1)
|
|
ASSERT(nTool >= 0);
|
|
|
|
m_Tools->RemoveAt(nTool);
|
|
|
|
if ((m_Tools->GetSize() + m_wWide - 2) / (m_wWide - 1) <= 11 && m_wWide > 1)
|
|
m_wWide -= 1;
|
|
|
|
SizeByButtons(-1, TRUE);
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
// private GetTool:
|
|
//
|
|
CTool* CToolboxWnd::GetTool(WORD wID)
|
|
{
|
|
int nTools = (int)m_Tools->GetSize();
|
|
for (int i = 0; i < nTools; i++)
|
|
{
|
|
CTool* t = (CTool*)m_Tools->GetAt(i);
|
|
if (t && t->m_wID == wID)
|
|
return t;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
//
|
|
// SetToolState
|
|
//
|
|
// Used by the owner of a button to modify the state of the button.
|
|
// This does not notify the owner of the new state; presumably the
|
|
// owner knows what it's doing to its own buttons. This allows the
|
|
// owner to use this API during a WM_TOOLDOWN, etc., without getting
|
|
// into a shouting match with the toolbox.
|
|
//
|
|
WORD CToolboxWnd::SetToolState(WORD wID, WORD wState)
|
|
{
|
|
CRect rect;
|
|
CTool* t = GetTool(wID);
|
|
if (t && !(t->m_wState & TF_NYI))
|
|
{
|
|
WORD w = t->m_wState;
|
|
t->m_wState = wState;
|
|
|
|
//
|
|
// if state hasn't changed, return to avoid invalidate and
|
|
// associated flicker.
|
|
//
|
|
|
|
if (w == wState)
|
|
return w;
|
|
|
|
//
|
|
// Calculate the rectangle of the button whose state is changing,
|
|
// and invalidate it.
|
|
//
|
|
// replaces ed's simplistic (and flickering) code:
|
|
//
|
|
// Invalidate(FALSE)
|
|
//
|
|
|
|
for (int i = 0; (CTool*)m_Tools->GetAt(i) != t; i += 1)
|
|
{
|
|
ASSERT(i != m_Tools->GetSize());
|
|
}
|
|
|
|
rect.left = (i % m_wWide) * m_btnsize.x + m_nOffsetX;
|
|
rect.top = (i / m_wWide) * m_btnsize.y + m_nOffsetY;
|
|
rect.right = rect.left + m_btnsize.x;
|
|
rect.bottom = rect.top + m_btnsize.y;
|
|
|
|
InvalidateRect(&rect, TRUE);
|
|
return w;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// SetToolStyle:
|
|
// Used by the owner of a button to modify the style of the button.
|
|
// This forces the state of the button to be enabled and released.
|
|
// This does not notify the owner of the new state; presumably the
|
|
// owner knows what it's doing to its own buttons. This allows the
|
|
// owner to use this API during a WM_TOOLDOWN, etc., without getting
|
|
// into a shouting match with the toolbox.
|
|
//
|
|
WORD CToolboxWnd::SetToolStyle(WORD wID, WORD wStyle)
|
|
{
|
|
CTool* t = GetTool(wID);
|
|
if (t)
|
|
{
|
|
WORD w = t->m_wStyle;
|
|
t->m_wStyle = wStyle;
|
|
t->m_wState = 0;
|
|
Invalidate(FALSE);
|
|
return w;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
//
|
|
// SelectTool
|
|
//
|
|
// Selects a given tool and deselects all the other tools. So, for instance,
|
|
// to select the arrow, call pToolbox->SelectTool(IDMB_ARROW);
|
|
//
|
|
void CToolboxWnd::SelectTool(WORD wID)
|
|
{
|
|
//
|
|
// first clear all the tools except the one we want pressed, then
|
|
// select the one we want.
|
|
//
|
|
for (int i = 0; i < m_Tools->GetSize(); i += 1)
|
|
{
|
|
CTool* pTool = (CTool*)m_Tools->GetAt(i);
|
|
|
|
if (pTool->m_wID != wID)
|
|
SetToolState(pTool->m_wID, 0);
|
|
}
|
|
|
|
SetToolState( wID, TF_SELECTED );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/* CToolboxWnd::CurrentTool
|
|
*
|
|
* Returns the ID of the currently selected tool.
|
|
*/
|
|
WORD CToolboxWnd::CurrentToolID()
|
|
{
|
|
int nTools = (int)m_Tools->GetSize();
|
|
for (int i = 0; i < nTools; i++)
|
|
{
|
|
CTool* t = (CTool*)m_Tools->GetAt(i);
|
|
if (t && t->m_wState == TF_SELECTED)
|
|
return t->m_wID;
|
|
}
|
|
return IDMB_ARROW;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
#define HITTYPE_SUCCESS 0 // hit an item in the control bar
|
|
#define HITTYPE_NOTHING (-1) // hit nothing, but hit the control bar itself
|
|
#define HITTYPE_OUTSIDE (-2) // hit a window outside of the control bar
|
|
#define HITTYPE_TRACKING (-3) // this app is has the focus (is tracking)
|
|
#define HITTYPE_INACTIVE (-4) // the app is not active
|
|
#define HITTYPE_DISABLED (-5) // the control bar is disabled
|
|
#define HITTYPE_FOCUS (-6) // the control bar has focus
|
|
|
|
int CToolboxWnd::HitTestToolTip( CPoint point, UINT* pHit )
|
|
{
|
|
if (pHit)
|
|
*pHit = (UINT)-1; // assume it won't hit anything
|
|
|
|
int iReturn = HITTYPE_INACTIVE;
|
|
|
|
// make sure this app is active
|
|
if (theApp.m_bActiveApp)
|
|
{
|
|
// check for this application tracking (capture set)
|
|
if (! m_tCapture)
|
|
{
|
|
// finally do the hit test on the items within the control bar
|
|
ScreenToClient( &point );
|
|
|
|
CRect rect;
|
|
CTool* pTool = ToolFromPoint( &rect, &point );
|
|
|
|
if (pTool && rect.PtInRect( point ))
|
|
{
|
|
iReturn = HITTYPE_SUCCESS;
|
|
|
|
if (pHit)
|
|
*pHit = pTool->m_wID;
|
|
}
|
|
else
|
|
iReturn = HITTYPE_OUTSIDE;
|
|
}
|
|
else
|
|
iReturn = HITTYPE_TRACKING;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
TRACE2( "HitTestToolType %d - %u\n", iReturn, pHit );
|
|
#endif
|
|
|
|
return iReturn;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
UINT CToolboxWnd::OnCmdHitTest( CPoint point, CPoint* pCenter )
|
|
{
|
|
ASSERT_VALID( this );
|
|
|
|
// now hit test against CToolBar buttons
|
|
CRect rect;
|
|
UINT nHit = (UINT)-1;
|
|
CTool* pTool = ToolFromPoint( &rect, &point );
|
|
|
|
if (pTool)
|
|
nHit = pTool->m_wID;
|
|
|
|
return nHit;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// private ToolFromPoint:
|
|
// Given a CPoint in client coordinates, this function returns the tool
|
|
// associated with the button at that point, if any. If a tool is found,
|
|
// the given CRect (if not NULL) is filled with the bounds of the tool's
|
|
// button.
|
|
//
|
|
CTool* CToolboxWnd::ToolFromPoint(CRect* rect, CPoint* pt) const
|
|
{
|
|
CRect c = m_rcTools;
|
|
CPoint p = *pt;
|
|
|
|
if (p.x < c.left || p.x >= c.right
|
|
|| p.y < c.top || p.y >= c.bottom)
|
|
return NULL;
|
|
|
|
int x = (p.x - m_nOffsetX) / m_btnsize.x;
|
|
int y = (p.y - m_nOffsetY) / m_btnsize.y;
|
|
int i = x + (y * m_wWide);
|
|
|
|
if (i >= m_Tools->GetSize())
|
|
return NULL;
|
|
|
|
CTool* t = (CTool*)(m_Tools->GetAt( i ));
|
|
|
|
if (t && rect)
|
|
{
|
|
rect->left = m_btnsize.x * x + m_nOffsetX;
|
|
rect->top = m_btnsize.y * y + m_nOffsetY;
|
|
rect->right = rect->left + m_btnsize.x;
|
|
rect->bottom = rect->top + m_btnsize.y;
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnLButtonDown:
|
|
|
|
void CToolboxWnd::OnLButtonDown(UINT wFlags, CPoint point)
|
|
{
|
|
wFlags; // Avoid unused arg warnings
|
|
m_tCapture = ToolFromPoint( &m_lasttool, &point );
|
|
m_downpt = point;
|
|
|
|
if (m_tCapture)
|
|
{
|
|
CRect rect = m_lasttool;
|
|
CString strPrompt;
|
|
|
|
m_bInside = FALSE;
|
|
|
|
rect.InflateRect( -1, -1 );
|
|
|
|
if (rect.PtInRect( point ))
|
|
{
|
|
if (m_tCapture->m_wID <= IDMB_USERBTN)
|
|
GetOwner()->SendMessage( WM_SETMESSAGESTRING, (WPARAM)m_tCapture->m_wID );
|
|
|
|
if (m_tCapture->m_wState & TF_DISABLED)
|
|
m_tCapture = NULL;
|
|
else
|
|
m_bInside = TRUE;
|
|
}
|
|
else
|
|
m_tCapture = NULL;
|
|
}
|
|
else
|
|
{
|
|
CControlBar::OnLButtonDown(wFlags,point);
|
|
}
|
|
|
|
if (m_tCapture )
|
|
{
|
|
SetCapture();
|
|
|
|
if (m_tCapture)
|
|
InvalidateRect( &m_lasttool, TRUE );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CToolboxWnd::OnRButtonDown(UINT wFlags, CPoint point)
|
|
{
|
|
wFlags;
|
|
point;
|
|
if (GetCapture() == this)
|
|
CancelDrag();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*DK*/
|
|
// LRESULT CToolboxWnd::OnHelpHitTest(WPARAM wParam, LPARAM lParam)
|
|
// {
|
|
// CPoint pt(lParam);
|
|
// CTool* t = ToolFromPoint(&m_lasttool, &pt);
|
|
//
|
|
// if (t == NULL)
|
|
// return CMiniFrmWnd::OnHelpHitTest(wParam, lParam);
|
|
// else
|
|
// {
|
|
// ASSERT( t->m_wID );
|
|
// return HID_BASE_BUTTON + t->m_wID;
|
|
// }
|
|
// }
|
|
|
|
|
|
// OnLButtonDblClk: FUTURE: Maybe just not use CS_DBLCLKS?
|
|
//
|
|
void CToolboxWnd::OnLButtonDblClk(UINT wFlags, CPoint point)
|
|
{
|
|
OnLButtonDown(wFlags, point);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CToolboxWnd::SetStatusText(int nHit)
|
|
{
|
|
if (nHit == -1 && m_pLastHot != 0)
|
|
{
|
|
m_pLastHot->m_wState &= ~TF_HOT;
|
|
InvalidateRect(&m_rectLastHot, TRUE);
|
|
m_pLastHot = 0;
|
|
}
|
|
|
|
return CControlBar::SetStatusText(nHit);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnMouseMove:
|
|
//
|
|
void CToolboxWnd::OnMouseMove(UINT wFlags, CPoint point)
|
|
{
|
|
CTool* t = m_tCapture;
|
|
|
|
if (! t || (t->m_wState & TF_DISABLED))
|
|
{
|
|
if (m_hTheme)
|
|
{
|
|
CRect rectHot;
|
|
|
|
CTool* pHot = ToolFromPoint(&rectHot, &point);
|
|
|
|
if (m_pLastHot != pHot)
|
|
{
|
|
if (m_pLastHot)
|
|
{
|
|
m_pLastHot->m_wState &= ~TF_HOT;
|
|
InvalidateRect(&m_rectLastHot, TRUE);
|
|
}
|
|
|
|
if (pHot)
|
|
{
|
|
pHot->m_wState |= TF_HOT;
|
|
InvalidateRect(&rectHot, TRUE);
|
|
}
|
|
|
|
m_rectLastHot = rectHot;
|
|
m_pLastHot = pHot;
|
|
}
|
|
}
|
|
|
|
CControlBar::OnMouseMove( wFlags, point );
|
|
return;
|
|
}
|
|
|
|
BOOL bWasInside = m_bInside;
|
|
CRect rect = m_lasttool;
|
|
|
|
rect.InflateRect( -1, -1 );
|
|
|
|
m_bInside = ((! (t->m_wState & TF_DRAG)) && rect.PtInRect( point ));
|
|
|
|
if (bWasInside != m_bInside)
|
|
InvalidateRect( &m_lasttool, TRUE );
|
|
|
|
if (t && !(t->m_wState & TF_DISABLED))
|
|
{
|
|
// if it's a mousemove and we're draggable, then see how far it
|
|
// is from the original mousedown -- if it's a fair distance,
|
|
// then drag it.
|
|
if ((t->m_wStyle & TS_DRAG) &&
|
|
(((point.x - m_downpt.x) > 3) ||
|
|
((point.y - m_downpt.y) > 3) ||
|
|
((m_downpt.x - point.x) > 3) ||
|
|
((m_downpt.y - point.y) > 3)))
|
|
{
|
|
t->m_wState |= TF_DRAG;
|
|
|
|
if (t->m_wStyle & TS_STICKY)
|
|
{
|
|
if (!(t->m_wState & TF_SELECTED))
|
|
{
|
|
t->m_wState |= TF_SELECTED;
|
|
|
|
if (t->m_pOwner)
|
|
t->m_pOwner->SendMessage(TM_TOOLDOWN, t->m_wID);
|
|
}
|
|
|
|
if (m_bInside)
|
|
InvalidateRect(&m_lasttool, TRUE);
|
|
|
|
m_bInside = FALSE; // looks stuck immediately!
|
|
}
|
|
}
|
|
if (t->m_pOwner && (t->m_wState & TF_DRAG))
|
|
{
|
|
CPoint spt = point;
|
|
ClientToScreen(&spt);
|
|
|
|
// if the drag and drop began ok, release the captured tool
|
|
// if (t->m_pOwner->BeginDragDrop( t, spt ))
|
|
// m_tCapture = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
// OnLButtonUp:
|
|
|
|
void CToolboxWnd::OnLButtonUp(UINT wFlags, CPoint point)
|
|
{
|
|
if (! m_tCapture )
|
|
{
|
|
CControlBar::OnLButtonUp( wFlags, point );
|
|
return;
|
|
}
|
|
|
|
CTool* t = m_tCapture;
|
|
|
|
if (t && ! (t->m_wState & TF_DISABLED))
|
|
{
|
|
m_bInside = (point.x >= m_lasttool.left
|
|
&& point.x < m_lasttool.right
|
|
&& point.y >= m_lasttool.top
|
|
&& point.y < m_lasttool.bottom);
|
|
|
|
if (m_bInside)
|
|
{
|
|
if (t->m_wStyle & TS_STICKY)
|
|
{
|
|
if (! (t->m_wState & TF_DRAG))
|
|
{
|
|
t->m_wState ^= TF_SELECTED;
|
|
|
|
InvalidateRect(&m_lasttool, TRUE);
|
|
|
|
if (t->m_pOwner)
|
|
t->m_pOwner->SendMessage( t->m_wState & TF_SELECTED?
|
|
TM_TOOLDOWN : TM_TOOLUP, t->m_wID );
|
|
}
|
|
}
|
|
|
|
if (t->m_wStyle & TS_CMD)
|
|
{
|
|
if (t->m_pOwner)
|
|
AfxGetMainWnd()->SendMessage( WM_COMMAND, t->m_wID );
|
|
}
|
|
}
|
|
}
|
|
ReleaseCapture();
|
|
m_tCapture = NULL;
|
|
m_bInside = FALSE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CToolboxWnd::OnCommand(UINT wParam, LONG lParam)
|
|
{
|
|
AfxGetMainWnd()->SendMessage(WM_COMMAND, wParam, lParam);
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CToolboxWnd::DrawButtons(CDC& dc, RECT* rcPaint)
|
|
{
|
|
CRect rect;
|
|
CRect updateRect;
|
|
int i, n;
|
|
|
|
if (rcPaint == NULL)
|
|
{
|
|
GetClientRect( &updateRect );
|
|
rcPaint = &updateRect;
|
|
}
|
|
|
|
CDC memdc;
|
|
memdc.CreateCompatibleDC(&dc);
|
|
|
|
if (m_hTheme == 0)
|
|
{
|
|
// Force the buttons to be rebuilt here
|
|
DrawStockBitmaps();
|
|
}
|
|
|
|
CBitmap* obm = memdc.SelectObject( m_bmPopped );
|
|
CBrush* obr = memdc.SelectObject( GetSysBrush( COLOR_BTNTEXT ) );
|
|
|
|
n = (int)m_Tools->GetSize();
|
|
|
|
BOOL bUsedImageWell = FALSE;
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
CTool* t = (CTool*)m_Tools->GetAt(i);
|
|
|
|
if (! t)
|
|
continue;
|
|
|
|
rect.left = (i % m_wWide) * m_btnsize.x + m_nOffsetX;
|
|
rect.top = (i / m_wWide) * m_btnsize.y + m_nOffsetY;
|
|
|
|
rect.right = rect.left + m_btnsize.x;
|
|
rect.bottom = rect.top + m_btnsize.y;
|
|
|
|
CRect ir;
|
|
|
|
if (! ir.IntersectRect( rcPaint, &rect ))
|
|
continue;
|
|
|
|
// Select the right stock bitmap, and remember to
|
|
// shove the graphic if it's in a pushed state.
|
|
//
|
|
CBitmap* bmStock = m_bmPopped;
|
|
int xshove = 0, yshove = 0;
|
|
int iButtonStateId = TS_NORMAL;
|
|
|
|
if (t->m_wState & (TF_SELECTED | TF_DRAG))
|
|
{
|
|
bmStock = m_bmStuck;
|
|
xshove = 1; yshove = 1;
|
|
iButtonStateId = t->m_wState & TF_HOT ? TS_HOTCHECKED : TS_CHECKED;
|
|
}
|
|
else if (t->m_wState & TF_HOT)
|
|
{
|
|
iButtonStateId = TS_HOT;
|
|
}
|
|
|
|
if ((t == m_tCapture && m_bInside) && !(t->m_wState & TF_DRAG))
|
|
{
|
|
bmStock = m_bmPushed;
|
|
xshove = 2; yshove = 2;
|
|
iButtonStateId = TS_PRESSED;
|
|
}
|
|
|
|
// Draw a blank button first...
|
|
|
|
if (m_hTheme)
|
|
{
|
|
DrawThemeBackground(m_hTheme, dc, TP_BUTTON, iButtonStateId, &rect, 0);
|
|
}
|
|
else
|
|
{
|
|
::DrawBitmap(&dc, bmStock, &rect, SRCCOPY, &memdc);
|
|
}
|
|
|
|
// Now draw the glyph on top...
|
|
rect.OffsetRect( xshove, yshove );
|
|
|
|
if (! bUsedImageWell)
|
|
{
|
|
if (! m_imageWell.Open())
|
|
goto LReturn;
|
|
|
|
bUsedImageWell = TRUE;
|
|
|
|
if (! m_imageWell.CalculateMask())
|
|
goto LReturn;
|
|
}
|
|
|
|
CPoint pt( rect.left + (rect.Width() - 16) / 2,
|
|
rect.top + (rect.Height() - 16) / 2 );
|
|
|
|
m_imageWell.DrawImage( &dc, pt, t->m_nImage );
|
|
}
|
|
|
|
LReturn:
|
|
if (bUsedImageWell)
|
|
m_imageWell.Close();
|
|
|
|
memdc.SelectObject(obr);
|
|
memdc.SelectObject(obm);
|
|
memdc.DeleteDC();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnPaint:
|
|
//
|
|
|
|
void CToolboxWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
if (dc.m_hDC == NULL)
|
|
{
|
|
theApp.SetGdiEmergency();
|
|
return;
|
|
}
|
|
DrawButtons(dc, &dc.m_ps.rcPaint);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnClose
|
|
//
|
|
// A toolbox is usally created by the parent, and will be destroyed
|
|
// specifically by the parent upon leaving the app. When the user closes
|
|
// the toolbox, it is simply hidden. The parent can then reshow it without
|
|
// recreating it.
|
|
//
|
|
// This also changes the menu test to "show" rather than "hide"
|
|
|
|
void CToolboxWnd::OnClose()
|
|
{
|
|
#ifdef TRYANYTHING
|
|
CControlBar::OnClose();
|
|
#endif
|
|
// ShowWindow(SW_HIDE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnDestroy
|
|
//
|
|
void CToolboxWnd::OnDestroy()
|
|
{
|
|
if (m_hTheme)
|
|
{
|
|
CloseThemeData(m_hTheme);
|
|
m_hTheme = 0;
|
|
}
|
|
CControlBar::OnDestroy();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnThemeChanged
|
|
//
|
|
LRESULT CToolboxWnd::OnThemeChanged(WPARAM, LPARAM)
|
|
{
|
|
if (m_hTheme)
|
|
{
|
|
CloseThemeData(m_hTheme);
|
|
}
|
|
m_hTheme = SafeOpenThemeData(GetSafeHwnd(), L"toolbar");
|
|
InvalidateRect(0, TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnToolDown:
|
|
//
|
|
LONG CToolboxWnd::OnToolDown(UINT wID, LONG /* lParam */)
|
|
{
|
|
for (int i = 0; i < m_Tools->GetSize(); i += 1)
|
|
{
|
|
CTool* pTool = (CTool*)m_Tools->GetAt(i);
|
|
|
|
if (pTool->m_wID != wID)
|
|
SetToolState(pTool->m_wID, 0);
|
|
}
|
|
|
|
return (LONG)TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnToolUp:
|
|
//
|
|
LONG CToolboxWnd::OnToolUp(UINT /* wID */, LONG /* lParam */)
|
|
{
|
|
for (int i = 0; i < m_Tools->GetSize(); i += 1)
|
|
{
|
|
CTool* pTool = (CTool*)m_Tools->GetAt(i);
|
|
SetToolState(pTool->m_wID, 0);
|
|
}
|
|
SetToolState(IDMB_ARROW, TF_SELECTED);
|
|
|
|
return (LONG)TRUE;
|
|
}
|
|
#ifdef XYZZYZ
|
|
/******************************************************************************/
|
|
// OnSwitch:
|
|
//
|
|
LONG CToolboxWnd::OnSwitch(UINT /* wID */, LONG /* point */)
|
|
{
|
|
return (LONG)TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// OnQueryDrop:
|
|
//
|
|
BOOL CToolboxWnd::BeginDragDrop (CTool* /*pTool*/, CPoint /*pt*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
/******************************************************************************/
|
|
|
|
CTool::CTool(CToolboxWnd* pOwner, WORD wID, int nImage,
|
|
WORD wStyle /* = 0 */, WORD wState /* = 0 */)
|
|
{
|
|
m_pOwner = pOwner;
|
|
m_wID = wID;
|
|
m_nImage = nImage;
|
|
m_wStyle = wStyle;
|
|
m_wState = wState;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|