logosres: and logosref: commands

Page 1 of 1 (16 items)
This post has 15 Replies | 1 Follower

Posts 10
Todd Hoatson | Forum Activity | Posted: Mon, Jul 2 2018 2:13 PM

I am working on a program / app that runs in parallel with Logos and I want to keep the two in sync.  So I would like to send commands to Logos to keep my resources which are indexed by scripture references focused on the right verse(s).  I know I can send a command like:

logosres:niv2011;ref=BibleNIV.Romans8.28

This will open Logos, open the NIV and scroll to Romans 8:28.

I have also seen:

logosref:Bible.Ro6.4

This will open Logos, open the ESV (I'm not sure why this was the one chosen), and then scroll to Romans 6:4.

What I would like to do is send a command for Logos to scroll in whatever scripture-ref-based resources are open, including commentaries.  In other words, to leave the resource unspecified and have Logos work with whatever is open (rather than opening the ESV).  Is there a way to do this?

Better yet, is there a way to tell Logos to scroll a Link Set (rather than a resource)?

Ordinarily, for resources you can click on the down-arrow next to the resource icon (upper-left corner of the open resource) and choose "Copy location as:  L4" in order to see the command syntax.  But this obviously only works for specific resources.  I know there are other possible commands (including logos4:), but they are undocumented...

Anyone know the answer to this?  Thanks!

Posts 23705
Forum MVP
Dave Hooton | Forum Activity | Replied: Mon, Jul 2 2018 3:33 PM

Todd Hoatson:
logosref:Bible.Ro6.4

This will open Logos, open the ESV (I'm not sure why this was the one chosen), and then scroll to Romans 6:4.

The command will open your preferred resource - set via Prioritize in your Library.

Todd Hoatson:
What I would like to do is send a command for Logos to scroll in whatever scripture-ref-based resources are open, including commentaries. 

If a Commentary is prioritized higher than a Bible, logosref will open that commentary. But that isn't a practical use of Prioritization. Use logosres to open a commentary, because you can't specify an Open resource nor a Link Set.

Todd Hoatson:
I know there are other possible commands (including logos4:), but they are undocumented...

See https://wiki.logos.com/Hyperlinks#The_Anatomy_of_a_Link for information on logos4, and other datatypes to use in logosref.

Dave
===

Windows & Android

Posts 7727
LogosEmployee

Todd Hoatson:

I am working on a program / app that runs in parallel with Logos and I want to keep the two in sync.  So I would like to send commands to Logos to keep my resources which are indexed by scripture references focused on the right verse(s).  I know I can send a command like:

What I would like to do is send a command for Logos to scroll in whatever scripture-ref-based resources are open, including commentaries.  In other words, to leave the resource unspecified and have Logos work with whatever is open (rather than opening the ESV).  Is there a way to do this?

You could accomplish this (on Windows) by using the COM API: https://wiki.logos.com/Logos_4_COM_API 

Your program could enumerate the open panels and send each one (that's currently opened to a Bible reference) a navigation request to your desired reference.

Posts 10
Todd Hoatson | Forum Activity | Replied: Tue, Jul 3 2018 2:33 PM

@Dave Hooton, thanks for your helpful response...

> ... you can't specify an Open resource nor a Link Set.

Rats!

Posts 10
Todd Hoatson | Forum Activity | Replied: Tue, Jul 3 2018 2:41 PM

Bradley Grainger:

You could accomplish this (on Windows) by using the COM API

I was afraid you'd say that...  Using the command(s) with ShellExecuteEx() in C++ is SO much easier than using COM.  It's like the difference between a heart catheterization and a heart transplant!  Smile  Even MS isn't promoting COM anymore.

I already created a little test program using the COM approach in C#, and that works kinda OK (Sometimes Logos responds, sometimes it doesn't).  But it's so much harder in C++, and that's the language used for the program I'm trying to modify...  Crying

Posts 10
Todd Hoatson | Forum Activity | Replied: Fri, Aug 3 2018 1:29 PM

To further elucidate the problem of using the Logos COM API in C++:

Logos classes and entry points for C# & C++ are completely different?!?  I used OLE View to Open LogosCOM.exe & Save As a header file.  Looking at this header file, it's definitely Logos stuff, but...

* there is no Launcher to start Logos (as I had used in my C# test program)
* there is no GetOpenPanels() to list the open Logos windows
  - there is GetWindows(), but what can I do with it???
* most functions return LPDISPATCH, which doesn't indicate what data is returned

What is the point of Logos providing an extensive (5000+ lines of code!) API if there is so little documentation for how to use it?  (I know about the Logos 4 COM API on the wiki.)  And how can it be so completely different between C# & C++?

Posts 7727
LogosEmployee

I wasn't able to successfully save as a header file with OLEView, but the TypeLib in LogosCOM.exe looks (to me) exactly like the Logos 4 COM API documented on the wiki. (I think it has to be, in order to marshal the COM interfaces between processes properly.)

Specifically, I do see a Launcher, I do see GetOpenPanels, I don't see GetWindows; I don't see any of the changes you describe.

Posts 10
Todd Hoatson | Forum Activity | Replied: Sat, Aug 4 2018 8:05 AM

Hi Brad, thanks for your response...

To get Logos COM object definitions into a header file, I followed these instructions (from a coworker):
- Run OLE View as Admin
- View COM Objects (aka. Type Libraries)
- Look for "Logos Bible Software 4 Type Library"
IF library not registered...
- select File->View Type Lib
- Navigate to %localappdata%\local\logos\system\
- Open LogosCOM.exe
- select File->Save As [header file]

But, as you say, the header file generated seems to be really wrong, somehow...

Can you comment how you got to TYPELIB Viewer?  And how do you bring these definitions into a C++ project in Visual Studio?

Thanks!
Todd

Posts 7727
LogosEmployee

Todd Hoatson:
Run OLE View as Admin

If I run as Admin, I can't view the type library (it hangs); if I don't run as admin, it doesn't hang, but saving as a header file fails.

(Possibly my installation of VS native tools is out-of-date; I haven't used these programs in probably 10 years.)

Todd Hoatson:
Can you comment how you got to TYPELIB Viewer? 

I used File > View Typelib, and selected the LogosCom.exe file.

Todd Hoatson:
And how do you bring these definitions into a C++ project in Visual Studio?

I believe you can use #import "file:C:\Path\To\LogosCom.exe" to automatically import the typelib (VS will generate LogosCom.tli and LogosCom.tlh files that have the extracted interfaces).

Posts 10
Todd Hoatson | Forum Activity | Replied: Fri, Aug 10 2018 12:39 PM

OK, here's the C++ code that I have so far:

Logos4Lib::ILogosLauncherPtr launcher;
CLSID clsLogosLauncher;
HRESULT success;

// if Logos is already running, return with current instance
if (m_pdispLogosApp != NULL)
    return TRUE;

/* Obtain the CLSID that identifies LOGOS launcher */
if (FAILED(success = CLSIDFromProgID(L"LogosBibleSoftware.Launcher", &clsLogosLauncher)))
{
  MessageBox(NULL, _T("Cannot obtain CLSID from ProgID"), _T("Failed"), MB_OK | MB_ICONSTOP);
  return FALSE;
}

// start a new copy of Logos Launcher, grab the IDispatch interface
if (FAILED(success = CoCreateInstance(clsLogosLauncher, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&launcher))))
{
  MessageBox(NULL, _T("Cannot start an instance of Logos for Automation."), _T("Failed"), MB_OK | MB_ICONSTOP);
  return FALSE;
}
else
{
  launcher->LaunchApplication("");
  m_pdispLogosApp = launcher->Application;
}

So far, so good.  This starts Logos.  Now I can move forward to use the application pointer to issue commands, just as I did with C#.  This code is not terribly complicated; I wish Logos / Faithlife would have provided a sample like this for us C++ users.  It was quite difficult finding information about how to set this up...

Posts 10
Todd Hoatson | Forum Activity | Replied: Sat, Aug 11 2018 7:41 PM

One other point I should mention for completeness (maybe this will end up on the Logos 4 COM API page someday?)...

the ILogosLauncherPtr is a smart pointer, so when the launcher variable goes away (i.e. its deconstructor is called, as would happen automatically when the variable goes out of scope), the smart pointer's usage counter is decremented, and when it gets to 0, the COM object is released.  So the code calls CoCreateInstance(), but there is no corresponding call to destroy that instance.  It's handled automatically (at least, that's what I've been told should happen).

Posts 10
Todd Hoatson | Forum Activity | Replied: Mon, Aug 13 2018 9:19 AM

NEW PROBLEM!

When there is a change in location in a Bible within Logos, my C# test program is notified via callback method.  The C# code for that looks like this:

private static ILogosPositionHandler m_positionHandler = new LibronixPositionHandler();

...

var launcher = new LogosLauncher();
launcher.LaunchApplication(string.Empty);
logosApplication = launcher.Application;
m_positionHandler.PositionChanged += OnPositionInLibronixChanged;

OnPositionInLibronixChanged is the name of a method in my program that my program asks Logos to call whenever there is a change in the biblical reference for a resource.

I believe this code is working.  But when I try to translate this to C++, I get a MAJOR PROBLEM!

When I search the include file which is automatically generated from the type library by the #import statement, I don't find any references to ILogosPositionHandler or LibronixPositionHandler().  In fact, I don't find any occurrences of either Position or Handler in the .tlh file.  Shouldn't the Logos COM API be the same, regardless of the language using it???

Posts 7727
LogosEmployee
Bradley Grainger (Faithlife) | Forum Activity | Replied: Tue, Aug 14 2018 10:06 AM

Todd Hoatson:
var launcher = new LogosLauncher();
launcher.LaunchApplication(string.Empty);
logosApplication = launcher.Application;
m_positionHandler.PositionChanged += OnPositionInLibronixChanged;

What is the type of m_positionHandler, and who defines the PositionChanged event? 

Todd Hoatson:
When I search the include file which is automatically generated from the type library by the #import statement, I don't find any references to ILogosPositionHandler or LibronixPositionHandler().

I've never heard of these types either, and they're not described at https://wiki.logos.com/Logos_4_COM_API. Where did you find them?

Posts 10
Todd Hoatson | Forum Activity | Replied: Tue, Aug 21 2018 8:31 AM

OK, sorry - the missing stuff was not from the Logos 4 COM API; it was from a sample program I was looking at.  So I tried recreating that in C++, referencing information that I found here:  https://docs.microsoft.com/en-us/cpp/cpp/event-handling-in-native-cpp

B
ut I'm still having lots of problems getting the callback stuff to work.  If I can figure it out, I'll post the answers here, for the benefit of others...

Posts 10
Todd Hoatson | Forum Activity | Replied: Tue, Aug 28 2018 9:33 AM

I now have the following in my code:

  Logos4Lib::ILogosLauncherPtr CLinkLogos::m_pLauncher = NULL;

  [event_receiver(native)]
  class CEventReceiver
  {
  public:
      void OnLogosPanelChanged(IDispatch * Panel, IDispatch * Hint)
      {
          printf_s("OnLogosPanelChanged was called.\n");
      }

      void hookEvent(Logos4Lib::ILogosApplicationEvents *pEventSource)
      {
          __hook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
                       &CEventReceiver::OnLogosPanelChanged);
      }

      void unhookEvent(Logos4Lib::ILogosApplicationEvents *pEventSource)
      {
          __unhook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
                           &CEventReceiver::OnLogosPanelChanged);
      }
  };

  ...

  // make sure we have a Logos Launcher object
  if (m_pLauncher == NULL)
  m_bHaveLogos = GetLogosLauncher();

  // if we have a Logos Launcher object, the COM object is operational
  if (m_pLauncher != NULL)
  {
      Logos4Lib::ILogosApplicationEvents eventSource;
      CEventReceiver eventReceiver;

      eventReceiver.hookEvent(&eventSource);
  }

I get the following error message when compiling:

"usage of ATL attributes is deprecated"
    with regard to:
        [event_receiver(native)]

" 'Logos4Lib::ILogosApplicationEvents::PanelChanged': could not resolve event
    note: There are no events:
    note: 'HRESULT Logos4Lib::ILogosApplicationEvents::PanelChanged(IDispatch *,IDispatch *)': is not an event"
    with regard to:
        __hook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
                     &CEventReceiver::OnLogosPanelChanged);

" 'Logos4Lib::ILogosApplicationEvents': cannot instantiate abstract class
    note: due to following members:
    note: 'HRESULT IUnknown::QueryInterface(const IID &,void **)': is abstract"
    with regard to:
        Logos4Lib::ILogosApplicationEvents eventSource;

Any suggestions?

Posts 7727
LogosEmployee
Bradley Grainger (Faithlife) | Forum Activity | Replied: Tue, Aug 28 2018 11:15 AM

Todd Hoatson:
Any suggestions?

Sorry, it's been probably 10 years since I did COM event handling in C++, and I remember very little of it. I never used these ATL helpers; IIRC we used IConnectionPointContainer::FindConnectionPoint and IConnectionPoint::Advise. Presumably these ATL attributes do the same thing under the hood, but maybe dropping down to the lower-level interfaces will help pinpoint the problem.

Page 1 of 1 (16 items) | RSS