private void PrepareDefaultStringFormat() { if (defaultStringFormat == IntPtr.Zero) { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipStringFormatGetGenericDefault(out defaultStringFormat)); } }
private void PrepareGraphics() { if (graphics == IntPtr.Zero) { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipCreateFromHDC(hdc, out graphics)); } }
public void Dispose() { if (graphics != IntPtr.Zero) { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteGraphics(graphics)); graphics = IntPtr.Zero; } if (defaultStringFormat != IntPtr.Zero) { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteStringFormat(defaultStringFormat)); graphics = IntPtr.Zero; } if (originalPen != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, originalPen); } if (originalBrush != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, originalBrush); } if (originalFont != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, originalFont); } }
private void DrawStringGDIPlus(Color color, FontConfig font, int x, int y, string text) { PrepareGraphics(); PrepareDefaultStringFormat(); GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipCreateFontFamilyFromName(font.FontFamily, IntPtr.Zero, out var fontFamilyPtr)); try { FontStyle fontStyle = GdiPlusAPI.GetFontStyle(font); GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipCreateFont(fontFamilyPtr, font.Size, fontStyle, Unit.UnitPixel, out var fontPtr)); try { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipCreateSolidFill(color.ToArgb(), out var brush)); try { RectF rect = new RectF(x, y, 0, 0); GdiPlusAPI.GdipDrawString(graphics, text, text.Length, fontPtr, ref rect, defaultStringFormat, brush); } finally { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteBrush(brush)); } } finally { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteFont(fontPtr)); } } finally { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteFontFamily(fontFamilyPtr)); } }
private void FillRectangleGDIPlus(Color color, int x, int y, int width, int height) { PrepareGraphics(); GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipCreateSolidFill(color.ToArgb(), out var brush)); try { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipFillRectangleI(graphics, brush, x, y, width, height)); } finally { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteBrush(brush)); } }
public void Run(INativeWindowStartupInfo startupInfo) { GdiplusStartupInput gdiPlusStartupInput = GdiplusStartupInput.CreateV1(); GdiPlusAPI.CheckStatus(GdiPlusAPI.GdiplusStartup(out var gdiPlusToken, ref gdiPlusStartupInput, out _)); IntPtr hInstance = Win32API.GetModuleHandleW(null); var windowClass = new WNDCLASSEXW(); windowClass.cbSize = (uint)Marshal.SizeOf <WNDCLASSEXW>(); windowClass.lpfnWndProc = WindowProc; windowClass.hInstance = hInstance; windowClass.lpszClassName = WindowClassName; var atom = Win32API.RegisterClassExW(ref windowClass); if (atom == 0) { throw new InvalidOperationException("Failed to register window class."); } try { const int CW_USEDEFAULT = unchecked ((int)0x80000000); IntPtr hwnd = Win32API.CreateWindowExW( 0, WindowClassName, startupInfo.Title, Win32WindowStyle.WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, startupInfo.Width, startupInfo.Height, IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero ); if (hwnd == IntPtr.Zero) { throw new InvalidOperationException("Failed to create a window."); } var window = new Win32Window(hwnd, startupInfo); windows.Add(hwnd, window); startupInfo.OnCreate(window); try { Win32API.ShowWindow(hwnd, Win32ShowWindowCommand.SW_SHOWNORMAL); MSG msg = new MSG(); int mRet; while ((mRet = Win32API.GetMessageW(ref msg, IntPtr.Zero, 0, 0)) != 0) { if (mRet == -1) { throw new InvalidOperationException("Failed to retrieve a message."); } Win32API.TranslateMessage(ref msg); Win32API.DispatchMessageW(ref msg); } } finally { // usually window will be destroyed before this point, unless error occurs if (Win32API.DestroyWindow(hwnd) == 0) { // todo: log warning ? } } } finally { if (Win32API.UnregisterClassW(WindowClassName, hInstance) == 0) { // todo: log warning } // todo: use separate finally for GDI+ GdiPlusAPI.GdiplusShutdown(gdiPlusToken); } }