I am using C# and WinForms to create UI of my application.
I have main window and dialog, which is shown modal to the main window. Dialog window is not shown in task bar. I go to another application and return back by clicking at the main window task bat icon. I can see locked main window but cannot see dialog unless I select it in Alt-Tab. This is confusing for an application user.
How can I ensure showing modal window in this situation? I can see similar but unfortunately unsolved question ALT+TAB in Vista activates main window instead of previously active child window which regards to Vista (and I have Windows 7).
This is probably because you don't use the ShowDialog(owner) overload. You should fret a little bit about the exact reason that ShowDialog() cannot find an owner by itself and picked the desktop window instead. It isn't healthy. I cannot guess why from your post. See what explicitly setting the owner buys you.
Oh, this will happen when the dialog runs on its own thread. In which case ShowDialog(owner) is going to bomb.
It sounds like your dialog is not properly owned by the main window. Make sure you have assigned the main window to the dialog object's Owner property before showing the modal dialog.
Related
I have a WPF application using the ICDBurn interface to burn some data to a disk.
After calling ICDBurn::Burn a dialog is shown and the user should not be able to continue working with the application until this dialog is handled, which is not the default behaviour.
I tried passing both IntPtr.Zero as well as the applications main window handle as a parent to ICDBurn::Burn, but the result was the same.
So I want this dialog to be modal, but I would settle for setting this dialog to always on top as well.
As a first step, I figured I would need a handle to the dialog's window. I tried EnumChildWindows but did not find the dialog there.
How can I set this dialog to modal?
Edit:
based on the comment from IInspectable, I maybe passed the wrong window handle to Burn. I am using new WindowInteropHelper(Application.Current.MainWindow).Handle and I think I use no other windows in the application.
Ahh, WPF...
To get ICDBurn::Burn to correctly open as a modal dialog, it has to be called on the UI Thread (using Application.Current.MainWindow.Dispatcher).
I am in a need of hiding the console window, which I quickly resolved by P/Invoking ShowWindow. However, the call hides the console window as well as the taskbar button of the console window. I need the taskbar button to remain visible. I am not, however, looking for a way to minimize the console window. Clicking the taskbar button show not do anything. I tried to use SetWinEventHook and hide the window every time it was activated, but to no avail, as the window calling this function must run message loop in order to receive the events (and my console window didn't, no matter if I set OutOfContext or InContext flag).
Is there a way I can make my console application run, show itself in taskbar, then hide itself (or never show itself in a first place) and just keep running with no window but taskbar button visible?
The normal way to get a button on the taskbar is to create a visible unowned top-level window. So that's no use to you. One possible alternative is to use ITaskbarList::AddTab to add a button. I don't know whether or not this will do anything for an invisible window. Either way you'd need to run a message loop for your window. Even if you could do this the net result would not feel very nice for the user.
Suppose, I have the following task.
There is a main application form with numerous buttons; when you click on each of these buttons, you get one more form. The second click on the button should close the opened form.
These forms should not be shown in taskbar, because they are auxiliary. They should not be dialog, because that will block the main application form and prevent user from performing some other operations with the main window or with other forms like the one that is opened. They should be shown above the main form, but not above other windows (so TopMost doesn't suite). When such forms are closed, the main form should be notified, and when the main form is minimized, they should be minimized as well.
How would you solve this problem?
The current solution is based on using hooks. It's not very easy to understand and very difficult to maintain (mainly because I am not experienced in win32). It works fine for about 90% of situations, but in 10% it doesn't.
Maybe, the requirements to forms behavior are to strict?
I would recomment using some window-manager, so each button will tell the window-manager to toggle visibility of form X, if X is not there it will be shown, if it is, it will be closed.
You should be able to configure the windows such that they will not show up in the taskbar.
For the visibility, I am not sure what you mean. When you open a form via a button, it will usually go to front, which should be ok. If you switch the window then, what do you expect? Should the main window always stay in the background or is it allowed to come to the front when focused?
Whenever I have seen applications change such standard behaviors, they failed in some way. Either wrong windows showed up or some were not accessible anymore or the user was just confused because these windows didn't act like all other windows.
It's not a problem. Use the Show(owner) overload to display the form.
An owned form is always on top of its owner. It minimizes automatically when you minimize the main window. No need for ShowInTaskbar. Another window model supported by winforms is MDI, check out the MdiParent property. The child windows are confined inside the bounds of the main window. Also consider using UserControls instead of a form, you can swap them in and out as needed. Or a tabbed interface, using TabControl. Weifenluo's DockPanel suite is a very popular implementation of the Visual Studio style windowing model, supporting windows that can be docked and floating within the main window. Plenty of choices here :)
Here's how most of your requirements can be accomplished:
Set the Owner of each child Form to be the Main Form.
MSDN Quote:
When a form is owned by another form,
it is closed or hidden with the owner
form. For example, consider a form
named Form2 that is owned by a form
named Form1. If Form1 is closed or
minimized, Form2 is also closed or
hidden. Owned forms are also never
displayed behind their owner form. You
can use owned forms for windows such
as find and replace windows, which
should not disappear when the owner
form is selected. To determine the
forms that are owned by a parent form,
use the OwnedForms property.
For stoping a form from appearing in task bar you need to set the ShowInTaskBar property
I have a window that opens another window. I want that when this window it's opened i can't do anything on the parent window. (I'm not allowed to click buttons for example)
How I can do that?
Thanks.
You need to call the ShowDialog method instead of Show to show the second window as a modal dialog.
You want a modal window instead of a modeless window. A modal window means that the parent window is not usable while the child window is open.
You can open a modal window with ShowDialog.
You can open a modeless window with just Show.
I Recommend you to use MDI scenario behaving as child and parent windows but for instance according to the point you can use code below.
NewWindow.ShowDialog() method instead of NewWindow.Show() as it will disable background window
but that's not good practice we should implement MDI.
I've never seen a desktop application opening on multiple windows and disabling older ones.
I would like to display a status window in my C# Windows Forms application that informs the user when the application is waiting to acquire a lock. This is an application-defined thing, however, the window should be visible and always remain on top of all other windows of my application, even when the user clicks on another window (like for example the larger main window behind it).
It must not be modal (so ShowDialog() cannot be used) because the app needs to keep trying in the background and close the window automatically if the lock could eventually be acquired, and it really should not be top-most for the entire window station (i.e. all applications running in that terminal session).
I know the Form.TopMost property, but it can only bring and keep a single window above all others, even those from other applications. This is clearly not what I'm looking for.
I know that this is possible, I've seen it many times before in other applications. I just don't know how it can be done.
If you pass your main form into the Show method of the status form, it will stay on top of the main form, but not on top of other applications. So, in the main form you can have code like so:
StatusForm statusForm = new StatusForm();
statusForm.Show(this);
However, this will only point out one single window of your application as the owner.
You have to set the Owner property of the child form to the parent form, and use Show to show the child form.