c++ - Winforms RichTextBox 作为 istream

标签 c++ winforms richtextbox istream

我正在将基于控制台的程序改编为 GUI。

控制台程序读取一个文本文件并“编译”它。

我的 GUI 应用程序读取文本文件并显示在 RichTextBox 中。

我正在寻找一种将 RichTextBox 视为 C++ std::istream 的方法。这将允许我使用控制台程序中的代码而无需修改它。

我搜索了网络和 StackOverflow,但没有找到任何将 RichTextBox 视为 std::istream 的解决方案。

有人知道任何允许将 RichTextBox 视为 std::istream 的 Winforms 库函数吗?

我的想法:

  1. 创建适配器以将 RichTextBox 视为流。
  2. 更改控制台程序以将“getline”函数传递给 编译器部分,并有两个 getline 函数(一个作为 std::getline,另一个用于从 RichTextBox 获取一行)。
  3. 将 RichTextBox 内容写入文件并将文件提供给 编译器。

我在使用“.NET”4.0 的 Win 7 上使用 Visual Studio 2010,使用 C++(不要建议任何 C# 技术,因为我翻译不流利)

最佳答案

在真正的 C++ 中,您可以像这样从 RTF 控件创建流缓冲区:

class RTF_buf : public std::streambuf {
    std::vector<char> buffer;
public:
    RTF_buf(HWND ctrl) {
        DWORD len = SendMessage(ctrl, WM_GETTEXTLENGTH, 0, 0);
        buffer.resize(len+1);
        SendMessageA(ctrl, WM_GETTEXT, len+1, (LPARAM)&buffer[0]);
        setg(&buffer[0], &buffer[0], &buffer[len]);
    }
};

请注意,这实际上并不限于 RTF 控件。再举一个例子,它也可以与普通的 EDIT 控件一起正常工作。

C++/CLI 为此增加了一些麻烦。首先,您要处理 RichTextBox 中的“宽”字符。其次,您不会(通常)从 HWND 开始——您必须通过其 Handle 属性从 System.Windows.Forms.RichTextBox 中检索它。不幸的是,这会将 HWND 作为 IntPtr 而不是 HWND 返回,因此您必须添加强制转换才能使其成为正确的类型.这让代码有点难看,但也没什么可怕的:

#include <windows.h>
#include <streambuf>
#include <iostream>
#include <vector>
#include <algorithm>

#pragma comment(lib, "user32.lib")

using namespace System;
using namespace System::Windows::Forms;

class RTF_buf : public std::wstreambuf {
    std::vector<wchar_t> buffer;
public:
    RTF_buf(RichTextBox^ control) {
        HWND ctrl = *reinterpret_cast<HWND *>(&control->Handle);
        int len = SendMessage(ctrl, WM_GETTEXTLENGTH, 0, 0);
        buffer.resize(len+1);
        SendMessage(ctrl, WM_GETTEXT, len+1, (LPARAM)&buffer[0]);
        setg(&buffer[0], &buffer[0], &buffer[len]);
    }
};

我们可以像这样创建一个缓冲区和 istream:

RTF_buf b(this->richTextBox1);
std::wistream in(&b);

最后,我们可以从我们的流中读取数据并像处理任何其他(宽)流一样处理它们。例如:

wchar_t ch;

while (in >> ch)
    // do something with ch

所以 C++/CLI 确实给任务增加了一点点复杂性,但最终只是一点点——主要是获取控件句柄并将其转换为正确类型的一行代码。除此之外,缓冲区类的代码几乎不需要更改,并且实例化和使用它的更改仅在我们使用宽字符而不是窄字符的范围内。

关于c++ - Winforms RichTextBox 作为 istream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20621608/

相关文章:

c# - 我如何使用 .MatchCase 和 .WholeWord?

c++ - 为什么结构体的 sizeof 不等于每个成员的 sizeof 之和?

c++ - 实时操作系统 : windows ce : Real mode and protected mode memory accessibility overhead

c++ - "Expected unqualified-id"将我的代码设为模板时出现错误,而在将其设为模板之前没有出现该错误?

C# - 拉伸(stretch)文本框以适应包含的窗口

c# - DataType 来存储和使用具有特定限制的通用类型?

C++ 建议拼写错误的单词

c# - 我可以使继承自 System.Windows.Forms.Form 类的类始终在代码 View 中打开吗?

wpf - 如何设置下一个要写入的文本的RichTextBox字体?

.net - 将RTF文件从资源加载到WPF应用程序中的RichTextBox中