Тема: Компонент Delphi для просмотра DWG

Народ! Не знает ли кто-нибудь, есть ли в природе компонент Delphi для просмотра DWG-файлов, и , если есть, то где его взять? Или, в крайнем случае, ActiveX Component

Re: Компонент Delphi для просмотра DWG

Стоит такая же проблема. Знаю следующие компоненты
1. Autodesk Voloview (говорят. сильно тормозит)
2. InvisoX Free version  http://www.infograph.com/. Не хочет работать как ActiveX контрол (пишет "Unsupported format")
3. TwinView Activex http://www.cadwork.pl/ru/twinviewx.html
цена неизвестна.
Если у кого-нибудь есть еще информация о ActiveX компонентах для просмотра DWG файлов - поделитесь

Re: Компонент Delphi для просмотра DWG

Код для предпросмотра dwg на паскале:

procedure TFormBrowser.QuickView(filename: string);
// Процедура предпросмотра любого файла
var
  Ext: string;
  vs: string;
// Процедура просмотра ThumbNail. Весь секрет в ней!
  procedure setImgAsThumb;
    var
      s: TFileStream;
      clrData: pointer;
      hdrStart,
      hdrSz,
      bmpStart,
      bmpSz,
      wmfStart,
      wmfSz,
      hgt,
      wdt,
      ipos: dword;
      i: cardinal;
      sentV: array[1..16] of byte;
      mHead: packed record
        allSz : dword;
        imgCnt: byte;
      end;
      dHead: packed record
        code  : byte;
        dStart: dword;
        dSize : dword;
      end;
      intBmpHdr: BITMAPINFOHEADER;
      intBmp   : HBITMAP;
      intBmpInf: ^BITMAPINFO;
      dc       : HDC;
    const
      sent: array[1..16] of
byte=($1F,$25,$6D,$07,$D4,$36,$28,$28,
      $9D,$57,$CA,$3F,$9D,$44,$10,$2B
     );
  begin
    hdrStart:=0;
    hdrSz:=0;
    bmpStart:=0;
    bmpSz:=0;
    wmfStart:=0;
    wmfSz:=0;
    hgt:=0;
    wdt:=0;
    if AcadVer(filename, vs)>12
      then begin
// Открыли файл для чтения
        s:=TFileStream.Create(filename, fmOpenRead);
        s.Seek($0D, 0);
        s.Read(ipos, sizeof(ipos));
        s.Seek(ipos, 0);
        s.Read(sentV[1], 16);
        if CompareMem(@sentV, @sent, 16)
          then begin
            s.Read(mHead, sizeof(mHead));
            for i:=1 to mHead.imgCnt do begin
              s.Read(dHead, sizeof(dHead));
              case dHead.code of
                1 : begin
                      hdrStart:=dHead.dStart;
                      hdrSz:=dHead.dSize;
                    end;
                2 : begin
                      bmpStart:=dHead.dStart;
                      bmpSz:=dHead.dSize;
                    end;
                3 : begin
                      wmfStart:=dHead.dStart;
                      wmfSz:=dHead.dSize;
                    end;
              end;//case
            end;
            if (bmpStart<>0) and (bmpSz<>0)
              then begin
// Разыскали картинку
                s.Seek(bmpStart, 0);
                s.Read(intBmpHdr, sizeof(intBmpHdr));
                if intBmpHdr.biSizeImage>0
                  then begin
                    GetMem(intBmpInf,
                            (sizeof(BITMAPINFOHEADER)+
                              (intBmpHdr.biClrUsed*4)
                            )
                           );
                    intBmpInf^.bmiHeader:=intBmpHdr;
                    s.Read(intBmpInf^.bmiColors,
                                   (intBmpHdr.biClrUsed*4)
                          );
                    GetMem(clrData, intBmpHdr.biSizeImage);
                    s.Read(clrData^, intBmpHdr.biSizeImage);
                    dc:=CreateDC('DISPLAY', nil, nil, nil);
// Прочитали
                    intBmp:=CreateDIBitmap(dc,
                                           intBmpHdr,
                                           CBM_INIT,
                                           clrData,
                                           intBmpInf^,
                                           DIB_RGB_COLORS);
                    if intBmp<>0
                      then begin
// И нарисовали на форме
                        viewImage.Picture.Bitmap.Handle:=intBmp;
                        viewImage.Show;
                        viewScrollBoxImg.Show;
                      end;
                    FreeMem(intBmpInf);
                    FreeMem(clrData);
                    DeleteDC(dc);
                  end;
              end;
          end;
        s.Free;
      end;
  end;
// Основная процедура предпросмотра
begin
  if not (FileExists(filename))
    then begin
// Выводим вместо картинки сообщение "Просмотр невоможен"
      NoView;
      Exit;
    end;
  if AnsiCompareFileName(filename, FCurrentViewF)=0
    then exit;
  FCurrentViewF:=filename;
  viewScrollBoxImg.Visible:=false;
  viewText.Visible:=False;
  bShowDWF.Hide;
  if not cbQViewEnable.Checked
    then begin
      NoView;
      Exit;
    end;
  Ext:=copy(ExtractFileExt(filename), 2, length(filename));
  Ext:=AnsiUpperCase(Ext);
  if FTxtExts.IndexOf(Ext)>=0
    then begin
      viewText.Visible:=True;
      panView.Alignment:=taLeftJustify;
      viewText.FileName:=Filename;
      viewText.IsOpen:=true;
      if not viewText.IsOpen
        then NoView;
    end
// Просмотр DWG-файла
  else if Ext = 'DWG'
    then begin//dwg
      vs:='Рисунок Автокад';
// Просмотр картинки
      setImgAsThumb;
      panView.Caption:=vs;
      Ext:=ExistsDWFforDWG(filename);
      bShowDWF.Visible:=Ext<>'';
      FDWFFile:=Ext;
      panView.Alignment:=taCenter;
      Screen.Cursor:=crDefault;
    end //ext=dwg
// Просмотр обычных картинок
  else if ((Ext = 'BMP')
        or (Ext = 'ICO')
        or (Ext = 'WMF')
        or (Ext = 'JPG')
        or (Ext = 'JPEG')
        or (Ext = 'GIF')
        )
    then begin
      viewText.Visible:=False;
      bShowDWF.Hide;
      viewScrollBoxImg.Visible:=false;
      panView.Caption:='';
      panView.Alignment:=taLeftJustify;
      try
        Screen.Cursor:=crHourGlass;
        viewImage.Picture.LoadFromFile(Filename);
        viewScrollBoxImg.Visible:=true;
      except
        NoView;
      end;
      Screen.Cursor:=crDefault;
    end
    else if (Ext='DWF')
    then begin
      try
        FDWFFile:=Filename;
        bShowDWF.Show;
        panView.Caption:='';
      except
        NoView;
      end;
    end
    else NoView;
end;

Re: Компонент Delphi для просмотра DWG

> vektor
Хоть бы ссылались, откуда взяли. Это было написано мною лет 7 назад. В коде ссылки на  viewImage,        viewScrollBoxImg,  NoView, bShowDWF и т.п., о которых читающие эту страницу не знают.
Это только просмотр встроенной bmp. Для просмотра превьювов теперь у меня  есть компонент. Будет опубликован в книге.
Для просмотра DWG "компонентов" нет. И не будет. Потому, что это весьма сложное дело. Ранее формат DWG просматривали своими самоделками, пока он был прост. Теперь, с периодическими успехами, его ковыряет OpenDwg Alliance. У них есть кое-какие инструменты, но это не то, что можно воткнуть в Delphi как компонент или OCX.
Для настоящего просмотра надо покупать ObjectDBX, а его и продают-то не всем, а только бизнес-партнерам AutoDesk.

Re: Компонент Delphi для просмотра DWG

> ShaggyDoc
Откуда взял ей богу не помню (давно было, вполне возможно, что и 7 лет назад). ВАШИХ АВТОРСКИХ ПРАВ не оспариваю. Сам на Дельфях не пишу. Данный код переводил на C++ без проблем так же не зная, что есть

viewImage, viewScrollBoxImg, NoView, bShowDWF и т.п.

.
По поводу

Это только просмотр встроенной bmp

, так я выше тоже самое и указал, дабы не путать людей.

Для настоящего просмотра

и сам с успехом использую OpenDwg Viewkit. И в принципе не советую набивать свои проекты различного рода компонентами ActiveX.

Re: Компонент Delphi для просмотра DWG

ShaggyDoc пишет:

Хоть бы ссылались, откуда взяли.

Ежели задел за самолюбие, то прошу прощения.

Re: Компонент Delphi для просмотра DWG

> vektor
>Ежели задел за самолюбие, то прошу прощения
Самолюбие ни при чем.  Просто кусок кода, вырванный из контекста статьи, вызывает еще больше вопросов.
В отношении ViewKit вы правы. Но это не для "дельфинов"...  Просмотр DWG действительно лучше делать на C++. Хороших ActiveX для этого и не появится.

Re: Компонент Delphi для просмотра DWG

> ShaggyDoc
По поводу "хороших" ActiveX полностью согласен. Не появится, и не ждем.

Re: Компонент Delphi для просмотра DWG

Уважаемый Mo!
Заходите на www.cadsofttools.com,  там есть программа ABViewer позволяет просматривать и печатать dwg файлы версии до 2002 включительно, программа создана на основе VCL класса для отображения DWG файлов в Delphi, если Вам нужен подобный компонент пишите на info@cadsofttools.com, там же есть  есть классы, для работы с DXF и HPGL

Re: Компонент Delphi для просмотра DWG

А теперь и DWG 2004 / 2005 поддерживается.
www.cadsofttools.com

Re: Компонент Delphi для просмотра DWG

> ShaggyDoc
Подскажите, пожалуйста, адреса статей где можно посмотреть оригинал алгоритма с коментариями.

Re: Компонент Delphi для просмотра DWG

> Серега
Подробно описано в книге "САПР на базе AutoCAD - как это делается".
Компонент для Delphi с исходниками можно взять на www.kurganobl.ru/cad/
Это только просмотр растрового превьюва!
Для полного просмотра DWG лучше всего использовать продукты с www.cadsofttools.com. Но они платные.

Re: Компонент Delphi для просмотра DWG

unit DWGView;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;
type
  BITMAPINFO256 = record
    bmiHeader: BITMAPINFOHEADER;
    bmiColors: array[0..255] of RGBQUAD;
  end;
type
  TNoPreviewEvent = procedure(Sender: TOBject) of object;
  TFileErrorEvent = procedure(Sender: TOBject; DWGName: string) of object;
  TDWGView = class(TImage)
  private
    FDWGVersion: string;
    FDWGFile: string;
    FNoPreviewEvent: TNoPreviewEvent;
    FOnFileError: TFileErrorEvent;
    FImage: TImage;
    procedure SetDWGFile(const Value: string);
    procedure SetFImage(const Value: TImage);
    { Private declarations }
  protected
    procedure ReadDWG;
    constructor TDWGView;
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property Image: TImage read FImage write SetFImage;
    property DWGFile: string read FDWGFile write SetDWGFile;
    property DWGVersion: string read FDWGVersion;
    property OnNoPreview: TNoPreviewEvent read FNoPreviewEvent write FNoPreviewEvent;
    property OnFileError: TFileErrorEvent read FOnFileError write FOnFileError;
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('Voice', [TDWGView]);
end;
procedure TDWGView.ReadDWG;
var
  DWGF: TFileStream; // ?????Д??
  MemF: TMemoryStream; // ???????ц?й
  BMPF: TMemoryStream; // ?????Д??
  SentinelF: TMemoryStream; //?ЁХчЧЦ??  16ЧЦ??
  bif: BITMAPINFO256; // ?????Д???Е??
  bfh: BITMAPFILEHEADER; // ?????Д???Д???? 14ЧЦ??
  PosSentinel: LongInt; // ?ЁХчЧЦ????Ц?
  LenPreview: Integer; // ???ЁХчЧЦ??Ц???Х??ц?????????????Д????
  RasterPreview: ShortInt; // ???ч?????????????Д???ц??ЧЦ??Х???
  // 0  ???ё?????????? 1  ?ё??BMP????
    // 2  ?ё??WMF????    3  ?????ё??BMP??WMF????
  PosBMP: Integer; // ?????ДХ?????Ц?ё?????????????
  LenBMP: Integer; // ????????ё?????BITMAPFILEHEADER????ё?????????????
  IndexPreview: Integer;
  TypePreview: Shortint; // ????????
begin
  if Assigned(FOnFileError) then
    FOnFileError(Self, FDWGFile);
  DWGF := TFileStream.Create(FDWGFile, fmOpenRead);
  BMPF := TMemoryStream.Create;
  MemF := TMemoryStream.Create;
  SentinelF := TMemoryStream.Create;
  try
    SetLength(FDWGVersion, 6);
    DWGF.ReadBuffer(FDWGVersion[1], 6);
    DWGF.Position := 13; // ?Д??????13??Ц????ЁХчЧЦ??
    DWGF.Read(PosSentinel, 4);
    DWGF.Position := PosSentinel;
    SentinelF.CopyFrom(DWGF, 16); // ?????ЁХчЧЦ??
    DWGF.Read(LenPreview, 4); // ????
    DWGF.Read(RasterPreview, 1); // ????????????
    for IndexPreview := RasterPreview - 1 downto 0 do
    begin
      MemF.Position := 0;
      MemF.CopyFrom(DWGF, 9); // ???????ц?й 9ЧЦ??
      MemF.Position := 0;
      MemF.Read(TypePreview, 1); // TypePreview ????????
      case TypePreview of
        1: ; // ?????Д???цД???
        2:
          begin
            // BMP????,??DWG?Д??Ц??ё???ДBMP?????Й????????Ч?BMP?????Д
            // ???у?Д??????ё????????ё??BITMAPFILEHEADER????
            MemF.Position := 1;
            MemF.Read(PosBMP, 4); // 2,5
            MemF.Read(LenBMP, 4); // 6,9
            DWGF.Position := PosBMP;
            DWGF.ReadBuffer(bif, sizeof(bif));
            with bif do
            begin
              bmiColors[0].rgbBlue := 0;
              bmiColors[0].rgbGreen := 0;
              bmiColors[0].rgbRed := 0;
              bmiColors[225].rgbBlue := 255;
              bmiColors[225].rgbGreen := 255;
              bmiColors[225].rgbRed := 255;
            end;
            bfh.bfType := $4D42;
            bfh.bfSize := LenBMP + sizeof(bfh); //
            bfh.bfReserved1 := 0;
            bfh.bfReserved2 := 0;
            bfh.bfOffBits := 14 + $28 + 1024;
            BMPF.Position := 0;
            BMPF.Write(bfh, sizeof(bfh));
            BMPF.WriteBuffer(bif, sizeof(bif));
            BMPF.CopyFrom(DWGF, LenBMP - 1064);
            BMPF.Position := 0;
            Picture.Bitmap.LoadFromStream(BMPF);
          end;
        3: ; // WMF?Д??ё??ь?ёУ?22ЧЦ?????ДAldus?Д????
      end;
    end;
  finally
    SentinelF.Free;
    MemF.Free;
    DWGF.Free;
    BMPF.Free;
  end;
end;
procedure TDWGView.SetDWGFile(const Value: string);
begin
  FDWGFile := Value;
  ReadDWG;
end;
procedure TDWGView.SetFImage(const Value: TImage);
begin
  FImage := Value;
end;
constructor TDWGView.TDWGView;
begin
  //TODO: Add your source code here
  FDWGFile := '';
  FDWGVersion := '';
end;
end.

Взято с Russian Delphi Knowledge Base http://forum.vingrad.ru , но это не компонент, хотя по сути, можешь заюзать этот код с небольшими переделками для копирования DWG на канву,