Тема: Диалог "Диспечер типов линий"

Подскажите как вывести диалог "Диспечер типов линий".

Re: Диалог "Диспечер типов линий"

Есть такая недокументированная функция acedLinetypeDialog в AutoCAD 2004-2006:

bool __cdecl acedLinetypeDialog(AcDbObjectId, bool, char *&, AcDbObjectId &);

Она экспортируется из acad.exe и есть в acad.lib

Re: Диалог "Диспечер типов линий"

Забыл дать пояснения по параметрам. Это не 100%, но думаю что близко:

bool __cdecl acedLinetypeDialog(
   AcDbObjectId old_linetypeId,  // Id для текущего типа линии: acdbCurDwg()->celtype();
   bool IncludeByBlockByLayer,   // Можно ли выбирать тип линии "послою" или "поблоку"
   char *&new_linetypeName,      // Имя выбранного в диалоге типа линии
   AcDbObjectId &new_linetypeId  // Id для выбранного типа линии.
);

Думаю, что перед ее вызовом неплохо бы переключить ресурсы на AutoCAD.
P.S.:
Самое смешное, что обертку для использования этой функции в .NET дали, и она описана в Help'е как Autodesk.AutoCAD.Windows.LinetypeDialog, а C++-ой функции нет ни в Help'е, ни в *.h-файлах.

Re: Диалог "Диспечер типов линий"

> Александр Ривилис
Попробовал эту фичу:

    FARPROC func;
    HMODULE AcadModule = ::GetModuleHandle(NULL);
    func = ::GetProcAddress(AcadModule,"acedLinetypeDialog");

- результата никакого: GetProcAddress возвращает "0". Или я что-то не так делаю?

Re: Диалог "Диспечер типов линий"

> Debalance
1) Это функция не C, а C++ и поэтому если делать так, как ты, то:

func = ::GetProcAddress(AcadModule,"?acedLinetypeDialog@@YA_NVAcDbObjectId@@_NAAPADAAV1@@Z");

Да и func нужно описывать не так...
2) Но это все лишнее. Правильно так:

bool __cdecl acedLinetypeDialog(
 AcDbObjectId old_linetypeId,  // Id для текущего типа линии: acdbCurDwg()->celtype();
 bool IncludeByBlockByLayer,   // Можно ли выбирать тип линии "послою" или "поблоку"
 char *&new_linetypeName,      // Имя выбранного в диалоге типа линии
 AcDbObjectId &new_linetypeId  // Id для выбранного типа линии.
);
void GetLineType()
{
  AcDbObjectId new_linetypeId;
  char *new_linetypename = NULL;
  if (acedLinetypeDialog(acdbCurDwg()->celtype(),true,new_linetypename,new_linetypeId) && new_linetypename) {
    acutPrintf("\nВыбран тип линии: %s",new_linetypename);
    free(new_linetypename);
  } else {
    acutPrintf("\nТип линии не выбран!");
  }
}

Все, что нужно прилинкуется автоматически из acad.lib

Re: Диалог "Диспечер типов линий"

А так если тебе очень хочется воспользоваться GetProcAddress(...):

void GetLineType()
{
  typedef bool (__cdecl ACEDLINETYPEDIALOG)(AcDbObjectId,bool,char *&,AcDbObjectId &);
  ACEDLINETYPEDIALOG *func = NULL;
  HMODULE AcadModule = ::GetModuleHandle(NULL);
  func = (ACEDLINETYPEDIALOG *)::GetProcAddress(AcadModule,"?acedLinetypeDialog@@YA_NVAcDbObjectId@@_NAAPADAAV1@@Z");
  if (func) {
    AcDbObjectId new_linetypeId;
    char *new_linetypename = NULL;
    if (func(acdbCurDwg()->celtype(),true,new_linetypename,new_linetypeId) && new_linetypename) {
      acutPrintf("\nВыбран тип линии: %s",new_linetypename);
      free(new_linetypename);
    } else {
      acutPrintf("\nТип линии не выбран!");
    }
  }
}

Тоже работает. :)
P.S. Ошибка в описании ACEDLINETYPEDIALOG исправлена.

Re: Диалог "Диспечер типов линий"

> Александр Ривилис
Можете считать меня извращенцем но второй метод мне нравится больше:) Кстати, замечательно работает в Акаде2000-2002.
P.S:
Небольшая ниточность в объявлении нового типа функции: надо указать "&" после AcDbObjectId в последнем параметре...

Re: Диалог "Диспечер типов линий"

Debalance пишет:

Можете считать меня извращенцем...

Ну почему же. Если очень хочется, то можно и так. Хотя для меня есть такое правило - если функция присутствует в одном из .lib-файлов, то я описываю ее явно и не использую GetProcAddress(...). Если же ее там нет (а так в AutoCAD бывало), то приходится явно получать ее адрес с использованием GetProcAddress(...).

Небольшая ниточность в объявлении нового типа функции:

Твоя правда. Я удалял имена параметров функций и слегка переборщил.

Re: Диалог "Диспечер типов линий"

> Александр Ривилис
Продолжая тему недокументированных функций хотелось бы поинтересоваться у Вас, Александр, - существует ли какой-нибудь универсальный способ "вычленения" количества параметров и их типов в таких функциях. Ну предположим можно ли расшифровать "@@YA_NVAcDbObjectId@@_NAAPADAAV1@@Z" и имеет ли сия запись какой-либо разумный перевод?

Re: Диалог "Диспечер типов линий"

> Debalance
Да. Сия запись имеет разумный перевод. Для "перевода" можно воспользоваться UNDNAME.EXE из состава Visual Studio:

UNDNAME.EXE "?acedLinetypeDialog@@YA_NVAcDbObjectId@@_NAAPADAAV1@@Z"
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation 1981-2001. All rights reserved.
Undecoration of :- "?acedLinetypeDialog@@YA_NVAcDbObjectId@@_NAAPADAAV1@@Z"
is :- "bool __cdecl acedLinetypeDialog(class AcDbObjectId,bool,char * &,class AcDbObjectId &)"

Re: Диалог "Диспечер типов линий"

> Александр Ривилис
Спасибо, Александр!