// * // * Copyright (C) 2008 Roger Alsing : http://www.RogerAlsing.com // * // * This library is free software; you can redistribute it and/or modify it // * under the terms of the GNU Lesser General Public License 2.1 or later, as // * published by the Free Software Foundation. See the included license.txt // * or http://www.gnu.org/copyleft/lesser.html for details. // * // * using System; using System.Drawing; using System.Windows.Forms; using Alsing.Windows; namespace Alsing.Drawing.GDI { public class GDISurface : GDIObject { private WeakReference _Control; protected IntPtr _OldBmp = IntPtr.Zero; protected IntPtr _OldBrush = IntPtr.Zero; protected IntPtr _OldFont = IntPtr.Zero; protected IntPtr _OldPen = IntPtr.Zero; protected IntPtr mhBMP; protected IntPtr mhDC; protected int mHeight; protected int mTabSize = 4; protected int mWidth; public GDISurface(IntPtr hDC) { mhDC = hDC; } public GDISurface(int width, int height, IntPtr hdc) { Init(width, height, hdc); Create(); } public GDISurface(int width, int height, GDISurface surface) { Init(width, height, surface.hDC); Create(); } public GDISurface(int width, int height, Control CompatibleControl, bool BindControl) { IntPtr hDCControk = Alsing.Windows.NativeMethods.ControlDC(CompatibleControl); Init(width, height, hDCControk); Alsing.Windows.NativeMethods.ReleaseDC(CompatibleControl.Handle, hDCControk); if (BindControl) { Control = CompatibleControl; } Create(); } private Control Control { get { if (_Control != null) return (Control) _Control.Target; return null; } set { _Control = new WeakReference(value); } } public IntPtr hDC { get { return mhDC; } } public IntPtr hBMP { get { return mhBMP; } } public Color TextForeColor { //map get,settextcolor get { return Alsing.Windows.NativeMethods.IntToColor(Alsing.Windows.NativeMethods.GetTextColor(mhDC)); } set { Alsing.Windows.NativeMethods.SetTextColor(mhDC, Alsing.Windows.NativeMethods.ColorToInt(value)); } } public Color TextBackColor { //map get,setbkcolor get { return Alsing.Windows.NativeMethods.IntToColor(Alsing.Windows.NativeMethods.GetBkColor(mhDC)); } set { Alsing.Windows.NativeMethods.SetBkColor(mhDC, Alsing.Windows.NativeMethods.ColorToInt(value)); } } public bool FontTransparent { //map get,setbkmode //1=transparent , 2=solid get { return Alsing.Windows.NativeMethods.GetBkMode(mhDC) < 2; } set { Alsing.Windows.NativeMethods.SetBkMode(mhDC, value ? 1 : 2); } } public GDIFont Font { get { var tm = new GDITextMetric(); var fontname = new string(' ', 48); Alsing.Windows.NativeMethods.GetTextMetrics(mhDC, ref tm); Alsing.Windows.NativeMethods.GetTextFace(mhDC, 79, fontname); var gf = new GDIFont { FontName = fontname, Bold = (tm.tmWeight > 400), Italic = (tm.tmItalic != 0), Underline = (tm.tmUnderlined != 0), Strikethrough = (tm.tmStruckOut != 0), Size = ((int) (((tm.tmMemoryHeight)/(double) tm.tmDigitizedAspectY)*72)) }; return gf; } set { IntPtr res = Alsing.Windows.NativeMethods.SelectObject(mhDC, value.hFont); if (_OldFont == IntPtr.Zero) _OldFont = res; } } protected void Init(int width, int height, IntPtr hdc) { mWidth = width; mHeight = height; mhDC = Alsing.Windows.NativeMethods.CreateCompatibleDC(hdc); mhBMP = Alsing.Windows.NativeMethods.CreateCompatibleBitmap(hdc, width, height); IntPtr ret = Alsing.Windows.NativeMethods.SelectObject(mhDC, mhBMP); _OldBmp = ret; if (mhDC == (IntPtr)0) throw new OutOfMemoryException("hDC creation FAILED!!"); if (mhDC == (IntPtr) 0) throw new OutOfMemoryException("hBMP creation FAILED!!"); } public Size MeasureString(string Text) { //map GetTabbedTextExtent //to be implemented return new Size(0, 0); } public Size MeasureTabbedString(string Text, int tabsize) { int ret = Alsing.Windows.NativeMethods.GetTabbedTextExtent(mhDC, Text, Text.Length, 1, ref tabsize); return new Size(ret & 0xFFFF, (ret >> 16) & 0xFFFF); } public void DrawString(string Text, int x, int y, int width, int height) { //to be implemented //map DrawText } public Size DrawTabbedString(string Text, int x, int y, int taborigin, int tabsize) { int ret = Alsing.Windows.NativeMethods.TabbedTextOut(mhDC, x, y, Text, Text.Length, 1, ref tabsize, taborigin); return new Size(ret & 0xFFFF, (ret >> 16) & 0xFFFF); } //--------------------------------------- //render methods , //render to dc , //render to control //render to gdisurface public void RenderTo(IntPtr hdc, int x, int y) { //map bitblt Alsing.Windows.NativeMethods.BitBlt(hdc, x, y, mWidth, mHeight, mhDC, 0, 0, (int)GDIRop.SrcCopy); } public void RenderTo(GDISurface target, int x, int y) { RenderTo(target.hDC, x, y); } public void RenderTo(GDISurface target, int SourceX, int SourceY, int Width, int Height, int DestX, int DestY) { Alsing.Windows.NativeMethods.BitBlt(target.hDC, DestX, DestY, Width, Height, hDC, SourceX, SourceY, (int)GDIRop.SrcCopy); } public void RenderToControl(int x, int y) { IntPtr hdc = Alsing.Windows.NativeMethods.ControlDC(Control); RenderTo(hdc, x, y); Alsing.Windows.NativeMethods.ReleaseDC(Control.Handle, hdc); } //--------------------------------------- public Graphics CreateGraphics() { return Graphics.FromHdc(mhDC); } //--------------------------------------- public void FillRect(GDIBrush brush, int x, int y, int width, int height) { APIRect gr; gr.top = y; gr.left = x; gr.right = width + x; gr.bottom = height + y; Alsing.Windows.NativeMethods.FillRect(mhDC, ref gr, brush.hBrush); } public void DrawFocusRect(int x, int y, int width, int height) { APIRect gr; gr.top = y; gr.left = x; gr.right = width + x; gr.bottom = height + y; Alsing.Windows.NativeMethods.DrawFocusRect(mhDC, ref gr); } public void FillRect(Color color, int x, int y, int width, int height) { var b = new GDIBrush(color); FillRect(b, x, y, width, height); b.Dispose(); } public void InvertRect(int x, int y, int width, int height) { APIRect gr; gr.top = y; gr.left = x; gr.right = width + x; gr.bottom = height + y; Alsing.Windows.NativeMethods.InvertRect(mhDC, ref gr); } public void DrawLine(GDIPen pen, Point p1, Point p2) { IntPtr oldpen = Alsing.Windows.NativeMethods.SelectObject(mhDC, pen.hPen); APIPoint gp; gp.x = 0; gp.y = 0; Alsing.Windows.NativeMethods.MoveToEx(mhDC, p1.X, p1.Y, ref gp); Alsing.Windows.NativeMethods.LineTo(mhDC, p2.X, p2.Y); Alsing.Windows.NativeMethods.SelectObject(mhDC, oldpen); } public void DrawLine(Color color, Point p1, Point p2) { var p = new GDIPen(color, 1); DrawLine(p, p1, p2); p.Dispose(); } public void DrawRect(Color color, int left, int top, int width, int height) { var p = new GDIPen(color, 1); DrawRect(p, left, top, width, height); p.Dispose(); } public void DrawRect(GDIPen pen, int left, int top, int width, int height) { DrawLine(pen, new Point(left, top), new Point(left + width, top)); DrawLine(pen, new Point(left, top + height), new Point(left + width, top + height)); DrawLine(pen, new Point(left, top), new Point(left, top + height)); DrawLine(pen, new Point(left + width, top), new Point(left + width, top + height + 1)); } public void Clear(Color color) { var b = new GDIBrush(color); Clear(b); b.Dispose(); } public void Clear(GDIBrush brush) { FillRect(brush, 0, 0, mWidth, mHeight); } public void Flush() { Alsing.Windows.NativeMethods.GdiFlush(); } protected override void Destroy() { if (_OldBmp != IntPtr.Zero) Alsing.Windows.NativeMethods.SelectObject(hDC, _OldBmp); if (_OldFont != IntPtr.Zero) Alsing.Windows.NativeMethods.SelectObject(hDC, _OldFont); if (_OldPen != IntPtr.Zero) Alsing.Windows.NativeMethods.SelectObject(hDC, _OldPen); if (_OldBrush != IntPtr.Zero) Alsing.Windows.NativeMethods.SelectObject(hDC, _OldBrush); if (mhBMP != (IntPtr) 0) Alsing.Windows.NativeMethods.DeleteObject(mhBMP); if (mhDC != (IntPtr) 0) Alsing.Windows.NativeMethods.DeleteDC(mhDC); mhBMP = (IntPtr) 0; mhDC = (IntPtr) 0; base.Destroy(); } public void SetBrushOrg(int x, int y) { APIPoint p; p.x = 0; p.y = 0; Alsing.Windows.NativeMethods.SetBrushOrgEx(mhDC, x, y, ref p); } } }