durs / node-activex

Node.JS Implementaion of ActiveXObject
MIT License
326 stars 62 forks source link

listen events from Object #32

Open pr0duc3r opened 6 years ago

pr0duc3r commented 6 years ago

Hello,

I am using the winax to invoke methods in a COM Object and works fine. Now I need to listen to events of that Object. How should I get arround that? Thank you. Great job.

durs commented 6 years ago

Unfortunately, this requires the implementation of the native IUnknown interface, which is required by IConnectionPoint::Advise. But this is problematic in node javascript

сб, 23 июн. 2018 г. в 1:30, Leandro notifications@github.com:

Hello,

I am using the winax to invoke methods in a COM Object and works fine. Now I need to listen to events of that Object. How should I get arround that? Thank you. Great job.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/durs/node-activex/issues/32, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjGNTW36EYN4EENvhcAaGkKPMGoY2J4ks5t_W_rgaJpZM4U0gLE .

drummerv commented 6 years ago

@durs You can do it bro!!! I need this feature.

durs commented 6 years ago

sorry, a universal solution does not work

asinbow commented 5 years ago

COM provides self-inspect mechanism. According to Qt QAxBase https://github.com/qt/qtactiveqt/blob/92b453c705c3259e03913002e5ab34d599647852/src/activeqt/container/qaxbase.cpp#L2792, I have built a demo project (https://github.com/asinbow/CppActiveXEventDemo) for listening ActiveX/COM event.

// Presudo code of https://github.com/asinbow/CppActiveXEventDemo/blob/master/CppActiveXEventDemo/CppActiveXEventDemo.cpp
application = CoCreateInstance(...);
typeLib = application->GetContainingTypeLib(...);

connectionPoints = application->QueryInterface(IID_IConnectionPointContainer);
for (connectionPoint of connectionPoints) { // in most case only one connection point
  typeInfo = typeLib->GetTypeInfoOfGuid(connectionPoint->GetConnectionInterface());
  typeAttr = typeInfo->GetTypeAttr(...);
  for (int i = 0; i < typeAttr->cFuncs; i++) { // event functions
    funcDesc = typeInfo->GetFuncDesc(i);
    names = typeInfo->GetNames(funcDesc->memid);
    funcName = names[0]; // function name
    for (int j = 1; j < names.size(); j++) {
      paramName = names[j]; // parameter name
      paramDesc = funcDesc->lprgelemdescParam[j - 1]; // parameter type and description
    }
  }

  connectionPoint->Advise(&eventHandler, ...); // listen to events of connectionPoint
}

class EventHandler : public IDispatch {
  // ...
  HRESULT Invoke(...) {
    // callback
    // TODO ...
    return S_OK;
  }
};

EventHandler eventHandler;

Maybe we can do something more. @durs How do you think about this? Would it work?

asinbow commented 5 years ago

https://github.com/durs/node-activex/pull/44

asinbow commented 5 years ago

Event listener is implemented in https://github.com/durs/node-activex/pull/46 And I am waiting for @durs 's suggestion.

And next step, we can do something more:

  1. implement Unadvise
  2. ensure no memory leak
  3. format code
jkash20 commented 4 years ago

Hi

The events seem to work with the COM objects like Excel, InternetExplorer etc., but does NOT seem to work the custom COM component. I have been provided with a custom COM component. I'm able to call the methods and properties, but unable to register to the event.

Any help would be highly appreciated.

savely-krasovsky commented 4 years ago

@asinbow also have problems with proprietary COM blob:

const IServerStartup = new winax.Object('Moagent32.IServerStartup');
const IMoagent = IServerStartup.PropIMoagent

const connectionPoints = winax.getConnectionPoints(IMoagent)
const connectionPoint = connectionPoints[0]

connectionPoint.advise({
    MosaixEvent: function (err_flag, notify_type, mosaix_data_packet, err_code, err_text) {
        console.log(mosaix_data_packet)
    }
})

Still getting -2147467262 (Interface not supported)...

From ITypeLib Viewer: изображение