Files
envi-code/SourceCode/Code2026/tg_shs/shs_public/TgSheet.cpp
T
2026-09-28 15:28:50 +08:00

584 lines
16 KiB
C++

#include "stdafx.h"
//#include <DbObject.h>
#include <DbGridSheet.h>
//#include <arxtools.h>
#include "TSheetEdJig.h"
#include "TAPI.h"
AcDbObjectId GetHitSheet(XPoint ptHit)
{
AcDbObjectId id;
PickSet ss(SS_FREE);
RBList mask(RTDXF0, _T("ATS_SHEET"), NULL);
if(GetEntByDxf(ss, _T("ATS_SHEET"))==Acad::eOk) {
long lCount=ss.Length();
for(long i=0L; i<lCount; i++) {
Entity ent=ss[i];
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbSheet, pSheet);
if(pSheet && pSheet->IsValid()) {
XPoly2D poly;
pSheet->GetBorder(poly);
if((ptHit&poly)==PR_INSIDE) {
acdbGetObjectId(id, ent.name);
break;
}
}
OPENOBJ_END();
}
}
return id;
}
////////////////////////////////////////////////////////////////////////////////////
// 单元递增
////////////////////////////////////////////////////////////////////////////////////
void CopyCellAndPlus()
{
int nRowFrom, nColFrom, nRowTo, nColTo;
XPoint ptSize, ptStart, ptEnd, ptPick;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
AcDbObjectId idSheet = NULL;
if(ads_getpoint(NULL, _T("\n点取第一个单元格<退出>: "), ptPick) != RTNORM)
return;
idSheet=GetHitSheet(ptPick);
if(!idSheet)
return;
TDbSheet *pSheet = NULL;
acdbOpenObject(pSheet, idSheet, AcDb::kForRead);
if(!pSheet)
return;
TSheetEdJig jig;
jig.SetPrompt(_T("\n点取最后一个单元格<退出>: "));
jig.SetSheetId(idSheet);
jig.SetOperCode(TSheetEdJig::kMultCell);
jig.SetPoint1(ptPick);
jig.SetNeedPlus(TRUE);
if(jig.DoIt()==RTNORM) {
jig.GetHitCells(pSheet, nRowFrom, nColFrom, nRowTo, nColTo);
}
else{
pSheet->close();
return;
}
int len = abs(nRowTo - nRowFrom) + 1;
int nRow = nRowFrom;
int nCol = nColFrom;
const TGridCell *pCell = pSheet->HitTestOnCell(ptPick, &nRow, &nCol);
CString csText = pCell->GetText();
if(nRow == nRowFrom && nCol == nColFrom){
for(int i=1;i<len;i++){
ptSize = pSheet->GetCellSize(nRowFrom+i, nColFrom);
ptStart = pSheet->GetCellPoint(nRowFrom+i, nColFrom);
if(pSheet->upgradeOpen()==Acad::eOk) {
TGridCell *pCell=(*pSheet)(nRowFrom+i, nColFrom);
pSheet->assertWriteEnabled();
SHORT nStateShift = GetKeyState(VK_SHIFT);
BOOL bShift = (nStateShift&256)!=0;
if(!bShift){
SHORT nStateCtrl = GetKeyState(VK_CONTROL);
BOOL bCtrl = (nStateCtrl&256)!=0;
if(bCtrl)
csText = PlusString(csText, 1, FALSE);
else
csText = PlusString(csText, 1, TRUE);
}
pCell->SetText(csText);
pSheet->downgradeOpen();
}
}
}
else{
for(int i=1;i<len;i++){
ptSize = pSheet->GetCellSize(nRowTo-i, nColTo);
ptStart = pSheet->GetCellPoint(nRowTo-i, nColTo);
if(pSheet->upgradeOpen()==Acad::eOk) {
TGridCell *pCell=(*pSheet)(nRowTo-i, nColTo);
pSheet->assertWriteEnabled();
SHORT nStateShift = GetKeyState(VK_SHIFT);
BOOL bShift = (nStateShift&256)!=0;
if(!bShift){
SHORT nStateCtrl = GetKeyState(VK_CONTROL);
BOOL bCtrl = (nStateCtrl&256)!=0;
if(bCtrl)
csText = PlusString(csText, 1, FALSE);
else
csText = PlusString(csText, 1, TRUE);
}
pCell->SetText(csText);
pSheet->downgradeOpen();
}
}
}
pSheet->close();
}
////////////////////////////////////////////////////////////////////////////////////
// 删除表行
////////////////////////////////////////////////////////////////////////////////////
void SheetDelRow()
{
XPushVar<int> vOsMode(_T("OSMODE"), 0);
ads_prompt(_T("\n本命令也可以通过[表行编辑]实现!"));
TSheetEdJig jig;
jig.SetOperCode(TSheetEdJig::kSingleRow);
while(1){
jig.SetPrompt(_T("\n请点取要删除的表行<退出>"));
int nKeyIndex=0;
int nCode=jig.DoIt(&nKeyIndex);
if(nCode != RTNORM)
return;
int nRow;
AcDbObjectId id = jig.GetHitRow(nRow);
if(!!id) {
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbSheet, pSheet);
if(pSheet) {
pSheet->RemoveRow(nRow);
}
OPENOBJ_END();
}
}
}
////////////////////////////////////////////////////////////////////////////////////
// 增加表行
////////////////////////////////////////////////////////////////////////////////////
void SheetInsertRow()
{
XPushVar<int> vOsMode(_T("OSMODE"), 0);
ads_prompt(_T("\n本命令也可以通过[表行编辑]实现!"));
TSheetEdJig jig;
jig.SetOperCode(TSheetEdJig::kSingleRow);
jig.SetKeyword(_T("A S"));
BOOL bBefor = TRUE;
BOOL bCopy = FALSE;
while(1){
if(bBefor)
jig.SetPrompt(_T("\n请点取一表行以(在本行之前)插入新行 [在本行之后插入(A)/复制当前行(S)]<退出>"));
else
jig.SetPrompt(_T("\n请点取一表行以(在本行之后)插入新行 [在本行之前插入(A)/复制当前行(S)]<退出>"));
int nKeyIndex=0;
int nCode=jig.DoIt(&nKeyIndex);
if(nCode == RTKWORD){
if(nKeyIndex == 0)
bBefor = !bBefor;
else
bCopy = TRUE;
continue;
}
else if(nCode != RTNORM)
return;
int nRow;
AcDbObjectId id = jig.GetHitRow(nRow);
if(!!id) {
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbSheet, pSheet);
if(pSheet) {
if(!bBefor){
nRow ++;
}
pSheet->AddRowAt(nRow);
if(bCopy)
pSheet->CopyRow(nRow+1, nRow);
}
OPENOBJ_END();
}
}
}
////////////////////////////////////////////////////////////////////////////////////
// 撤销合并
////////////////////////////////////////////////////////////////////////////////////
void SheetDelMerge()
{
ads_prompt(_T("\n本命令也可以通过[单元编辑]实现!"));
XPoint ptSize, ptStart, ptEnd, ptPick;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
AcDbObjectId idSheet = NULL;
if(ads_getpoint(NULL, _T("\n点取已经合并的单元格<退出>: "), ptPick) != RTNORM)
return;
idSheet=GetHitSheet(ptPick);
if(!idSheet)
return;
OPENOBJ_BEGIN(idSheet, AcDb::kForWrite, TDbSheet, pSheet);
if(pSheet) {
int nRow, nCol;
const TGridCell *pCell=pSheet->HitTestOnCell(ptPick, &nRow, &nCol);
if(!pCell)
return;
if(!pCell->GetRange()) {
adsout << _T("\n该单元格不是合并单元格, 无法撤销合并!");
} else {
pSheet->ExplodeCell(nRow, nCol);
}
}
OPENOBJ_END();
}
////////////////////////////////////////////////////////////////////////////////////
// 表格填写
////////////////////////////////////////////////////////////////////////////////////
static BOOL SheetHook(MSG* msg)
{
BOOL bRet=FALSE;
switch(msg->message) {
case WM_KEYDOWN: {
if(msg->wParam == VK_RETURN){
g_nKey = VK_RETURN;
acedPostCommand(_T(" "));
bRet = TRUE;
}
else if(msg->wParam == VK_ESCAPE){
g_nKey = VK_ESCAPE;
acedPostCommand(_T(" "));
bRet = TRUE;
}
else if(msg->wParam == VK_RIGHT){
g_nKey = VK_RIGHT;
acedPostCommand(_T(" "));
bRet = TRUE;
}
else if(msg->wParam == VK_LEFT){
g_nKey = VK_LEFT;
acedPostCommand(_T(" "));
bRet = TRUE;
}
else if(msg->wParam == VK_UP){
g_nKey = VK_UP;
acedPostCommand(_T(" "));
bRet = TRUE;
}
else if(msg->wParam == VK_DOWN){
g_nKey = VK_DOWN;
acedPostCommand(_T(" "));
bRet = TRUE;
}
break;
}
case WM_MOUSEWHEEL:{
bRet = TRUE;
break;
}
case WM_MBUTTONDOWN:{
bRet = TRUE;
break;
}
case WM_RBUTTONUP:{
g_nKey = VK_RBUTTON;
acedPostCommand(_T(" "));
bRet = TRUE;
}
default:
break;
}
return bRet;
}
void InitSheetHook(BOOL bTrue)
{
static BOOL bMsgHook=FALSE;
if(bTrue) {
if(!bMsgHook)
bMsgHook=acedRegisterFilterWinMsg(SheetHook);
} else {
if(bMsgHook) {
acedRemoveFilterWinMsg(SheetHook);
bMsgHook=FALSE;
g_nKey = 0;
}
}
}
int g_nKey = 0;
void InputSheetCell()
{
CEdit *pEdit = new CEdit();
XPoint ptPick;
AcDbObjectId idSheet = NULL;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
if(ads_getpoint(NULL, _T("\n点取编辑单元格<退出>: "), ptPick) != RTNORM)
return;
InitSheetHook(TRUE);
idSheet = GetHitSheet(ptPick);
if(!idSheet)
return;
TDbSheet *pSheet = NULL;
acdbOpenObject(pSheet, idSheet, AcDb::kForRead);
if(!pSheet)
return;
XPoint ptSize, ptStart, ptEnd;
int nRow, nCol, nRowAll, nColAll;
CString csText;
nRowAll = pSheet->GetRowNum();
nColAll = pSheet->GetColumnNum();
const TGridCell *pCell = pSheet->HitTestOnCell(ptPick, &nRow, &nCol);
csText = pCell->GetText();
ptSize = pSheet->GetCellSize(nRow, nCol);
ptStart = pSheet->GetCellPoint(nRow, nCol);
ptEnd.x = ptStart.x + ptSize.x*DocGetPScale();
ptEnd.y = ptStart.y - ptSize.y*DocGetPScale();
CPoint ptDwgView1, ptDwgView2;
int cvport=0;
VERIFY(xg_getvar(_T("CVPORT"), &cvport)==RTNORM);
acedCoordFromWorldToPixel(cvport, ptStart, ptDwgView1);
acedCoordFromWorldToPixel(cvport, ptEnd, ptDwgView2);
CAcModuleResourceOverride vTmp;
pEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP |WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN,
CRect(ptDwgView1.x, ptDwgView1.y,ptDwgView2.x,ptDwgView2.y), acedGetAcadDwgView(), IDC_USER_SHEET_EDIT);
pEdit->SetWindowText(csText);
int lenText = csText.GetLength();
pEdit->SetSel(0, lenText);
pEdit->SetFocus();
int nKey, ret;
ads_prompt(_T("\n请在编辑框内输入文字<可利用上、下、左、右控制表格移位;ESC键退出;回车键完成>"));
while(1){
ret = ads_getint(_T(""), &nKey);
if(ret == RTNONE && g_nKey != 0) {
if(g_nKey == VK_ESCAPE)
break;
CString csTmp;
pEdit->GetWindowText(csTmp);
TGridCell *pCell=(*pSheet)(nRow, nCol);
if(csTmp != csText){
if(pSheet->upgradeOpen()==Acad::eOk) {
pSheet->assertWriteEnabled();
pCell->SetText(csTmp);
pSheet->downgradeOpen();
}
else
break;
}
if(g_nKey == VK_RETURN || g_nKey == VK_RBUTTON)
break;
else if(g_nKey == VK_RIGHT){
nCol++;
if(nCol == nColAll){
nRow++;
if(nRow == nRowAll)
break;
nCol = 0;
}
}
else if(g_nKey == VK_LEFT){
nCol--;
if(nCol == -1){
nRow--;
if(nRow == -1)
break;
nCol = nColAll-1;
}
}
else if(g_nKey == VK_UP){
nRow--;
if(nRow == -1){
break;
}
}
else if(g_nKey == VK_DOWN){
nRow++;
if(nRow == nRowAll){
break;
}
}
if(pEdit)
pEdit->DestroyWindow();
TGridCell *pCellNew = (*pSheet)(nRow, nCol);
csText = pCellNew->GetText();
ptSize = pSheet->GetCellSize(nRow, nCol);
ptStart = pSheet->GetCellPoint(nRow, nCol);
ptEnd.x = ptStart.x + ptSize.x*DocGetPScale();
ptEnd.y = ptStart.y - ptSize.y*DocGetPScale();
CPoint ptDwgView1, ptDwgView2;
int cvport=0;
VERIFY(xg_getvar(_T("CVPORT"), &cvport)==RTNORM);
acedCoordFromWorldToPixel(cvport, ptStart, ptDwgView1);
acedCoordFromWorldToPixel(cvport, ptEnd, ptDwgView2);
pEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP |WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN,
CRect(ptDwgView1.x, ptDwgView1.y,ptDwgView2.x,ptDwgView2.y), acedGetAcadDwgView(), IDC_USER_SHEET_EDIT);
pEdit->SetWindowText(csText);
int lenText = csText.GetLength();
pEdit->SetSel(0, lenText);
pEdit->SetFocus();
}
else if(ret == RTCAN)
break;
}
pSheet->close();
InitSheetHook(FALSE);
if(pEdit)
pEdit->DestroyWindow();
delete pEdit;
}
////////////////////////////////////////////////////////////////////////////////////
// 单元复制
////////////////////////////////////////////////////////////////////////////////////
BOOL GetBlkAttrib(Entity entTemp, TCellBlockInsert &blk)
{
AcDbBlockReference *pBlockRef = NULL;// 定义块表指针
AcDbObjectId eId;
acdbGetObjectId(eId, entTemp);
acdbOpenObject(pBlockRef, eId, AcDb::kForRead);
if(!pBlockRef)
return FALSE;
AcDbObjectIterator *pIterator;
pIterator = pBlockRef->attributeIterator();
AcDbEntity *pEnt;
AcDbAttribute *pAtt;
for (pIterator->start(); !pIterator->done(); pIterator->step())
{
//遍历块中实体
AcDbObjectId att_id;
att_id = pIterator->objectId();
acdbOpenAcDbEntity(pEnt, att_id, AcDb::kForRead);
pAtt = AcDbAttribute::cast(pEnt);
if(pAtt != NULL)
{
TCHAR *cname = pAtt->tag();//得到标记
CString csRet, csTag;
csTag.Format(_T("%s"), cname);
if(pAtt->isInvisible() == Adesk::kFalse){
TCHAR *cval = pAtt->textString();//得到值
csRet.Format(_T("%s"), cval);
delete[] cval;
TAttribValue *pAttrib = new TAttribValue();
pAttrib->m_sName = csTag;
pAttrib->m_sValue = csRet;
blk.m_lstAttribs.Append(pAttrib);
}
delete[] cname;
}
pEnt->close();
}
delete pIterator;
pBlockRef->close();
return TRUE;
}
void CopyCellContent()
{
RBList rbMask = ads_buildlist( -4, _T("<or"), RTDXF0, _T("ATS_TEXT"), RTDXF0, _T("TEXT"), -4, _T("or>"), NULL);
BOOL bIsCopy = FALSE;
BOOL bIsBlk = FALSE;
Entity entText;
TSheetEdJig jig;
CString csCopyText;
TGridStyle oldStyle;
int nOldRow, nOldCol;
AcDbObjectId idOld = NULL;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
int nKeyIndex=0;
jig.SetKeyword(_T("A B"));
jig.SetPrompt(_T("\n点取拷贝源单元格 [选取文字(A)/选取图块(B)]<退出>:"));
while(1){
jig.SetOperCode(TSheetEdJig::kSingleCell);
int nCode=jig.DoIt(&nKeyIndex);
if(nCode == RTNORM){
AcDbObjectId idSheet = GetHitSheet(jig.m_ptResult);
if(!!idSheet) {
SHORT nStateCtrl = GetKeyState(VK_CONTROL);
BOOL bCtrl = (nStateCtrl&256)!=0;
OPENOBJ_BEGIN(idSheet, AcDb::kForWrite, TDbSheet, pSheet);
pSheet->assertWriteEnabled();
int nRow, nCol;
pSheet->HitTestOnCell(jig.m_ptResult, &nRow, &nCol);
TGridCell *pCell=(*pSheet)(nRow, nCol);
if(bIsCopy && !bCtrl){
if(!bIsBlk)
pCell->SetText(csCopyText);
else{
TCellBlockInsert blk;
blk.m_sBlockName = csCopyText;
blk.m_nControlFlag = CBF_AUTOSIZE | CBF_UNISCALE | CBF_SHOW_ATTR | CBF_EQUAL_SIDE;
GetBlkAttrib(entText, blk);
XString xsBlk;
blk.OutputDesc(xsBlk);
pCell->SetText(xsBlk);
}
}
else{
if(bCtrl && !!idOld) {
pSheet->assertWriteEnabled();
TGridCell *pCell=(*pSheet)(nOldRow, nOldCol);
pCell->SetGridStyle(oldStyle);
}
jig.SetPrompt(_T("\n点取粘贴至单元格(按CTRL键重新选择复制源)[选取文字(A)/选取图块(B)]<退出>: "));
idOld = idSheet;
oldStyle = pCell->GetGridStyle();
TGridStyle newStyle = oldStyle;
nOldRow = nRow;
nOldCol = nCol;
newStyle.SetFlagBit(OF_TEXTCOLOR, TRUE);
newStyle.SetTextColor(1);
pCell->SetGridStyle(newStyle);
csCopyText = pCell->GetText();
bIsCopy = TRUE;
bIsBlk = FALSE;
}
OPENOBJ_END();
}
}
else if(nCode == RTKWORD && nKeyIndex == 0){
if(SelectEntity(_T("\n请选择拷贝源文字<退出>:"), entText, rbMask) != RTNORM)
continue;
TCHAR szText[256];
entText.GetData(1, szText);
csCopyText = szText;
bIsCopy = TRUE;
bIsBlk = FALSE;
}
else if(nCode == RTKWORD && nKeyIndex == 1){
RBList rbMask2(RTDXF0, _T("INSERT"), 8, _T("*"), NULL);
if(SelectEntity(_T("\n请选择拷贝源图块<退出>:"), entText, rbMask2) != RTNORM)
continue;
TCHAR szText[256];
entText.GetData(2, szText);
csCopyText = szText;
bIsCopy = TRUE;
bIsBlk = TRUE;
}
else{
if(!!idOld) {
OPENOBJ_BEGIN(idOld, AcDb::kForWrite, TDbSheet, pSheet);
if(pSheet){
pSheet->assertWriteEnabled();
TGridCell *pCell=(*pSheet)(nOldRow, nOldCol);
pCell->SetGridStyle(oldStyle);
}
OPENOBJ_END();
}
break;
}
}
}