windows-nt/Source/XPSP1/NT/public/internal/windows/inc/duser/duivalue.h
2020-09-26 16:20:57 +08:00

444 lines
13 KiB
C++

/*
* Value
*/
#ifndef DUI_CORE_VALUE_H_INCLUDED
#define DUI_CORE_VALUE_H_INCLUDED
#pragma once
namespace DirectUI
{
////////////////////////////////////////////////////////
// Value
/*
* Value Multithreading
*
* Values are immutable and are a process-wide resource. A value created in one thread can be
* used in any thread. Access to them are synchronized (thread-safe) and they do not have
* thread-affinity.
*
* TODO: Impl thread-safety for Values
*/
// Forward declarations
class Element;
class Layout;
class PropertySheet;
class Expression;
typedef DynamicArray<Element*> ElementList;
// Value will maintain the lifetime of ElementLists, Layouts, PropertySheets, and Expressions after
// a new Value is created with a pointer to the object (these objects are created externally). When
// the reference count goes to zero, these objects will be deleted.
#define DUIV_UNAVAILABLE -2
#define DUIV_UNSET -1
#define DUIV_NULL 0
#define DUIV_INT 1
#define DUIV_BOOL 2
#define DUIV_ELEMENTREF 3
#define DUIV_ELLIST 4 // List deleted on Value destruction and made immutable on create (Value only object holding external created ElementList)
#define DUIV_STRING 5 // String duplicated on creation and freed on destruction (Value creates new internal instance)
#define DUIV_POINT 6
#define DUIV_SIZE 7
#define DUIV_RECT 8
#define DUIV_FILL 9
#define DUIV_LAYOUT 10 // Layout object destroyed on Value destruction (Value only object holding external created Layout)
#define DUIV_GRAPHIC 11 // Bitmap handle freed on Value destruction (Value creates new internal instance)
#define DUIV_SHEET 12 // PropertySheet object destroyed on Value destruction and made immutable on create (Value only object holding external created PropertySheet)
#define DUIV_EXPR 13 // Expression object destroyed on Value destruction (Value only object holding external created Expression)
#define DUIV_ATOM 14
#define DUIV_CURSOR 15 // Will not destroy cursor handle upon value destruction
// Value structures and macros
#define FILLTYPE_HGradient ((BYTE)0)
#define FILLTYPE_VGradient ((BYTE)1)
#define FILLTYPE_Solid ((BYTE)2)
#define FILLTYPE_TriHGradient ((BYTE)3)
#define FILLTYPE_TriVGradient ((BYTE)4)
#define FILLTYPE_DrawFrameControl ((BYTE)5) // DrawFrameControl fill
#define FILLTYPE_DrawThemeBackground ((BYTE)6) // DrawThemeBackground fill
struct Fill // Solid colors and fills
{
BYTE dType;
union
{
struct
{
COLORREF cr;
COLORREF cr2;
COLORREF cr3;
} ref;
struct
{
UINT uType;
UINT uState;
} fillDFC;
struct
{
HTHEME hTheme;
int iPartId;
int iStateId;
} fillDTB;
};
};
// Graphic
// Graphic objects may either have an Alpha channel applied to the entire bitmap,
// may have full alpha transparency of a particular color in the bitmap (with the
// option of an auto-color pick (upper left corner)), or neither
#define GRAPHICTYPE_Bitmap ((BYTE)0)
#define GRAPHICTYPE_Icon ((BYTE)1)
#define GRAPHICTYPE_EnhMetaFile ((BYTE)2)
#ifdef GADGET_ENABLE_GDIPLUS
#define GRAPHICTYPE_GpBitmap ((BYTE)3)
#endif
// Valid modes for Bitmaps (Alpha or RGB used depending on mode), meaning based on context of use
#define GRAPHIC_NoBlend ((BYTE)0)
#define GRAPHIC_AlphaConst ((BYTE)1)
#define GRAPHIC_AlphaConstPerPix ((BYTE)2)
#define GRAPHIC_TransColor ((BYTE)3)
#define GRAPHIC_Stretch ((BYTE)4)
#define GRAPHIC_NineGrid ((BYTE)5)
#define GRAPHIC_NineGridTransColor ((BYTE)6)
#define GRAPHIC_NineGridAlphaConstPerPix ((BYTE)7)
struct Graphic
{
HANDLE hImage; // Will hold hBitmap, hIcon, hEnhMetaFile or Gdiplus::Bitmap
HANDLE hAltImage;
USHORT cx;
USHORT cy;
struct
{
BYTE dImgType : 2;
BYTE dMode : 3;
bool bFlip : 1;
bool bRTLGraphic: 1;
bool bFreehImage: 1;
union
{
BYTE dAlpha;
struct
{
BYTE r: 8;
BYTE g: 8;
BYTE b: 8;
} rgbTrans;
};
} BlendMode;
};
struct Cursor
{
HCURSOR hCursor;
};
// Compile-time static version of the Value class
struct _StaticValue
{
BYTE _fReserved0;
BYTE _fReserved1;
short _dType;
int _cRef;
int _val0;
int _val1;
int _val2;
int _val3;
};
struct _StaticValueColor
{
BYTE _fReserved0;
BYTE _fReserved1;
short _dType;
int _cRef;
BYTE dType;
COLORREF cr;
COLORREF crSec;
USHORT x;
USHORT y;
};
struct _StaticValuePtr
{
BYTE _fReserved0;
BYTE _fReserved1;
short _dType;
int _cRef;
void* _ptr;
};
// Value class (24-bytes)
class Value
{
private:
BYTE _fReserved0; // Reserved for small block allocator
BYTE _fReserved1; // Data alignment padding
short _dType;
int _cRef;
union
{
int _intVal;
bool _boolVal;
Element* _peVal;
ElementList* _peListVal;
LPWSTR _pszVal;
POINT _ptVal;
SIZE _sizeVal;
RECT _rectVal;
Fill _fillVal;
Layout* _plVal;
Graphic _graphicVal;
PropertySheet* _ppsVal;
Expression* _pexVal;
ATOM _atomVal;
Cursor _cursorVal;
};
void _ZeroRelease();
public:
#if DBG
bool IsZeroRef() { return !_cRef; }
#endif
// Value creation methods
static Value* CreateInt(int dValue);
static Value* CreateBool(bool bValue);
static Value* CreateElementRef(Element* peValue);
static Value* CreateElementList(ElementList* peListValue);
static Value* CreateString(LPCWSTR pszValue, HINSTANCE hResLoad = NULL);
static Value* CreatePoint(int x, int y);
static Value* CreateSize(int cx, int cy);
static Value* CreateRect(int left, int top, int right, int bottom);
static Value* CreateColor(COLORREF cr);
static Value* CreateColor(COLORREF cr0, COLORREF cr1, BYTE dType = FILLTYPE_HGradient);
static Value* CreateColor(COLORREF cr0, COLORREF cr1, COLORREF cr2, BYTE dType = FILLTYPE_TriHGradient);
static Value* CreateFill(const Fill & clrSrc);
static Value* CreateDFCFill(UINT uType, UINT uState);
static Value* CreateDTBFill(HTHEME hTheme, int iPartId, int iStateId);
static Value* CreateLayout(Layout* plValue);
static Value* CreateGraphic(HBITMAP hBitmap, BYTE dBlendMode = GRAPHIC_TransColor, UINT dBlendValue = (UINT)-1, bool bFlip = false, bool bRTL = false);
#ifdef GADGET_ENABLE_GDIPLUS
static Value* CreateGraphic(Gdiplus::Bitmap * pgpbmp, BYTE dBlendMode = GRAPHIC_TransColor, UINT dBlendValue = (UINT)-1, bool bFlip = false, bool bRTL = false);
#endif
static Value* CreateGraphic(HICON hIcon, bool bFlip = false, bool bRTL = false);
static Value* CreateGraphic(LPCWSTR pszBMP, BYTE dBlendMode = GRAPHIC_TransColor, UINT dBlendValue = (UINT)-1, USHORT cx = 0, USHORT cy = 0, HINSTANCE hResLoad = NULL,
bool bFlip = false, bool bRTL = false);
static Value* CreateGraphic(LPCWSTR pszICO, USHORT cxDesired, USHORT cyDesired, HINSTANCE hResLoad = NULL, bool bFlip = false, bool bRTL = false);
static Value* CreateGraphic(HENHMETAFILE hEnhMetaFile, HENHMETAFILE hAltEnhMetaFile = NULL);
static Value* CreatePropertySheet(PropertySheet* ppsValue);
static Value* CreateExpression(Expression* pexValue);
static Value* CreateAtom(LPCWSTR pszValue);
static Value* CreateCursor(LPCWSTR pszValue);
static Value* CreateCursor(HCURSOR hValue);
// Reference count methods
void AddRef() { if (_cRef != -1) _cRef++; } // -1 is static value
void Release() { if (_cRef != -1 && !--_cRef) _ZeroRelease(); } // -1 is static value
int GetRefCount() { return _cRef; }
// Accessors
int GetType();
LPVOID GetImage(bool bGetRTL);
int GetInt();
bool GetBool();
Element* GetElement();
ElementList* GetElementList(); // Invalid if released (object referred to destroyed)
const LPWSTR GetString(); // Invalid if released (object referred to destroyed)
const POINT* GetPoint(); // Invalid if released
const SIZE* GetSize(); // Invalid if released
const RECT* GetRect(); // Invalid if released
const Fill* GetFill(); // Invalid if released
Layout* GetLayout(); // Invalid if released (object referred to destroyed)
Graphic* GetGraphic(); // Invalid if released (object indirectly referred to destroyed)
PropertySheet* GetPropertySheet(); // Invalid if released (object referred to destroyed)
Expression* GetExpression(); // Invalid if released (object referred to destroyed)
ATOM GetAtom(); // Invalid if released
Cursor* GetCursor(); // Invalid if released
// Equality
bool IsEqual(Value* pv);
// Conversion
LPWSTR ToString(LPWSTR psz, UINT c);
// Common values
static Value* pvUnavailable;
static Value* pvNull;
static Value* pvUnset;
static Value* pvElementNull;
static Value* pvElListNull;
static Value* pvBoolTrue;
static Value* pvBoolFalse;
static Value* pvStringNull;
static Value* pvPointZero;
static Value* pvSizeZero;
static Value* pvRectZero;
static Value* pvIntZero;
static Value* pvLayoutNull;
static Value* pvGraphicNull;
static Value* pvSheetNull;
static Value* pvExprNull;
static Value* pvAtomZero;
static Value* pvCursorNull;
static Value* pvColorTrans;
};
//LPVOID GetImage(Graphic *pg, bool bGetRTL);
#define GethBitmap(pv, bGetRTL) ((HBITMAP)pv->GetImage(bGetRTL))
#define GethIcon(pv, bGetRTL) ((HICON)pv->GetImage(bGetRTL))
#define GethEnhMetaFile(pv, bGetRTL) ((HENHMETAFILE)pv->GetImage(bGetRTL))
#define GetGpBitmap(pv, bGetRTL) ((Gdiplus::Bitmap *)pv->GetImage(bGetRTL))
#define StaticValue(name, type, val0) static _StaticValue name = { 0, 0, type, -1, val0, 0, 0, 0 }
#define StaticValue2(name, type, val0, val1) static _StaticValue name = { 0, 0, type, -1, val0, val1, 0, 0 }
#define StaticValue4(name, type, val0, val1, val2, val3) static _StaticValue name = { 0, 0, type, -1, val0, val1, val2, val3 }
#define StaticValueColorSolid(name, cr) static _StaticValueColor name = { 0, 0, DUIV_FILL, -1, FILLTYPE_Solid, cr, 0, 0, 0 }
#define StaticValuePtr(name, type, ptr) static _StaticValuePtr name = { 0, 0, type, -1, ptr }
// Accessors
inline int
Value::GetType()
{
return _dType;
}
inline int
Value::GetInt() // Copy passed out
{
DUIAssert(_dType == DUIV_INT, "Invalid value type");
return _intVal;
}
inline bool
Value::GetBool() // Copy passed out
{
DUIAssert(_dType == DUIV_BOOL, "Invalid value type");
return _boolVal;
}
inline Element *
Value::GetElement() // Copy passed out
{
DUIAssert(_dType == DUIV_ELEMENTREF, "Invalid value type");
return _peVal;
}
inline ElementList *
Value::GetElementList() // Copy passed out, invalid (destroyed) if value released
{
DUIAssert(_dType == DUIV_ELLIST, "Invalid value type");
return _peListVal;
}
inline const LPWSTR
Value::GetString() // Copy passed out, invalid (destroyed) if value released
{
DUIAssert(_dType == DUIV_STRING, "Invalid value type");
return _pszVal;
}
inline const POINT *
Value::GetPoint() // Pointer to internal structure, invalid if value released
{
DUIAssert(_dType == DUIV_POINT, "Invalid value type");
return &_ptVal;
}
inline const SIZE *
Value::GetSize() // Pointer to internal structure, invalid if value released
{
DUIAssert(_dType == DUIV_SIZE, "Invalid value type");
return &_sizeVal;
}
inline const RECT *
Value::GetRect() // Pointer to internal structure, invalid if value released
{
DUIAssert(_dType == DUIV_RECT, "Invalid value type");
return &_rectVal;
}
inline const Fill *
Value::GetFill() // Pointer to internal structure, invalid if value released
{
DUIAssert(_dType == DUIV_FILL, "Invalid value type");
return &_fillVal;
}
inline Layout *
Value::GetLayout() // Copy passed out, invalid (destroyed) if value released
{
DUIAssert(_dType == DUIV_LAYOUT, "Invalid value type");
return _plVal;
}
inline Graphic *
Value::GetGraphic() // Pointer to internal structure, invalid if value released
{
DUIAssert(_dType == DUIV_GRAPHIC, "Invalid value type");
return &_graphicVal;
}
inline PropertySheet * Value::GetPropertySheet() // Copy passed out, invalid (destroyed) if value released
{
DUIAssert(_dType == DUIV_SHEET, "Invalid value type");
return _ppsVal;
}
inline Expression *
Value::GetExpression() // Copy passed out, invalid (destroyed) if value released
{
DUIAssert(_dType == DUIV_EXPR, "Invalid value type");
return _pexVal;
}
inline ATOM
Value::GetAtom() // Copy passed out
{
DUIAssert(_dType == DUIV_ATOM, "Invalid value type");
return _atomVal;
}
inline Cursor *
Value::GetCursor() // Pointer to internal structure, invalid if value released
{
DUIAssert(_dType == DUIV_CURSOR, "Invalid value type");
return &_cursorVal;
}
} // namespace DirectUI
#endif // DUI_CORE_VALUE_H_INCLUDED