Creating winsock client through MFC doc/view architecture - c++

I have a game TicTacToe which was created in MFC with document/view architecture and I have server (standart console application) witn winsockets. Where I should initialize socket in client to connect it with server? (It must be exactly winsock, without Csocket). I know how to create winsockets, but I don't know WHERE I must create them in doc/view architecture. (The only I know is to initialize "WSADATA wsaData" in "InitInstance")

It depends on your program design. If you utilised the whole Document/View architecture you would had document's File->Open / File->New / File->Save handlers. So, it seems right to put the communication code there.
However, if the Document is just a "dummy" class that was created by the Wizard, but never used, with all the code put in the View, then you can continue to enhance the program the same way. Put the "connection" part in your OnInitialUpdate method, and the disconnection part into WM_CLOSE handler.
It is probably a good idea to provide the user with "Connect" option (either via a Menu or Toolbar option, or both). Then put the code there

Related

What is a good MFC C++ GUI architecture for multiple similar window arrangements

I am considering a rewrite of an MFC Dialog application I wrote over a decade ago. I originally chose a Dialog application type because in general the user clicks control inputs and the application provides real-time data from hardware via USB and displays the data in edit boxes. The app also writes information to a file. Since the user never does any file editing I didn't see a need for SDI or MDI application type.
I've now learned that the SDI application type along with CFormView provides some interesting advantages such as scrolling, window resizing:
http://forums.codeguru.com/showthread.php?267664-MFC-Dialog-How-to-enhance-a-dialog-based-application-with-Menu-Toolbar
The reason for my rewrite is that my application is un-maintainable and doesn't scale well. Originally I created a CDialog for each type of "screen" that I show but lots of code is common among the various screens. In fact over time I started reusing CDialog classes and with the use of state variables simply hid, renamed, or repositioned many of the controls to make the screen look appropriate in the context of the application.
I tried deriving the CDialog classes from a common base class but I didn't achieve great code reuse this way. I also found that I had common resources that I was constantly passing around to the various windows which just added unnecessary overhead.
As the application evolved it also became difficult to keep track of the state of the application (for processing USB hardware data input, user input, button enabling etc). Using a hierarchical statechart as the basis for my application might clean this up.
Should I consider putting a superset of ALL the necessary controls on ONE CFormView and simply hiding, renaming, and repositioning controls from the very beginning and using a statechart to manage this?
All the examples I see put the code directly in the input control handlers but maybe I should use the handlers to change state and then let the state machine do the decision-making to reduce this spaghetti code.
So my primary questions are:
1. Would SDI would buy me anything for writing and reading files (such as reporting and logging) if the user does not perform editing?
2. Does CFormView make sense?
3. Does it make sense to put all controls on one CFormView instead of multiple classes and Dialog resources?
4. Have you tried using a state machine in MFC such as Boost Statechart or Miro Samek's Quantum Leaps?
http://www.boost.org/doc/libs/1_58_0/libs/statechart/doc/index.html
http://www.state-machine.com/products/index.html

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.

Is there an equivalent to MFCs OnUpdate in Qt?

I have an existing application that uses MFC for the UI, and I'm trying to migrate to Qt. For the most part the migration is straight forward, but I'm not sure how to manage the enabled state of actions (menu and toolbar items).
In MFC you implement a callback with enable/disable logic, and this is called when the item is displayed. In Qt, you only have access to the setEnabled() method.
Is there a built-in or standardized way of connecting an update callback to an action? or do I need to create my solution using timers and registering actions with it? In a large application such as the one I'm working with, the 'should enable' logic can jump all over the place - i.e. certain files on disk must exist, the main display must have a selection, the application's ProcessManager::isProcessing() must be false, etc. It doesn't seem practical to rely on setEnabled() being called on specific actions when there are so many conditions behind the enable/disable logic.
The most "standard" Qt way would be the use of signals/slots.
In my MDI apps, which are based on the Qt MainWindow/MDI examples, I just connect a single "updateMenus()" function to the signal emitted whenever an MDI subwindow is shown or hidden.
Now that may not be enough granularity for your application. So what you could do is - still have a single "updateMenus()" method - but connect it to each menu's "aboutToShow()/aboutToHide()" signals.
That way you keep the logic from sprawling all over the place, and only update menus right when they are needed (like in MFC's OnCmdUI()).
Here's my mainwindow constructor:
mp_mdiArea = new QMdiArea();
setCentralWidget(mp_mdiArea);
connect(mp_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(updateMenus()));
And here's my updateMenus():
void MainWindow::updateMenus()
{
bool hasMdiChild = (activeMdiChild() != nullptr);
mp_actionSave->setEnabled(hasMdiChild);
mp_actionSaveAs->setEnabled(hasMdiChild);
mp_actionClose->setEnabled(hasMdiChild);
}
See Qt 4.8 doc for menu->aboutToShow()/Hide() here

Create a background process with system tray icon

I'm trying to make a Windows app that checks some things in the background, and inform the user via a systray icon.
The app is made with Not managed C++ and there is no option to switch to .net or Java.
If the user wants to stop the app, he will use the tray icon.
The app can't be a Service because of the systray side and because it must run without installing anything on the user computer ( it's a single .exe )
Using the typical Win32 program structure ( RegisterClass, WndProc and so on ) i dont know how can i place some code to run apart the window message loop.
Maybe i have to use CreateProcess() or CreateThread()? Is It the correct way to handle the Multithreading environment?
If i have to use CreateProcess()/CreateThread(), how can i comunicate between the two threads?
Thanks ;)
As for the system tray icon, you'll need Shell_NotifyIcon.
See http://msdn.microsoft.com/en-us/library/bb762159.aspx
I doubt you want to create new processes to do this, you want to create a thread in your application. The API to do this is CreateThread. But if you are using C++, you should really be investigating the use of frameworks and class libraries to do this, not writing what will effectively be C code from scratch.
All threads belonging to an application share the global variables of the application, which can thus be used for communication. You will need to protect such multi-threaded access with something like a critical section.

Choosing between a Dialog Based Vs SDI Projects

I am new to MFC well not entirely new but wanted to ask experts on this forum as why one would choose one project over the other. I hope this is not a stupid question as I am relatively new to MFC.
Thanks so much
Chose based on what template your application fits best into:
Single Document Interface (SDI) - if your application needs to work with only 1 document or data object or data set at a time
Example: notepad.exe
Multiple Document Interface (MDI) - if your applicaiton needs to work with multiple documents or data objects or data set at a time
Example: Visual Studio
Dialog Based - for anything else.
Example: Calculator
No matter what you chose, you still have the same functionality available to you in the end and you can cusotmize it in any way. So you aren't limiting yourself to anything you start with.
All variants come with CWinApp which is the base class for which you derive your MFC applications.
With a dialog based application you start with a CDialog as well. With an SDI application you start with CMainFrame, CDocument, and CView as well.
If you select an SDI project you get a whole Model-View-Controller framework included.
You get a document class (inheriting from CDocument) which ideally should hold all of the data, and a view class (inheriting from CView) to do with the display.
You get given a hosting frame with a menu already attached, and there are functions you can override to save and load to file.
If you have a dialog based application, then you get one dialog. That's it. Of course, this dialog can spawn off others, but the application essentially consists of a dialog.
If you're developing a small application that just does one task, a dialog application is appropriate, because you don't need the overhead.
If you are developing an application where the user will be loading, editing and saving data, then the SDI path would be more appropriate.
Having answered your question, I'd politely ask if there was a compelling reason why you were choosing MFC over Windows Forms. I believe that MFC was an excellent technology for its day, but the Visual Studio suite offers more advanced tools (if you're prepared to go down the .NET path).
If a "document" is the right metaphor for your application, use SDI or MDI. (Single of only one document can be open at a time, Multiple if more than one.) When you think about it, the document metaphor really isn't appropriate for most applications.