Bee Eee Blog

coding

Firing an event from within a thread. (At least one way)

by brian on Jan.16, 2008, under .NET, c#, coding

It took me forever to think of this easy method of firing an event from with a thread to the main thread.  In searching the web I found several complicated methods that either didn’t work or won’t worth the hassel.  But it turns out to be incredible simple and easy to do.  The only caveat is that the  event subscriber must be a System.Windows.Forms.Control or derived from one

Basically you just get the control target of the delegate and use it’s BeginInvoke or Invoke method and .Net does the rest.

        private void DoCommandFinished(Command cmd)
        {
            if ( null != CommandFinished )
            {
                System.Windows.Forms.Control c = CommandFinished.Target as System.Windows.Forms.Control;
                if (null != c)
                {
                    c.BeginInvoke(CommandFinished, cmd);
                }
            }
        }

I checked this method in my main window thread with the InvokeRequired function. It worked well.

Leave a Comment : more...

c# .Net double buffering — plus a little

by brian on Jan.08, 2008, under .NET, GUI, Uncategorized, c#, c# coding GUI, coding

It seems I left out something that helps the quality of the .Net provided form double buffering when you are doing custom drawing. Just override OnPaintBackground and leaving it blank. This prevents the background from being momentarily drawn when you don’t want it to be.

so again here’s how to enable double buffering on the form:

this.SetStyle(
          ControlStyles.AllPaintingInWmPaint |
          ControlStyles.UserPaint |
          ControlStyles.DoubleBuffer,true);

And then the override

protected override void OnPaintBackground(PaintEventArgs e)
{
}
2 Comments : more...

Free Asynchronous Message Queue

by brian on Jan.07, 2008, under GUI, c#, c# coding GUI, coding

If you’ve ever used a message queue to talk to different parts of your application you know that sometimes you run into a problem with tangled call stacks; especially if one message can causes another message to be sent.

However, in c# .Net there is a simple way to untangle the call stack of the message queue. Just use the BeginInvoke method. This unwinds the stack and uses a delegate to call your message reception handler from the control’s thread.

For instance:

delegate void PostOfficeMessageHandler( POMessage message );

public void SendMessage(Control Sender, POMessage Message)
{
    PostOfficeMessageHandler mh = recipients[Sender];
    Sender.BeginInvoke(mh, Message);
}

The advantages of this method of deliver are two fold. 1. The stack is unwound. 2. It makes message handler in the control’s threads solving some threading issues.

There are a couple of disadvantages. 1. Extra overhead. 2. If the message causes problems you may not know where it’s coming from!

Leave a Comment more...

Terrain 0.3 release.

by brian on Jan.05, 2008, under c#, coding, graphics, terrain

Well I finally had a little time today to work on my terrain generation software. It’s written in C++ using the SDL and SDL_gfx graphics libraries along with the Guichan GUI library. I had a bunch of fun adding relief shading. Basically it lightening or darkening the color based on the derivative (change in elevation). The steeper the positive change in elevation the brighter and the steeper the elevation loss the darker.

Anyway the results were really quite good, even a bit better than I expected. Here is an example:

Flat 2D results.

Flat 2d rendering

3d Rendering
3d (orthographic) Rendering of terrain

Anyway if you want to download a copy and try just go to http://bee-eee.com/ it’s under the software/terrain section.

Leave a Comment more...

C# capture the mouse — Get a global hook on the mouse.

by brian on Jan.04, 2008, under .NET, GUI, c#, coding

I’m developing a component that is like the sidebar in the Visual C# Express (c). To get it to appear when the mouse is over the control isn’t a problem, however I soon discovered that using the MouseEnter and MouseLeave didn’t work. When I went over child controls the MouseLeave would be called and cause my sidebar to collapse.


Instead I had to create a global mouse hook so that no matter what control the mouse was over I could get a mouse event.

First was the code to import the hook function:

// create a mouse over eventstatic int WH_MOUSE_LL = 14;
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string moduleName);

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int UnhookWindowsHookEx(IntPtr hhook);

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, uint wParam, IntPtr lParam);
delegate IntPtr HookProc(int nCode, uint wParam, IntPtr lParam);

private HookProc hookProc;
private IntPtr hook;

Here is the event handler

IntPtr LowLevelMouseProc(int nCode, uint wParam, IntPtr lParam)
{
    // get the current mouse position
    Point p = Cursor.Position;

    // convert to client rectangle to screen position
    Rectangle r = RectangleToScreen(ClientRectangle);

    // check to see if mouse is within control bounds
    bool exp = (p.Y > r.Top && p.Y < r.Bottom && p.X > r.Left && p.X < r.Right);

    // adjust the expansion
    if (exp != Expanded)
         Expanded = exp;

    // Finished with this
    return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}

Then the initialization code I put in the OnLoad event handler:

if (!DesignMode)
{
    hookProc = new HookProc(LowLevelMouseProc);
    hook = SetWindowsHookEx(WH_MOUSE_LL, hookProc, GetModuleHandle(null), 0);
}

And then code for closing in the OnHandleDestroyed event handler:

protected override void OnHandleDestroyed(EventArgs e)
{
        UnhookWindowsHookEx(hook);
        base.OnHandleDestroyed(e);
}

That should just about do it then. Now the UserControl can sense whether the mouse is overhead whether or not the mouse is over a child control.

Leave a Comment more...

Thread Safe calling to a form

by brian on Jan.03, 2008, under .NET, c#, c# coding GUI, coding

Here is an example of a thread-safe call into a form.

delegate void logCallback(string strLog);
private void log(string log)
{
  if (this.InvokeRequired)
  {
    logCallBack d = new logCallback(log);
    this.Invoke(d, log);
  }
  else
  {
     this.log( strLog );
  }
}

First we determine whether the overhead of an invoke can be dismissed. Then if we must invoke we first create an instance of the delegate. Then we call invoke. That’s it. Not too hard.

2 Comments more...

Hiding TabControl tabs in c#

by brian on Jan.02, 2008, under .NET, GUI, c#, coding

Finally found how this way online to hide the tabs on a tab control. Works pretty good. This will quite simplify my GUI coding and mean I won’t need to import a component. Thanks jeeftan

Rectangle rect = new RectangleF(
                        tabPage1.Left,
                        tabPage1.Top,
                        tabPage1.Width,
                        tabPage1.Height );
tabControl1.Region = new Region(rect);
Leave a Comment more...

C# Enabling Double buffering for a form.

by brian on Jan.01, 2008, under .NET, GUI, c#, coding

Ran across a simple how-to to enable double buffering for a form. Just put the code snippet in the form’s constructor after the InializeComponents

this.SetStyle(
            ControlStyles.AllPaintingInWmPaint |
            ControlStyles.UserPaint |
            ControlStyles.DoubleBuffer,true);

This gets rid of flicker, it also makes draw a tad slower.

Found the code at: http://www.bobpowell.net/doublebuffer.htm Thanks Bob Powell!

3 Comments more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...