Hide a CDialogImpl dialog when user cancels - c++

Using a CDialogImpl derived class as a dialog-based WTL/ATL app, I want to hide the main window when the user clicks the upper right "X" button (or presses Esc or Alt+F4).
Currently the "X" closes the dialog and ends the application.
I want to change this behaviour and only hide the dialog box instead of closing it. Is this possible?

I'm not sure if ATL/WTL provides some wrapper for this but in WinAPI, the function you are looking for is ShowWindow, which you would invoke as so:
ShowWindow(hwnd, SW_HIDE);
If you want this to happen when the application is closed, the message you need to handle is WM_CLOSE.
After a quick search, MSDN reveals CWindow::ShowWindow, which is the wrapper I mentioned earlier.

Related

Is there a way to make MessageBox not freeze the application?

I'm currently experimenting around with message boxes using the Windows.h module in C++ and I'm curious if there is a way to make the function not hang/freeze the application.
I tried using the MessageBox function and it just hangs/freezes the application until there is user input to the messagebox
The Windows API function MessageBox will create a modal dialog box, which means that the owner window gets disabled and the function will only return as soon as the dialog box is closed.
If you don't want the owner window to get disabled and want the function to return immediately, you should instead create a modeless dialog box using the functions CreateDialog or CreateDialogIndirect.
Another option besides using CreateDialog would be to create a secondary thread and use MessageBox with a NULL hWnd argument.

Hide windows console if minimized

I have a Qt based console application, that has to be located on the Windows System Tray (aka Notification Area).
The question: how can I hide the console window instead of minimizing it if the user clicks on "minimize" icon? I know the ShowWindow method, but as I guess, I have to call it asynchronously.
You need to obtain the HWND window handle of the Console window, then you can use ShowWindow to show or hide it in the usual way.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683175(v=vs.85).aspx
The question is when do you do this? You need to know when the window is minimised in order to know whether to hide it.
You could check this periodically, but you should be careful to ensure you are not preventing laptops etc. from sleeping by doing so.
Alternatively you could install a message hook, or subclass the window, to recieve immediate notifications.
Subclassing the window is probably the best method.

Opening a window in other method than `DialogBox`

I have a dialog IDD_WINDOW_INFO that has to be opened when the user clicks a button or a menu item in my C++ Win32 application. The method that I use to open the dialog is in the following line:
DialogBox(hInstance, MAKEINTRESOURCE(IDD_WINDOW_INFO), hMainWindow, WindowInfoProc);
but my problem is that when that dialog box opens, the user cannot operate with the main window of my application. So what can I do to have both windows active?
You are calling DialogBox which shows the dialog modally. When a modal dialog is shown, the other owning windows are disabled and only the modal dialog can accept input. That is the very essence and intent of a modal dialog. The idea is that you can interact only with the dialog, and cannot interact with the other windows.
Another answer suggests passing NULL as the hWndParent parameter to DialogBox. That's not the solution. That will result in you having an unowned window. Yes, you will be able to interact with the main window, but when you do so your main window will appear on top of the dialog. That's because the ownership is set incorrectly. I recommend that you read about window ownership to better understand the issue.
The correct solution to your problem is to show a modeless dialog. A modeless dialog allows you to interact with the other windows in your application. And that's exactly what you ask for in the question.
You show modeless dialogs by calling CreateDialog followed by ShowWindow. This MSDN article shows an example: Using Dialog Boxes.
If I recall correctly, you can either pass NULL instead of the handle to the parent window or change the dialogbox type in the resource editor.
That is an easy way to do it, however the following is certainly better - since having an unowned dialog isn't your best choice.
The point is that DialogBox() will create a modal dialog window, while CreateDialog does not. Modal dialogs disable the parent window.
From MSDN: A modeless dialog box neither disables the owner window nor sends messages to it.
That should solve your problem.
CreateDialog(hInstance, MAKEINTRESOURCE(IDD_WINDOW_INFO), hMainWindow, WindowInfoProc);
ShowWindow(hWnd, SW_SHOW);

Create two windows in one application?

It might be a simple question, but I don't know where to start the search for the answer. How do I create two individual windows interface in one application using native winapi? Do I put two CreateWindow() functions using same HINSTANCE? What if I want a login screen windows and the content page such that login screen comes first, and after I press the button, the login screen is destroyed, and the content page appears. How do I do such trick?
I was thinking of using DestroyWindow and then CreateWindow inside the button click message. However, this would mean the main while loop (for translate/dispatch msg) in WinMain will exit its loop and cause the whole program to exit. Another way is to pre-create it in WinMain, but how would I notify the WinMain if the button was clicked and enter the second loop instead of exiting the program?
You're over-thinking it. To create two windows, call CreateWindow twice. It's just that simple.
Calling DestroyWindow does not cause your program to exit its message pump. Calling PostQuitMessage is what does that. So don't do that.
When the button is clicked, destroy the one window and create the other. There are no tricks. The message pump delivers messages to all windows (unless you're doing it wrong by explicitly requesting messages for one window, but you shouldn't do that).

Ampersand accelerators cause a beep in a Win32 dialog

I have a dynamically created toolbar on a plain Win32 dialog. My buttons are added with & shortcuts which correctly puts underscore to characters following ampersand but pressing Alt+(char) causes a beep and the button is not clicked.
It has been a while since I have done Win32 API development. Is there something that needs to be done to a dynamically created child window (toolbar) in order for the accelerator keys to work?
This could be something really obvious that I am missing...
Well... You have to write code to handle these keypresses and convert them into WM_COMMAND messages. The traditional way to do this is to define an accelerator table and process them using TranslateAccelerator() - but of course, you're free to do it however you like... Just make sure the keys you handle jibe with the keys you underline!
You might also find this KB article helpful: How to use accelerator keys within a modal dialog box in Visual C++... Or, for a more in-depth (and MFC-free) look at implementing custom message processing in dialogs, check out Raymond Chen's articles on the dialog manager, specifically part 4: The dialog loop and part 9: Custom accelerators in dialog boxes (but seriously, read the whole thing, you know you want to...)
The beep indicates that the command isn't handled by any window in your app.
Since you created the toolbar dynamically, I would guess that the toolbar window isn't set up properly as a child window of your main window (i.e., it's parent and owner window are not set).
To test: click on the toolbar so it has the focus, then press Alt- and it should work.