📄 treeeditcontrol.h
字号:
/*------------------------------------------------------------------------------*
* File Name:TreeEditControl.h *
* Creation: CPY 6/21/2003 *
* Purpose: OriginC Header file for general vsFlexGrid based TreeEditor *
* Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, *
* All Rights Reserved *
* *
* Modification Log: *
* CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS *
* CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT *
*------------------------------------------------------------------------------*/
#include "GridControl.h"
#define EDITOR_ID 101
#define EDIT_COL_INDEX 1
#define LABEL_COL_INDEX 0
//---- CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT
#define JUSTIFICATION_CHECKBOX flexPicAlignCenterCenter
#define JUSTIFICATION_NUM flexPicAlignLeftCenter //flexPicAlignRightCenter
#define JUSTIFICATION_STR flexPicAlignLeftCenter
//----
class TreeEditControl : public GridListControl
{
public:
void Init(int nID, bool bFlatDlgDisplay, bool bSubBranch, PEVENT_FUNC pfn, Dialog& dlg)
{
m_dwEditor = 0;
m_bIsFlatDialogDisplay = bFlatDlgDisplay;
GridListControl::Init(nID, dlg);
m_bDataReady = false;
//WAIT_BUG_FIX
// m_dlg = dlg;
m_pdlg = &dlg;
m_pfnEvent = pfn;
m_strNumFormat = "*"; //CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT
m_flx.Rows = 0;
m_flx.FixedRows = 0;//hide the Col heading
m_flx.Cols = 2;
m_flx.FixedCols = 0;//hide the Row heading
m_flx.SelectionMode = flexSelectionFree;//flexSelectionByRow; //Forces selections to span entire rows.
m_flx.Editable = flexEDKbdMouse;
//flx.GridLines = flexGridInsetHorz;
m_flx.OwnerDraw = flexODContent; //flexODOver;
m_flx.AllowSelection = false;
//m_flx.ExplorerBar = flexExSortShow;
m_flx.AllowUserResizing = flexResizeColumns;
if(!m_bIsFlatDialogDisplay)
{
m_flx.GridLines = flexGridNone;
SetAlternateRowColors();
m_flx.ExtendLastCol = true;
}
else
{
m_flx.ExtendLastCol = false;
}
if(bSubBranch)
{
m_flx.OutlineCol = 0;
m_flx.OutlineBar = flexOutlineBarSimpleLeaf;
m_flx.MergeCells = flexMergeSpill;
m_bIsOutlineTree = true;
m_bIsFlatDialogDisplay = false;
}
else
m_bIsOutlineTree = false;
RemoveSelection();
}
//----CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
bool IsResizeOnCollapse(int nRow, int nState)
{
if(nRow < 0)
return true;
DWORD dwTemp = m_flx.RowData(nRow);
if(dwTemp)
{
if((GETNBRANCH_KEEP_SIZE_ON_COLLAPSE & dwTemp) && flexOutlineCollapsed == nState)
return false;
if((GETNBRANCH_KEEP_SIZE_ON_EXPAND & dwTemp) && nState < flexOutlineCollapsed)
return false;
}
return true;// default is to resize
}
//----
void SetGridLines(int nOption)
{
m_flx.GridLines = nOption;
}
void OnDestroy(void)
{
Cleanup();
}
bool Update(TreeNode& tr, bool bResize = true, bool bInit = false)
{
m_trEdit = tr;
//--- CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
string strTemp;
if(m_trEdit.GetAttribute(STR_ATTRIB_VERT_GRID_LINES, strTemp))
{
SetGridLines(atoi(strTemp));
}
if(m_trEdit.GetAttribute(STR_ATTRIB_NUMFMT, strTemp))
m_strNumFormat = strTemp;
//---
m_flx.Redraw = flexRDNone;
if(bInit)
{
Cleanup();
m_flx.Rows = m_flx.FixedRows; //delete all but headers
addTreeNodes(tr);
}
prepareGridForDisplay(bResize, bInit);
m_flx.Redraw = flexRDBuffered;
if(bInit)
{
RemoveSelection();
m_bDataReady = true;
}
return true;
}
void Cleanup()
{
EditorManager trNodeManager;
int nCol = EDIT_COL_INDEX;
DWORD dwTemp;
for(int nRow = 0; nRow < m_flx.Rows; nRow++)
{
// clean up Row Data
dwTemp = m_flx.Cell(flexcpData, nRow, nCol);
trNodeManager.Delete(dwTemp);
m_flx.Cell(flexcpData, nRow, nCol) = 0;
}
}
//virtual
void ClearAll()
{
Cleanup();
GridListControl::ClearAll();
}
void GetGridSize(int& nx, int& ny)
{
GridListControl::GetGridSize(nx, ny);
if(!m_bIsFlatDialogDisplay)
{
ny += 3; // somehow needs spaces for the edge or something
nx += 24;
}
else
{
ny += 3;
nx += 21;
}
}
BOOL OnReconstructGrid(UINT wParam, UINT lParam)
{
BOOL bRet = FALSE;// return TRUE to indicate need for resize
bool bNeedResize = (wParam & GRID_CHANGE_SHOW)? true : false;
m_bDataReady = false;
if(bNeedResize)
{
int nRow = m_flx.Row;
int nCol = m_flx.Col;
RemoveSelection();
Update(m_trEdit, false);
bRet = TRUE;
if(nCol > 0 && nRow >= 0)
{
m_flx.Select(nRow,nCol);
}
}
else
{
if(wParam & GRID_CHANGE_ENABLE)
updateGridEnableSettings();
//---- CPY 5/30/03 QA70-4577 EVENT_HANDLER_NEED_DIALOG_AND_VALUE_UPDATE
if(wParam & GRID_CHANGE_VALUE)
bRet = updateGridValues();
if(wParam & GRID_CHANGE_SIZE)
bRet = true;
//---- end
}
m_bDataReady = true;
return bRet;
}
///// vsFlexGrid events
BOOL OnSetFocus()
{
m_flx.Col=1;
m_flx.Row=0;
return true;
}
BOOL OnEditorKillFocus( uint wParam = 0, uint lParam=0 )
{
_DBINT("On OnEditorKillFocus, ", m_dwEditor)
if(0==m_dwEditor)
{
if(lParam)
{
_DBSTR("OnEditorKillFocus Error, this should not happen.");
}
return TRUE;
}
if(lParam && m_dwEditor != lParam)
{
// debug
//printf("m_dwEditor=%X, lParam = %X\n", m_dwEditor, lParam);
}
m_flx.Row = m_nEditRow;
m_flx.Col = m_nEditCol;
OnAfterEdit(m_nEditRow, m_nEditCol);
EditorManager trNodeManager;
trNodeManager.DestroyEditor(m_dwEditor);
m_dwEditor = 0;
return TRUE;
}
void OnDrawCell(UINT hDC, int nRow, int nCol, int nLeft, int nTop, int nRight, int nBottom, BOOL* pDone)
{
DWORD dwTemp = m_flx.Cell(flexcpData, nRow, nCol);
if(dwTemp)
{
EditorManager trNodeManager;
BOOL bSelected = nRow == m_flx.RowSel && nCol == m_flx.ColSel? true:false;
RECT rect;
SetRect(rect, nLeft, nTop, nRight, nBottom);
//InflateRect(&rect, -m_nHaldGridLineWidth, -m_nHaldGridLineWidth);
rect.right -= m_nHaldGridLineWidth;
rect.bottom -= m_nHaldGridLineWidth;
//_DBINT("in Drawcell, bSelected=", bSelected)
*pDone = trNodeManager.DrawCell(dwTemp, hDC, &rect, bSelected);
return;
}
*pDone = FALSE;// let VSFlex grid to finish drawing cell
}
void OnComboCloseUp(int nRow, int nCol, BOOL* pFinishEdit)
{
TreeNode trNode = get_tree_node(nRow);
if(trNode && (TRGP_ENUM_COMBO == trNode.ID || TRGP_STR_LIST ==trNode.ID) )
{
*pFinishEdit = true;
}
}
void OnBeforeMouseDown(short nButton, short nShift, float X, float Y, BOOL* pCancel)
{
int iRow = m_flx.MouseRow;
int iCol = m_flx.MouseCol;
OnEditorKillFocus();
if(iCol == 0 && !m_bIsOutlineTree) // label col
{
_DBINT("Quite at ", iRow)
RemoveSelection();
*pCancel = TRUE;
return;
}
TreeNode trNode = get_tree_node(iRow);
if(!trNode)
{
out_int("no tree node at row = ", iRow);
*pCancel = TRUE;
return;
}
if(iCol == 0 && trNode.ID != TRGP_BRANCH)
{
RemoveSelection();
*pCancel = TRUE;
return;
}
GridListControl::OnBeforeMouseDown(nButton, nShift, X, Y, pCancel);
}
void OnButtonClick(int nRow, int nCol)
{
TreeNode trNode = get_tree_node(nRow);
PEVENT_FUNC pfn = getEventHandler(trNode);
if(pfn && trNode.IsValid())
{
if(pfn(m_trEdit, nRow, trNode.ID, *m_pdlg)) //CPY 5/30/03 QA70-4577 EVENT_HANDLER_NEED_DIALOG_AND_VALUE_UPDATE, add *this
{
string strOldVal = m_flx.Cell(flexcpText, nRow, nCol);
m_flx.Cell(flexcpText, nRow, nCol) = trNode.Text;
if(updateGridColWidth(nRow, strOldVal))
PostDlgMessage(WM_USER_RECONSTRUCT, GRID_CHANGE_SIZE);
}
}
}
void OnRowColChange()
{
if(!m_bDataReady)
return;
int nRow = m_flx.Row;
TreeNode trNode = get_tree_node(nRow);
if(trNode)
{
switch(trNode.ID)
{
case TRGP_CHECK:
case TRGP_STR_LIST:
case TRGP_COLOR:
case TRGP_RANGE:
case TRGP_STR_BUTTON:
break;
default:
DWORD dwTemp = m_flx.Cell(flexcpData, nRow, EDIT_COL_INDEX);
if(0 == dwTemp) // if there is a Propty object, then we should pass this along, for now, lets just ignore them
{
m_flx.EditCell();
m_flx.EditSelStart = 0;
m_flx.EditSelLength = 30000; // try to select all
}
break;
}
}
}
void OnValidateEdit(int nRow, int nCol, BOOL* pCancel)
{
string strEdit = m_flx.EditText;
DWORD dwTemp = m_flx.Cell(flexcpData, nRow, nCol);
if(dwTemp)
{
EditorManager trNodeManager;
if(!trNodeManager.ValidateEdit(dwTemp, strEdit))
*pCancel = TRUE;
return;
}
TreeNode trNode = get_tree_node(nRow);
if(trNode)
{
if(is_node_need_numeric_validation(trNode))
{
if(!is_numeric(strEdit))
*pCancel = true;
}
}
}
void OnBeforeEdit(long nRow, long nCol, BOOL* pCancel)
{
if(nCol != EDIT_COL_INDEX)
{
*pCancel = TRUE;
return;
}
TreeNode trNode = get_tree_node(nRow);
if(trNode)
{
if(trNode.Enable == 0 || TRGP_BRANCH == trNode.ID)
{
*pCancel = TRUE;
return;
}
}
DWORD dwTemp = m_flx.Cell(flexcpData, nRow, nCol);
if(dwTemp)
{
*pCancel = TRUE;
if(m_dwEditor) // busy, possible due to come messaging problem
{
_DBINT("OnBeforeEdit, should be NULL, but has ", m_dwEditor)
return;
}
if(nRow != m_flx.MouseRow || nCol != m_flx.MouseCol)
{
_DBSTR("Custom Editor must be initiated from mouse click only")
return;
}
RECT rect;
GetCellRect(nRow, nCol, rect);
string strFontName = m_flx.Cell(flexcpFontName, nRow, nCol);
int nFontSize = m_flx.Cell(flexcpFontSize, nRow, nCol);
EditorManager trNodeManager;
string strCombo, strEditMask;
m_flx.ComboSearch = trNodeManager.GetEditInfo(dwTemp, strCombo, strEditMask);
m_flx.ComboList = strCombo;
m_flx.EditMask = strEditMask;
// DWORD CreateEditor(DWORD dwData, const RECT * lpcRect, HWND hwndOwner, UINT nControlID=100, LPCTSTR lpcszFontName=NULL, int nFontSize=0);
m_dwEditor = trNodeManager.CreateEditor(dwTemp, &rect, GetDlgSafeHwnd(), EDITOR_ID, strFontName, nFontSize);
int nOK = trNodeManager.StartEdit(dwTemp, nRow);
if(m_dwEditor)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -