In my C++ code, I create an instance of a Java class through JNI. That Java class's job is to create a WebView dynamically that should go on top of the application's views.
My current strategy is to retrieve the application's main activity, dynamically create a WebView and attach it to the main activity's list of views. Is this possible? Is it better to create an activity?
This functionality is meant for a standalone library that clients can use. So unfortunately it can't be part of the main application's activity.
At minimum, is it possible to retrieve the application's main activity from an unrelated Java class?
In the end, my Java class has a static method Init that is called by my activity to store the reference to the activity. Later, when my C++ code creates an instance of the Java class it retrieves that reference and uses it.
Related
So I'm just learning MFC to see if I want to start using it over normal Win32 programming. I have a SDI MFC application setup. I have a view with members that create a CTreeCtrl and CHeaderCtrl. I have a CDwordArray setup as m_ColWidths that is currently in my View class, but using MFC, should this be in the document class instead since I'll want to save and restore it to keep the users widths when program exits? I guess even though it's only part of the view it's still data and use GetDocument() to reference them?
TIA!!
Application state should not be stored in the document. The purpose of the CDocument(-derived) class is:
A document represents the unit of data that the user typically opens with the File Open command and saves with the File Save command.
CDocument supports standard operations such as creating a document, loading it, and saving it. The framework manipulates documents using the interface defined by CDocument.
The designated entity to store application state (e.g. size and visibility of UI elements) is the CWinAppEx(-derived) implementation:
CWinAppEx handles the application state, saves the state to the registry, loads the state from the registry, [...].
I have a dialog-based MFC application that hosts CPropertySheet.
The idea is to scan some folder for DLLs, load each of them dynamically (using LoadLibrary()), acquire a pointer to a function that would work like a CPropertyPage factory, use that function to create per-DLL CPropertyPage instances and insert them to CPropertySheet.
In other words, scan a folder for plugins, acquire the per-plugin property pages and insert them to CPropertySheet of the main application so each plugin would have it's own options GUI.
Plugins are implemented in a form of regular MFC dlls (not extension dlls). I'm aware that AFX_MANAGE_STATE(AfxGetStaticModuleState()) is to be employed.
Each CPropertyPage being created must be derived from an abstract interface (say, IPluginOptionsPropPage) so it would be possible to cast the pointer that factory function returns to IPluginOptionsPropPage.
This task is supposed to be a routine one, however, I could not found any sound examples.
Yes it can be done. You can try these steps
Load the property page library using ::LoadLibrary. The return handle is the handle for the resource.
m_hResInstance = ::LoadLibrary(strFile);
Before creating the instance of the property page, set the instance of the resource handle to the library's handle.
m_hCurrent = AfxGetResourceHandle();
AfxSetResourceHandle(hResInstance);
//Create your property sheet here.
Then reset the resource handle to the current process resource.
//Reset the previous
AfxSetResourceHandle(m_hCurrent);
This will enable you to load the resource of the property page, others like header and library or function pointer can be used as intended.
I'm using a QJSEngine to make an application scriptable. I'd like the JavaScript side to be able to modify the user interface. My main issue right now is accessing the Qt API from JavaScript.
To create widgets, I added a createWidget() wrapper that uses QUILoader:
// JavaScript
var w = helpers.createWidget("QPushButton");
// C++
QJSValue helpers::createWidget(QString type)
{
QUILoader ld;
return engine.newQObject(ld.createWidget(type));
}
I've also registered all the enums from qt_getQtMetaObject(), which seems to take care of all the namespace-level enums from qnamespace.h. It doesn't look like it's part of the public API though.
Am I really supposed to this stuff manually or am I missing something? Isn't there a registerAllTheThings() function that creates a global Qt object through which the Qt API available?
If there isn't, then I have a problem. I can create QWidgets with a QUILoader, but I couldn't find a way of creating other objects, such as a QStandardItemModel. I thought all Qt classes would already be registered through qRegisterMetaType(), but they're not: QMetaType::type("QStandardItemModel") fails by returning UnknownType. Again, am I missing some initialization function call that registers everything?
I would recommend using a QQmlEngine instead of the QJSEngine.
Is is derived from QJSEngine so it can do the same things, in the same module so no extra dependencies.
It provides an easy way to register types for instantiation in QML, has a plugin loading mechanism (imports), etc.
I presented that as part of my talk at Qt World Summit 2015: https://www.youtube.com/watch?v=7LsKoVrb8C8
I have developed a MFC ActiveX control, that displays a graph using data retrieved from Kepware OPC Server using OPC Client. OPC Client code is part of ActiveX control code. The OPC client is launched in a separate thread from main control thread. The control works well when there is only one instance of it on the MFC dialog. However if I add another instance of it on same form, the curve on the graph starts malfunctioning. From the logs I can see that Control app class which is ultimately derived from CWinApp is instantiated only once. Any ideas why it is messing up? Are any global variables being shared between two instances? I am using Visual Studio 2008.
If your ActiveX control is located inside a DLL this DLL is always loaded once into the process that uses the ActiveX control. So it is normal that you only have one CWinApp object even if you have multiple controls.
So you need to design your object in a way, that global data inside the DLL doesn't affect the behaviour or data inside a control instance.
I suppose that you have some global data, that is used by the first control. And when another instance is created this global data is modified by the second instance and the first instance shows wrong data or misbehaves.
All state of such an ActiveX must be located and allocated inside the object.
I am reading about prototype pattern by GoF book. Here is the text snippet
Configuring an application with classes dynamically: Some runtime
environments let you load classes into an application dynamically. The
prototype pattern is the key to exploiting such facilities in a
language like C++.
An application that wants to create instances of a dynamically loaded
classes won't be able to reference its constructor statically.
Instead, runtime environment creates an instance of each class
automatically when it's loaded, and registers with a prototype
manager. Then the application can ask the prototype manager for newly
loaded classes, classes that weren't ;omled with the program orginally
My questions on above
What does author mean by "An application that wants to create instances of a dynamically loaded classes won't be able to reference its constructor statically" ? For example if we use dynamic link library I can still create object using new so what does author mean by we won't be able to reference constructor statically?
Request to give an example how prototype pattern is used to exploit load classes application dynamically.
My 50 cents on this :
I believe the author is referring to situations where you don't have the class definitions in the symbols library, however you want to instantiate objects, and pass them to the library consumer functions (so you are the memory owner, the shared library is the consumer , but you don't have access to the concrete classes inside the library )
Example ( I will write one from the top of my head to underline a scenario where it would be useful then I will write another one that I actually bumped into)
Having a dynamic library TextEditorWidgets.dll and your main application , the TextEditorWidget exposes an abstract prototype TEWPrototype , and a factory method of getting certain prototypes according to let's say a string identifier.
Having the factory method exposed from the dll defined as :
TEWPrototype* TEWPrototype::getPrototypeFor(string identifier)
{
TEWPrototype* result;
if (identifier == "SomeWidget")
{
result = ConcreteSomeWidgetPrototype;
} else if ...
return result;
}
Inside your application you can use the following code :
{
vector<TEWPrototype*> allocatedWidgets;
...
TEWPrototype* SomeWidget = TEWPrototype::getPrototypeFor("SomeWidget").clone();// you are now the memory owner
allocatedWidgets.push_back(SomeWidget); // keep for deletion
TextEditorWidgetsHandle->doSomethingWithTheWidget(SomeWidget);// pass the instantiation to the consumer who knows the widget full definition
}
In the example above you have the following pros as the app develoer :
you will control what the dll allocates , when and how
you will control if the widgets get deleted or not through the lifetime of the application
The pros as the dll developer :
you will be able to add new Widgets while providing backwards functionality
you have the guarantee that nobody will use your internal widgets functionality outside the .dll
Practical example :
While working on a game , new entities were created by the game development team, and we needed a fast way to give the Designers the new objects for them to add into the game scene. We had our own in house editor, so we had control over the design tool.
The approach was to have the World Editor load .dlls , then expose in the editor menus what objects were loaded in the dlls. The editor didn't know what classes were inside the dlls, it only knew about them having a draw and a setPosition function (and some other things).
When the dll was loaded , inside the editor, the name of the object was added into an object prototype manager (basically we had a static function getAvailableObjects and after dll load, we would query that in order to get the strings).
When a Designer was choosing from a menu an object (let's say for example Crate), then a new instance of that object was created that was drawn inside the editor , and the designer could move it around.
The editor couldn't instantiate the object by itself because he knew nothing about the size of the object nor about his constructor. However we had pre-instantiated objects for each type, that were getting cloned each time the Artist chosed to create a "new" Crate.
The preinstantiated objects were also used in the preview .
When the development team released a new set of entities , we just provided the new dll to the Designers, and they would only need to "refresh" the editor an BOOM : magic happened : new objects in the menu .
As an alternative, an abstract factory can provide kind of the same functionality.