windows-nt/Source/XPSP1/NT/shell/themes/clipper/clipper.cpp

2115 lines
62 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//--------------------------------------------------------------------------
// Clipper.cpp : test out theme drawing and fast clipping
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "resource.h"
#define ASSERT(x)
#include "uxthemep.h"
#include "tmschema.h"
#include "borderfill.h"
#include "imagefile.h"
#include "textdraw.h"
#include "stdlib.h"
#include "stdio.h"
#include "autos.h"
//--------------------------------------------------------------------------
#define RECTWIDTH(rc) (rc.right - rc.left)
#define RECTHEIGHT(rc) (rc.bottom - rc.top)
#define CLIPPER_FONTHEIGHT 55
//--------------------------------------------------------------------------
HINSTANCE hInst;
HWND hwndMain;
HWND hwndTab;
HWND hwndDisplay;
TCHAR *pszMainWindowClass = L"Clipper";
TCHAR *pszDisplayWindowClass = L"ClipperDisplay";
//-----------------------------------------------------------------------------------
enum IMAGEFILEDRAW
{
IF_REG,
IF_TRANS,
IF_ALPHA
};
//-----------------------------------------------------------------------------------
LPCWSTR szPageNames[] =
{
L"BorderFill",
L"BorderFill-R",
L"ImageFile",
L"ImageFile-R",
L"Glyph",
L"Glyph-R",
L"MultiImage",
L"MultiImage-R",
L"Text",
L"Text-R",
L"Borders",
L"Borders-R",
L"SourceSizing",
L"SourceSizing-R",
};
//-----------------------------------------------------------------------------------
enum GROUPID
{
GID_BORDERFILL,
GID_IMAGEFILE,
GID_GLYPH,
GID_MULTIIMAGE,
GID_TEXT,
GID_BORDERS,
GID_SRCSIZING,
};
//-----------------------------------------------------------------------------------
#define MAXGROUPS ((ARRAYSIZE(szPageNames))/2)
#define MAXTESTITEMS 50
//-----------------------------------------------------------------------------------
// Foward declarations of functions included in this code module:
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DisplayWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void CreateDrawObjects();
BOOL CreateAllWindows();
void RegisterWindowClasses();
//-----------------------------------------------------------------------------------
HRESULT MakeErrorLast() {return E_FAIL;}
//-----------------------------------------------------------------------------------
BOOL CaptureBitmaps();
BOOL WriteBitmapToFile(BITMAPINFOHEADER *pHdr, BYTE *pBits, LPCWSTR pszBaseName);
BOOL WriteBitmapHeader(HANDLE hOutFile, BYTE *pMemoryHdr, DWORD dwTotalPixelBytes);
void OnDisplayResize();
void PaintObjects(HDC hdc, RECT *prc, int iGroupId);
//-----------------------------------------------------------------------------------
SIZE szCell = {100, 60};
RECT rcDraw = {10, 10, 50, 45}; // where to draw within cell
//-----------------------------------------------------------------------------------
struct TESTITEM
{
HTHEME hTheme;
DWORD dwDtbFlags;
WCHAR szName[MAX_PATH];
};
//-----------------------------------------------------------------------------------
//---- scrolling support ----
int iVertOffset = 0;
int iMaxVertOffset = 0; // set by WM_SIZE
int iVertLineSize = 10; // # of pixels
int iVertPageSize = 0; // set by WM_SIZE
//-----------------------------------------------------------------------------------
int iItemCount[MAXGROUPS] = {0};
TESTITEM TestItems[MAXGROUPS][MAXTESTITEMS];
BOOL fCapturing = FALSE;
//-----------------------------------------------------------------------------------
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
hInst = hInstance;
RegisterWindowClasses();
InitCommonControlsEx(NULL);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
//---- parse cmdline params ----
USES_CONVERSION;
LPCSTR p = W2A(lpCmdLine);
while (*p)
{
while (isspace(*p))
p++;
//---- parse switches ----
if ((*p == '/') || (*p == '-'))
{
p++;
if ((*p == 'c') || (*p == 'C'))
{
p++;
fCapturing = TRUE;
}
}
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CLIPPER);
if (fCapturing)
{
CaptureBitmaps();
return 0;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return static_cast<int>(msg.wParam);
}
//--------------------------------------------------------------------------
BOOL CaptureBitmaps()
{
//---- paint each tab page to a memory dc & convert to a bitmap file ----
HDC hdcClient = GetDC(NULL);
RECT rt = {0, 0, 800, 600}; // currently captures all good info
BITMAPINFOHEADER BitMapHdr = {sizeof(BITMAPINFOHEADER), WIDTH(rt), HEIGHT(rt), 1, 24, BI_RGB};
//---- create a DIB to paint into ----
BYTE *pBits;
HBITMAP hBitmap = CreateDIBSection(hdcClient, (BITMAPINFO *)&BitMapHdr, DIB_RGB_COLORS,
(void **)&pBits, NULL, 0);
HDC hdcMemory = CreateCompatibleDC(hdcClient);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmap);
//---- for each tab that we can draw ----
for (int iTabNum=0; iTabNum < ARRAYSIZE(szPageNames); iTabNum++)
{
iVertOffset = 0;
iVertPageSize = RECTHEIGHT(rt);
int iGroupId = iTabNum/2;
//---- keep tester interested by sync. visuals ----
TabCtrl_SetCurSel(hwndTab, iTabNum);
OnDisplayResize();
iVertPageSize = RECTHEIGHT(rt);
InvalidateRect(hwndDisplay, NULL, TRUE);
if (iTabNum % 2) // if its a mirrored page
SetLayout(hdcMemory, LAYOUT_RTL);
else
SetLayout(hdcMemory, 0);
//---- clear the background first ----
HBRUSH hbr = CreateSolidBrush(RGB(255, 255, 255));
FillRect(hdcMemory, &rt, hbr);
//---- draw the objects/labels for this tab ----
PaintObjects(hdcMemory, &rt, iGroupId);
//---- now copy DIB bits to a bitmap file ----
WriteBitmapToFile(&BitMapHdr, pBits, szPageNames[iTabNum]);
}
//---- clean up ----
SelectObject(hdcMemory, hOldBitmap);
DeleteDC(hdcMemory);
DeleteObject(hBitmap);
ReleaseDC(NULL, hdcClient);
return TRUE;
}
//--------------------------------------------------------------------------
BOOL WriteBitmapToFile(BITMAPINFOHEADER *pHdr, BYTE *pBits, LPCWSTR pszBaseName)
{
BOOL fWroteFile = FALSE;
//---- get size of bitmap ----
int iDibWidth = pHdr->biWidth;
int iDibHeight = pHdr->biHeight;
int iRawBytes = iDibWidth * 3;
int iBytesPerRow = 4*((iRawBytes+3)/4);
int iPixelBytesTotal = iBytesPerRow * iDibHeight;
//---- create the bitmap file ----
WCHAR szName[MAX_PATH];
wsprintf(szName, L"%s.bmp", pszBaseName);
HANDLE hFileOutput = CreateFile(szName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFileOutput == INVALID_HANDLE_VALUE)
{
printf("\nError - could not open bitmap file for output: %s\n", szName);
goto exit;
}
//---- write the bitmap FILE header ----
if (! WriteBitmapHeader(hFileOutput, (BYTE *)pHdr, iPixelBytesTotal))
goto exit;
//---- write the bitmap MEMORY header ----
DWORD dw;
if (! WriteFile(hFileOutput, pHdr, sizeof(*pHdr), &dw, NULL))
goto exit;
//---- write the bitmap bits ----
if (! WriteFile(hFileOutput, pBits, iPixelBytesTotal, &dw, NULL))
goto exit;
//---- close the file ----
CloseHandle(hFileOutput);
fWroteFile = TRUE;
exit:
return fWroteFile;
}
//---------------------------------------------------------------------------
BOOL WriteBitmapHeader(HANDLE hOutFile, BYTE *pMemoryHdr, DWORD dwTotalPixelBytes)
{
BOOL fOK = FALSE;
BYTE pbHdr1[] = {0x42, 0x4d};
BYTE pbHdr2[] = {0x0, 0x0, 0x0, 0x0};
int iFileLen;
DWORD dw;
//---- add bitmap hdr at front ----
HRESULT hr = WriteFile(hOutFile, pbHdr1, sizeof(pbHdr1), &dw, NULL);
if (FAILED(hr))
goto exit;
//---- add length of data ----
iFileLen = dwTotalPixelBytes + sizeof(BITMAPFILEHEADER);
hr = WriteFile(hOutFile, &iFileLen, sizeof(int), &dw, NULL);
if (FAILED(hr))
goto exit;
hr = WriteFile(hOutFile, pbHdr2, sizeof(pbHdr2), &dw, NULL);
if (FAILED(hr))
goto exit;
//---- offset to bits (who's idea was *this* field?) ----
int iOffset, iColorTableSize;
DWORD dwSize;
iOffset = sizeof(BITMAPFILEHEADER);
dwSize = *(DWORD *)pMemoryHdr;
iOffset += dwSize;
iColorTableSize = 0;
switch (dwSize)
{
case sizeof(BITMAPCOREHEADER):
BITMAPCOREHEADER *hdr1;
hdr1 = (BITMAPCOREHEADER *)pMemoryHdr;
if (hdr1->bcBitCount == 1)
iColorTableSize = 2*sizeof(RGBTRIPLE);
else if (hdr1->bcBitCount == 4)
iColorTableSize = 16*sizeof(RGBTRIPLE);
else if (hdr1->bcBitCount == 8)
iColorTableSize = 256*sizeof(RGBTRIPLE);
break;
case sizeof(BITMAPINFOHEADER):
case sizeof(BITMAPV4HEADER):
case sizeof(BITMAPV5HEADER):
BITMAPINFOHEADER *hdr2;
hdr2 = (BITMAPINFOHEADER *)pMemoryHdr;
if (hdr2->biClrUsed)
iColorTableSize = hdr2->biClrUsed*sizeof(RGBQUAD);
else
{
if (hdr2->biBitCount == 1)
iColorTableSize = 2*sizeof(RGBQUAD);
else if (hdr2->biBitCount == 4)
iColorTableSize = 16*sizeof(RGBQUAD);
else if (hdr2->biBitCount == 8)
iColorTableSize = 256*sizeof(RGBQUAD);
}
break;
}
iOffset += iColorTableSize;
hr = WriteFile(hOutFile, &iOffset, sizeof(int), &dw, NULL);
if (FAILED(hr))
goto exit;
fOK = TRUE;
exit:
return fOK;
}
//--------------------------------------------------------------------------
void DrawTargetRect(HDC hdc, RECT *prc, COLORREF cr)
{
//---- draw purple target dashed rect ----
//---- prepare drawing objects ----
HPEN hPen = CreatePen(PS_DOT, 1, cr);
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
//---- draw that thing ----
Rectangle(hdc, prc->left-1, prc->top-1, prc->right+1, prc->bottom+1);
//---- restore DC ----
SelectObject(hdc, hOldPen);
SelectObject(hdc, hOldBrush);
DeleteObject(hPen);
}
//--------------------------------------------------------------------------
void DrawClip(HTHEME hTheme, HDC hdc, RECT *prc, int iRowIndex, int iColIndex,
DWORD dwDtbFlags)
{
RECT rect, rcClip;
int left = prc->left + (iColIndex+1)*szCell.cx;
int top = prc->top + (iRowIndex+1)*szCell.cy;
HRESULT hr = S_OK;
SetRect(&rect, left + rcDraw.left, top + rcDraw.top,
left + rcDraw.right, top + rcDraw.bottom);
//---- draw purple target dashed rect ----
DrawTargetRect(hdc, &rect, RGB(128, 128, 255));
switch (iColIndex) // clipping type
{
case 0: // no clipping
break;
case 1: // over clipping
rcClip = rect;
rcClip.left -= 4;
rcClip.right += 4;
rcClip.top -= 4;
rcClip.bottom += 4;
break;
case 2: // exact clipping
rcClip = rect;
break;
case 3: // partial overlap
rcClip = rect;
rcClip.left += 8;
rcClip.right -= 8;
rcClip.top += 8;
rcClip.bottom -= 8;
break;
case 4: // InOut1
rcClip = rect;
rcClip.left -= 3;
rcClip.right = rcClip.left + 20;
rcClip.top -= 3;
rcClip.bottom = rcClip.top + 20;
break;
case 5: // InOut2
rcClip = rect;
rcClip.left += 20;
rcClip.right += 5;
rcClip.top += 15;;
rcClip.bottom += 5;
break;
case 6: // out clip
rcClip.left = rect.right + 6;
rcClip.right = rcClip.left + 9;
rcClip.top = rect.top - 2;
rcClip.bottom = rect.bottom + 2;
break;
}
//---- draw red clipping rect ----
if (iColIndex)
{
HPEN hPen = CreatePen(PS_DOT, 1, RGB(255, 0, 0));
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
Rectangle(hdc, rcClip.left-1, rcClip.top-1, rcClip.right+1, rcClip.bottom+1);
SelectObject(hdc, hOldPen);
SelectObject(hdc, hOldBrush);
DeleteObject(hPen);
}
DTBGOPTS DtbOpts = {sizeof(DtbOpts)};
DtbOpts.dwFlags = dwDtbFlags;
if (iColIndex) // pass clipping rect
{
DtbOpts.dwFlags |= DTBG_CLIPRECT;
DtbOpts.rcClip = rcClip;
}
hr = DrawThemeBackgroundEx(hTheme, hdc, 1, 2, &rect, &DtbOpts);
if (FAILED(hr))
{
WCHAR buff[100];
wsprintf(buff, L"DrawThemeBackgroundEx err: hr=0x%x, irow=%d, icol=%d",
hr, iRowIndex, iColIndex);
//MessageBox(NULL, buff, L"Error", MB_OK);
}
}
//--------------------------------------------------------------------------
void DrawTextObjects(HTHEME hTheme, HDC hdc, RECT *prc, int iRowIndex, LPCWSTR pszName)
{
int left = prc->left + 4; // some padding away from edge
int top = prc->top + iRowIndex*szCell.cy + 18; // try to center
//---- draw label in left cell ----
TextOut(hdc, left, top, pszName, wcslen(pszName));
left += szCell.cx;
RECT rc = {left, top, left+szCell.cx*5, top+szCell.cy};
//---- draw actual test text ----
HRESULT hr = DrawThemeText(hTheme, hdc, 1, 2, L"Testing Text Drawing", -1, 0, 0, &rc);
if (FAILED(hr))
{
WCHAR buff[100];
wsprintf(buff, L"DrawThemeText err: hr=0x%x, irow=%d",
hr, iRowIndex);
MessageBox(NULL, buff, L"Error", MB_OK);
}
}
//--------------------------------------------------------------------------
void DrawClips(HTHEME hTheme, HDC hdc, RECT *prc, int iRowIndex, LPCWSTR pszName,
DWORD dwDtbFlags)
{
//---- label object on left ----
int left = prc->left + 4; // some padding away from edge
int top = prc->top + (iRowIndex+1)*szCell.cy + 18; // try to center
//---- manual page clipping ----
if ((top + szCell.cy) < 0)
return;
if (top > iVertPageSize)
return;
TextOut(hdc, left, top, pszName, wcslen(pszName));
//---- draw clipping variations ----
for (int i=0; i <= 6; i++)
{
DrawClip(hTheme, hdc, prc, iRowIndex, i, dwDtbFlags);
}
}
//--------------------------------------------------------------------------
void AddItem(CDrawBase *pObject, CTextDraw *pTextObj, LPCWSTR pszName, int iGroupId,
DWORD dwOtdFlags=0, DWORD dwDtbFlags=0)
{
HTHEME hTheme = NULL;
if (iItemCount[iGroupId] >= MAXTESTITEMS)
return;
if (pObject)
{
if (pObject->_eBgType == BT_BORDERFILL)
{
CBorderFill *pTo = new CBorderFill;
if (pTo)
{
memcpy(pTo, pObject, sizeof(CBorderFill));
hTheme = CreateThemeDataFromObjects(pTo, NULL, dwOtdFlags);
}
}
else // imagefile
{
CMaxImageFile *pFrom = (CMaxImageFile *)pObject;
CMaxImageFile *pTo = new CMaxImageFile;
if (pTo)
{
//---- transfer CImageFile object & variable number of DIBINFO's ----
DWORD dwLen = sizeof(CImageFile) + sizeof(DIBINFO)*pFrom->_iMultiImageCount;
memcpy(pTo, pFrom, dwLen);
hTheme = CreateThemeDataFromObjects(pTo, NULL, dwOtdFlags);
}
}
}
else // text object
{
CTextDraw *pTo = new CTextDraw;
if (pTo)
{
memcpy(pTo, pTextObj, sizeof(CTextDraw));
hTheme = CreateThemeDataFromObjects(NULL, pTo, dwOtdFlags);
}
}
if (hTheme)
{
int iIndex = iItemCount[iGroupId];
TestItems[iGroupId][iIndex].hTheme = hTheme;
TestItems[iGroupId][iIndex].dwDtbFlags = dwDtbFlags;
lstrcpy(TestItems[iGroupId][iIndex].szName, pszName);
iItemCount[iGroupId]++;
}
else
{
MessageBox(NULL, L"Error creating hTheme from obj", L"Error", MB_OK);
}
}
//--------------------------------------------------------------------------
void CreateBorderFillNoDraw()
{
CBorderFill bfill;
memset(&bfill, 0, sizeof(bfill));
//---- make a BorderFill obj with a border ----
bfill._eBgType = BT_BORDERFILL;
bfill._fNoDraw = TRUE;
AddItem(&bfill, NULL, L"NoDraw", GID_BORDERFILL);
}
//--------------------------------------------------------------------------
void CreateBorderFillSquare()
{
CBorderFill bfill;
memset(&bfill, 0, sizeof(bfill));
//---- make a BorderFill obj with a border ----
bfill._eBgType = BT_BORDERFILL;
bfill._eBorderType = BT_RECT;
bfill._iBorderSize = 0;
bfill._eFillType = FT_SOLID;
bfill._crFill = RGB(128, 255, 255);
AddItem(&bfill, NULL, L"Square", GID_BORDERFILL);
}
//--------------------------------------------------------------------------
void CreateBorderFillBorder()
{
CBorderFill bfill;
memset(&bfill, 0, sizeof(bfill));
//---- make a BorderFill obj with a border ----
bfill._eBgType = BT_BORDERFILL;
bfill._eBorderType = BT_RECT;
bfill._crBorder = RGB(255, 128, 128);
bfill._iBorderSize = 3;
bfill._eFillType = FT_SOLID;
bfill._crFill = RGB(128, 255, 255);
AddItem(&bfill, NULL, L"Border", GID_BORDERFILL);
}
//--------------------------------------------------------------------------
void CreateBorderFillCircle()
{
CBorderFill bfill;
memset(&bfill, 0, sizeof(bfill));
//---- make a BorderFill obj with a border ----
bfill._eBgType = BT_BORDERFILL;
bfill._eBorderType = BT_ROUNDRECT;
bfill._crBorder = RGB(255, 128, 128);
bfill._iBorderSize = 3;
bfill._iRoundCornerWidth = 80;
bfill._iRoundCornerHeight = 80;
bfill._eFillType = FT_SOLID;
bfill._crFill = RGB(128, 255, 255);
AddItem(&bfill, NULL, L"Circle", GID_BORDERFILL);
}
//--------------------------------------------------------------------------
void CreateBorderFillGradient()
{
CBorderFill bfill;
memset(&bfill, 0, sizeof(bfill));
//---- make a BorderFill obj with a border ----
bfill._eBgType = BT_BORDERFILL;
bfill._eBorderType = BT_RECT;
bfill._crBorder = RGB(255, 128, 128);
bfill._iBorderSize = 3;
bfill._eFillType = FT_HORZGRADIENT;
//---- gradients ----
bfill._iGradientPartCount = 2;
bfill._crGradientColors[0] = RGB(0, 0, 0);
bfill._crGradientColors[1] = RGB(255, 255, 255);
bfill._iGradientRatios[0] = 0;
bfill._iGradientRatios[1] = 255;
AddItem(&bfill, NULL, L"Gradient", GID_BORDERFILL);
}
//--------------------------------------------------------------------------
void CreateBorderFillCircleGradient()
{
CBorderFill bfill;
memset(&bfill, 0, sizeof(bfill));
//---- make a BorderFill obj with a border ----
bfill._eBgType = BT_BORDERFILL;
bfill._eBorderType = BT_ROUNDRECT;
bfill._crBorder = RGB(255, 128, 128);
bfill._iBorderSize = 3;
bfill._iRoundCornerWidth = 80;
bfill._iRoundCornerHeight = 80;
bfill._eFillType = FT_HORZGRADIENT;
//---- gradients ----
bfill._iGradientPartCount = 2;
bfill._crGradientColors[0] = RGB(0, 0, 0);
bfill._crGradientColors[1] = RGB(255, 255, 255);
bfill._iGradientRatios[0] = 0;
bfill._iGradientRatios[1] = 255;
AddItem(&bfill, NULL, L"CircleGradient", GID_BORDERFILL);
}
//--------------------------------------------------------------------------
void CreateImageFileBorder(SIZINGTYPE eSizeType, BOOL fSizeBorders, BOOL fForceSizeRect)
{
CImageFile cif;
memset(&cif, 0, sizeof(cif));
cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_BORDERTEST)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- create a ImageFile object that sizes with STRETCH ----
cif._eBgType = BT_IMAGEFILE;
if (fSizeBorders)
{
cif._fSourceGrow = TRUE;
cif._fIntegralSizing = TRUE;
}
cif._fMirrorImage = TRUE;
cif._iImageCount = 1;
cif._eImageLayout = IL_VERTICAL;
cif._ImageInfo.iSingleWidth = 18;
cif._ImageInfo.iSingleHeight = 17;
cif._ImageInfo.eSizingType = eSizeType;
cif._ImageInfo.iMinDpi = 96;
cif._szNormalSize.cx = 50;
cif._szNormalSize.cy = 50;
SetRect((RECT *)&cif._SizingMargins, 3, 3, 3, 3);
DWORD dwOtdFlags = 0;
if (fForceSizeRect)
{
dwOtdFlags |= OTD_FORCE_RECT_SIZING;
}
AddItem(&cif, NULL, L"BorderTest", GID_BORDERS, dwOtdFlags);
}
//--------------------------------------------------------------------------
void CreateImage(int iBgImageId, int iStateCount, SIZINGTYPE eSizeType, BOOL fSrcSizing, int iGroupId,
LPCWSTR pszName, int lw, int rw, int th, int bh)
{
CMaxImageFile mif;
memset(&mif, 0, sizeof(mif));
if (iBgImageId)
{
mif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(iBgImageId)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
}
//---- create a ImageFile object ----
mif._eBgType = BT_IMAGEFILE;
mif._fMirrorImage = TRUE;
mif._iImageCount = iStateCount;
mif._eImageLayout = IL_VERTICAL;
mif._ImageInfo.eSizingType = eSizeType;
mif._ImageInfo.iMinDpi = 96;
mif._szNormalSize.cx = 60;
mif._szNormalSize.cy = 40;
mif._eGlyphType = GT_IMAGEGLYPH;
//---- set Width/Height ----
BITMAP bm;
GetObject(mif._ImageInfo.hProcessBitmap, sizeof bm, &bm);
mif._ImageInfo.iSingleWidth = bm.bmWidth;
mif._ImageInfo.iSingleHeight = bm.bmHeight/iStateCount;
mif._ImageInfo.szMinSize.cx = bm.bmWidth;
mif._ImageInfo.szMinSize.cy = bm.bmHeight/iStateCount;
SetRect((RECT *)&mif._SizingMargins, lw, rw, th, bh);
SetRect((RECT *)&mif._ContentMargins, lw, rw, th, bh);
DWORD dwOtdFlags = 0;
if (fSrcSizing)
{
dwOtdFlags |= OTD_FORCE_RECT_SIZING;
}
AddItem(&mif, NULL, pszName, iGroupId, dwOtdFlags);
}
//--------------------------------------------------------------------------
void CreateProgressTrack()
{
CMaxImageFile mif;
memset(&mif, 0, sizeof(mif));
mif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_PROGRESS_TRACK)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- create a ImageFile object ----
mif._eBgType = BT_IMAGEFILE;
mif._fMirrorImage = TRUE;
mif._iImageCount = 1;
mif._eImageLayout = IL_VERTICAL;
mif._ImageInfo.eSizingType = ST_TILE;
mif._ImageInfo.iMinDpi = 96;
mif._szNormalSize.cx = 60;
mif._szNormalSize.cy = 40;
//---- set Width/Height ----
BITMAP bm;
GetObject(mif._ImageInfo.hProcessBitmap, sizeof bm, &bm);
mif._ImageInfo.iSingleWidth = bm.bmWidth;
mif._ImageInfo.iSingleHeight = bm.bmHeight/1;
mif._ImageInfo.szMinSize.cx = 10;
mif._ImageInfo.szMinSize.cy = 10;
mif._szNormalSize.cx = 100;
mif._szNormalSize.cy = 18;
mif._fSourceShrink = TRUE;
SetRect((RECT *)&mif._SizingMargins, 4, 4, 3, 3);
SetRect((RECT *)&mif._ContentMargins, 4, 4, 3, 3);
AddItem(&mif, NULL, L"Progress", GID_SRCSIZING, 0);
}
//--------------------------------------------------------------------------
void CreateProgressChunk()
{
CMaxImageFile mif;
memset(&mif, 0, sizeof(mif));
//---- create a ImageFile object ----
mif._eBgType = BT_IMAGEFILE;
mif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_PROGRESS_CHUNK)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
mif._fMirrorImage = TRUE;
mif._iImageCount = 1;
mif._eImageLayout = IL_VERTICAL;
mif._ImageInfo.eSizingType = ST_TILE;
mif._ImageInfo.iMinDpi = 96;
mif._szNormalSize.cx = 60;
mif._szNormalSize.cy = 40;
mif._eGlyphType = GT_IMAGEGLYPH;
//---- set Width/Height ----
BITMAP bm;
GetObject(mif._ImageInfo.hProcessBitmap, sizeof bm, &bm);
mif._ImageInfo.iSingleWidth = bm.bmWidth;
mif._ImageInfo.iSingleHeight = bm.bmHeight/1;
mif._ImageInfo.szMinSize.cx = 10;
mif._ImageInfo.szMinSize.cy = 10;
mif._szNormalSize.cx = 100;
mif._szNormalSize.cy = 18;
SetRect((RECT *)&mif._SizingMargins, 0, 0, 6, 5);
SetRect((RECT *)&mif._ContentMargins, 0, 0, 6, 5);
AddItem(&mif, NULL, L"Progress", GID_SRCSIZING, 0);
}
//--------------------------------------------------------------------------
void CreateRadioImage()
{
CMaxImageFile mif;
memset(&mif, 0, sizeof(mif));
//---- create a ImageFile object ----
mif._eBgType = BT_IMAGEFILE;
mif._fMirrorImage = TRUE;
mif._iImageCount = 8;
mif._eImageLayout = IL_VERTICAL;
mif._szNormalSize.cx = 60;
mif._szNormalSize.cy = 40;
mif._eImageSelectType = IST_DPI;
mif._iMultiImageCount = 3;
mif._eTrueSizeScalingType = TSST_DPI;
mif._fUniformSizing = TRUE;
mif._eHAlign = HA_CENTER;
mif._eVAlign = VA_CENTER;
int iMinDpis[] = {96, 118, 185};
//---- process multiple images ----
for (int i=0; i < 3; i++)
{
DIBINFO *pdi = &mif.MultiDibs[i];
int idnum = IDB_RADIO13 + i;
pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
pdi->iMinDpi = iMinDpis[i];
//---- get bitmap width/height ----
BITMAP bm;
GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
pdi->iSingleWidth = bm.bmWidth;
pdi->iSingleHeight = bm.bmHeight/8;
pdi->szMinSize.cx = pdi->iSingleWidth;
pdi->szMinSize.cy = pdi->iSingleHeight;
pdi->eSizingType = ST_TRUESIZE;
pdi->crTransparent = RGB(255, 0, 255);
pdi->fTransparent = TRUE;
}
//---- set primary image ----
mif._ImageInfo = mif.MultiDibs[0];
AddItem(&mif, NULL, L"RadioButton", GID_SRCSIZING, OTD_FORCE_RECT_SIZING);
}
//--------------------------------------------------------------------------
void CreateCheckImage()
{
CMaxImageFile mif;
memset(&mif, 0, sizeof(mif));
//---- create a ImageFile object ----
mif._eBgType = BT_IMAGEFILE;
mif._fMirrorImage = TRUE;
mif._iImageCount = 12;
mif._eImageLayout = IL_VERTICAL;
mif._szNormalSize.cx = 60;
mif._szNormalSize.cy = 40;
mif._eImageSelectType = IST_DPI;
mif._iMultiImageCount = 3;
mif._eTrueSizeScalingType = TSST_DPI;
mif._fUniformSizing = TRUE;
mif._eHAlign = HA_CENTER;
mif._eVAlign = VA_CENTER;
int iMinDpis[] = {96, 118, 185};
//---- process multiple images ----
for (int i=0; i < 3; i++)
{
DIBINFO *pdi = &mif.MultiDibs[i];
int idnum = IDB_CHECK13 + i;
pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
pdi->iMinDpi = iMinDpis[i];
//---- get bitmap width/height ----
BITMAP bm;
GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
pdi->iSingleWidth = bm.bmWidth;
pdi->iSingleHeight = bm.bmHeight/12;
pdi->szMinSize.cx = pdi->iSingleWidth;
pdi->szMinSize.cy = pdi->iSingleHeight;
pdi->eSizingType = ST_TRUESIZE;
pdi->fAlphaChannel = TRUE;
}
//---- set primary image ----
mif._ImageInfo = mif.MultiDibs[0];
AddItem(&mif, NULL, L"CheckBox", GID_SRCSIZING, OTD_FORCE_RECT_SIZING);
}
//--------------------------------------------------------------------------
void CreateScrollGlyph()
{
CMaxImageFile mif;
memset(&mif, 0, sizeof(mif));
//---- create a ImageFile object ----
mif._eBgType = BT_IMAGEFILE;
mif._eGlyphType = GT_IMAGEGLYPH;
mif._fMirrorImage = TRUE;
mif._iImageCount = 16;
mif._eImageLayout = IL_VERTICAL;
mif._szNormalSize.cx = 30;
mif._szNormalSize.cy = 10;
mif._eImageSelectType = IST_NONE;
mif._fUniformSizing = TRUE;
mif._eHAlign = HA_CENTER;
mif._eVAlign = VA_CENTER;
SetRect((RECT *)&mif._SizingMargins, 5, 5, 5, 5);
SetRect((RECT *)&mif._ContentMargins, 0, 0, 3, 3);
//---- background image ----
DIBINFO *pdi = &mif._ImageInfo;
pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_SCROLL_ARROWS)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- get bitmap width/height ----
BITMAP bm;
GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
pdi->iSingleWidth = bm.bmWidth;
pdi->iSingleHeight = bm.bmHeight/16;
pdi->szMinSize.cx = pdi->iSingleWidth;
pdi->szMinSize.cy = pdi->iSingleHeight;
pdi->iMinDpi = 96;
pdi->eSizingType = ST_STRETCH;
//---- glyph image ----
pdi = &mif._GlyphInfo;
mif._GlyphInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(IDB_SCROLL_GLPYHS)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
pdi->fTransparent = TRUE;
pdi->crTransparent = RGB(255, 0, 255);
GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
pdi->iSingleWidth = bm.bmWidth;
pdi->iSingleHeight = bm.bmHeight/16;
pdi->szMinSize.cx = pdi->iSingleWidth;
pdi->szMinSize.cy = pdi->iSingleHeight;
pdi->iMinDpi = 96;
pdi->eSizingType = ST_TRUESIZE;
mif._fSourceShrink = TRUE;
mif._fSourceGrow = TRUE;
mif._eTrueSizeScalingType = TSST_SIZE;
mif._iTrueSizeStretchMark = 100;
//---- add it (without OTD_FORCE_RECT_SIZING) ----
AddItem(&mif, NULL, L"ScrollBox", GID_SRCSIZING, 0);
}
//--------------------------------------------------------------------------
void CreateImageFileStretch(IMAGEFILEDRAW eDraw, int iGroupId)
{
CImageFile cif;
memset(&cif, 0, sizeof(cif));
int idnum = IDB_STRETCH;
if (eDraw == IF_TRANS)
idnum = IDB_STRETCH_TRANS;
cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- create a ImageFile object that sizes with STRETCH ----
cif._eBgType = BT_IMAGEFILE;
cif._fMirrorImage = TRUE;
cif._iImageCount = 5;
cif._eImageLayout = IL_VERTICAL;
cif._ImageInfo.iSingleWidth = 20;
cif._ImageInfo.iSingleHeight = 19;
cif._ImageInfo.eSizingType = ST_STRETCH;
if (eDraw == IF_TRANS)
{
cif._ImageInfo.fTransparent = TRUE;
cif._ImageInfo.crTransparent = RGB(255, 0, 255);
}
SetRect((RECT *)&cif._SizingMargins, 4, 4, 4, 4);
LPCWSTR p = L"Stretch";
if (eDraw == IF_TRANS)
p = L"Stretch+Trans";
AddItem(&cif, NULL, p, iGroupId);
}
//--------------------------------------------------------------------------
void CreateImageFileTile(IMAGEFILEDRAW eDraw, int iGroupId)
{
CImageFile cif;
memset(&cif, 0, sizeof(cif));
int idnum = IDB_TILE;
if (eDraw == IF_TRANS)
idnum = IDB_TILE_TRANS;
DIBINFO *pdi = &cif._ImageInfo;
pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- create a ImageFile object that sizes with TILE ----
pdi->eSizingType = ST_TILE;
cif._eBgType = BT_IMAGEFILE;
cif._fMirrorImage = TRUE;
cif._iImageCount = 5;
cif._eImageLayout = IL_VERTICAL;
cif._ImageInfo.iSingleWidth = 20;
cif._ImageInfo.iSingleHeight = 19;
if (eDraw == IF_TRANS)
{
cif._ImageInfo.fTransparent = TRUE;
cif._ImageInfo.crTransparent = RGB(255, 0, 255);
}
SetRect((RECT *)&cif._SizingMargins, 4, 4, 9, 9);
LPCWSTR p = L"Tile";
if (eDraw == IF_TRANS)
p = L"Tile+Trans";
AddItem(&cif, NULL, p, iGroupId);
}
//--------------------------------------------------------------------------
void CreateImageFileTrueSize(IMAGEFILEDRAW eDraw, int iGroupId)
{
CImageFile cif;
memset(&cif, 0, sizeof(cif));
int idnum = IDB_TRUE;
if (eDraw == IF_TRANS)
idnum = IDB_TRUE_TRANS;
else if (eDraw == IF_ALPHA)
idnum = IDB_TRUE_ALPHA;
cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- create a ImageFile object that sizes with STRETCH ----
cif._eBgType = BT_IMAGEFILE;
cif._iImageCount = 8;
cif._fMirrorImage = TRUE;
cif._eImageLayout = IL_HORIZONTAL;
cif._ImageInfo.iSingleWidth = 16;
cif._ImageInfo.iSingleHeight = 16;
cif._ImageInfo.eSizingType = ST_TRUESIZE;
if (eDraw == IF_TRANS)
{
cif._ImageInfo.fTransparent = TRUE;
cif._ImageInfo.crTransparent = RGB(255, 0, 255);
}
else if (eDraw == IF_ALPHA)
{
cif._ImageInfo.fAlphaChannel = TRUE;
}
LPCWSTR p = L"TrueSize";
if (eDraw == IF_TRANS)
p = L"True+Trans";
else if (eDraw == IF_ALPHA)
p = L"True+Alpha";
AddItem(&cif, NULL, p, iGroupId);
}
//--------------------------------------------------------------------------
void CreateImageFileCharGlyph()
{
CImageFile cif;
memset(&cif, 0, sizeof(cif));
int idnum = IDB_GLYPHBG;
cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- specify bg info ----
cif._eBgType = BT_IMAGEFILE;
cif._fMirrorImage = TRUE;
cif._iImageCount = 3;
cif._eImageLayout = IL_HORIZONTAL;
cif._ImageInfo.iSingleWidth = 16;
cif._ImageInfo.iSingleHeight = 22;
cif._ImageInfo.eSizingType = ST_STRETCH;
SetRect((RECT *)&cif._SizingMargins, 1, 1, 1, 1);
//---- specify the char/font info ----
cif._eGlyphType = GT_FONTGLYPH;
cif._crGlyphTextColor = RGB(0, 0, 255);
cif._iGlyphIndex = 62;
cif._lfGlyphFont.lfWeight = FW_NORMAL;
cif._lfGlyphFont.lfHeight = CLIPPER_FONTHEIGHT;
lstrcpy(cif._lfGlyphFont.lfFaceName, L"marlett");
//---- specify alignment ----
cif._eHAlign = HA_CENTER;
cif._eVAlign = VA_CENTER;
LPCWSTR p = L"FontGlyph";
AddItem(&cif, NULL, p, GID_GLYPH);
}
//--------------------------------------------------------------------------
void CreateImageFileImageGlyph(IMAGEFILEDRAW eDraw, BOOL fForceMirror)
{
CImageFile cif;
memset(&cif, 0, sizeof(cif));
int idnum = IDB_GLYPHBG;
cif._ImageInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- specify bg info ----
cif._eBgType = BT_IMAGEFILE;
cif._fMirrorImage = TRUE;
cif._eGlyphType = GT_IMAGEGLYPH;
cif._iImageCount = 3;
cif._eImageLayout = IL_HORIZONTAL;
cif._ImageInfo.iSingleWidth = 16;
cif._ImageInfo.iSingleHeight = 22;
cif._ImageInfo.eSizingType = ST_STRETCH;
SetRect((RECT *)&cif._SizingMargins, 1, 1, 1, 1);
//---- specify glyph info ----
WCHAR szName[MAX_PATH];
if (eDraw == IF_REG)
{
idnum = IDB_GLYPH;
lstrcpy(szName, L"ImageGlyph");
cif._GlyphInfo.iSingleWidth = 10;
cif._GlyphInfo.iSingleHeight = 7;
}
else if (eDraw == IF_TRANS)
{
idnum = IDB_GLYPH_TRANS;
lstrcpy(szName, L"ImageTrans");
cif._GlyphInfo.fTransparent = TRUE;
cif._GlyphInfo.crTransparent = RGB(255, 0, 255);
cif._GlyphInfo.iSingleWidth = 10;
cif._GlyphInfo.iSingleHeight = 7;
}
else
{
idnum = IDB_GLYPH_ALPHA;
lstrcpy(szName, L"ImageAlpha");
cif._GlyphInfo.fAlphaChannel = TRUE;
cif._GlyphInfo.iSingleWidth = 16;
cif._GlyphInfo.iSingleHeight = 16;
}
cif._GlyphInfo.hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
//---- specify alignment ----
cif._eHAlign = HA_CENTER;
cif._eVAlign = VA_CENTER;
DWORD dwDtbFlags = 0;
if (fForceMirror)
{
dwDtbFlags |= DTBG_MIRRORDC;
lstrcat(szName, L"+M");
}
AddItem(&cif, NULL, szName, GID_GLYPH, 0, dwDtbFlags);
}
//--------------------------------------------------------------------------
void CreateMultiImage()
{
CMaxImageFile MaxIf;
memset(&MaxIf, 0, sizeof(MaxIf));
//---- specify general info ----
MaxIf._eBgType = BT_IMAGEFILE;
MaxIf._fMirrorImage = TRUE;
MaxIf._iImageCount = 8;
MaxIf._eImageLayout = IL_VERTICAL;
MaxIf._eImageSelectType = IST_SIZE;
MaxIf._iMultiImageCount = 3;
MaxIf._iTrueSizeStretchMark = 50;
MaxIf._eTrueSizeScalingType = TSST_SIZE;
MaxIf._fUniformSizing = TRUE;
MaxIf._eHAlign = HA_CENTER;
MaxIf._eVAlign = VA_CENTER;
int iUsageSizes[] = {20, 24, 32};
//---- specify alignment ----
MaxIf._eHAlign = HA_CENTER;
MaxIf._eVAlign = VA_CENTER;
for (int i=0; i < MaxIf._iMultiImageCount; i++)
{
int idnum = IDB_MULTI1 + i;
DIBINFO *pdi = &MaxIf.MultiDibs[i];
pdi->hProcessBitmap = (HBITMAP)LoadImage(hInst, static_cast<LPCWSTR>(IntToPtr(idnum)),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
pdi->szMinSize.cx = iUsageSizes[i];
pdi->szMinSize.cy = iUsageSizes[i];
//---- get bitmap width/height ----
BITMAP bm;
GetObject(pdi->hProcessBitmap, sizeof bm, &bm);
pdi->iSingleWidth = bm.bmWidth;
pdi->iSingleHeight = bm.bmHeight/8;
pdi->eSizingType = ST_TRUESIZE;
pdi->fAlphaChannel = TRUE;
}
//---- set primary image ----
MaxIf._ImageInfo = MaxIf.MultiDibs[0];
AddItem(&MaxIf, NULL, L"MultiImage", GID_MULTIIMAGE);
}
//--------------------------------------------------------------------------
void CreateTextObj()
{
CTextDraw td;
memset(&td, 0, sizeof(td));
//---- text ----
td._crText = RGB(255, 128, 128); // red
//---- font ----
td._fHaveFont = TRUE;
td._lfFont.lfWeight = FW_NORMAL;
td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
td._lfFont.lfQuality = ANTIALIASED_QUALITY;
lstrcpy(td._lfFont.lfFaceName, L"arial");
AddItem(NULL, &td, L"TextObj", GID_TEXT);
}
//--------------------------------------------------------------------------
void CreateShadowTextObj()
{
CTextDraw td;
memset(&td, 0, sizeof(td));
//---- text ----
td._crText = RGB(255, 139, 139); // light red
//---- font ----
td._fHaveFont = TRUE;
td._lfFont.lfWeight = FW_NORMAL;
td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
td._lfFont.lfQuality = ANTIALIASED_QUALITY;
lstrcpy(td._lfFont.lfFaceName, L"arial");
//---- shadow ----
td._ptShadowOffset.x = 2;
td._ptShadowOffset.y = 2;
td._crShadow = RGB(149, 0, 0); // dark red
td._eShadowType = TST_SINGLE;
AddItem(NULL, &td, L"ShadowText", GID_TEXT);
}
//--------------------------------------------------------------------------
void CreateBorderTextObj()
{
CTextDraw td;
memset(&td, 0, sizeof(td));
//---- text ----
td._crText = RGB(255, 139, 139); // light red
//---- font ----
td._fHaveFont = TRUE;
td._lfFont.lfWeight = FW_NORMAL;
td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
td._lfFont.lfQuality = ANTIALIASED_QUALITY;
lstrcpy(td._lfFont.lfFaceName, L"arial");
//---- border ----
td._iBorderSize = 1;
td._crBorder = RGB(128, 128, 255); // light blue
AddItem(NULL, &td, L"BorderText", GID_TEXT);
}
//--------------------------------------------------------------------------
void CreateBorderShadowTextObj()
{
CTextDraw td;
memset(&td, 0, sizeof(td));
//---- text ----
td._crText = RGB(255, 139, 139); // light red
//---- font ----
td._fHaveFont = TRUE;
td._lfFont.lfWeight = FW_NORMAL;
td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
td._lfFont.lfQuality = ANTIALIASED_QUALITY;
lstrcpy(td._lfFont.lfFaceName, L"arial");
//---- shadow ----
td._ptShadowOffset.x = 2;
td._ptShadowOffset.y = 2;
td._crShadow = RGB(149, 0, 0); // dark red
td._eShadowType = TST_SINGLE;
//---- border ----
td._iBorderSize = 1;
td._crBorder = RGB(0, 0, 0); // black
AddItem(NULL, &td, L"BorderShadow", GID_TEXT);
}
//--------------------------------------------------------------------------
void CreateBlurShadowTextObj()
{
CTextDraw td;
memset(&td, 0, sizeof(td));
//---- text ----
td._crText = RGB(255, 139, 139); // light red
//---- font ----
td._fHaveFont = TRUE;
td._lfFont.lfWeight = FW_NORMAL;
td._lfFont.lfHeight = CLIPPER_FONTHEIGHT;
td._lfFont.lfQuality = ANTIALIASED_QUALITY;
lstrcpy(td._lfFont.lfFaceName, L"arial");
//---- shadow ----
td._ptShadowOffset.x = 2;
td._ptShadowOffset.y = 2;
td._crShadow = RGB(149, 0, 0); // dark red
td._eShadowType = TST_CONTINUOUS;
AddItem(NULL, &td, L"BlurShadow", GID_TEXT);
}
//--------------------------------------------------------------------------
void LabelClip(HDC hdc, RECT *prc, int iColIndex, LPCWSTR pszName)
{
int left = prc->left + (iColIndex+1)*szCell.cx;
int top = prc->top + 6; // some padding from very top of window
//---- manual page clipping ----
if ((top + szCell.cy) < 0)
return;
if (top > iVertPageSize)
return;
TextOut(hdc, left, top, pszName, wcslen(pszName));
}
//--------------------------------------------------------------------------
void CreateDrawObjects()
{
//---- borderfill group ----
CreateBorderFillNoDraw();
CreateBorderFillSquare();
CreateBorderFillBorder();
CreateBorderFillCircle();
CreateBorderFillGradient();
CreateBorderFillCircleGradient();
//---- imagefile group ----
CreateImageFileStretch(IF_REG, GID_IMAGEFILE);
CreateImageFileStretch(IF_TRANS, GID_IMAGEFILE);
CreateImageFileTile(IF_REG, GID_IMAGEFILE);
CreateImageFileTile(IF_TRANS, GID_IMAGEFILE);
CreateImageFileTrueSize(IF_REG, GID_IMAGEFILE);
CreateImageFileTrueSize(IF_TRANS, GID_IMAGEFILE);
CreateImageFileTrueSize(IF_ALPHA, GID_IMAGEFILE);
//---- glyph group ----
//CreateImageFileCharGlyph();
CreateImageFileImageGlyph(IF_REG, FALSE);
CreateImageFileImageGlyph(IF_TRANS, FALSE);
CreateImageFileImageGlyph(IF_TRANS, TRUE);
CreateImageFileImageGlyph(IF_ALPHA, FALSE);
//---- MultiImage group ----
CreateMultiImage();
//---- text group ----
CreateTextObj();
CreateShadowTextObj();
CreateBorderTextObj();
CreateBorderShadowTextObj();
CreateBlurShadowTextObj();
//---- borders group ----
CreateImageFileBorder(ST_TRUESIZE, FALSE, FALSE);
CreateImageFileBorder(ST_STRETCH, FALSE, FALSE);
CreateImageFileBorder(ST_STRETCH, TRUE, TRUE);
CreateImageFileBorder(ST_TILE, TRUE, TRUE);
//---- SrcSizing group ----
CreateImage(IDB_PUSHBUTTON, 5, ST_STRETCH, TRUE, GID_SRCSIZING, L"PushButton",
8, 8, 9, 9);
CreateRadioImage();
CreateCheckImage();
CreateScrollGlyph();
CreateProgressTrack();
CreateProgressChunk();
}
//--------------------------------------------------------------------------
void CenterRect(POINT &ptCenter, int iSize, RECT *prc)
{
int iSizeA = iSize/2;
int iSizeB = iSize - iSizeA;
prc->left = ptCenter.x - iSizeA;
prc->right = ptCenter.x + iSizeB;
prc->top = ptCenter.y - iSizeA;
prc->bottom = ptCenter.y + iSizeB;
}
//--------------------------------------------------------------------------
void DrawMultiImages(HDC hdc, RECT *prc, HTHEME hTheme)
{
SIZE szMyCell = {80, 80};
int iRowIndex = 0;
int iSizes[] = {12, 16, 20, 24, 32, 48, 64};
//---- draw various sizes of image ----
for (int iIndex=0; iIndex < ARRAYSIZE(iSizes); iIndex++)
{
int iSize = iSizes[iIndex];
//---- label object on left ----
int left = prc->left + 4; // some padding away from edge
int top = prc->top + (iRowIndex)*szMyCell.cy + 18; // try to center
//---- manual page clipping ----
if ((top + szMyCell.cy) < 0)
return;
if (top > iVertPageSize)
return;
WCHAR szName[MAX_PATH];
wsprintf(szName, L"Size: %d", iSize);
TextOut(hdc, left, top+15, szName, wcslen(szName));
//---- draw image in all of its states ----
int iPartId = BP_RADIOBUTTON;
for (int iStateId=RBS_UNCHECKEDNORMAL; iStateId <= RBS_CHECKEDDISABLED; iStateId++)
{
left += szMyCell.cx;
RECT rc = {left, top, left+szMyCell.cx, top+szMyCell.cy};
//---- draw purple target dashed rect ----
DrawTargetRect(hdc, &rc, RGB(128, 128, 255));
//---- calc center pt ----
POINT ptCenter = {left + szMyCell.cx/2, top + szMyCell.cy/2};
//---- rect to draw into ----
CenterRect(ptCenter, iSize, &rc);
//---- draw red rect for "draw into" rect ----
DrawTargetRect(hdc, &rc, RGB(255, 0, 0));
HRESULT hr = DrawThemeBackground(hTheme, hdc, iPartId, iStateId, &rc, NULL);
if (FAILED(hr))
{
WCHAR buff[100];
wsprintf(buff, L"DrawThemeBackground err: hr=0x%x, irow=%d, iPartId=%d",
hr, iRowIndex, iPartId);
//MessageBox(NULL, buff, L"Error", MB_OK);
}
}
iRowIndex++;
}
}
//--------------------------------------------------------------------------
void DrawBorders(HDC hdc, RECT *prc, TESTITEM *pTestItem)
{
int top = prc->top + 4;
int left = prc->left + 6;
//---- message on top line ----
WCHAR szBuff[100];
lstrcpy(szBuff, L"Image: BorderTest.bmp, 18x17, 24 bit, Sizing Margins: 3, 3, 3, 3");
TextOut(hdc, left, top+15, szBuff, wcslen(szBuff));
top += 44;
//---- FIRST row: draw border test obj in 6 different sizes ----
SIZE szMyCell = {120, 120};
//---- manual page clipping ----
if (((top + szMyCell.cy) >= 0) && (top <= iVertPageSize))
{
LPCWSTR pszLabels [] = { L"TrueSize", L"Stretch", L"Stretch", L"Stretch",
L"Stretch", L"Stretch", L"Stretch"};
SIZE szSizes[] = { {60, 40}, {60, 40}, {6, 40}, {3, 40}, {60, 6}, {60, 2}, {2, 3} };
//---- draw various sizes of image ----
for (int iIndex=0; iIndex < ARRAYSIZE(szSizes); iIndex++)
{
SIZE sz = szSizes[iIndex];
//---- label object on top ----
left = prc->left + iIndex*szMyCell.cx + 6; // some padding away from edge
wsprintf(szBuff, L"%s (%dx%d)", pszLabels[iIndex], sz.cx, sz.cy);
TextOut(hdc, left, top+15, szBuff, wcslen(szBuff));
//---- draw image ----
RECT rc = {left, top+50, left+sz.cx, top+50+sz.cy};
int i = (iIndex==0) ? 0 : 1;
HRESULT hr = DrawThemeBackground(pTestItem[i].hTheme, hdc, 0, 0, &rc, NULL);
if (FAILED(hr))
{
WCHAR buff[100];
wsprintf(buff, L"DrawThemeBackground err in DrawBorders: hr=0x%x, iIndex=%d",
hr, iIndex);
//MessageBox(NULL, buff, L"Error", MB_OK);
}
}
}
//---- SECOND row: draw 2 other border objects real big (test border scaling) ----
top += szMyCell.cy;
szMyCell.cx = 380;
szMyCell.cy = 300;
SIZE sz = {szMyCell.cx - 30, szMyCell.cy - (50 + 10)};
//---- manual page clipping: first row ----
if (((top + szMyCell.cy) >= 0) && (top <= iVertPageSize))
{
LPCWSTR pszLabels [] = { L"Border Scaling (stretch)", L"Border Scaling (tile)"};
//---- draw various sizes of image ----
for (int iIndex=0; iIndex < ARRAYSIZE(pszLabels); iIndex++)
{
//---- label object on top ----
int left = prc->left + iIndex*szMyCell.cx + 6; // some padding away from edge
TextOut(hdc, left, top+15, pszLabels[iIndex], wcslen(pszLabels[iIndex]));
//---- draw image ----
RECT rc = {left, top+50, left+sz.cx, top+50+sz.cy};
HRESULT hr = DrawThemeBackground(pTestItem[2+iIndex].hTheme, hdc, 0, 0, &rc, NULL);
if (FAILED(hr))
{
WCHAR buff[100];
wsprintf(buff, L"DrawThemeBackground err in DrawBorders: hr=0x%x, iIndex=%d",
hr, iIndex);
//MessageBox(NULL, buff, L"Error", MB_OK);
}
}
}
}
//--------------------------------------------------------------------------
void DrawSrcSizing(HDC hdc, RECT *prc, TESTITEM *pTestItem)
{
SIZE szMyCell = {120, 110};
int top = prc->top + 4;
int left = prc->left + szMyCell.cx + 6;
//---- labels on top line ----
LPCWSTR TopLabels[] = {L"Small", L"Regular", L"Large", L"High DPI"};
SIZE szStretchSizes[] = { {50, 6}, {75, 23}, {90, 65}, {340, 100} };
SIZE szTrueSizes[] = { {10, 6}, {13, 13}, {30, 30}, {340, 100} };
int iStates[] = {5, 6, 6, 0, 0};
for (int i=0; i < ARRAYSIZE(TopLabels); i++)
{
TextOut(hdc, left, top, TopLabels[i], wcslen(TopLabels[i]));
left += szMyCell.cx;
}
top += 30;
//---- draw rows ----
for (int iRow=0; iRow < 5; iRow++)
{
//---- draw name on left ----
left = prc->left + 6;
WCHAR *pszName = pTestItem[iRow].szName;
TextOut(hdc, left, top-5, pszName, wcslen(pszName));
for (int iSize=0; iSize < ARRAYSIZE(szStretchSizes); iSize++)
{
left += szMyCell.cx;
SIZE *psz;
if ((iRow > 0) && (iRow < 4))
{
psz = &szTrueSizes[iSize];
}
else
{
psz = &szStretchSizes[iSize];
}
RECT rc = {left, top, left + psz->cx, top + psz->cy};
HTHEME hTheme = pTestItem[iRow].hTheme;
if (hTheme)
{
DrawThemeBackground(hTheme, hdc, 0, iStates[iRow], &rc, NULL);
if (iRow == 4) // progress control
{
RECT rcContent;
GetThemeBackgroundContentRect(hTheme, hdc,
0, 0, &rc, &rcContent);
DrawThemeBackground(pTestItem[5].hTheme, hdc, 0, iStates[iRow], &rcContent, NULL);
}
}
}
top += szMyCell.cy;
}
}
//--------------------------------------------------------------------------
void PaintObjects(HDC hdc, RECT *prc, int iGroupId)
{
//---- select in a fixed size font for resolution-independent bits ----
HFONT hfFixedSize = CreateFont(18, 6, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,
0, 0, 0, 0, L"MS Sans Serif");
HFONT hOldFont = (HFONT)SelectObject(hdc, hfFixedSize);
RECT rc = *prc;
rc.top -= iVertOffset;
rc.bottom -= iVertOffset;
if (iGroupId == GID_TEXT) // text object
{
for (int i=0; i < iItemCount[iGroupId]; i++)
{
DrawTextObjects(TestItems[iGroupId][i].hTheme, hdc, &rc, i,
TestItems[iGroupId][i].szName);
}
}
else if (iGroupId == GID_MULTIIMAGE)
{
DrawMultiImages(hdc, prc, TestItems[iGroupId][0].hTheme);
}
else if (iGroupId == GID_BORDERS)
{
DrawBorders(hdc, prc, TestItems[iGroupId]);
}
else if (iGroupId == GID_SRCSIZING)
{
DrawSrcSizing(hdc, prc, TestItems[iGroupId]);
}
else
{
LabelClip(hdc, &rc, 0, L"NoClip");
LabelClip(hdc, &rc, 1, L"OverClip");
LabelClip(hdc, &rc, 2, L"ExactClip");
LabelClip(hdc, &rc, 3, L"PartialClip");
LabelClip(hdc, &rc, 4, L"InOut1");
LabelClip(hdc, &rc, 5, L"InOut2");
LabelClip(hdc, &rc, 6, L"OutClip");
for (int i=0; i < iItemCount[iGroupId]; i++)
{
DrawClips(TestItems[iGroupId][i].hTheme, hdc, &rc, i,
TestItems[iGroupId][i].szName, TestItems[iGroupId][i].dwDtbFlags);
}
}
//---- restore the font ----
SelectObject(hdc, hOldFont);
DeleteObject(hfFixedSize);
}
//--------------------------------------------------------------------------
void RegisterWindowClasses()
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
//---- register MAIN window class ----
wcex.style = 0;
wcex.lpfnWndProc = (WNDPROC)MainWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(hInst, (LPCTSTR)IDI_CLIPPER);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCWSTR)IDC_CLIPPER;
wcex.lpszClassName = pszMainWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
RegisterClassEx(&wcex);
//---- register DISPLAY window class ----
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)DisplayWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(hInst, (LPCTSTR)IDI_CLIPPER);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCWSTR)IDC_CLIPPER;
wcex.lpszClassName = pszDisplayWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
RegisterClassEx(&wcex);
}
//--------------------------------------------------------------------------
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
CreateDrawObjects();
if (! CreateAllWindows())
return FALSE;
ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);
return TRUE;
}
//--------------------------------------------------------------------------
void HandleVScroll(int message, WPARAM wParam, LPARAM lParam)
{
int iOldVertOffset = iVertOffset;
if (message == WM_VSCROLL)
{
switch (LOWORD(wParam))
{
case SB_LINEUP:
iVertOffset -= iVertLineSize;
break;
case SB_LINEDOWN:
iVertOffset += iVertLineSize;
break;
case SB_PAGEUP:
iVertOffset -= iVertPageSize;
break;
case SB_PAGEDOWN:
iVertOffset += iVertPageSize;
break;
case SB_THUMBPOSITION:
iVertOffset = HIWORD(wParam);
break;
}
}
else // mouse wheel
{
iVertOffset -= (GET_WHEEL_DELTA_WPARAM(wParam)/10);
}
//---- keep in valid range ----
if (iVertOffset < 0)
{
iVertOffset = 0;
}
else if (iVertOffset > iMaxVertOffset)
{
iVertOffset = iMaxVertOffset;
}
//---- scroll or repaint, as needed ----
if (iVertOffset != iOldVertOffset)
{
SetScrollPos(hwndDisplay, SB_VERT, iVertOffset, TRUE);
int iDiff = (iVertOffset - iOldVertOffset);
if (abs(iDiff) >= iVertPageSize)
{
InvalidateRect(hwndDisplay, NULL, TRUE);
}
else
{
ScrollWindowEx(hwndDisplay, 0, -iDiff, NULL, NULL, NULL,
NULL, SW_INVALIDATE | SW_ERASE);
}
}
}
//--------------------------------------------------------------------------
void OnDisplayResize()
{
int iTabNum = TabCtrl_GetCurSel(hwndTab);
if (iTabNum < 0)
iTabNum = 0;
int iGroupId = iTabNum/2;
RECT rc;
GetClientRect(hwndDisplay, &rc);
iVertPageSize = RECTHEIGHT(rc);
iMaxVertOffset = ((iItemCount[iGroupId]+1)*szCell.cy) - iVertPageSize;
if (iMaxVertOffset < 0)
iMaxVertOffset = 0;
if (iVertOffset > iMaxVertOffset)
iVertOffset = iMaxVertOffset;
//---- set scrolling info ----
SetScrollRange(hwndDisplay, SB_VERT, 0, iMaxVertOffset, FALSE);
SetScrollPos(hwndDisplay, SB_VERT, iVertOffset, TRUE);
}
//--------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
int iWidth, iHeight;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_NOTIFY:
NMHDR *phdr;
phdr = (NMHDR *)lParam;
if (phdr->code == TCN_SELCHANGE) // tab selection
{
iVertOffset = 0;
OnDisplayResize();
InvalidateRect(hwndDisplay, NULL, TRUE);
}
break;
case WM_SIZE:
iWidth = LOWORD(lParam);
iHeight = HIWORD(lParam);
MoveWindow(hwndTab, 0, 0, iWidth, iHeight, TRUE);
RECT rc;
SetRect(&rc, 0, 0, iWidth, iHeight);
TabCtrl_AdjustRect(hwndTab, FALSE, &rc);
MoveWindow(hwndDisplay, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), TRUE);
break;
case WM_MOUSEWHEEL:
HandleVScroll(message, wParam, lParam);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//--------------------------------------------------------------------------
LRESULT CALLBACK DisplayWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int iTabNum = TabCtrl_GetCurSel(hwndTab);
if (iTabNum < 0)
iTabNum = 0;
int iGroupId = iTabNum/2;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
RECT rt;
hdc = BeginPaint(hWnd, &ps);
if (iTabNum % 2) // if its a mirrored page
SetLayout(hdc, LAYOUT_RTL);
else
SetLayout(hdc, 0);
GetClientRect(hWnd, &rt);
PaintObjects(hdc, &rt, iGroupId);
EndPaint(hWnd, &ps);
break;
case WM_VSCROLL:
HandleVScroll(message, wParam, lParam);
return 0;
case WM_SIZE:
OnDisplayResize();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//--------------------------------------------------------------------------
BOOL CreateAllWindows()
{
TCITEM tci = {0};
BOOL fOk = FALSE;
int i;
//---- create main window ----
hwndMain = CreateWindow(pszMainWindowClass, L"Clipper", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
if (! hwndMain)
goto exit;
//---- create tab control covering main client area ----
RECT rc;
GetClientRect(hwndMain, &rc);
hwndTab = CreateWindowEx(0, WC_TABCONTROL, L"",
WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TCS_MULTILINE|TCS_HOTTRACK|WS_VISIBLE,
rc.left, rc.top, (int)RECTWIDTH(&rc), (int)RECTHEIGHT(&rc), hwndMain, NULL, hInst, NULL);
if (! hwndTab)
goto exit;
//---- create the display window in the tab control "display area" ----
hwndDisplay = CreateWindow(pszDisplayWindowClass, L"", WS_CHILD|WS_VSCROLL|WS_VISIBLE,
rc.left, rc.top, (int)RECTWIDTH(&rc), (int)RECTHEIGHT(&rc), hwndTab, NULL, hInst, NULL);
if (! hwndDisplay)
goto exit;
//---- add tab pages ----
tci.mask = TCIF_TEXT;
TabCtrl_SetPadding(hwndTab, 7, 3);
for (i=0; i < ARRAYSIZE(szPageNames); i++)
{
tci.pszText = (LPWSTR)szPageNames[i];
SendMessage(hwndTab, TCM_INSERTITEM, i, (LPARAM)&tci);
}
fOk = TRUE;
exit:
return fOk;
}
//--------------------------------------------------------------------------
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
//--------------------------------------------------------------------------