MFC: how to show a welcome dialog first? - visual-studio

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?

Related

How can I get data from dialog of window?

I am a newbie in Xlib world. In my project,I want to share my window to another via Remote desktop protocol, but they only saw content of window and didn't see anything if click on menu item of window. I used XGetImage to get data of specifies window. But If that window contain dialog ( see image here) I couldn't get data of dialog .
I use freeRDP source code, I modify in X11_shadow.c
function:
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem){
...
image = XGetImage(subsystem->display, 58720435, 0, 0, surface->width,
surface->height, AllPlanes,ZPixmap); //with 58720435 is window id of chrome
... }
In my opinion, the most important here is how can I get data of dialog in Window. I have a solution :
1. get window id of that dialog ( I am not sure the dialog has owner Window ID)
2. Use XGetImage get data of that dialog.
But It's not working.
I works on Linux environment.
Are there any solutions for my problems?
Thank you very much

How to show a dialog from another dialog?

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);
}

XLIB Decoration questions

I'm writing a small window manager, that add a basic decoration around a window, but actually i have several question about adding/remove decoration of a window.
First Question
Actually the decoration is added during MapNotify event, but it seems to be not a good idea, because it add decoration also to a menu opened by an application everytime the mapnotify is fired with a new window, but i want only to add decoration to main window. Maybe i have to check if the current window is a child of another window ? Actually my code just create the decoration window with a specific name, so at every MapNotify request i give the decoration window a dummy name (Parent) to distinguish it from all other windows in that way if the MapNotify event is launched on a decoration window, at least it doesn't add another decoration.
But i don't understand if MapNotify is launched not only for parent window but also for childrend probably the risk is that i add more than one decoration window.
The actual code is the following:
void map_notify_handler(XEvent local_event, Display* display, ScreenInfos infos){
printf("Map Notify\n");
XWindowAttributes win_attr;
char *child_name;
XGetWindowAttributes(display, local_event.xmap.window, &win_attr);
XFetchName(display, local_event.xmap.window, &child_name);
printf("Attributes: W: %d - H: %d - Name: %s\n", win_attr.width, win_attr.height, child_name);
if(child_name!=NULL){
if(strcmp(child_name, "Parent")){
Window new_win = draw_window_with_name(display, RootWindow(display, infos.screen_num), "Parent", infos.screen_num,
win_attr.x, win_attr.y, win_attr.width, win_attr.height+DECORATION_HEIGHT, 0,
BlackPixel(display, infos.screen_num));
XMapWindow(display, new_win);
XReparentWindow(display,local_event.xmap.window, new_win,0, DECORATION_HEIGHT);
XSelectInput(display, local_event.xmap.window, SubstructureNotifyMask);
put_text(display, new_win, child_name, "9x15", 10, 10, BlackPixel(display,infos.screen_num), WhitePixel(display, infos.screen_num));
}
}
XFree(child_name);
}
So how to avoid adding of decoration on every window except the main application window (or the popup windows, there is a way to distinguish the type of window? How can i figure it out?)
Second Question
WHen i exit a program the window that is destroyed is just the application window not the parent decoration, how to destroy the current window and also the decoration?
I tried with the following:
void destroy_notify_handler(XEvent local_event, Display *display){
Window window = local_event.xdestroywindow.event;
XDestroyWindow(display, window);
}
But i receive the following error:
Error occurred: BadWindow (invalid Window parameter)
I use event instead of window because it seems that it contains the parent window (i read it from there: http://tronche.com/gui/x/xlib/events/window-state-change/destroy.html)
But even if i use window i have the same problem.
Or maybe i have to destroy the parent window earlier? Maybe during UnMapNotify? But how to understand if the event is launched just because the window is going to be closed or for some other reasons?
Thanks for the help :)
Read EWMH spec and you'll find answers to all questions.
Check "override redirect" window flag
You are trying
to destroy window which is already destroyed. Instead of using
event.xdestroywindow.event window id just delete your decoration
window.
Don't forget to add client window to save set if you are
writing reparenting WM. That way if you kill wm application windows
are not destroyed but reparented back to root window

Winapi: window is "sent to back" when using EnableWindow() function

To prevent users from clicking in my main_window when a MessageBox appears I have used:
EnableWindow(main_window,FALSE);
I got a sample MessageBox:
EnableWindow(main_window,FALSE);
MessageBox(NULL,"some text here","About me",MB_ICONASTERISK);
EnableWindow(main_window,TRUE);
The problem is that when I press "OK" on my MessageBox it closes and my main_window is send to back of all other system windows. Why this is happening?
I tried to put:
SetFocus(main_window);
SetActiveWindow(main_window);
after and before : EnableWindow(main_window,TRUE) the result was strange: it worked 50/50. Guess I do it the way it shouldn't be.
Btw.
Is there a better solution to BLOCK mouse click's on specific window than:
EnableWindow(main_window,FALSE);
Displaying modal UI requires that the modal child is enabled and the owner is disabled. When the modal child is finished the procedure has to be reversed. The code you posted looks like a straight forward way to implement this.
Except, it isn't.
The problem is in between the calls to MessageBox and EnableWindow, code that you did not write. MessageBox returns after the modal child (the message box) has been destroyed. Since this is the window with foreground activiation the window manager then tries to find a new window to activate. There is no owning window, so it starts searching from the top of the Z-order. The first window it finds is yours, but it is still disabled. So the window manager skips it and looks for another window, one that is not disabled. By the time the call to EnableWindow is executed it is too late - the window manager has already concluded that another window should be activated.
The correct order would be to enable the owner prior to destroying the modal UI.
This, however, is only necessary if you have a reason to implement modality yourself. The system provides a standard implementation for modal UI. To make use of it pass a handle to the owning window to calls like MessageBox or CreateDialog (*), and the window manager will do all the heavy lifting for you.
(*): The formal parameter to CreateDialog is unfortunately misnamed as hWndParent. Parent-child and owner-owned relationships are very different (see About Windows).

Is it OK to delete window from callback window function (Windows OS)?

I want to make Application where you can see only one window at a time in order to save memory. Let's say, we have one window, after pressing a button another window shows, but the previous is deleted. If the button pressing is handled in window callback function, is it safe to delete the window from inside of that window function and recreate it after the new window is closed? Something like that:
void callback(...) {
...
if (msgID == ENTER_KEY) {
deleteMyself();
showWindow2();
createMyself();
}
...
}
Could you suggest better approach if this one is not good?
I think this is generally on a desktop a bad idea. So you would loose everything the userinput. And depending on your application the user maybe confuses why an options dialog closes the main window.
However on a mobile device it is normal only to have just one window (except you use dialogs). But in those cases all inputs should be stored so that the window can be reovered to its old state.
In general if you have trouble with the memory managment better check if you leak somewhere memory in most cases the GUI does not need so much memory.

Resources