#include "StdAfx.h" // 键盘输入的返回结果 static int s_nInputRet; // 关键字列表,多个关键字中间不需要加空格区分 static const TCHAR* s_szKeyword; // Zyu add on 101208,键盘输入的关键字 static WPARAM s_nInput; CPoint m_ptLeft;// add by xly on 110104 鼠标点取位置 // 捕获键盘输入关键字的动作 static BOOL InputKeyWord(MSG* msg) { if (!acdbCurDwg()) { return FALSE; } BOOL bRet = FALSE; // 关键字控制表中的关键字的个数 int iLen = 0; for (iLen = 0; ;iLen++) { if (s_szKeyword[iLen] == _T('\0')) { break; } } //modify by lxb on 2011/12/01 switch(msg->message) { case WM_KEYDOWN: // 键盘输入 { if (msg->wParam == VK_RETURN || msg->wParam == VK_SPACE) // 键盘输入回车和空格 { s_nInputRet = RTNONE; msg->wParam = VK_SPACE; } else { for (int i = 0; i < iLen; i++) //是否是输入关键字 { if (msg->wParam == s_szKeyword[i]) { ads_printf(CString(s_szKeyword[i])); s_nInput = msg->wParam; s_nInputRet = RTKWORD; msg->wParam = VK_SPACE; } } } } break; case WM_RBUTTONDOWN: // 鼠标右键 { s_nInputRet = RTNONE; msg->wParam = VK_SPACE; } break; case WM_LBUTTONDOWN: // add by xly on 110104 鼠标左键点取位置 { m_ptLeft = msg->pt; } break; default: break; } /* // 没有关键字 if (iLen < 1) { // 没有关键字输入的时候支持判断结果 switch(msg->message) { case WM_KEYDOWN: // 键盘输入关键字 { if (msg->wParam == VK_RETURN || msg->wParam == VK_SPACE) // 键盘输入回车和空格 { s_nInputRet = RTNONE; msg->wParam = VK_SPACE; } } break; case WM_RBUTTONDOWN: // 鼠标右键 { s_nInputRet = RTNONE; msg->wParam = VK_SPACE; } break; case WM_LBUTTONDOWN: // add by xly on 110104 鼠标左键点取位置 { m_ptLeft = msg->pt; } break; default: break; } return bRet; } for (int i = 0; i < iLen; i++) { switch(msg->message) { case WM_KEYDOWN: // 键盘输入关键字 { if (msg->wParam == s_szKeyword[i]) // 键盘输入Q { ads_printf(CString(s_szKeyword[i])); s_nInputRet = RTKWORD; // Zyu add on 101208,保存键盘输入结果 s_nInput = msg->wParam; msg->wParam = VK_SPACE; } else if (msg->wParam == VK_RETURN || msg->wParam == VK_SPACE) // 键盘输入回车和回车 add by lxb on 2011/11/29 { s_nInputRet = RTNONE; msg->wParam = VK_SPACE; } } break; case WM_RBUTTONDOWN: // 鼠标右键 { s_nInputRet = RTNONE; msg->wParam = VK_SPACE; } break; case WM_LBUTTONDOWN: // add by xly on 110104 鼠标左键点取位置 { m_ptLeft = msg->pt; } break; default: break; } } */ return bRet; } // 判断选择集的选择的情况: // 1.选择了关键字:RTKWORD;2.按Esc键退出:RTCAN;3.选择到了实体:RTNORM; // 4.没有选择到实体:RTERROR;5.鼠标右键\回车:RTNONE // 修改关键字可以在钩子函数InputKeyWord中修改 int SelectEnts(CString csPrompt, PickSet &ssResult, TRBList &rbBaseMask, const TCHAR* szKeyword) { s_szKeyword = szKeyword; // 钩子函数监视键盘中输入关键字 acedRegisterFilterWinMsg(InputKeyWord); // 保存返回结果 int nRet = 0; const TCHAR *szTempPrompts[2]={csPrompt, _T("") }; int iRet = ssResult.Get(_T(":S:$"), szTempPrompts, NULL, rbBaseMask); if (s_nInputRet == RTKWORD) { nRet = RTKWORD; s_nInputRet = 0; } else if (s_nInputRet == RTNONE) { nRet = RTNONE; s_nInputRet = 0; } else if (iRet == RTNORM) { nRet = RTNORM; } else if (iRet == RTCAN) { nRet = RTCAN; } else { nRet = RTERROR; } // 释放函数 acedRemoveFilterWinMsg(InputKeyWord); return nRet; } // add by xly on 110128 两点构造一条多段线 TGGePoly2D GetExtentPolyByTwoCorner(const TADSGePoint3d &ptStart, const TADSGePoint3d &ptEnd ) { TADSGePoint3d ptLowLeft, ptLowRight, ptUpRight, ptUpLeft; if (ptStart.x > ptEnd.x) { ptLowLeft.x = ptEnd.x; ptUpLeft.x = ptEnd.x; ptLowRight.x = ptStart.x; ptUpRight.x = ptStart.x; } else { ptLowLeft.x = ptStart.x; ptUpLeft.x = ptStart.x; ptLowRight.x = ptEnd.x; ptUpRight.x = ptEnd.x; } if (ptStart.y > ptEnd.y) { ptLowLeft.y = ptEnd.y; ptLowRight.y = ptEnd.y; ptUpLeft.y = ptStart.y; ptUpRight.y = ptStart.y; } else { ptLowLeft.y = ptStart.y; ptLowRight.y = ptStart.y; ptUpLeft.y = ptEnd.y; ptUpRight.y = ptEnd.y; } TGGePoly2D poly(1); poly.AppendNode(ptLowLeft); poly.AppendNode(ptLowRight); poly.AppendNode(ptUpRight); poly.AppendNode(ptUpLeft); return poly; } // 判断选择集的选择的情况:只支持框选 // 1.选择了关键字:RTKWORD;2.按Esc键退出:RTCAN;3.选择到了实体:RTNORM; // 4.没有选择到实体:RTERROR;5.鼠标右键\回车:RTNONE;pt1:框选的角点;pt2:框选的角点 // 修改关键字可以在钩子函数InputKeyWord中修改 int SelectEnts1(CString csPrompt, PickSet &ssResult, TRBList &rbBaseMask, const TCHAR* szKeyword,XPoint &pt1,XPoint &pt2) { s_szKeyword = szKeyword; // 钩子函数监视键盘中输入关键字 acedRegisterFilterWinMsg(InputKeyWord); // 保存返回结果 int nRet = 0; nRet = acedGetPoint(NULL, csPrompt, pt1); if (nRet==RTNORM) { nRet = GetCornerPoint(pt1, NULL, pt2); if (nRet==RTNORM) { // 框选范围显示 TGGePoly2D poly = GetExtentPolyByTwoCorner(pt1, pt2); RBList rbRegion = poly.Polygon(); // 框选模式选择集 PickSet ssMouseSel(SS_FREE); ssMouseSel.Get(_T("CP"), rbRegion, NULL, rbBaseMask); } else { // 释放函数 acedRemoveFilterWinMsg(InputKeyWord); return nRet; } } if (s_nInputRet == RTKWORD) { nRet = RTKWORD; s_nInputRet = 0; } else if (s_nInputRet == RTNONE) { nRet = RTNONE; s_nInputRet = 0; } else if (nRet == RTNORM) { nRet = RTNORM; } else if (nRet == RTCAN) { nRet = RTCAN; } else { nRet = RTERROR; } // 释放函数 acedRemoveFilterWinMsg(InputKeyWord); return nRet; } // 此函数不是很准确,可以删除 int SelectEnts(CString csPrompt1, CString csPrompt2, PickSet &ssResult, TRBList &rbBaseMask, const TCHAR* szKeyword) { // 状态行提示 CString csPromt = csPrompt1, csKeyword = szKeyword; bool bIsFirSel= true; // 标记是否是第一次选择 PickSet ssNew(SS_FREE); // 保存选择集返回的结果 int nRet; while(1) { // 获得选择集的结果 nRet = SelectEnts(csPromt, ssResult, rbBaseMask, csKeyword); if (bIsFirSel) // 第一次选择 { if (nRet == RTKWORD) { break; } else if (nRet == RTNORM) { csPromt = csPrompt2; csKeyword = _T(""); bIsFirSel = false; ssResult.Redraw(3); ssNew += ssResult; continue; } else if (nRet == RTCAN|| nRet == RTNONE) { // 更新显示 ssResult.Redraw(4); break; } } else // 第一次以后的选择 { if (nRet == RTNORM) { ssResult.Redraw(3); continue; } else if (nRet == RTCAN) { ssResult.Redraw(4); // 更新显示 break; } else if (nRet == RTERROR) { continue; } else { break; } } } return nRet; } // sg add 110208,在用户拾取的区域内获得对象 // bAccurateLoc:在判断实体是否被选中时,是否精确比较线是否被选中,或者只粗略计算范围; // bEntInBlock:标记希望获得块内的对象,或者块对象; int GetEntityByPoly(TADSGePoint3d pt1, TADSGePoint3d pt2, AcDbObjectIdArray &idAry, BOOL bAccurateLoc, BOOL bEntInBlock, const TCHAR* pszDxf) { XPoint ptLow, ptUp, ptMax, ptMin; ptLow = Ucs2Wcs(pt1); ptUp = Ucs2Wcs(pt2); ptMax = Max(ptLow, ptUp); ptMin = Min(ptLow, ptUp); if (bEntInBlock) // 直接得到块内的对象 { GetViewSafeSelection(idAry, TRUE, ptMin, ptMax, pszDxf, bAccurateLoc); return RTNORM; } // 得到范围内的块对象 TGGePoly2D poly = GetExtentPolyByTwoCorner(pt1, pt2); RBList rbRegion = poly.Polygon(); // 框选模式选择集 PickSet ssMouseSel(SS_FREE); ssMouseSel.Get(_T("CP"), rbRegion, NULL, RBList()); ssMouseSel.AsIdArray(idAry); return RTNORM; } // modify by xly on 101104 支持多次选择的选择集,当第一次选择提示语第二次不同时,支持关键字(单个关键字); /* 参数说明: 首次选择时,支持输入关键字,在csPrompt1与csPrompt2两个字符串进行切换提示; 再次选择时,命令行提示csNextPrompt; 最终的选择结果,存放在ssResult中; aryPtInput,记录用户点选的点(世界坐标系); bFirState:记录关键字切换的开关; bAccurateLoc:在判断实体是否被选中时,是否精确比较线是否被选中,或者只粗略计算范围; bEntInBlock:标记希望获得块内的对象,或者块对象; 返回值说明: 用户取消选择时返回:RTCAN;右键回车时返回:RTNONE; */ int SelectEnts(CString csPrompt1, CString csPrompt2, PickSet &ssResult, TRBList &rbBaseMask, const TCHAR* szKeyword, CString csNextPrompt, AcGePoint3dArray &aryPtInput, bool &bFirState, BOOL bAccurateLoc, BOOL bEntInBlock) { // 状态行提示 CString csPromt = csPrompt1, csKeyword = szKeyword; bool bIsFirSel= true; // 标记是否是第一次选择 PickSet ssNew(SS_FREE); // 保存选择集返回的结果 int nRet(0); while(1) { if (bIsFirSel) { csPromt = bFirState ? csPrompt1 : csPrompt2; } // 获得选择集的结果 XPoint pt1, pt2; nRet = SelectEnts1(csPromt, ssNew, rbBaseMask, csKeyword, pt1, pt2); if (bIsFirSel) // 第一次选择 { if (nRet == RTKWORD) { bFirState = !bFirState; bEntInBlock = !bEntInBlock; continue; } else if (nRet == RTNORM) { // 第一次选择成功后,再次选择时切换提示语 csPromt = csNextPrompt; csKeyword = _T(""); bIsFirSel = false; // 保存成功点 aryPtInput.append(pt1); aryPtInput.append(pt2); // 根据框选点找到实体的id AcDbObjectIdArray arIds; GetEntityByPoly(pt1, pt2, arIds, bAccurateLoc, bEntInBlock); // 将实体的id保存到选择集中 for (int i=0; iisKindOf(AcDbText::desc()) && !pEnt->isKindOf(TDbText::desc())) continue; else if (pEnt->isKindOf(AcDbText::desc())) { if (!NDoorWinCheck::CheckName(CString(AcDbText::cast(pEnt)->textString()))) { arIds.removeAt(i--); continue; } } else if (pEnt->isKindOf(TDbText::desc())) { if (!NDoorWinCheck::CheckName(CString(TDbText::cast(pEnt)->GetText()))) { arIds.removeAt(i--); continue; } } if (!NDoorWinCheck::TextLayCompare(CString(pEnt->layer()))) { arIds.removeAt(i--); continue; } // if ((CString(_T("WINDOW_TEXT")).Compare(pEnt->layer()) != 0) && // (CString(_T("DOOR_FIRE_TEXT")).Compare(pEnt->layer()) != 0)) // { // arIds.removeAt(i--); // continue; // } } OPENOBJ_END() } } // sg modify 111017,清空上一次框选的选择集,其实放到“ssResult += ssNew”后更好 // ssNew.Erase(); ssNew.Free(); // 将实体的id保存到选择集中 int i = 0; for (i = 0; i < (int)arIds.length(); i++) { // sg add 111024,考虑将已有实体,不再重复添加到选择集中 if (NDoorWinCheck::FindIdArry(idAryAll, arIds[i]) != -1) // 对象已经在数组中 { arIds.removeAt(i--); continue; } ssNew += arIds.at(i); // 如果没有找到,再添加到选择集中和idAryAll、idAryBlock中 } idAryAll.append(arIds); idAryBlock.append(arIds); for (i = 0; i < (int)idAryBlock.length(); i++) { if (NDoorWinCheck::FindIdArry(aryIdsNoBlock, idAryBlock[i]) != -1) idAryBlock.removeAt(i--); } // 设置选择集亮显 ssNew.Redraw(3); ssResult += ssNew; continue; } else if (nRet == RTCAN) // 不与nRet==RTCAN合并的原因是区分取消(ESC)和右键回车 { ssResult.Redraw(4); // 更新显示 nRet = RTCAN; break; } else if (nRet == RTNONE) { ssResult.Redraw(4); // 更新显示 nRet = RTNORM; break; } } return nRet; } //监控系统消息类 和 选择集类 定义 //add by lxb on 2011/12/02 begin //Hook int THook::s_iValue = -1; CString THook::s_sKeyRet = _T(""); CString THook::s_sPormat = _T(""); CString THook::s_sKeyWord = _T(""); THook::THook(const CString &sPormat,TCHAR *pszKeyWord) { s_sPormat = _T(""); s_sPormat = sPormat; s_sKeyWord = _T(""); s_sKeyWord = pszKeyWord; acedRegisterFilterWinMsg(ListenMsg); } THook::~THook() { acedRemoveFilterWinMsg(ListenMsg); } int THook::GetValue() { int iRe = s_iValue; s_iValue = -1; return iRe; } CString THook::GetKeyWord() { CString sz = _T(""); TCHAR szKey[131] ={0}; if (s_sKeyWord != _T("")) { acedInitGet(RSG_OTHER,s_sKeyWord.GetBuffer(s_sKeyWord.GetLength())); acedGetKword(s_sPormat,szKey); } CString sCAD = szKey; if (sCAD == _T("")) { sz = s_sKeyRet; } else { sz = sCAD; } s_sKeyRet = _T(""); return sz; } BOOL THook::ListenMsg(MSG* pMsg) { switch (pMsg->message) { case WM_RBUTTONDOWN: { s_iValue = 1; } break; case WM_LBUTTONDOWN: { s_iValue = 0; } break; case WM_KEYDOWN: { if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_SPACE) { s_iValue = 1; } else if (pMsg->wParam == VK_ESCAPE) { s_iValue = 2; } else { for (int i = 0; i < s_sKeyWord.GetLength(); i++) { if (pMsg->wParam == s_sKeyWord[i])//关键字 { ads_printf(CString(s_sKeyWord[i])); s_sKeyRet.Format(_T("%c"),(TCHAR)pMsg->wParam); pMsg->wParam = VK_RETURN; break; } } } } break; default: break; } return(false);//消息继续传递下去 } //TPickEntSetEx TPickEntSetEx::TPickEntSetEx():ssTatol(PickSet(SS_FREE)) { } TPickEntSetEx::~TPickEntSetEx() { for (long i=0;i