📄 tlpaint.c
字号:
//:TLPaint.c - paint tree list
//
// $Id: TLPaint.c,v 1.23 1999/03/25 20:52:54 pbj Exp $
//
#include "TLIntern.h"
#include <math.h>
typedef struct _DOTTEDSTRUCT {
HDC hDC;
DWORD dwDottedColor;
} DOTTEDSTRUCT;
//----------------------------------------------------|
// 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));
}
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);
}
//----------------------------------------------------|
// Truncate text string
BOOL TruncateText (HDC hdc, char * szorig, int xmax, char * sztrunc) {
SIZE s;
int l, w;
BOOL bTruncated = FALSE;
lstrcpy (sztrunc, szorig);
GetTextExtentPoint32 (hdc, szorig, lstrlen (szorig), &s);
w = s.cx + 4;
l = lstrlen (szorig);
if (l < 3) {
if (w > xmax) {
bTruncated = TRUE;
lstrcpy (sztrunc, "");
}
}
else {
l = lstrlen (szorig) - 3;
while ((w > xmax) && (l >= 0)) {
bTruncated = TRUE;
lstrcpy (&sztrunc[l], "...");
GetTextExtentPoint32 (hdc, sztrunc, lstrlen (sztrunc), &s);
w = s.cx + 4;
l--;
}
if (l < 0) lstrcpy (sztrunc, "");
}
return bTruncated;
}
//----------------------------------------------------|
// Calculate how many lines are needed
int CountRows (TLTreeItem* p) {
int i = 0;
while (p) {
i++;
if (p->childItem && (p->state & TLIS_EXPANDED))
i += CountRows (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 = 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)
void CALLBACK DottedLineProc (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
void PaintItems (HDC hdc, TLWndData* pWD, int *item, int* y, int indent,
TLTreeItem* p) {
HBRUSH oldbrush, bgbrush, fgbrush, barbrush;
INT iBCent, iBMPos;
HPEN oldpen, textpen;
SIZE s;
INT ix, iy, cx, xoffset;
TLColumnItem* pci;
TLListItem* pli;
RECT rc;
DOTTEDSTRUCT DottedStruct;
double f;
char sz256[256];
iBCent = pWD->iBCent;
iBMPos = pWD->iBMPos;
DottedStruct.hDC = hdc;
xoffset = indent - pWD->iHorizontalPos;
while (p) {
// increment item count
(*item)++;
// check if items are visible in window
if ((*item) > (pWD->iFirstRow + pWD->iMaxRows + 2)) break;
if ((*item) > pWD->iFirstRow) {
// first paint the tree items ...
// select colors based on state of tree item
if (pWD->bTreeFocused) {
if (p->state & (TLIS_SELECTED|TLIS_DRAGGEDOVER)) {
bgbrush = pWD->selbgbrush;
fgbrush = pWD->selfgbrush;
textpen = pWD->seltextpen;
DottedStruct.dwDottedColor = pWD->selfocuscolor;
pWD->textbgcolor = GetSysColor (COLOR_HIGHLIGHT);
SetTextColor (hdc, GetSysColor (COLOR_HIGHLIGHTTEXT));
}
else {
bgbrush = pWD->unselbgbrush;
fgbrush = pWD->unselfgbrush;
textpen = pWD->unseltextpen;
DottedStruct.dwDottedColor = pWD->unselfocuscolor;
pWD->textbgcolor = GetSysColor (COLOR_WINDOW);
SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
}
}
else {
if ((p->state & (TLIS_SELECTED|TLIS_DRAGGEDOVER)) &&
(pWD->style & TLS_SHOWSELECTIONALWAYS)) {
bgbrush = pWD->unfocusbgbrush;
fgbrush = pWD->unselfgbrush;
textpen = pWD->unseltextpen;
DottedStruct.dwDottedColor = pWD->unselfocuscolor;
pWD->textbgcolor = GetSysColor (COLOR_BTNFACE);
SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
}
else {
bgbrush = pWD->unselbgbrush;
fgbrush = pWD->unselfgbrush;
textpen = pWD->unseltextpen;
DottedStruct.dwDottedColor = pWD->unselfocuscolor;
pWD->textbgcolor = GetSysColor (COLOR_WINDOW);
SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
}
}
SetBkColor (hdc, pWD->textbgcolor);
// set rectangle coordinates
// rectangle sensitive to "selection" mouse clicks
p->selectRect.left = xoffset + BUTTONWIDTH;
p->selectRect.right = pWD->tlInval.right;
p->selectRect.top = *y+1;
p->selectRect.bottom = p->selectRect.top + pWD->iRowHeight;
// rectangle sensitive to "button" mouse clicks
if (p->cChildren && (pWD->style & TLS_HASBUTTONS)) {
p->buttonRect.left = xoffset;
p->buttonRect.right = p->buttonRect.left + BUTTONWIDTH;
p->buttonRect.top = *y;
p->buttonRect.bottom = p->buttonRect.top + pWD->iRowHeight;
}
else {
p->buttonRect.left = xoffset + BUTTONWIDTH;
p->buttonRect.right = xoffset + BUTTONWIDTH;
p->buttonRect.top = *y;
p->buttonRect.bottom = 0;
}
// rectangle which is highlighted when item is selected
p->hiliteRect.left =
min (xoffset + BUTTONWIDTH+BITMAPWIDTH+HTEXTSHIFT,
pWD->iFirstColumnWidth);
p->hiliteRect.top = *y+1;
p->hiliteRect.bottom = p->selectRect.top + pWD->iRowHeight;
if (p->state & TLIS_BOLD) SelectObject (hdc, pWD->hFontBold);
else if (p->state & TLIS_ITALICS)
SelectObject (hdc, pWD->hFontItalic);
else SelectObject (hdc, pWD->hFont);
if (TruncateText (hdc, p->pszText,
pWD->iFirstColumnWidth-
(indent + BUTTONWIDTH+BITMAPWIDTH+HTEXTSHIFT),
sz256))
p->state |= TLIS_TRUNCATED;
else
p->state &= ~TLIS_TRUNCATED;
GetTextExtentPoint32 (hdc, sz256, lstrlen (sz256), &s);
p->hiliteRect.right = p->hiliteRect.left + s.cx + HTEXTSHIFT;
pli = p->listItem;
pci = pWD->columnItem;
ix = pWD->iFirstColumnWidth;
while (pci && pli) {
ix += pci->cx;
if (pli->state & TLIS_VISIBLE) p->hiliteRect.right = ix;
pci = pci->nextItem;
pli = pli->nextItem;
}
// if focused, draw box
FillRect (hdc, &p->hiliteRect, bgbrush);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -