Files
envi-code/SourceCode/Code2026/Dimension/InPlaceEdit.cpp
T
2026-09-28 15:28:50 +08:00

702 lines
15 KiB
C++

#include "stdafx.h"
#include "acdocman.h "
#include "InplaceEdit.h"
#include "globalFunc.h"
#include "PickEntSet.h"
#include "AcDbObjectPtr.h"
#include "AecDbEntityBaseEx.h"
CInPlaceEdit g_InPlaceEdit;
static int g_colorInPlaceText = RGB(0, 70, 160);
static int g_colorInPlaceGround = RGB(235, 233, 230);
static int g_iInPlaceFontHeight = 18;
//TARCH_IMPEXP bool GlobalFunc::FindRT_MANIFEST();
CInPlaceEdit::CInPlaceEdit():m_pSubText(NULL),m_bDoModel(false),m_bSetMessageText(FALSE)
{
acedEditor->addReactor(this);
}
CInPlaceEdit::~CInPlaceEdit()
{
if (this != &g_InPlaceEdit)
acedEditor->removeReactor(this);
if(m_pSubText!=NULL)
delete m_pSubText;
}
void CInPlaceEdit::lispWillStart(const TCHAR * firstLine)
{
EndEdit();
}
void CInPlaceEdit::commandWillStart(const TCHAR * cmdStr)
{
EndEdit();
}
void CInPlaceEdit::BeginEdit(SubText*pSubText)
{
if(pSubText==NULL)
return;
bool bDifEnt=true;
if(m_pSubText!=NULL&&pSubText!=NULL&&
m_pSubText->GetObjectId()==pSubText->GetObjectId())
{
bDifEnt=false;
if(m_pSubText->GetIndex()==pSubText->GetIndex())
{
delete pSubText;
return;
}
}
CWnd *pView=acedGetAcadDwgView();
if(pView==NULL)
{
delete pSubText;
return;
}
EndEdit(bDifEnt);
m_pSubText=pSubText;
if(bDifEnt)
m_pSubText->Highlight();
XPoint ptMin,ptMax;
CString sText=pSubText->GetText();
pSubText->GetExtent2d(ptMin,ptMax);
// 空轴号时取不出轮廓,即轮廓无效 --- wyg 20090618
if(ptMin.Distance2d(ptMax)<1E-6 || ptMin.x > ptMax.x)
//if(ptMin.Distance2d(ptMax)<1E-6)
{
pSubText->SetText(_T("SHS"));
pSubText->GetExtent2d(ptMin,ptMax);
pSubText->SetText(sText);
}
CPoint pt0,pt1;
int cvport=0;
xg_getvar(_T("CVPORT"), &cvport);
acedCoordFromWorldToPixel(cvport, ptMin, pt0);
acedCoordFromWorldToPixel(cvport, ptMax, pt1);
CRect rect(min(pt0.x,pt1.x),min(pt0.y,pt1.y),max(pt0.x,pt1.x),max(pt0.y,pt1.y));
CPoint ptCenter=rect.CenterPoint();
TCString sAcadVer;
xg_getvar(_T("ACADVER"), sAcadVer);
double dAcadVer = _tstof(sAcadVer);
//modify by xlc on 110616 解决2012平台在位编辑框不显示的问题
//Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL|ES_MULTILINE|ES_WANTRETURN,CRect(0,0,0,0),pView,6000);
if (dAcadVer > 18.11)
{
pView->ClientToScreen(&ptCenter);
acedGetAcadFrame()->ScreenToClient(&ptCenter);
Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL|ES_MULTILINE|ES_WANTRETURN,CRect(0,0,0,0),acedGetAcadFrame(),6000);
}
else
{
Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL|ES_MULTILINE|ES_WANTRETURN,CRect(0,0,0,0),pView,6000);
}
CFont font;
font.CreateStockObject(DEFAULT_GUI_FONT);
LOGFONT logFont;
font.GetObject (sizeof (logFont),&logFont);
logFont.lfHeight=-g_iInPlaceFontHeight;
m_font.CreateFontIndirect (&logFont);
SetFont(&m_font);
CSize size=GetDC()->GetOutputTextExtent(_T("a"));
CRect rectEdit(ptCenter.x-size.cy*0.8,ptCenter.y-size.cy/2,ptCenter.x+size.cy*0.8,ptCenter.y+size.cy/2);
//add by xlc on 110616 解决2012平台空字符串时编辑框偏移的问题
if (dAcadVer < 18.11)
{
if(sText==_T(""))
{
long dx=rectEdit.left-min(pt0.x,pt1.x);
rectEdit.OffsetRect(-dx,0);
}
}
MoveWindow(rectEdit);
m_bCreating=true;
SetWindowText(sText);
SetSel(0,-1);
SetFocus();
SetModify(FALSE);
RecalcLayout();
m_bCreating=false;
CPoint ptCursor;
GetCursorPos(&ptCursor);
GetParent()->ScreenToClient(&ptCursor);
if(!rect.PtInRect(ptCursor))
{
GetWindowRect(rect);
ptCenter=rect.CenterPoint();
SetCursorPos(ptCenter.x,ptCenter.y);
}
//modify by xlc on 110616 解决2012平台在位编辑框不显示的问题
if (dAcadVer > 18.11)
{
this->BringWindowToTop();
}
}
void CInPlaceEdit::RefreshPlace()
{
CWnd *pView=acedGetAcadDwgView();
XPoint ptMin,ptMax;
CString sText=m_pSubText->GetText();
m_pSubText->GetExtent2d(ptMin,ptMax);
// 空轴号时取不出轮廓,即轮廓无效 --- wyg 20090618
if(ptMin.Distance2d(ptMax)<1E-6 || ptMin.x > ptMax.x)
//if(ptMin.Distance2d(ptMax)<1E-6)
{
m_pSubText->SetText(_T("TArch"));
m_pSubText->GetExtent2d(ptMin,ptMax);
m_pSubText->SetText(sText);
}
CPoint pt0,pt1;
int cvport=0;
xg_getvar(_T("CVPORT"), &cvport);
acedCoordFromWorldToPixel(cvport, ptMin, pt0);
acedCoordFromWorldToPixel(cvport, ptMax, pt1);
CRect rect(min(pt0.x,pt1.x),min(pt0.y,pt1.y),max(pt0.x,pt1.x),max(pt0.y,pt1.y));
CPoint ptCenter=rect.CenterPoint();
CRect rectEdit;
GetWindowRect(rectEdit);
int width=rectEdit.Width(),height=rectEdit.Height();
rectEdit.left=ptCenter.x-width/2;
rectEdit.right=ptCenter.x+width/2;
rectEdit.top=ptCenter.y-height/2;
rectEdit.bottom=ptCenter.y+height/2;
MoveWindow(rectEdit,FALSE);
RecalcLayout();
Invalidate();
ShowCaret();
}
void CInPlaceEdit::RecalcLayout()
{
bool bCenter=m_bCreating;
//取当前范围
CRect rect,rectParent,rectOld;
GetParent()->GetWindowRect(rectParent);//父窗口范围
GetParent()->ScreenToClient(rectParent);
GetWindowRect(rect);//当前范围
GetParent()->ScreenToClient(rect);
rectOld=rect;
//确定大小
CSize size(0,0);
CDC *pDC=GetDC();
pDC->SelectObject(&m_font);
CString sText;
GetWindowText(sText);
if(sText.GetLength()>0&&m_pSubText->IsMultiLine())
{
for(long s=0;s<sText.GetLength();)
{
long e=sText.Find(_T('\n'),s);
if(e==NOT_FOUND)
e=sText.GetLength();
CSize sizeLine=pDC->GetOutputTextExtent(sText.Mid(s,e-s));
if(sizeLine.cx>size.cx)
size.cx=sizeLine.cx;
if(sizeLine.cy<=0)
sizeLine=pDC->GetOutputTextExtent(_T("a"));
size.cy+=sizeLine.cy;
s=e+1;
}
if(sText.GetLength()>0&&sText.GetAt(sText.GetLength()-1)==_T('\n'))
{
CSize sizeLine=pDC->GetOutputTextExtent(_T("a"));
size.cy+=sizeLine.cy;
}
}
else if(sText.GetLength()==0)
size=pDC->GetOutputTextExtent(_T("a"));
else
size=pDC->GetOutputTextExtent(sText);
ReleaseDC(pDC);
size.cy+=5;
size.cx+=18;
if(size.cy>rectParent.Height()-10)
size.cy=rectParent.Height()-10;
if(size.cx<24)
size.cx=24;
if(size.cx>rectParent.Width()-10)
size.cx=rectParent.Width()-10;
//调整大小
long dx=size.cx-rect.Width();
if(dx>0)
{
if(bCenter)
{
rect.left-=dx/2;
rect.right+=dx-dx/2;
}
else
rect.right+=dx;
}
long dy=size.cy-rect.Height();
if(dy>0)
{
if(bCenter)
{
rect.top-=dy/2;
rect.bottom+=dy-dy/2;
}
else
rect.bottom+=dy;
}
//调整当前窗口到父窗口范围
if(rect.left<rectParent.left+5)
rect.OffsetRect(rectParent.left+5-rect.left,0);
if(rect.right>rectParent.right-5)
rect.OffsetRect(rectParent.right-5-rect.right,0);
if(rect.top<rectParent.top+5)
rect.OffsetRect(0,rectParent.top+5-rect.top);
if(rect.bottom>rectParent.bottom-5)
rect.OffsetRect(0,rectParent.bottom-5-rect.bottom);
if(rectOld!=rect)
MoveWindow(rect);
}
void CInPlaceEdit::MoveToNext(bool bVert,bool bPre)//ok
{
if(m_pSubText==NULL)
return;
SubText*pNext=m_pSubText->GetNext(bVert,bPre);
if(pNext==NULL)
return;
BeginEdit(pNext);
}
void CInPlaceEdit::EndEdit(bool bUnhighlight)//ok
{
if(m_pSubText==NULL)
return;
if(GetSafeHwnd()==NULL)
{
delete m_pSubText;
m_pSubText=NULL;
return;
}
if(bUnhighlight)
m_pSubText->Highlight(false);
if(GetModify())
{
CString sText;
GetWindowText(sText);
acDocManager->lockDocument(curDoc());
m_pSubText->Update(sText);
acDocManager->unlockDocument(curDoc());
if(!bUnhighlight)
m_pSubText->Highlight();
}
delete m_pSubText;
m_pSubText=NULL;
DestroyWindow();
}
void CInPlaceEdit::CancelEdit()//ok
{
if(m_pSubText!=NULL)
{
m_pSubText->Highlight(false);
delete m_pSubText;
m_pSubText=NULL;
}
if(GetSafeHwnd()!=NULL)
DestroyWindow();
}
BEGIN_MESSAGE_MAP(CInPlaceEdit,CEdit)
ON_WM_KILLFOCUS()
ON_WM_MENUSELECT()
ON_WM_EXITMENULOOP()
ON_MESSAGE(WM_ACAD_KEEPFOCUS, onAcadKeepFocus)
ON_CONTROL_REFLECT_EX(EN_CHANGE, OnEnChange)
ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()
HBRUSH CInPlaceEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
m_brush.DeleteObject();
m_brush.CreateSolidBrush(g_colorInPlaceGround);
pDC->SelectObject(&m_brush);
pDC->SetTextColor((COLORREF)g_colorInPlaceText);
pDC->SetBkColor((COLORREF)g_colorInPlaceGround);
return (HBRUSH)(m_brush.GetSafeHandle());
}
BOOL CInPlaceEdit::OnEnChange()
{
RecalcLayout();
SetCursor(LoadCursor(NULL,IDC_IBEAM));
return TRUE;
}
LONG_PTR CInPlaceEdit::onAcadKeepFocus( UINT_PTR, LONG_PTR )//ok
{
return TRUE;
}
void CInPlaceEdit::OnKillFocus(CWnd*pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
if(!m_bDoModel&&!IsChild(pNewWnd))
EndEdit();
}
bool CInPlaceEdit::IsLeftEnd()
{
int s,e;
GetSel(s,e);
return e==0;
}
bool CInPlaceEdit::IsRightEnd()
{
int l,h;
GetSel(l,h);
CString sText;
GetWindowText(sText);
#if (ADS>15)
if(GlobalFunc::FindRT_MANIFEST())
{
OSVERSIONINFO osVer;
osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
VERIFY(GetVersionEx(&osVer)==TRUE);
if(osVer.dwPlatformId==VER_PLATFORM_WIN32_NT && osVer.dwMajorVersion>=5 && osVer.dwMinorVersion>=1) {
CString csText=sText;
XString xsText;
xsText=csText;
int nCount=_tcslen(xsText);
int iLow=l, iUp=h;
for(int idx=0; idx<nCount; idx++) {
if(idx>=iUp)
break;
TCHAR c=xsText[idx];
if(c<0) { //汉字
if(idx<iLow)
iLow++;
if(idx<iUp)
iUp++;
idx++;
}
}
l=iLow;
h=iUp;
}
}
#endif
return h==sText.GetLength();
}
bool CInPlaceEdit::IsUpEnd()
{
if(m_pSubText->IsMultiLine())
{
int s,e;
GetSel(s,e);
return LineFromChar(s)==0;
}
return true;
}
bool CInPlaceEdit::IsDownEnd()
{
if(m_pSubText->IsMultiLine())
{
int s,e;
GetSel(s,e);
return LineFromChar(e)==GetLineCount()-1;
}
return true;
}
BOOL CInPlaceEdit::PreTranslateMessage(MSG *pMsg)
{
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_RETURN)
{
if(!m_pSubText->IsMultiLine())
{
EndEdit();
return TRUE;
}
else
{
CRect rect,rectParent;
GetWindowRect(rect);
GetParent()->GetWindowRect(rectParent);
CDC* pDC=GetDC();
pDC->SelectObject(&m_font);
CSize size=pDC->GetOutputTextExtent(_T("a"));
ReleaseDC(pDC);
rect.bottom+=size.cy;
if(rectParent.Height()-10>=rect.Height())
{
GetParent()->ScreenToClient(rect);
MoveWindow(rect);
}
}
}
else if(pMsg->wParam==VK_ESCAPE)
{
CancelEdit();
return TRUE;
}
else if(pMsg->wParam==VK_TAB)
{
MoveToNext(false,false);
return TRUE;
}
else if(pMsg->wParam==VK_RIGHT&&IsRightEnd())
{
MoveToNext(false,false);
return TRUE;
}
else if(pMsg->wParam==VK_LEFT&&IsLeftEnd())
{
MoveToNext(false,true);
return TRUE;
}
else if(pMsg->wParam==VK_UP&&IsUpEnd())
{
MoveToNext(true,true);
return TRUE;
}
else if(pMsg->wParam==VK_DOWN&&IsDownEnd())
{
MoveToNext(true,false);
return TRUE;
}
}
else if(pMsg->message==WM_MOUSEWHEEL)
GetParent()->PostMessage(WM_MOUSEWHEEL,pMsg->wParam,pMsg->lParam);
else if(pMsg->message==WM_VIEW_CHANGED)
RefreshPlace();
return CEdit::PreTranslateMessage(pMsg);
}
bool CInPlaceEdit::GetPosition(int& h, int& l)
{
DWORD n;
n = GetSel();
l = (int)LOWORD(n);
h = (int)HIWORD(n);
#if (ADS>15)
if(!GlobalFunc::FindRT_MANIFEST())
return TRUE;
OSVERSIONINFO osVer;
osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
VERIFY(GetVersionEx(&osVer)==TRUE);
if(osVer.dwPlatformId==VER_PLATFORM_WIN32_NT && osVer.dwMajorVersion>=5 && osVer.dwMinorVersion>=1) {
CString csText;
GetWindowText(csText);
XString xsText;
xsText=csText;
int nCount=_tcslen(xsText);
int iLow=l, iUp=h;
for(int idx=0; idx<nCount; idx++) {
if(idx>=iUp)
break;
TCHAR c=xsText[idx];
if(c<0) { //汉字
if(idx<iLow)
iLow++;
if(idx<iUp)
iUp++;
idx++;
}
}
l=iLow;
h=iUp;
}
#endif
return TRUE;
}
void InPlaceEdit()
{
RBList mask(RTDXF0,_T("AEC_*"),NULL);
Entity ent;
if(GlobalFunc::SelectEntity(_T("\n选择需要修改文字的图元<退出>:"),ent,mask)!=RTNORM)
return;
SubText*pSubText=NULL;
OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbEntityBaseEx, pEnt);
if(pEnt!=NULL)
{
pSubText=pEnt->GetSubText(0);
if(pSubText==NULL)
pSubText=pEnt->GetSubText(1);
}
OPENOBJ_END();
if(pSubText==NULL)
{
OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbCurveBaseEx, pEnt);
if(pEnt!=NULL)
pSubText=pEnt->GetSubText(0);
OPENOBJ_END();
}
if(pSubText!=NULL)
{
acedSSSetFirst(NULL,NULL);
g_InPlaceEdit.BeginEdit(pSubText);
}
}
BOOL MsgHookBody(MSG *msg)
{
TCString sAcadVer;
xg_getvar(_T("ACADVER"), sAcadVer);
double dAcadVer = _tstof(sAcadVer);
BOOL bSelNull = FALSE;// SB add 2004/4/26 空点右键
static bool bLockCtrl = false;
XString sCmdNames;
xg_getvar(_T("CMDNAMES"), sCmdNames);
if (_tcsstr(sCmdNames, _T("3DORBIT")))
return FALSE;
// 3DORBIT的时候不能更改视图
BOOL nRet = FALSE;
AcGsView *pGsView = NULL;
CRect rect;
static DWORD nRBtnDownTime = 0xFFFFFFFF;
switch (msg->message)
{
case WM_LBUTTONDBLCLK:
{
int nCmdActive = 0;
xg_getvar(_T("CMDACTIVE"), &nCmdActive);
CView *pView = GlobalFunc::GetCurDwgView();
if (!nCmdActive&&pView!=NULL)
{
XPoint pt;
CPoint ptClient = msg->pt;
pView->ScreenToClient(&ptClient);
int nCurVp = 0;
xg_getvar(_T("CVPORT"), &nCurVp);
acedCoordFromPixelToWorld(nCurVp, ptClient, pt);
XPoint ptUcs = GlobalFunc::Wcs2Ucs(pt);
if (!g_InPlaceEdit.IsWindowVisible())
{
SubText *pSubText = NULL;
PickSet ss(SS_FREE);
if (dAcadVer>16.1)
{
RBList mask(RTDXF0, _T("AEC_*"), NULL);
ss.Get(ptUcs, mask);
}
else
{
RBList mask(RTDXF0, _T("AEC_*,TEXT"), NULL);
ss.Get(ptUcs, mask);
}
if (ss.Length()==0)
{
XPoint _pt2(ptUcs.x, ptUcs.y+1E9);
XPoint _pt1(ptUcs.x, ptUcs.y-1E9);
RBList rbFence = ads_buildlist(RT3DPOINT, &_pt1, RT3DPOINT, &_pt2, NULL);
ss.Get(_T("F"), rbFence, NULL,
RBList(RTDXF0, _T("AEC_SUOYINTUMING,AEC_SUOYINFUHAO"), NULL));
}
pSubText = GlobalFunc::HitTestOnText(ss, pt);
if (pSubText!=NULL)
{
acedSSSetFirst(NULL, NULL);
g_InPlaceEdit.BeginEdit(pSubText);
acedPostCommand(_T("\33"));
nRet = TRUE;
break;
}
else
{
//双击空白取消对象选择
PickSet ss1(SS_FREE);
ss1.Get(ptUcs);
if (ss1.Length()==0)
{
acedSSSetFirst(NULL, NULL);
acedPostCommand(_T("\33"));
//nRet=TRUE;
break;
}
}
}
}
//双击启动对象编辑
if (!nCmdActive)
{
PickSet ss(SS_FREE);
RBList mask(RTDXF0, _T("AEC_*"), NULL);
ss.Get(_T("I"), NULL, NULL, mask);
BOOL bFlag = FALSE;
AecObjectEditMethod pMethod = NULL;
if (ss.Length()==1)
{
OPENOBJ_BEGIN(ss[0L], AcDb::kForRead, AecXDbEntityBaseEx, pEnt);
if (pEnt!=NULL)
pMethod = pEnt->GetEditMethod();
OPENOBJ_END();
OPENOBJ_BEGIN(ss[0L], AcDb::kForRead, AecXDbCurveBaseEx, pEnt);
if (pEnt!=NULL)
pMethod = pEnt->GetEditMethod();
OPENOBJ_END();
if (pMethod)
{
AcDbObjectId idObj;
if (acdbGetObjectId(idObj, ss[0L]) == Acad::eOk)
{
pMethod(idObj);
nRet = TRUE;
}
}
}
}
}
break;
default:
break;
}
return nRet;
}
#if ARX > 22
bool AecGlobalMsgHook(MSG *msg)
#else
BOOL AecGlobalMsgHook(MSG *msg)
#endif
{
if (!curDoc() || !acdbCurDwg() || !GlobalFunc::IsOfAcadWindows(msg->hwnd)
//|| !GlobalFunc::DocGetIsDwgBegin() // Add on 2002/6/10, 解决打开图形未完成时键入字符导致崩溃
)
return FALSE;
int wpara = msg->wParam;
BOOL bRet = MsgHookBody(msg);
return bRet;
}