📄 tlpaint.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
TLPaint.c - paint tree list
$Id: TLPaint.c,v 1.21 2002/09/30 14:28:42 pbj Exp $
____________________________________________________________________________*/
#include "TLIntern.h"
#include <math.h>
typedef struct _DOTTEDSTRUCT {
HDC hDC;
DWORD dwDottedColor;
} DOTTEDSTRUCT;
#define TRUNCBUFSIZE 256
// _______________________________________________
//
// Initialize painting routines -- create pens, brushes, etc.
void
TLInitPaint (
TLWndData* pWD)
{
DWORD rgb;
BYTE r, g, b;
LOGFONT lf;
HDC hdcMem, hdcScreen;
HBITMAP hOldBitmap;
TEXTMETRIC tm;
RECT rc;
HPEN pen;
int i;
hdcMem = CreateCompatibleDC (NULL);
pWD->selbgbrush = CreateSolidBrush (GetSysColor (COLOR_HIGHLIGHT));
pWD->unselbgbrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
pWD->selfgbrush = CreateSolidBrush (GetSysColor (COLOR_HIGHLIGHTTEXT));
pWD->unselfgbrush = CreateSolidBrush (GetSysColor (COLOR_WINDOWTEXT));
pWD->unfocusbgbrush = CreateSolidBrush (GetSysColor (COLOR_BTNFACE));
pWD->unselfocuscolor = GetSysColor (COLOR_HIGHLIGHT);
r = GetRValue (pWD->unselfocuscolor);
if (r > 127)
r = 0;
else
r = 255;
g = GetGValue (pWD->unselfocuscolor);
if (g > 127)
g = 0;
else
g = 255;
b = GetBValue (pWD->unselfocuscolor);
if (b > 127)
b = 0;
else
b = 255;
pWD->selfocuscolor = PALETTERGB (r, g, b);
pWD->seltextpen = CreatePen (
PS_SOLID, 0, GetSysColor (COLOR_HIGHLIGHTTEXT));
pWD->unseltextpen = CreatePen (
PS_SOLID, 0, GetSysColor (COLOR_WINDOWTEXT));
pWD->buttonpen = CreatePen(PS_SOLID, 0, GetSysColor (COLOR_3DSHADOW));
pWD->linecolor = GetSysColor (COLOR_3DSHADOW);
pWD->barcolor = GetSysColor (COLOR_3DSHADOW);
pWD->stdbarbrush = CreateSolidBrush (GetSysColor (COLOR_3DSHADOW));
pWD->spcbarbrush = CreateHatchBrush (
HS_BDIAGONAL, GetSysColor (COLOR_HIGHLIGHTTEXT));
pWD->hilightpen = CreatePen (
PS_SOLID, 0, GetSysColor (COLOR_3DHILIGHT));
pWD->shadowpen = CreatePen (
PS_SOLID, 0, GetSysColor (COLOR_3DDKSHADOW));
// GetDeviceCaps returns positive value for displays with 2-256 colors
if (GetDeviceCaps (hdcMem, NUMCOLORS) > 0)
{
hdcScreen = GetDC (NULL);
pWD->barbgbitmap = CreateCompatibleBitmap (hdcScreen, 8, 8);
hOldBitmap = SelectObject (hdcMem, pWD->barbgbitmap);
rc.left = 0;
rc.top = 0;
rc.bottom = 8;
rc.right = 8;
FillRect (hdcMem, &rc, pWD->unselbgbrush);
pen = CreatePen (PS_SOLID, 0, GetSysColor (COLOR_3DLIGHT));
SelectObject (hdcMem, pen);
for (i=-8; i<8; i+=2)
{
MoveToEx (hdcMem, i, 0, NULL);
LineTo (hdcMem, i+8, 8);
}
DeleteObject (pen);
pWD->barbgbrush = CreatePatternBrush (pWD->barbgbitmap);
SelectObject (hdcMem, hOldBitmap);
ReleaseDC (NULL, hdcScreen);
}
// GetDeviceCaps returns -1 for displays with more than 8 bit depth
else
{
rgb = GetSysColor (COLOR_BTNFACE);
r = GetRValue (rgb);
r = 255 - ((255 - r)/2);
g = GetGValue (rgb);
g = 255 - ((255 - g)/2);
b = GetBValue (rgb);
b = 255 - ((255 - b)/2);
pWD->barbgbitmap = NULL;
pWD->barbgbrush = CreateSolidBrush (RGB (r,g,b));
}
if (pWD->style & TLS_USEDEFAULTGUIFONT)
{
GetObject (GetStockObject (DEFAULT_GUI_FONT),
sizeof(LOGFONT), &lf);
}
else
{
SystemParametersInfo (
SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0);
}
pWD->hFont = CreateFontIndirect (&lf);
lf.lfItalic = !lf.lfItalic;
pWD->hFontItalic = CreateFontIndirect (&lf);
lf.lfItalic = !lf.lfItalic;
lf.lfWeight = FW_BOLD;
pWD->hFontBold = CreateFontIndirect (&lf);
SelectObject (hdcMem, pWD->hFont);
GetTextMetrics (hdcMem, &tm);
pWD->iRowHeight = tm.tmHeight + (2 * (TEXTVERTOFF+1)) -1;
if (pWD->iRowHeight <= BITMAPHEIGHT)
pWD->iRowHeight = BITMAPHEIGHT +1;
DeleteDC (hdcMem);
}
// _______________________________________________
//
// Close painting routines -- delete pens, brushes, etc.
void
TLClosePaint (
TLWndData* pWD)
{
DeleteObject (pWD->selbgbrush);
DeleteObject (pWD->unselbgbrush);
DeleteObject (pWD->selfgbrush);
DeleteObject (pWD->unselfgbrush);
DeleteObject (pWD->unfocusbgbrush);
DeleteObject (pWD->stdbarbrush);
DeleteObject (pWD->spcbarbrush);
DeleteObject (pWD->barbgbrush);
DeleteObject (pWD->seltextpen);
DeleteObject (pWD->unseltextpen);
DeleteObject (pWD->buttonpen);
DeleteObject (pWD->hilightpen);
DeleteObject (pWD->shadowpen);
DeleteObject (pWD->hFont);
DeleteObject (pWD->hFontItalic);
DeleteObject (pWD->hFontBold);
if (pWD->barbgbitmap)
DeleteObject (pWD->barbgbitmap);
}
// _______________________________________________
//
// get wide char representation of text
static INT
sGetWideText (
CHAR* psz,
WCHAR* wsz,
UINT ulenWide)
{
const unsigned char* psrc = psz;
WCHAR* pwsz = wsz;
int iIn = 0;
int iOut = 0;
WCHAR u;
if (psrc)
{
while ((*psrc) &&
(iOut < (int)ulenWide))
{
u = 0;
if ((*psrc) < 0x80)
{
u = *psrc++;
iIn++;
}
else if ((*psrc) < 0xC0)
{
// invalid char
}
else if ((*psrc) < 0xE0)
{
u = (*psrc++) & 0x1F;
iIn++;
if ((*psrc & 0xC0) == 0x80)
{
u <<= 6;
u += (*psrc++) & 0x3F;
iIn++;
if (u < 0x80)
u = 0;
}
else
u = 0;
}
else if ((*psrc) < 0xF0)
{
u = (*psrc++) & 0x0F;
iIn++;
u <<= 6;
if ((*psrc & 0xC0) == 0x80)
{
u += (*psrc++) & 0x3F;
iIn++;
u <<= 6;
if ((*psrc & 0xC0) == 0x80)
{
u += (*psrc++) & 0x3F;
iIn++;
if (u < 0x800)
u = 0;
}
else
u = 0;
}
else
u = 0;
}
else
{
// too many bits to hold in a UCS-2 char
}
if (u)
{
*pwsz++ = u;
iOut++;
}
else
{
// invalid character or NULL
iIn = 0;
break;
}
}
}
if (iOut < (int)ulenWide)
{
*pwsz = 0;
}
return iOut;
}
// _______________________________________________
//
// Truncate text string
static BOOL sTruncateText (
HDC hdc,
WCHAR* wsz,
int xmax)
{
BOOL bShowToolTip = FALSE;
SIZE s;
int l, w;
// truncate at <newline>, if present
l = 0;
while (wsz[l])
{
if (wsz[l] == '\n')
{
wsz[l] = 0;
bShowToolTip = TRUE;
break;
}
l++;
}
GetTextExtentPoint32W (hdc, wsz, lstrlenW (wsz), &s);
w = s.cx + 4;
l = lstrlenW (wsz);
if (l < 3)
{
if (w > xmax)
{
bShowToolTip = TRUE;
wsz[0] = 0;
}
}
else
{
l = lstrlenW (wsz) - 3;
while ((w > xmax) && (l >= 0))
{
bShowToolTip = TRUE;
lstrcpyW (&wsz[l], L"...");
GetTextExtentPoint32W (hdc, wsz, lstrlenW (wsz), &s);
w = s.cx + 4;
l--;
}
if (l < 0)
wsz[0] = 0;
}
return bShowToolTip;
}
// _______________________________________________
//
// Calculate how many lines are needed
static int
sCountRows (
TLTreeItem* p)
{
int i = 0;
while (p)
{
i++;
if (p->childItem && (p->state & TLIS_EXPANDED))
i += sCountRows (p->childItem);
p = p->nextItem;
}
return i;
}
// _______________________________________________
//
// Get row number of item
BOOL
TLGetRow (
TLTreeItem* root,
TLTreeItem* p,
int* row)
{
while (root)
{
if (p == root)
return TRUE;
(*row)++;
if (root->childItem && (root->state & TLIS_EXPANDED))
{
if (TLGetRow (root->childItem, p, row))
return TRUE;
}
root = root->nextItem;
}
return FALSE;
}
// _______________________________________________
//
// Item has just been expanded -- scroll window appropriately
void
TLExpandAutoScroll (
TLWndData* pWD,
TLTreeItem* p)
{
int itemRow = 0;
if (TLGetRow (pWD->rootItem, p, &itemRow))
{
if (((itemRow-pWD->iFirstRow) + p->cChildren) >= pWD->iMaxRows)
{
if (p->cChildren >= pWD->iMaxRows)
pWD->iFirstRow = itemRow;
else
pWD->iFirstRow = itemRow + p->cChildren - pWD->iMaxRows +1;
if (pWD->iFirstRow < 0)
pWD->iFirstRow = 0;
}
}
return;
}
// _______________________________________________
//
// Item has just been selected -- scroll window appropriately
BOOL
TLSelectAutoScroll (
TLWndData* pWD,
TLTreeItem* p)
{
int itemRow = 0;
if (TLGetRow (pWD->rootItem, p, &itemRow))
{
if ((itemRow-pWD->iFirstRow) >= pWD->iMaxRows)
{
pWD->iFirstRow = itemRow - pWD->iMaxRows +1;
if (pWD->iFirstRow < 0)
pWD->iFirstRow = 0;
return TRUE;
}
if (itemRow < pWD->iFirstRow)
{
pWD->iFirstRow = max (0, itemRow);
return TRUE;
}
}
return FALSE;
}
// _______________________________________________
//
// Invalidate the specified item
void
TLInvalidateItem (
TLWndData* pWD,
TLTreeItem* p)
{
RECT rc;
rc = p->hiliteRect;
rc.left = pWD->tlInval.left;
InvalidateRect (pWD->hWnd, &rc, TRUE);
}
// _______________________________________________
//
// draw a dotted line by setting alternate pixels
// (callback to LineDDA)
static void CALLBACK
sDottedLineProc (
INT iX,
INT iY,
LPARAM lpData)
{
DOTTEDSTRUCT *pDottedStruct;
pDottedStruct = (DOTTEDSTRUCT*)lpData;
if (!((iX+iY) & 0x0001))
SetPixel (pDottedStruct->hDC, iX, iY, pDottedStruct->dwDottedColor);
}
// _______________________________________________
//
// Paint one level of list
static void
sPaintItems (
HDC hdc,
TLWndData* pWD,
int* item,
int* y,
int indent,
TLTreeItem* p)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -