You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
486 lines
14 KiB
C++
486 lines
14 KiB
C++
// XTPFunctions.cpp : global functions.
|
|
//
|
|
// This file is a part of the XTREME CONTROLS MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPImageManager.h"
|
|
#include "Common/XTPHookManager.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
|
|
|
|
#ifdef _XTP_INCLUDE_COMMANDBARS
|
|
#include "CommandBars/XTPCommandBarsDefines.h"
|
|
#include "CommandBars/XTPCommandBars.h"
|
|
#include "CommandBars/XTPCommandBar.h"
|
|
#include "CommandBars/XTPPopupBar.h"
|
|
#include "CommandBars/XTPPaintManager.h"
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// helper function which sets the font for a window and all its children
|
|
// and also resizes everything according to the new font
|
|
//-----------------------------------------------------------------------------
|
|
|
|
_XTP_EXT_CLASS void AFXAPI XTPChangeWindowFont(CWnd* pWnd, CFont* pFont)
|
|
{
|
|
CRect windowRect;
|
|
|
|
// grab old and new text metrics
|
|
TEXTMETRIC tmOld, tmNew;
|
|
CDC * pDC = pWnd->GetDC();
|
|
CFont * pSavedFont = pDC->SelectObject(pWnd->GetFont());
|
|
pDC->GetTextMetrics(&tmOld);
|
|
pDC->SelectObject(pFont);
|
|
pDC->GetTextMetrics(&tmNew);
|
|
pDC->SelectObject(pSavedFont);
|
|
pWnd->ReleaseDC(pDC);
|
|
|
|
long oldHeight = tmOld.tmHeight + tmOld.tmExternalLeading;
|
|
long newHeight = tmNew.tmHeight + tmNew.tmExternalLeading;
|
|
|
|
// calculate new dialog window rectangle
|
|
CRect clientRect, newClientRect, newWindowRect;
|
|
|
|
pWnd->GetWindowRect(windowRect);
|
|
pWnd->GetClientRect(clientRect);
|
|
long xDiff = windowRect.Width() - clientRect.Width();
|
|
long yDiff = windowRect.Height() - clientRect.Height();
|
|
|
|
newClientRect.left = newClientRect.top = 0;
|
|
newClientRect.right = clientRect.right * tmNew.tmAveCharWidth / tmOld.tmAveCharWidth;
|
|
newClientRect.bottom = clientRect.bottom * newHeight / oldHeight;
|
|
|
|
newWindowRect.left = windowRect.left -
|
|
(newClientRect.right - clientRect.right)/2;
|
|
newWindowRect.top = windowRect.top -
|
|
(newClientRect.bottom - clientRect.bottom)/2;
|
|
newWindowRect.right = newWindowRect.left + newClientRect.right + xDiff;
|
|
newWindowRect.bottom = newWindowRect.top + newClientRect.bottom + yDiff;
|
|
|
|
pWnd->MoveWindow(newWindowRect);
|
|
|
|
pWnd->SetFont(pFont);
|
|
|
|
// iterate through and move all child windows and change their font.
|
|
CWnd* pChildWnd = pWnd->GetWindow(GW_CHILD);
|
|
|
|
while (pChildWnd)
|
|
{
|
|
pChildWnd->SetFont(pFont);
|
|
pChildWnd->GetWindowRect(windowRect);
|
|
|
|
CString strClass;
|
|
::GetClassName(pChildWnd->m_hWnd, strClass.GetBufferSetLength(32), 31);
|
|
strClass.MakeUpper();
|
|
if (strClass == _T("COMBOBOX"))
|
|
{
|
|
CRect rect;
|
|
pChildWnd->SendMessage(CB_GETDROPPEDCONTROLRECT, 0, (LPARAM) &rect);
|
|
windowRect.right = rect.right;
|
|
windowRect.bottom = rect.bottom;
|
|
}
|
|
|
|
pWnd->ScreenToClient(windowRect);
|
|
windowRect.left = windowRect.left * tmNew.tmAveCharWidth / tmOld.tmAveCharWidth;
|
|
windowRect.right = windowRect.right * tmNew.tmAveCharWidth / tmOld.tmAveCharWidth;
|
|
windowRect.top = windowRect.top * newHeight / oldHeight;
|
|
windowRect.bottom = windowRect.bottom * newHeight / oldHeight;
|
|
pChildWnd->MoveWindow(windowRect);
|
|
|
|
pChildWnd = pChildWnd->GetWindow(GW_HWNDNEXT);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// FUNCTION: XTPDrawEmbossed
|
|
//-----------------------------------------------------------------------------
|
|
|
|
_XTP_EXT_CLASS void AFXAPI XTPDrawEmbossed(CDC* pDC, CImageList& imageList, int nIndex, CPoint point, BOOL bInColor)
|
|
{
|
|
IMAGEINFO imgInfo;
|
|
VERIFY(imageList.GetImageInfo(0, &imgInfo));
|
|
CRect rcImage = imgInfo.rcImage;
|
|
|
|
// create memory dc
|
|
CDC memDC;
|
|
memDC.CreateCompatibleDC(pDC);
|
|
|
|
// create mono or color bitmap
|
|
CBitmap bitmap;
|
|
if (bInColor)
|
|
{
|
|
bitmap.CreateCompatibleBitmap(pDC, rcImage.Width(), rcImage.Height());
|
|
}
|
|
else
|
|
{
|
|
bitmap.CreateBitmap(rcImage.Width(), rcImage.Height(), 1, 1, NULL);
|
|
}
|
|
|
|
// draw image into memory DC--fill BG white first
|
|
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
|
|
memDC.PatBlt(0, 0, rcImage.Width(), rcImage.Height(), WHITENESS);
|
|
imageList.Draw(&memDC, nIndex, CPoint(0, 0), ILD_TRANSPARENT);
|
|
|
|
// Draw using highlight offset by (1, 1), then shadow
|
|
CBrush brShadow(GetXtremeColor(COLOR_3DSHADOW));
|
|
CBrush brHilite(GetXtremeColor(COLOR_3DHIGHLIGHT));
|
|
|
|
CBrush* pOldBrush = pDC->SelectObject(&brHilite);
|
|
pDC->BitBlt(point.x + 1, point.y + 1, rcImage.Width(), rcImage.Height(), &memDC, 0, 0, 0xB8074A);
|
|
|
|
pDC->SelectObject(&brShadow);
|
|
pDC->BitBlt(point.x, point.y, rcImage.Width(), rcImage.Height(), &memDC, 0, 0, 0xB8074A);
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
memDC.SelectObject(pOldBitmap);
|
|
bitmap.DeleteObject();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// FUNCTION: XTPDrawShadedRect
|
|
//-----------------------------------------------------------------------------
|
|
|
|
_XTP_EXT_CLASS void AFXAPI XTPDrawShadedRect(CDC *pDC, CRect& rect)
|
|
{
|
|
// Bit pattern for a monochrome brush with every
|
|
// other pixel turned off
|
|
WORD bits[] =
|
|
{
|
|
0x0055, 0x00AA, 0x0055, 0x00AA,
|
|
0x0055, 0x00AA, 0x0055, 0x00AA
|
|
};
|
|
|
|
// Need a monochrome pattern bitmap
|
|
CBitmap bitmap;
|
|
bitmap.CreateBitmap(8, 8, 1, 1, &bits);
|
|
|
|
// Create the pattern brush
|
|
CBrush brush;
|
|
brush.CreatePatternBrush(&bitmap);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
|
|
COLORREF crBack = pDC->SetBkColor(GetXtremeColor(COLOR_3DFACE));
|
|
COLORREF crText = pDC->SetTextColor(GetXtremeColor(COLOR_3DHIGHLIGHT));
|
|
|
|
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
|
|
|
|
// Restore the device context
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SetBkColor(crBack);
|
|
pDC->SetTextColor(crText);
|
|
|
|
brush.DeleteObject();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// DIBs use RGBQUAD format:
|
|
// 0xbb 0xgg 0xrr 0x00
|
|
//
|
|
// Reasonably efficient code to convert a COLORREF into an
|
|
// RGBQUAD is byte-order-dependent, so we need different
|
|
// code depending on the byte order we're targeting.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define RGB_TO_RGBQUAD(r, g, b) (RGB(b, g, r))
|
|
#define RGBQUAD_INIT(r, g, b) (RGB_TO_RGBQUAD(r, g, b)), (RGB(r, g, b))
|
|
#define CLR_TO_RGBQUAD(clr) (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CXTPReplaceColorHandler - Helper object to replace color in a given DC
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CXTPReplaceColorHandler
|
|
{
|
|
public:
|
|
|
|
// Input: pTargetDC - DC in which to replace colors
|
|
// nWidth - width of the rectangle to replace (starting from (0, 0))
|
|
// nHeight - height of the rectangle to replace the color (starting from (0, 0))
|
|
// Summary: Constructor takes parameters common for the operation.
|
|
CXTPReplaceColorHandler(CDC* pTargetDC, int nWidth, int nHeight);
|
|
|
|
// Summary:
|
|
virtual ~CXTPReplaceColorHandler();
|
|
|
|
// Summary: Initialization, returns false if fails to initialize
|
|
bool Init();
|
|
|
|
// Summary: Replaces one color with another
|
|
bool ReplaceColor(COLORREF clrFrom, COLORREF clrTo);
|
|
|
|
protected:
|
|
|
|
int m_nWidth;
|
|
int m_nHeight;
|
|
bool m_bOldBitmap; // true if m_pOldBitmap was initialized
|
|
CDC m_dcMask; //
|
|
CDC* m_pTargetDC; // a DC to replace colors in place
|
|
CBitmap m_bitmapMask; // monochrome bitmap to work with
|
|
CBitmap* m_pOldBitmap; // previously selected bitmap
|
|
COLORREF m_clrOldText;
|
|
COLORREF m_clrOldBk;
|
|
};
|
|
|
|
CXTPReplaceColorHandler::CXTPReplaceColorHandler(CDC* pTargetDC, int nWidth, int nHeight)
|
|
: m_pOldBitmap(NULL)
|
|
, m_bOldBitmap(false)
|
|
, m_pTargetDC(pTargetDC)
|
|
, m_clrOldBk(pTargetDC->GetBkColor())
|
|
, m_clrOldText(pTargetDC->GetTextColor())
|
|
, m_nWidth(nWidth)
|
|
, m_nHeight(nHeight)
|
|
{
|
|
|
|
}
|
|
|
|
CXTPReplaceColorHandler::~CXTPReplaceColorHandler()
|
|
{
|
|
if (m_bOldBitmap)
|
|
{
|
|
m_dcMask.SelectObject(m_pOldBitmap);
|
|
}
|
|
m_pTargetDC->SetBkColor(m_clrOldBk);
|
|
m_pTargetDC->SetTextColor(m_clrOldText);
|
|
}
|
|
|
|
bool CXTPReplaceColorHandler::Init()
|
|
{
|
|
if (!m_dcMask.CreateCompatibleDC(m_pTargetDC))
|
|
{
|
|
return false;
|
|
}
|
|
if (!m_bitmapMask.CreateBitmap(m_nWidth, m_nHeight, 1, 1, NULL))
|
|
{
|
|
return false;
|
|
}
|
|
m_pOldBitmap = m_dcMask.SelectObject(&m_bitmapMask);
|
|
m_bOldBitmap = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CXTPReplaceColorHandler::ReplaceColor(COLORREF clrFrom, COLORREF clrTo)
|
|
{
|
|
// filter out trivial case
|
|
if (clrFrom == clrTo)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// Initialize the mask:
|
|
// 1. Set the background color of the source DC to the color to translate.
|
|
// so 1s would be the bits where color match has been found
|
|
// 2. Create the object mask for the bitmap by performing a BitBlt
|
|
// from the source bitmap to a monochrome bitmap.
|
|
m_pTargetDC->SetBkColor(clrFrom);
|
|
if (!m_dcMask.BitBlt(0, 0, m_nWidth, m_nHeight, m_pTargetDC, 0, 0, SRCCOPY))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// zero out destination pixels we would want to replace with another color
|
|
m_pTargetDC->SetTextColor(RGB(255, 255, 255));
|
|
m_pTargetDC->SetBkColor(RGB(0, 0, 0));
|
|
if (!m_pTargetDC->BitBlt(0, 0, m_nWidth, m_nHeight, &m_dcMask, 0, 0, SRCAND))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// now, replace zeroed pixels with destination color
|
|
if (clrTo != RGB(0, 0, 0))
|
|
{
|
|
m_pTargetDC->SetBkColor(clrTo);
|
|
m_pTargetDC->SetTextColor(RGB(0, 0, 0));
|
|
if (!m_pTargetDC->BitBlt(0, 0, m_nWidth, m_nHeight, &m_dcMask, 0, 0, SRCPAINT))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// done
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// FUNCTION: XTPChildWindowFromPoint()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
_XTP_EXT_CLASS HWND AFXAPI XTPChildWindowFromPoint(HWND hWnd, POINT point)
|
|
{
|
|
ASSERT(hWnd != NULL);
|
|
if (!hWnd)
|
|
return 0;
|
|
|
|
// check child windows
|
|
::ClientToScreen(hWnd, &point);
|
|
|
|
HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
|
|
for (; hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT))
|
|
{
|
|
if ((UINT)(WORD)::GetDlgCtrlID(hWndChild) != (WORD)-1 &&
|
|
(::GetWindowLong(hWndChild, GWL_STYLE) & WS_VISIBLE))
|
|
{
|
|
// see if point hits the child window
|
|
CRect rect;
|
|
::GetWindowRect(hWndChild, rect);
|
|
if (rect.PtInRect(point))
|
|
return hWndChild;
|
|
}
|
|
}
|
|
|
|
return NULL; // not found
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// FUNCTION: XTPPathExists()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
_XTP_EXT_CLASS BOOL AFXAPI XTPPathExists(LPCTSTR lpszFileName)
|
|
{
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hFind = ::FindFirstFile(lpszFileName, &fd);
|
|
|
|
if (hFind != INVALID_HANDLE_VALUE)
|
|
{
|
|
::FindClose(hFind);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// FUNCTION: XTPCreateView()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
_XTP_EXT_CLASS CWnd* AFXAPI XTPCreateView(CWnd* pParentWnd, CRuntimeClass *pViewClass, CDocument *pDocument/*= NULL*/, CCreateContext *pContext/*= NULL*/, DWORD dwStyle/*= AFX_WS_DEFAULT_VIEW*/, CWnd* pOwnerWnd/*= NULL*/, UINT nID/*= AFX_IDW_PANE_FIRST*/)
|
|
{
|
|
if (!pContext && !pViewClass)
|
|
return NULL;
|
|
|
|
#ifdef _DEBUG
|
|
ASSERT(pContext != NULL || pViewClass != NULL);
|
|
ASSERT(pContext != NULL || pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
|
|
ASSERT(pContext != NULL || AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE));
|
|
#endif
|
|
|
|
if (pOwnerWnd == NULL)
|
|
pOwnerWnd = pParentWnd;
|
|
|
|
CCreateContext contextT;
|
|
if (pContext == NULL)
|
|
{
|
|
// if no context specified, generate one from the
|
|
// currently selected client if possible.
|
|
contextT.m_pLastView = NULL;
|
|
contextT.m_pCurrentFrame = NULL;
|
|
contextT.m_pNewDocTemplate = NULL;
|
|
contextT.m_pCurrentDoc = pDocument;
|
|
contextT.m_pNewViewClass = pViewClass;
|
|
|
|
if (pDocument != NULL)
|
|
contextT.m_pNewDocTemplate = pDocument->GetDocTemplate();
|
|
|
|
pContext = &contextT;
|
|
}
|
|
if (!pContext->m_pNewViewClass)
|
|
return NULL;
|
|
|
|
CWnd* pWnd = NULL;
|
|
TRY
|
|
{
|
|
pWnd = (CWnd*)pContext->m_pNewViewClass->CreateObject();
|
|
if (pWnd == NULL)
|
|
AfxThrowMemoryException();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
TRACE0("Out of memory creating a view.\n"); // Note: DELETE_EXCEPTION(e) not required
|
|
return NULL;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
ASSERT_KINDOF(CWnd, pWnd);
|
|
ASSERT(pWnd->m_hWnd == NULL); // not yet created.
|
|
|
|
// Create with the right size (wrong position)
|
|
CRect rect(0, 0, 0, 0);
|
|
if (!pWnd->Create(NULL, NULL, dwStyle,
|
|
rect, pParentWnd, nID, pContext))
|
|
{
|
|
TRACE0("Failed to create docking window view.\n");
|
|
return NULL;
|
|
}
|
|
|
|
pWnd->SetOwner(pOwnerWnd);
|
|
return pWnd;
|
|
}
|
|
|
|
|
|
_XTP_EXT_CLASS BOOL AFXAPI XTPContextMenu(CMenu* pPopup, UINT nFlags, int x, int y, CWnd* pWnd, int nIDBitmap, BOOL bNoNotify)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
nIDBitmap;
|
|
bNoNotify;
|
|
|
|
#ifdef _XTP_INCLUDE_COMMANDBARS
|
|
if (XTPPaintManager())
|
|
{
|
|
CXTPPopupBar* pPopupBar = CXTPPopupBar::CreatePopupBar(NULL);
|
|
|
|
if (nIDBitmap > 0)
|
|
{
|
|
CXTPImageManager* pImageManager = new CXTPImageManager();
|
|
pImageManager->SetIcons(nIDBitmap);
|
|
pPopupBar->SetImageManager(pImageManager);
|
|
}
|
|
|
|
|
|
if (!pPopupBar->LoadMenu(pPopup))
|
|
{
|
|
pPopupBar->InternalRelease();
|
|
return bResult;
|
|
}
|
|
|
|
bResult = CXTPCommandBars::TrackPopupMenu(pPopupBar, nFlags | (bNoNotify ? TPM_NONOTIFY : 0), x, y, pWnd);
|
|
pPopupBar->InternalRelease();
|
|
}
|
|
else
|
|
{
|
|
bResult = pPopup->TrackPopupMenu(nFlags, x, y, pWnd);
|
|
}
|
|
|
|
#else // Toolkit Standard
|
|
|
|
bResult = pPopup->TrackPopupMenu(nFlags, x, y, pWnd);
|
|
|
|
#endif
|
|
return bResult;
|
|
|
|
}
|