Janyou's blog

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

C#  Code:

   
   1: using System;
   2: using System.Drawing;
   3: using System.Drawing.Imaging;
   4: using System.Runtime.InteropServices;
   5: using System.Windows.Forms;
   6:  
   7: public static class GraphicDrawRtfText
   8: {
   9:     private static RichTextBoxDrawer rtfDrawer;
  10:  
  11:  
  12:     public static void DrawRtfText(Graphics graphics, string rtf, Rectangle layoutArea, Rectangle targetArea)
  13:     {
  14:         if (rtfDrawer == null)
  15:         {
  16:             rtfDrawer = new RichTextBoxDrawer();
  17:         }
  18:         rtfDrawer.Rtf = rtf;
  19:         rtfDrawer.Draw(graphics, layoutArea, targetArea);
  20:     }
  21:  
  22:  
  23:     private class RichTextBoxDrawer : RichTextBox
  24:     {
  25:         //Code converted from code found here: http://support.microsoft.com/kb/812425/en-us
  26:  
  27:         //Convert the unit used by the .NET framework (1/100 inch) 
  28:         //and the unit used by Win32 API calls (twips 1/1440 inch)
  29:         private const double anInch = 14.4;
  30:  
  31:         protected override CreateParams CreateParams
  32:         {
  33:             get
  34:             {
  35:                 CreateParams createParams = base.CreateParams;
  36:                 if (SafeNativeMethods.LoadLibrary("msftedit.dll") != IntPtr.Zero)
  37:                 {
  38:                     createParams.ExStyle |= SafeNativeMethods.WS_EX_TRANSPARENT; // transparent
  39:                     createParams.ClassName = "RICHEDIT50W";
  40:                 }
  41:                 return createParams;
  42:             }
  43:         }
  44:  
  45:  
  46:         public void Draw(Graphics graphics, RectangleF layoutArea, RectangleF targetArea)
  47:         {
  48:             //Calculate the area to render.
  49:             SafeNativeMethods.RECT rectLayoutArea;
  50:             rectLayoutArea.Top = (int) (0*anInch);
  51:             rectLayoutArea.Bottom = (int) (targetArea.Bottom*anInch);
  52:             rectLayoutArea.Left = (int) (0*anInch);
  53:             rectLayoutArea.Right = (int) (targetArea.Right*anInch);
  54:  
  55:  
  56:             Bitmap Bmp = new Bitmap((int) layoutArea.Width,
  57:                                     (int) layoutArea.Height, PixelFormat.Format32bppArgb);
  58:  
  59:  
  60:             Graphics g = Graphics.FromImage(Bmp);
  61:             IntPtr hdc = g.GetHdc();
  62:  
  63:             //create a metafile, convert the size to himetrics
  64:             //Metafile metafile = new Metafile(hdc, new
  65:             //RectangleF(0, 0, layoutArea.Width * 26, layoutArea.Height * 26));
  66:  
  67:             Metafile metafile = new Metafile(hdc, new
  68:                                                       RectangleF(0, 0, layoutArea.Width, layoutArea.Height),
  69:                                              MetafileFrameUnit.Pixel);
  70:             g.ReleaseHdc(hdc);
  71:             g.Dispose();
  72:  
  73:             g = Graphics.FromImage(metafile);
  74:             IntPtr hDCEMF = g.GetHdc();
  75:  
  76:             SafeNativeMethods.FORMATRANGE fmtRange;
  77:             fmtRange.chrg.cpMax = -1; //Indicate character from to character to
  78:             fmtRange.chrg.cpMin = 0;
  79:             fmtRange.hdc = hDCEMF; //Use the same DC for measuring and rendering
  80:             fmtRange.hdcTarget = hDCEMF; //Point at printer hDC
  81:             fmtRange.rc = rectLayoutArea; //Indicate the area on page  to print
  82:             fmtRange.rcPage = rectLayoutArea; //Indicate size of page
  83:  
  84:             IntPtr wParam = IntPtr.Zero;
  85:             wParam = new IntPtr(1);
  86:  
  87:             //Get the pointer to the FORMATRANGE structure in memory
  88:             IntPtr lParam = IntPtr.Zero;
  89:             lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
  90:             Marshal.StructureToPtr(fmtRange, lParam, false);
  91:  
  92:             SafeNativeMethods.SendMessage(Handle,
  93:                                           SafeNativeMethods.EM_FORMATRANGE, wParam, lParam);
  94:  
  95:             //Free the block of memory allocated
  96:             Marshal.FreeCoTaskMem(lParam);
  97:  
  98:             //Release the device context handle obtained by a previous call
  99:             g.ReleaseHdc(hDCEMF);
 100:             g.Dispose();
 101:  
 102:  
 103:             graphics.DrawImage(metafile, layoutArea.Location);
 104:         }
 105:  
 106:         #region SafeNativeMethods
 107:  
 108:         private static class SafeNativeMethods
 109:         {
 110:             [DllImport("USER32.dll")]
 111:             public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
 112:  
 113:             [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
 114:             public static extern IntPtr LoadLibrary(string lpFileName);
 115:  
 116:             [StructLayout(LayoutKind.Sequential)]
 117:             public struct RECT
 118:             {
 119:                 public int Left;
 120:                 public int Top;
 121:                 public int Right;
 122:                 public int Bottom;
 123:             }
 124:  
 125:             [StructLayout(LayoutKind.Sequential)]
 126:             public struct CHARRANGE
 127:             {
 128:                 public int cpMin; //First character of range (0 for start of doc)
 129:                 public int cpMax; //Last character of range (-1 for end of doc)
 130:             }
 131:  
 132:             [StructLayout(LayoutKind.Sequential)]
 133:             public struct FORMATRANGE
 134:             {
 135:                 public IntPtr hdc; //Actual DC to draw on
 136:                 public IntPtr hdcTarget; //Target DC for determining text formatting
 137:                 public RECT rc; //Region of the DC to draw to (in twips)
 138:                 public RECT rcPage; //Region of the whole DC (page size) (in twips)
 139:                 public CHARRANGE chrg; //Range of text to draw (see earlier declaration)
 140:             }
 141:  
 142:             public const int WM_USER = 0x0400;
 143:             public const int EM_FORMATRANGE = WM_USER + 57;
 144:             public const int WS_EX_TRANSPARENT = 0x20;
 145:        
 146:         }
 147:  
 148:         #endregion
 149:     }
 150: }

 

RichTextBox's  zoom factor =1

image 

RichTextBox's zoom factor =2

image

note:

Uses a RichTextBox control and sends it an EM_FORMATRANGE that can draw some rft to the screen(image) .

But this method can't zoom the image(RichTextBox's zoom factor no effect).

So you can draw to a metafile  and set the ScaleTrasform  of the Graphics object and draw the metafile.

Of course,the output image is not perfect(not the same as RichTextBox's output).

 

Refences:

1.http://support.microsoft.com/kb/812425/zh-cn

2.http://www.andrewvos.com/?p=392

3.http://bytes.com/forum/thread829284.html

posted on 2008-10-22 15:44  janyou  阅读(1377)  评论(0编辑  收藏  举报