Тема: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

В своей проге не могу найти ошибку - уже едет крыша...:(
Но может ошибка не у меня. Использую AcDbDoubleClickEdit. Открыл пример из ObjectARX 2002\samples\DblClick, откомпилировал, забросил в StartUp Suite. Создал чертеж в нем к примеру одна окружность, сохранил, вышел из акада. Загружаю акад, открываю сохраненный файл, делаю двойной клик по окружности (окружность меняет цвет), закрываю файл (не выхожу из акада) без сохранения. И тут самое интересное. Пытаюсь создать новый файл - фатальная ошибка. Что за хрень... Попробовал на другой машине - то же. Моя прога уже работает пол года и вот случайно обнаружил... Похоже что такая шняга только в акаде 2002. Что это - ошибка в библиотеке? Подскажите, плиз, может кто сталкивался...

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

> bkrug
Проверил - действительно глюк. Возможно поэтому этот класс и не хотели документировать в AutoCAD 2002, и в стандартной поставке ObjectARX SDK 2002 его нет.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Т. е. лучше обходить стороной этот класс? Остается beginDoubleClick из AcEditorReactor. Может кто сбросит пример кода (или ссылочку) реализации этой функции, ну к примеру для блока с именем "MyBlock" (не сочтите за наглость, самому копаться долго придется, нет времени). И еще попутно вопросик. Блок имеет аттрибуты. Мне надо чтобы только на "MyBlock" срабатывала моя прога, на остальные блоки с аттрибутами срабатывала стандартная комманда акада eattedit.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

> bkrug
Боюсь, что beginDoubleClick тебе не поможет. :( Причина в том, что после его обработки все равно вызывается стандартное окно редактирования объекта. Специально это только что проверил. Попробуй поработать с хуками. Пример есть в ObjectARX SDK в samples\editor\mfcsamps\pretranslate

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Пример хука. Надеюсь, что он тебе поможет:

BOOL FilterInstalled = FALSE;
BOOL DoubleClickFilter(MSG *pMsg)
{
  BOOL MyBlock = FALSE;
  // Обрабатываем только если DBLCLK и это окно DwgView
  if (pMsg->message == WM_LBUTTONDBLCLK && acedGetAcadDwgView()->GetSafeHwnd() == pMsg->hwnd) {
    acedDwgPoint dcsPt,ucsPt;  CPoint winPt(LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
    // Преобразуем координаты курсора в DCS
    acedCoordFromPixelToWorld(winPt, dcsPt);
    struct resbuf dcs, ucs;
    dcs.restype = RTSHORT; dcs.resval.rint = 2; // DCS
    ucs.restype = RTSHORT; ucs.resval.rint = 1; // UCS
    // Преобразуем координаты курсора в UCS для acedSSGet
    acedTrans(dcsPt, &dcs, &ucs, FALSE, ucsPt);
    ads_name ss,en;
    // Находим примитив под курсором:
    if (acedSSGet(":E", ucsPt, NULL, NULL, ss) == RTNORM) {
      // Нужно обязательно включить блокировку!!!
      if (acDocManager->lockDocument(curDoc()) == Acad::eOk) {
        AcDbObjectId eid; acedSSName(ss,0,en);
        if (acdbGetObjectId(eid,en) == Acad::eOk) {
          AcDbObjectPointer<AcDbBlockReference> pBlk(eid,AcDb::kForRead);
          if (pBlk.openStatus() == Acad::eOk) {
            AcDbObjectPointer<AcDbBlockTableRecord> pBtr(pBlk->blockTableRecord(),AcDb::kForRead);
            if (pBtr.openStatus() == Acad::eOk) {
              char *pName = NULL;
              if (pBtr->getName(pName) == Acad::eOk) {
                // Если указан блок и его имя "Myblock" - обработаем его
                // Если нет - пусть с ним мучается AutoCAD
                if (!stricmp(pName,"MyBlock")) {
                  pBtr->close();
                  acedAlert("Это наш блок - попробуем его редактировать.");
                  // Снимаем ручки
                  acedSSSetFirst(NULL,NULL);
                  // Увеличим масштаб блока в 1.2 раза
                  AcGeScale3d sc = pBlk->scaleFactors();
                  sc.setToProduct(sc,1.2);
                  Acad::ErrorStatus es;
                  if ((es = pBlk->upgradeOpen()) == Acad::eOk) {
                    pBlk->setScaleFactors(sc);
                    pBlk->downgradeOpen();
                  } else {
                    char buf[256];
                    sprintf(buf,"Ошибка при попытке открыть блок на запись: %s",acadErrorStatusText(es));
                    acedAlert(buf);
                  }
                  // Сообщаем AutoCAD, что ему уже не нужно
                  // обрабатывать DBLCLK
                  MyBlock = TRUE;
                }
                free(pName);
              }
            }
          }
          acDocManager->unlockDocument(curDoc());
        }
      }
    }
  }
  return MyBlock;
}

В InitApp:

FilterInstalled = acedRegisterFilterWinMsg(DoubleClickFilter);

В UnloadApp:

if (FilterInstalled) {
  acedRemoveFilterWinMsg(DoubleClickFilter);
}

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Спасибо, Александр Ривилис!
Попробовал я с хуками:) Но почему-то первый двойной клик не залетает в мою фунцию (только со второго раза. Т. е. двойной клик по тексту в только что открытом файле вызовет редактор текста и только второй д. клик попадет в "ловушку")

BOOL filterMouse(MSG *pMsg)
{
    if (pMsg->message == WM_LBUTTONDBLCLK)
    {
        return TRUE;
    }
    return FALSE;
}

Короче, то ли лыжы не едут, то ли я....:(
Да и опасно как-то использовать такие вещи, можно наворотить....
А может забить на акад 2002?
Еще раз спасибо...

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

OOPS, затормозил....
Ща изучу и опробую Ваш верхний код, спасибо:)

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

За код спасибо огромное (узнал много интересного)... Все работает... почти:)
Если открыть чертеж с проводника например (в кот. есть блок MyBlock) и первая операция - это двойной клик по MyBlock, то ловушка не срабатывает:(
Мелочь конечно, но все-таки...

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Я проверял это только AutoCAD 2006 - из проводника работает. Вообще-то эта программка должна работать (с небольшими изменениями) во всех версиях AutoCAD начиная с R14.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

К коду претензий нет никаких. Опробовал на акаде 2006 (правда OARX2004) - то же самое, первый двойной клик не попадает в хук. Может я чего-то не инициализирую?
По поводу AcDbDoubleClickEdit:
http://discussion.autodesk.com/thread.j … dID=420312
Граждане!!!! Пробовал ли кто-н. произвести операции, которые я описал в самом начале, на акаде 2002. Скажите, что это только у меня проблемы, и я от всех отстану;)))

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

> bkrug
Я же тебе подтвердил, что у меня работает аналогично. А на http://discussion.autodesk.com/thread.j … dID=420312 ты не указал, что нужно после даблклика закрыть чертеж не сохраняя его! Поэтому и не смогли воспоизвести ошибку. Баг связан именно с тем, что модификация произведена, а чертеж не сохранился. Я себе не ставил SP1 на AutoCAD 2002. Возможно в нем этот баг исправлен.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Ясно, я просто всю жизнь Немецкий учил, вот и видимо не смог донести точно...
А по поводу первого дблклика, не пробовали на акаде 2002, 2004? Может будет время....

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

> bkrug
Хочу уточнить. У тебя установка хука производится в InitApp? Проверь (поставь отладочную печать), что InitApp происходит до первого DblClk.
В AutoCAD 2002-2006 - все работает четко с первого раза. Проверял и из проводника (кроме 2002), настраивал открытие файла и по click, и по dblclk. В любом случае все в порядке.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Значит что-то у меня:(
Установка хука производится в InitApp. InitApp происходит до первого DblClk, проверил.
Буду искать...
Может приложение какое-н ловит первым дблклик и следовательно дальше не рассылается. Так как хук работает сразу после загрузки чертежа, именно первый двойной клик не доходит.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

Нашел! На свои же грабли....
Гружу свои проги (в основном LSP), и среди них есть dvb. Если закоментировать строки
(vl-vbaload ....), то все тип-топ. Что к чему?... Но это уже другая история:)
Не зря https://www.caduser.ru/forum/topic20709.html пишут. Присоединяюсь ко всем хорошим словам:) Спасибо....

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

> bkrug
И внутрь функции DoubleClickFilter при первом dblclk не попадаешь вообще?
Возможно проверка (acedGetAcadDwgView()->GetSafeHwnd() == pMsg->hwnd) - слишком жесткая...

Может приложение какое-н ловит первым дблклик и следовательно дальше не рассылается.

Очень может быть... Поотключай временно все лишние приложения.
Есть вариант воспользоваться стандартным Windows-ким хуком:

WNDPROC gWndProc;
LRESULT CALLBACK fWndProc(HWND hwnd, UINT uMsg,WPARAM wParam,LPARAM lParam)
{
  if(uMsg == WM_LBUTTONDBLCLK)
  {
    // Твоя обработка dblclk
    return true; //<<QUIT_DETECTED>>
  }
  // Send all the messages you receive to AutoCAD so they can be handled as normal
  return ::CallWindowProc(gWndProc,hwnd,uMsg,wParam,lParam);
}
void fAddWinHook()
{
  gWndProc = (WNDPROC)::SetWindowLongPtr(acedGetAcadDwgView()->GetSafeHwnd(),GWL_WNDPROC,(long)fWndProc);
}

Сразу предупреждаю, что не проверял, но по логике должно работать.

Re: AutoCAD 2002. Как пользоваться AcDbDoubleClickEdit?

bkrug пишет:

Если закоментировать строки
(vl-vbaload ....), то все тип-топ. Что к чему?... Но это уже другая история:)

Очень похоже, что при инициализации VBA происходит сброс очереди сообщений...

Не зря https://www.caduser.ru/forum/topic20709.html пишут. Присоединяюсь ко всем хорошим словам:)

Спасибо....
smile