📄 gridctrl.cpp.svn-base
字号:
CGridCell* pCell = GetCell(cell.row, cell.col);
if (pCell)
{
SendMessageToParent(cell.row, cell.col, GVN_BEGINLABELEDIT);
EmptyCell(pCell, cell.row, cell.col);
SetModified(TRUE, cell.row, cell.col);
SendMessageToParent(cell.row, cell.col, GVN_ENDLABELEDIT);
}
}
Invalidate();
}
COleDataSource* CGridCtrl::CopyTextFromGrid()
{
USES_CONVERSION;
CCellRange Selection = GetSelectedCellRange();
if (!IsValid(Selection)) return NULL;
// Write to shared file (REMEBER: CF_TEXT is ANSI, not UNICODE, so we need to convert)
CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
// Get a tab delimited string to copy to cache
CString str;
CGridCell *pCell;
for (int row = Selection.GetMinRow(); row <= Selection.GetMaxRow(); row++)
{
str.Empty();
if( Selection.GetMinCol() > 0 )
{
pCell = GetCell(row,0);
if( pCell )
str = pCell->szText + _T("\t");
}
for (int col = Selection.GetMinCol(); col <= Selection.GetMaxCol(); col++)
{
pCell = GetCell(row,col);
if (pCell && (pCell->state & GVIS_SELECTED))
{
if (pCell->szText.IsEmpty())
str += _T(" ");
else
str += pCell->szText;
}
if (col != Selection.GetMaxCol())
str += _T("\t");
}
if (row != Selection.GetMaxRow())
str += _T("\r\n");
sf.Write(T2A(str.GetBuffer(1)), str.GetLength());
str.ReleaseBuffer();
}
char c = '\0';
sf.Write(&c, 1);
DWORD dwLen = (DWORD)sf.GetLength();
HGLOBAL hMem = sf.Detach();
if (!hMem)
return NULL;
hMem = ::GlobalReAlloc(hMem, dwLen, GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
if (!hMem)
return NULL;
// Cache data
COleDataSource* pSource = new COleDataSource();
pSource->CacheGlobalData(CF_TEXT, hMem);
return pSource;
}
BOOL CGridCtrl::PasteTextToGrid(CCellID cell, COleDataObject* pDataObject)
{
if (!IsValid(cell) || !IsCellEditable(cell) || !pDataObject->IsDataAvailable(CF_TEXT))
return FALSE;
// Get the text from the COleDataObject
HGLOBAL hmem = pDataObject->GetGlobalData(CF_TEXT);
CMemFile sf((BYTE*) ::GlobalLock(hmem), ::GlobalSize(hmem));
// CF_TEXT is ANSI text, so we need to allocate a char* buffer
// to hold this.
LPSTR szBuffer = new char[::GlobalSize(hmem)];
if (!szBuffer)
return FALSE;
sf.Read(szBuffer, ::GlobalSize(hmem));
::GlobalUnlock(hmem);
// Now store in generic TCHAR form so we no longer have to deal with
// ANSI/UNICODE problems
CString strText = szBuffer;
delete szBuffer;
// Parse text data and set in cells...
strText.LockBuffer();
CString strLine = strText;
int nLine = 0;
// Find the end of the first line
int nIndex;
do {
int nColumn = 0;
nIndex = strLine.Find(_T("\n"));
// Store the remaining chars after the newline
CString strNext = (nIndex < 0)? _T("") : strLine.Mid(nIndex+1);
// Remove all chars after the newline
if (nIndex >= 0)
strLine = strLine.Left(nIndex);
// Make blank entries a "space"
if (strLine.IsEmpty() && nIndex >= 0)
strLine = _T(" ");
LPTSTR szLine = strLine.GetBuffer(1);
// Break the current line into tokens (tab or comma delimited)
LPTSTR pszCellText = _tcstok(szLine, _T("\t,\n"));
while (pszCellText != NULL)
{
CCellID TargetCell(cell.row + nLine, cell.col + nColumn);
if (IsValid(TargetCell))
{
CString strCellText = pszCellText;
strCellText.TrimLeft(); strCellText.TrimRight();
SendMessageToParent(TargetCell.row, TargetCell.col, GVN_BEGINLABELEDIT);
SetItemText(TargetCell.row, TargetCell.col, strCellText);
SetModified(TRUE, TargetCell.row, TargetCell.col);
SendMessageToParent(TargetCell.row, TargetCell.col, GVN_ENDLABELEDIT);
// Make sure cell is not selected to avoid data loss
SetItemState(TargetCell.row, TargetCell.col,
GetItemState(TargetCell.row, TargetCell.col) & ~GVIS_SELECTED);
}
pszCellText = _tcstok(NULL, _T("\t,\n"));
nColumn++;
}
strLine.ReleaseBuffer();
strLine = strNext;
nLine++;
} while (nIndex >= 0);
strText.UnlockBuffer();
Invalidate();
return TRUE;
}
#endif
#ifndef GRIDCONTROL_NO_DRAGDROP
void CGridCtrl::OnBeginDrag()
{
if (!m_bAllowDragAndDrop) return;
COleDataSource* pSource = CopyTextFromGrid();
if (pSource)
{
SendMessageToParent(GetSelectedCellRange().GetTopLeft().row,
GetSelectedCellRange().GetTopLeft().col,
GVN_BEGINDRAG);
m_MouseMode = MOUSE_DRAGGING;
DROPEFFECT dropEffect = pSource->DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE);
if (dropEffect & DROPEFFECT_MOVE)
CutSelectedText();
if (pSource)
delete pSource; // Did not pass source to clipboard, so must delete
}
}
DROPEFFECT CGridCtrl::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState,
CPoint point)
{
// Any text data available for us?
if (!m_bAllowDragAndDrop || !IsEditable() || !pDataObject->IsDataAvailable(CF_TEXT))
return DROPEFFECT_NONE;
// Find which cell we are over and drop-highlight it
CCellID cell = GetCellFromPt(point, FALSE);
// If not valid, set the previously drop-highlighted cell as no longer drop-highlighted
if (!IsValid(cell))
{
OnDragLeave();
m_LastDragOverCell = CCellID(-1,-1);
return DROPEFFECT_NONE;
}
if (!IsCellEditable(cell))
return DROPEFFECT_NONE;
// Have we moved over a different cell than last time?
if (cell != m_LastDragOverCell)
{
// Set the previously drop-highlighted cell as no longer drop-highlighted
if (IsValid(m_LastDragOverCell)) {
UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
nState & ~GVIS_DROPHILITED);
RedrawCell(m_LastDragOverCell);
}
m_LastDragOverCell = cell;
// Set the new cell as drop-highlighted
if (IsValid(m_LastDragOverCell)) {
UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
nState | GVIS_DROPHILITED);
RedrawCell(m_LastDragOverCell);
}
}
// Return an appropraite value of DROPEFFECT so mouse cursor is set properly
if (dwKeyState & MK_CONTROL)
return DROPEFFECT_COPY;
else
return DROPEFFECT_MOVE;
}
DROPEFFECT CGridCtrl::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState,
CPoint point)
{
// Any text data available for us?
if (!m_bAllowDragAndDrop || !pDataObject->IsDataAvailable(CF_TEXT))
return DROPEFFECT_NONE;
// Find which cell we are over and drop-highlight it
m_LastDragOverCell = GetCellFromPt(point, FALSE);
if (!IsValid(m_LastDragOverCell))
return DROPEFFECT_NONE;
if (!IsCellEditable(m_LastDragOverCell))
return DROPEFFECT_NONE;
if (IsValid(m_LastDragOverCell))
{
UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
nState | GVIS_DROPHILITED);
RedrawCell(m_LastDragOverCell);
}
// Return an appropraite value of DROPEFFECT so mouse cursor is set properly
if (dwKeyState & MK_CONTROL)
return DROPEFFECT_COPY;
else
return DROPEFFECT_MOVE;
}
void CGridCtrl::OnDragLeave()
{
// Set the previously drop-highlighted cell as no longer drop-highlighted
if (IsValid(m_LastDragOverCell)) {
UINT nState = GetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col);
SetItemState(m_LastDragOverCell.row, m_LastDragOverCell.col,
nState & ~GVIS_DROPHILITED);
RedrawCell(m_LastDragOverCell);
}
}
BOOL CGridCtrl::OnDrop(COleDataObject* pDataObject, DROPEFFECT /*dropEffect*/,
CPoint /* point */)
{
BOOL bResult = FALSE;
if (!m_bAllowDragAndDrop || !IsCellEditable(m_LastDragOverCell))
return bResult;
m_MouseMode = MOUSE_NOTHING;
OnDragLeave();
return PasteTextToGrid(m_LastDragOverCell, pDataObject);
}
#endif
#ifndef GRIDCONTROL_NO_CLIPBOARD
void CGridCtrl::OnEditCut()
{
if (!IsEditable())
return;
COleDataSource* pSource = CopyTextFromGrid();
if (!pSource) return;
pSource->SetClipboard();
CutSelectedText();
}
void CGridCtrl::OnEditCopy()
{
COleDataSource* pSource = CopyTextFromGrid();
if (!pSource) return;
pSource->SetClipboard();
}
void CGridCtrl::OnEditPaste()
{
if (!IsEditable())
return;
// Get the Focus cell, or if none, get the topleft (non-fixed) cell
CCellID cell = GetFocusCell();
if (!IsValid(cell)) cell = GetTopleftNonFixedCell();
if (!IsValid(cell)) return;
// Attach a COleDataObject to the clipboard and paste the data to the grid
COleDataObject obj;
if (obj.AttachClipboard())
PasteTextToGrid(cell, &obj);
}
#endif
void CGridCtrl::OnEditSelectAll()
{
SelectAllCells();
}
#ifndef GRIDCONTROL_NO_CLIPBOARD
void CGridCtrl::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
CCellRange Selection = GetSelectedCellRange();
pCmdUI->Enable(Selection.Count() && IsValid(Selection));
}
void CGridCtrl::OnUpdateEditCut(CCmdUI* pCmdUI)
{
CCellRange Selection = GetSelectedCellRange();
pCmdUI->Enable(IsEditable() && Selection.Count() && IsValid(Selection));
}
void CGridCtrl::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
CCellID cell = GetFocusCell();
BOOL bCanPaste = IsValid(cell) && IsCellEditable(cell) &&
::IsClipboardFormatAvailable(CF_TEXT);
pCmdUI->Enable(bCanPaste);
}
#endif
void CGridCtrl::OnUpdateEditSelectAll(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bEnableSelection);
}
////////////////////////////////////////////////////////////////////////////////////////
// hittest-like functions
BOOL CGridCtrl::MouseOverRowResizeArea(CPoint& point) const
{
if (point.x >= GetFixedColumnWidth())
return FALSE;
CCellID idCurrentCell = GetCellFromPt(point);
CPoint start;
if (!GetCellOrigin(idCurrentCell, &start))
return FALSE;
int endy = start.y + GetRowHeight(idCurrentCell.row);
if ((point.y - start.y <= m_nResizeCaptureRange && idCurrentCell.row != 0) ||
endy - point.y <= m_nResizeCaptureRange)
{
return TRUE;
}
else
return FALSE;
}
BOOL CGridCtrl::MouseOverColumnResizeArea(CPoint& point) const
{
if (point.y >= GetFixedRowHeight())
return FALSE;
CCellID idCurrentCell = GetCellFromPt(point);
CPoint start;
if (!GetCellOrigin(idCurrentCell, &start))
return FALSE;
int endx = start.x + GetColumnWidth(idCurrentCell.col);
if ((point.x - start.x <= m_nResizeCaptureRange && idCurrentCell.col != 0) ||
endx - point.x <= m_nResizeCaptureRange)
{
return TRUE;
}
else
return FALSE;
}
// Get cell from point
CCellID CGridCtrl::GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck /*=TRUE*/) const
{
CCellID idTopLeft = GetTopleftNonFixedCell();
CCellID cellID; // return va
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -