Skip to main content
Participant
February 27, 2026
Question

Programmatically access link information in C++ plugin

  • February 27, 2026
  • 1 reply
  • 26 views

Hello,

I would like to access the links in the link list in my C++ plugin.

 

I need the path to the linked file and the page number.

I came up with some code that works, but it seems a bit cumbersome to me and i am not sure if this is the right approach.

static void logAllLinks(const IDocument* const doc)
{
IDataBase* db = ::GetDataBase(doc);

LinkQuery query;
InterfacePtr<ILinkManager> linkMgr(db, db->GetRootUID(), UseDefaultIID());

InterfacePtr<IPageList> pages(doc, UseDefaultIID());

UIDList uids(db);

const int32 cnt = linkMgr->QueryLinks(query, kIDLinkClientID, uids);
for (int32 i = 0; i < cnt; ++i)
{
UIDRef linkRef(db, uids[i]);

InterfacePtr<ILink> link(linkRef, UseDefaultIID());

UID resUID = link->GetResource();
InterfacePtr<ILinkResource> linkResource(db, resUID, UseDefaultIID());


// get link name (path)
PMString linkName = linkResource->GetLongName(false);

// get modification date
IDTime modtime = linkResource->GetModTime();
WideString timeString;
bool success = modtime.DateToString(timeString, false);

// get frame
UID frameUID = link->GetObject();
UIDRef frameRef = UIDRef(db, frameUID);


InterfacePtr<IHierarchy> hierarchy(frameRef, UseDefaultIID());

// get parent
UID parentUID = hierarchy->GetParentUID();
UIDRef parentFrameRef = UIDRef(db, parentUID);

// get page
UID pageUID = Utils<ILayoutUtils>()->GetOwnerPageUID(hierarchy, kTrue);

int32 pageNum = pages->GetPageIndex(pageUID);
pageNum += 1; // 0 - based

AppGlobals::Instance().getLogger()->log("logAllLinks: Found link: [frame: %d] [parent frame: %d] [name: %s] [page: %d] [modified: %s]", Logger::E_LOG_LEVEL::ELL_DEBUG,
frameRef.GetUID().Get(), parentFrameRef.GetUID().Get(), Helper::stringWithPMString(linkName).c_str(), pageNum, Helper::stringWithPMString(timeString).c_str());
}
}

 

Is there an easier way to do this and are there any pitfalls I need to be aware of?

 

Thanks

    1 reply

    Community Expert
    February 27, 2026

    What part is bothering you. At first look it seems fine to me. You query the list and then use the link object to query other properties. You can read the SDK documentation and check out the SDK samples like Snippet Runner to see if there are other ways mentioned/implemented.

    -Manan
    Participant
    February 27, 2026

    Hi Manan,

    thanks for replying.

     

    The problem I have with the API is that there are 100 different ways to achieve the goal. For example

    InterfacePtr<ILinkResource> linkResource(linkManager->QueryResourceByUID(link->GetResource()));

    // vs

    InterfacePtr<ILinkResource> linkResource(db, link->GetResource(), UseDefaultIID());

    for me as a beginner it's pretty confusing and i never know when to use which.

     

    Thanks

    leo.r
    Community Expert
    Community Expert
    February 27, 2026

    as a beginner, use what works and don’t worry about 99 other ways. once you gain more experience, you can refine your code if needed.