0

什么可能导致ShowCaretSetCaretPos失败ERROR_ACCESS_DENIED

我正在创建插入符号WM_CREATE并将插入符号显示在WM_COMMAND. 我检查并CreateCaret成功执行。

它们应该在同一个线程中运行。

我在调用之前使用SetScrollInfoand来更新窗口的内容。但我不认为这些会导致失败..InvalidateRectShowCaretShowCaret

相关代码:

#define CHAR_WIDTH  7
#define CHAR_HEIGHT 12

case WM_CREATE:
    CreateCaret(hWnd, NULL, CHAR_WIDTH, 2);
    UpdateScrollbar(hWnd); // calls SetScrollInfo. initially nMin and nMax are both 0
    return 0;

case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDM_OPENFILE:
        if (DoOpenFile(hWnd))
        {
            InvalidateRect(hWnd, NULL, TRUE);
            UpdateScrollbar(hWnd);

            if (SetCaretPos(CHAR_WIDTH * 12, CHAR_HEIGHT - 1) == 0)
            {
                char ss[33];
                sprintf_s(ss, "DEBUG 2: %d\n", GetLastError());
                OutputDebugString(ss);
            }

            if (ShowCaret(hWnd) == 0)
            {
                char ss[33];
                sprintf_s(ss, "DEBUG 3: %d\n", GetLastError());
                OutputDebugString(ss);
            }
        }
        break;
    }
    return 0;
4

1 回答 1

5

是的,您没有正确执行此操作。每个消息队列(换句话说,每个线程)只有一个插入符号。当另一个窗口已经有一个插入符号时,您不能创建插入符号,最有可能的情况是编辑框。在您的窗口收到焦点 WM_SETFOCUS 消息之前,您不得创建或显示插入符号当窗口失去焦点时,你必须销毁它,WM_KILLFOCUS 消息。

您使用 GetLastError() 的方式也很危险,尽管您现在可能会侥幸逃脱。在 C 或 C++ 中计算参数的顺序是不确定的。您冒着改变错误代码的参数表达式之一的风险。在调用其他任何内容之前始终获取错误代码,将其存储在局部变量中。

并且永远不要跳过错误检查,至少您必须 assert() 返回值。CreateCaret() 调用现在可能会失败,因为刚刚创建的窗口将永远不会获得焦点。

于 2013-03-02T16:26:45.523 回答