chenhui1214 发表于 2014-7-16 13:05:00

外部图块重复使用程序(无法预览块图标)

问题描述:
在绘图时,经常要用到一些重复使用的块。我把这些经常要用到的图例做成了块,单独放在一个BlockLib.dwg文件中。想做一个类似于自带的insert对话框类似的应用程序,但是是从外部文件中打开块,并插入。我写了一下程序,但是不能预览块图标。请各位大侠帮忙看看,是哪里问题?
(PS:如果图块已经在文件中了,那是可以成功预览的。)
我的方法:
//新建一个临时的数据库,打开外部文件
AcDbDatabase *pExDb= new AcDbDatabase(Adesk::kFalse);
Acad::ErrorStatus es = pExDb->readDwgFile(_T("C:\\BlockLib.dwg"));
//利用块表迭代器查找块表记录
AcDbBlockTableIterator *pItr;
pBlockTable->newIterator (pItr);
pItr->getRecord(pRecord,AcDb::kForRead);
//利用wblock函数和inser函数添加块定义
AcDbDatabase* pOutputDb;
                        pExDb->wblock(pOutputDb,BlkRecordID);
                        AcDbObjectId blockId;
                        acdbHostApplicationServices()->workingDatabase()->insert
                              (blockId,pBlckName,pOutputDb);
代码(贴出对话框资源类class BlockViewdlg的代码)
//-----------------------------------------------------------------------------
//----- BlockViewdlg.h : Declaration of the BlockViewdlg
//-----------------------------------------------------------------------------
#pragma once
//-----------------------------------------------------------------------------
#include "acui.h"
#include "resource.h"
//-----------------------------------------------------------------------------
class BlockViewdlg : public CAcUiDialog {
      DECLARE_DYNAMIC (BlockViewdlg)
public:
      BlockViewdlg (CWnd *pParent =NULL, HINSTANCE hInstance =NULL) ;
      enum { IDD = IDD_DIA_VIEWER} ;
protected:
      virtual void DoDataExchange (CDataExchange *pDX) ;
      afx_msg LRESULT OnAcadKeepFocus (WPARAM, LPARAM) ;
      DECLARE_MESSAGE_MAP()
public:
      CStatic m_bmofBlkref;
      CAcUiPickButton m_close;
      CAcUiPickButton m_butinsert;
      CListBox m_listofblkID;
      virtual BOOL OnInitDialog();
      afx_msg void OnLbnSelchangeListBlockid();
      afx_msg void OnBnClickedButtonInsert();
      afx_msg void OnBnClickedButtonClose();
      afx_msg void OnClose();
      
public:
      CString m_strBlockID;
protected:
      /*HBITMAP BlockIconToBMP(const AcDbObjectId& BlkID,HDC hdc,CString selRcdName);*/
      HBITMAP BlockIconToBMP(const AcDbObjectId& BlkID, HDC hdc);
public:
      AcArray m_preIcon;
} ;
//-----------------------------------------------------------------------------
//----- BlockViewdlg.cpp : Implementation of BlockViewdlg
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "BlockViewdlg.h"
#include "dbsymtb.h"
#include "acutmem.h"
#include "resource.h"
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC (BlockViewdlg, CAcUiDialog)
BEGIN_MESSAGE_MAP(BlockViewdlg, CAcUiDialog)
      ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnAcadKeepFocus)
      ON_LBN_SELCHANGE(IDC_LIST_BLOCKID, &BlockViewdlg::OnLbnSelchangeListBlockid)
      ON_BN_CLICKED(IDC_BUTTON_INSERT, &BlockViewdlg::OnBnClickedButtonInsert)
      ON_BN_CLICKED(IDC_BUTTON_CLOSE, &BlockViewdlg::OnBnClickedButtonClose)
      ON_WM_CLOSE()
END_MESSAGE_MAP()
//-----------------------------------------------------------------------------
BlockViewdlg::BlockViewdlg (CWnd *pParent /*=NULL*/, HINSTANCE hInstance /*=NULL*/) : CAcUiDialog (BlockViewdlg::IDD, pParent, hInstance) {
}
//-----------------------------------------------------------------------------
void BlockViewdlg::DoDataExchange (CDataExchange *pDX) {
      CAcUiDialog::DoDataExchange (pDX) ;
      DDX_Control(pDX, IDC_BITMAP_VIEWER, m_bmofBlkref);
      DDX_Control(pDX, IDC_BUTTON_CLOSE, m_close);
      DDX_Control(pDX, IDC_BUTTON_INSERT, m_butinsert);
      DDX_Control(pDX, IDC_LIST_BLOCKID, m_listofblkID);
}
//-----------------------------------------------------------------------------
//----- Needed for modeless dialogs to keep focus.
//----- Return FALSE to not keep the focus, return TRUE to keep the focus
LRESULT BlockViewdlg::OnAcadKeepFocus (WPARAM, LPARAM) {
      return (TRUE) ;
}
BOOL BlockViewdlg::OnInitDialog()
{
      CAcUiDialog::OnInitDialog();
      // TODO:在此添加额外的初始化;
      /*AcDbDatabase extDatabase(Adesk::kFalse);
      AcDbDatabase *pExDb= new AcDbDatabase(Adesk::kFalse);//0,false is OK.
      //需要增加文件已经打开的异常处理;
      Acad::ErrorStatus es = pExDb->readDwgFile(_T("C:\\BlockLib.dwg"));
      if (es !=Acad::eOk)
      {
                delete pExDb;
                MessageBox(_T("找不到块图库!"), _T("ERROR"), MB_OK);
                this->SendMessage(WM_CLOSE);
                return FALSE;
      }
      //else
      //{
      //      //添加查找文件的程序;2014-7-12
      //}
      AcDbBlockTable *pBlockTable;
      AcDbBlockTableRecord *pRecord;
      pExDb->getBlockTable(pBlockTable,AcDb::kForRead);
      AcDbBlockTableIterator *pItr;
      pBlockTable->newIterator (pItr);
      for (pItr->start();!pItr->done();pItr->step())
      {
                pItr->getRecord(pRecord,AcDb::kForRead);
                ACHAR* pBlckName;
                pRecord->getName(pBlckName);
                CString strName(pBlckName);
                if (strName.Compare(ACDB_MODEL_SPACE)!=0&&
                        strName.Compare(ACDB_PAPER_SPACE)!=0&&
                        strName.Compare(_T("*Paper_Space0"))!=0)
                {                        
                        /*acedCommand(RTSTR,"BLOCKICON",RTSTR,pBlckName,RTNONE);*/
                        m_listofblkID.AddString(strName);
                        AcDbObjectId BlkRecordID;
                        pBlockTable->getAt(pBlckName,BlkRecordID);
                        AcDbDatabase* pOutputDb;
                        pExDb->wblock(pOutputDb,BlkRecordID);
                        AcDbObjectId blockId;
                        acdbHostApplicationServices()->workingDatabase()->insert
                              (blockId,pBlckName,pOutputDb);
                        AcDbBlockTableRecord *pBlkTblRcd=NULL;
                        //AcArray icon; //UInt8:8位无符号整数;
                        /*PreviewIcon icon;*/
                        Acad::ErrorStatus es = acdbOpenObject(pBlkTblRcd,blockId,AcDb::kForRead);
                        if (acedCommand(RTSTR,"_BLOCKICON",RTSTR,strName,0)!=RTNORM)
                        {
                              AfxMessageBox(_T("无法打开!"));
                              /*::SendMessage(WM_CLOSE);*/
                              return FALSE;
                        }
                        
                        if(!pBlkTblRcd->hasPreviewIcon())
                        {      
                              /*acedCommand(RTSTR,"BLOCKICON",RTSTR,selRcdName,RTNONE);*/
                              pBlkTblRcd->close();
                              return FALSE;
                        }
                }      
               
                acutDelString(pBlckName);
                pRecord->close();
      }
      delete pItr;
      pBlockTable->close();
      delete pExDb;
      return TRUE;// return TRUE unless you set the focus to a control
      // 异常: OCX 属性页应返回 FALSE
}
void BlockViewdlg::OnLbnSelchangeListBlockid()
{
      // TODO: 在此添加控件通知处理程序代码
      // 图形预览;
      CPaintDC dc(this);
      int icursel = m_listofblkID.GetCurSel();
      m_listofblkID.GetText(icursel,m_strBlockID);
      AcDbBlockTable *pBlockTable;
      acdbHostApplicationServices()->workingDatabase()
                ->getBlockTable(pBlockTable,AcDb::kForRead);
      AcDbObjectId blkId;
      pBlockTable->getAt(m_strBlockID,blkId);      
      HBITMAP hBitmap=BlockIconToBMP(blkId,dc.GetSafeHdc());
      /*AcDbBlockTableRecord *pBlkRec;
    pBlockTable->getAt(m_strBlockID,pBlkRec);
      HBITMAP hBitmap=BlockIconToBMP(pBlkRec,dc.GetSafeHdc());      */
      m_bmofBlkref.SetBitmap(hBitmap);
      pBlockTable->close();
}
void BlockViewdlg::OnBnClickedButtonInsert()
{
      // TODO: 在此添加控件通知处理程序代码
}
void BlockViewdlg::OnBnClickedButtonClose()
{
      // TODO: 在此添加控件通知处理程序代码
}
void BlockViewdlg::OnClose()
{
      // TODO: 在此添加消息处理程序代码和/或调用默认值;
      CAcUiDialog::OnClose();
}
//获得指定的块表记录的预览图像,输入参数:块表记录的ID,设备描述表句柄;
//HBITMAP BlockIconToBMP(const AcDbObjectId& BlkID,HDC hdc,CString selRcdName)
//{
//      AcDbBlockTableRecord *pBlkTblRcd=NULL;
//      AcArray icon;
//      Acad::ErrorStatus es = acdbOpenObject(pBlkTblRcd,BlkID,AcDb::kForRead);
//      if (Acad::eOk != es)
//      {
//                AfxMessageBox(_T("无法打开!"));
//                /*::SendMessage(WM_CLOSE);*/
//                return FALSE;
//      }
//      if(!pBlkTblRcd->hasPreviewIcon())
//      {      
//                acedCommand(RTSTR,"BLOCKICON",RTSTR,selRcdName,0);
//      }
//      pBlkTblRcd->getPreviewIcon(icon);
//      pBlkTblRcd->close();
//      BITMAPINFOHEADER * ih = (BITMAPINFOHEADER*)(icon.asArrayPtr());    //位图信息头;
//      /*memcpy(&ih,icon.asArrayPtr(),sizeof(ih));*/
//      size_t memsize=sizeof(BITMAPINFOHEADER)+((1 icon; //UInt8:8位无符号整数;
      /*PreviewIcon icon;*/
      Acad::ErrorStatus es = acdbOpenObject(pBlkTblRcd,BlkID,AcDb::kForRead);
      if (Acad::eOk != es)
      {
                AfxMessageBox(_T("无法打开!"));
                /*::SendMessage(WM_CLOSE);*/
                return FALSE;
      }
      if(!pBlkTblRcd->hasPreviewIcon())
      {      
                /*acedCommand(RTSTR,"BLOCKICON",RTSTR,selRcdName,RTNONE);*/
                pBlkTblRcd->close();
                return FALSE;
      }
      es = pBlkTblRcd->getPreviewIcon(icon);
      if (Acad::eOk != es)
      {
                AfxMessageBox(_T("无法打开!"));
                /*::SendMessage(WM_CLOSE);*/
                return FALSE;
      }
      pBlkTblRcd->close();
      BITMAPINFOHEADER ih ;    //位图信息头;
      memcpy(&ih,icon.asArrayPtr(),sizeof(ih));
      size_t memsize=sizeof(BITMAPINFOHEADER)+((1
该贴已经同步到 **** Hidden Message *****

chenhui1214 发表于 2014-7-16 13:06:00

不能在对话框中预览块的图标,但是在设计中心中能看到块定义图标。感觉是wblock和insert的问题。请各位大侠出手相救啊!

风树 发表于 2014-7-17 19:42:00

帮顶,有结果了吗,是不是现实范围的问题

chenhui1214 发表于 2014-7-18 13:13:00


还没有哦。你也有类似的问题?

zdqwy19 发表于 2014-7-18 21:54:00


放一个源代码多好,也好调试。

风树 发表于 2014-7-18 22:05:00


没试过从啊
猜的,
没有工具在手,暂时无能为力,
密切关注。
页: [1]
查看完整版本: 外部图块重复使用程序(无法预览块图标)