📄 nheaderctrl.cpp
字号:
// NHeaderCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "NCombo.h"
#include "NHeaderCtrl.h"
#include "NWindow.h"
#include "gdi.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNHeaderCtrl
static const CSize sIcon(6,4);
static const CSize sButton(14,16);
#define UP TRUE
#define DOWN !UP
// Function name : CNHeaderCtrl::CNHeaderCtrl
// Description : default constcutro
// Return type :
// Argument :
CNHeaderCtrl::CNHeaderCtrl():m_brBkGnd(RGB(192,192,192))
{
m_pParent = NULL;
m_nScrolling = 0;
m_bCaptured = FALSE;
m_nSetText = 0;
}
// Function name : CNHeaderCtrl::~CNHeaderCtrl
// Description :
// Return type :
CNHeaderCtrl::~CNHeaderCtrl()
{
for (int i = 0; i < m_arColumns.GetSize(); i++)
delete m_arColumns[i];
m_arColumns.RemoveAll();
}
BEGIN_MESSAGE_MAP(CNHeaderCtrl, CWnd)
//{{AFX_MSG_MAP(CNHeaderCtrl)
ON_WM_LBUTTONDOWN()
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_SETFOCUS()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// Function name : =
// Description : Store the new selected item...
// Return type : CNHeaderCtrl* CNHeaderCtrl::operator
// Argument : int nItem
CNHeaderCtrl* CNHeaderCtrl::operator = (int nItem)
{
m_nSelected = nItem;
CNEdit* pNEdit = NULL;
CNListCtrl* pNListCtrl = m_pParent->GetListCtrl();
ASSERT (pNListCtrl);
IncUserReason();
for (int i = 0; pNEdit = GetNEdit(i); i++)
pNEdit->SetWindowText(pNListCtrl->GetItemText(nItem, i));
DecUserReason();
return this;
}
// Function name : CNHeaderCtrl::IsUserReason
// Description :
// Return type : BOOL
BOOL CNHeaderCtrl::IsUserReason()
{
return m_nSetText == 0;
}
/////////////////////////////////////////////////////////////////////////////
// CNHeaderCtrl message handlers
// Function name : CNHeaderCtrl::PreCreateWindow
// Description : register this window
// Return type : BOOL
// Argument : CREATESTRUCT& cs
BOOL CNHeaderCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), m_brBkGnd, NULL);
cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
return CWnd::PreCreateWindow(cs);
}
// Function name : CNHeaderCtrl::OnMouseMove
// Description : Draw the button in different states,
// when the mouse is captured and mouse cursor is over the button
// Return type : void
// Argument : UINT nFlags
// Argument : CPoint point
void CNHeaderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bCaptured)
DrawButton(NULL, !GetButtonRect().PtInRect(point));
CWnd::OnMouseMove(nFlags, point);
}
// Function name : CNHeaderCtrl::OnLButtonUp
// Description : When mouse is released...
// Return type : void
// Argument : UINT nFlags
// Argument : CPoint point
void CNHeaderCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bCaptured)
{
ReleaseCapture();
DrawButton(NULL, UP);
m_pParent->GetListCtrl()->SetCapture();
m_bCaptured = FALSE;
}
CWnd::OnLButtonUp(nFlags, point);
}
// Function name : CNHeaderCtrl::OnLButtonDown
// Description : If the mouse is clicked into button, draw this.
// Return type : void
// Argument : UINT nFlags
// Argument : CPoint point
void CNHeaderCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
SetFocus();
if (GetButtonRect().PtInRect(point))
{
DrawButton(NULL, DOWN);
m_pParent->GetListCtrl()->Toggle();
SetCapture();
m_bCaptured = TRUE;
}
CWnd::OnLButtonDown(nFlags, point);
}
// Function name : CNHeaderCtrl::SetParent
// Description :
// Return type : void
// Argument : CNWindow *pParent
void CNHeaderCtrl::SetParent(CNWindow *pParent)
{
m_pParent = pParent;
}
// Function name : CNHeaderCtrl::OnCreate
// Description : OnCreate ...
// Return type : int
// Argument : LPCREATESTRUCT lpCreateStruct
int CNHeaderCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return OnInit();
}
// Function name : CNHeaderCtrl::OnInit
// Description : Called after create function
// Return type : int
int CNHeaderCtrl::OnInit()
{
return 0;
}
// Function name : CNHeaderCtrl::DrawButton
// Description : Draw button up
// Return type : void
// Argument : CDC *pDC
void CNHeaderCtrl::DrawButton(CDC *pDC, BOOL bUp)
{
CDC* pDrawDC = pDC ? pDC : GetDC();
CRect r(GetButtonRect());
pDrawDC->FillRect(r, &m_brBkGnd);
pDrawDC->DrawEdge(r, bUp ? EDGE_RAISED : EDGE_SUNKEN, BF_RECT);
r.InflateRect(-CSize((r.Width() - sIcon.cx ) / 2, (r.Height() - sIcon.cy)/2));
if (!bUp) r.OffsetRect(1,1);
pDrawDC->DrawIcon(r.TopLeft(), AfxGetApp()->LoadIcon(IDI_ICON_DOWN));
if (!pDC) ReleaseDC(pDrawDC);
}
// Function name : CNHeaderCtrl::OnPaint
// Description : Draw the button
// Return type : void
void CNHeaderCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawButton(&dc, UP);
}
// Function name : CNHeaderCtrl::IsScrolling
// Description :
// Return type : BOOL
BOOL CNHeaderCtrl::IsScrolling()
{
return m_nScrolling != 0;
}
// Function name : CNHeaderCtrl::ScrollToPos
// Description :
// Return type : void
// Argument : int nPos
void CNHeaderCtrl::ScrollToPos(int nPos)
{
if ( !IsScrolling() )
{
CNListCtrl* pListCtrl = m_pParent->GetListCtrl();
m_nScrolling++;
if (int n = m_arColumns.GetSize())
{
// Just do this
HideCaret();
CRect rect; rect.SetRectEmpty();
rect.left = -nPos + 2;
rect.top = 1; rect.bottom = GetDefaultHeight() - 2;
CRect rButton = GetButtonRect();
BOOL bInter = FALSE;
CEdit* pEdit = NULL;
for (int i = 0; i < n; i++)
{
rect.right = rect.left + pListCtrl->GetColumnWidth(i);
pEdit = m_arColumns[i]->GetEdit();
CRect rInter, rEdit(rect);
if (rInter.IntersectRect(rEdit, rButton))
{
rEdit.right = rButton.left;
rEdit.left = min(rEdit.left, rEdit.right);
bInter = TRUE;
}
pEdit->SetWindowPos(0, rEdit.left, rEdit.top, rEdit.Width() - 1, rEdit.Height(), SWP_FRAMECHANGED | SWP_NOZORDER | SWP_DRAWFRAME);
rect.left = rect.right;
}
ShowCaret();
}
m_nScrolling--;
}
}
// Function name : CNHeaderCtrl::ResizeLastEdit
// Description :
// Return type : void
void CNHeaderCtrl::ResizeLastEdit()
{
CRect rect = GetButtonRect(), rScreen(rect);
ClientToScreen(&rScreen);
CWnd* pNEdit = WindowFromPoint(rScreen.CenterPoint());
if (Lookup(pNEdit) >= 0)
{
CRect rNEdit; pNEdit->GetWindowRect(rNEdit);
pNEdit->GetParent()->ScreenToClient(&rNEdit);
rNEdit.right = rect.left;
pNEdit->MoveWindow(rNEdit);
}
}
// Function name : CNHeaderCtrl::GetTotalWidth2
// Description :
// Return type : int
// Argument : CNEdit *pEdit
// Argument : int nMaxScroll
int CNHeaderCtrl::GetTotalWidth2(CNEdit *pEdit, int nMaxScroll)
{
int iEdit = Lookup(pEdit);
CNListCtrl* pNListCtrl = m_pParent->GetListCtrl();
int nResult = 0, bResultRest = 0;
for (int i = 0; i < iEdit; i++)
nResult += pNListCtrl->GetColumnWidth(i);
for (i = iEdit; i < m_arColumns.GetSize(); i++)
bResultRest += pNListCtrl->GetColumnWidth(i);
if (nResult + bResultRest < nMaxScroll)
return 0;
else
if (bResultRest < nMaxScroll)
return nResult -( nMaxScroll - bResultRest);
return nResult;
}
// Function name : CNHeaderCtrl::Next
// Description :
// Return type : void
// Argument : CNEdit *pEdit
// Argument : BOOL bNext
void CNHeaderCtrl::Next(CNEdit *pEdit, BOOL bNext)
{
int iEdit = NULL;
int nColumns = m_arColumns.GetSize();
if ((iEdit = Lookup(pEdit)) >= 0)
{
CNEdit* pNEdit = NULL;
for (int i = 0; i < nColumns; i++)
{
iEdit = iEdit + (bNext ? + 1 : -1);
if (bNext)
iEdit = abs(iEdit) % nColumns;
else
if (iEdit < 0)
iEdit = nColumns - 1;
pNEdit = GetNEdit(iEdit);
if (pNEdit->CanBeFocused())
{
pNEdit->SetFocus();
break;
}
}
}
}
// Function name : CNHeaderCtrl::Lookup
// Description : Who is responsablie with thsi edit?
// Return type : int
// Argument : CNEdit *pEdit
int CNHeaderCtrl::Lookup(CWnd *pEdit)
{
if (pEdit)
{
int nColumns = m_arColumns.GetSize();
for (int i = 0; i < nColumns; i++)
if (m_arColumns[i]->GetEdit()->m_hWnd == pEdit->m_hWnd)
return i;
}
return -1;
}
// Function name : CNHeaderCtrl::GetButtonRect
// Description : return the button rect
// Return type : CRect
CRect CNHeaderCtrl::GetButtonRect()
{
CRect rect; GetClientRect(rect);
rect.left = max(rect.right - sButton.cx, 0);
rect.InflateRect(-CSize(0 , 1 ));
return rect;
}
// Function name : CNHeaderCtrl::OnSize
// Description : On resize resize all.
// Return type : void
// Argument : UINT nType
// Argument : int cx
// Argument : int cy
void CNHeaderCtrl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if (m_pParent)
ScrollToPos(m_pParent->GetListCtrl()->GetHScroll());
}
// Function name : CNHeaderCtrl::OnSetFocus
// Description : When header receives the focus, dispatch this to active edit
// Return type : void
// Argument : CWnd* pOldWnd
void CNHeaderCtrl::OnSetFocus(CWnd* pOldWnd)
{
CWnd::OnSetFocus(pOldWnd);
if (CNEdit* pNEdit = GetNEdit(m_pParent->GetColumnKey()))
pNEdit->SetFocus();
}
// Function name : CNHeaderCtrl::GetNEdit
// Description : return from array, nIndex edit
// Return type : CNEdit*
// Argument : int nIndex
CNEdit* CNHeaderCtrl::GetNEdit(int nIndex)
{
if (nIndex >= 0)
if (nIndex < m_arColumns.GetSize())
return (CNEdit*)m_arColumns[nIndex]->GetEdit();
return NULL;
}
// Function name : CNHeaderCtrl::GetDefaultHeight
// Description : Default height
// Return type : int
int CNHeaderCtrl::GetDefaultHeight()
{
return m_pParent->GetListCtrl()->GetItemHeight() + 2;
}
void CNHeaderCtrl::IncUserReason()
{
m_nSetText++;
}
void CNHeaderCtrl::DecUserReason()
{
m_nSetText--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -