|
|
//-----------------------------------------------------------------------------
// File: uiglobals.cpp
//
// Desc: CUIGlobals is a class that packs and holds most information
// relevent to a UI session. Many classes make reference to
// CUIGlobals all the time.
//
// CPaintHelper encapsulates GDI calls, simplifying GDI operations.
//
// Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
#define __DEFINE_ELEMENT_STRUCTURES__
#include "uielements.h"
static const GUID GUID_DIConfigAppEditLayout = { 0xfd4ace13, 0x7044, 0x4204, { 0x8b, 0x15, 0x9, 0x52, 0x86, 0xb1, 0x2e, 0xad } };
CUIGlobals::CUIGlobals(UIG_PARAMS_DEFINE) :
// globals...
m_hrInit(S_OK),
m_hrFinalResult(S_OK),
m_hInst(NULL), m_lpDI(NULL),
m_dwFlags(0), m_wszUserNames(NULL), m_pSurface(NULL), m_pSurface3D(NULL), m_lpCallback(NULL), m_pvRefData(NULL),
m_bAllowEditLayout(FALSE),
m_bUseColorSet(FALSE),
// ui...
m_pElement(NULL), m_nElements(0), m_pFont(NULL), m_nFonts(0), m_pBrush(NULL), m_nBrushes(0), m_pPen(NULL), m_nPens(0), m_pColor(NULL), m_nColors(0) { tracescope(__ts,_T("CUIGlobals::CUIGlobals()\n"));
m_hrInit = Init(UIG_PARAMS_DEFINE_PASS); }
void CUIGlobals::SetTableColor(UICOLOR uic, COLORREF c) { UICOLORINFO *info = GetColorInfo(uic); assert(info != NULL); if (info == NULL) return;
info->rgb = c; }
HRESULT CUIGlobals::Init(UIG_PARAMS_DEFINE) {tracescope(__ts,_T("CUIGlobals::Init(...)\n"));
HRESULT hr = S_OK;
// get instance handle
m_hInst = (HINSTANCE)g_hModule; if (m_hInst == NULL) { etrace(_T("hInst NULL\n")); return E_FAIL; }
// create direct input
DWORD dwVer = DIRECTINPUT_VERSION; hr = DirectInput8Create(m_hInst, dwVer, IID_IDirectInput8W, (LPVOID *)&m_lpDI, NULL); if (FAILED(hr) || m_lpDI == NULL) { m_lpDI = NULL; etrace2(_T("Could not create DirectInput ver 0x%08x\n -> DirectInputCreateEx() returned 0x%08x\n"), dwVer, hr); return hr; }
// save flags
m_dwFlags = dwFlags; #ifdef CFGUI__FORCE_NON_NULL_WSZUSERNAMES
if (wszUserNames == NULL) wszUserNames = _T("Forced Non-NULL Username"); #endif
if (wszUserNames == NULL) { etrace(_T("wszUserNames was passed NULL\n")); return E_FAIL; }
// save user names
m_wszUserNames = DupSuperString(wszUserNames); if (m_wszUserNames == NULL) { etrace(_T("Could not duplicate user names\n")); return E_FAIL; }
// make sure we were passed an action format
if (lpAcFor == NULL) { etrace(_T("lpAcFor param NULL\n")); return E_INVALIDARG; }
// copy the acfor to the master
hr = InitMasterAcForArray(lpAcFor, int(dwNumAcFor)); if (FAILED(hr)) { etrace1(_T("InitMasterAcForArray() failed, returning 0x%08x\n"), hr); return hr; }
// get surface
if (lpSurface != NULL) { hr = lpSurface->QueryInterface(IID_IDirect3DSurface8, (void **)&m_pSurface3D); if (FAILED(hr) || m_pSurface3D == NULL) { m_pSurface3D = NULL; }
hr = lpSurface->QueryInterface(IID_IDirectDrawSurface, (void **)&m_pSurface); if (FAILED(hr) || m_pSurface == NULL) { m_pSurface = NULL; }
if (m_pSurface == NULL && m_pSurface3D == NULL) etrace(_T("lpSurface was non-NULL but could not get IDirect3DSurface8 or IID_IDirectDrawSurface from it")); }
// save callback and ref data
m_lpCallback = lpCallback; m_pvRefData = pvRefData;
// see whether or not we're allowing edit layout mode
m_bAllowEditLayout = IsEqualGUID(RefMasterAcFor(0).guidActionMap, GUID_DIConfigAppEditLayout);
// init a bunch of stuff necessary for painting
if (!InitColorsAndTablesAndObjects(lpDIColorSet)) return E_FAIL;
// dump info if debug
#ifdef DBG
Dump(); #endif
// return success if we got here
return S_OK; }
BOOL CUIGlobals::InitColorsAndTablesAndObjects(LPDICOLORSET lpDIColorSet) {tracescope(__ts,_T("CUIGlobals::InitColorsAndTablesAndObjects()\n"));
// init ui tables
if (!InitTables()) { etrace(_T("Could not initialize tables\n")); return FALSE; }
// decide whether or not to use the passed colorset
if (lpDIColorSet != NULL) { m_ColorSet = *lpDIColorSet;
m_bUseColorSet = !IsZeroOrInvalidColorSet(m_ColorSet); } else m_bUseColorSet = FALSE;
// use it, or use defaults
if (m_bUseColorSet) { // transfer colors from passed colorset
SetTableColor(UIC_TEXTFORE, D3DCOLOR2COLORREF(m_ColorSet.cTextFore)); SetTableColor(UIC_TEXTHIGHLIGHT, D3DCOLOR2COLORREF(m_ColorSet.cTextHighlight)); SetTableColor(UIC_CALLOUTLINE, D3DCOLOR2COLORREF(m_ColorSet.cCalloutLine)); SetTableColor(UIC_CALLOUTHIGHLIGHT, D3DCOLOR2COLORREF(m_ColorSet.cCalloutHighlight)); SetTableColor(UIC_BORDER, D3DCOLOR2COLORREF(m_ColorSet.cBorder)); SetTableColor(UIC_CONTROLFILL, D3DCOLOR2COLORREF(m_ColorSet.cControlFill)); SetTableColor(UIC_HIGHLIGHTFILL, D3DCOLOR2COLORREF(m_ColorSet.cHighlightFill)); SetTableColor(UIC_AREAFILL, D3DCOLOR2COLORREF(m_ColorSet.cAreaFill)); } else { // use default colors
SetTableColor(UIC_TEXTFORE, RGB(255, 255, 255)); SetTableColor(UIC_TEXTHIGHLIGHT, RGB( 0, 255, 0)); SetTableColor(UIC_CALLOUTLINE, RGB(255, 255, 255)); SetTableColor(UIC_CALLOUTHIGHLIGHT, RGB( 0, 255, 0)); SetTableColor(UIC_BORDER, RGB(255, 255, 0)); SetTableColor(UIC_CONTROLFILL, RGB( 0, 191, 0)); SetTableColor(UIC_HIGHLIGHTFILL, RGB( 0, 0, 0)); SetTableColor(UIC_AREAFILL, RGB( 0, 0, 0)); }
// create the table objects
CreateObjects();
return TRUE; }
CUIGlobals::~CUIGlobals() { tracescope(__ts,_T("CUIGlobals::~CUIGlobals()\n"));
if (m_wszUserNames != NULL) free((LPVOID)m_wszUserNames); m_wszUserNames = NULL;
if (m_lpDI != NULL) m_lpDI->Release(); m_lpDI = NULL;
if (m_pSurface != NULL) m_pSurface->Release(); m_pSurface = NULL;
if (m_pSurface3D != NULL) m_pSurface3D->Release(); m_pSurface3D = NULL;
ClearMasterAcForArray();
ClearTables(); }
void CUIGlobals::Dump() { tracescope(ts, _T("UIGlobals...\n\n"));
traceHEXPTR(m_hInst); traceHEXPTR(m_lpDI); LPTSTR str = AllocConfigureFlagStr(m_dwFlags); trace1(_T("m_dwFlags = %s\n"), str); free(str); traceSUPERSTR(m_wszUserNames); traceHEXPTR(m_pSurface); traceHEXPTR(m_pSurface3D); traceHEXPTR(m_lpCallback); traceBOOL(m_bAllowEditLayout); { tracescope(__csts, _T("m_ColorSet...\n")); traceHEX(m_ColorSet.cTextFore); traceHEX(m_ColorSet.cTextHighlight); traceHEX(m_ColorSet.cCalloutLine); traceHEX(m_ColorSet.cCalloutHighlight); traceHEX(m_ColorSet.cBorder); traceHEX(m_ColorSet.cControlFill); traceHEX(m_ColorSet.cHighlightFill); traceHEX(m_ColorSet.cAreaFill); } traceBOOL(m_bUseColorSet); trace(_T("\n")); TraceActionFormat(_T("Master ActionFormat 0:"), RefMasterAcFor(0)); trace(_T("\n\n")); }
LPDIRECTINPUT8W CUIGlobals::GetDI() { if (m_lpDI == NULL) return NULL;
m_lpDI->AddRef(); return m_lpDI; }
IDirectDrawSurface *CUIGlobals::GetSurface() { if (m_pSurface == NULL) return NULL;
m_pSurface->AddRef(); return m_pSurface; }
IDirect3DSurface8 *CUIGlobals::GetSurface3D() { if (m_pSurface3D == NULL) return NULL;
m_pSurface3D->AddRef(); return m_pSurface3D; }
void CUIGlobals::DeleteObjects() { // make sure all our gdi objects are deleted
int i; if (m_pFont != NULL) for (i = 0; i < m_nFonts; i++) { UIFONTINFO &info = m_pFont[i]; if (info.hFont != NULL) DeleteObject(info.hFont); info.hFont = NULL; } if (m_pBrush != NULL) for (i = 0; i < m_nBrushes; i++) { UIBRUSHINFO &info = m_pBrush[i]; if (info.hBrush != NULL) DeleteObject(info.hBrush); info.hBrush = NULL; if (info.hPen != NULL) DeleteObject(info.hPen); info.hPen = NULL; } if (m_pPen != NULL) for (i = 0; i < m_nPens; i++) { UIPENINFO &info = m_pPen[i]; if (info.hPen != NULL) DeleteObject(info.hPen); info.hPen = NULL; } }
void CUIGlobals::ClearTables() { // make sure all our gdi objects are deleted
DeleteObjects();
// delete the tables, null the pointers, and zero the counters
#define FREETABLE(member, memnum) \
{ \ if (member != NULL) \ delete [] member; \ member = NULL; \ memnum = 0; \ } FREETABLE(m_pElement, m_nElements); FREETABLE(m_pFont, m_nFonts); FREETABLE(m_pBrush, m_nBrushes); FREETABLE(m_pPen, m_nPens); FREETABLE(m_pColor, m_nColors); }
BOOL CUIGlobals::InitTables() { BOOL bSuccess = TRUE;
// make sure the tables have been cleared
ClearTables();
// allocate our own copies of all the tables
#define ALLOCTABLE(member, memnum, type, init, num) \
{ \ member = new type [memnum = num]; \ if (member == NULL) \ { \ memnum = 0; \ bSuccess = FALSE; \ } \ else \ memcpy(member, init, sizeof(type) * memnum); \ } ALLOCTABLE(m_pElement, m_nElements, UIELEMENTINFO, uielement, NUMUIELEMENTS); ALLOCTABLE(m_pFont, m_nFonts, UIFONTINFO, uifont, NUMUIFONTS); ALLOCTABLE(m_pBrush, m_nBrushes, UIBRUSHINFO, uibrush, NUMUIBRUSHES); ALLOCTABLE(m_pPen, m_nPens, UIPENINFO, uipen, NUMUIPENS); ALLOCTABLE(m_pColor, m_nColors, UICOLORINFO, uicolor, NUMUICOLORS);
return bSuccess; }
void CUIGlobals::RecreateObjects() { DeleteObjects(); CreateObjects(); }
void CUIGlobals::CreateObjects() { // make sure all our gdi objects are created
int i; if (m_pFont != NULL) { HDC hDC = GetDC(NULL); for (i = 0; i < m_nFonts; i++) { UIFONTINFO &info = m_pFont[i]; if (info.hFont == NULL) { LOGFONT lf; lf.lfHeight = -MulDiv(info.nPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72); lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = info.bBold ? FW_BOLD : FW_NORMAL; lf.lfItalic = FALSE; lf.lfUnderline = FALSE; lf.lfStrikeOut = FALSE; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; _tcscpy(lf.lfFaceName, info.lfFaceName);
info.hFont = (HGDIOBJ)CreateFontIndirect(&lf); } } ReleaseDC(NULL, hDC); } if (m_pBrush != NULL) for (i = 0; i < m_nBrushes; i++) { UIBRUSHINFO &info = m_pBrush[i]; if (info.hBrush == NULL) info.hBrush = (HGDIOBJ)CreateSolidBrush(GetColor(info.eColor)); if (info.hPen == NULL) info.hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, GetColor(info.eColor)); } if (m_pPen != NULL) for (i = 0; i < m_nPens; i++) { UIPENINFO &info = m_pPen[i]; if (info.hPen == NULL) info.hPen = (HGDIOBJ)CreatePen(info.fnPenStyle, info.nWidth, GetColor(info.eColor)); } }
#define IMPLGETINFO(Type, TYPE, Types, t) \
UI##TYPE##INFO *CUIGlobals::Get##Type##Info(UI##TYPE t) \ { \ if (m_p##Type != NULL) \ for (int i = 0; i < m_n##Types; i++) \ if (m_p##Type[i].e##Type == t) \ return &(m_p##Type[i]); \ return NULL; \ }
IMPLGETINFO(Element, ELEMENT, Elements, e) IMPLGETINFO(Font, FONT, Fonts, f) IMPLGETINFO(Brush, BRUSH, Brushes, b) IMPLGETINFO(Pen, PEN, Pens, p) IMPLGETINFO(Color, COLOR, Colors, c)
#undef IMPLGETINFO
#define IMPLGET(T, Name, Type, TYPE, v, def, ret) \
T CUIGlobals::Get##Name(UI##TYPE ui##v) \ { \ UI##TYPE##INFO *v = Get##Type##Info(ui##v); \ if (!v) \ return def; \ return ret; \ }
IMPLGET(HGDIOBJ, Font, Element, ELEMENT, e, NULL, GetFont(e->eFont)) IMPLGET(HGDIOBJ, Font, Font, FONT, f, NULL, f->hFont) IMPLGET(HGDIOBJ, Brush, Element, ELEMENT, e, NULL, GetBrush(e->eBrush)) IMPLGET(HGDIOBJ, Brush, Brush, BRUSH, b, NULL, b->hBrush) IMPLGET(HGDIOBJ, Pen, Element, ELEMENT, e, NULL, GetPen(e->ePen)) IMPLGET(HGDIOBJ, Pen, Brush, BRUSH, b, NULL, b->hPen) IMPLGET(HGDIOBJ, Pen, Pen, PEN, p, NULL, p->hPen) IMPLGET(COLORREF, BrushColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eBrush)) IMPLGET(COLORREF, PenColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->ePen)) IMPLGET(COLORREF, TextColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eText)) IMPLGET(COLORREF, BkColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eBk)) IMPLGET(COLORREF, Color, Brush, BRUSH, b, RGB(255, 127, 127), GetColor(b->eColor)) IMPLGET(COLORREF, Color, Pen, PEN, p, RGB(255, 127, 127), GetColor(p->eColor)) IMPLGET(COLORREF, Color, Color, COLOR, c, RGB(255, 127, 127), c->rgb)
#undef IMPLGET
CPaintHelper::CPaintHelper(CUIGlobals &uig, HDC hDC) : m_uig(uig), m_priv_hDC(hDC), m_hDC(m_priv_hDC), m_eFont(UIF_VOID), m_eBrush(UIB_VOID), m_ePen(UIP_VOID), m_eText(UIC_VOID), m_eBk(UIC_VOID), m_hOldFont(NULL), m_hOldBrush(NULL), m_hOldPen(NULL), m_bOldFont(FALSE), m_bOldBrush(FALSE), m_bOldPen(FALSE) { if (m_hDC != NULL) { m_oldtextcolor = GetTextColor(m_hDC); m_oldbkcolor = GetBkColor(m_hDC); m_oldbkmode = GetBkMode(m_hDC); } }
CPaintHelper::~CPaintHelper() { if (m_hDC != NULL) { if (m_bOldFont) SelectObject(m_hDC, m_hOldFont); if (m_bOldBrush) SelectObject(m_hDC, m_hOldBrush); if (m_bOldPen) SelectObject(m_hDC, m_hOldPen);
SetTextColor(m_hDC, m_oldtextcolor); SetBkColor(m_hDC, m_oldbkcolor); SetBkMode(m_hDC, m_oldbkmode); } }
void CPaintHelper::SetElement(UIELEMENT eElement) { UIELEMENTINFO *info = m_uig.GetElementInfo(eElement); if (!info) return;
if (info->eFont != UIF_LAST) SetFont(info->eFont); if (info->eBrush != UIB_LAST) SetBrush(info->eBrush); if (info->ePen != UIP_LAST) SetPen(info->ePen); SetText(info->eText, info->eBk); }
void CPaintHelper::SetFont(UIFONT eFont) { if (m_eFont == eFont || eFont == UIF_LAST) return;
HGDIOBJ hObj = m_uig.GetFont(eFont); if (hObj == NULL) return;
if (m_hDC != NULL) { HGDIOBJ hOld = NULL; hOld = SelectObject(m_hDC, hObj); if (!m_bOldFont) m_hOldFont = hOld; m_bOldFont = TRUE; }
m_eFont = eFont; }
void CPaintHelper::SetBrush(UIBRUSH eBrush) { if (m_eBrush == eBrush || eBrush == UIB_LAST) return;
HGDIOBJ hObj = eBrush == UIB_NULL ? GetStockObject(NULL_BRUSH) : m_uig.GetBrush(eBrush); if (hObj == NULL) return;
if (m_hDC != NULL) { HGDIOBJ hOld = NULL; hOld = SelectObject(m_hDC, hObj); if (!m_bOldBrush) m_hOldBrush = hOld; m_bOldBrush = TRUE; }
m_eBrush = eBrush; }
void CPaintHelper::SetPen(UIPEN ePen) { if (m_ePen == ePen || ePen == UIP_LAST) return;
HGDIOBJ hObj = ePen == UIB_NULL ? GetStockObject(NULL_PEN) : m_uig.GetPen(ePen); if (hObj == NULL) return;
if (m_hDC != NULL) { HGDIOBJ hOld = NULL; hOld = SelectObject(m_hDC, hObj); if (!m_bOldPen) m_hOldPen = hOld; m_bOldPen = TRUE; }
m_ePen = ePen; }
void CPaintHelper::SetText(UICOLOR eText, UICOLOR eBk) { if (m_eText != eText && eText != UIC_LAST) { if (m_hDC != NULL) SetTextColor(m_hDC, m_uig.GetColor(eText)); m_eText = eText; } if (m_eBk != eBk && eBk != UIC_LAST) { if (m_hDC != NULL) { if (eBk == UIC_NULL) SetBkMode(m_hDC, TRANSPARENT); else { SetBkColor(m_hDC, m_uig.GetColor(eBk)); SetBkMode(m_hDC, OPAQUE); } } m_eBk = eBk; } }
BOOL CPaintHelper::LineTo(int x, int y) { if (m_hDC == NULL) return FALSE;
return ::LineTo(m_hDC, x, y); }
BOOL CPaintHelper::MoveTo(int x, int y, SPOINT *last) { if (m_hDC == NULL) return FALSE;
POINT p; BOOL bRet = MoveToEx(m_hDC, x, y, &p); if (last) *last = p; return bRet; }
BOOL CPaintHelper::Rectangle(SRECT r, UIRECTTYPE eType) { // fail on no dc
if (m_hDC == NULL) return FALSE;
// see if we lack a pen or brush (might add more checks later)
BOOL bNoPen = m_ePen == UIP_NULL; BOOL bNoBrush = m_eBrush == UIB_NULL;
// fail if trying to do an outline without a pen
if (eType == UIR_OUTLINE && bNoPen) return FALSE;
// fail if trying to do a solid without a brush
if (eType == UIR_SOLID && bNoBrush) return FALSE;
// save old objects if we change anything...
HGDIOBJ hOldBrush = NULL, hOldPen = NULL;
// select a null brush if we're doing an outline and we're not already null brushed
if (eType == UIR_OUTLINE && m_eBrush != UIB_NULL) hOldBrush = SelectObject(m_hDC, GetStockObject(NULL_BRUSH));
// select a pen the same color as the current brush if doing solid
if (eType == UIR_SOLID || m_ePen == UIP_NULL) { HGDIOBJ hPen = m_uig.GetPen(m_eBrush); if (hPen == NULL) return FALSE; hOldPen = SelectObject(m_hDC, hPen); }
// draw the rect
BOOL bRet = ::Rectangle(m_hDC, r.left, r.top, r.right, r.bottom);
// restore whatever changed
if (eType == UIR_OUTLINE && m_eBrush != UIB_NULL) SelectObject(m_hDC, hOldBrush); if (eType == UIR_SOLID || m_ePen == UIP_NULL) SelectObject(m_hDC, hOldPen);
return bRet; }
const DIACTIONFORMATW &CUIGlobals::RefMasterAcFor(int i) { assert(IsValidMasterAcForIndex(i)); return m_MasterAcForArray[i]; }
BOOL CUIGlobals::IsValidMasterAcForIndex(int i) { if (i < 0 || i >= m_MasterAcForArray.GetSize()) return FALSE;
return TRUE; }
HRESULT CUIGlobals::InitMasterAcForArray(const DIACTIONFORMATW *af, int n) { if (n < 1) return E_FAIL;
ClearMasterAcForArray();
m_MasterAcForArray.SetSize(n);
for (int i = 0; i < n; i++) { HRESULT hr = CopyActionFormat(m_MasterAcForArray[i], af[i]); if (FAILED(hr)) { m_MasterAcForArray.SetSize(i); ClearMasterAcForArray();
return hr; } }
return S_OK; }
void CUIGlobals::ClearMasterAcForArray() { int s = m_MasterAcForArray.GetSize();
for (int i = 0; i < s; i++) CleanupActionFormatCopy(m_MasterAcForArray[i]);
m_MasterAcForArray.RemoveAll(); assert(m_MasterAcForArray.GetSize() == 0); }
LPCWSTR CUIGlobals::GetUserName(int i) { return GetSubString(m_wszUserNames, i); }
int CUIGlobals::GetNumUserNames() { return CountSubStrings(m_wszUserNames); }
void CUIGlobals::SetFinalResult(HRESULT hr) { m_hrFinalResult = hr; }
HRESULT CUIGlobals::GetFinalResult() { return m_hrFinalResult; }
int CUIGlobals::GetUserNameIndex(LPCWSTR wsz) { for (int i = 0; i < GetNumUserNames(); i++) if (_wcsicmp(wsz, GetUserName(i)) == 0) return i;
return -1; }
|