I have a large C++/MFC application that can start in two modes: 1) regular GUI mode and 2) special mode when it was started with command line parameters in which case the GUI part of the program is not shown but instead I add an icon to the notification (system) tray.
To ensure that the main window is not shown for mode 2 I process the WM_WINDOWPOSCHANGING as follows:
void OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
CDialog::OnWindowPosChanging(lpwndpos);
// TODO: Add your message handler code here
//Prevent main window from showing
lpwndpos->flags &= ~SWP_SHOWWINDOW;
}
The issue happens if after processing this message the logic determines an error in a command line and wants to show the main window. But I can't seem to show the main window after processing the WM_WINDOWPOSCHANGING message like I showed above.
PS. The project is C++ MFC written for Visual Studio 2008.
Related
I'm writing an application that communicates and initializes instruments (via COM ports) during the initialization phase of a Dialog (using MFC, on Windows 10).
The instrument initialization is presently taking between 4 seconds and 10 seconds. So the GUI won't appear until the initialization is finished.
I want to know how to perform the drawing of the GUI, then call the instrument initialization function.
Here's a code fragment:
BOOL MyDialog::OnInitDialog()
{
//...
// code to initialize dialog widgets
//...
Initialize_Intruments();
return false;
}
From the Microsoft Documentation of the CDialog::OnInitDialog method:
Remarks
Windows sends the WM_INITDIALOG message to the dialog box during the Create, CreateIndirect, or DoModal calls, which occur immediately before the dialog box is displayed. {emphasis mine}
I want to perform functionality, after the dialog box is displayed, during initialization of the dialog.
How to do this using C++, MFC, Visual Studio (2017) and Windows 10?
Notes:
The application is a single dialog that runs test procedures.
A splash screen is another technique under consideration.
I have a multi-threaded application with several supporting DLLs and several popup dialogs. My Main App loads all DLLs on startup, which creates all popups, but they are kept hidden until needed.
When the user presses a button in the main app, a particular popup is shown (from the DLL) by calling ShowWindow( SW_SHOW ) (modeless)
Sometimes (1-in-10 times?) the popup simply fails to show and the Main App hangs. OnShowWindow of the Popup dialog is never called. I have tried calling ShowWindowASync instead, and it still fails to show the popup sometimes, but this call doesn't lock the Main App.
This problem only affects popups within a single DLL.
If the popup shows the first time ShowWindow is called, it can be closed and re-opened indefinitely throughout the lifetime of the Main App. If (using ShowWindowASync), the popup fails to show, it will never show during the lifetime of the Main App. I can re-run the application (without rebuilding anything) and there is a hit-or-miss chance that it will work or fail. I haven't been able to identify any predictive conditions or properties.
I have used tools to renumber all of my resource elements so that there are no conflicts throughout the solution.
UPDATE:
I used Winspector to get some information about the dialog when it does and does not work.
When the dialog works (shows properly), Winspector reports that my dialog has valid position (10,96, 1015, 514), style attributes that match the resource template, ID of 0 (not sure what ID means), and the "Owner EXE" is "MyApp.exe" - I can see many messages passing in and out of the dialog, including WM_SHOWWINDOW.
When the dialog fails (does not get a show window message), Winspector reports position (-1512, 190, -517, 634), style attributes that do not match the resource template, ID 509290824, and owner EXE is "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" - I also do not see ANY messages in the message viewer within Winspector when the dialog fails to show.
Clearly, the dialog is not getting created correctly. CDialog::Create never fails for me. Additionally, I experience this problem in release (not using Visual Studio) so it's not a VS-specific problem.
The dialog was getting created from a thread that was not executing a message pump. This was the root problem. I had tried to initialize all dialogs (i.e. call "Create") from an "init" thread, and then use them later on in the winproc/GUI thread. Can't do this apparently.
A pointer to the dialog was then retrieved into the winproc/GUI (which has a message pump), but by that time, the dialog was already "corrupt" and no longer responding to winproc properly
My program/environment...VS2010, C++, MFC100, CWinAppEx, CMDIFrameWndEx. MFC feature pack.
I am creating and handling a CPreviewView derivative. My method treats this preview view as a normal view that the user can keep up and active. Where as the default PreviewView paints over the current view and 'takes over' the child frame.
One thing I can't figure out is how to gain control over the ON_UPDATE_COMMAND_UI message maps that should be directed to all CDocuments. When a CPreviewView is created it somehow disables all the command handlers to CDocuments. The command handlers to CViews are still up and working.
All Documents open in my MDI app don't receive their ON_UPDATE_COMMAND_UI messages. I can move these message handlers out to the View, or Frame but there are too many to do this efficiently.
Does anyone know where in the CPreviewView class turns off document handlers?
First of all, MFC is not a "locked" framework. Its complete source resides on your own PC in the following folder: "your Visual Studio folder"\VC\atlmfc\src\mfc\ (on my PC it is: c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfc) The source for CPreviewView is in viewprev.cpp file. I just opened the file and in the DoPrintPreview they are calling this:
pParent->OnSetPreviewMode(TRUE, pState); // Take over Frame Window
According to MSDN this method:
The default implementation disables all standard toolbars and hides the main menu and the main client window. This turns MDI frame windows into temporary SDI frame windows.
I have opened the file called winfrm.cpp and checked that this method is doing, and it does disable all the menu. Obviously, no Update messages will be sent to documents while preview mode is on.
The MSDN article at the hyperlink above says that you need to override the OnSetPreviewMode method for your frame to:
customize the hiding and showing of control bars and other frame window parts during print preview. Call the base class implementation from within the overridden version.
This should not be a problem.
I am using VS2010 for my MFC SDI application.
In MainFrame Class in OnCreate(LPCREATESTRUCT lpCreateStruct) function I am opening one dialog box and on IDCANCLE replay from the Dialog box I want to close my application.
I am using following code for the same in onCreate Function.
CTermsConditionDlg objTNCDlg;
if(!objTNCDlg.DoModal() == IDCANCLE){
return -1;
}
Now my Question is after return Statement the application is Showing message box as shown in Image.
I want to disable this message box and close my application.
Can any one help how can I do That.
Thank You in Advance.
Why do you place this dialog so late into you initialization?
The problem is the SDI framework that relay on some initial things that are expected to run always. In this case it is always expected that the mainframe can be created. See code in CSingleDocTemplate::OpenDocumentFile
Just place this code into InitInistance before LoadFrame or ProcessShellCommand is called. In this case you can easily terminate without disturbing problems.
Another Idea is to allow the creation of the window, but simply using a PostMessage(WM_CLOSE); In this case the initialization is done, everything is created and the application terminates again.
I am working on a project. It has GUI and i add Start button on it , which is handled by some function. and after clicking on start ,that Gui shows the output. I want to disable that handler function. Whenever i debug that project, start button should automatically started and GUI shows the output.
This is the code of that handler. What should i change or move that function ?
void CServerSocketDlg::OnBtnStart()
{
UpdateData();
StartX();
}
Need your suggestion. Thanks
So add something like this in an appropriate location. For example, in a dialog, you could put it in OnInitDialog:
#ifdef _DEBUG
if(IsDebuggerPresent())
{
/* code here to automatically do whatever you need when a debugger is attached */
}
#endif
This code will only be compiled in the "Debug" versions of the application and will execute only if the application is running under the debugger.