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

655 lines
17 KiB
C++

#include "stdafx.h"
#include "KTNormDoorDlg.h"
#include "KTBlkRecsView.h"
#include "dbobjptr.h"
#include "KTSetting.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CAcExtensionModule Pool3dCmdDll;
#define WM_VIEWDBLCLKSEL (WM_USER + 0x1200)
KTNormDoorDlg::KTNormDoorDlg(CWnd* pParent /*=NULL*/)
: CDialog(KTNormDoorDlg::IDD, pParent)
, m_dHeight(2100)
, m_dElRef(0)
, m_sMaterial(_T("断桥铝合金玻璃门窗"))
, m_sProvider(_T("斯卡特门窗"))
{
//{{AFX_DATA_INIT(KTNormDoorDlg)
m_sDist = _T("300");
m_sNo = _T("No");
m_sWidth = _T("1500");
m_nInstyle = 2;
//}}AFX_DATA_INIT
m_dwData.m_sBlock = _T("KTDOOR02");
m_dwData.m_sBlock3D = _T("KTDOOR02_3D");
m_dwData.m_eInsStyle = kByCenter;
m_dwData.m_nType = 2;
m_sDwgFile = _T("KTDOOR02.dwg");
m_sDwg3DFile = _T("KTDOOR02_3D.dwg");
GET_CACHE(KTNormDoorDlg
, %s%s%s%d%f%s%f%s%s
, &m_sDist
, &m_sNo
, &m_sWidth
, &m_nInstyle
, &m_dHeight
, &m_dwData.m_sBlock
, &m_dwData.m_dBomEl
, &m_dwData.m_sMaterial
, &m_dwData.m_sProvider);
}
KTNormDoorDlg::~KTNormDoorDlg()
{
AcDbDatabase *pDb = NULL;
for (int i = 0; i < m_arpDb.length(); i++)
{
pDb = (AcDbDatabase *)m_arpDb.at(i);
delete pDb;
}
}
void KTNormDoorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STATIC_PREVIEW, m_wndPreView);
DDX_Control(pDX, IDC_TOOLTIP, m_wndTip);
DDX_Control(pDX, IDC_COMBOWIDTH, m_wndComboWidth);
DDX_Control(pDX, IDC_COMBONO, m_wndComboNo);
DDX_Control(pDX, IDC_COMBODIST, m_wndComboDist);
DDX_CBString(pDX, IDC_COMBODIST, m_sDist);
DDX_CBString(pDX, IDC_COMBONO, m_sNo);
DDX_CBString(pDX, IDC_COMBOWIDTH, m_sWidth);
DDX_Radio(pDX, IDC_SEQU_INSERT, m_nInstyle);
DDX_Text(pDX, IDC_EDIT1, m_dHeight);
DDX_Text(pDX, IDC_EDIT2, m_dElRef);
DDX_Text(pDX, IDC_EDIT12, m_sMaterial);
DDX_Text(pDX, IDC_EDIT3, m_sProvider);
}
BEGIN_MESSAGE_MAP(KTNormDoorDlg, CDialog)
//{{AFX_MSG_MAP(KTNormDoorDlg)
ON_MESSAGE(WM_VIEWDBLCLKSEL, OnStaticPreview)
ON_BN_CLICKED(IDC_SEQU_INSERT, OnSequInsert)
ON_BN_CLICKED(IDC_FIXT_ONPIER, OnFixtOnpier)
ON_BN_CLICKED(IDC_DOTE_CEN_INSERT, OnDoteCenInsert)
ON_BN_CLICKED(IDC_CENT_INSERT, OnCentInsert)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &KTNormDoorDlg::OnBnClickedButton1)
ON_WM_DESTROY()
END_MESSAGE_MAP()
BOOL KTNormDoorDlg::OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult)
{
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
UINT_PTR nCtrlID = pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
nCtrlID = ::GetDlgCtrlID((HWND)nCtrlID);
}
CString sTipText;
if (nCtrlID == IDC_SEQU_INSERT)
sTipText = _T("指定距离顺序插入");
else if(nCtrlID == IDC_DOTE_CEN_INSERT)
sTipText = _T("轴网居中定位插入");
else if(nCtrlID == IDC_CENT_INSERT)
sTipText = _T("按墙居中定位插入");
else if(nCtrlID == IDC_FIXT_ONPIER)
sTipText = _T("沿墙指定距离插入");
#ifdef UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
::WideCharToMultiByte(CP_ACP , 0, sTipText, -1, pTTTA->szText, sizeof(pTTTA->szText), NULL, NULL );
else
lstrcpyn(pTTTW->szText, sTipText, _tcslen(pTTTW->szText));
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
lstrcpyn(pTTTA->szText, sTipText, _tcslen(pTTTA->szText));
else
::MultiByteToWideChar(CP_ACP , 0, sTipText, -1, pTTTW->szText, sizeof(pTTTW->szText) );
#endif // UNICODE
*pResult = 0;
m_wndTip.SetWindowText(sTipText);
return TRUE;
}
BOOL KTNormDoorDlg::OnInitDialog()
{
CDialog::OnInitDialog();
EnableToolTips();
m_bmpStyle[0].LoadBitmap(IDB_SEQUINSERT);
m_bmpStyle[1].LoadBitmap(IDB_DOTECENINS);
m_bmpStyle[2].LoadBitmap(IDB_CENTINSERT);
m_bmpStyle[3].LoadBitmap(IDB_BUTTERINST);
((CButton*)GetDlgItem(IDC_SEQU_INSERT))->SetBitmap(m_bmpStyle[0]);
((CButton*)GetDlgItem(IDC_DOTE_CEN_INSERT))->SetBitmap(m_bmpStyle[1]);
((CButton*)GetDlgItem(IDC_CENT_INSERT))->SetBitmap(m_bmpStyle[2]);
((CButton*)GetDlgItem(IDC_FIXT_ONPIER))->SetBitmap(m_bmpStyle[3]);
((CButton*)GetDlgItem(IDC_SEQU_INSERT))->SetCheck(2);
if (!m_wndPreView.SubclassDlgItem(IDC_STATIC_PREVIEW,this))
return FALSE;
CString sDwgFile;
KTSetting::GetKTPsPath(sDwgFile);
sDwgFile += _T("Support\\Cells\\");
sDwgFile += m_sDwgFile;
m_sDwgFile = sDwgFile;
ShowSlide();
#ifndef ZWCAD
#if ARX>=20
m_wndPreView.mpView->setVisualStyle(AcGiVisualStyle::k2DWireframe);
#else
m_wndPreView.mpView->setMode(AcGsView::k2DOptimized);
#endif
#else
#if defined(R24)
m_wndPreView.mpView->setMode(AcGsView::k2DOptimized);
#else
m_wndPreView.mpView->setVisualStyle(AcGiVisualStyle::k2DWireframe);
#endif
#endif
m_wndComboDist.EnableWindow(FALSE);
InitGenDoorWidthCombo();
UpdateData(FALSE);
return TRUE;
}
void KTNormDoorDlg::InitGenDoorWidthCombo()
{
LPCTSTR pszWidths[] = {_T("700"),_T("750"),_T("800"),_T("900"),_T("1000"),_T("1100"),
_T("1200"),_T("1500"),_T("1800"),_T("2000"),_T("2400"),_T("2700"),_T("3000"),_T("3600"),0};
int i = 0;
while(pszWidths[i] != NULL)
{
if (m_wndComboWidth.FindString(0,pszWidths[i]) == -1)
{
m_wndComboWidth.AddString(pszWidths[i]);
}
++i;
}
}
LRESULT KTNormDoorDlg::OnStaticPreview(WPARAM wparam,LPARAM lparam)
{
KTBlkRecsView recView;
recView.SetCurRec(m_dwData.m_sBlock,FALSE);
int nRes = recView.DoModal();
if (nRes == IDOK)
{
CString s3DFile;
recView.GetCurRec(m_sDwgFile,m_dwData.m_sBlock,m_dwData.m_sBlock3D,s3DFile);
m_sDwg3DFile = s3DFile;
ShowSlide();
Invalidate();
RedrawWindow();
}
return 0l;
}
void KTNormDoorDlg::ShowSlide()
{
AcDbDatabase *pDb = new AcDbDatabase(false);
Acad::ErrorStatus es = pDb->readDwgFile(m_sDwgFile);
if (es != Acad::eOk)
{
AfxMessageBox(CString(_T("打开文件失败 \"")) + m_sDwgFile + _T("\""));
delete pDb;
return;
}
AcGsView *pView = m_wndPreView.view();
if (pView != NULL) pView->eraseAll();
// now initialise the drawing control
InitDrawingControl(pDb,m_dwData.m_sBlock);
m_arpDb.append(pDb);
}
Acad::ErrorStatus KTNormDoorDlg::InitDrawingControl (AcDbDatabase *pDb, const TCHAR *space)
{
// have we got a valid drawing
if (pDb == NULL)
return Acad::eNullBlockName;
AcDbBlockTableRecordPointer spaceRec(space, pDb, AcDb::kForRead);
// if ok
if (spaceRec.openStatus() == Acad::eOk)
{
// initialize the preview control
m_wndPreView.init(true);
// set the view to the *Active* AutoCAD view
CGsPreviewCtrl* pPreViewCtrl = &m_wndPreView;
AcGeMatrix3d xform;
SetViewTo(m_wndPreView.mpView, pDb, xform);
AcDbBlockReference *pRef = new AcDbBlockReference();
pRef->setBlockTableRecord(spaceRec->objectId());
pRef->setPosition(AcGePoint3d::kOrigin);
pRef->setRotation(0.0);
bool bIsDoor = true;
AcGeScale3d scale(500,500,500);
if (!bIsDoor)
scale.set(500,240,500);
pRef->setScaleFactors(scale);
pRef->setColorIndex(4);
pPreViewCtrl->view()->add(pRef, pPreViewCtrl->model());
AcGePoint3d ptS,ptE;
//绘制两侧墙体
AcDbLine* pLn = new AcDbLine;
ptS.set(-550,120,0);
ptE.set(-250,120,0);
pLn->setStartPoint(ptS);pLn->setEndPoint(ptE);
pLn->setColorIndex(9);
pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model());
pLn = new AcDbLine;
ptS.set(-250,120,0);
ptE.set(-250,-120,0);
pLn->setStartPoint(ptS);pLn->setEndPoint(ptE);
pLn->setColorIndex(9);
pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model());
pLn = new AcDbLine;
ptS.set(-250,-120,0);
ptE.set(-550,-120,0);
pLn->setStartPoint(ptS);pLn->setEndPoint(ptE);
pLn->setColorIndex(9);
pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model());
//R
pLn = new AcDbLine;
ptS.set(550,120,0);
ptE.set(250,120,0);
pLn->setStartPoint(ptS);pLn->setEndPoint(ptE);
pLn->setColorIndex(9);
pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model());
pLn = new AcDbLine;
ptS.set(250,120,0);
ptE.set(250,-120,0);
pLn->setStartPoint(ptS);pLn->setEndPoint(ptE);
pLn->setColorIndex(9);
pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model());
pLn = new AcDbLine;
ptS.set(250,-120,0);
ptE.set(550,-120,0);
pLn->setStartPoint(ptS);pLn->setEndPoint(ptE);
pLn->setColorIndex(9);
pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model());
// tell the view to display this space
m_wndPreView.view()->add(spaceRec.object(), m_wndPreView.model());
}
return spaceRec.openStatus();
}
bool KTNormDoorDlg::GetActiveViewPortInfo (AcDbDatabase *pDb, ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter)
{
// if not ok
if (pDb == NULL)
return false;
// get the current working database as a backup
AcDbDatabase *workingDataBase = acdbHostApplicationServices()->workingDatabase();
// now set the working database
//acdbHostApplicationServices()->setWorkingDatabase(pDb);
// make sure the active view port is uptodate
//acedVports2VportTableRecords();
// open the view port records
AcDbViewportTable *pVTable = NULL;
Acad::ErrorStatus es = pDb->getViewportTable (pVTable, AcDb::kForRead);
// if we opened them ok
if (es == Acad::eOk)
{
AcDbViewportTableRecord *pViewPortRec = NULL;
es = pVTable->getAt (_T("*Active"), pViewPortRec, AcDb::kForRead);
if (es == Acad::eOk)
{
// get the height of the view
height = pViewPortRec->height ();
// get the width
width = pViewPortRec->width ();
// if the user wants the center of the viewport used
if (getViewCenter == true)
{
struct resbuf rb;
memset (&rb, 0, sizeof (struct resbuf));
// get the system var VIEWCTR
acedGetVar (_T("VIEWCTR"), &rb);
// set that as the target
target = AcGePoint3d (rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
}
// we want the viewports camera target setting
else
{
// get the target of the view
target = pViewPortRec->target ();
}
// get the view direction
viewDir = pViewPortRec->viewDirection ();
// get the view twist of the viewport
viewTwist = pViewPortRec->viewTwist ();
}
// close after use
pVTable->close ();
pViewPortRec->close();
}
// now restore the original working database
// acdbHostApplicationServices()->setWorkingDatabase(workingDataBase);
return (true);
}
//////////////////////////////////////////////////////////////////////////
// set the passed AcGsView to the *Active* AutoCAD AcDbDatabase view
void KTNormDoorDlg::SetViewTo(AcGsView *pView, AcDbDatabase *pDb, AcGeMatrix3d& viewMat)
{
// we are going to set the view to the current view of the drawing
// The overall approach is to calculate the extents of the database in the coordinate system of the view
// Calculate the extents in WCS
AcGePoint3d extMax(500,500,0); //= pDb->extmax();
AcGePoint3d extMin(-500,-500,0); //= pDb->extmin();
// get the view port information - see parameter list
ads_real height = 0.0, width = 0.0, viewTwist = 0.0;
AcGePoint3d targetView;
AcGeVector3d viewDir;
GetActiveViewPortInfo (pDb, height, width, targetView, viewDir, viewTwist, true);
// we are only interested in the directions of the view, not the sizes, so we normalise.
viewDir = viewDir.normal();
//**********************************************
// Our view coordinate space consists of z direction
// get a perp vector off the z direction
// Make sure its normalised
AcGeVector3d viewXDir = viewDir.perpVector ().normal();
// correct the x angle by applying the twist
viewXDir = viewXDir.rotateBy (viewTwist, -viewDir);
// now we can work out y, this is of course perp to the x and z directions. No need to normalise this,
// as we know that x and z are of unit length, and perpendicular, so their cross product must be on unit length
AcGeVector3d viewYDir = viewDir.crossProduct (viewXDir);
// find a nice point around which to transform the view. We'll use the same point as the center of the view.
AcGePoint3d boxCenter = extMin + 0.5 * ( extMax - extMin );
//**********************************************
// create a transform from WCS to View space
// this represents the transformation from WCS to the view space. (Actually not quite since
// we are keeping the fixed point as the center of the box for convenience )
viewMat = AcGeMatrix3d::alignCoordSys (boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
boxCenter, viewXDir, viewYDir, viewDir).inverse();
AcDbExtents wcsExtents(extMin, extMax);
// now we have the view Extents
AcDbExtents viewExtents = wcsExtents;
// transforms the extents in WCS->view space
viewExtents.transformBy (viewMat);
//**********************************************
// get the extents of the AutoCAD view
double xMax = fabs(viewExtents.maxPoint ().x - viewExtents.minPoint ().x);
double yMax = fabs(viewExtents.maxPoint ().y - viewExtents.minPoint ().y);
//**********************************************
// setup the view
AcGePoint3d eye = boxCenter + viewDir;
// upvector
pView->setView(eye, boxCenter, viewYDir, xMax, yMax);
// update the gsView
if (pView != NULL)
{
pView->invalidate();
pView->update();
}
}
void KTNormDoorDlg::OnOK()
{
UpdateData();
double dWidth = _ttof(m_sWidth);
if (dWidth < 1.0)
{
AfxMessageBox(_T("门宽度太小,请输入合适的宽度!"));
return;
}
//创建blockrec id;
if (!CreateBlockRecord())
{
AfxMessageBox(_T("创建门窗二维块失败,检查软件安装是否正确!"));
return;
}
if (!CreateBlockRecord3d())
{
AfxMessageBox(_T("创建门窗三维块失败,检查软件安装是否正确!"));
return;
}
m_dwData.m_dWidth = dWidth;
m_dwData.m_sNo = m_sNo;
m_dwData.m_dDistFr = _ttof(m_sDist);
m_dwData.m_eInsStyle = (InsStyle)(m_nInstyle + 1);
m_dwData.m_dHeight = m_dHeight;
m_dwData.m_dBomEl = 0.0;
SET_CACHE(KTNormDoorDlg
, %s%s%s%d%f%s%f%s%s
, m_sDist
, m_sNo
, m_sWidth
, m_nInstyle
, m_dHeight
, m_dwData.m_sBlock
, m_dwData.m_dBomEl
, m_dwData.m_sMaterial
, m_dwData.m_sProvider);
CDialog::OnOK();
}
void KTNormDoorDlg::OnCancel()
{
CDialog::OnCancel();
}
DWDATA* KTNormDoorDlg::GetData()
{
AcDbBlockTable* pTable = NULL;
acdbCurDwg()->getBlockTable(pTable,AcDb::kForRead);
if (pTable != NULL)
{
pTable->getAt(m_dwData.m_sBlock,m_dwData.m_idRec);
pTable->close();
}
m_dwData.m_dHeight = m_dHeight;
m_dwData.m_dBomEl = m_dElRef;
m_dwData.m_sMaterial = m_sMaterial;
m_dwData.m_sProvider = m_sProvider;
return &m_dwData;
}
void KTNormDoorDlg::OnSequInsert()
{
m_dwData.m_eInsStyle = kByOrder;
m_wndComboDist.EnableWindow(FALSE);
}
void KTNormDoorDlg::OnFixtOnpier()
{
m_dwData.m_eInsStyle = kByButter;
m_wndComboDist.EnableWindow(TRUE);
}
void KTNormDoorDlg::OnDoteCenInsert()
{
m_dwData.m_eInsStyle = kByDoteCen;
m_wndComboDist.EnableWindow(FALSE);
}
void KTNormDoorDlg::OnCentInsert()
{
m_dwData.m_eInsStyle = kByCenter;
m_wndComboDist.EnableWindow(FALSE);
}
BOOL KTNormDoorDlg::CreateBlockRecord()
{
AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTable* pTbl = NULL;
pWorkDb->getSymbolTable(pTbl, AcDb::kForRead);
if (pTbl != NULL)
{
if ( Acad::eOk == pTbl->getAt(m_dwData.m_sBlock,m_dwData.m_idRec) )
{
pTbl->close();
return TRUE;
}
pTbl->close();
}
AcDbDatabase* pDb = new AcDbDatabase(false);
ASSERT(pDB != NULL);
if (pDb->readDwgFile(m_sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk)
{
delete pDb;
return FALSE;
}
AcDbBlockTable* pBT = NULL;
pDb->getSymbolTable(pBT, AcDb::kForRead);
if (pBT == NULL)
{
delete pDb;
return FALSE;
}
AcDbObjectId idBlock;
pBT->getAt(m_dwData.m_sBlock, idBlock);
pBT->close();
AcDbDatabase* pTempDb = NULL;
pDb->wblock(pTempDb, idBlock);
delete pDb;
if (pTempDb == NULL) return FALSE;
if (pWorkDb->insert(m_dwData.m_idRec, m_dwData.m_sBlock, pTempDb) != Acad::eOk)
{
delete pTempDb;
return FALSE;
}
delete pTempDb;
return TRUE;
}
BOOL KTNormDoorDlg::CreateBlockRecord3d()
{
TCHAR sDrive[MAX_PATH],sDir[MAX_PATH],sFileName[MAX_PATH],sExt[MAX_PATH];
#ifdef _UNICODE
_wsplitpath(m_sDwgFile, sDrive, sDir, sFileName, sExt);
#else
_splitpath(m_sDwgFile, sDrive, sDir, sFileName, sExt);
#endif
AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTable* pTbl = NULL;
pWorkDb->getSymbolTable(pTbl, AcDb::kForRead);
if (pTbl != NULL)
{
if ( Acad::eOk == pTbl->getAt(m_dwData.m_sBlock3D, m_dwData.m_idRec3d) )
{
pTbl->close();
return TRUE;
}
pTbl->close();
}
CString sDwg3DFile;
sDwg3DFile.Format(_T("%s%s%s"),sDrive,sDir,m_sDwg3DFile);
AcDbDatabase* pDb = new AcDbDatabase(false);
ASSERT(pDB != NULL);
if (pDb->readDwgFile(sDwg3DFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk)
{
delete pDb;
return FALSE;
}
AcDbBlockTable* pBT = NULL;
pDb->getSymbolTable(pBT, AcDb::kForRead);
if (pBT == NULL)
{
delete pDb;
return FALSE;
}
AcDbObjectId idBlock;
pBT->getAt(m_dwData.m_sBlock3D, idBlock);
pBT->close();
AcDbDatabase* pTempDb = NULL;
pDb->wblock(pTempDb, idBlock);
delete pDb;
if (pTempDb == NULL) return FALSE;
if (pWorkDb->insert(m_dwData.m_idRec3d, m_dwData.m_sBlock3D, pTempDb) != Acad::eOk)
{
delete pTempDb;
return FALSE;
}
delete pTempDb;
return TRUE;
}
void KTNormDoorDlg::OnBnClickedButton1()
{
OnStaticPreview(0,0);
}
void KTNormDoorDlg::OnDestroy()
{
CDialog::OnDestroy();
}