Closed Smurf-IV closed 4 months ago
Help needed with RTL Language Developers to check if Normal font in an RTL is revered like the Bug indicates above, or is "Normal" and only RTL languages are reversed, or it's the RTL font that does the standard reversing.
Help needed with RTL Language Developers to check if Normal font in an RTL is revered like the Bug indicates above, or is "Normal" and only RTL languages are reversed, or it's the RTL font that does the standard reversing.
Posting a pinned comment to Discord
Help needed with RTL Language Developers to check if Normal font in an RTL is revered like the Bug indicates above, or is "Normal" and only RTL languages are reversed, or it's the RTL font that does the standard reversing.
I'm not sure if I understand you correctly. Does my screenshot posted to the linked issue not help with this? If not, please try to elaborate and I'll be happy to help if it's still needed.
@Ahmed-Abdelhameed Help needed is for a developer who has RTL set as the OS, would be needed to work out why the internals of Krypton do not work, and then to apply the fix across all components and related dll's (Navigator / Ribbon / Extended / etc.) Your images are the same as the ones at the start of this bug.
But, you have also added that the Title elements should also be swapped around as well. 👍
@Smurf-IV Okay, here's my progress so far...
First of all, I don't think the OS language or RTL plays a role here since the RightToLeft
and RightToLeftLayout
properties can be toggled regardless. Please correct me if I missed something but I got the same behavior when I tested on Windows with Arabic language (RTL layout).
So, after a lot of investigating, I figured out the cause of the text (and buttons) being flipped/mirrored. I'm not submitting a PR though because I don't have a complete solution yet. I'm just posting what I found so far and maybe you or @Wagnerp can pick up from where I left as you both obviously have more experience with the internals of Krypton than me.
The problem begins in the VisualForm.OnNonClientPaint()
method, specifically at this line:
using (Graphics g = Graphics.FromHdc(_screenDC))
Here's the complete code for context:
// Create one the correct size and cache for future drawing
IntPtr hBitmap = PI.CreateCompatibleBitmap(hDC, windowBounds.Width, windowBounds.Height);
// If we managed to get a compatible bitmap
if (hBitmap != IntPtr.Zero)
{
try
{
// Must use the screen device context for the bitmap when drawing into the
// bitmap otherwise the Opacity and RightToLeftLayout will not work correctly.
PI.SelectObject(_screenDC, hBitmap);
// Drawing is easier when using a Graphics instance
using (Graphics g = Graphics.FromHdc(_screenDC))
{
WindowChromePaint(g, windowBounds);
}
// Now blit from the bitmap to the screen
PI.BitBlt(hDC, 0, 0, windowBounds.Width, windowBounds.Height, _screenDC, 0, 0, PI.SRCCOPY);
}
finally
{
// Delete the temporary bitmap
PI.DeleteObject(hBitmap);
}
}
else
{
// Drawing is easier when using a Graphics instance
using Graphics g = Graphics.FromHdc(hDC);
WindowChromePaint(g, windowBounds);
}
As you can see, it's using the screen's device context and only when that fails does it fall back to using the window's device context (i.e., hDC
) in the else
block. What I found out is that when creating a Graphics instance from the window's hdc, we get one that is already set up with RTL rendering (assuming RTL is enabled). However, when using the screen's device context, the Graphics instance is not set up for that (hence, the mirroring).
Now, I'm not entirely sure whether using the screen device context is necessary or how the caching mentioned in the code comment above works. If it's not necessary, then we can just get rid of the if
block and use the code that's in the else
block (i.e., Graphics.FromHdc(hDC)
). If it is necessary, then we need to set up the Graphics instance to (un-)mirror the rendering. This can be achieved using something like the following:
using (Graphics g = Graphics.FromHdc(_screenDC))
{
if (this.RightToLeftLayout && this.RightToLeft == RightToLeft.Yes)
{
g.TranslateTransform(windowBounds.Width, 0);
g.ScaleTransform(-1, 1);
}
WindowChromePaint(g, windowBounds);
}
Using either of the fixes described above causes the RTL layout to work correctly (icon and text on the right, displayed correctly/unmirrored, and the buttons are on the left):
However, there are two things I still didn't figure out.
1) Part of the form/border is still not displayed. I'm not sure why yet.
2) Even though the buttons are now on the left, the HitTest (triggered by WM_NCHITTEST
) still thinks they're on the right. So, the HitTest logic needs to be fixed too; I just didn't have enough time to investigate this part yet. Here's a demo that shows both issues:
As per comment in #786, button specs including help should be flipped along with the hit areas.
@Smurf-IV & @Ahmed-Abdelhameed These may help adjust the 'hit' targets, but they're not used in KForm
Hi @Smurf-IV,
Is this still being worked on?
Hi @Smurf-IV,
Is this still being worked on?
Hi @giduac
No, but the bug still remains. Hit test logic needs to be flipped plus a slice of the KForm is sliced off. You can see for yourself if you toggle the RightToLeftLayout
property.
Hi @Smurf-IV
Do we know where the bug is on this one, or is it a case of creating a 'special' KForm?
Do we know where the bug is on this one, or is it a case of creating a 'special' KForm?
@Ahmed-Abdelhameed: created a demo (As in the gif above), but did not supply it. So yes, "we" will need to replicate of not supplied
Do we know where the bug is on this one, or is it a case of creating a 'special' KForm?
@Ahmed-Abdelhameed: created a demo (As in the gif above), but did not supply it. So yes, "we" will need to replicate of not supplied
@Smurf-IV
I wonder if there's something in the WinForms repo that can be used?
Hi @Smurf-IV & @giduac
I think I've found something... look at https://github.com/dotnet/winforms/blob/main/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs, specifically lines 867 - 873...
Superseded by #1570
As seen with the fix for #313 Both Set:
RightAlign only:
RTL Only:
Originally posted by @Smurf-IV in https://github.com/Krypton-Suite/Standard-Toolkit/issues/313#issuecomment-918412005
And an old reference to an active Component Krypton Bug: https://github.com/ComponentFactory/Krypton/issues/94