How do you have a window that has no icon in the tasktray? - c++

I found the windows style WS_EX_TOOLWINDOW but this changes the title bar. Is there a way to not have the tasktray icon but keep the normal window titlebar?

You usually do want to do this if you have added an alternate means to restore the window - for example placing an icon in the notification tray.
The usual way of ensuring the taskbar does not display your window is to create it with a hidden parent window. Whenever a window has a parent, the parent window is used to create the button - hidden windows are not shown on the taskbar.
Also, WS_EX_APPWINDOW should be removed as that performs the opposite hint to the shell and forces the window onto the taskbar even if it would otherwise not have been shown.

Related

Remove window from taskbar on Windows 10

I want to remove window from taskbar on Windows 10 with multiple desktops.
For Windows 8.1 i used ITaskbarList::DeleteTab and it works excellent.
For Windows 10 this method hides Windows from taskbar too, but after it i see this window on all desktops. I want to see this window only on one desktop.
Does anyone know the method to hide window from task bar in Windows 10 and stay this window on one desktop?
Below you can see, what i meant under "hide window from task bar in Windows 10":
In my understanding, borne out by my empirical tests, the windows that appear in the taskbar previews are exactly the same windows that would ordinarily appear in the taskbar. A long time ago, say in Windows 2000, each of an application's eligible windows would just appear as buttons on the taskbar. Starting in Windows XP, taskbar grouping became an option, so that all eligible windows from a single application could be grouped together and appear as a single button on the taskbar. Then, in Windows Vista, it became possible to display previews of these open windows when you hovered over the corresponding taskbar button. Neither Windows 8 nor Windows 10 changed that fundamental rule; they only changed the appearance of the previews.
As such, we can refer back to the MSDN documentation for the rules about which windows appear on the taskbar:
The Shell creates a button on the taskbar whenever an application creates a window that isn't owned. To ensure that the window button is placed on the taskbar, create an unowned window with the WS_EX_APPWINDOW extended style. To prevent the window button from being placed on the taskbar, create the unowned window with the WS_EX_TOOLWINDOW extended style. As an alternative, you can create a hidden window and make this hidden window the owner of your visible window.
Raymond Chen has summarized these rules more precisely here. Quoting him:
There are some basic rules on which windows go into the taskbar. In short:
If the WS_EX_APPWINDOW extended style is set, then it will show (when visible).
If the window is a top-level unowned window, then it will show (when visible).
Otherwise it doesn't show.
(Though the ITaskbarList interface muddies this up a bit.)
You were muddying it up before, calling ITaskbarList::DeleteTab. That is not necessary. To ensure that a window does not appear in the taskbar, just apply the converse of the rules governing when a window does appear in the taskbar.
If you have a top-level unowned window, it will be shown in the taskbar unless you remove the WS_EX_APPWINDOW extended window style. If you have an owned window, then it will not be shown in the taskbar unless the WS_EX_APPWINDOW extended window style is set to force it there.
So if you have the WS_EX_APPWINDOW extended window style set, you should remove it. That is forcing the window to be displayed in the taskbar.
Otherwise, you should set an owner for your window. For example, make the second window be owned by the first.
TL;DR:
Remove both WS_EX_APPWINDOW and WS_EX_TOOLWINDOW from the extended style.
Set an owner for the window.
Example:
Removing flags from the extended style:
SetWindowLong(myHWND, GWL_EXSTYLE,
GetWindowLong(myHWND, GWL_EXSTYLE) & ~WS_EX_APPWINDOW & ~WS_EX_TOOLWINDOW);
Setting an owner:
SetWindowLongPtr(myHWND, GWLP_HWNDPARENT, myOwnerHWND);
Full explanation:
Despite Cody's answer being great, it does not quite answer the exact question.
The exact question is: "How to display a window that does not appear in the taskbar, yet appears only on one virtual desktop?
As Cody explained, there are several ways to remove the taskbar button for a window. However, there is only one way among them that makes it display on only one virtual desktop at the same time.
If you include the flag WS_EX_APPWINDOW in your extended style, it will force the window to show in the taskbar. That's why it must be cleared in this case.
If you include the flag WS_EX_TOOLWINDOW in your extended style, it will force the window not to show in the taskbar, but will force the window to be shown on all virtual desktops. Thus it's not an option either here.
Finally, if your window has neither flags, it will show in the taskbar if and only if it does not have an owner. Either way, it will not force itself on all virtual desktops. Hence, the solution is to have neither flags but to set an owner.
Add WS_EX_NOACTIVATE to the ex styles of the window.
https://learn.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles
A top-level window created with this style does not become the
foreground window when the user clicks it. The system does not bring
this window to the foreground when the user minimizes or closes the
foreground window. The window should not be activated through
programmatic access or via keyboard navigation by accessible
technology, such as Narrator. To activate the window, use the
SetActiveWindow or SetForegroundWindow function. The window does not
appear on the taskbar by default. To force the window to appear on the
taskbar, use the WS_EX_APPWINDOW style.

Win32: Is it possible to show the window but to hide it from taskbar?

If I have an win32 application with several windows, is it possible to show a window but hide the window icon in the taskbar?
I have tried creating the window with WS_EX_TOOLWINDOW and WS_EX_APPWINDOW.
You have a few options:
Tool windows do not have taskbar buttons. Create a tool window by including the WS_EX_TOOLWINDOW extended window style.
Owned windows without the WS_EX_APPWINDOW extended style do not have taskbar buttons.
Hidden windows do not have taskbar buttons.
Option 1 is simple enough. If you don't want to use a tool window, use a combination of 2 and 3. Create a hidden unowned window that is the owner of your main window.

How to create multiple Dialogues?

In a Project I am using multiple dialogues so in that my requirement is while I am initiating dialog if it is modal then it should come top else it should be behind the parent window...so suggest me how to do it???
Modal dialog always come to the top of the parent window. But what is the else case? You have a non-Modal dialog that should stay behind the Parent window? This doesn't make sense to me.
But if you want to have a non-modal dialog behind the parent window (or any other window) you need to define NULL for the dialog as a parent (owner window). Than you can change the Z-order of the top level window to be behind/after the parent window (use SetWindowPos for this).
Please note that the user can always change the Z-Order of top-level windows when he clicks on it.
Remember: If the window is owned by a parent it is always on top of the owned window.

Use dialog controls without stealing focus

I have a modeless CDialog that contains controls, some CButtons and a CScrollbar. The CDialog is parented off of an edit box that I want to keep focus at all times. The problem is that whenever the user uses the controls, clicking a button or on the scrollbar, the control steals focus from the edit box, causing both the parent window to draw without focus (grayed-out header bar), and causing the control to take all the keyboard input. Is there a way for the controls to respond to mouse actions but not steal focus?
The controls and the dialog are all created with WS_CHILD. The controls are parented off the dialog, and the dialog is parented off of the edit box.
I've tried setting focus back after the controls are used, but that causes the parent window to flicker as it loses and then regains focus. Basically I want something that works like a combo box, where the scroll bar can be clicked or dragged around, but keyboard input still goes to the dialog itself, not just the scroll bar, and the whole thing never loses focus.
I haven't done anything like this for a long time, so I'm sure there are a million little details, but I think the starting point is to override the handling of WM_MOUSEACTIVATE.
I am a little confused about child-parent relationship you described.
Can you explain what do you mean by:
The CDialog is parented off of an edit box that I want to keep focus at all times
Any window hosting other windows inside of the client area is a parent of those windows. It is impossible to create window without WS_CHILD that is contained by other window.
Therefore all dialog’s controls are children of this dialog. It is also possible that child window hosts another child window.
CDialog is just an MFC representation of a dialog window; the same applies to other controls. For example CButton is an MFC class that wraps handle of the window’s window that is predefined as window button control.
Dialog never has focus unless is empty (does not have any controls). If dialog contains even one control, this control always has focus.
What focus means is that any given window receives mouse and keyboard messages. Only one control can have focus at any given time. In order for scroll bar to process mouse click or keyboard to move slider, scroll bar must have focus; therefore some other control must give it up.
Combo box drop box (I think this is what you are referring to) is not a child of the dialog. It is a popup window that for the duration has keyboard focus and captures mouse. When it drops down, dialog is deactivated and once dropdown hides, dialog state is changed back to active hence focus never changes, it returns to the control that had focus when dialog was deactivated.
What you are trying to do is probably possible but it would require a lot of coding. Probably hooking messages would do the job but I think it would be going against the stream.

Hide main MFC window while modal dialog is active?

I have a native C++ MFC app. It has a main window based on CWnd, and user action can create a modal dialog. While the dialog is active, I want the main window to disappear, the dialog to be visible, and the main window's icon to remain in the task bar.
How can I accomplish this?
If I hide the main window (ShowWindow(SW_HIDE)), the task bar icon disappears. If I minimize the main window (SW_MINIMIZE), the icon remains. However, since the dialog is owned by the main window, this also hides the dialog.
After the dialog is created, clicking on the task bar icon makes the dialog visible. Naturally, I do not want to require the user to do this.
Even if I insert ShowWindow(SW_SHOW) in the dialog's OnInit handler, the dialog remains not visible. Spy++ shows that its visible bit is set, though. Same is true if I add SetWindowActive to OnInit.
I am not interested in changing the UI design. While the dialog is active, the user interacts only with it, and is not interested in anything in the main window. Therefore, the main window should disappear.
Using Windows VS2005 under WinXP32.
Well, in the block of code where you create the dialog and show it modal, you can do whatever you want to the main window of your app (show/hide) as long as you make the desktop window the parent of your dialog. Usually, the constructor for CDialog and derivatives takes a default argument of NULL for the parent window in which the framework ends up substituting AfxGetMainWnd(). Instead pass CWnd::GetDesktopWindow() as the parent of your dialog and then you should probably be able to hide your main window. However, you still might have a problem with the taskbar--but I'll let someone else give hints since I know nothing offhand about it.
In OnInitDialog, add following codes
//Set windows size zero, the windows disappear.
MoveWindow(0,0,0,0);
//If you want it invisible on taskbar. add following codes.
DWORD dwStyle = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
dwStyle &=~WS_EX_APPWINDOW;
dwStyle |= WS_EX_TOOLWINDOW;
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, dwStyle);
You're fighting the OS. A modal dialog, by definition, disables but does not hide the "main" (parent) window. If you wanted another window, make a second one, but don't tell the OS to treat it as a modal dialog over the first window.
Perhaps you can resize the main window to a really small size and always keep it behind the modal dialog.