Saturday, October 10, 2026

Handling links in the Blog Manager Program

Maybe reading the series of blogs about Prolog from last year gave me a sense of nostalgia, programming on Friday afternoons with CoPilot. This caused me to wonder if I could change the target of the links contained within the blogs: at the moment, clicking on a link will cause the chosen blog to be displayed by Internet Explorer, which is somewhat out of date. How could I get the blogs to be displayed in Chrome (or whatever the default browser is)?

CoPilot explained that IE is opened because the TWebBrowser component that I am using in the BPM is an abstraction of part of IE, so of course any link is going to be opened with this program. To change this, I would need to write a message handler that intercepts the link and invokes a different program. True to form with CoPilot, I then spent at least an hour trying to get the interceptor to work with a click on a link with no success. It turned out that CoPilot had given me the wrong message handler, but even when that was corrected, the interceptor still didn't work.

Eventually some rather arcane code was required to get the links to display in Chrome. At some stage in the process, I also realised that it would be good if links to other blog entries would be displayed within the BPM instead of invoking Chrome. This too took some time to make it work correctly; I originally thought that I could use the links on the statusbar1, but when I actually came to do this, I could see that the address and the statusbar text were not the same. I realised that a simple query would give me the data that I required, and a bit later I realised that I don't need the statusbar nor the code that loads it and catches clicks. So one part of the unit became more complicated and one part became simpler.

I'm showing the interceptor code as I don't know how much of the browser internals are documented.

procedure TShowBlogContent.webNewWindow2(Sender: TObject; var ppDisp: IDispatch; var Cancel: WordBool); var linkedblog: integer; Doc: IHTMLDocument2; Elem: IHTMLElement; URL, linkedname: string; begin Cancel:= True; // stop IE from opening a new window Doc:= web.Document as IHTMLDocument2; Elem:= Doc.activeElement; if Assigned(Elem) then URL:= Elem.getAttribute('href', 0); if URL <> '' then begin if pos ('https://nbnewman.blogspot.com', url) = 1 then begin qLinkedBlog.params[0].asinteger:= blog; qLinkedBlog.params[1].asstring:= url; qLinkedBlog.open; linkedblog:= qLinkedBlog.fields[0].asinteger; linkedname:= qLinkedBlog.fields[1].asstring; flag:= not qLinkedBlog.isempty; qLinkedBlog.close; if flag then begin TShowBlogContent.create (true, linkedblog, linkedname); exit end; end; ShellExecute(0, 'open', PChar(URL), nil, nil, SW_SHOWNORMAL);end; end; end;

I've discovered a little bug with the above code - some of the addresses start with https and some with http, without the 's'. The latter kind of link doesn't work, so I'll have to change the expression pos ('https://nbnewman.blogspot.com', url) to pos ('nbnewman.blogspot.com', url). 

Another caveat/bug is that the link has to include 'target="_blank"' for the NewWindow2 event to fire. New blogs have this in their links, old blogs don't. It's easier to add this tag to the blog sources than to try and capture clicks using a different method.

Internal links
[1] 1810



This day in blog history:

Blog #Date TitleTags
41310/10/2011Watching the weight / 2Diet, Acupuncture
76410/10/2014Continuing to watch the weightTV series, Health, Walking
98110/10/2016Pain whilst walkingWalking
108010/10/2017HersonissosHoliday, Greece
126310/10/2019CosmologyPersonal, Gateway, Non-fiction books
134510/10/2020Simple baked salmonCooking
201510/10/2025How to define the 'sister' relationship/predicate in Prolog?Programming, Prolog, CoPilot

No comments: