📄 cpublickeysview.cpp
字号:
{
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;
}
#define MAXUSERIDSTRING kPGPMaxUserIDSize + 32
void
CPublicKeysView::DrawItemColumn(
CDC& itemDC,
const char *userID,
const CRect& prcClip) const
{
PGPUInt32 ulen;
WCHAR wsz[MAXUSERIDSTRING];
// CString cuserID(userID);
// itemDC.FitStringToWidth(cuserID, prcClip.Width());
// itemDC.ExtTextOut(prcClip.Left() + 2, prcClip.Top() + 1,
// ETO_CLIPPED | ETO_OPAQUE, prcClip, cuserID, cuserID.Length(), NULL);
pgpUTF8StringToUCS2 (userID, kPGPUnicodeNullTerminated,
wsz, MAXUSERIDSTRING, &ulen);
sTruncateText (itemDC.DC(), wsz, prcClip.Right() - prcClip.Left());
// print the text
ExtTextOutW(itemDC.DC(), prcClip.Left() + 2, prcClip.Top() + 1,
ETO_CLIPPED | ETO_OPAQUE,
prcClip,
wsz,
lstrlenW(wsz),
NULL);
}
void
CPublicKeysView::DrawKeyItemAux(
LPDRAWITEMSTRUCT pDIS,
PGPBoolean isFocused) const
{
PubKeyItem *pItem = reinterpret_cast<PubKeyItem *>(pDIS->itemData);
pgpAssertAddrValid(pItem, PubKeyItem);
CDC itemDC(pDIS->hDC);
CRect itemRect = pDIS->rcItem;
mPDE->image.Draw(pItem->icon, itemDC, PixelsLeftMargin, itemRect.Top(),
ILD_TRANSPARENT);
itemRect.Left() = CIcon::kSmallIconWidth + PixelsLeftMargin;
if (mActiveColumns & kUserIDColFlag)
{
itemRect.Right() = GetColumnWidth(mUserIDColIndex);
CFont oldFont(itemDC.SelectObject(mPDE->hFont.Get()));
CRect origRect(itemRect);
if (pItem->isOnlyKeyIDValid)
itemDC.SelectObject(mPDE->hStrikeOut.Get());
// See if we need the lock icon.
if (pItem->locked)
{
CRect tempRect(itemRect);
tempRect.Left() = tempRect.Right() - CIcon::kSmallIconWidth;
// Enough space. Draw Lock.
if (tempRect.Left() > itemRect.Left())
{
if ((pDIS->itemState & ODS_SELECTED) && isFocused)
itemDC.FillRect(tempRect, mPDE->highBrush);
else
itemDC.FillRect(tempRect, mPDE->backBrush);
}
mPDE->image.Draw(ImageIDs::kClosedLock, itemDC, tempRect.Left(),
tempRect.Top(), ILD_TRANSPARENT);
// Make space for lock from text.
itemRect.Right() -= CIcon::kSmallIconWidth;
}
DrawItemColumn(itemDC, pItem->userID, itemRect);
itemRect.Left() = itemRect.Right();
}
if (mActiveColumns & kValidityColFlag)
{
itemRect.Right() += GetColumnWidth(mValidityColIndex);
if (mDisplayMarginal)
{
DrawBar(itemDC, itemRect, pItem->validity, 2,
((pDIS->itemState & ODS_SELECTED) && isFocused));
}
else
{
DrawNoviceButton(itemDC, itemRect, pItem->validity, 2,
((pDIS->itemState & ODS_SELECTED) && isFocused));
}
itemRect.Left() = itemRect.Right();
}
if (mActiveColumns & kSizeColFlag)
{
itemRect.Right() += GetColumnWidth(mSizeColIndex);
CFont oldFont(itemDC.SelectObject(mPDE->hFont.Get()));
DrawItemColumn(itemDC, pItem->sizeStr, itemRect);
itemDC.SelectObject(oldFont.Get());
itemRect.Left() = itemRect.Right();
}
}
void
CPublicKeysView::DrawKeyItem(LPDRAWITEMSTRUCT pDIS) const
{
PGPBoolean isFocused = TRUE;
if (GetFocus() != Handle())
isFocused = FALSE;
CDC dc(pDIS->hDC);
PGPUInt32 uiFlags = ILD_TRANSPARENT;
// Check to see if this item is selected
if ((pDIS->itemState & ODS_SELECTED) && isFocused)
{
// Set the text background and foreground colors
dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(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
dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(GetSysColor(COLOR_WINDOW));
}
DrawKeyItemAux(pDIS, isFocused);
pDIS->rcItem.left += CIcon::kSmallIconWidth;
if (!isFocused)
return;
// If we changed the colors for the selected item, undo it
if (pDIS->itemState & ODS_SELECTED)
{
// Set the text background and foreground colors
dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(GetSysColor(COLOR_WINDOW));
}
// If the item is focused, now draw a focus rect around the entire row
// if (pDIS->itemState & ODS_FOCUS)
// dc.DrawFocusRect(pDIS->rcItem);
}
CPublicKeysView::PubKeyItem *
CPublicKeysView::GetItemAtIndex(PGPInt32 i) const
{
LVITEM lvi;
lvi.mask = LVIF_PARAM;
lvi.iItem = i;
lvi.iSubItem = 0;
GetItem(&lvi);
return reinterpret_cast<PubKeyItem *>(lvi.lParam);
}
PGPInt32
CPublicKeysView::GetIndexOfItem(const PubKeyItem *pItem) const
{
LVFINDINFO lvfi;
pgpClearMemory(&lvfi, sizeof(lvfi));
lvfi.flags = LVFI_PARAM;
lvfi.lParam = reinterpret_cast<LPARAM>(pItem);
return FindItem(-1, &lvfi);
}
void
CPublicKeysView::UpdateKeyItemInfo(PubKeyItem *pItem)
{
pgpAssertAddrValid(pItem, PubKeyItem);
CPGPKeyID keyID(pItem->keyID);
if (pItem->isOnlyKeyIDValid)
{
pItem->icon = ImageIDs::kInvalidUserId;
pItem->validity = 0;
pItem->trust = 0;
strcpy(pItem->sizeStr, UCommonStrings::Get(
UCommonStrings::kUnknownUserSizeString));
CString userID;
GetUnknownUserIDString(keyID, userID);
strcpy(pItem->userID, userID);
}
else
{
CPGPKey key(pItem->key);
if (key.GetBooleanProp(kPGPKeyProperty_IsAxiomatic))
{
pItem->validity = ConvertFromPGPValidity(
kPGPValidity_Complete) + 1;
pItem->trust = ConvertFromPGPTrust(kPGPKeyTrust_Ultimate) + 1;
}
else
{
pItem->validity = ConvertFromPGPValidity(
key.GetNumericProp(kPGPKeyProperty_Validity));
pItem->trust = ConvertFromPGPTrust(
key.GetNumericProp(kPGPKeyProperty_Trust));
}
if (keyID.Algorithm() == kPGPPublicKeyAlgorithm_RSA)
{
if (key.GetBooleanProp(kPGPKeyProperty_CanDecrypt))
pItem->icon = ImageIDs::kRSASecKey;
else
pItem->icon = ImageIDs::kRSAPubKey;
sprintf(pItem->sizeStr, "%i",
key.GetNumericProp(kPGPKeyProperty_Bits));
}
else
{
if (key.GetBooleanProp(kPGPKeyProperty_CanDecrypt))
pItem->icon = ImageIDs::kDSASecKey;
else
pItem->icon = ImageIDs::kDSAPubKey;
CPGPKey subKey(pItem->subKey);
sprintf(pItem->sizeStr, "%i/%i",
subKey.GetNumericProp(kPGPSubKeyProperty_Bits),
key.GetNumericProp(kPGPKeyProperty_Bits));
}
CString userID;
key.GetPrimaryUserIDName(userID);
UString::SmartStringCopy(pItem->userID, userID,
sizeof(pItem->userID));
}
}
void
CPublicKeysView::AddKeyItem(PubKeyItem *pItem)
{
pgpAssert(FindKeyIDIndex(pItem->keyID) == -1);
UpdateKeyItemInfo(pItem);
LV_ITEM lvItem;
pgpClearMemory(&lvItem, sizeof(lvItem));
lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
lvItem.lParam = reinterpret_cast<LPARAM>(pItem);
lvItem.iImage = 0;
lvItem.pszText = pItem->userID;
lvItem.iSubItem = 0;
lvItem.iItem = GetItemCount();
InsertItem(&lvItem);
mItemList.AddTail(pItem);
}
void
CPublicKeysView::CreateDrawElements()
{
pgpAssert(IsNull(mPDE));
auto_ptr<PKViewDrawElements> pDE(new PKViewDrawElements);
pDE->stdBarBrush.CreateSolid(GetSysColor(COLOR_3DSHADOW));
pDE->spcBarBrush.CreateHatch(HS_BDIAGONAL, GetSysColor(COLOR_WINDOW));
pDE->gSelTextPen.Create(PS_SOLID, 0, GetSysColor(COLOR_WINDOWTEXT));
pDE->gUnselTextPen.Create(PS_SOLID, 0, GetSysColor(COLOR_WINDOW));
pDE->barColor = GetSysColor(COLOR_3DSHADOW);
pDE->buttonPen.Create(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));
pDE->hilightPen.Create(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));
pDE->barBGBrush.CreateSolid(GetSysColor(COLOR_3DFACE));
pDE->highBrush.CreateSolid(GetSysColor(COLOR_HIGHLIGHT));
pDE->backBrush.CreateSolid(GetSysColor(COLOR_WINDOW));
LOGFONT lf;
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0);
pDE->hFont.CreateIndirect(lf);
lf.lfItalic = !lf.lfItalic;
pDE->hItalic.CreateIndirect(lf);
lf.lfItalic = !lf.lfItalic;
lf.lfStrikeOut = TRUE;
pDE->hStrikeOut.CreateIndirect(lf);
// Initialize image list.
CDC dc;
dc.AttachFromWindow(NULL, TRUE); // DC for desktop
PGPUInt32 numBits = dc.GetDeviceCaps(BITSPIXEL) *
dc.GetDeviceCaps(PLANES);
if (numBits <= 8)
{
pDE->image.Create(CIcon::kSmallIconWidth, CIcon::kSmallIconHeight,
ILC_COLOR | ILC_MASK, ImageIDs::kNumPubKeyBitmaps, 0);
CBitmap images(UModuleInstance::Get(),
MAKEINTRESOURCE(IDB_PKIMAGES4BIT));
pDE->image.AddMasked(images, ImageIDs::kMaskColor);
}
else
{
pDE->image.Create(CIcon::kSmallIconWidth, CIcon::kSmallIconHeight,
ILC_COLOR24 | ILC_MASK, ImageIDs::kNumPubKeyBitmaps, 0);
CBitmap images(UModuleInstance::Get(),
MAKEINTRESOURCE(IDB_PKIMAGES24BIT));
pDE->image.AddMasked(images, ImageIDs::kMaskColor);
}
mPDE = pDE.release();
}
void
CPublicKeysView::DeleteDrawElements()
{
pgpAssert(IsntNull(mPDE));
delete mPDE;
mPDE = NULL;
}
void
CPublicKeysView::UpdateColumns()
{
using namespace UCommonStrings;
DeleteColumn(mUserIDColIndex);
DeleteColumn(mValidityColIndex);
DeleteColumn(mSizeColIndex);
CRect listRect;
GetClientRect(listRect);
LV_COLUMN lvCol;
pgpClearMemory(&lvCol, sizeof(lvCol));
lvCol.mask = LVCF_WIDTH | LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT;
PGPUInt32 i = 0;
PGPInt32 listWidth = listRect.Width();
if (mActiveColumns & kUserIDColFlag)
{
lvCol.fmt = LVCFMT_LEFT;
lvCol.pszText = const_cast<char *>(Get(kPubKeysViewUserIDCol));
lvCol.cx = static_cast<PGPInt32>(kUserIDColRatio*listWidth);
mUserIDColIndex = InsertColumn(i++, &lvCol);
}
if (mActiveColumns & kValidityColFlag)
{
lvCol.fmt = LVCFMT_CENTER;
lvCol.pszText = const_cast<char *>(Get(kPubKeysViewValidityCol));
lvCol.cx = static_cast<PGPInt32>(kValidityColRatio*listWidth);
mValidityColIndex = InsertColumn(i++, &lvCol);
}
if (mActiveColumns & kSizeColFlag)
{
lvCol.fmt = LVCFMT_LEFT;
lvCol.pszText = const_cast<char *>(Get(kPubKeysViewSizeCol));
lvCol.cx = static_cast<PGPInt32>(kSizeColRatio*listWidth);
mSizeColIndex = InsertColumn(i++, &lvCol);
}
}
void
CPublicKeysView::GenerateMeasureItem() const
{
// Fool the system into sending us a new WM_MEASUREITEM.
CRect rect;
GetWindowRect(rect);
WINDOWPOS wp;
wp.hwnd = Handle();
wp.cx = rect.Width();
wp.cy = rect.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, reinterpret_cast<LPARAM>(&wp));
}
BOOL
CPublicKeysView::OnDrawItem(PGPUInt16 ctrlId, LPDRAWITEMSTRUCT pDIS)
{
if (!IsWindowEnabled())
return FALSE;
switch (pDIS->itemAction)
{
case ODA_DRAWENTIRE:
case ODA_FOCUS:
case ODA_SELECT:
DrawKeyItem(pDIS);
break;
}
return TRUE;
}
void
CPublicKeysView::OnKeyDown(PGPUInt32 vKey, PGPUInt32 keyData)
{
switch (vKey)
{
case 'a':
case 'A':
// Select all items on ctrl-A.
if (!mSingleSelect && (GetAsyncKeyState(VK_CONTROL) & 1))
SelectAllItems();
else
CListView::OnKeyDown(vKey, keyData);
break;
default:
CListView::OnKeyDown(vKey, keyData);
break;
}
}
BOOL
CPublicKeysView::OnMeasureItem(PGPUInt16 ctrlId, LPMEASUREITEMSTRUCT pMIS)
{
if (pMIS->CtlType != ODT_LISTVIEW)
return FALSE;
CDC listDC;
CFont font(GetFont());
listDC.AttachFromWindow(Handle());
HFONT oldFont = listDC.SelectObject(font.Get());
TEXTMETRIC tm;
if (!listDC.GetTextMetrics(&tm))
return TRUE;
// Add a little extra space between items.
pMIS->itemHeight = tm.tmHeight + 1;
if (pMIS->itemHeight < (CIcon::kSmallIconHeight + 1))
pMIS->itemHeight = CIcon::kSmallIconHeight + 1;
listDC.SelectObject(oldFont);
listDC.Clear();
return TRUE;
}
PGPUInt32
CPublicKeysView::OnNotify(PGPUInt16 ctrlId, LPNMHDR pNMHDR)
{
if (pNMHDR->hwndFrom == Handle())
{
NMLISTVIEW *pNMLV = reinterpret_cast<NMLISTVIEW *>(pNMHDR);
if (pNMHDR->code == LVN_COLUMNCLICK)
SortOnColumn(pNMLV->iSubItem);
return 0;
}
else
{
return CListView::OnNotify(ctrlId, pNMHDR);
}
}
void
CPublicKeysView::OnNcDestroy()
{
CListView::OnNcDestroy();
Clear();
}
void
CPublicKeysView::OnSysColorChange()
{
CListView::OnSysColorChange();
DeleteDrawElements();
CreateDrawElements();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -