Character offset of hyperlinks in fields

External developers... This forum's for you!

Character offset of hyperlinks in fields

Postby HairyHighlandCow » Sun Feb 25, 2018 5:54 am

If you click on a hyperlink object in a field you can trigger the 'clickfieldobject' message and get information about the link that was just clicked on. However, I needed to find out if there were any hyperlinks in the currently selected chunk in a field and there didn't seem to be a way to do that. This was necessary so the user could either edit an existing hyperlink in the selection or add a new one to it.

Having looked some of the IT toolbox samples, I put together an external that scans through the selection in a field for a hyperlink and returns the object's offset, ID number and URL text. It seems to work fine, but I just wanted to check I haven't done anything wrong querying the Waste records:

Code: Select all
void doMyFunction(void)
   SCErr            err;
   SInt32            selStart = 0, selEnd = 0, offset, selScan, ID;
   WEHandle         hWE = nil;
   WEObjectDescHandle   objectDesc = nil;
   WEObjectDesc      *desc;
   Str255            fldDesc;
   Boolean            objectFound = false;
   iota            tempiota;
   Handle            h = nil, urlH = nil;
   OSType            objType;
   Size            handleSize = 0;

   c2pstrcpy(fldDesc, *par->params[0]);
   selStart = max(0, atol(*par->params[1])-1);
   selEnd = max(0, atol(*par->params[2])-1);
   // Grab the 'display' WEHandle for the specified field
   c2pstrcpy(fldDesc, *par->params[0]);
   if((err = GetUIWEHandle(par, fldDesc, &hWE)) != isOK) {
      Fail("fetching display WERec for specified field");
   // Scan from start character to end character looking for an object
   selScan = selStart;
   while (objectFound == false && selScan <= selEnd){
      objectFound = (!(err = weGetObjectAtOffset(par, hWE, selScan, &objectDesc)));
   if (objectFound){
      if (!(err = weGetObjectID(par, objectDesc, &ID))){
         if (!objectDesc) {
            Fail("No such object");
         desc = *objectDesc;
         if ((desc->objectType != kTypeIota) && (desc->objectType != kTypeOldIota)) {
            Fail("Couldn't find a matching object");
         offset = desc->objectOffset;

         tempiota = **(iotahand)desc->objectDataHandle;
         PtrToHand(*, &h, GetHandleSize(;
         objType = getLinkType(&tempiota);

         if (objType == kTypeTextLink){
            iotaptr ip = &tempiota;
            if ((urlH = (Handle)getaltdata(ip->altdata, eHyperlinkURL))) {
               handleSize = GetHandleSize(urlH);

         char outputString[256 + handleSize];
         // tab-delimited output: <objectOffset> <objectID> [<objectURL>]
         sprintf(outputString, "%ld\t%ld\t", offset + 1, ID);
         if (handleSize > 0){
            // Select only the located hyperlink in the field
            (**hWE).selStart = offset;
            (**hWE).selEnd = offset + 1;
            // Add the URL to the end of the output string
            int sl = strlen(outputString);
            strcat(outputString, *urlH);
            outputString[sl + handleSize] = (char)0;
         TouchUIWEHandle(par, fldDesc, false);
         if (h != nil) DisposeHandle(h);
         Fail("couldn't get object info");   
      Fail("no object in that range");

One final note– it might be useful if getting 'the objects' of a field returned the character offset of each object as well as the Number, ID, Name, URL and LinkText information. This would avoid the need for the above external.


Externals, projects and software made with SC:
User avatar
Posts: 256
Joined: Sun Jul 06, 2008 1:45 pm
Location: London, UK

Re: Character offset of hyperlinks in fields

Postby codegreen » Fri Mar 09, 2018 7:03 pm

Hi Alec,

Sorry, I was lost in the code mines for a few weeks...

I recognize the stuff in that snippet, but couldn't find the headers needed to compile it. Basically the theory of operation is correct though (you could also walk the object list directly yourself checking if the offsets are within the desired range).

FWIW I've exposed some additional related WASTE routines in the 4.8 IT that should help with this kind of thing, and also added objects offsets as requested.

Posts: 1556
Joined: Mon Jul 14, 2008 11:03 pm

Return to Xcode and the Internals Toolbox

Who is online

Users browsing this forum: No registered users and 0 guests