#.net #system.drawing #drawstring #text-justify
#.net #system.drawing #drawstring #текст-выравнивание
Вопрос:
Мне нужно преобразовать строку в растровое изображение с полным выравниванием. Я знаю, что StringFormat .Выравнивание не поддерживает выравнивание по полному выравниванию. Итак, я ищу решение для рисования строки на растровом изображении с полным выравниванием. Rictextbox имеет полное выравнивание, но я думаю, что он использует WinAPI для выравнивания текста. Может быть, я могу нарисовать текст с помощью RichTextBox, но я не знаю, как получить растровое изображение элементов управления (скриншот) без отображения в форме. Есть ли какой-либо трюк или альтернативная сторонняя библиотека для System.Рисование.Графика?
Ответ №1:
Я использовал метод для рисования RichTextBox
на растровом изображении.
public class ExtendedRichTextBox : RichTextBox
{
private const double inch = 1440 / 96;//Not 14.4!!, believe me you can see someone use 1.44 but it doesn't work on big bitmaps. They round the 1440/96 as 14.4 but it works on only small sized works. use /96
public void DrawToBitmap(Graphics graphics, Rectangle bound)
{
Update(); // Ensure RTB fully painted
IntPtr hDC = graphics.GetHdc();
FORMATRANGE fmtRange;
RECT rect;
rect.Left = (int)Math.Ceiling(bound.X * inch);
rect.Top = (int)Math.Ceiling(bound.Y * inch);
rect.Right = (int)Math.Ceiling(bound.Right * inch);
rect.Bottom = (int)Math.Ceiling(bound.Bottom * inch);
int fromAPI;
fmtRange.hdc = hDC;
fmtRange.hdcTarget = hDC;
fmtRange.chrg.cpMin = 0;
fmtRange.chrg.cpMax = -1;
fmtRange.rc = rect;
fmtRange.rcPage = rect;
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
Marshal.StructureToPtr(fmtRange, lParam, false);
fromAPI = SendMessage(Handle, EM_FORMATRANGE, 0, lParam);
fromAPI = SendMessage(Handle, EM_FORMATRANGE, 1, lParam);
Marshal.FreeCoTaskMem(lParam);
fromAPI = SendMessage(Handle, EM_FORMATRANGE, 0, new IntPtr(0));
graphics.ReleaseHdc(hDC);
}
}
Вы можете найти реализации WinAPI на веб-сайте pinvoke. Но вы можете взять и здесь:
[DllImport("USER32.dll")]
private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
private const int WM_USER = 0x400;
private const int EM_FORMATRANGE = WM_USER 57;
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct CHARRANGE
{
public int cpMin;
public int cpMax;
}
[StructLayout(LayoutKind.Sequential)]
private struct FORMATRANGE
{
public IntPtr hdc;
public IntPtr hdcTarget;
public RECT rc;
public RECT rcPage;
public CHARRANGE chrg;
}
И вот пример использования.
var richtext = new ExtendedRichTextBox();
/*I've implemented a RichTextBox but it isn't realted with this question.
You can use simply RichTextBox. ExtendedRichTextBox has support rtl.*/
richtext.Font = font;
richtext.ForeColor = textColor;
richtext.Text = sometext;
richtext.SelectAll();
richtext.RightToLeft = rtl;
richtext.SelectionAlignment = align;
//Fix the rtl bug in RichTextBox
if (rtl == RightToLeft.Yes)
{
if (align == TextAlign.Center)
richtext.Rtf = richtext.Rtf.Replace(@"qr", @"qc");
else if (align == TextAlign.Left)
richtext.Rtf = richtext.Rtf.Replace(@"qr", @"ql");
else if (align == TextAlign.Justify)
richtext.Rtf = richtext.Rtf.Replace(@"qr", @"qj");
}
//textRect is where we want to put text in.
var tempBitmap = new Bitmap(textRect.Width, textRect.Height);
richtext.DrawToBitmap(Graphics.FromImage(tempBitmap), tempRect);
tempBitmap.MakeTransparent(richtext.BackColor);
graph.DrawImage(tempBitmap, panelRect.X, panelRect.Y);
Комментарии:
1. Что такое выравнивание и выравнивание текста в примере . решает ли ваше решение выравнивание по выравниванию ?