I'm stuck on a QtWebKit bridge issue on Windows and I ran out of
options. I don't have access to the exact code used but its something like below.
C++
class MyObject : QWidget {
Q_OBJECT
public:
QString data() const;
void setData(QString);
Q_PROPERTY(QString data READ data WRITE setData)
};
/* ... */
MyObject myObject;
frame->addToJavaScriptWindowObject("myObject", &myObject);
JavaScript
function drop(e) {
var url = e.dataTransfer.getData('url');
//alert(url); // Displays url correctly
myObject.data = url; // Assigns url to C++ object myObject
}
The alert box correctly displays the string value, e.g. 10.10.0.1.
The parameter on setData gives me the string "1". If I then view then memory at that address, I see the full url in memory (formatted as UTF-32 (4 bytes per character)), but whatever I try (toStdString, toAscii, utf16 - just to get sensible data) I do not seem to be able to get/use the whole string.
I event thought that maybe the debugger is playing a trick on me, so I pass the data to the method that actually needs this data (which also used a QString) it all might work - but sadly no.
Even if I make MyObject::setData Q_INVOKABLE and call setData directly I get the same
behaviour:
myObject.setData(url); // Assigns url to C++ object myObject
If I just pass the data as literal, all DOES work correctly, like
myObject.setData('10.10.0.1');
or
myObject.data = '10.10.0.1';
I do not understand why passing a literal works but a variable not, the 'url' variable should be a string type.
I'm partly there. String passing works as expected. However, the C++ object is embedded on a webpage and wraps an ActiveX (ActiveQt) object.
For this, I've seen some pages where you create a class that inherits from a QWebPage. There you have a createPlugins method that asks the QUiLoader to construct the widget for you (alternatively you use the Qt Metatype system). And my C++ object is registered.
When I use this custom WebPage on my WebView (using setPage), the strings are passed in wrongly. When I disable calling setPage, the strings passed correctly.
So string passing works (in some conditions).
I've created a new issue for this: Qt Webkit bridge ActiveQt string
Related
I'm constructing what needs to be a name of var on the fly using
var myNameToConstruct = 'prefix_' + t; // where t is a value passed as string from a function
Using this name I need to initiate a method of an object earlier defined as
var prefix_someName = $("#ele").getObjInstance(); // where getObjInstance is a method used by this particular object.
prefix_someName from my second line of code is an object in itself but the name I'm constructing is a string so even though it looks the same, it is not the same thing (what I gather from this code blowing up)
Is there a way to turn prefix_someName(string) into prefix_someName(object) on the go so that its recognized properly and the method can be called on it or do I have to rewrite code on a deeper level to make this happen?
If your objects are defined globally:
window[myNameToConstruct].methodToCall();
For example, I'm trying to isolate the first 5 characters of window.location.
var ltype, string = 'string';
console.log(window.location); // file:///C:/for example
console.log(typeof window.location); // [OBJECT]
lType=window.location.substr(0,5); // 'not a function' (quite so)
string=window.location;
lType=string.substr(0,5); // fails similarly
Q1: Can I somehow 'bind' substr() to window.location?
I can see that string=window.location replicates a reference and not
a value, so
Q2: How can a separate, discrete copy of a complex structure such as an object or an array be created [without using JSON.stringify() or JSON.parse() - which is what I am presently resorting to]?
try
string = window.location.href.toString();
instead of
string=window.location;
Because window.location will return object not a string.
window.location is an object, so you can't use string functions on it - as you've noticed. In order to get the actual location as a string (to perform string operations on it), you'll need to convert it to a string somehow.
window.location.href is a property provided by the object itself.
window.location.toString() is a method on all JavaScript objects, overridden here.
However, beware of the XY problem. It looks to me like you're trying to retrieve the protocol (the http: bit) of the URI. There's a property for that too - window.location.protocol.
lType = window.location.protocol;
You should use that - it's more robust (consider https:// or, worse, ftp://...).
I have the following IDL which works fine for passing a string value from JS to C++. The JS code passes a string value to the c++/COM object.
[id(1), helpstring("method DoSomething")] HRESULT DoSomething([in] BSTR otlToken);
I now need to add another method to return a string to a javascript caller. I added the following to the IDL:
[id(3), helpstring("method GetValue")] HRESULT GetValue([out] BSTR *nicknames);
The developer who is working on the JS side says he gets a message about wrong number of arguments and other things depending on if he tries to call the method or access it as a property.
Does JS require a call by reference to get this or do I have to pass the one BSTR* param as [in,out]?
How can I get this to work? (getting a string value from C++/IDL to a JS caller?
What does the IDL have to look like and what should the JS code look like?
Javascript itself does not know how to handle values returned through parameters. You have to explicitly declare which parameter is the return value otherwise COM will simply return the HRESULT. You can do this with the following.
[id(3), helpstring("method GetValue")] HRESULT GetValue([out, retval] BSTR *nicknames);
I want to call a method in flex from javascript side,
so that I can retrieve javascript object which contains data in flex.
now I'm trying like
var result:Object = new Object()
var keyset:Array = data.getKeySet();
for (var i:int = 0 ; i < keyset.length ; i++) {
result[keyset[i]] = data.get(keyset[i]);
}
return result;
but it do not work. how can I make it right?
p.s. I know it is fundamental question, but I couldn't find anything even though I googled for an hour. So please help!
To communicate between Flash/Flex and JS on the page, use the ExternalInterface class. You can't directly pass objects, but you can convert your object into a serialisable/string. Here's how you'd call a function called 'myFunc' and set it two arguments, a string and a number:
ExternalInterface.call('myFunc',1,'aString');
After the function name, which must always be a string, there is a ...rest parameter. Simply enough, this means you can send any number of arguments to the function, separating them with commas (we do two here).
If you used AS2 at any point in the past you may know the 'eval' function, this was inherited from (and is thus still used by) JS - it analyses a string and attempts to parse it into JavaScript, using this you can literally send Javascript code instead of a func/args:
ExternalInterface.call('alert("Hello!")');
If you want two-way communication, use the ExternalInterface.addCallBack function to register a function as callable from JS.
In case of errors when doing this, you may need to adjust your embed code: "In the object tag for the SWF file in the containing HTML page, set the following parameter:
param name="allowScriptAccess" value="always"
I believe you cannot call a method in AS3 from JS directly (and vice-versa). There should be an interface for it though, where one can call the other. If i remember correctly, you should use the ExternalInterface API.
Also, you can't pass Flex objects to JS (and vice-versa) also. Try building a generic object that is serializable to JSON and use that serialized data in passing data to each other. The receiving party can parse it back to use the data. In this example, the code passed a string from JS to AS3.
In your case, the Flex function would:
build an object
stuff it with data
serialize it into a JSON string
return the string to the caller
Then when JS calls the function:
JS receives the string
Use JSON.parse() to reconstruct the JSON string into a JS object
use the object
When I use the System.Web.Script.Serialization.JavaScriptSerializer.Serialize method, I get back valid JSON code.
This is usually perfect, but sometimes I want to get back the result as a Javascript object, not JSON. The Serialize method has an overload that takes a SerializationFormat parameter. That looks perfect... but it is marked as internal!
How can I get out a string of Javascript from the Serializer?
Take a look at the JScript DLL Eval object's JScriptEvaluate method (http://msdn.microsoft.com/en-us/library/microsoft.jscript.eval.jscriptevaluate.aspx):
using Microsoft.JScript;
var MyJSObject = Eval.JScriptEvaluate("{a:'Property1',b:'Property2'}", Engine);