Jump to content
  • Advertisement
Sign in to follow this  
Link

[c#] create a floating toolbar

This topic is 4809 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 CODE
using System.Runtime.InteropServices;
//// END NEW CODE

namespace 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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!