windows 在 C++ 中将文本附加到 Win32 EditBox

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7200137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:56:28  来源:igfitidea点击:

Appending text to a Win32 EditBox in C++

c++windowswinapi

提问by Ozzah

I have an EditBox HWND tbLog, and the following function (which doesn't work):

我有一个 EditBoxHWND tbLog和以下功能(不起作用):

void appendLogText(char* newText)
{
  int len = GetWindowTextLength(tbLog);

  char* logText = new char[len + strlen(newText) + 1];
  GetWindowText(tbLog, logText, len);

  strcat(logText, newText);

  SendMessage(tbLog, WM_SETTEXT, NULL, (LPARAM)TEXT(logText));

  delete[] logText;
}

and I call it like so:

我这样称呼它:

appendLogText("Put something in the Edit box.\r\n");
appendLogText("Put something else in the Edit box.\r\n");

First of all, what does TEXT()actually do? I have tried with/without it: (LPARAM)logTextand (LPARAM)TEXT(logText)and there is no difference as far as I can see.

首先,TEXT()实际上是做什么的?我试过有/没有它:(LPARAM)logText并且(LPARAM)TEXT(logText)据我所知没有区别。

Second, what am I doing wrong in my append function? If I comment out my deleteline, then the first time I run the append function, I get garbage coming up in my Editbox, followed by the message. The second time I run it, the program crashes. If I don't have it commented out, then it crashes even the first time.

其次,我在 append 函数中做错了什么?如果我注释掉我的delete行,那么当我第一次运行 append 函数时,我的编辑框中会出现垃圾,然后是消息。我第二次运行它时,程序崩溃了。如果我没有将其注释掉,那么即使是第一次它也会崩溃。

回答by Chris Becke

I would rewrite the function, in C, like this:

我会用 C 重写函数,如下所示:

void appendLogText(LPCTSTR newText)
{
  DWORD l,r;
  SendMessage(tbLog, EM_GETSEL,(WPARAM)&l,(LPARAM)&r);
  SendMessage(tbLog, EM_SETSEL, -1, -1);
  SendMessage(tbLog, EM_REPLACESEL, 0, (LPARAM)newText);
  SendMessage(tbLog, EM_SETSEL,l,r);
}

Its important to save and restore the existing selection or the control becomes very annoying for anyone to use who wants to select and copy some text out of the control.

保存和恢复现有选择很重要,否则对于想要选择和复制一些文本的人来说,控件变得非常烦人。

Also, the use of LPCTSTR ensures that the function can be called when you build with either a multibyte or unicode character set.

此外,使用 LPCTSTR 可确保在使用多字节或 unicode 字符集构建时可以调用该函数。

The TEXT macro was out of place, and should be used to wrap string literals:

TEXT 宏不合适,应该用于包装字符串文字:

LPCTSTR someString = TEXT("string literal");

Windows NT Operating systems are natively unicode so building multibyte applications is inefficient. Using TEXT() on string literals, and LPTSTR in place of 'char*' helps with this conversion to unicode. But really it would probably be most efficient to just switch explicitly to unicode programming on windows: in place of char, strlen, std::string, use wchar_t, std::wstring, wsclen, and L"string literals".

Windows NT 操作系统本身就是 unicode,因此构建多字节应用程序的效率很低。在字符串文字上使用 TEXT() 并使用 LPTSTR 代替 'char*' 有助于将这种转换为 unicode。但实际上,在 Windows 上显式切换到 unicode 编程可能是最有效的:代替 char、strlen、std::string,使用 wchar_t、std::wstring、wsclen 和 L“字符串文字”。

Switching your projects build settings to Unicode will make all the windows API functions expect unicode strings.

将项目构建设置切换为 Unicode 将使所有 Windows API 函数都期望使用 Unicode 字符串。



It has been brought to my very belated attention that passing -1 as the WPARAM of EM_SETSEL merely unselects any selection but does not move the insertion point. So the answer should be ammended to (also untested):

我很晚才注意到,将 -1 作为 EM_SETSEL 的 WPARAM 传递只会取消选择任何选择,但不会移动插入点。所以答案应该修改为(也未经测试):

void appendLogText(HWND hWndLog, LPCTSTR newText)
{
  int left,right;
  int len = GetWindowTextLength(hWndLog);
  SendMessage(hWndLog, EM_GETSEL,(WPARAM)&left,(LPARAM)&right);
  SendMessage(hWndLog, EM_SETSEL, len, len);
  SendMessage(hWndLog, EM_REPLACESEL, 0, (LPARAM)newText);
  SendMessage(hWndLog, EM_SETSEL,left,right);
}