ActiveX on other Window

Hello
I am using an ActiveX control on the main window.
Is it possible to somehow use the same instance on another window?
I don’t need events, just a few methods. I tried with:
GLO:Object = ?Ocx{Prop:Object}
(on Main window, after Ocx is initialized)
and then on another window
?NewOcx{Prop:Object} = GLO:Object
but it doesn’t work
Thanks.

I would think not since the OCX was initialized with the originals windows handle and is bound to the 1st window. Why would you need something like this? Maybe you could send all the events from the 1st window to the 2nd window’s OCX if you wanted to mimic it on the 2nd. But what is the use case for this type of behavior?

I was thinking of something like GetObject where it is possible to get the running object and send some methods to it.
In my case, from the Main window, I send data to different procedures for processing and when the processing is finished, each of the running procedures returns a response directly to the client (and not to the Main window). I know about Notify but I would like to avoid returning to the Main procedure.
Now I send the object in a variable (from the Main window) and it works fine except that on other windows I always have to register a new ActiveX instance and then use the objects from the original instance. I would like to avoid registering a new instance every time.
svapifnc.inc has a GetActiveObject API but I don’t know how to use it.

At the very least, if you drive the object via a global pointer, from multiple threads, you should have thread safety concerns.

Unless you know for sure this specific ActiveX is thread-safe, your approach will fail.

I recommend putting the object on a Window, then using thread-safe ways to communicate with that window, which then in turn talks to the ActiveX.

1 Like

ActiveX is thread-safe and I’m struggling with that too. Some methods that ActiveX calls are executed in its separate thread and I don’t know what to do with that. I tried to write a C++ DLL that would act as a “bridge” between ActiveX and Clarion and manage threads. Each ActiveX method call is properly logged in the C++ DLL, but when I pass it to the Clarion DLL, it doesn’t pick up that call.
In C++ I have implemented CriticalSection, before calling the Clarion procedure, but Clarion does not register the call.
Then I wrote a C++ console application that uses that same C++ DLL and it manages to call the Clarion procedure without any problem (because it is single threaded), so it’s a matter of separate threads that I don’t know how to pass to the Clarion DLL.
ChatGPT suggested using AttachThreadToClarion(BOOL), however I am unable to declare and export that API in Clarion DLL because it says that it is already declared in Clarun.dll (Error: Duplicate symbol ATTACHTHREADTOCLARION in THR.OBJ).
Then I exported it like this:

AttachThreadToClarion(BOOL RegisterThread),PASCAL,NAME('_AttachThreadToClarion')

but C++ failed to load it on

typedef void(__stdcall* AttachThreadToClarionType)(BOOL);
g_AttachThreadToClarion = (AttachThreadToClarionType)GetProcAddress(g_hClarionDLL, "_AttachThreadToClarion");

I also try with

g_AttachThreadToClarion = (AttachThreadToClarionType)GetProcAddress(g_hClarionDLL, "AttachThreadToClarion");

but no luck

Pretty sure I had our user use PASCAL on the prototype

void PASCAL AttachThreadToClarion (int);

You should not need to export or declare this in your CLARION code at all. It’s part of the Clarion RTL.

Thinking back on where I’ve used AttachThreadToClarion(), sometimes it was in windows API callbacks and things like that. But I think it was called from C++ using the above Prototype too.

Thank you all.
After reading a lot about threads in Clarion, I guess I’ll try to avoid using threads.
Especially in a multi-user environment, where it’s very difficult to manage variables and shared procedures. It’s very easy to run into problems that can go undetected for a long time. :no_mouth: