GDI в другом окне - C#
Формулировка задачи:
Доброе время суток, господа. Недавно начал изучать C#, так что не очень сильно ругайте, если что. Инет по этой теме уже облазил достаточно, но ничего не нашел.
Задача в общем простая, но что-то не очень выходит:нужно вывести текст на рабочем столе из приложения .Net (C#). Для этого есть целый класс Api с импортированными в него структурами, и функциями API.
Значит необходимые функции и структуры:
и есть процедура некоторого класса, использующего класс Api:
Так вот, в коде создается шрифт, и выводится текст, с вышесозданным шрифтом. Текст-то выводится, но видимо, что-то не совсем так со шрифтом. Что бы я ни делал с этим шрифтом, какие бы параметры не устанавливал - текст выводится стандартным шрифтом. Где я ошибаюсь? Может что-то с преобразованием указателя IntPtr и структуры шрифта?
Заранее спасибо.
internal class Api
{
...................................................................
public enum FontClipPrecisions : byte
{
CLIP_DEFAULT_PRECIS = 0,
CLIP_CHARACTER_PRECIS = 1,
CLIP_STROKE_PRECIS = 2,
CLIP_MASK = 15,
CLIP_LH_ANGLES = (1 << 4),
CLIP_TT_ALWAYS = (2 << 4),
CLIP_EMBEDDED = (8 << 4)
}
public enum FontOutPrecisions : byte
{
OUT_DEFAULT_PRECIS = 0,
OUT_STRING_PRECIS = 1,
OUT_CHARACTER_PRECIS = 2,
OUT_STROKE_PRECIS = 3,
OUT_TT_PRECIS = 4,
OUT_DEVICE_PRECIS = 5,
OUT_RASTER_PRECIS = 6,
OUT_TT_ONLY_PRECIS = 7,
OUT_OUTLINE_PRECIS = 8,
OUT_SCREEN_OUTLINE_PRECIS = 9
}
public enum FontPitchAnnFamilies : byte
{
DEFAULT_PITCH = 0,
TMPF_FIXED_PITCH = 0x1,
FIXED_PITCH = 1,
VARIABLE_PITCH = 2,
WAVECAPS_PITCH = 0x1
}
public enum FontCharsets : byte
{
ANSI_CHARSET = 0,
DEFAULT_CHARSET = 1,
SYMBOL_CHARSET = 2,
MAC_CHARSET = 77,
SHIFTJIS_CHARSET = 128,
HANGEUL_CHARSET = 129,
JOHAB_CHARSET = 130,
CHINESEBIG5_CHARSET = 136,
GREEK_CHARSET = 161,
TURKISH_CHARSET = 162,
HEBREW_CHARSET = 177,
ARABIC_CHARSET = 178,
BALTIC_CHARSET = 186,
RUSSIAN_CHARSET = 204,
THAI_CHARSET = 222,
EASTEUROPE_CHARSET = 238,
OEM_CHARSET = 255
}
public enum FontWeigth : uint
{
FW_DONTCARE = 0,
FW_THIN = 100,
FW_EXTRALIGHT = 200,
FWJJLTRAUGHT = 200,
FWJJGHT = 300,
FW_NORMAL = 400,
FW_REGULAR = 400,
FW_MEDiUM = 500,
FW_SEMIBOLD = 600,
FW_DEMiBOLD = 600,
FW_BOLD = 700,
FW_EXTRABOLD = 800,
FW_ULTRABOLD = 800,
FWJHEAVY = 900,
FW_BLACK = 900
}
public enum FontQuality : byte
{
NONANTIALIASED_QUALITY = 3,
ANTIALIASED_QUALITY = 4,
CLEARTYPE_QUALITY =5,
CLEARTYPE_NATURAL_QUALITY = 6
}
public struct LOGFONT
{
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public FontWeigth lfWeight;
public byte lfItalic;
public byte lfUnderline;
public byte lfStrikeout;
public FontCharsets lfCharSet;
public FontOutPrecisions lfOutPrecision;
public FontClipPrecisions lfClipPrecision;
public FontQuality lfQuality;
public FontPitchAnnFamilies lfPitchAndFamily;
// Hack - Portable.NET doesn't support structure marshaling yet.
private byte lfFaceName_0;
private byte lfFaceName_1;
private byte lfFaceName_2;
private byte lfFaceName_3;
private byte lfFaceName_4;
private byte lfFaceName_5;
private byte lfFaceName_6;
private byte lfFaceName_7;
private byte lfFaceName_8;
private byte lfFaceName_9;
private byte lfFaceName_10;
private byte lfFaceName_11;
private byte lfFaceName_12;
private byte lfFaceName_13;
private byte lfFaceName_14;
private byte lfFaceName_15;
private byte lfFaceName_16;
private byte lfFaceName_17;
private byte lfFaceName_18;
private byte lfFaceName_19;
private byte lfFaceName_20;
private byte lfFaceName_21;
private byte lfFaceName_22;
private byte lfFaceName_23;
private byte lfFaceName_24;
private byte lfFaceName_25;
private byte lfFaceName_26;
private byte lfFaceName_27;
private byte lfFaceName_28;
private byte lfFaceName_29;
private byte lfFaceName_30;
private byte lfFaceName_31;
private static void SetFaceName(out byte dest, string value, int index)
{
if(value == null || index >= value.Length)
{
dest = 0;
}
else
{
dest = (byte)(value[index]);
}
}
public string lfFaceName
{
set
{
SetFaceName(out lfFaceName_0, value, 0);
SetFaceName(out lfFaceName_1, value, 1);
SetFaceName(out lfFaceName_2, value, 2);
SetFaceName(out lfFaceName_3, value, 3);
SetFaceName(out lfFaceName_4, value, 4);
SetFaceName(out lfFaceName_5, value, 5);
SetFaceName(out lfFaceName_6, value, 6);
SetFaceName(out lfFaceName_7, value, 7);
SetFaceName(out lfFaceName_8, value, 8);
SetFaceName(out lfFaceName_9, value, 9);
SetFaceName(out lfFaceName_10, value, 10);
SetFaceName(out lfFaceName_11, value, 11);
SetFaceName(out lfFaceName_12, value, 12);
SetFaceName(out lfFaceName_13, value, 13);
SetFaceName(out lfFaceName_14, value, 14);
SetFaceName(out lfFaceName_15, value, 15);
SetFaceName(out lfFaceName_16, value, 16);
SetFaceName(out lfFaceName_17, value, 17);
SetFaceName(out lfFaceName_18, value, 18);
SetFaceName(out lfFaceName_19, value, 19);
SetFaceName(out lfFaceName_20, value, 20);
SetFaceName(out lfFaceName_21, value, 21);
SetFaceName(out lfFaceName_22, value, 22);
SetFaceName(out lfFaceName_23, value, 23);
SetFaceName(out lfFaceName_24, value, 24);
SetFaceName(out lfFaceName_25, value, 25);
SetFaceName(out lfFaceName_26, value, 26);
SetFaceName(out lfFaceName_27, value, 27);
SetFaceName(out lfFaceName_28, value, 28);
SetFaceName(out lfFaceName_29, value, 29);
SetFaceName(out lfFaceName_30, value, 30);
SetFaceName(out lfFaceName_31, value, 31);
}
}
}
[DllImport("gdi32")] //ANSI
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool TextOutA(IntPtr hdc, int x, int y, string textstring, int charCount);
[DllImport("user32")]
public extern static System.IntPtr GetDC(System.IntPtr hwnd);
[DllImport("user32")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC);
[DllImport("gdi32")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32")]
public static extern IntPtr CreatePen(int fnPenStyle, int nWidth, int crColor);
[DllImport("gdi32")]
public static extern IntPtr CreateBrushIndirect(ref LOGBRUSH lplb);
.....................................................................................................
} public unsafe void DrawData()
{
hDTDC = Api.GetDC(IntPtr.Zero);
Api.LOGFONT f = new Api.LOGFONT();
f.lfHeight = 30;
f.lfWidth = 0;
f.lfEscapement = 0; //направление строки
f.lfHeight = 400; //один пункт=20 твипов
f.lfWidth = 4;
f.lfWeight = Api.FontWeigth.FW_BOLD;
f.lfItalic = 1;
f.lfUnderline = 0;
f.lfCharSet = Api.FontCharsets.RUSSIAN_CHARSET;
f.lfOrientation = 0;
f.lfQuality = 0;
f.lfClipPrecision = Api.FontClipPrecisions.CLIP_DEFAULT_PRECIS;
f.lfOutPrecision = Api.FontOutPrecisions.OUT_TT_ONLY_PRECIS;
f.lfFaceName = "Bodoni MT Black";
IntPtr prevFont = Api.CreateFontIndirectA(ref f);
IntPtr pf = new IntPtr(&f);
Api.SelectObject(hDTDC, pf);
Api.TextOutA(hDTDC, 200, 500, "Здравствуй мир!", 15);
Api.SelectObject(hDTDC, prevFont);
Api.DeleteObject(pf);
Api.ReleaseDC(IntPtr.Zero, hDTDC);
}Решение задачи: «GDI в другом окне»
textual
Листинг программы
Api.LOGFONT f = new Api.LOGFONT(); //Создали логфонт
...
IntPtr prevFont = Api.CreateFontIndirectA(ref f);//На основе логфонта создали реальный объект HFONT
...
Api.SelectObject(hDTDC, prevFont);//А теперь мы его выделяем в наш HDC("can be selected as the current font for any device context")