По поводу первого вопроса:
1) acedCommand в этом контексте использовать нельзя. Можно или acedPostCommand или curDoc()->sendStringToExecute()
2) В твоем коде ты не блокируешь действие клавиши DELETE, что приводит к тому что AutoCAD должен удалить выбранные тобой примитивы. Функция acedRegisterFilterWinMsg требует callback-функции, которая возвращает TRUE или FALSE. Причем если она возвращает TRUE, то этот MSG не передается дальше для обработки в AutoCAD.
Вот пример работающей функции, которая запускает команду _ERASE если нажата клавиша DELETE:
BOOL IsPickFirstEmpty()
{
RB *gset = NULL, *pset = NULL;
BOOL flag_empty = TRUE;
if (acedSSGetFirst(&gset,&pset) == RTNORM) {
if (pset) {
if (pset->restype == RTPICKS) {
long l = 0;
acedSSLength(pset->resval.rlname,&l);
acedSSFree(pset->resval.rlname);
if (l > 0) flag_empty = FALSE;
}
acutRelRb(pset);
}
if (gset) {
if (gset->restype == RTPICKS) acedSSFree(gset->resval.rlname);
acutRelRb(gset);
}
}
return flag_empty;
}
BOOL IsEmptyCmdLine()
{
CString Colon = _T(":");
CWnd *wTextCmdLine = acedGetAcadTextCmdLine();
if (wTextCmdLine) {
//---------------------------------------------------------------
// Find First Child Window of AcadTextCmdLine window is command
// line, which must have only text "Command:"
// (or localized version of this text)
//---------------------------------------------------------------
CWnd *wCommandLine = wTextCmdLine->GetWindow(GW_CHILD);
if (wCommandLine) {
// Is command line empty?
// Algorithm: Last nonblank symbol in command line must be ":" and
// there is not other ":" in command line!
CString sCommandLine;
wCommandLine->GetWindowText(sCommandLine);
// Delete all right blank symbols
sCommandLine.TrimRight();
// Is last nonblank symbol ":" ?
if (sCommandLine.Right(1) != Colon) return FALSE;
// Is where any other ":" in command line ?
if (sCommandLine.Find(Colon) != sCommandLine.GetLength()-1) return FALSE;
}
}
return TRUE;
}
//
// This function gets the Window messages
// *BEFORE* AutoCAD processes them.
//
BOOL filterProc(MSG *pMsg)
{
if (pMsg->message != WM_KEYDOWN) return FALSE; // Continue
if (GetKeyState(VK_SHIFT) & 0x8000) return FALSE; // Continue
if (pMsg->wParam == VK_DELETE) {
if (pMsg->hwnd == acedGetAcadDwgView()->GetSafeHwnd() ||
(GetParent(pMsg->hwnd) == acedGetAcadTextCmdLine()->GetSafeHwnd() &&
pMsg->hwnd != GetWindow(acedGetAcadTextCmdLine()->GetSafeHwnd(),GW_CHILD)) ||
(GetParent(pMsg->hwnd) == acedGetAcadDockCmdLine()->GetSafeHwnd() &&
pMsg->hwnd != GetWindow(acedGetAcadDockCmdLine()->GetSafeHwnd(),GW_CHILD))) {
//
// Step 1: Make sure that there is no active command
// and that there is nothing in the command line.
RB var;
if (acedGetVar(_T("CMDACTIVE"),&var) == RTNORM && var.resval.rint == 0) {
if (IsEmptyCmdLine() && !IsPickFirstEmpty()) {
acedPostCommand(_T("_ERASE "));
return TRUE; // Remove message
}
}
} // if
} // if
return FALSE; // Continue
}
Это работающий код.
По поводу второго вопроса: AcDbDatabase::currentSpaceId() возвращает AcDbObjectId для активного пространства (ACDB_MODEL_SPACE или что-то другое) - сравниваешь и узнаешь (упрощенно без обработки ошибок):
static bool IsModelSpace(void)
{
AcDbObjectId idCurrent = acdbCurDwg()->currentSpaceId();
AcDbBlockTablePointer pBT(acdbCurDwg(),AcDb::kForRead);
if (pBT.openStatus() == Acad::eOk) {
AcDbObjectId idModel;
if (pBT->getAt(ACDB_MODEL_SPACE,idModel) == Acad::eOk) {
if (idModel == idCurrent) return true;
}
}
return false;
}