I've been working on a mirrored RTL (right-to-left) version of Lutz Roeder's great CommandBar control for Windows Forms. There's one problem left, which I haven't solved yet, so I'd appreciate any comment on the matter.

This is my tweaked CommandBar:

 

As you may have noticed, I have custom-drawn the MenuItems. Aren't round rectangles just swell? (c:

Nothing wrong in this picture, but take a look at the next one. The phenomena surfaces when you hover with the mouse from the second menu to the third. The menu text disappears, and the hottracking remains. This is obviously a mirroring issue.

 

You may find interest in Middle East MSDN's article about mirroring (there are a few useful mirrored controls downloadable there). Mirroring a Windows Forms control is easy:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams CP;
        CP = base
.CreateParams;
        if(!base
.DesignMode)
            CP.ExStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
        return
CP;
    }
}

protected override CreateParams CreateParams
{
    get
    {
        CreateParams CP;
        CP = base
.CreateParams;
        if(!base
.DesignMode)
            CP.ExStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
        return
CP;
    }
}

protected override CreateParams CreateParams
{
    get
    {
        CreateParams CP;
        CP = base
.CreateParams;
        if(!base
.DesignMode)
            CP.ExStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
        return
CP;
    }
}

public const int WS_EX_LAYOUTRTL = 0x400000;
public const int WS_EX_NOINHERITLAYOUT = 0x100000;

const int WS_EX_LAYOUTRTL = 0x400000;
public const int WS_EX_NOINHERITLAYOUT = 0x100000;

 

You can also create a property to control this.

The above problem could be a bug in GDI+. I started to suspect that it was the culprit when the menu image, which was drawn using Graphics.DrawImage, appeared on the left side. In mirroring, the entire coordinate system of a window changes, so if you specify a point (x,y), the x would be the distance from the right, not from the left. Lutz used a function from ImageList (using P/Invoke) called ImageList_DrawIndirect to draw the “disabled” image, and I noticed they were drawn correctly. So I copied the code to the non-disabled part as well, and it worked. The bottom line is, that the Framework's DrawImage method couldn't handle a mirrored control, which made me wonder if this is the reason for the bug described above.

Wow, that was a long post. I hope it was clear enough. I will be releasing the source code here as soon as I get it working. I haven't found an RTL [Command/Re/Cool/]Bar for .NET anywhere else…

Tagged with:
 

Comments are closed.

Set your Twitter account name in your settings to use the TwitterBar Section.