【问题标题】:ShowCaret and SetCaretPos failing with ERROR_ACCESS_DENIEDShowCaret 和 SetCaretPos 因 ERROR_ACCESS_DENIED 而失败
【发布时间】:2019-01-18 18:03:06
【问题描述】:

什么可能导致ShowCaretSetCaretPosERROR_ACCESS_DENIED 失败?

我在WM_CREATE 中创建插入符号并在WM_COMMAND 中显示插入符号。 我查了一下,CreateCaret 执行成功了。

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

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

相关代码:

#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;

【问题讨论】:

  • 窗口是你的窗口吗?由调用ShowCaretSetCaretPos 的进程创建?可能的故障模式是受密码保护的屏幕保护程序。哪个版本的操作系统?
  • @DavidHeffernan 是的,我的窗口。 Windows 7 x64
  • 该代码对我来说看起来不错。我现在没有主意了。

标签: c++ winapi


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2011-07-23
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 2022-01-05
    • 2014-06-15
    相关资源
    最近更新 更多