BIM Coordinator Program (INT) April 22, 2024

Find the next step in your career as a Graphisoft Certified BIM Coordinator!

Archicad C++ API
About Archicad add-on development using the C++ API.
SOLVED!

Copy the GUID/s of the current selection(single or multiple objects) to Clipboard

SajW
Participant
Can someone help me to write the code to Copy the GUID/s of the current selection(single or multiple objects) to Clipboard.

So far I have used the Database_Control Example without any success.
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
#include "ClipBoard.hpp"


static GS::Array<API_Guid>	GetSelectedElements ()
{
	GSErrCode            err;
	API_SelectionInfo    selectionInfo;
	API_Neig             **selNeigs;

	err = ACAPI_Selection_Get (&selectionInfo, &selNeigs, false);
	BMKillHandle ((GSHandle *)&selectionInfo.marquee.coords);
	if (err != NoError || selectionInfo.typeID == API_SelEmpty) {
		BMKillHandle ((GSHandle *)&selNeigs);
		return GS::Array<API_Guid>();
	}

	const UInt32 nSel = BMGetHandleSize ((GSHandle)selNeigs) / sizeof (API_Neig);

	GS::Array<API_Guid> guidArray;
	for (UInt32 i = 0; i < nSel; ++i) {
		guidArray.Push ((*selNeigs).guid);
	}

	BMKillHandle ((GSHandle *)&selNeigs);

	return guidArray;
}


static void CopyGUIDsOfCurrentSelectionToClipboard ()
{
	GS::UniString string;

	const GS::Array<API_Guid>	guidsOfCurrentSelection = GetSelectedElements ();
	for (UIndex ii = 0; ii < guidsOfCurrentSelection.GetSize (); ++ii) {
		string += APIGuidToString (guidsOfCurrentSelection[ii]) + '\n';
	}

	Clipboard::GetInstance ().SetUniString (Clipboard::uniTextTypeId, string);
}

 

Simply call CopyGUIDsOfCurrentSelectionToClipboard function to use.
You're welcome

UPDATE: I modified the code, now it's platform independent, works both on Windows and macOS platforms.

View solution in original post

6 REPLIES 6
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
#include "ClipBoard.hpp"


static GS::Array<API_Guid>	GetSelectedElements ()
{
	GSErrCode            err;
	API_SelectionInfo    selectionInfo;
	API_Neig             **selNeigs;

	err = ACAPI_Selection_Get (&selectionInfo, &selNeigs, false);
	BMKillHandle ((GSHandle *)&selectionInfo.marquee.coords);
	if (err != NoError || selectionInfo.typeID == API_SelEmpty) {
		BMKillHandle ((GSHandle *)&selNeigs);
		return GS::Array<API_Guid>();
	}

	const UInt32 nSel = BMGetHandleSize ((GSHandle)selNeigs) / sizeof (API_Neig);

	GS::Array<API_Guid> guidArray;
	for (UInt32 i = 0; i < nSel; ++i) {
		guidArray.Push ((*selNeigs).guid);
	}

	BMKillHandle ((GSHandle *)&selNeigs);

	return guidArray;
}


static void CopyGUIDsOfCurrentSelectionToClipboard ()
{
	GS::UniString string;

	const GS::Array<API_Guid>	guidsOfCurrentSelection = GetSelectedElements ();
	for (UIndex ii = 0; ii < guidsOfCurrentSelection.GetSize (); ++ii) {
		string += APIGuidToString (guidsOfCurrentSelection[ii]) + '\n';
	}

	Clipboard::GetInstance ().SetUniString (Clipboard::uniTextTypeId, string);
}

 

Simply call CopyGUIDsOfCurrentSelectionToClipboard function to use.
You're welcome

UPDATE: I modified the code, now it's platform independent, works both on Windows and macOS platforms.

SajW
Participant
Severity Code Description Project File Line Suppression State
Error (active) E1696 cannot open source file "ClipBoard.hpp"

Cannot solve the error associated with the #Include. Do you have any suggestion?
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
You're right, sorry, ClipBoard.hpp is not part of the public API Development Kit.

Which version of ARCHICAD are you using?

If you use ARCHICAD 22, then feel free to copy ClipBoard.hpp from this zip file into the Support\Modules\GSUtils folder inside the Development Kit.
SajW
Participant
static void CopyGUIDsOfCurrentSelectionToClipboard()
{
	GS::UniString string;

	const GS::Array<API_Guid>	guidsOfCurrentSelection = GetSelectedElements();
	for (UIndex ii = 0; ii < guidsOfCurrentSelection.GetSize(); ++ii) {
		string += APIGuidToString(guidsOfCurrentSelection[ii]) + '\n';
	}

	Clipboard::GetInstance().Empty();
	Clipboard::GetInstance().SetUniString(Clipboard::uniTextTypeId, string);
}

 

It works.
I had to call Empty() as well.

-

Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni

Hi Guys,

 

Let me inform you that clipboard handling is supported by C++ API from version 25.

The DGClipboard.hpp is part of the development kit (Support\Modules\DGLib). Using the DG::Clipboard singleton instance you can get or set the content of the clipboard easily.

 

Please note that the code I previously posted at this topic is outdated (worked for previous versions).

Here is the updated example code:

#include "APIEnvir.h"
#include "ACAPinc.h"
#include "APICommon.h"

#include "DGClipboard.hpp"


static GS::Array<API_Guid>	GetSelectedElements ()
{
	API_SelectionInfo	selectionInfo = {};
	GS::Array<API_Neig>	selNeigs;

	ACAPI_Selection_Get (&selectionInfo, &selNeigs, false);
	BMKillHandle ((GSHandle*)&selectionInfo.marquee.coords);

	return selNeigs.Transform<API_Guid> ([](const API_Neig& neig) { return neig.guid; });
}


static void CopyGUIDsOfSelectedElementsToClipboard ()
{
	GS::UniString string;

	const GS::Array<API_Guid>	guidsOfCurrentSelection = GetSelectedElements ();
	for (const API_Guid& guid : guidsOfCurrentSelection) {
		string += APIGuidToString (guid) + '\n';
	}

	DG::Clipboard::GetInstance ().Clear ();
	DG::Clipboard::GetInstance ().SetUniString (DG::Clipboard::uniTextTypeId, string);
}


static GSErrCode	SelectElementsFromClipboard ()
{
	GS::UniString clipboardString;
	DG::Clipboard::GetInstance ().GetUniString (DG::Clipboard::uniTextTypeId, clipboardString);

	GS::Array<GS::UniString> guidStrings;
	clipboardString.Split ("\n", GS::UniString::SkipEmptyParts, &guidStrings);

	const USize count = guidStrings.GetSize ();
	GS::Array<API_Neig> neigs = guidStrings.Transform<API_Neig> ([] (const GS::UniString & string) {
		return API_Neig (APIGuidFromString (string.ToCStr ().Get ()));
	});

	return ACAPI_Element_Select (neigs, true);
}
Learn and get certified!