📄 formlistctrl.cpp
字号:
// FormListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "FormListCtrl.h"
#include "FormItem.h"
#include "FormItemString.h"
#include "FormItemDateTime.h"
#include "FormItemGroup.h"
#include "FormItemCheck.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
using namespace DRA;
//---------------------------------------------------------------------------
//
// CFormListCtrl
//
//---------------------------------------------------------------------------
CFormListCtrl::CFormListCtrl()
: m_iEdit (-1),
m_iSelected (-1),
m_bEditable (false),
m_bResizing (false),
m_pGroup (NULL)
{
}
CFormListCtrl::~CFormListCtrl()
{
}
BEGIN_MESSAGE_MAP(CFormListCtrl, CBaseListCtrl)
//{{AFX_MSG_MAP(CFormListCtrl)
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetDispInfo)
ON_WM_DESTROY()
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_ADJUSTSIP, OnAdjustSip)
ON_MESSAGE(WM_SELECT_NEXT, OnSelectNext)
ON_MESSAGE(WM_SELECT_PREV, OnSelectPrev)
ON_MESSAGE(WM_CLOSE_EDITOR, OnCloseEditor)
ON_WM_SIZE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
END_MESSAGE_MAP()
//---------------------------------------------------------------------------
//
// CFormListCtrl operations
//
//---------------------------------------------------------------------------
// CFormListCtrl::ValidateData
//
// Validates the form's data
//
BOOL CFormListCtrl::ValidateData()
{
BOOL bValid = TRUE;
int i,
nItems = GetItemCount();
for(i = 0; bValid && (i < nItems); ++i)
{
CFormItem* pItem = (CFormItem*) GetItemData(i);
if(pItem)
bValid = bValid && pItem->ValidateData();
else
bValid = FALSE;
}
return bValid;
}
// CFormListCtrl::FindFormItem
//
// Finds a form item. Returns the index of the item
// or -1 if not found
//
int CFormListCtrl::FindFormItem(CFormItem *pItem)
{
int i,
iItem = -1,
nItems = GetItemCount();
for(i = 0; (iItem == -1) && (i < nItems); ++i)
if(GetItemData(i) == (DWORD)pItem)
iItem = i;
return iItem;
}
// CFormListCtrl::RemoveItem
//
// Removes an item from the list
//
BOOL CFormListCtrl::RemoveItem(CFormItem* pItem)
{
int iItem = FindFormItem(pItem);
BOOL bOk = (iItem != -1);
if(bOk)
bOk = DeleteItem(iItem);
return bOk;
}
// CFormListCtrl::SelectItem
//
// Selects or deselects an item
//
void CFormListCtrl::SelectItem(int iItem, BOOL bSelect)
{
ASSERT(iItem >= 0 && iItem < GetItemCount());
CFormItem* pItem = (CFormItem*) GetItemData(iItem);
if(pItem != NULL)
{
pItem->Select(this, bSelect, iItem);
RedrawItems(iItem, iItem);
}
}
// CFormListCtrl::SetRowHeight
//
// Sets the row height through the dummy image list
//
void CFormListCtrl::SetRowHeight(int nHeight)
{
if(m_imglHeight.m_hImageList)
m_imglHeight.DeleteImageList();
m_imglHeight.Create(1, nHeight, ILC_COLOR, 1, 1);
SetImageList(&m_imglHeight, LVSIL_SMALL);
}
// CFormListCtrl::GetSubItemRect
//
// Calculates the subitem's rect
// This method is based on Lee Nowotny's code.
//
BOOL CFormListCtrl::GetSubItemRect(int iItem, int iSubItem, RECT &rc)
{
CHeaderCtrl* pHeader;
int nColumnCount,
nColumnOffset,
i;
RECT rcClient;
//
// Make sure that the item is visible
//
// if(!EnsureVisible(iItem, TRUE))
// return FALSE;
//
// Make sure that nCol is valid
//
pHeader = GetHeaderCtrl();
if(!pHeader)
return FALSE;
nColumnCount = pHeader->GetItemCount();
if(iSubItem >= nColumnCount || GetColumnWidth(iSubItem) < 5)
return FALSE;
//
// Get the column offset
//
nColumnOffset = 0;
for(i = 0; i < iSubItem; i++)
nColumnOffset += GetColumnWidth(i);
//
// Get the total item rect
//
GetItemRect(iItem, &rc, LVIR_BOUNDS);
//
// Now scroll if we need to expose the column
//
GetClientRect(&rcClient);
if(nColumnOffset + rc.left < 0 || nColumnOffset + rc.left > rcClient.right)
{
SIZE size;
if(nColumnOffset + rc.left > 0)
size.cx = -(nColumnOffset - rc.left);
else
size.cx = nColumnOffset - rc.left;
size.cy = 0;
Scroll(size);
rc.left -= size.cx;
}
//
// Calculate the sub item rectangle
//
rc.left += nColumnOffset;
rc.right = rc.left + GetColumnWidth(iSubItem);
if(rc.right > rcClient.right)
rc.right = rcClient.right;
return TRUE;
}
// CFormListCtrl::HitTestEx
//
// Extended hit test method
// This method is based on Lee Nowotny's code.
//
int CFormListCtrl::HitTestEx(CPoint &point, int *pSubItem)
{
int nColumn = 0,
iRow = HitTest (point, NULL),
iBottom,
nColumnCount;
if(pSubItem)
*pSubItem = 0;
//
// Make sure that the ListView is in LVS_REPORT
//
if((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
return iRow;
//
// Get the top and iBottom iRow visible
//
iRow = GetTopIndex();
iBottom = iRow + GetCountPerPage();
if(iBottom > GetItemCount())
iBottom = GetItemCount();
//
// Get the number of columns
//
CHeaderCtrl* pHeader = GetHeaderCtrl();
nColumnCount = pHeader->GetItemCount();
//
// Loop through the visible iRows
//
for(; iRow <= iBottom; iRow++)
{
//
// Get bounding rect of item and check whether point falls in it.
//
CRect Rect;
GetItemRect(iRow, &Rect, LVIR_BOUNDS);
if(Rect.PtInRect(point))
{
//
// Now find the column
//
for(nColumn = 0; nColumn < nColumnCount; nColumn++)
{
int nColWidth = GetColumnWidth(nColumn);
if(point.x >= Rect.left && point.x <= (Rect.left + nColWidth))
{
if(pSubItem)
*pSubItem = nColumn;
return iRow;
}
Rect.left += nColWidth;
}
}
}
return -1;
}
// CFormListCtrl::ResizeDataColumn
//
// Resizes the data column (index 1) given the label column width and control size.
//
void CFormListCtrl::ResizeDataColumn()
{
CRect rc;
GetClientRect(&rc);
SetColumnWidth(1, rc.Width() - GetColumnWidth(0) - GetSystemMetrics(SM_CXVSCROLL));
}
// CFormListCtrl::MoveDivider
//
// Moves the divider dx pixels to the right or left (negative)
//
void CFormListCtrl::MoveDivider(int dx)
{
int xDivider = GetColumnWidth(0);
int xMin = 20;
int xMax;
CRect rc;
GetClientRect(&rc);
xMax = rc.Width() - GetSystemMetrics(SM_CXVSCROLL) - xMin;
xDivider += dx;
if(xDivider < xMin)
xDivider = xMin;
else if(xDivider > xMax)
xDivider = xMax;
SetColumnWidth(0, xDivider);
SetColumnWidth(1, rc.Width() - xDivider - GetSystemMetrics(SM_CXVSCROLL));
}
// CFormListCtrl::DrawDivider
//
// Draws the vertical divider line at the given x position
//
void CFormListCtrl::DrawDivider(int x)
{
CRect rc;
HDC hDC = ::GetDC(m_hWnd);
HPEN hOldPen,
hPen = ::CreatePen(PS_SOLID, SCALEX(2), RGB(128, 128, 128));
int nROP2;
GetClientRect(&rc);
hOldPen = (HPEN)::SelectObject(hDC, hPen);
nROP2 = ::SetROP2(hDC, R2_NOTXORPEN);
LineVert(hDC, x, rc.top, rc.bottom);
::SetROP2(hDC, nROP2);
::SelectObject(hDC, (HGDIOBJ)hOldPen);
::ReleaseDC(m_hWnd, hDC);
}
// CFormListCtrl::CloseEditor
//
// Closes an editor
//
bool CFormListCtrl::CloseEditor()
{
if(m_iEdit != -1)
{
CFormItem* pEdit = (CFormItem*) GetItemData(m_iEdit);
if(pEdit->ShowEditor(this, FALSE, m_iEdit, 1))
{
RedrawItems(m_iEdit, m_iEdit);
m_iEdit = -1;
return true;
}
}
return false;
}
//---------------------------------------------------------------------------
//
// CFormListCtrl virtual methods
//
//---------------------------------------------------------------------------
// CFormListCtrl::Initialize
//
// Initializes the control.
// Return true if succeeded
//
BOOL CFormListCtrl::Initialize()
{
LOGFONT lf;
int nLogPixelsY = DRA::LogPixelsY();
//
// Create the big font
//
lf.lfHeight = DRA::HIDPIMulDiv(-9, nLogPixelsY, 72);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_NORMAL;
lf.lfItalic = FALSE;
lf.lfUnderline = FALSE;
lf.lfStrikeOut = 0;
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
_tcscpy(lf.lfFaceName, TEXT("Tahoma"));
m_fontBig.CreateFontIndirect(&lf);
//
// Create the bold font
//
lf.lfHeight = DRA::HIDPIMulDiv(-8, nLogPixelsY, 72);
lf.lfWeight = FW_BOLD;
m_fontBold.CreateFontIndirect(&lf);
//
// Create the underlined font
//
lf.lfWeight = FW_NORMAL;
lf.lfUnderline = TRUE;
m_fontUnder.CreateFontIndirect(&lf);
//
// Inserts the invisible columns
//
InsertColumn(0, _T("0"), LVCFMT_LEFT, DRA::SCALEX( 80), -1);
InsertColumn(1, _T("1"), LVCFMT_LEFT, DRA::SCALEX(140), 1);
SetRowHeight(DRA::HIDPIMulDiv(18, nLogPixelsY, 96));
ResizeDataColumn();
return TRUE;
}
// CFormListCtrl::ItemUpdated
//
// An item was updated
//
void CFormListCtrl::ItemUpdated(CFormItem *pItem, DWORD dwData)
{
}
// CFormListCtrl::ItemOptions
//
// An item is displaying its options
//
void CFormListCtrl::ItemOptions(CFormItem *pItem)
{
}
// CFormListCtrl::OnCmdMsg
//
// Distribute the command messages through any sub windows
//
BOOL CFormListCtrl::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if(m_iEdit != -1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -