私は RichTextBox コントロールを使用していますが、行間を除いてうまくいっています。PARAFORMAT2 で SendMessage を介して相互運用呼び出しを使用して、段落の行間を設定しています。
それはうまくいきます。それは私がする必要があることを正確に行います。問題は、RTF 文字列を保存してから戻すと、行間情報が失われることです。
2 つ目の RichText Box を追加し、以下のコードを使用することで、これを証明できます。richTextBox1 では、rtf 文字列が適切にフォーマットされています。しかし、richTextBox2 に到達するまでには、再びシングルスペースになっています。
private void button15_Click(object sender, EventArgs e)
{
string rtf = richTextBox1.Rtf;
richTextBox2.Rtf = rtf;
}
フォーマットを維持するための提案はありますか? /ls 設定を使用して RTF 文字列を壊すことができることはわかっていますが、それは非常に苦痛です。どこかに欠けているだけのよりクリーンなソリューションはありますか?
アップデート:
EM_STREAMIN/OUT の提案はすばらしいものですが、残念なことに同じ狂気の結果になります。STREAMIN と STREAMOUT について詳しく読んだときに、コントロールによって提供される SaveFile と LoadFile がこれら 2 つのメッセージ コマンドの単純なラッパーであることを発見したので、簡単にするために、このサンプルではこれら 2 つのコマンドを使用しています。サンプルアプリケーションを添付しています。このコードを 1 つのテキスト ボックスと 5 つのボタンを含むフォームにカット アンド ペーストできるはずです。
読み込み、保存、クリア、DoubleSpace、SingleSpace
私は MemoryStream オブジェクトを使用して、[保存] と [読み込み] のクリックの間の一時データを処理しています。テスト: (1) DoubleSpace ボタンを使用して、1 つまたは複数の段落の間隔を変更します。(2) RichText を MemoryStream に保存します。(3) リッチ テキスト コントロールをクリアします。(4) MemoryStream データをコントロールに再ロードします。
再ロードすると、ダブルスペースのフォーマットが失われることに注意してください。他のすべての書式はそのままです。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication4
{
public partial class Form2 : Form
{
MemoryStream ms = new MemoryStream();
public Form2()
{
InitializeComponent();
// First, load some crap in...
richTextBox1.Text = "The quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. \r\nThe quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. \r\nThe quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. The quick red fox jumped over the lazy brown dog. ";
}
private void btnLoad_Click(object sender, EventArgs e)
{
ms.Seek(0, SeekOrigin.Begin);
richTextBox1.LoadFile(ms, RichTextBoxStreamType.RichText);
}
private void btnSave_Click(object sender, EventArgs e)
{
if (ms.Length > 0) ms.Dispose();
ms = new MemoryStream();
richTextBox1.SaveFile(ms, RichTextBoxStreamType.RichText);
}
private void btnSingleSpace_Click(object sender, EventArgs e)
{
SetParagraphSpacing(richTextBox1, 0);
}
private void btnDoubleSpace_Click(object sender, EventArgs e)
{
SetParagraphSpacing(richTextBox1, 2);
}
private void btnClear_Click(object sender, EventArgs e)
{
richTextBox1.Text = "";
}
[DllImport("USER32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wp, IntPtr lp);
public void SetParagraphSpacing(RichTextBox rtb, int Spacing)
{
PARAFORMAT2 paraform = new PARAFORMAT2();
paraform.cbSize = Marshal.SizeOf(paraform);
paraform.bLineSpacingRule = Convert.ToByte(Spacing);
paraform.wReserved = 0;
paraform.dwMask = ParaMessages.PFM_LINESPACING;
IntPtr res = IntPtr.Zero;
IntPtr wparam = IntPtr.Zero;
//Get the pointer to the FORMATRANGE structure in memory
IntPtr lparam = IntPtr.Zero;
lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(paraform));
Marshal.StructureToPtr(paraform, lparam, false);
//Send the rendered data for printing
res = SendMessage(rtb.Handle, ParaMessages.EM_SETPARAFORMAT, wparam, lparam);
//Free the block of memory allocated
Marshal.FreeCoTaskMem(lparam);
}
[StructLayout(LayoutKind.Sequential)]
public struct PARAFORMAT2
{
public int cbSize;
public uint 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 = 32)]
public int[] rgxTabs;
// PARAFORMAT2 from here onwards.
public int dySpaceBefore;
public int dySpaceAfter;
public int dyLineSpacing;
public short sStyle;
public byte bLineSpacingRule;
public byte bOutlineLevel;
public short wShadingWeight;
public short wNumberingStart;
public short wNumberingStyle;
public short wNumberingTab;
public short wBorderSpace;
public short wBorderWidth;
public short wBorders;
}
public class ParaMessages
{
public static uint PFM_SPACEAFTER = 128;
public static uint PFM_LINESPACING = 256;
// Constants from the Platform SDK.
public static uint EM_SETEVENTMASK = 1073;
public static uint EM_GETPARAFORMAT = 1085;
public static uint EM_SETPARAFORMAT = 1095;
public static uint EM_SETTYPOGRAPHYOPTIONS = 1226;
public static uint WM_SETREDRAW = 11;
public static uint TO_ADVANCEDTYPOGRAPHY = 1;
public static uint PFM_ALIGNMENT = 8;
public static uint SCF_SELECTION = 1;
}
}
}