How to use 'ArborGVT' - Serg-Norseman/Arbor GitHub Wiki

How to use 'ArborGVT'

C++

C++ port of 'ArborGVT' provides its functionality through the 'arborgvt.dll' via IArborVisual COM interface.

Provided by the DLL IArborVisual is not a "pure" COM object. It's just an object that implements IUnknown and thus having ref-counting. But in general this is an "usual" C++ object.

'arborgvt.dll' exports single function: createArborVisual. Client code uses this exported function to create IArborVisual object.

Assuming client is written on C++ too:

ATL::CComPtr<IArborVisual> visual;
HRESULT hr = createArborVisual(&visual);

Then you call IArborVisual::createWindow method:

hr = visual->createWindow(hwnd, style, exStyle, createdWindow, WM_NOTIFY_DPICHANGED);

where:

  • hwnd is a handle to the parent or owner window of the window being created,
  • style is the style of the window being created,
  • exStyle is the extended window style of the window being created,
  • createdWindow is handle to an event that is set to signaled state after the new window got valid HWND,
  • WM_NOTIFY_DPICHANGED is a message identifier sent to the new window when parent window (hwnd) gets WM_DPICHANGED message.

IArborVisual::createWindow method creates new window asynchronously. That's why this method requires createdWindow event. Once the new window is ready (createdWindow was set to signaled state) you can retrieve its HWND with IArborVisual::getHWND method.

When you want to add new data to the graph you have two options: add two vertices and connecting edge with one call and add vertices and edges with dedicated methods.

To add vertices and edge at one time use IArborVisual::addEdge method:

HRESULT IArborVisual::addEdge(_In_ std::wstring&& tail, _In_ std::wstring&& head, _In_ float length);

tail and head is vertex names and length is length of directed connecting edge.

Or use the following dedicated methods to add vertices and edges:

HRESULT IArborVisual::addEdge(_In_ ARBOR vertex* tail, _In_ ARBOR vertex* head, _In_ const float length, _In_ const float stiffness, _In_ const bool directed, _In_ const D2D1_COLOR_F& color, _Outptr_result_maybenull_ ARBOR edge** e);
HRESULT IArborVisual::addEdge(_In_ ARBOR vertex* tail, _In_ ARBOR vertex* head, _In_ const float length, _In_ const bool directed, _In_ const D2D1_COLOR_F& color, _Outptr_result_maybenull_ ARBOR edge** e);
HRESULT IArborVisual::addVertex(_In_ std::wstring&& name, _In_ const D2D1_COLOR_F& bkgndColor, _In_ const D2D1_COLOR_F& textColor, _In_ float mass, _In_ bool fixed, _Outptr_result_maybenull_ ARBOR vertex** v);

For example:

using namespace std::string_literals;

ARBOR vertex* tail {};
ARBOR vertex* head {};
ARBOR edge* e {};
D2D1_COLOR_F bkgndColor = D2D1::ColorF {D2D1::ColorF::Red, 1.0f};
D2D1_COLOR_F textColor = D2D1::ColorF {D2D1::ColorF::White, 1.0f};
HRESULT hr = visual->addVertex(TEXT("'/' root"s), bkgndColor, textColor, 1.0f, false, &tail);
WAPI check_hr(hr);
bkgndColor = D2D1::ColorF {D2D1::ColorF::Green, 1.0f};
hr = visual->addVertex(TEXT("/dev/sda"s), bkgndColor, textColor, 1.0f, false, &head);
WAPI check_hr(hr);
hr = visual->addEdge(tail, head, 1.0f, true, bkgndColor, &e);
WAPI check_hr(hr);
...
hr = visual->addEdge(TEXT("/dev/sda"s), TEXT("srcsrv.dll"s), 1.0f);

You can find a full sample code in dtsample project.