Console App that produced a form(Windows Form)? - c++

How can I create a windows form using a console app? Like when I run the console app it will show a form(windows form). Anyone can help me?

First, you have to understand, how windows in Windows works. Each windowed program manages something called a message queue. Messages are informations from system (and other applications), that something happened, for example someone pressed a key or moved a mouse, such that window can react to that user action properly.
Processing messages (including dispatching them to proper window) is a responsibility of the program and in Windows Forms applications is done in Application.Run method (or somewhere near that) by some internal message processing loop. But if you want to display a window in your console application, someone has to take responsibility for this process, otherwise window won't work correctly (actually, they won't work at all).
If you display a window modally, it will process messages coming to it by itself, so you can call directly myWindow.ShowDialog from your code and that will work - but will lock console input away until the window is closed. That means, you will be able to send text to console by Console.WriteLine, but you won't be able to - for instance - ask user for text by Console.ReadLine until the window is closed.
class Program
{
public static void Main(string[] args)
{
System.Windows.Forms.Form f = new System.Windows.Forms.Form();
f.Click += (o, e) => { Console.WriteLine("Clicked!"); };
f.ShowDialog();
Console.ReadLine();
}
}
// (run, then click on a form to observe result)
If, on the other hand, you want to display a window in a non-dialog way, things get complicated. The simplest thing comming to my mind is to create Windows Forms application and use AllocConsole to create separate console window for application (for example Blender does that). The other option is to create two different applications - console and Windows Forms one, run the second from the first and manage their communication by some mechanism (named pipes, shared global memory, windows messages, TCP/IP etc.)

It is not directly supported no.
What you could do is have two separate applications, one form and one console. Start the console one from the form one and pass data between the applications. If you want to set the form to be "inside" the console application you can use
http://msdn.microsoft.com/en-us/library/aa984420%28v=vs.71%29.aspx

Related

How to obtain and interact with QWidgets from QProcess

I have Application A which is a third party Windows application (with GUI) that uses the Qt library.
I want to write Application B which will be responsible for starting Application A. I want Application B to also find buttons on Application B (QWidgets) and send them mouse inputs (click, double click etc).
I can run Application A through using the start function on a QProcess.
How do I do the following from my instance of the QProcess:
Get the top level window(s) for the process
Get a widget by name or (other identifiable attribute)
Get the widgets caption, colour and coordinates (and maybe some other data)
Send mouse move and click events to specific coordinates
Give a widget keyboard focus
Send keyboard key presses
Note - I know how to do this with the Windows API, but asking for a way via Qt. The specific Application A in question does not use the native windowing system, therefore window handles will not show up in Spy++ or Windows API functions.
Update 1 - Cannot seem to get any meaningful objects through the process's children
My attempt at getting child widgets for the process:
QProcess* process = new QProcess();
QString program = "\"C:\\Program Files (x86)\\foo\\bar.exe\"";
process->start(program);
auto widgets = process->findChildren<QWidget*>("", Qt::FindChildrenRecursively);
auto i = widgets.count();
// i = 0
If I find children of type <QObject*> I get 4 results. I used metaObject()->className() to see that I have two pairs of QWindowsPipeReader and QWinOverlappedIoNotifier objects.
Update 2 - Cannot create/inject window from another process
I noticed that when I run the QProcess I can use Windows API functions to get the top level window (top level only). I read in the Qt documentation that you can create a QWindow from the handle of a window in another process using QWindow::fromWinId.
Using this function will throw an 0xC0000005: Access violation reading location 0x00000000. error. I am not passing in a null handle. I am using reinterpret_cast to get the HWND to a WId type. It creates a QWindow only when I create a QApplication beforehand.
The new QWindow will have no children (using window->findChildren<QObject*>("", Qt::FindChildrenRecursively); I assume that the creation of the QWindow does not bring across associated child widgets.
Update 3 - I am currently reading into whether inter-process communication can be used
I have come across various threads, questions and code snippets regarding ICP in Qt. I don't see anything so far that specifically shows that ICP is possible when one of the processes is third party.
I have seen that the Squish Gui test tool lets you interrogate QWidget properties.
This will never work the way you intend it to.
If you really wish to take direct control over the other application, you must inject your code into that application. Let's assume that the application uses a dynamically linked Qt. Then:
Build a binary-compatible version of Qt, using the same compiler that was used to build the application you intend to tweak.
Replace the application's Qt with yours. Everything should still work fine, given that yours should be binary compatible. If not, the binary compatibility isn't there, and you must tweak things until they work.
Edit your Qt to add a hook to initialize your code at the end of QApplication constructor. This makes the Qt module that provides QApplication dependent on your code.
Put your code into a dll that the widgets (for Qt 5) or gui (for Qt 4) module is now dependent on.
Again replace the app's Qt with yours, with hooks that start your code.
Your code will of course need to be asynchronous, and will be monitoring the application's progress by inspecting the qApp->activeWindow(), qApp->allWidgets(), etc.
That's pretty much the only way to do it. You can of course inject your code in any other way you desire, but you will need to work with a binary-compatible version of Qt just to compile your code. Note that binary compatibility encompasses more than merely using the same compiler version and Qt version. Many of the configure switches must be the same, too.

Multiple consoles for a single application C++

Is it possible to create two console windows (one being the main) and the secondary being a pop-up like a message box in Windows Forms?
I only want the secondary console window to hold IDs (that will be hard coded into the application) So the user does not have to keep returning to the main menu to check available IDs
If so how would you go about it?
Many Thanks
Yes, you can do it.
The solution is actually very simple - our process can start a new helper child-process, so the helper process will display whatever our process sends it. We can easily implement such a solution with pipes: for each new console (that I'll call logger), we'll open a pipe, and execute a Console-Helper application - the role of this application is very simple, it will print everything sent through the pipe. Check out this article Multiple consoles for a single application for details (contains the source code).
In the code, it implement a console class CConsoleLogger, then you can create multiple console windows like:
CConsoleLogger another_console;
another_console.Create("This is the first console");
another_console.printf("WOW !!! COOLL !!! another console ???");
And you will get something like:
Take a look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms682528(v=vs.85).aspx for instructions for creating a console window.
Nop
A process can be associated with only one console.
AllocConsole

Application not starting until form is displayed to user for the first time

This is a weird question. I have written a .NET application that starts a process. This process is a MFC application written in c++. For some reason the process does not start doing anything until the form is displayed to the user for the first time. For example, if the process starts minimized I have to un-minimize it (click on it) before it will start doing whatever it's supposed to do. Also, if my application is running and starting this process while the screen is locked the process behaves the same as if it's minimized. It doesn't start doing anything until I unlock the screen and it is displayed to the user for the first time. Like I said, this is a weird question so I hope I'm conveying the problem properly.
Sounds like your functionality is embedded in MFC Windows' load event. If you want the application to be more reactive, move that code to your application class.

Add console to existing MFC application

I'm working with 2 friends in a class project to make a D&D game. so far for the assignments I've been doing character creation stuff and strutting on the command line.
Now we're bringing or part together and I need to output ny dice rolls on a console and a few things on another one that will have to become the main view or tab or whatever it's called when it requires input/attention.
Problem is I never learned MFC yet because I didn't need it. How hard would it be to make a sample MFC console all that I can give to the teammate in charge of the GUI?
Could anyone point me to some instruction on making a console for an MFC app and how to give it output and receive output?
First, you can't. for both Unix/Linux and Windows, there is a one console/process limit. If you want another console, you have to create another process, that writes and reads the other console, while you send and receive the data.
You can use a NamedPipe http://msdn.microsoft.com/en-us/library/windows/desktop/aa365590%28v=vs.85%29.aspx to send data between processes, and the CreateProcess() function lets you create a process with a separate Console window.
Alternatively you can just write a Console-Look-a-Like window in some GUI.

Getting input if the window is not active (Windows)

Short version:
How can I receive input messages in Windows with C++/C when the window is not active?
Background information:
I'm currently working on an Input System that should not depend on any window, so it can e.g. be used in the console as well.
My idea is to create an invisible window only receiving messages, which is possible using HWND_MESSAGE as hWndParent. It only receives input messages when it's active though, and I don't want this. It should always receive input (unless the application requests it no longer does so, e.g. because it lost focus).
I know this is possible somehow, many applications support global shortcuts (e.g. media players (playback control) or instant messengers (opening the contact list)), I just don't know how. Do you know?
Options:
RegisterHotKey if you need to register just one or a few hotkeys
SetWindowsHookEx with WH_KEYBOARD / WH_KEYBOARD_LL. Use when you need to filter many or all keyboard events. However, the hook code needs to be implemented in a DLL (which is loaded into other processes). You need separate 32 bit and 64 bit versions of the DLL
You need to setup windows keyboard input hook. Here is an example how to do it; it is even easier to do in C++