Adding A Block Using ActiveX Client In C++
问题:How do I add a block to a drawing through an ActiveX Client in C++?
解答:
There are two interface objects that are mirrored to their ObjectARX
counterparts: IAcadBlocks to AcDbBlockTable and IAcadBlock to
AcDbBlockTableRecord. You then need to get to the interface objects and call the
appropriate methods.
These are the key steps to doing this:
1. Create a standalone MFC AppWiard EXE that is dialog-based.
2. Use the ClassWizard to import the following interfaces (from acad.tlb) and
declare them as private member variables of the dialog class:
IAcadApplication m_IApp;
IAcadDocument m_IDoc;
IAcadBlock m_IBlock;
IAcadBlocks m_IBlocks;
3. In the dialog's OnInitDialog(), assign a separate button handler, and get
the application and document object (a button with handler code shown below).
void CClientDlg::OnStart()
{
HRESULT hr = NOERROR;
CLSID clsid;
LPUNKNOWN pUnk = NULL;
LPDISPATCH pDisp = NULL;
BeginWaitCursor();
CoInitialize(NULL);
hr = ::CLSIDFromProgID(L"AutoCAD.Application", &clsid);
if (SUCCEEDED(hr))
{
if(::GetActiveObject(clsid, NULL, &pUnk) == S_OK)
{
VERIFY(pUnk->QueryInterface(IID_IDispatch,(LPVOID*)&pDisp) == S_OK);
m_IApp.AttachDispatch(pDisp);
pUnk->Release();
}
else
VERIFY(m_IApp.CreateDispatch(clsid) == TRUE);
m_IApp.SetVisible(TRUE);
pDisp = m_IApp.GetActiveDocument();
m_IDoc.AttachDispatch(pDisp);
}
else
AfxMessageBox("Acad.Application is not registered!");
//CoUninitialize(); // do this in the dialog's exit code
EndWaitCursor();
}
4. Create a button and its handler, then add the following code:
void CClientDlg::OnAddBlock()
{
VARIANT var;
double pt = {2, 2, 0};
getVariantFromDblArray(&var, pt);
const char blkName[] = "TEST";
LPDISPATCH p = m_IDoc.GetBlocks();
m_IBlocks.AttachDispatch(p);
p = m_IBlocks.Add(var, blkName);
m_IBlock.AttachDispatch(p);
}
HRESULT getVariantFromDblArray(VARIANT* pVal, const double pt)
{
pVal->vt = VT_ARRAY | VT_R8;
SAFEARRAYBOUND rgsaBound;
rgsaBound.lLbound = 0L;
rgsaBound.cElements = 3;
pVal->parray = SafeArrayCreate(VT_R8, 1, &rgsaBound);
if (! pVal->parray)
return E_OUTOFMEMORY;
HRESULT hr;
for (long i = 0; i < 3; i++)
if ((hr = SafeArrayPutElement(pVal->parray, &i,
(void*)&pt))!=S_OK)
return hr;
return S_OK;
}
页:
[1]