Skip to main content
GameDev.net gamedev.net
🔒 Locked

[c#] create a floating toolbar

Started by Link Jun 13, 2005 at 1:29 PM 5 replies 4.6k views
Original Post
Link
Link
Hi guys it is very important for me can create a floating toolbar that appear active if the main one is active, and not when the main is not. Ok it need to handle hook windows message and it is not relly simple but it is possible you can see it exists and works in much graphic program gui and you can see a c++ example here: http://www.codeproject.com/docking/dockwnd.asp Ok now i need a C# version of this example but i don't know where. If someone know where can i learn or if he can show me some row of code i'm grateful.
Link
Link
Someone know how can i do?
MauMan
MauMan
You use essentially the same trick. You can override WndProc() in your classes to process Win32 messages.

For example if you added the following code to your main window form and toolbar form:
    private const uint WM_NCACTIVATE = 0x0086; // From Winuser.h    protected override void WndProc(ref Message m)    {      if ( m.Msg == WM_NCACTIVATE )      {        m.Result = (IntPtr)1; // return TRUE        return;      }           // Process unhandled messages      base.WndProc( ref m );    }

You would get the windows where the window bars were always painted as active. It should be straight forward to extend this to pass around a little state information to have the proper behaviour.

Edit: Added comments to code
---CyberbrineDreamsSuspected implementation of the Windows idle loop: void idle_loop() { *((char*)rand()) = 0; }
Link
Link
thanks mauman but i've just arrived to this code.
My trouble is right this:
"..to extend this to pass around a little state information to have the proper behaviour"

make more windows of the same application actived and deactived at the same time.
Please i ask you just another little contribuite to my solving.
Really thanks if you.
MauMan
MauMan
Well what I mean is that you need to somehow keep track of all of the windows that you want to be active or inactive. You need to do more than that if you want to do all of the things described in the article.

Following is a naive implementation w/out error handling and such that simply keeps track of the active/inactive window states

using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;//// BEGIN NEW CODEusing System.Runtime.InteropServices;//// END NEW CODEnamespace ActiveToolWindowTest{  /// <summary>  /// Summary description for Form1.  /// </summary>  public class MainForm : System.Windows.Forms.Form  {    /// <summary>    /// Required designer variable.    /// </summary>    private System.ComponentModel.Container components = null;    public MainForm()    {      //      // Required for Windows Form Designer support      //      InitializeComponent();      //// BEGIN NEW CODE      RegisterCoactiveForm( this );      new ToolbarForm( this, "Toolbar #1" );      new ToolbarForm( this, "Toolbar #2" );      new ToolbarForm( this, "Toolbar #3" );      //// END NEW CODE    }    /// <summary>    /// Clean up any resources being used.    /// </summary>    protected override void Dispose( bool disposing )    {      if( disposing )      {        if (components != null)         {          components.Dispose();        }      }      base.Dispose( disposing );    }    #region Windows Form Designer generated code    /// <summary>    /// Required method for Designer support - do not modify    /// the contents of this method with the code editor.    /// </summary>    private void InitializeComponent()    {      //       // MainForm      //       this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);      this.ClientSize = new System.Drawing.Size(292, 266);      this.Name = "MainForm";      this.Text = "Main Window";    }    #endregion    /// <summary>    /// The main entry point for the application.    /// </summary>    [STAThread]    static void Main()     {      Application.Run(new MainForm());    }    //// BEGIN NEW CODE    /// <summary>    /// List of all forms that should be [in]active at the same time    /// </summary>    protected ArrayList coactiveFormList = new ArrayList();    /// <summary>    /// Add a form to the list    /// </summary>    public void RegisterCoactiveForm( Form form )    {      coactiveFormList.Add( form );    }    /// <summary>    /// Remove a form from the list    /// </summary>    public void UnregisterCoactiveForm( Form from )    {      coactiveFormList.Remove( from );    }    /// <summary>    /// Tests to see if any of the windows are active    /// </summary>    /// <returns>true if any of the windows are active</returns>    public bool IsAnyWindowActive()    {      foreach ( Form form in coactiveFormList )        if ( form == ActiveForm )          return true;      return false;    }    /// <summary>    /// Sends a message to update the non-client areas of the forms    /// </summary>    public void UpdateTitleBars()    {      bool active = IsAnyWindowActive();      foreach ( Form form in coactiveFormList )      {        if ( !form.IsDisposed )          Win32.SendMessage( form.Handle, Win32.WM_NCACTIVATE, active ? (IntPtr)Win32.TRUE : (IntPtr)Win32.FALSE, IntPtr.Zero );      }    }    protected override void WndProc(ref Message m)    {      if ( m.Msg == Win32.WM_ACTIVATE )      {        UpdateTitleBars();      }      base.WndProc( ref m );    }    //// END NEW CODE  }  //// BEGIN NEW CODE   /// <summary>  /// Toolbar class  /// </summary>  public class ToolbarForm : System.Windows.Forms.Form  {    public ToolbarForm( MainForm mainForm, string title )    {      // Make the window look like a toolbar      this.Text            = title;      this.Owner           = mainForm;      this.ShowInTaskbar   = false;      this.FormBorderStyle = FormBorderStyle.SizableToolWindow;      this.Size            = new System.Drawing.Size(300, 50);      // Register is as an active form      mainForm.RegisterCoactiveForm( this );      Show();    }    protected override void Dispose( bool disposing )    {      if( disposing )      {        MainForm mainForm = Owner as MainForm;        mainForm.UnregisterCoactiveForm( this );      }      base.Dispose( disposing );    }    protected override void WndProc(ref Message m)    {      if ( m.Msg == Win32.WM_ACTIVATE )      {        MainForm mainForm = Owner as MainForm;        mainForm.UpdateTitleBars();      }      base.WndProc( ref m );    }  }  /// <summary>  /// Glue to Win32 code/constants we need  /// </summary>  public class Win32  {    // Constants, mostly from Winuser.h    public const uint WM_ACTIVATE    = 0x0006;    public const uint WM_NCACTIVATE  = 0x0086;    public const uint TRUE           = 1;    public const uint FALSE          = 0;    [DllImport("user32.dll",CharSet=CharSet.Auto)]    public static extern int SendMessage( IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam );  }  //// END NEW CODE}


This may not be the best way but it should be simple enough to understand.

Basically it has a MainForm and 0 or more ToolbarForms. The MainForm has a list (coactiveFormList) to keep a list of all of the forms that need to be kept in sync. The main form is added to this list and each toolbar adds itself in its constructor and removes itself in its Dispose method.

If either the MainForm or any of the ToolbarForms get a WM_ACTIVATE message all of the forms are sent a WM_NCACTIVATE message to paint them the way we want them painted.

I marked the code I added from what you get with the wizard with //// [BEGIN|END] NEW CODE comments.

I hope this helps.
---CyberbrineDreamsSuspected implementation of the Windows idle loop: void idle_loop() { *((char*)rand()) = 0; }
Link
Link
I don't know how to ask you thank. :)
Anyway i do it, thanks.
Now i try your code and wish to make all things to work.
MauMan
MauMan
Not a problem. Good luck with your project...
---CyberbrineDreamsSuspected implementation of the Windows idle loop: void idle_loop() { *((char*)rand()) = 0; }

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.