05/28/2012

Add block reference to a tool palette

In the user interface you can select a block reference in the drawing and simply drag & drop it onto a tool palette. I would like to do the same programmatically: add a new item to the tool palette that references a given block and create a preview image for it.

Solution

You can not only drag & drop a block reference onto a tool palette, but you can also copy-paste it onto the tool palette. And this is what the following solution takes advantage of. We COPYCLIP the block reference and then call the Paste() function of the tool palette.

Here is the ObjectARX solution:

staticvoid BlockRefToToolPalette(void)

{

// select block reference

ads_name name;

ads_point pt;

if (acedEntSel(L"Select block reference", name, pt) != RTNORM)

return;

// get the tool palette where we want to add an item

CAcTcUiToolPaletteSet* ps = AcTcUiGetToolPaletteWindow();

CAcTcUiToolPalette* pal =

ps->FindPalette(L"Architectural", NULL, FALSE);

if (pal == NULL)

return;

// copyclip the block reference

if (acedCommand(

RTSTR, L"_COPYCLIP", RTENAME,

name, RTSTR, L"", RTNONE) != RTNORM)

return;

// paste the clipboard onto the palette

IDataObject* pdo;

if (SUCCEEDED(::OleGetClipboard(&pdo)))

{

if (pal->Paste(pdo, 0, NULL))

{

// success

}

}

}

Since the above ARX functions do not have corresponding .NET wrappers, we need to P/Invoke those functions. Note that the DllImport.EntryPoints are specific to AutoCAD 2010. In case of other AutoCAD versions you would need to use a tool like e.g. Dependency Walker (depends.exe) to check the correct entry point.

Comments

In the user interface you can select a block reference in the drawing and simply drag & drop it onto a tool palette. I would like to do the same programmatically: add a new item to the tool palette that references a given block and create a preview image for it.

Solution

You can not only drag & drop a block reference onto a tool palette, but you can also copy-paste it onto the tool palette. And this is what the following solution takes advantage of. We COPYCLIP the block reference and then call the Paste() function of the tool palette.

Here is the ObjectARX solution:

staticvoid BlockRefToToolPalette(void)

{

// select block reference

ads_name name;

ads_point pt;

if (acedEntSel(L"Select block reference", name, pt) != RTNORM)

return;

// get the tool palette where we want to add an item

CAcTcUiToolPaletteSet* ps = AcTcUiGetToolPaletteWindow();

CAcTcUiToolPalette* pal =

ps->FindPalette(L"Architectural", NULL, FALSE);

if (pal == NULL)

return;

// copyclip the block reference

if (acedCommand(

RTSTR, L"_COPYCLIP", RTENAME,

name, RTSTR, L"", RTNONE) != RTNORM)

return;

// paste the clipboard onto the palette

IDataObject* pdo;

if (SUCCEEDED(::OleGetClipboard(&pdo)))

{

if (pal->Paste(pdo, 0, NULL))

{

// success

}

}

}

Since the above ARX functions do not have corresponding .NET wrappers, we need to P/Invoke those functions. Note that the DllImport.EntryPoints are specific to AutoCAD 2010. In case of other AutoCAD versions you would need to use a tool like e.g. Dependency Walker (depends.exe) to check the correct entry point.