在 RichTextBox 中按下时如何更改 Enter KeyChar?
How to change the Enter KeyChar when pressed in a RichTextBox?
我目前的任务是为一些格式化文本编写文本编辑器。出于显而易见的原因,我选择使用 RichTextBox。到目前为止,对于每个键,我都能够修改它的 KeyChar
,可以通过覆盖 ProcessCmdKey
方法或订阅 KeyPress
事件或覆盖 virtual
方法 OnKeyPress
.
我在这个例子中使用的rtf文本是这样的:
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}{\f1\fnil Courier New;}{\f2\fnil Verdana;}}
{\colortbl ;\red0\green0\blue0;}
{*\generator Riched20 10.0.19041}\viewkind4\uc1
\pard\sa180\sl72\slmult1\ulc1\ul\b\f0\fs21 Header1:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\ul\b\f0 Header2:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\ul\b\f0 Header3:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\line\ulc1\f0 Signature...\ulc1\f2\fs20\par
}
所以对于这个 rtf,我基本上是在每次用户按下 Enter 时尝试模拟 Shift + Enter,以便换行符比按下 Enter 时的默认换行符小。
我为此宣布了自己的 RichTextBox
,希望我能深入挖掘:
public class CustomRichTextBox : RichTextBox { ... }
为了阐明我到目前为止所做的尝试 - 这些是我的方法,非常适合普通字符:
使用ProcessCmdKey
将字符A更改为B:
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if(keyData == Keys.A)
{
m.WParam = new IntPtr((int)Keys.B);
return base.ProcessCmdKey(ref m, Keys.B);
}
else if(keyData == (Keys.Shift | Keys.A))
{
m.WParam = new IntPtr((int)(Keys.Shift | Keys.B));
return base.ProcessCmdKey(ref m, (Keys.Shift | Keys.B));
}
return base.ProcessCmdKey(ref m, keyData);
}
使用OnKeyPress
将字符A更改为B:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if(e.KeyChar == 'A')
{
e.KeyChar = 'B';
}
else if(e.KeyChar == 'a')
{
e.KeyChar = 'b';
}
base.OnKeyPress(e);
}
只有我按回车,没有按预期工作(对我没有影响):
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if (keyData == Keys.Enter)
{
m.WParam = new IntPtr((int)(Keys.Shift | Keys.Enter));
return base.ProcessCmdKey(ref m, (Keys.Shift | Keys.Enter));
}
return base.ProcessCmdKey(ref m, keyData);
}
没有简单的方法可以实现这一点,还是我错过了什么?
编辑:
我忘了在 OnKeyPress
中包含该方法。这是我尝试过的:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if(e.KeyChar == '\r')
{
e.KeyChar = '\u2028';
}
base.OnKeyPress(e);
}
这里是结果:
事实证明,使用 SendKeys
并通过返回 true 来阻止 Enter KeyPress...
实现起来非常容易
private bool sendingEnter = false;
public override bool PreProcessMessage(ref Message msg)
{
if(msg.Msg == WM_KEYDOWN && msg.WParam.ToInt32() == VK_RETURN)
{
if (!sendingEnter)
{
sendingEnter = true;
SendKeys.Send("+{ENTER}");
return true;
}
else
{
sendingEnter = false;
}
}
return base.PreProcessMessage(ref msg);
}
我目前的任务是为一些格式化文本编写文本编辑器。出于显而易见的原因,我选择使用 RichTextBox。到目前为止,对于每个键,我都能够修改它的 KeyChar
,可以通过覆盖 ProcessCmdKey
方法或订阅 KeyPress
事件或覆盖 virtual
方法 OnKeyPress
.
我在这个例子中使用的rtf文本是这样的:
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}{\f1\fnil Courier New;}{\f2\fnil Verdana;}} {\colortbl ;\red0\green0\blue0;} {*\generator Riched20 10.0.19041}\viewkind4\uc1 \pard\sa180\sl72\slmult1\ulc1\ul\b\f0\fs21 Header1:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\ul\b\f0 Header2:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\ul\b\f0 Header3:\ulc1\ulnone\b0\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\ulc1\f0 Lorem ipsum.\ulc1\f1\line\line\ulc1\f0 Signature...\ulc1\f2\fs20\par }
所以对于这个 rtf,我基本上是在每次用户按下 Enter 时尝试模拟 Shift + Enter,以便换行符比按下 Enter 时的默认换行符小。
我为此宣布了自己的 RichTextBox
,希望我能深入挖掘:
public class CustomRichTextBox : RichTextBox { ... }
为了阐明我到目前为止所做的尝试 - 这些是我的方法,非常适合普通字符:
使用ProcessCmdKey
将字符A更改为B:
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if(keyData == Keys.A)
{
m.WParam = new IntPtr((int)Keys.B);
return base.ProcessCmdKey(ref m, Keys.B);
}
else if(keyData == (Keys.Shift | Keys.A))
{
m.WParam = new IntPtr((int)(Keys.Shift | Keys.B));
return base.ProcessCmdKey(ref m, (Keys.Shift | Keys.B));
}
return base.ProcessCmdKey(ref m, keyData);
}
使用OnKeyPress
将字符A更改为B:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if(e.KeyChar == 'A')
{
e.KeyChar = 'B';
}
else if(e.KeyChar == 'a')
{
e.KeyChar = 'b';
}
base.OnKeyPress(e);
}
只有我按回车,没有按预期工作(对我没有影响):
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if (keyData == Keys.Enter)
{
m.WParam = new IntPtr((int)(Keys.Shift | Keys.Enter));
return base.ProcessCmdKey(ref m, (Keys.Shift | Keys.Enter));
}
return base.ProcessCmdKey(ref m, keyData);
}
没有简单的方法可以实现这一点,还是我错过了什么?
编辑:
我忘了在 OnKeyPress
中包含该方法。这是我尝试过的:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if(e.KeyChar == '\r')
{
e.KeyChar = '\u2028';
}
base.OnKeyPress(e);
}
这里是结果:
事实证明,使用 SendKeys
并通过返回 true 来阻止 Enter KeyPress...
private bool sendingEnter = false;
public override bool PreProcessMessage(ref Message msg)
{
if(msg.Msg == WM_KEYDOWN && msg.WParam.ToInt32() == VK_RETURN)
{
if (!sendingEnter)
{
sendingEnter = true;
SendKeys.Send("+{ENTER}");
return true;
}
else
{
sendingEnter = false;
}
}
return base.PreProcessMessage(ref msg);
}