Simple way to Emit msil

This is a very simple example to introduce how to easily emit msil code on the fly with System.Reflexion.Emit.

1 – The simpler, the better
using System;
using System.Collections.Generic;
using System.Text;
namespace HelloWorldEmit
{
 class Program
 {
 static void Main(string[] args)
 {
 SayHello();
 }
 public static void SayHello()
 {
 Console.WriteLine("Hello world");
 }
 }
}
2- IL code

Once compiled, we will use .Net Reflector and see ILCode of SayHello method in the assembly.

.method public hidebysig static void SayHello() cil managed
{
    .maxstack 8
    L_0000: nop
    L_0001: ldstr "Hello world"
    L_0006: call void [mscorlib]System.Console::WriteLine(string)
    L_000b: nop
    L_000c: ret
}

To emit this msil code is not a simple task, you have to translate it in your code with method provided by System.Reflexion.Emit package.
If you like IL and you want to keep it clearly and your code look similar to MSIL you can use EmitHelper (« Emit with a human face ») of BLToolKitFramework.
The example below shows how we can be lazier with tool.

3- C# to Emit – Use ReflectionEmitLanguage Reflector pluggin

Fortunately ReflectionEmitLanguage pluggin on Reflector generate c# Emit library code ready to use.

That’s a screenshot of what we get when SayHello method is translated to ReflectionEmitLanguage with .net Reflector.

reflector Reflection.Emit-Language
reflector screenshot
4-Add and call emit code

Now we will use this peace of code to add emit code method to our main class and call it. We cannot add directly generated method to an existing type.
So we build an intermediate type to call it.


namespace HelloWorldEmit
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t = DefineType("HelloWorldEmit", "Program");
            MethodInfo method = t.GetMethod("SayHello",System.Reflection.BindingFlags.Static | BindingFlags.Public);
            method.Invoke(null, null);
        }

        /// <summary>
        /// Generate intermediate type to call
        /// </summary>
        /// <param name="assName"></param>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static Type DefineType(string assName,string typeName)
        {
            AssemblyName asmName = new AssemblyName(assName);
            AppDomain domain = AppDomain.CurrentDomain;
            AssemblyBuilder demoAssembly =
                domain.DefineDynamicAssembly(asmName,
                    AssemblyBuilderAccess.Run);
            ModuleBuilder demoModule =
                demoAssembly.DefineDynamicModule(asmName.Name);
            TypeBuilder generatedType = demoModule.DefineType(typeName, TypeAttributes.Public);
            MethodBuilder hello = BuildMethodSayHello(generatedType);
            return generatedType.CreateType();
        }

        /// <summary>
        /// Method copied pasted from reflector
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static MethodBuilder BuildMethodSayHello(TypeBuilder type)
        {
            // Declaring method builder
            // Method attributes
            System.Reflection.MethodAttributes methodAttributes =
                  System.Reflection.MethodAttributes.Public
                | System.Reflection.MethodAttributes.HideBySig
                | System.Reflection.MethodAttributes.Static;
            MethodBuilder method = type.DefineMethod("SayHello", methodAttributes);
            // Preparing Reflection instances
            MethodInfo method1 = typeof(Console).GetMethod(
                "WriteLine",
                BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{
            typeof(String)
            },
                null
                );
            // Setting return type
            method.SetReturnType(typeof(void));
            // Adding parameters
            ILGenerator gen = method.GetILGenerator();
            // Writing body
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ldstr, "Hello world");
            gen.Emit(OpCodes.Call, method1);
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ret);
            // finished
            return method;
        }
    }
}

Enable click on Toolbar or MenuStrip without focus on winform

This hack provide to enable click on Toolbar or Menu strip without focus on form container when you are not in mdi mode (IsMdiContainer = false on your main form).
This is very useful if you use transparency on multiple forms and you can’t use Multiple Document Interface functionality.
You can found this trick on paint.net class sources (PaintDotNet.SystemLayer.ToolStripEx) and more information on this blog

1 – Define winform native constants
/// <summary>
/// winform native constants
/// </summary>
public class NativeConstants
{
 internal const uint WM_MOUSEACTIVATE = 0x21;

 internal const uint MA_ACTIVATE = 1;

 internal const uint MA_ACTIVATEANDEAT = 2;

 internal const uint MA_NOACTIVATE = 3;

 internal const uint MA_NOACTIVATEANDEAT = 4;
}

2 – Override WndProc of System.Windows.Forms.ToolStrip
/// <summary>
/// Click through method implementation
/// </summary>
public class ToolStripCT : ToolStrip //or MenuStrip, BindingNavigator etc...
{
 public ToolStripCT(ToolStripItem[] toolStripItems)
 : base(toolStripItems)
 {
 }

 /// <summary>
 /// Overided for activete direct click on a toolstrip item
 /// and not default behavior :  set focus to the form container and fire event until you click again
 /// </summary>
 /// <param name="m"></param>
 protected override void WndProc(ref System.Windows.Forms.Message m)
 {
 base.WndProc(ref m);
 if (m.Msg == NativeConstants.WM_MOUSEACTIVATE &&
 m.Result == (IntPtr) NativeConstants.MA_ACTIVATEANDEAT)
 {
 m.Result = (IntPtr) NativeConstants.MA_ACTIVATE;
 }
 }
}