How to show a dialog from another dialog? - winapi

I am newbie to MFC. I have a native C++ MFC app. I want to show a dialog from main dialog. In the main dialog I am having three button (Back, Next, Cancel) respectively.
On the Next button click event I am calling DoModal to show another dialog by hiding the main dialog as follows,
void CFirstPage::OnBnNextButton()
{
::ShowWindow(this->GetSafeHwnd(),SW_HIDE);
CSecondPage secondDlg;
secondDlg.DoModal();
}
void CSecondPage::OnBnBackBtnClicked()
{
::ShowWindow(this->GetSafeHwnd(),SW_HIDE);
CFirstPage FirstPage;
FirstPage.DoModal();
}
After executing this code snippet, the main dialog got hidden and even the application icon also disappears from the taskbar and again appears when the other dialog pops up.
(Basically I am having the same icon for both the dialogs, the icon should not get disappeared and appear again. It has to remain same without appearing and disappearing .)
How can show the icon in the taskbar without any flickering effect?
During traversing from back to next in middle I clicked cancel and the Cancel event is handled as follows,
void CFirstPage::OnCancel()
{
CDialog::EndDialog(TRUE);//For closing the dialog.
}
void CSecondPage::OnCancel()
{
CDialog::EndDialog(TRUE);//For closing the dialog.
}
Steps1:Click Next in the main dialog
Step2: Click Cancel in the second page
Now the application closes. But still instance is active in the "TaskManager". As per my understanding no instance should be alive once windows is closed ?
I suspect as the first dialog is only hidden not ended that instance is still existing in the TaskManager. Is this understanding correct?
How can I resolve this issue?
Can anyone kindly help me to resolve this issue.

As said by Iinspectable property sheets are best suited for your your problem statement.A very good example on how to use CPropertysheets can be found in codeproject
CProperty sheet example

Probably your main windows is still hidden after you end dialog with second page. Ending dialog of CSecondPage does not close application only closes active CSecondPage dialog.
Also OnCancel/OnOK does not need to be overriden if you just EndDialog with it. There is default behaviour implemented in OnCancel, which will close the dialog.
After secondPage.DoModal() show your main dialog again, or close it if that is the behaviour you want to achieve.

FirstPage isn't the original first dialog now, so you should store the first dialog object by yourself. You can do that like this:
void CFirstPage::OnBnNextButton()
{
::ShowWindow(this->GetSafeHwnd(),SW_HIDE);
CSecondPage secondDlg;
secondDlg.setFirstDialog(this); //customer function to store first dialig object
secondDlg.DoModal();
}
void CSecondPage::OnBnBackBtnClicked()
{
::ShowWindow(this->GetSafeHwnd(),SW_HIDE);
::ShowWindow(m_firstDialog->GetSafeHwnd(), SW_SHOW);
}

Related

How winform's ReportViewer hides the "Exporting" window

I'm using The Viewer's reporting feature in Winform, Which has the ability to export pdfs, but before clicking on the export to pop up the save window, a "exporting" window will appear, I want to hide this window but I can't solve it after trying some methods, who can help me?
Click on the screenshot of the question
I tried something but couldn't solve it:
foreach(Form item in Applictaion.OpenForms){
//Hide this window
if(item.Title == "正在导出")
item.Hide();
}
I also tried this:
if (this.reportViewer1.Controls.Find("exportDialog", true)[0] is Form form)
{
//"exportDialog" may be the Name property value I tried to find in the source code, but it was prompted that "index out of range"
form.Hide();
}

MFC: Prevent CDialog from being hidden when main window is minimized?

I have a derived CDialog (actually CBCGPDialog) that was created with a NULL parent window. Yet, when I minimize the main program the dialog goes away. If I do something like:
void CMyDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
CBCGPDialog::OnShowWindow(bShow, nStatus);
if (bShow==0 && nStatus==SW_PARENTCLOSING) {
ShowWindow(SW_SHOWNORMAL);
}
}
It will open it back up but there is a flash. Where would I catch the minimize request in CMyDlg to prevent it from minimizing? (This dialog only has a close option on it, so if they don't want it shown, they would close it, it contains more of a window to show stuff than a normal dialog of options, maybe I should move it to a CWnd?)

MFC: how to show a welcome dialog first?

When launch the program, I want to show a welcome dialog first before showing the main window. My current approach is like below.
BOOL CMyApp::InitInstance()
{
...
// The one and only window has been initialized, so show and update it
m_pMainWnd->ShowWindow(SW_HIDE);
//m_pMainWnd->UpdateWindow();
// call DragAcceptFiles only if there's a suffix
// In an SDI app, this should occur after ProcessShellCommand
CWelcomeDialog welcome_dialog;
welcome_dialog.DoModal();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
Towards the end of InitInstance(), originally it uses (SW_SHOW). At first, I try commenting it out but it still shows. So I change to (SW_HIDE). It works but has unpleasant visual artifacts. Is there way to stop showing the main window as early as possible?
Another issue is that when I hide main window and show the dialog, the dialog is not in the center position of the main window.
In general, how to implement a welcome dialog and to show it well-centered before anything else?

UI Button - activate buttons with keyboard input

this is probably dead easy but I can't find a solution. I made a dialogue system and have a UI-button to click when the player should display a sentence next.
The issue is that the button is only triggered onMouseclick and I would like to change the input button to Enter. Would anyone know how to go about this?
If you need to determine if the button is selected first or not, I suggest you take a look at this page: https://docs.unity3d.com/ScriptReference/UI.Selectable.IsHighlighted.html
If you don't want pressing the button to have any functionality, you just wouldn't link it to any functions.
Working code might look something like this:
public class selectableExample : Selectable{
BaseEventData _event;
void Update()
{
if (IsHighlighted(_event) == true)
{
if (Input.GetKeyDown("enter")){
print("replace me with working function"); // whatever you want to have happen on button press
}
}
}
}
You simply attach this to your button and it should respond the same as being pressed. To be honest, it hardly seems like you actually need a button at all for this though, you'd probably be fine with just a label telling the player to press "Enter" and then simply checking for that input.
You can use the Event Trigger component to use one of the many event types. Select Submit (this is set to enter and return in the input settings at edit>project settings>input by default).
Don't set anything in the OnClick event.
The only thing needed now is to actively highlight the button from somewhere with ReferenceToButton.Select().

How can a dialog become responsive while waiting for a call to DoModal() to return?

A button on a dialog causes a child dialog to be created, and displayed modally.
e.g:
void ParentDialog::OnButton()
{
ChildDialog dlg;
int ret = dlg.DoModal();
}
The parent dialog is initially unresponsive as expected. But, the child dialog also makes COM calls to a server module, which causes the server to make COM calls back to the parent dialog... to update displayed data, etc. In one case, this causes the parent dialog to suddenly become responsive again even though the child dialog is still on screen. Both dialogs can now be interacted with even though the parent dialog is still patiently waiting for OnButton()to return.
How can this happen? I'm trawling the code but is there anything specific I should be looking for?
The dialog has its own message pump/loop and inside the call it has a loop where it keeps receiving and dispatching window messages. This includes COM related messages worker windows receive and convert to COM callbacks you are seeing. Once the dialog is closed, respective windows are destroyed, the function exits from the loop and returns control to your code.
That is, without returning control to your code immediately, window message dispatching still keeps working as usually and UI is responsive.
MSDN:
... The function displays the dialog box, disables the owner window, and starts its own message loop to retrieve and dispatch messages for the dialog box.
When the dialog box procedure calls the EndDialog function, DialogBox destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter specified by the dialog box procedure when it called EndDialog.
You can create a modeless dialog and use RunModalLoop to wait for the dialog to finish, somewhat similar to DoModal()
void CMyWnd::foo()
{
static BOOL isOpen = FALSE;
if (isOpen) return;//optional, prevents opening multiple dialogs
CDialog dlg;
dlg.Create(IDD_DIALOG1, this);
dlg.ShowWindow(SW_SHOW);
isOpen = TRUE;
int result = dlg.RunModalLoop(0);
dlg.DestroyWindow();
isOpen = 0;
TRACE("res:%d\n", result);
}
Problem: Note that in the above example you can close the program but the dialog will still be up. You have to force the dialog close, the above function doesn't deal with that.
Or you can create modeless dialog the usual way:
if (m_Dlg) return;
m_Dlg = new CDialog
m_Dlg.Create(IDD_DIALOG1, this);
m_Dlg.ShowWindow(SW_SHOW);
However in this example if user clicks OK/Cancel then you don't know about it, you have to override OnOK()/OnCancel then send message to parent Window/Dialog, process message, and then destroy the dialog manually.

Resources