c#类Word项目编号功能(100分给一人,绝不食言)

wolfmvp 2009-02-18 09:46:46
问题说明:
1、在RichTextBox控件中实现,首先说明一下,不是实现项目符号的功能,而是实现项目编号(针对RTF文件)…
2、项目编号的类型任意,可以使英文字母、数字、罗马数字均可
3、大概操作思路为:在RichTextBox控件下有一个Button按钮,先选定RichTextBox控件中的文本内容,然后单击Button按钮,预期出现的效果:文本全部左对齐,在各行文本的最左边有编号出现(编号任意,由得分者设定);当我再次选定有编号的文本时,以前设定的文本编号消失,没有设定的出现项目编号(如果还有什么不明白的,就打开Word熟悉一下项目编号功能,操作文件的后缀名不是.doc文件,是.RTF文件)…
4、最后补充一点:本程序是C# WinForm下的,开发工具最好选用VS2008(程序代码需要有注释)
5、本帖3日之内必然结贴,无论有没有结果…
...全文
870 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
congzhongxiao_57 2010-11-12
  • 打赏
  • 举报
回复
试试自己登陆了没
顶顶更健康
jixiaojie 2010-02-09
  • 打赏
  • 举报
回复
登陆了为啥还看不到内容?
liuningjian 2009-02-28
  • 打赏
  • 举报
回复
http://www.codeproject.com/KB/miscctrl/RichTextBoxEx.aspx,这个能够解决你的问题。
wolfmvp 2009-02-28
  • 打赏
  • 举报
回复
上面有实现项目编号的代码,全部代码为扩展RichTextBox控件功能…
wolfmvp 2009-02-28
  • 打赏
  • 举报
回复
接上文的代码:

public void NumberedBullet(bool TurnOn)
{
PARAFORMAT2 paraformat1 = new PARAFORMAT2();
paraformat1.dwMask = (int)(PFM_NUMBERING | PFM_OFFSET | PFM_NUMBERINGSTART |
PFM_NUMBERINGSTYLE | PFM_NUMBERINGTAB);
if (!TurnOn)
{
paraformat1.wNumbering = 0;
paraformat1.dxOffset = 0;
}
else
{
paraformat1.wNumbering = (short)_BulletType;
paraformat1.dxOffset = this.BulletIndent;
paraformat1.wNumberingStyle = (short)_BulletStyle;
paraformat1.wNumberingStart = _BulletNumberStart;
paraformat1.wNumberingTab = 500;
}
SendMessage(new System.Runtime.InteropServices.HandleRef(this, this.Handle),
0x447, 0, paraformat1);
}

#endregion

#region Printing
//Convert the unit used by the .NET framework (1/100 inch)
//and the unit used by Win32 API calls (twips 1/1440 inch)
private const double anInch = 14.4;

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}

[StructLayout(LayoutKind.Sequential)]
private struct CHARRANGE
{
public int cpMin; //First character of range (0 for start of doc)
public int cpMax; //Last character of range (-1 for end of doc)
}

[StructLayout(LayoutKind.Sequential)]
private struct FORMATRANGE
{
public IntPtr hdc; //Actual DC to draw on
public IntPtr hdcTarget; //Target DC for determining text formatting
public RECT rc; //Region of the DC to draw to (in twips)
public RECT rcPage; //Region of the whole DC (page size) (in twips)
public CHARRANGE chrg; //Range of text to draw (see earlier
//declaration)
}

private const int WM_USER = 0x0400;
private const int EM_FORMATRANGE = WM_USER + 57;

[DllImport("USER32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp,
IntPtr lp);

// Render the contents of the RichTextBox for printing
// Return the last character printed + 1 (printing start from this point for
// next page)
public int Print(int charFrom, int charTo, PrintPageEventArgs e)
{
//Calculate the area to render and print
RECT rectToPrint;
rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);
rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);
rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);
rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);

//Calculate the size of the page
RECT rectPage;
rectPage.Top = (int)(e.PageBounds.Top * anInch);
rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);
rectPage.Left = (int)(e.PageBounds.Left * anInch);
rectPage.Right = (int)(e.PageBounds.Right * anInch);

IntPtr hdc = e.Graphics.GetHdc();

FORMATRANGE fmtRange;
fmtRange.chrg.cpMax = charTo; //Indicate character from to character to
fmtRange.chrg.cpMin = charFrom;
fmtRange.hdc = hdc; //Use the same DC for measuring and rendering
fmtRange.hdcTarget = hdc; //Point at printer hDC
fmtRange.rc = rectToPrint; //Indicate the area on page to print
fmtRange.rcPage = rectPage; //Indicate size of page

IntPtr res = IntPtr.Zero;

IntPtr wparam = IntPtr.Zero;
wparam = new IntPtr(1);

//Get the pointer to the FORMATRANGE structure in memory
IntPtr lparam = IntPtr.Zero;
lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
Marshal.StructureToPtr(fmtRange, lparam, false);

//Send the rendered data for printing
res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);

//Free the block of memory allocated
Marshal.FreeCoTaskMem(lparam);

//Release the device context handle obtained by a previous call
e.Graphics.ReleaseHdc(hdc);

//Return last + 1 character printer
return res.ToInt32();
}



private PrintDocument _PrintDocument;

public PrintDocument PrintDocument
{
get { return _PrintDocument; }
set
{
_PrintDocument = value;
if (_PrintDocument != null)
{
_PrintDocument.BeginPrint += new PrintEventHandler(
_PrintDocument_BeginPrint);
_PrintDocument.PrintPage += new PrintPageEventHandler(
_PrintDocument_PrintPage);
}
}
}

void _PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
{
// Print the content of RichTextBox. Store the last character printed.
checkPrint = this.Print(checkPrint, this.TextLength, e);

// Check for more pages
if (checkPrint < this.TextLength)
e.HasMorePages = true;
else
e.HasMorePages = false;
}

void _PrintDocument_BeginPrint(object sender, PrintEventArgs e)
{
checkPrint = 0;
}


int checkPrint = 0;

#endregion

#region Search
int SearchIndex = 0;
public void Search(string SearchText)
{
//MDI form search term always holds precedence than the local search term
//as the user might be interested in searchning same term in more than
//one windows...

SearchIndex = (SearchIndex >= 0 ? SearchIndex : 0);

if (SearchIndex >= Text.Length)
MessageBox.Show(
"Reached Page End \nUnable to find Specified Text \"" + SearchText + "\"");

if (this.Text.Length > 0 && !string.IsNullOrEmpty(SearchText))
{
this.Focus();
SearchIndex = this.Find(SearchText, SearchIndex, RichTextBoxFinds.None);
if (SearchIndex == -1)
MessageBox.Show(
"Reached Page End \nUnable to find Specified Text \"" + SearchText + "\"");
else
SearchIndex += SearchText.Length;
}

}


public void Lock()
{
this.ReadOnly = true;
this.BackColor = SystemColors.Info;
}

public void Unlock()
{
this.ReadOnly = false;
this.BackColor = SystemColors.Window;

}


#endregion

}

}

//
wolfmvp 2009-02-28
  • 打赏
  • 举报
回复
谢谢楼上的兄弟,马上兑换诺言,CSDN果然很强悍…

//
// using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Printing;

namespace RichTextBoxEx.Controls
{

public class RichTextBoxEx : RichTextBox
{

#region BULLETING

[StructLayout(LayoutKind.Sequential)]
private class PARAFORMAT2
{
public int cbSize;
public int dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public int[] rgxTabs;

public int dySpaceBefore; // Vertical spacing before para
public int dySpaceAfter; // Vertical spacing after para
public int dyLineSpacing; // Line spacing depending on Rule
public short sStyle; // Style handle
public byte bLineSpacingRule; // Rule for line spacing (see tom.doc)
public byte bOutlineLevel; // Outline Level
public short wShadingWeight; // Shading in hundredths of a per cent
public short wShadingStyle; // Byte 0: style, nib 2: cfpat, 3: cbpat
public short wNumberingStart; // Starting value for numbering
public short wNumberingStyle; // Alignment, Roman/Arabic, (), ), ., etc.
public short wNumberingTab; // Space bet 1st indent and 1st-line text
public short wBorderSpace; // Border-text spaces (nbl/bdr in pts)
public short wBorderWidth; // Pen widths (nbl/bdr in half twips)
public short wBorders; // Border styles (nibble/border)

public PARAFORMAT2()
{
this.cbSize = Marshal.SizeOf(typeof(PARAFORMAT2));
}
}

#region PARAFORMAT MASK VALUES
// PARAFORMAT mask values
private const uint PFM_STARTINDENT = 0x00000001;
private const uint PFM_RIGHTINDENT = 0x00000002;
private const uint PFM_OFFSET = 0x00000004;
private const uint PFM_ALIGNMENT = 0x00000008;
private const uint PFM_TABSTOPS = 0x00000010;
private const uint PFM_NUMBERING = 0x00000020;
private const uint PFM_OFFSETINDENT = 0x80000000;

// PARAFORMAT 2.0 masks and effects
private const uint PFM_SPACEBEFORE = 0x00000040;
private const uint PFM_SPACEAFTER = 0x00000080;
private const uint PFM_LINESPACING = 0x00000100;
private const uint PFM_STYLE = 0x00000400;
private const uint PFM_BORDER = 0x00000800; // (*)
private const uint PFM_SHADING = 0x00001000; // (*)
private const uint PFM_NUMBERINGSTYLE = 0x00002000; // RE 3.0
private const uint PFM_NUMBERINGTAB = 0x00004000; // RE 3.0
private const uint PFM_NUMBERINGSTART = 0x00008000; // RE 3.0

private const uint PFM_RTLPARA = 0x00010000;
private const uint PFM_KEEP = 0x00020000; // (*)
private const uint PFM_KEEPNEXT = 0x00040000; // (*)
private const uint PFM_PAGEBREAKBEFORE = 0x00080000; // (*)
private const uint PFM_NOLINENUMBER = 0x00100000; // (*)
private const uint PFM_NOWIDOWCONTROL = 0x00200000; // (*)
private const uint PFM_DONOTHYPHEN = 0x00400000; // (*)
private const uint PFM_SIDEBYSIDE = 0x00800000; // (*)
private const uint PFM_TABLE = 0x40000000; // RE 3.0
private const uint PFM_TEXTWRAPPINGBREAK = 0x20000000; // RE 3.0
private const uint PFM_TABLEROWDELIMITER = 0x10000000; // RE 4.0

// The following three properties are read only
private const uint PFM_COLLAPSED = 0x01000000; // RE 3.0
private const uint PFM_OUTLINELEVEL = 0x02000000; // RE 3.0
private const uint PFM_BOX = 0x04000000; // RE 3.0
private const uint PFM_RESERVED2 = 0x08000000; // RE 4.0

public enum AdvRichTextBulletType
{
Normal = 1,
Number = 2,
LowerCaseLetter = 3,
UpperCaseLetter = 4,
LowerCaseRoman = 5,
UpperCaseRoman = 6
}

public enum AdvRichTextBulletStyle
{
RightParenthesis = 0x000,
DoubleParenthesis = 0x100,
Period = 0x200,
Plain = 0x300,
NoNumber = 0x400
}
#endregion

[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam,
[In, Out, MarshalAs(UnmanagedType.LPStruct)] PARAFORMAT2 lParam);

private AdvRichTextBulletType _BulletType = AdvRichTextBulletType.Number;
private AdvRichTextBulletStyle _BulletStyle = AdvRichTextBulletStyle.Period;
private short _BulletNumberStart = 1;


public AdvRichTextBulletType BulletType
{
get { return _BulletType; }
set
{
_BulletType = value;
NumberedBullet(true);
}
}
public AdvRichTextBulletStyle BulletStyle
{
get { return _BulletStyle; }
set
{
_BulletStyle = value;
NumberedBullet(true);
}
}
wolfmvp 2009-02-27
  • 打赏
  • 举报
回复
真的没有牛人解决吗?希望CSDN上不会让我失望…
哈哈潜伏哥 2009-02-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wangping_li 的回复:]
RichTextBox有一个Bullet属性可以实现项目编号
这是MSDN的示例,可以参考下:
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.richtextbox.bulletindent.aspx
但是特殊符号和数字编号就得自己扩展了
[/Quote]

学习了。
cgpu456 2009-02-24
  • 打赏
  • 举报
回复
顶一下
wolfmvp 2009-02-24
  • 打赏
  • 举报
回复
再次期待,我需要源代码,思路我也有,但是将问题连贯起来时有困难…
所以还是希望有N人能贴出代码,万分感谢…
jacklee_008 2009-02-24
  • 打赏
  • 举报
回复
试试自动化吧
wolfmvp 2009-02-24
  • 打赏
  • 举报
回复
又可以实现的本楼主愿意将次200分奉送……
期待问题的解决……
睡神在睡觉 2009-02-21
  • 打赏
  • 举报
回复
没看明白要干啥。。。帮顶!
dingwb 2009-02-21
  • 打赏
  • 举报
回复
关注!
uncleson88 2009-02-20
  • 打赏
  • 举报
回复
rt1.SelectionBullet = true;

wangping_li 2009-02-20
  • 打赏
  • 举报
回复
RichTextBox有一个Bullet属性可以实现项目编号
这是MSDN的示例,可以参考下:
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.richtextbox.bulletindent.aspx
但是特殊符号和数字编号就得自己扩展了
wetcom 2009-02-20
  • 打赏
  • 举报
回复
得了解RTF文件格式定义吧,把这个搞清楚了你那个问题就好办了
baiyunyinv 2009-02-20
  • 打赏
  • 举报
回复
关注!!
iwxiaot 2009-02-20
  • 打赏
  • 举报
回复
不知道,顶一下
tongwei7 2009-02-20
  • 打赏
  • 举报
回复
顶一下
加载更多回复(10)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧