Active X control custom events fail to fire in Javascript - javascript

I have written a custom active X control using the IDispatch interface that I would like to communicate with javascript. I have successfully gotten the javascript -> COM path working; I can call a javascript function on my active x object and receive a corresponding INVOKE call in my dll.
To receive events on the javascript side, I am following the advice in this article: http://jeffcode.blogspot.com/2008/02/how-to-create-activex-control-that.html
When I load my test page, I get a call to FindConnectionPoint followed by a call to Advise, as I would expect. When I call Invoke on the interface given by Advise, I get a success status message, but nothing happens on the js side!
This is the javascript code I am using to test event handling:
function FooActiveX::ReceiveMessage(msg)
{
alert(msg);
}
Interestingly, if I remove that, I don't get the calls to FindConnectionPoint or Advise anymore, so it's doing SOMETHING.
Any advice on how to debug this problem or things to try would be very helpful. Thank you!
My idl interface definition file looks like this:
[
uuid("1bf6bb1a-3232-11e4-a195-a6c5e4d22fb7"),
version(1.0),
]
library FooControlLib
{
interface IFooControl;
dispinterface DFooControlEvents;
importlib("stdole2.tlb");
[
uuid("1bf6bb1a-3232-11e4-a195-a6c5e4d22fb8"),
hidden
]
dispinterface DFooControlEvents
{
properties:
methods:
[id(DISPID_RECEIVEMESSAGE)] void ReceiveMessage( [in] BSTR msg );
}
[
odl,
dual,
uuid("1bf6bb1a-3232-11e4-a195-a6c5e4d22fb9"),
oleautomation
]
interface IFooControl : IDispatch
{
[id(DISPID_SENDMESSAGE)] HRESULT SendMessage( [in] BSTR msg);
}
[
uuid("1bf6bb1a-3232-11e4-a195-a6c5e4d22fc0")
]
coclass FooControl
{
[default] interface IFooControl;
[source, default] dispinterface DFooControlEvents;
}
}
EDIT: It seems that the problem is related to the parameter in the ReceiveMessage method. If I remove the "msg" parameter, the alert box will display properly.

Found my problem. The arguments to the method are passed to Invoke as an array of VARIANTARG structures. I had set the value, but not the vt member of that struct, which identifies the type of the parameter. I don't know why invoke returned an OK status.

Related

Ramda: access input object's properties inside R.ifElse() function call

I have this existing function:
const inferProcessingError = R.ifElse(
R.propEq('conversionJobStatus', 3),
R.always('Last Process failed with error; please contact DevOps'),
R.always(null)
);
which is called like this:
const msg = inferProcessingError(jobStruct || {});
with this jobStruct:
{"id":9,"mediaGroupId":1000000,"conversionJobStatus":3,
"errorDetails": {
"Cause": {
"errorMessage": "MediaConvert Job Failed with ERROR status: ERROR Video codec [indeo4] is not a supported input video codec",
},
"Error": "Error",
}
}
and I need to create an error message string which includes the data from the Cause.errorMessage element.
This would be dead simple with a native JavaScript function, but I'm learning Ramda and want to just modify the existing code to include in the error message.
An R.prop('Cause')['errorMessage'] could work except that I can't figure out how to reference the jobStruct that was passed in to the inferProcessingError statement.
I can see that the R.ifElse and subsequent Ramda functions are able to get that reference, but when I embed an R.prop('Cause') in the error message string, it resolves to a function and not the value of the Cause element because it seems to be waiting for the data structure.
So...how do I gain access to the jobStruct reference? (arguments is not defined here).
UPDATE:
I can get this to work by referencing the original jobStruct as in R.Prop('ErrorDetails', jobStruct)['Cause']['errorMessage'] but that seems rather kludgy to me...
BUT if the call to inferProcessingError is actually inside a map statement and references an element in a larger structure, then the map index is not available to reference the data structure for the R.prop.
Perhaps you could use the pipe and path methods to achieve this "the ramda way".
Begin by using ramda's path() function to extract the nested errorMessage value from the input jobStruct object. Next, enclose that in a pipe() that transforms the extracted message into a string formatted with a custom error prefix:
const incCount = R.ifElse(
R.propEq('conversionJobStatus', 3),
/* Evaluate this pipe if the error case is satisfied */
R.pipe(
/* Path to extract message from input object */
R.path(["errorDetails", "Cause", "errorMessage"]),
/* Prefix string to extracted error message */
R.concat('Custom error prefix:')),
R.always('')
);
incCount({"id":9,"mediaGroupId":1000000,"conversionJobStatus":3,
"errorDetails": {
"Cause": {
"errorMessage": "MediaConvert Job Failed with ERROR etc etc",
},
"Error": "Error",
}
});
Here's a working example - hope that helps!
Update
Thanks to #customcommander for the suggestion to use concat for the string prefix, as well as returning an empty string value for the second branch

Binding javascript code to android code with objects parameters

As the title suggests, I'm trying to bind javascript code to my android app so I can react in my app to an event/message that my website is sending.
After reading the official android documentation related to javascript binding I managed to easily implement it.. as long as it's a string.
What is working fine?
I implemented the following code in my app:
/** Instantiate the interface and set the context */
class ClientInterface(private val mContext: Context) {
/** Show a toast from the web page */
#JavascriptInterface
fun postMessage(message: String) {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show()
}
}
if the parameter of the 'postMessage' function is a String and I'm passing a String from my javascript as a parameter, everything is fine. it's passing the string.
my problem is that I am trying to get a JSONObject instead of a String, and it's not working.
I tried casting everything I thought might work.. JSONObject / JSONObject? / Any / Any? / Object / Object? and so on..
when I'm sending an object on my javascript, nothing seems to work. all I get in my app is a null response.
anyone ever tried something like that? what am I missing?
P.S - here's my javascript code for reference:
var objectMessage = {
type: "quote",
code: "My name is Inigo Montoya. You killed my father, prepare to die!"
}
window.CLIENT.postMessage(objectMessage);
You can't pass an object only primitive!
So you need to stringify your object.
var objectMessage = {
type: "quote",
code: "My name is Inigo Montoya. You killed my father, prepare to die!"
}
window.CLIENT.postMessage(JSON.stringify(objectMessage));

Got a 404 error on my JavaScript route

I'm using Play! v2 and I added a JavaScript method on my page that tries to retrieve data from the server. The client sends 2 information, a deal and a boolean (withDebug).
My routes file:
GET /:deal/tailLog controllers.MyController.tailLog(deal: String, withDebug: Boolean)
I also tried that, without success:
GET /:deal/tailLog?withDebug=:withDebug controllers.MyController.tailLog(deal: String, withDebug: Boolean)
MyController class contains the following methods:
public static Result tailLog(String deal, Boolean withDebug) {
...
}
public static Result javascriptRoutes() {
response().setContentType("text/javascript");
return ok(Routes.javascriptRouter("jsRoutes",
...,
controllers.routes.javascript.MyController.tailLog()
));
}
And finally, the JavaScript call is:
function tailLog() {
var withDebug = $("#logs-debug").is(':checked');
jsRoutes.controllers.MyController.tailLog('mydeal', withDebug).ajax({
...
});
}
When this method is called, my application is calling the URL http://localhost:9000/mydeal/tailLog?withDebug=false, which is the URL pattern I want, but fails with a 404 error message.
Note that before I added the withDebug parameter, everything was working fine.
What am I doing wrong?
Thanks.
In Play 2.0.4, you must use 0/1 to bind boolean parameters (and not false/true)
A little update in your javascript should fix this error:
var withDebug = $("#logs-debug").is(':checked') ? 1 : 0;

Question about socket.io event hook up in the following code

In the node.js/socket.io code accompanying this article the following code is used to hook up events:
socket.on('message', function(message) {
var handler = messageFactory[message.messageType];
$chatMessages.append(handler(message));
});
What is the logic/effect of referencing messageFactory as an array (or at least using [] symbols)? Does it create different handles for different messageType?
Thanks!
What is the logic/effect of referencing messageFactory as an array (or at least using [] symbols)? Does it create different handles for different messageType?
messageFactory is an object with two methods chat and system.
I would assume message.messageType is either "chat" or "system"
So messageFactory[message.messageType] simply gets one of the two methods.
Then handler(message) calls that method.
This is becuase messageFactory.chat === messageFactory["chat"]
If you take a look at the server file ("Listing 5: The chatRoom module.") you will see methods returning
return {
messageType: 'system',
text: originalNick + ' changed nick to ' + newNick
};
So the server returns a message object with a messageType property thats read on the client, it appears that messageType is only "chat" or "system".
That code is basically the OO Command Design Pattern. It's running a different command based on the type of object returned

CHtmlView: How to get data on click?

I have an MFC application that uses CHtmlView. It displays some text in html format from some temp html file. Is it possible to handle mouse click on a paragraph to send some data to the program? I understand that javascript can be used to handle click, but how to pass the data from javascript function to the application??
Thanks.
It is possible to cleanly call the containing application from within the Javascript of the HTML page. At the Javascript level the MSHTML interface that is doing the actual work of the CHtmlView provides an "external" object that acts as a way back to the calling application.
Suppose we want to add a method "someCall()" that can be called from Javascript, and that the method takes a string as an argument. In JavaScript we would call it with something like
external.someCall("An example string");
In the MFC application, we need to write a CCmdTarget derived object to act as the implementation of the "external" object as a dispatch-based COM object, something like:
class TestExternal : public CCmdTarget
{
public:
TestExternal()
{
EnableAutomation();
}
void SomeCall(LPCWSTR str)
{
// This is where we get called when the Javascript runs...
}
private:
DECLARE_DISPATCH_MAP()
};
BEGIN_DISPATCH_MAP(TestExternal,CCmdTarget)
DISP_FUNCTION(TestExternal,"someCall",SomeCall,VT_EMPTY,VTS_WBSTR)
END_DISPATCH_MAP()
To tie this implementation of "external" with the HTML view, in a class derived from CHtmlView you need to over-ride OnGetExternal() and to point it to an instance of TestExternal that lives at least as long as the CHtmlView:
class TestHtmlView : public CHtmlView
{
// Usual implementation stuff goes here...
public:
HRESULT OnGetExternal(LPDISPATCH *lppDispatch)
{
*lppDispatch = m_external.GetIDispatch(TRUE);
return S_OK;
}
private:
TestExternal m_external;
};
Note that I haven't actually tested this, but it seems about right from memory ...

Categories