在C++中向Win32 EditBox追加文本

3

我有一个EditBox HWND 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;
}

我这样调用它:

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

首先,TEXT()函数实际上是做什么的?我已经尝试过带/不带它:(LPARAM)logText(LPARAM)TEXT(logText),就我所看到的而言,没有任何区别。
其次,在我的追加函数中,我做错了什么?如果我注释掉delete行,那么第一次运行append函数时,我的Editbox中会出现垃圾字符,然后是消息。第二次运行它,程序就会崩溃。如果我不注释它,那么甚至第一次都会崩溃。

1
我会使用WM_SETSEL和WM_REPLACESEL来完成这个任务,这样更有效率。在字面值上使用TEXT宏,而不是在这里使用。另外,你为什么要写C代码而不是C++呢? - David Heffernan
大卫,请回答并我会接受。我找到了一个非常简单的解决方案:void appendLogText(LPSTR newText){ SendMessage(tbLog, EM_SETSEL, 0, -1); SendMessage(tbLog, EM_SETSEL, -1, -1); SendMessage(tbLog, EM_REPLACESEL, 0, (LPARAM)TEXT(newText)); } - Ozzah
Chris 做得比我好。 - David Heffernan
2个回答

10

我会像这样重新编写这个函数,使用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);
}

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

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

TEXT宏放置不当,应该用于包装字符串文字:

LPCTSTR someString = TEXT("string literal");

Windows NT操作系统天生支持Unicode,因此构建多字节应用程序效率低下。使用TEXT()处理字符串文字和LPTSTR替代'char *'有助于将其转换为Unicode。但实际上,在Windows上显式切换到Unicode编程可能是最有效的方法:使用wchar_t、std::wstring、wsclen和L"字符串文字"替代char、strlen、std::string。

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


我很晚才意识到将-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);
}

我讨厌使用字母 l 作为变量。我总是将其与数字 1 搞混 >,> - aquirdturtle
这是在前面添加而不是在后面添加。 - vallentin

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接