📄 rddraw.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: RDdraw.c,v 1.3 2002/08/29 01:57:42 wjb Exp $
____________________________________________________________________________*/
#include "RDprecmp.h"
#include "pgpUnicode.h"
#define MAXUSERIDSTRING kPGPMaxUserIDSize + 32
/*
* OwnDraw.c ListView draw routines to accommidate italics/strikeout
*
* These routines use the ownerdraw characteristic of the standard
* listview to provide custom drawing routines.
*
* Copyright (C) 2002 PGP Corporation
* All rights reserved.
*/
void CreateDrawElements(PGPContextRef context,DRAWSTRUCT *ds)
{
LOGFONT lf;
ds->DisplayMarginal=FALSE;
ds->stdbarbrush =
CreateSolidBrush (GetSysColor (COLOR_3DSHADOW));
ds->spcbarbrush =
CreateHatchBrush(HS_BDIAGONAL, GetSysColor (COLOR_WINDOW));
ds->g_seltextpen =
CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOWTEXT));
ds->g_unseltextpen =
CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOW));
ds->barcolor = GetSysColor (COLOR_3DSHADOW);
ds->buttonpen = CreatePen(PS_SOLID, 0, GetSysColor (COLOR_3DSHADOW));
ds->hilightpen = CreatePen (PS_SOLID, 0,
GetSysColor (COLOR_3DHILIGHT));
ds->shadowpen = CreatePen (PS_SOLID, 0,
GetSysColor (COLOR_3DDKSHADOW));
ds->barbgbrush = CreateSolidBrush (GetSysColor (COLOR_3DFACE));
ds->HighBrush=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
ds->BackBrush=CreateSolidBrush(GetSysColor(COLOR_WINDOW));
SystemParametersInfo (SPI_GETICONTITLELOGFONT,
sizeof(LOGFONT), &lf, 0);
ds->hFont=CreateFontIndirect (&lf);
lf.lfItalic = !lf.lfItalic;
ds->hItalic=CreateFontIndirect (&lf);
lf.lfItalic = !lf.lfItalic;
lf.lfStrikeOut=TRUE;
ds->hStrikeOut = CreateFontIndirect (&lf);
// ImageList Init
PGPsdkUICreateImageList(&(ds->hIml));
}
void DeleteDrawElements(DRAWSTRUCT *ds)
{
DeleteObject(ds->stdbarbrush);
DeleteObject(ds->spcbarbrush);
DeleteObject(ds->g_seltextpen);
DeleteObject(ds->g_unseltextpen);
DeleteObject(ds->hilightpen);
DeleteObject(ds->shadowpen);
DeleteObject(ds->buttonpen);
DeleteObject(ds->barbgbrush);
DeleteObject(ds->HighBrush);
DeleteObject(ds->BackBrush);
DeleteObject(ds->hFont);
DeleteObject(ds->hItalic);
DeleteObject(ds->hStrikeOut);
ImageList_Destroy(ds->hIml);
}
void DrawBar(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
int DataValue,int MaxValue,BOOL Selected)
{
RECT rc;
HBRUSH oldbrush,barbrush;
HPEN oldpen;
COLORREF oldbkcolor;
int cx;
CopyRect(&rc,ptrBarRect);
if(Selected)
{
FillRect (hdc, &rc, ds->HighBrush);
oldpen = SelectObject (hdc, ds->g_unseltextpen);
}
else
{
FillRect (hdc, &rc, ds->BackBrush);
oldpen = SelectObject (hdc, ds->g_seltextpen);
}
rc.top+=5;
rc.left+=5;
rc.bottom-=5;
rc.right-=5;
if(rc.right<=rc.left)
return;
cx=rc.right-rc.left;
oldbrush = SelectObject (hdc, ds->barbgbrush);
SelectObject (hdc, ds->buttonpen);
Rectangle (hdc, rc.left - 1, rc.top - 1,
rc.right + 2, rc.bottom + 2);
SelectObject (hdc, ds->shadowpen);
MoveToEx (hdc, rc.left, rc.bottom, NULL);
LineTo (hdc, rc.left, rc.top);
LineTo (hdc, rc.right, rc.top);
SelectObject (hdc, ds->hilightpen);
LineTo (hdc, rc.right, rc.bottom);
LineTo (hdc, rc.left, rc.bottom);
if (MaxValue != 0)
{
if (DataValue > MaxValue)
{
barbrush = ds->spcbarbrush;
rc.right = rc.left + cx;
}
else
{
barbrush = ds->stdbarbrush;
rc.right = rc.left +
(int)(((float)DataValue /
(float)MaxValue)
* (float)cx);
}
}
else
rc.right = rc.left;
rc.top++;
rc.left++;
if (rc.right > rc.left)
{
oldbkcolor=SetBkColor (hdc, ds->barcolor);
FillRect (hdc, &rc, barbrush);
rc.top--;
rc.left--;
// hilight pen already selected
MoveToEx (hdc, rc.right, rc.top, NULL);
LineTo (hdc, rc.left, rc.top);
LineTo (hdc, rc.left,rc.bottom);
SelectObject (hdc, ds->shadowpen);
LineTo (hdc, rc.right, rc.bottom);
LineTo (hdc, rc.right, rc.top);
SetBkColor(hdc,oldbkcolor);
}
SelectObject (hdc, oldbrush);
SelectObject (hdc, oldpen);
}
void DrawNoviceButton(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
int DataValue,int MaxValue,BOOL Selected)
{
DWORD NoviceIcon;
// HICON hIcon;
if(Selected)
{
FillRect (hdc, ptrBarRect, ds->HighBrush);
}
else
{
FillRect (hdc, ptrBarRect, ds->BackBrush);
}
if((ptrBarRect->right-ptrBarRect->left)>=CX_SMICON)
{
NoviceIcon=IDX_INVALID;
if(DataValue>2)
NoviceIcon=IDX_AXIOMATIC;
if(DataValue==2)
NoviceIcon=IDX_VALID;
if((!ds->MarginalInvalid)&&(DataValue==1))
NoviceIcon=IDX_VALID;
#ifdef _WIN32
ImageList_Draw(ds->hIml,NoviceIcon,
hdc,
ptrBarRect->left+((ptrBarRect->right-ptrBarRect->left-16)/2),
ptrBarRect->top+((ptrBarRect->bottom-ptrBarRect->top-16)/2),
ILD_TRANSPARENT);
#else
hIcon=LoadIcon(gPGPsdkUILibInst,MAKEINTRESOURCE(NoviceIcon));
DrawIcon(hdc,
ptrBarRect->left+((ptrBarRect->right-ptrBarRect->left-32)/2),
ptrBarRect->top+((ptrBarRect->bottom-ptrBarRect->top-32)/2),
hIcon);
DeleteObject(hIcon);
#endif
}
}
LISTSTRUCT *GetListStruct(HWND hwndList)
{
LISTSTRUCT *lsRet;
PRECGBL prg;
prg=(PRECGBL)GetWindowLong(GetParent(hwndList),GWL_USERDATA);
lsRet=&(prg->lsUser);
if(lsRet->hwndlist==hwndList)
return lsRet;
lsRet=&(prg->lsRec);
if(lsRet->hwndlist==hwndList)
return lsRet;
MessageBox(NULL,"Something's fishy","Ooops",MB_OK);
return 0;
}
DRAWSTRUCT *GetDrawStruct(HWND hDlg)
{
PRECGBL prg;
prg=(PRECGBL)GetWindowLong(hDlg,GWL_USERDATA);
return &(prg->ds);
}
void DrawStuff(LPDRAWITEMSTRUCT lpDrawItem)
{
PUSERKEYINFO pui;
DRAWSTRUCT *ds;
LISTSTRUCT *ls;
int index;
RECT rc;
//HICON hIcon;
HWND hDlg,hwndList;
int max;
BOOL focused;
focused=TRUE;
if(lpDrawItem->hwndItem!=0)
{
if(GetFocus()!=lpDrawItem->hwndItem)
focused=FALSE;
}
hwndList=lpDrawItem->hwndItem;
hDlg=GetParent(hwndList);
ls=GetListStruct(hwndList);
ds=GetDrawStruct(hDlg);
pui=(PUSERKEYINFO)(lpDrawItem->itemData);
CopyRect(&rc,&(lpDrawItem->rcItem));
#ifdef _WIN32
ImageList_Draw(ds->hIml,pui->icon,
lpDrawItem->hDC,
rc.left+((CX_SMICON-16)/2),
rc.top+((CY_SMICON-16)/2),
ILD_TRANSPARENT);
#else
hIcon=LoadIcon(gPGPsdkUILibInst,MAKEINTRESOURCE(pui->icon));
DrawIcon(lpDrawItem->hDC,
rc.left+((CX_SMICON-32)/2),
rc.top+((CY_SMICON-32)/2),
hIcon);
DeleteObject(hIcon);
#endif
rc.right=rc.left;
rc.left=rc.left+16;
max=0;
for(index=0;index<NUMCOLUMNS;index++)
{
#if LISTBOX
max=max+ls->colwidth[index];
#else
max=max+
ListView_GetColumnWidth(lpDrawItem->hwndItem,index);
#endif
}
for(index=0;index<NUMCOLUMNS;index++)
{
#if LISTBOX
rc.right=rc.right+ls->colwidth[index];
#else
rc.right=rc.right+
ListView_GetColumnWidth(lpDrawItem->hwndItem,index);
#endif
switch(index)
{
case 0:
{
HFONT oldFont;
RECT origrc;
// Save original rect
CopyRect(&origrc,&rc);
oldFont=SelectObject(lpDrawItem->hDC,
ds->hFont);
if(pui->pru->kind==kPGPRecipientUserKind_MissingRecipient)
SelectObject(lpDrawItem->hDC,
ds->hStrikeOut);
// See if we need the lock icon
if(pui->pru->lockRefCount!=0)
{
RECT temprc;
CopyRect(&temprc,&rc);
temprc.left=temprc.right-16;
if(temprc.left>rc.left)
{
// Enough space. Draw Lock
if((BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused)
{
FillRect (lpDrawItem->hDC, &temprc, ds->HighBrush);
}
else
{
FillRect (lpDrawItem->hDC, &temprc, ds->BackBrush);
}
ImageList_Draw(ds->hIml,IDX_CLOSEDLOCK,
lpDrawItem->hDC,
temprc.left+((CX_SMICON-16)/2),
temprc.top+((CY_SMICON-16)/2),
ILD_TRANSPARENT);
// Make space for lock from text
rc.right=rc.right-16;
}
}
DrawItemColumn(lpDrawItem->hDC,pui->UserId,
&rc);
// Set rectangle back to original
CopyRect(&rc,&origrc);
SelectObject(lpDrawItem->hDC,oldFont);
break;
}
case 1:
{
if(ds->DisplayMarginal)
DrawBar(ds,lpDrawItem->hDC,&rc,pui->Validity,
2,(BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused);
else
DrawNoviceButton(ds,lpDrawItem->hDC,&rc,pui->Validity,
2,(BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused);
break;
}
/* case 2: // we no longer display trust in rec dlg
{
DrawBar(ds,lpDrawItem->hDC,&rc,pui->Trust,
2,(BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused);
break;
}
*/
case 2:
{
HFONT oldFont;
oldFont=SelectObject(lpDrawItem->hDC,
ds->hFont);
DrawItemColumn(lpDrawItem->hDC,pui->szSize,
&rc);
SelectObject(lpDrawItem->hDC,oldFont);
break;
}
}
rc.left=rc.right;
}
lpDrawItem->rcItem.right=max;
}
//
// DrawListViewItem
//
// This routine, given a standard Windows LPDRAWITEMSTRUCT, draws the
// elements of our custom listview (adapted from a routine in the Microsoft
// Knowledge base)
//
void DrawListViewItem(LPDRAWITEMSTRUCT lpDrawItem)
{
UINT uiFlags;
BOOL focused;
focused=TRUE;
if(lpDrawItem->hwndItem!=0)
{
if(GetFocus()!=lpDrawItem->hwndItem)
focused=FALSE;
}
uiFlags=ILD_TRANSPARENT;
// Check to see if this item is selected
if ((lpDrawItem->itemState & ODS_SELECTED)&&(focused))
{
// Set the text background and foreground colors
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
// Also add the ILD_BLEND50 so the images come out selected
uiFlags |= ILD_BLEND50;
}
else
{
// Set the text background and foreground colors to the
// standard window colors
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
}
DrawStuff(lpDrawItem);
lpDrawItem->rcItem.left=lpDrawItem->rcItem.left+CX_SMICON;
if(!focused)
return;
// If we changed the colors for the selected item, undo it
if (lpDrawItem->itemState & ODS_SELECTED)
{
// Set the text background and foreground colors
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
}
// If the item is focused, now draw a focus rect around the entire row
if (lpDrawItem->itemState & ODS_FOCUS)
{
// Draw the focus rect
DrawFocusRect(lpDrawItem->hDC, &(lpDrawItem->rcItem));
}
return;
}
// _______________________________________________
//
// 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;
}
// DrawItemColumn
//
// Given a clipping rectange and some text, see how well we can fit
// it in there, and tack on ... if we can't
void DrawItemColumn(HDC hdc, LPTSTR lpsz, LPRECT prcClip)
{
WCHAR wsz[MAXUSERIDSTRING];
UINT ulen;
pgpUTF8StringToUCS2 (lpsz, kPGPUnicodeNullTerminated,
wsz, MAXUSERIDSTRING, &ulen);
sTruncateText (hdc, wsz, prcClip->right - prcClip->left);
// print the text
ExtTextOutW(hdc, prcClip->left + 2, prcClip->top + 1,
ETO_CLIPPED | ETO_OPAQUE,
prcClip,
wsz,
lstrlenW(wsz),
NULL);
}
// Main_OnDrawItem
//
// Entry function for the message handler. Basically, we want to draw
// the whole thing no matter what.
BOOL Main_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
{
// Make sure the control is the listview control
if ((lpDrawItem->CtlType != ODT_LISTVIEW)&&
(lpDrawItem->CtlType != ODT_LISTBOX))
return FALSE;
if(!IsWindowEnabled(lpDrawItem->hwndItem))
return FALSE;
switch (lpDrawItem->itemAction)
{
case ODA_DRAWENTIRE:
case ODA_FOCUS:
case ODA_SELECT:
DrawListViewItem((LPDRAWITEMSTRUCT)lpDrawItem);
break;
}
return TRUE;
}
// Main_OnMeasureItem
//
// Entry function for the message handler. We need to get the width and
// height of the font we're using.
void Main_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT * lpMeasureItem)
{
TEXTMETRIC tm;
HDC hdc;
HWND hwndLV;
HFONT hFont;
// Make sure the control is the listview control
if ((lpMeasureItem->CtlType != ODT_LISTVIEW)&&
(lpMeasureItem->CtlType != ODT_LISTBOX))
return;
// Get the handle of the ListView control we're using
hwndLV = GetDlgItem(hwnd, lpMeasureItem->CtlID);
// Get the font the control is currently using
hFont = (HFONT)(DWORD) SendMessage(hwndLV, WM_GETFONT, 0, 0L);
// Set the font of the DC to the same font the control is using
hdc = GetDC(hwndLV);
SelectObject(hdc, hFont);
// Get the height of the font used by the control
if (!GetTextMetrics(hdc, &tm))
return;
// Add a little extra space between items
lpMeasureItem->itemHeight = tm.tmHeight + 1;
// Make sure there is enough room for the images which are CY_SMICON high
if (lpMeasureItem->itemHeight < (CY_SMICON + 1))
lpMeasureItem->itemHeight = CY_SMICON + 1;
// Clean up
ReleaseDC(hwndLV, hdc);
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -