我创建了一个带有多行编辑控件的简单窗口:
Edit = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL,
WS_CHILD | WS_VISIBLE | ES_MULTILINE,
20, 200, 200, 200,
hWnd, (HMENU)EDIT, GetModuleHandle(NULL), NULL);
如果我使用WM_SETTEXT消息设置文本,我不会收到错误,但如果我使用EM_REPLACESEL 我收到错误5(ERROR_ACCESS_DENIED):
SendMessage(GetDlgItem(hWnd, EDIT), EM_REPLACESEL, 0, (LPARAM)TEXT("\r\nSome text"));
if (GetLastError()) {
/* Error 5 ERROR_ACCESS_DENIED */
}
与EM_SETSEL相同的问题:
SendMessage(GetDlgItem(hWnd, EDIT), EM_SETSEL, (WPARAM)(0),(LPARAM)(-1));
SendMessage(GetDlgItem(hWnd, EDIT), EM_REPLACESEL, 0, (LPARAM)TEXT("\r\nSome text"));
if (GetLastError()) {
/* Error 5 ERROR_ACCESS_DENIED */
}
我注意到如果我在EM_REPLACESEL之前发送WM_SETFOCUS消息,则没有错误:
SendMessage(GetDlgItem(hWnd, EDIT), WM_SETFOCUS, (WPARAM)GetDlgItem(hWnd, EDIT), 0);
SendMessage(GetDlgItem(hWnd, EDIT), EM_REPLACESEL, 0, (LPARAM)TEXT("\r\nSome text"));
if (GetLastError()) {
/* NO ERRORS */
}
如何解决此问题? 每次我想将一些文本附加到我的编辑框时,是否必须在EM_REPLACESEL之前发送WM_SETFOCUS消息?
感谢您的帮助!
答案 0 :(得分:1)
您可以先使用EM_SETSEL
,然后再使用EM_REPLACESEL
。
示例:
SendMessage(hwnd, EM_SETSEL, WPARAM(0), LPARAM(-1) );
SendMessage(hwnd, EM_REPLACESEL, WPARAM(TRUE), LPARAM(str) );
答案 1 :(得分:0)
您最有可能因UIPI而被拒绝访问。
编辑框是否由尝试发送邮件的同一应用程序创建?如果没有,执行SendMessage的应用程序的UIPI级别可能低于拥有Edit的应用程序。
如果您确实拥有创建编辑控件的应用程序和发送邮件的应用程序,您可以使用ChangeWindowMessageFilterEx允许特定邮件进入。
ChangeWindowMessageFilterEx(hwndOfWindowReceivingMessage, EM_REPLACESEL,
MSGFLT_ALLOW, NULL);
答案 2 :(得分:0)
不幸的是,没有记录支持EM_REPLACESEL的GetLastError意味着您必须设计一些备用策略来捕获故障。也许一些文本长度计算可行。
话虽如此,我很好奇为什么返回访问被拒绝错误。我在SetLastError / GetLastError存储错误代码的地址上设置了一个数据断点,发现它在GDI内部,而不是直接来自编辑控件。不是很有帮助,但至少是一个有趣的花絮。
答案 3 :(得分:0)
您可能需要使用SendDlgItemMessage而不是SendMessage。
答案 4 :(得分:0)
请注意,EM_SETSEL,EM_REPLACESEL等作用于插入符号;如果焦点不在控件上,则没有插入符号,这些消息将不起作用。您的用户必须单击控件才能获得焦点,或者您必须先执行WM_SETFOCUS。不幸的是,这就是控制的工作方式,它在失去焦点后没有选择的记忆(在获得它之前也没有一个选择)。
答案 5 :(得分:0)
试试这个
wchar_t buffer[256] = _T("here I am at camp granada \r\n");
int ndx = GetWindowTextLength (hEdit);
SetFocus (hEdit);
SendMessage(hEdit, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);
SendMessage(hEdit, EM_REPLACESEL, WPARAM(TRUE), (LPARAM)buffer );