Multiple control instances - enable event listening per instance  SOLVED

PDF-XChange Editor SDK for Developers

Moderators: TrackerSupp-Daniel, Tracker Support, Paul - Tracker Supp, Vasyl-Tracker Dev Team, Chris - Tracker Supp, Sean - Tracker, Ivan - Tracker Software, Tracker Supp-Stefan

Forum rules
DO NOT post your license/serial key, or your activation code - these forums, and all posts within, are public and we will be forced to immediately deactivate your license.

When experiencing some errors, use the IAUX_Inst::FormatHRESULT method to see their description and include it in your post along with the error code.
Post Reply
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Multiple control instances - enable event listening per instance

Post by zarkogajic »

Hi devs,

I'm trying to get my head around how to go with multiple ActiveX control instances...

I need to have multiple editor (IPXV_Control) instances in my app. My idea was to somehow handle all I have to handle in one location.

I've figured out how to manually create the IPXV_Ins: viewtopic.php?f=66&t=33169

Now, say I have formA hosting an instance of IPXV_Control (ctlrA) and formB hosting another instance of IPXV_Control (ctrlB). To make it more real-world I will actually have multiple instances of both formA and formB,

Next, I do EnableEventListening for ctrlA (+ handling the OnEvent for some events).

If I create formB (while formA is alive), load a document in cltrB -> ctrlA's OnEvent handler gets called!

If I also do EnableEventListening (for the same nEventID) for ctrlB - both OnEvent's will fire for ctrlA and ctrlB.

Not what I want.

For start, I need each control to only react on those events I enabled listening for a particular control.

Or, if both ctrlA and ctrlB handle the same nEventID (example. e.document.initialized) - when it happens I would need it to be (raised for) handled only by the control for which the event happened.

Ideally, I would like to EnableEventListening somehow for IPXV_Inst and then I would assign OnEvent handling method to ctrlA and ctrlB when needed. Then I would somehow need to know which control (ctrlA or ctrlB) raised the event.


p.s.
I know EnableEventListening works on the singleton instance of IPXV_Control - so I understand what's happening. I need a way around it :)



-žarko
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

Whilst the IPXV_Inst is a singleton, the IPXV_MainView's have their own IUIX_Obj. You can get the IPXV_MainFrame by index from the IPXV_Inst, then from it you can get the MainView by using the View property. Then you can get the MainView's object pointer.

Then, when you get the e.document.initialized event, you can get the IPXV_Document from the pFrom pointer. Then, you can get it's active IPXV_DocumentView, from which you can obtain the IUIX_Obj and get to the main view's object by Parent relations.

We'll see whether we can do something to optimize this logic for easier usage.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Alex,

Uh ... I've tried, no luck, so must be doing something wrong:

I get the ActiveView (IPXV_DocumentView) from doc (IPXV_Document(pFrom))

Then I iterate over Inst.MainFrm[].View (IPXV_MainView)

Are you saying that ActiveView.Obj is IPXV_MainView (tried and I think it is not) and I should compare those two?

Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

When you get the IPXV_DocumentView's IUIX_Obj, you should recursively get the parent of the object until you have found an IUIX_Obj with an ID of "mainView". Then cast it to the IPXV_MainView and there you have it.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Alex,

This will not work for e.document.initialized event as ActiveView for IPXV_Document(pFrom) is null - so cannot get in what control the document is being initialized.

For e.document.activated I can get the ActiveView from doc.

However, going up the parent does find the IPXV_MainView but this is neither of the View I have from Inst.MainFrm[].View (so "if mf.View = docMV" then never happens)

Code:

Code: Select all

    if (nEventID = EventID[e_document_activated]) then
    begin
      mainViewID := Inst.Str2ID('mainView', false);
      doc := IPXV_Document(pFrom);
      obj := doc.ActiveView.Obj;
      while Assigned(obj) AND (obj.ID <> mainViewID) do
        obj := obj.Parent;

      docMV := IPXV_MainView(obj);

      for frmCnt := 0 to -1 + Inst.MainFrmCount do
      begin
        mf := Inst.MainFrm[frmCnt];
        if mf.View = docMV then //<- never happens
        begin
          pEvent.Handled := true;
          Break;
        end;
      end;
    end;

-žarko
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Alex,

Ok, since you answered the other topic, I figured I need to do:

Code: Select all

docMV := IPXV_MainView(obj.Impl);
Then it works!

Still, this is open:
This will not work for e.document.initialized event as ActiveView for IPXV_Document(pFrom) is null - so cannot get in what control the document is being initialized.


Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

Yup, sadly no Document View in the e.document.initialized event yet - thus you cannot get to the parent here :(
Let us see what our lead devs say about this problem - probably we can resolve this issue somehow.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
User avatar
Vasyl-Tracker Dev Team
Site Admin
Posts: 2352
Joined: Thu Jun 30, 2005 4:11 pm
Location: Canada

Re: Multiple control instances - enable event listening per instance

Post by Vasyl-Tracker Dev Team »

Hi guys.

Here is working solution for "how to get proper MainView object when I have just IPXV_DocumentView | IPXV_PagesView | IPXV_BookmarksView | ... IPXV_Document | IPXC_Document | IPXC_Annotation | ..." question:

Code: Select all

///////////////////////////////////////////
// from document views:
///////////////////////////////////////////

mainView = Inst.GetMainViewFromUIObj(docView.DocView.Obj);
mainView = Inst.GetMainViewFromUIObj(pagesView.DocView.Obj);
mainView = Inst.GetMainViewFromUIObj(bookmarksView.DocView.Obj);
mainView = Inst.GetMainViewFromUIObj(pageThumbsView.DocView.Obj);
....

///////////////////////////////////////////
// from document:
///////////////////////////////////////////

IPXV_Document doc;
mainView = Inst.GetMainViewFromUIObj(doc.ActiveView.Obj);

///////////////////////////////////////////
// from core-document:
///////////////////////////////////////////

IPXC_Document coreDoc;
IPXV_Document doc = Inst.FindDocFromCoreDoc(coreDoc);
mainView = Inst.GetMainViewFromUIObj(doc.ActiveView.Obj);

///////////////////////////////////////////
// from core-objects:
///////////////////////////////////////////

IPXC_Annotation annot;
IPXC_Document coreDoc = annot.Page.Document;
IPXV_Document doc = Inst.FindDocFromCoreDoc(coreDoc);
mainView = Inst.GetMainViewFromUIObj(doc.ActiveView.Obj);

...

IPXC_Bookmark bkm;
IPXC_Document coreDoc = bkm.Document;
IPXV_Document doc = Inst.FindDocFromCoreDoc(coreDoc);
mainView = Inst.GetMainViewFromUIObj(doc.ActiveView.Obj);
HTH.
Vasyl Yaremyn
Tracker Software Products
Project Developer

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Hi Vasyl,

Great! Thanks.

Btw, im most cases above we need ActiveView - this is not accessible in e.document.initialized event (as per above posts).



Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

Well, that event can't be distinguished as there is no physical document view yet - there are other document events that come after it - you can use them for the needed operations.
Also, if you want fully distributed control over the Controls - use multi process environment - there you can have different IPXV_Inst pointers and everything will work smoothly.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Hi,

Ok, here's what (hopefully [read: so far] works):

I'm presuming that e.document.initialized can only happen in the ActiveMainFrm, so in that event we do not need the ActiveView (which at that moment is not assigned to doc), but we can use the IPXV_MainFrame of the Sender parameter (which is actually the PXV_Control that raised the event) and compare those two frames!

-žarko
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Sasha - Tracker Dev Team wrote: Wed Sep 25, 2019 11:54 am Whilst the IPXV_Inst is a singleton, the IPXV_MainView's have their own IUIX_Obj. You can get the IPXV_MainFrame by index from the IPXV_Inst, then from it you can get the MainView by using the View property. Then you can get the MainView's object pointer.
Hi Alex,

One more question here: why do you suggest to compare IPXV_MainView, why not just go level up to IPXV_MainFrame ?

Each instance of PXV_Control has its own Frame property of IPXV_MainFrame type, correct?

If I have an IPXV_Document I can get its Frame by Inst.GetMainViewFromUIObj(doc.ActiveView.Obj).Frame.

There's actually no need to iterate over Inst.MainFrm - just compare PXV_Control.Frame with IPXV_Document's Frame.

If they are the same - the document is withing that instance (frame) of PXV_Control.

Correct?

I see no reason to go down to View's (IPXV_MainView) for document and each IPXV_MainFrame.

p.s.
Do not answer "ok, if that works for you" :)

zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Sasha - Tracker Dev Team wrote: Thu Sep 26, 2019 9:40 am Also, if you want fully distributed control over the Controls - use multi process environment - there you can have different IPXV_Inst pointers and everything will work smoothly.
What do you mean by "multi process environment"?

I need to have multiple Controls in my app in different forms.

Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

What I mean is that every application that holds an IPXV_Control should run in the separate process and the connection between them should be done via pipes/sockets or something likewise. Then you will have all of the independent logic that you want.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Alex,

:)

I guess you know that's not what helps me here...

If I have multiple controls in one app - I simply must have them working separate from each other.

As mentioned before, by many forum members, say I have a Viewer (think plural) (so pxv_control with bare bones functionality) and an Editor (more or less all that psv_control has to offer) - they must act separately or at least as separately as I can force them.

p.s.
Can you please comment on :viewtopic.php?f=66&t=33170#p136601

Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

For starters, the IPXV_Control is just a class that eases up the usage of the different methods for IPXV_MainFrame and IPXV_MainView. The topmost level is IPXV_MainFrame. The Frame property of the control will return an ActiveMainFrame - not necessary the one that you need. Thus I suggested comparing the pointers - you can get to the IPXV_MainFrame level and compare there - not a problem.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Hi Alex,

Uops .. this part is interesting: "The Frame property of the control will return an ActiveMainFrame"

Since having multiple Controls obviously results in multiple MainFrames (one MainFrame per one Control) - how to get the Control from the MainFrame?

Say I have a document "doc" and I locate its Frame:
Inst.GetMainViewFromUIObj(doc.ActiveView.Obj, activeViewIfNotFound).Frame
How can I then know in what Control the document is? I cannot compare this to Control.Frame as this would return ActiveMainFrame, and if the document is not in the active Control/MainFrame ...

-žarko
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,
For starters, the IPXV_Control is just a class that eases up the usage of the different methods for IPXV_MainFrame and IPXV_MainView.
Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Hi Alex,

Sorry but I do not see how this answers my question...

Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

Hello žarko,

I do not understand your question - there is no Control - the topmost level is MainFrame. What you need to do is to distinguish between frames, that's all.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Alex,

Sorry, but your pvx_control is an ActiveX control one can place on a form - so there is "Control".

One can have more pxv_controls (Control) on different forms. Each Control with a few documents loaded.

Something happens (some event) in some document. You can get the MainFrame of where the document is - ok.

I cannot go level up from MainFrame to Control to know in what control that happened.

If only Control.Frame would return the actual Frame it hosts and not the Active one - most issues would be solved. What's more, Control should actually have a Frames property (and not Frame pointing to ActiveMainFrame), since:

The only way how one can have multiple MainFrames (but only one Control) is if you move the document tab using drag-drop and a new MainFrame is created (viewtopic.php?f=66&t=33188#p136642) - and there are some issues when this happens (explained in that post).

Is there any other way to create multiple MainFrames without having multiple Controls? If not, this would mean that Control == single MainFrame and in that way The Frame property should point to the MainFrame hosted in the Control, not the active one for Instance.

I hope the above is clear.

-žarko
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Alex,

I think I know from where the confusion comes. You stated:
Sasha - Tracker Dev Team wrote: Fri Sep 27, 2019 9:54 am The Frame property of the control will return an ActiveMainFrame
I think this is not true.

If there are multiple MainFrames, the Control.Frame returns the MainFrame it hosts - the one created by the Control.

When there are also additional "floating" frames auto-created by drag-dropping a document tab out of that main frame (more info below) - ActiveMainFrame will return the one with focus - not necessarily Control.Frame.

I have 3 forms and on each I have one Control. Iterating over forms and looking for Control on each form and its Frame:

Code: Select all

Inst.ActiveMainFrame: $02E36AD0
frm: pdfxViewerForm, Control.Frame:$02E36AD0, Control.Frame = Inst.ActiveMainFrame: True
frm: pdfxViewerForm_1, Control.Frame:$02E378D0, Control.Frame = Inst.ActiveMainFrame: False
frm: pdfxViewerForm_2, Control.Frame:$02E37A90, Control.Frame = Inst.ActiveMainFrame: False
Note the Frame's addresses. They are all different of course, and only the first active (has focus) form/control has the same address (so same object) as the Inst.ActiveMainFrame.

Some weird things happen when you tab-out a document of a MainFrame and a new auto-created MainFrame is initialized/created.

If that new "floating" MainFrame has focus then Control.Frame <> Inst.ActiveMainFrame.

p.s.
Disabling this drag-tab-out action would solve all the issues for multi control apps.


Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance  SOLVED

Post by Sasha - Tracker Dev Team »

zarkogajic wrote: Fri Sep 27, 2019 3:15 pm If there are multiple MainFrames, the Control.Frame returns the MainFrame it hosts - the one created by the Control.
Yes you are correct - double checked that in the code - the frame value is being assigned to when it's being created.
I've lost the initial question though.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
zarkogajic
User
Posts: 1370
Joined: Thu Sep 05, 2019 12:35 pm

Re: Multiple control instances - enable event listening per instance

Post by zarkogajic »

Hi Alex,

Thanks for confirming this.

Original question is now answered :)

Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am
Contact:

Re: Multiple control instances - enable event listening per instance

Post by Sasha - Tracker Dev Team »

:)
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
Post Reply