Any way to forward drag/drop events to embedded process window? - c++

A bit of background:
I need to embed a webview of some kind into a Qt application (that embeds python/PyQt) in order to display some html content. I am stuck with the MinGW build of Qt because that is what the Windows version of our software is built with and it is not feasible to migrate over to Visual C++. Unfortunately for me, QtWebKit has been removed from recent versions of Qt and its replacement, QtWebEngine, is not supported by the MinGW builds of Qt.
It appears my remaining options are one of
Maintain a custom build of Qt that reincludes the old QtWebKit code.
Embed some other rendering engine.
Launch a web browser in a separate process and embed its window in the main program.
I have looked into the first two options, and both sound like a bit of a PITA with a combination of outdated/abandoned code, and complicated build processes with patchy/outdated/conflicting documentation, and limited Windows support.
I've decided to explore the option of embedding a web browser process into my application. I've been successful at getting a firefox process embedded in PyQt using QWindow::fromWinId and QWidget::createWindowContainer
self.process = QtCore.QProcess()
self.process.setProgram('C:/Program Files (x86)/Mozilla Firefox/firefox.exe')
self.process.start()
time.sleep(1)
hwnd = get_window_handle(self.process.processId())
ext_win = QtGui.QWindow.fromWinId(hwnd)
widget = QtWidgets.QWidget.createWindowContainer(ext_win)
widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.ForeignWindow)
self.layout().addWidget(widget)
I can drag and drop html files into the embedded firefox window and they load just fine. I thought I might be able to exploit this feature by faking drag/drop events in order to programatically load files.
def fakeDragDropEvent(self, urls):
point = QtCore.QPoint(self.width()/2, self.height()/2)
self.mimedata = QtCore.QMimeData()
self.mimedata.setUrls(urls)
dragevent = QtGui.QDragEnterEvent(point, QtCore.Qt.CopyAction, self.mimedata, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)
app.postEvent(self, dragevent)
time.sleep(0.1)
dropevent = QtGui.QDragEnterEvent(point, QtCore.Qt.CopyAction, self.mimedata, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)
app.postEvent(self, dropevent)
These fake events can be picked up by the main window etc when I implement event handlers and set acceptDrops(True), however they seem to have no effect on the embedded process window.
Is there any way to make my embedded process window pick up these events? Or do I maybe need to program the drag/drop events using the native Windows API instead?
I'm also open to any other suggestions about how I can display html in my application.

Related

How to create an Evernote kind of widget for global menu of a MacOS/X desktop using QT?

How to create an application which stays in top of MacOS, something similar to below image. You can see the Evernote elephant icon.
I don't want to use xcode - because my application already built in QT, it has nice GUI, now I wanted to add extended feature something similar to Evernote. If I click on an elephant it will open a dialog box to write notes. In my case- it's a simple event like on/off buttons.
I have tried and created GUI widget apps but how to make one which resides like Evernote app ?
A custom pop up menu like the one pictured can be done several ways in Qt.
QML is the most modern way of making the menu with the customized styling you are looking for.
Apply the appropriate flags to the window/widget so it appears as a popup.
The same effects can also be done in QWidgets, but takes more code and probably will take longer to make. The flags you are looking for will be found under Qt Window Flags and/or under Qt Widget Attributes.
The stock stylings for Qt for different OS's deal mostly with title bars, status bars, buttons, drop downs, etc.
The base styles for Mac can be found here:
http://doc.qt.io/qt-5/gallery-macintosh.html
Once you go to a customized popup, you have to draw all of it yourself... but the native drawing elements in Qt are friendly enough and get you that look you are trying to do.
There are even some tools for exporting from Photoshop or Gimp directly to QML.
http://doc.qt.io/qtcreator/quick-export-to-qml.html
Hope that helps.
You are looking for a tray icon. Qt implements it in QSystemTrayIcon.
Further information
You may take a look at the System Tray Icon Example.
Many StackOverflow posts exist on this topic.
If you already have a program written for Qt, then you can compile and run it under MacOS/X much the same way you could compile it under (whatever OS you're using now). You'll need to install Xcode because Xcode includes the C++ compiler (clang) you'll need in order to compile your Qt program, but you don't have to use the Xcode IDE if you don't want to. Rather, you can either use the QtCreator IDE under MacOS/X, or you can simply open up a Terminal window and do a "qmake ; make" in the directory where your Qt-based program's .pro file is, and build it from the command line that way.
If, on the other hand, your question is actually about how to add an icon to the global menu of a MacOS/X desktop, then I don't think Qt has an API for that, so you'll need to drop down to using one of MacOS/X's native APIs. That will probably involve learning some Objective-C (or Objective-C++, if you prefer), but integrating a bit of Objective-C/C++ into your Qt app is doable with a bit of work.

Filling text in qwidget using win32 api

I have a problem. I am using C++ to develop an application in Win32 that among other scopes automatize some user input process in an external app in order for the user to be ready to operate.
Particularly I would like to use Win32 API to fill some text in a Qt QWidget control. I wrote a DLL in pure C to get this task done. I tested it on a MFC application and it works very well.
Anyway I could not get it to work for Qt QWidget controls.
I was able to get the right handle via the EnumChildWindows function (stored in the struct Field).
SendMessage(Field.hFound,WM_SETTEXT,(WPARAM)NULL,(LPARAM)_T("bla bla bla"));
But the SendMessage doesn't seem to work because maybe the control (most probably a QLineedit) supports other messages to get this job done.
Is there any specification for these events, I googled a lot but I could not find anything suitable.
What is the most straightforward way to get this code working? Is there an Event table mapping for Qt I could use? Do I have to use some Qt headers and link it against a DLL (this could be a problem because of licensing)?
Thanks in advance.
Qt, at least 4.8 and 5.x, uses foreign controls. None of the widgets, beyond the window, have native handles. Your EnumChildWindows is most likely not finding what you think it's finding.
If you don't have access to the Qt application's source code, there's nothing else you can do, short of injecting your own code into the running application. If the application is dynamically linked, you can figure out what version of Qt it's using, and what compiler it was compiled with, and the likely set of Qt configuration options. You can then compile your own code with the same compiler and using same Qt version, and inject it into the running application. You can then enumerate visible windows, and their children, and find the control you're after.

C++ Win32 get activated MDI szTitle

I'm writing a notepad program in MS C++ 2010 Express with Win32. So far whenever the user opens or saves the document, it updates the status bar with the saved / opened filename. I also want to change the status bar to the current filename everytime a different MDI is activated. How would I do this?
Your MDI child windows will get WM_MDIACTIVATE messages whenever their activation state changes - you then just have to pass that notification back to your top-level window in some way (via a custom message probably - you could even send the filename at the same time) to get it to update the status bar.
By the way, the MDI concept is more or less deprecated and Microsoft advise against using it in new applications:
Many new and intermediate users find it difficult to learn to use MDI
applications. Therefore, you should consider other models for your
user interface. However, you can use MDI for applications which do not
easily fit into an existing model
For a notepad-type application the "modern" way to do this would be via a tabbed interface.
This is what you need.
Send WM_MDIGETACTIVE to the current client to ge the active client.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644915%28v=vs.85%29.aspx

QT How to embed an application into QT widget

In our project we have three independent applications, and we have to develop a QT control application that controls these three applications. The main window will be seperated to three sub windows - each one display another one application.
I thought to use QX11EmbedWidget and QX11EmbedContainer widgets, but two problems with that:
The QX11Embed* is based on X11 protocol and I dont know if it's supported on non-x11 systems like Windows OS.
Since QT 5 these classes are not existing, and the QT documentation doesn't mention why.
So that I dont know whether to use it or not - I'll be happy to get an answers.
In addition, I see that the QT 5.1 contains QWidget::createWindowContainer(); function that in some posts it looks like this should be the replacement to the X11Embed. Can anyone please explian me more how can I use this function to create a QT widget that will run another application (a Calculator for example) inside its?
I have searched a lot in Google, and didn't find answers to my Qs.
Can anyone please help me? Am I on the right way?
Thanks!
If all three independent applications are written with Qt, and you have their source, you should be able to unify them just through the parenting of GUI objects in Qt.
http://qt-project.org/doc/qt-4.8/objecttrees.html
http://qt-project.org/doc/qt-4.8/widgets-and-layouts.html
http://qt-project.org/doc/qt-4.8/mainwindows-mdi.html
If you don't have access to them in that way, what you are talking about is like 3rd party window management. It is kind of like writing a shell, like Windows Explorer, that manipulates the state and the size of other window applications.
Use a program like Spy++ or AutoIt Spy for Windows and the similar ones for other OS's, and learn the identifying markings of your windows you want to control, like the class, the window title, etc. Or you can launch the exe yourself in a QProcess::startDetached() sort of thing.
http://qt-project.org/doc/qt-5.1/qtcore/qprocess.html#startDetached
Then using the OS dependent calls control the windows. The Qt library doesn't have this stuff built in for third party windows, only for ones under the QApplication that you launched. There are a lot of examples of doing things like this by AutoHotKey, or AHK. It is a scripting language that is made for automating a lot of things in the windows environment, and there is port for Mac as well (though I haven't tried the mac port myself).
So in the end you are looking at finding your window probably with a call like this:
#include <windows.h>
HWND hwnd_1 = ::FindWindow("Window_Class", "Window Name");
LONG retVal = GetWindowLongA(hwnd_1, GWL_STYLE); // to query the state of the window
Then manipulate the position and state of the window like so:
::MoveWindow(hwnd_1, x, y, width, height, TRUE);
::ShowWindow(hwnd_1, SW_SHOWMAXIMIZED);
You can even draw widgets on top of the windows you are controlling if you set your window flags correctly for the windows you are manipulating.
transparent QLabel with a pixmap
Cannot get QSystemTrayIcon to work correctly with activation reason
Some gotchas that come up in Windows when doing all of this, is finding out the quirks of the Windows UI when they set the Display scaling different from what you expect, and if you want to play nice with the Task bar, and handling all the modal windows of your programs you are manipulating.
So overall, it is do-able. Qt will make a nice interface for performing these commands, but in the end you are looking at a lot of work and debugging to get it in a beautiful, reliable, window manager.
Hope that helps.
I never tried it myself, but from the docs in Qt 5.1 I would try QWindow::fromId(WId id), which gives you a QWindow, which should be embeddable with createWindowContainer:
QWindow * QWindow::fromWinId(WId id) [static] Creates a local
representation of a window created by another process or by using
native libraries below Qt.
Given the handle id to a native window, this method creates a QWindow
object which can be used to represent the window when invoking methods
like setParent() and setTransientParent(). This can be used, on
platforms which support it, to embed a window inside a container or to
make a window stick on top of a window created by another process.
But no guarantee. :-)

Terminal to open a popup window in C++

My c++ application needs to display a message via a popup window or an alternative. My application is running on Ubuntu 12.04 version. Can I program the application to open a Ubuntu type popup window? If possible, how?
Do I need to use gnome window or something like that?
The simplest way to display a popup from a program that doesn't otherwise use a GUI, is probably just execute a command-line tool that does the work:
to display a notification with no buttons, you can use notify-send
system("/usr/bin/notify-send MessageSubject \"message body here\"");
if you want buttons so the user can give a response, you could use the (much uglier) xmessage
system("/usr/bin/xmessage")
(see each tool's manpage for all their options)
The alternative is really to use a full GUI framework (probably gtk+), and that's not typically a small change.
For example, you can use libnotify directly (giving you the same basic capabilities as notify-send, but more control), but this also depends on glib. So, now you've added two external dependencies when you could just have run system.
In order to display the popup or any kind of window, you will have to reference either gtk+ or qt libraries in your application/program. gtk+ is advisable, since the ubuntu unity desktop is also based on gtk+ - this way your program will have lesser overhead and more performance gain while running on ubuntu. You can either use the default C library (libgtk2.0) or the gtkmm (libgtkmm) for C++.
You can get more information on how to refer these libraries, initialize gtk_main in your main() function, etc. at this place: http://www.gtk.org/documentation.php