Custom ToolStrip renderer in C++/CLI - c++-cli

I want to make a custom renderer for ToolStrip, but all the manuals and guides are written in C#.
Here is an example https://www.codeproject.com/Articles/29497/Custom-Rendering-for-the-ToolStrip-MenuStrip-and-S
I tried porting this code to C++, but I didn't really succeed, since I don't really understand C#.
How to do it in C++/CLI?

That's if anyone needs my solution to the problem...
CustomColorTable.h
namespace YourNamespace
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class CustomColorTable : public System::Windows::Forms::ProfessionalColorTable {
public:
Color _color = Color::DeepPink;
public:
property Color MenuBorder
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemBorder
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemPressedGradientBegin
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemPressedGradientEnd
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemPressedGradientMiddle
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemSelected
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemSelectedGradientBegin
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuItemSelectedGradientEnd
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuStripGradientBegin
{
public: virtual Color get() override
{
return _color;
};
};
public:
property Color MenuStripGradientEnd
{
public: virtual Color get() override
{
return _color;
};
};
};
}
In your form with MenuStrip
#include "CustomColorTable.h"
namespace YourNamespace
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Resources;
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
this->MenuStrip1->RenderMode = System::Windows::Forms::ToolStripRenderMode::System;
this->MenuStrip1->Renderer = (gcnew System::Windows::Forms::ToolStripProfessionalRenderer(gcnew CustomColorTable()));
...
You can also do this for ToolStrip, you just need to change the names of the properties in CustomColorTable.h
Names of the properties can be found here

Related

How to use the `Ninject.Extensions.Factory` to dynamically generate factories for internals classes?

I need to use the Ninject.Extensions.Factory to generate the constructor of internal classes. Follow one example:
using Ninject.Extensions.Conventions;
using Ninject.Modules;
using Ninject.Extensions.Factory;
namespace ClassLibrary
{
using System;
namespace ClassLibrary
{
internal class Class1
{
public void Print(string message)
{
Console.WriteLine(message);
}
}
internal interface IClass1Factory
{
Class1 Create();
}
public interface IInterface2
{
void PrintMessage();
}
internal class Class2 : IInterface2
{
private readonly IClass1Factory _class1Factory;
public Class2(IClass1Factory class1Factory)
{
_class1Factory = class1Factory;
}
public void PrintMessage()
{
Class1 class1 = _class1Factory.Create();
class1.Print("Class2's IInterface2 'PrintMessage' implementation.");
}
}
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
Kernel.Bind(r => r
.FromThisAssembly()
.IncludingNonePublicTypes()
.SelectAllClasses()
.BindAllInterfaces());
Kernel.Bind<IClass1Factory>().ToFactory();
}
}
}
}
Application using the library:
using ClassLibrary.ClassLibrary;
using Ninject;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Load<MyNinjectModule>();
IInterface2 interface2 = kernel.Get<IInterface2>();
interface2.PrintMessage();
}
}
}
Even after include [assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)] I'm getting the following run tine error:
{"Type 'Castle.Proxies.IClass1FactoryProxy' from assembly
'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' is attempting to implement an inaccessible
interface.":""}
Any idea how to fix this?

Ninject issue with contextual binding and Lazy<T>

Ninject doesn't seem to correctly use WhenInjectedInto contstraint while also using Lazy<T>. Check the following example. The OnLandAttack and the OnLandAttackLazy should each be using the Samurai instance. But the Lazy<T> version ends up with the SpecialNinja instance. I'm guessing it's because it's not actually initialized in the contructor? But the type should still be correctly registered I would think. Am I missing something? FYI, this is using Ninject 3.2.2 and the Ninject.Extensions.Factory extension 3.2.1
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Load(new WarriorModule());
var amphibious = kernel.Get<IAttack>("amphibious");
amphibious.Execute();
var onLand = kernel.Get<IAttack>("onLand");
onLand.Execute();
var onLandLazy = kernel.Get<IAttack>("onLandLazy");
onLandLazy.Execute();
Console.ReadKey();
}
}
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWarrior>().To<Samurai>().WhenInjectedInto<OnLandAttack>();
Bind<IWarrior>().To<Samurai>().WhenInjectedInto<OnLandAttackLazy>();
Bind<IWarrior>().To<SpecialNinja>(); // <-- for everything else
Bind<IAttack>().To<AmphibiousAttack>().Named("amphibious");
Bind<IAttack>().To<OnLandAttack>().Named("onLand");
Bind<IAttack>().To<OnLandAttackLazy>().Named("onLandLazy");
}
}
public interface IWarrior
{
void Attack();
}
public class Samurai : IWarrior
{
public void Attack()
{
Console.WriteLine("\tSamurai Attack");
}
}
public class SpecialNinja : IWarrior
{
public void Attack()
{
Console.WriteLine("\tSpecial Ninja Attack");
}
}
public interface IAttack
{
void Execute();
}
public class OnLandAttack : IAttack
{
private readonly IWarrior warrior;
public OnLandAttack(IWarrior warrior)
{
this.warrior = warrior;
}
public void Execute()
{
Console.WriteLine("Begin OnLand attack");
this.warrior.Attack();
}
}
public class OnLandAttackLazy : IAttack
{
private readonly Lazy<IWarrior> warrior;
public OnLandAttackLazy(Lazy<IWarrior> warrior)
{
this.warrior = warrior;
}
public void Execute()
{
Console.WriteLine("Begin OnLandLazy attack");
this.warrior.Value.Attack();
}
}
public class AmphibiousAttack : IAttack
{
private readonly IWarrior warrior;
public AmphibiousAttack(IWarrior warrior)
{
this.warrior = warrior;
}
public void Execute()
{
Console.WriteLine("Begin Amphibious attack");
this.warrior.Attack();
}
}

how to check the an interface type in c++/cli

i want to convert that line from c# to c++/cli
Idocobj is IPart
IPart is an interface and Idocobj is an object.Are there any way to do this conversion.
i used this code :
Idocobj->GetType() == IPart::typeid
but it dosen't work
You can use dynamic_cast to check for "is". Here is an example:
using namespace System;
namespace NS
{
public interface class IFoo
{
void Test();
};
public ref class Foo : public IFoo
{
public: virtual void Test() {}
};
public ref class Bar
{
public: virtual void Test() {}
};
}
template<class T, class U>
bool isinst(U u) {
return dynamic_cast< T >(u) != nullptr;
}
int main()
{
NS::Foo^ f = gcnew NS::Foo();
NS::Bar^ b = gcnew NS::Bar();
if (isinst<NS::IFoo^>(f))
Console::WriteLine("f is IFoo");
if (isinst<NS::IFoo^>(b) == false)
Console::WriteLine("f is not IFoo");
Console::ReadKey();
}
But normally, you never use "is".... you always want to do something with the check... so normally you should use "as" which directly mapps to dynamic_cast:
NS::IFoo^ ifoo = dynamic_cast<NS::IFoo^>(f);
if (ifoo != nullptr)
{
// Do something...
ifoo->Test();
}

Changing default object scope with Ninject 2.2

Is it possible to change the default object scope in Ninject 2.2? If so, how is it done?
As far as I can tell you could override AddBinding() on the BindingRoot (StandardKernel or NinjectModule) and modify the ScopeCallback property on the binding object.
public class CustomScopeKernel : StandardKernel
{
public CustomScopeKernel(params INinjectModule[] modules)
: base(modules)
{
}
public CustomScopeKernel(
INinjectSettings settings, params INinjectModule[] modules)
: base(settings, modules)
{
}
public override void AddBinding(IBinding binding)
{
// Set whatever scope you would like to have as the default.
binding.ScopeCallback = StandardScopeCallbacks.Singleton;
base.AddBinding(binding);
}
}
This test should now pass (using xUnit.net)
public class DefaultScopedService { }
[Fact]
public void Should_be_able_to_change_default_scope_by_overriding_add_binding()
{
var kernel = new CustomScopeKernel();
kernel.Bind<DefaultScopedService>().ToSelf();
var binding = kernel.GetBindings(typeof(DefaultScopedService)).First();
binding.ScopeCallback.ShouldBe(StandardScopeCallbacks.Singleton);
}
The CustomScopeKernel will also work with Ninject modules.
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<DefaultScopedService>().ToSelf();
}
}
[Fact]
public void Should_be_able_to_change_default_scope_for_modules()
{
var module = new ServiceModule();
var kernel = new CustomScopeKernel(module);
var binding = kernel.GetBindings(typeof(DefaultScopedService)).First();
binding.ScopeCallback.ShouldBe(StandardScopeCallbacks.Singleton);
}

Business enum to DatContract Enum conversion in WCF

I have an enum
namespace Business
{
public enum Color
{
Red,Green,Blue
}
}
namespace DataContract
{
[DataContract]
public enum Color
{
[EnumMember]
Red,
[EnumMember]
Green,
[EnumMember]
Blue
}
}
I have the same enum as a datacontract in WCF with same values.
I need to convert the Business enum to the DataContract enum using a translator.
Hoe can I achieve this?
If you know both types at the time you need to do the conversion you can do something like:
Business.Color bc = Business.Color.Red;
DataContract.Color dcc = (DataContract.Color)Enum.Parse(typeof(DataContract.Color), bc.ToString())
Below, a more elegant style as the framework code.
public static class Enum<T> where T : struct
{
public static T Parse(string value)
{
return (T)Enum.Parse(typeof(T), value);
}
public static T Convert<U>(U value) where U : struct
{
if (!value.GetType().IsInstanceOfType(typeof(Enum)))
throw new ArgsValidationException("value");
var name = Enum.GetName(typeof (U), value);
return Parse(name);
}
}
//enum declaration
...
public void Main()
{
//Usage example
var p = Enum<DataContract.Priority>.Convert(myEntity.Priority);
}
And voilĂ !
You could use something like below:
public static class ColorTranslator
{
public static Business.Color TranslateColor(DataContract.Color from)
{
Business.Color to = new Business.Color();
to.Red = from.Red;
to.Green = from.Green;
to.Blue = from.Blue;
return to;
}
public static DataContract.Color TranslateColor(Business.Color from)
{
DataContract.Color to = new DataContract.Color();
to.Red = from.Red;
to.Green = from.Green;
to.Blue = from.Blue;
return to;
}
}