Friday, January 11, 2008

TextBoxRevolution

Precisei fazer uma TextBox com fundo transparente e também imagem de fundo, totalmente customizada, procurei na net e encontrei uma base, então resolvi melhorar e organizar bem o código, e esta ai o resultado.

Uma coisa que as vezes faz falta no Windows.Form, é o Attributes nos Controls, algo que temos no Asp.Net mas não no Windows.Form, e como eu também precisava deste recurso na TextBox então resolvi implementar isto também, por isso esta TextBox também suporta o Attributes, TextBoxRevolution.Attributes, assim já é possível anexar outros objetos ao Control.

[CODE]
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace TextBoxRevolutionTest
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form form = new Form();
form.Text = "TextBoxRevolution";
form.Width = 450;
form.Height = 250;
string text = @"
The Foundations of the GPL
Nobody should be restricted by the software they use. There are four freedoms that every user should have:
* the freedom to use the software for any purpose,
* the freedom to share the software with your friends and neighbors,
* the freedom to change the software to suit your needs, and
* the freedom to share the changes you make.
When a program offers users all of these freedoms, we call it free software.
Developers who write software can release it under the terms of the GNU GPL. When they do, it will be free software and stay free software, no matter who changes or distributes the program. We call this copyleft: the software is copyrighted, but instead of using those rights to restrict users like proprietary software does, we use them to ensure that every user has freedom.
";
TextBoxRevolution textBoxRevolution = new TextBoxRevolution();
textBoxRevolution.Name = "textBoxRevolution";
textBoxRevolution.Dock = DockStyle.Fill;
textBoxRevolution.Control.Name = "textBoxRevolutionOut";
textBoxRevolution.Transparent = true;
textBoxRevolution.Height = 0;
textBoxRevolution.TopMargin = 5;
textBoxRevolution.BorderStyle = BorderStyle.None;
textBoxRevolution.Multiline = true;
textBoxRevolution.ForeColor = Color.FromArgb(0, 0, 0);
textBoxRevolution.Text = text;
textBoxRevolution.Select(0, 0);
textBoxRevolution.Background += new TextBoxRevolution.OnBackground(textBoxRevolution_Background);
form.Controls.Add(textBoxRevolution);
Application.Run(form);
}
static Image textBoxRevolution_Background(TextBoxRevolution textBoxRevolution)
{
Color topColor = Color.FromArgb(235, 237, 241);
Color bottomColor = Color.FromArgb(225, 229, 232);
if (textBoxRevolution.Control.Name.EndsWith("Over"))
{
topColor = Color.FromArgb(249, 247, 255);
bottomColor = Color.FromArgb(238, 234, 255);
}
Bitmap img = new Bitmap(textBoxRevolution.Width, textBoxRevolution.Height);
Graphics g = Graphics.FromImage(img);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.FillRectangle(new SolidBrush(topColor), 0, 0, textBoxRevolution.Width, textBoxRevolution.Height);
g.FillRectangle(new SolidBrush(bottomColor), 0, textBoxRevolution.Height / 2, textBoxRevolution.Width - 50, textBoxRevolution.Height / 2);
g.FillEllipse(new SolidBrush(bottomColor), textBoxRevolution.Width - 100, textBoxRevolution.Height / 2, 100, 20);
g.FillRectangle(new SolidBrush(bottomColor), textBoxRevolution.Width - 50, (textBoxRevolution.Height / 2) + 10, textBoxRevolution.Width, textBoxRevolution.Height / 2);
return img;
}
}
}

namespace System.Windows.Forms
{
public class TextBoxRevolution : TextBox
{

public delegate Image OnBackground(TextBoxRevolution textBoxRevolution);
public event OnBackground Background;

PictureBox pictureBox = null;
Dictionary<string, object> attributes = new Dictionary<string, object>();

public TextBoxRevolution()
{
pictureBox = new PictureBox();
pictureBox.Dock = DockStyle.Fill;
this.ShortcutsEnabled = false;
this.Cursor = Cursors.Arrow;
this.Controls.Add(pictureBox);
}

public Dictionary<string, object> Attributes
{
get
{
return attributes;
}
set
{
attributes = value;
}
}

bool transparent = false;
public bool Transparent
{
get
{
return transparent;
}
set
{
transparent = value;
}
}

public PictureBox Control
{
get
{
return pictureBox;
}
}

int topMargin = 0;
public int TopMargin
{
get
{
return topMargin * -1;
}
set
{
topMargin = value;
}
}

protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case Win32.WM_PAINT:
Draw();
break;
case Win32.WM_HSCROLL:

case Win32.WM_VSCROLL:
this.Invalidate();
break;
}
}

public void Draw()
{
Bitmap bmpCaptured = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
Bitmap bmpResult = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
Rectangle r = new Rectangle(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height);
Win32.CaptureWindow(this, ref bmpCaptured);
if (Transparent)
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;
}
ImageAttributes imgAttrib = new ImageAttributes();

if (Transparent)
{
ColorMap[] colorMap = new ColorMap[1];
colorMap[0] = new ColorMap();
colorMap[0].OldColor = Color.White;
colorMap[0].NewColor = Color.Transparent;
imgAttrib.SetRemapTable(colorMap);
}
Graphics g = Graphics.FromImage(bmpResult);


try
{
g.DrawImage(Background(this), r, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, GraphicsUnit.Pixel, imgAttrib);
}
catch
{
}
g.DrawImage(bmpCaptured, r, 0, TopMargin, this.ClientRectangle.Width, this.ClientRectangle.Height, GraphicsUnit.Pixel, imgAttrib);
g.Dispose();
pictureBox.Image = (Image)bmpResult.Clone();
}

public int ContentHeight
{
get
{
return LinesCount * base.Font.Height;
}
}

public int LinesCount
{
get
{
const int EM_GETLINECOUNT = 186;
int lineCount = Win32.SendMessage(base.Handle, EM_GETLINECOUNT, IntPtr.Zero, IntPtr.Zero);
return lineCount + 1;
}
}
}

public class Win32
{
public const int WM_MOUSEMOVE = 0x0200;
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_LBUTTONUP = 0x0202;
public const int WM_RBUTTONDOWN = 0x0204;
public const int WM_LBUTTONDBLCLK = 0x0203;
public const int WM_MOUSELEAVE = 0x02A3;
public const int WM_PAINT = 0x000F;
public const int WM_ERASEBKGND = 0x0014;
public const int WM_PRINT = 0x0317;
public const int EN_HSCROLL = 0x0601;
public const int EN_VSCROLL = 0x0602;
public const int WM_HSCROLL = 0x0114;
public const int WM_VSCROLL = 0x0115;
public const int EM_GETSEL = 0x00B0;
public const int EM_LINEINDEX = 0x00BB;
public const int EM_LINEFROMCHAR = 0x00C9;
public const int EM_POSFROMCHAR = 0x00D6;
[DllImport("USER32.DLL", EntryPoint = "PostMessage")]
public static extern bool PostMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("USER32.DLL", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("USER32.DLL", EntryPoint = "GetCaretBlinkTime")]
public static extern uint GetCaretBlinkTime();
public const int WM_PRINTCLIENT = 0x0318;
public const long PRF_CHECKVISIBLE = 0x00000001L;
public const long PRF_NONCLIENT = 0x00000002L;
public const long PRF_CLIENT = 0x00000004L;
public const long PRF_ERASEBKGND = 0x00000008L;
public const long PRF_CHILDREN = 0x00000010L;
public const long PRF_OWNED = 0x00000020L;
public static bool CaptureWindow(System.Windows.Forms.Control control, ref System.Drawing.Bitmap bitmap)
{
Graphics g2 = Graphics.FromImage(bitmap);
int meint = (int)(PRF_CLIENT | PRF_ERASEBKGND);
System.IntPtr meptr = new System.IntPtr(meint);
System.IntPtr hdc = g2.GetHdc();
Win32.SendMessage(control.Handle, Win32.WM_PRINT, hdc, meptr);
g2.ReleaseHdc(hdc);
g2.Dispose();
return true;
}
}
}
[/CODE]

No comments:

Post a Comment