Two active forms

Hi!

I'm developing an application which needs 2 active forms at the same time - something like Photoshop with af form at top of the screen (the mainform) with a menu and a toolbar which can open different childforms. What I wan't is to have the mainform and one of the childforms to be active at the same time so that I can activate the menues and toolbar of the mainform with just a single mouseclick and shortcut keys from the keyboard while a childform is active.

I don't wan't to use a MDI form and childforms.

When I open a childform I add it as a OwnedForm to the mainform.

Is there a way to have 2 forms active at the same time

Thanks!

Brian



Answer this question

Two active forms

  • sub.0ne

    Hi JRQ

    I'm sorry but I don't understand what you are writing. Where do I find the CaptureKeyStroke property and the OnSwatchChanged event I don't think any of these is on the System.Windows.Forms.Form.

    I'm not using MDI as posted earlier.

    I'm using C#.

    Thanks

    Brian


  • Abelard

    Hi bhanu

    Because I wan't to take advantage of using two monitors connected to the computer. I wan't to be able to drag a childform to another screen and maximize it there. I don't think that is possible using mdi !

    The mainform should basically work as a menu/toolbar for opening different childforms that can be dragged to other monitors.

    Brian


  • jamesIEDOTNET

    Hi Alan

    Thanks for your answer but I still can't get this to work.

    I do use form.Show(). Using form border style of tool window and using Application.Run doesn't seem to work.

    What I wan't to do is the following:

    1. Run the application.
    2. Press Alt+shortcut key to open a new childform (works fine).
    3. Press Alt+shortcut key again to open a new childform (doesn't work because the first childform is active).

    Tanks again for your help!
    Brian


  • Suhaib

    There's a couple of ways to do this:

    You can show more than one form modeless, use form.show (not form.showdialog()) and you're off and running. Only one form can have the focus, but if you look closely at Photoshop & others that is what they are doing, a form border style of tool window prevents the title bar from displaying selected / not selected.

    You can have more than one Application.Run form going. This CAN be done but can get extremely unwieldy to program becuase you now have two message loops going. (message loop = WndProc)

    HTH



  • Billy2005

    Hi Jero

    I can't get the toolwindow approach to work. The tool window doesn't give back focus to the child windows and I still have to use two clicks to activate a menuitem.

    I don't wan't to use MDI because it prevents me from dragging a child window to another screen.

    Using the Form.MainMenuStrip also doesn't work. You have to add the menustrip to the controls collection and then it disappears from the mainform.

    Thanks anyway!

    Any other suggestions

    Brian


  • RichHamilton

    Brian

    Determined you can start another thread, and do an Application.Run from that thread, and presto you have two dialogs active. If you want a sample let me know.

    HTH



  • Sami Karaeen

    Isn't there anyone who can help me with this strange problem It shouldn't be that difficult for you experts

    Thanks!

    Brian


  • AamirKhurshid

    I think a simple message bubbling is in order.

    You set the CaptureKeyStroke to true, then using an event delegate, you bubble it up to the parent.

    So when you create new MDI child, you make the MainForm subscribes to the event. Make sure to pass the sender object (child form), so you will know which form to manipulate when needed. You can do same thing with the ToolWindow. You bubble up the event and it's related data to the main form, then the main formwill re-fire the event to the other children (tool pallete or MDI image child) probably just passing the same data. In this case you will have something like this inside your child form.

    ((MainForm)this.TopLevelControl).OnSwatchChanged += new ((MainForm)this.TopLevelControl).SwatchClickEventHandler(myMDIChild_OnSwatchChanged)


  • Daniel Hilgarth

    Tricky problem. I've found a solution but it is a bit iffy. The idea is to catch the keystrokes in the child form and, if they aren't used, to pass them to the main form. Here's the code that needs to go into the child form:

    public delegate bool CmdKeyDelegate(ref Message msg, Keys keyData);
    public partial class Form2 : Form {
    public event CmdKeyDelegate CmdKey;
    public Form2() {
    InitializeComponent();
    }
    private const int WM_SYSKEYDOWN = 0x0104;
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
    if (base.ProcessCmdKey(ref msg, keyData)) return true;
    if (msg.Msg == WM_SYSKEYDOWN && CmdKey != null)
    return CmdKey.Invoke(ref msg, keyData);
    return false;
    }
    }

    I'm overriding the ProcessCmdKey() method. If the message isn't used by the child form for its own menu short-cuts, and the Alt-key is down (WM_SYSKEYDOWN instead of WM_KEYDOWN), I generate the CmdKey event to let the main form have a crack at it. Here's the code for the main form:

    public partial class Form1 : Form {
    public Form1() {
    InitializeComponent();
    }
    private void newWindowToolStripMenuItem_Click(object sender, EventArgs e) {
    Form2 f2 = new Form2();
    f2.CmdKey += Form2_CmdKey;
    f2.Show(this);
    }
    private bool Form2_CmdKey(ref Message msg, Keys keyData) {
    // Keystroke not used by Form2, see if its a short-cut for us
    IntPtr oldhWnd = msg.HWnd;
    msg.HWnd = this.Handle;
    bool retval = this.ProcessCmdKey(ref msg, keyData);
    msg.HWnd = oldhWnd;
    return retval;
    }
    }

    Note the CmdKey event handler. It passes the original message from the child form to the ProcessCmdKey() method, which executes any menu shortcuts. It worked well but might have some unintended side-effects; be sure to thoroughly test it...


  • KaiserSozeTR

    This is a weird issue. It really should be easy...

    I have two suggestions.

    First, if you think about the photoshop example (note, I'm looking at PS 7.0), the image windows are MDI child windows of the main window. But the tool windows are not. I can't guearantee it, but I think when you click in the tool windows the focus immediately go back to the MDI child window. That means that any time you use a key shortcut, it can be trapped by the menu etc.

    You might be able to do something similar...

    The second suggestion is the Form.MainMenuStrip property. Check it out in MSDN. If you can set it to the MDI parent windows menu control then that might actually do what you want. The only problem that I can see is that it says you need to add it to the form's controls collection, but that may just be for display purposes.

    I haven't played with that second method but it wouldn't be hard to test. Give me a yell if it works.

    Regards

    Jero



  • Jim Fr

    I played with this a little myself.

    In VS2005 the ability to have two message loops on two seperate threads is no longer available "out of the box". There probably weren't many folks who needed this -- and that's your primary issue here.

    I'd run the two windows in two seperate processes. Interprocess communication used to be horribly difficult but in .net it's pretty easy and really fast too. Of course you'll need two instances of the IDE to debug it but it sounds like you are already setup for that.

    As dual monitor systems are becoming extremely common do we get better support in Vista or .net 3.0 I love my dual monitors... But they can be really irritating. Every morning I have to reset screen settings because XP can't/won't remember them (how hard can this be Microsoft are you listening I get the taskbar on the wrong screen every day).

    Some of us have monitor #2 on the LEFT side and this is never the default. Then there's the modal dialog open on the WRONG SIDE that you can't see but that's the developer's fault.

    If you want some more ideas on the two process model let me know I've done this before.



  • 3d_developer

    Hi

    Thanks for the reply but it doesn't seem to solve my problem. The "Alt" keystroke is populated to the mainform but not the next keystroke let's say i use Alt+F+N to open a new window the F and N keystrokes isn't populated to the mainform.

    Also i would like to be able to activate the menu with just a single mouseclick and not two (one to activate the mainform and one to open the menu).

    Hope someone can solve this for me.

    Brian


  • jaymoss

    Hi Alan

    Thanks for taking your time to help me out on this.

    I tried starting another thread an did an Application.Run() from that thread but i still don't get two active forms. Here is my code:

    private void newFormToolStripMenuItem_Click(object sender, EventArgs e)

    {

    Thread thread = new Thread(new ThreadStart(OpenForm));

    thread.Start();

    }

    private void OpenForm()

    {

    Form2 form2 = new Form2();

    this.AddOwnedForm(form2);

    Application.Run(form2);

    }

    Brian


  • IamHuM

    hi,

    could you please tell us why would you not prefer mdi

    thank you,
    bhanu.



  • Two active forms