I am trying to use an ActiveX control in my program.
QAxWidget* mAX = new QAxWidget();
mAX->setControl("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");
I know that there is a function:
put_ChannelType(long newValue)
But when I try to execute it:
mAX->dynamicCall("put_ChannelType(long)",2);
mAX->dynamicCall("put_ChannelType(int)",2);
mAX->dynamicCall("put_ChannelType(long)",QVariant(2));
mAX->dynamicCall("put_ChannelType(int)",QVariant(2));
I get:
QAxBase: Error calling IDispatch member put_ChannelType: Bad parameter count
Any idea what is going wrong ?
EDIT:
Weird thing is if I call
mAX->dynamicCall("put_ChannelType()");
I do not get any error message...
EDIT 2:
This also fails (as Constantin suggested)
QList<QVariant> varlist;
varlist << (int)1;
mAX->dynamicCall("put_ChannelType(int)",varlist);
Got this solved using the generateDocumentation() function.
I was using this ActiveX control in another application, but an MFC one.
It seems the function names I was referring to (which were in a machine generated IDispatch wrapper class created by VS) were not the same as the ones Qt listed.
i.e. put_ChannelType is actually SetChannelType...
Maybe this is just a version issue ?
Anyways, important part is knowing that generateDocumentation() can list you all the functions you can call with dynamicCall.
Is it OK?
mAX->dynamicCall("put_ChannelType(const QVariant &)", (long)2);
Related
First of all happy new year to everyone, hope you're doing well!
I'm working on a C++ project in which I need to call a C# DLL I created following the first answer of this post. Once I have the DLL, I need to call it from Qt, so by using dumpcpp and the .tlb file generated by regasm, I managed to get the .cpp and .h files to use my classes. Just as a reference, the namespace of the classes is Wrapper, and the main class is Device with guid {DD4A4896-C105-4C60-839B-B18C99C8FE15}.
Once I have the generated files to use the DLL, if I try to create a Wrapper:: Device instance on Qt, I get the following error:
QAxBase::setControl: requested control {dd4a4896-c105-4c60-839b-b18c99c8fe15} could not be instantiated
QAxBase::qt_metacall: Object is not initialized, or initialization failed
It doesn't give any more information, so I tried to check if the guid was stored on the system registry (I used the regasm command explained on the previously quoted post, and It said that it was successful, but you never know). Opening Registry editor and searching for the Guid revealed that it's present at: Computer\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{DD4A4896-C105-4C60-839B-B18C99C8FE15}, which, as far as I know, is the right route for these guids, and it points to the right DLL.
I though It may be due to some kind ActiveQt problem, and as the previously quoted post explained how to use that DLL from VS C++, I decided to give it a try, using this as an another reference. I've finished with this code, which is supposed to create an instance of my Device object
#include <iostream>
#include <atlstr.h>
#import "C:\Users\javie\Documents\Wrapper\Wrapper\bin\x86\Release\netstandard2.0\Wrapper.tlb" named_guids raw_interfaces_only
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
int main()
{
try
{
TESTHR(CoInitialize(0));
Wrapper::IDevicePtr devPtr = nullptr;
TESTHR(devPtr.CreateInstance("{DD4A4896-C105-4c60-839B-B18C99C8FE15}"));
}
catch (const _com_error& e)
{
CStringW out;
out.Format(L"Exception occurred. HR = %lx, error = %s", e.Error(), e.ErrorMessage());
MessageBoxW(NULL, out, L"Error", MB_OK);
}
CoUninitialize();// Uninitialize COM
std::cout << "Hello World!\n";
}
However, this doesn't work either, the createInstance method throws an exception of Class not registered and HR=80040154. Again, according to Registry editor, the class is registered, so I don't understand the error. I've also tried with devPtr.CreateInstance("Wrapper.Device"), devPtr.CreateInstance("Wrapper::Device") or `devPtr.CreateInstance("Wrapper::CLSID_Device") as the links I posted suggest, but in those cases I get another exception with HR=800401f3 and message Invalid class string.
It doesn't matter whether VS or Qt Creator are opened as administrator or not, I get the exact same error.
I have run out of ideas, and I really need to be able to use that DLL from Qt using the files generated by dumpcpp.
Does any one know what could be happening? It feels quite strange to me.
If your C++ application is 64-bit, that's the answer right there, because your C# component is 32-bit (or MSIL but registered to the 32-bit hive). In situations like these, a simple test using VBScript is always useful.
Write a simple VB Script (test.vbs)
Dim obj
Set obj = CreateObject("Wrapper.Device") ' or whatever your ProgID is
MsgBox TypeName(obj)
Now, run this macro 2 ways: with 32-bit and 64-bit versions of VBScript:
32-bit > c:\windows\SysWow64\cscript.exe test.vbs
64-bit > c:\windows\system32\cscript.exe test.vbs
This is assuming your C# component is dispatch compatible. If it's not, then it will still give you differing results that you can use to debug.
Assuming automation/IDispatch compatible, one will work and one won't if you have registered your component correctly.
Have you registered correctly? When I use regasm, I always use the the switches /tlb /codebase when registering the C# component for COM.
Ok, in case someone find the same error, I'll explain the solution I found.
The problem was that in my case, the C# class I developed depended on another 32 bits dll which was not registered on my PC. Once I registered the other dll, everything worked fine.
I don't know why VS kept telling me that the class was not registered when my class itselft was registered, it was one of its dependencies that wasn't registered.
Anyway, I discovered this thanks to Joseph's comments, so thanks a lot for your help.
i use the newer version of the v8 library. When i run demo from this page(process.cc),
my program crash when GetInternalField is called in UnwrapMap function. Does anyone have a similar problem, or does they know how to solve it?
Here example:
map<string, string>* JsHttpRequestProcessor::UnwrapMap(Local<Object> obj) {
Local<External> field = Local<External>::Cast(obj->GetInternalField(0)); // here segmentation fault
void* ptr = field->Value();
return static_cast<map<string, string>*>(ptr);
}
EDIT:
I solved my problem. I had to insert macro V8_COMPRESS_POINTERS = 1. Thank you
The provided sample works fine here; did you modify it in any way? How exactly are you running it?
You can only call obj->GetInternalField(0) if you know that obj is an object with internal fields. You can use obj->InternalFieldCount() to check. Objects only have internal fields if you, the embedder, gave them any. If you are trying to convert a regular JavaScript object to a C++ map, you'll have to iterate over its properties, not its internal fields.
So, I'm experimenting with Webkit GTK DOM functions. It's pretty straightforward, except for one thing: there's a useful part of the API called the WebKitDOMTreeWalker which, I assume, lets you walk over each node in the DOM, just like the TreeWalker object in Javascript.
Now, in Javascript a TreeWalker is created by calling:
document.createTreeWalker(root, nodesToShow, filter, entityExpandBol)
So, in WebKit GTK, there is an obvious counterpart in the API - a function called webkit_dom_document_create_tree_walker. The function signature is:
WebKitDOMTreeWalker* webkit_dom_document_create_tree_walker(WebKitDOMDocument* self, WebKitDOMNode* root, gulong what_to_show, WebKitDOMNodeFilter* filter, gboolean expand_entity_references, GError **error);
So creating a TreeWalker with WebKit GTK seems pretty straightforward - except for one big problem: the fourth argument in the webkit_dom_document_create_tree_walker expects a filter object, that is, it wants an instance of WebKitDOMNodeFilter. Well, the Javascript function also takes a filter, but you can pass null if you don't want to use a filter. With the Webkit API, passing NULL doesn't work. If you call:
WebKitDOMTreeWalker* walker = webkit_dom_document_create_tree_walker(doc, root, SHOW_ALL, NULL, false, err)
You get the error message:
** (webkit:3367): CRITICAL : WebKitDOMTreeWalker* webkit_dom_document_create_tree_walker(WebKitDOMDocument*,
WebKitDOMNode*, gulong, WebKitDOMNodeFilter*, gboolean, GError):
assertion `filter' failed
So, the WebKit API won't accept a NULL pointer for the filter argument. Evidently you need to pass an instance of a WebKitDOMNodeFilter. Okay, again - this wouldn't be a problem either, except I've searched far and wide through the WebKit API, as well as Google, and I can't find anyway to create a WebKitDOMNodeFilter object! The header file for WebKitDOMNodeFilter.h doesn't expose any constructor for WebKitDOMNodeFilter. It seems like the API doesn't ever expose anyway to actually construct a WebKitDOMNodeFilter object at all.
Yet... the API exposes many functions (like webkit_dom_document_create_tree_walker, and webkit_dom_document_create_node_iterator) which require a WebKitDOMNodeFilter. So... is the API just incomplete right now? Or, is there some way to create a Filter object which I'm just not seeing?
Can you try casting your null to the WebKitDOMNodeFilter type by calling
WEBKIT_DOM_NODE_FILTER(null)?
So I'm trying to make use of a GtkSourceView in C++ using GtkSourceViewmm, whose documentation and level of support give me the impression that it hasn't been very carefully looked at in a long time. But I'm always an optimist :)
I'm trying to add a SourceView using some code similar to the following:
Glib::RefPtr<gtksourceview::SourceLanguageManager> source_language_manager = gtksourceview::SourceLanguageManager::create();
Glib::RefPtr<gtksourceview::SourceLanguage> source_language = Glib::wrap(gtk_source_language_manager_guess_language(source_language_manager->gobj(), file, NULL));
Glib::RefPtr<gtksourceview::SourceBuffer> source_buffer = gtksourceview::SourceBuffer::create(source_language);
gtksourceview::SourceView* = m_source_view = new gtksourceview::SourceView(source_buffer);
m_vbox.pack_start(*m_source_view);
Unfortunately, it spits out the warning
(algoviz:4992): glibmm-WARNING **:
Failed to wrap object of type
'GtkSourceLanguage'. Hint: this error
is commonly caused by failing to call
a library init() function.
and when I look at it in a debugger, indeed the second line above (the one with the Glib::wrap()) is returning NULL. I have no idea why this is, but I tried to heed the warning by adding Glib::init() to the begining of the program, but that didn't seem to help at all either.
I've tried Google'ing around, but have been unsuccessful. Does anyone know what Glib wants me to init in order to be able to make that wrap call? Or, even better, does anyone know of any working sample code that uses GtkSourceViewmm (not just regular GtkSourceView)? I haven't been able to find any actual sample code, not even on Google Code Search.
Thanks!
It turns out, perhaps not surprisingly, that what I needed to init was:
gtksourceview::init();
After this, I ran into another problem with one of the parameter to gtksourceview::SourceLanguageManager, but this was caused by a genuine bug which I subsequently reported and was promptly fixed. So everything's working great now!
I use gtkmm. Typically you have to initialize things with something like :
_GTKMain = new Gtk::Main(0, 0, false);
Of course do not forget :
delete _GTKMain;
Check here for details :
http://library.gnome.org/devel/gtkmm/2.19/classGtk_1_1Main.html
(Sorry but the link option does not work ...)
Hi I have just started using C++ today, and I am working on checkboxes. I have tried using CheckBox1->Checked in an if statement or whatever, but it isn't working.
The error is:
Error 2 error C2227: left of '->Checked' must point to class/struct/union/generic type
EDIT: The Code is:
void function ()
{
if (1001->Checked)
{
Sleep(2000);
}
}
Without seeing some of your code, it's very difficult to offer targeted assistance.
However, that error message usually comes about because the item you're de-referencing is not a pointer.
Check to ensure it's of the correct type. It should be something along the lines of:
tCheckBox *CheckBox1;
One possibility is that you've declared it not as a pointer to the checkbox but as a checkbox itself:
tCheckBox CheckBox1;
Note the lack of the asterisk there that would otherwise mark it as a pointer. In that case, you would use CheckBox1.Checked rather than CheckBox1->Checked, if it's allowed by the framework (this isn't standard C++ since that beast has no concept of GUI libraries).
If that doesn't help, please post the code so we can offer better suggestions.
Update:
if (1001->Checked) ?????
1001 is not a pointer - it's not a variable of any description, it's an integer constant.
You need to declare and use a variable of some description. First step is, I think, to read up on the documentation for your framework and/or get some sample code that does compile and work, basing your initial work of that.
Use CButton::GetCheck() to determine the state of the checkbox - like so...
CButton* pButton = (CButton*) GetDlgItem(IDC_CHECKBOX_RESOURCE_ID);
if ( BST_CHECKED == pButton->GetCheck() )
{
// button is checked
}