📄 resorgsymbolslistctrl.cpp
字号:
/************************************************************************
*
* Resource ID Organiser Utility Library
*
* (c) Copyright 2001 by Andy Metcalfe (andy.metcalfe@lineone.net)
* All rights reserved.
*
************************************************************************
*
* Filename : ResOrgSymbolsListCtrl.cpp
*
* Description : CResOrgSymbolsListCtrl - list control class for a
* resource symbol file
*
* Compiler : Microsoft Visual C++ 6.0, Service Pack 3 or 4
*
* Target
* Environment : Windows 98/NT
*
* NOTE:
*
* This software is provided "as is" free for personal use. All
* title and copyrights in and to the software, including but not
* limited to any images, text, etc. incorporated into it, are
* owned by Andy Metcalfe, except where acknowledged otherwise.
*
* Your may freely to use this code in your own products, PROVIDED
* this notice is not removed or modified.
*
*
* Visit http://www.resorg.co.uk for latest updates
*
************************************************************************
*
* MODIFICATION HISTORY:
*
* This is a controlled document. See project configuration
* control tool for latest version and full version history.
*
* $Archive: /Projects/AddIns/ResOrg/ResOrgUtils/ResOrgSymbolsListCtrl.cpp $
* $Revision: 5 $
* $Date: 2/04/01 17:39 $
* $Author: Andy $
*
* $History: ResOrgSymbolsListCtrl.cpp $
*
* ***************** Version 5 *****************
* User: Andy Date: 2/04/01 Time: 17:39
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* 1. Fix a bug introduced in ResOrg 1.3.2: icons were not displaying
* when the control was used as a child window of a view
* 2. Highlight symbols with name (as well as value) conflicts in bold
*
* ***************** Version 4 *****************
* User: Andy Date: 27/03/01 Time: 15:23
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* 1. Made the "Status" column optional
* 2. Modifications to allow use in the "Symbol Conflicts" property page
*
* ***************** Version 3 *****************
* User: Andy Date: 5/03/01 Time: 19:01
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* CResOrgSymbolsListCtrl::SortList() now calls the base class to set the
* sort image on the header control
*
* ***************** Version 2 *****************
* User: Andy Date: 2/03/01 Time: 17:07
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Increased the width of the "Status" column
*
* ***************** Version 1 *****************
* User: Andy Date: 17/02/01 Time: 6:47
* Created in $/Projects/AddIns/ResOrg/ResOrgUtils
*
* ***************** Version 3 *****************
* User: Andy Date: 29/11/00 Time: 18:38
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added file banners
*
* $Nokeywords: $
*
************************************************************************/
// ResOrgSymbolsListCtrl.cpp : implementation file
//
#include "StdAfx.h"
#include "ResOrgUtils_Priv.h"
#include "ResourceSymbol.h"
#include "ResourceSymbolBuffer.h"
#include "ResOrgSymbolsListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Definitions for List Control column indices and titles
enum
{
UNKNOWN_COLUMN = -1,
NAME_COLUMN = 0,
TYPE_COLUMN,
ID_COLUMN,
STATUS_COLUMN
};
static DATA_TYPE eColumnType[] =
{
DT_STRING, // Name
DT_STRING, // Type
DT_DEC, // ID
DT_STRING // Status
};
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListCtrl class
/******************************************************************************
* Message Map implementation
*
******************************************************************************/
BEGIN_MESSAGE_MAP(CResOrgSymbolsListCtrl, CResOrgSymbolsListCtrl_BASE)
//{{AFX_MSG_MAP(CResOrgSymbolsListCtrl)
ON_WM_CREATE()
//}}AFX_MSG_MAP
// The following are outside of ClassWizard's reach as it can't understand
// them....
ON_NOTIFY_REFLECT( NM_CUSTOMDRAW, OnCustomDraw)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListCtrl construction/destruction
CResOrgSymbolsListCtrl::CResOrgSymbolsListCtrl(void)
{
m_nSortColumn = ID_COLUMN;
m_bSortAscending = true;
m_pResourceSymbolBuffer = NULL;
m_bShowStatusColumn = TRUE;
}
CResOrgSymbolsListCtrl::~CResOrgSymbolsListCtrl(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListCtrl overrides
void CResOrgSymbolsListCtrl::PreSubclassWindow(void)
{
if (m_ctrlImages.GetSafeHandle() == NULL)
{
m_ctrlImages.Create(SMALL_ICON_CX,
SMALL_ICON_CY, // Small icon
ILC_COLOR | ILC_MASK, // Colour depth
0, // Initial images
1); // Growby
SetImageList(&m_ctrlImages, LVSIL_SMALL);
}
CResOrgSymbolsListCtrl_BASE::PreSubclassWindow();
}
/******************************************************************************
* Sort the contents of the control by the specified column
*
******************************************************************************/
bool CResOrgSymbolsListCtrl::SortList(int nColumn, bool bAscending)
{
CResOrgSymbolsListCtrl_BASE::SortList(nColumn, bAscending);
m_nSortColumn = nColumn;
m_bSortAscending = bAscending;
// Re-sort contents if sorted before
if (m_nSortColumn >= 0)
{
CResOrgSymbolsListCtrl_BASE::SortList(nColumn, bAscending);
CCJSortClass sorter(this, nColumn);
sorter.Sort(bAscending, eColumnType[nColumn]);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListCtrl implementation
/******************************************************************************
* Initialise the list control before display.
*
******************************************************************************/
void CResOrgSymbolsListCtrl::Initialise(BOOL bFlatHeader /*= FALSE*/,
BOOL bShowStatusColumn /*= TRUE*/)
{
m_bShowStatusColumn = bShowStatusColumn;
// Create the columns in the the List Control
//
// For each row the properties specified are:
//
// 1. SubItem field number (0 based)
// 2. Text
// 3. Justification
// 4. Initial width in pixels, size to content (LVSCW_AUTOSIZE) or
// size to header (LVSCW_AUTOSIZE_USEHEADER)
//
// Change list control style to have:
//
// 1. Flat header (requires CJListCtrl)
// 2. Full row selection (requires ComCtl32.dll v4.71)
//
if (bFlatHeader)
{
SubclassHeader();
}
SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT);
VERIFY (-1 != InsertColumn(NAME_COLUMN, _T("Name"), LVCFMT_LEFT, 200, 0) );
VERIFY (-1 != InsertColumn(TYPE_COLUMN, _T("Type"), LVCFMT_LEFT, 100, 0) );
VERIFY (-1 != InsertColumn(ID_COLUMN, _T("Value"), LVCFMT_LEFT, 80, 1));
if (m_bShowStatusColumn)
{
VERIFY (-1 != InsertColumn(STATUS_COLUMN, _T("Status"), LVCFMT_LEFT, 300, 1));
}
}
/******************************************************************************
* Fill the list control with data
*
******************************************************************************/
void CResOrgSymbolsListCtrl::AddSymbols(CResourceSymbolBuffer* pResourceSymbolBuffer)
{
m_pResourceSymbolBuffer = pResourceSymbolBuffer;
SetRedraw(FALSE);
DeleteAllItems();
if (m_pResourceSymbolBuffer->GetSymbolCount() > 0)
{
POSITION pos = m_pResourceSymbolBuffer->GetFirstSymbolPosition();
while (pos != NULL)
{
CResourceSymbol* pSymbol = m_pResourceSymbolBuffer->GetNextSymbol(pos);
if (pSymbol != NULL)
{
AddSymbol(pSymbol);
}
}
SortList(m_nSortColumn, m_bSortAscending);
//AutoSizeColumn();
}
SetRedraw(TRUE);
Invalidate();
UpdateWindow();
RedrawWindow();
}
BOOL CResOrgSymbolsListCtrl::AddSymbol(CResourceSymbol* pSymbol)
{
int nItem = FindSymbol(pSymbol);
if (nItem < 0)
{
int nItem = InsertItem( GetItemCount(),
_T(""));
if (nItem >= 0)
{
SetItemData(nItem, (LPARAM)pSymbol);
UpdateSymbol(pSymbol);
return TRUE;
}
}
return FALSE;
}
BOOL CResOrgSymbolsListCtrl::UpdateSymbol(CResourceSymbol* pSymbol)
{
int nItem = FindSymbol(pSymbol);
if (nItem >= 0)
{
CString sLabel = pSymbol->GetName();
if (pSymbol->IsModified())
{
sLabel += _T(" *");
}
int nIconID = SymbolTypes.GetIconID( pSymbol->GetType() );
LVITEM item;
item.iItem = nItem;
item.iSubItem = NAME_COLUMN;
item.mask = LVIF_IMAGE ;//| LVIF_STATE;
item.iImage = m_ctrlImages.AddIcon(nIconID);
SetItem(&item);
SetItemText(nItem, NAME_COLUMN, sLabel);
SetItemText(nItem, TYPE_COLUMN, pSymbol->GetTypeName() );
/*
LVITEM item;
item.iItem = nItem;
item.iSubItem = TYPE_COLUMN;
item.mask = LVIF_IMAGE ;//| LVIF_STATE;
item.iImage = m_ctrlImages.AddIcon(nIconID);
SetItem(&item);
*/
SetItemText(nItem, ID_COLUMN, ::UIntToStr(pSymbol->GetValue()) );
if (m_bShowStatusColumn)
{
SetItemText(nItem, STATUS_COLUMN, m_pResourceSymbolBuffer->GetDisplayedStatus(pSymbol) );
}
}
return (nItem != -1);
}
BOOL CResOrgSymbolsListCtrl::RemoveSymbol(CResourceSymbol* pSymbol)
{
int nItem = FindSymbol(pSymbol);
if (nItem >= 0)
{
DeleteItem(nItem);
return TRUE;
}
return FALSE;
}
void CResOrgSymbolsListCtrl::RemoveAllSymbols(void)
{
DeleteAllItems();
}
BOOL CResOrgSymbolsListCtrl::Sort(void)
{
if (m_nSortColumn >= NAME_COLUMN)
{
SortList(m_nSortColumn, m_bSortAscending);
return TRUE;
}
return FALSE;
}
int CResOrgSymbolsListCtrl::FindSymbol(CResourceSymbol* pSymbol) const
{
int nItem = -1;
if (pSymbol != NULL)
{
LV_FINDINFO FindInfo;
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (DWORD)pSymbol;
nItem = FindItem(&FindInfo);
}
return nItem;
}
CResourceSymbol* CResOrgSymbolsListCtrl::LookupSelection(void) const
{
CResourceSymbol* pSymbol = NULL;
if (GetSelectedCount() == 1)
{
// Work out which one is selected
int nItem = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if (-1 != nItem)
{
// Get the data value from nItem
// This translates into a pointer to the data object
pSymbol = (CResourceSymbol*)GetItemData(nItem);
#ifdef _DEBUG
ASSERT(pSymbol != NULL);
if (pSymbol != NULL)
{
ASSERT_KINDOF(CResourceSymbol, pSymbol);
}
#endif
}
}
return pSymbol;
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListCtrl message handlers
int CResOrgSymbolsListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int nResult = CResOrgSymbolsListCtrl_BASE::OnCreate(lpCreateStruct);
if (-1 != nResult)
{
if (m_ctrlImages.GetSafeHandle() == NULL)
{
m_ctrlImages.Create(SMALL_ICON_CX,
SMALL_ICON_CY, // Small icon
ILC_COLOR | ILC_MASK, // Colour depth
0, // Initial images
1); // Growby
}
if (NULL == GetImageList(LVSIL_SMALL) )
{
SetImageList(&m_ctrlImages, LVSIL_SMALL);
}
}
return nResult;
}
void CResOrgSymbolsListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
CResOrgSymbolsListCtrl_BASE::OnCustomDraw(pNMHDR, pResult);
switch (lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW; // Request prepaint notifications for each item.
break;
case CDDS_ITEMPREPAINT: // Requested notification
if (lplvcd->nmcd.dwItemSpec >= 0)
{
if (m_bShowStatusColumn)
{
CResourceSymbol* pSymbol = (CResourceSymbol*)lplvcd->nmcd.lItemlParam;
if (NULL != pSymbol)
{
if (pSymbol->IsReadOnly())
{
lplvcd->clrText = ::GetSysColor(COLOR_GRAYTEXT);
// Request a post-paint notification so we can draw a grayed icon
*pResult = CDRF_NOTIFYPOSTPAINT;
}
else if ( !m_pResourceSymbolBuffer->IsUnique( pSymbol->GetName() ) ||
!m_pResourceSymbolBuffer->IsUnique(pSymbol->GetValue() ) )
{
// Highlight conflicting symbols in red...
lplvcd->clrText = RGB(255,0,0);
}
else if (pSymbol->IsModified())
{
// ...and changed symbols in blue...
lplvcd->clrText = RGB(0,0,255);
}
}
}
else
{
lplvcd->clrText = m_clrText;
}
}
break;
case CDDS_ITEMPOSTPAINT:
{
// Draw a "grayed" icon for read-only symbols
CResourceSymbol* pSymbol = (CResourceSymbol*)lplvcd->nmcd.lItemlParam;
if (NULL != pSymbol)
{
if (pSymbol->IsReadOnly())
{
// First, retrieve the image index
LV_ITEM item;
item.iItem = (int)lplvcd->nmcd.dwItemSpec;
item.iSubItem = 0;
item.mask = LVIF_IMAGE | LVIF_STATE;
GetItem(&item);
// Get the rectangle of the item from the list control
// The topleft corner is the point we need to draw the icon at
CRect rectIcon;
GetItemRect(item.iItem, &rectIcon, LVIR_ICON);
CPoint p( rectIcon.TopLeft() );
// Obtain a device context and a handle to the icon
CDC* pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
ASSERT(pDC != NULL);
HICON hIcon = m_ctrlImages.ExtractIcon(item.iImage);
ASSERT(hIcon != NULL);
// At last! Draw it...
pDC->DrawState(p, CSize(0,0), hIcon, DSS_DISABLED, (HBRUSH)NULL);
// Finally - a bit of cleanup to keep the auditors happy...
::DestroyIcon(hIcon);
}
}
}
*pResult = CDRF_DODEFAULT;
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -