GDI в другом окне - C#

Узнай цену своей работы

Формулировка задачи:

Доброе время суток, господа. Недавно начал изучать C#, так что не очень сильно ругайте, если что. Инет по этой теме уже облазил достаточно, но ничего не нашел. Задача в общем простая, но что-то не очень выходит:нужно вывести текст на рабочем столе из приложения .Net (C#). Для этого есть целый класс Api с импортированными в него структурами, и функциями API. Значит необходимые функции и структуры:
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);
.....................................................................................................
}
и есть процедура некоторого класса, использующего класс Api:
        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);
        }
Так вот, в коде создается шрифт, и выводится текст, с вышесозданным шрифтом. Текст-то выводится, но видимо, что-то не совсем так со шрифтом. Что бы я ни делал с этим шрифтом, какие бы параметры не устанавливал - текст выводится стандартным шрифтом. Где я ошибаюсь? Может что-то с преобразованием указателя IntPtr и структуры шрифта? Заранее спасибо.

Решение задачи: «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")

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.846 из 5
Похожие ответы