我正在将基于控制台的程序改编为 GUI。
控制台程序读取一个文本文件并“编译”它。
我的 GUI 应用程序读取文本文件并显示在 RichTextBox 中。
我正在寻找一种将 RichTextBox 视为 C++ std::istream
的方法。这将允许我使用控制台程序中的代码而无需修改它。
我搜索了网络和 StackOverflow,但没有找到任何将 RichTextBox 视为 std::istream
的解决方案。
有人知道任何允许将 RichTextBox 视为 std::istream
的 Winforms 库函数吗?
我的想法:
- 创建适配器以将 RichTextBox 视为流。
- 更改控制台程序以将“getline”函数传递给 编译器部分,并有两个 getline 函数(一个作为 std::getline,另一个用于从 RichTextBox 获取一行)。
- 将 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/