【问题标题】:What can reset cursor shape apart from SetCursor?除了 SetCursor,还有什么可以重置光标形状?
【发布时间】:2012-02-19 15:29:58
【问题描述】:

我维护一个使用 flash ocx 播放 SWF 文件的 C++ 应用程序。

当用户将鼠标悬停在 SWF 中的按钮上时,flash 在内部调用 WinAPI SetCursor 函数来设置 IDC_HAND 光标 - 我可以看到,当我通过 API Monitor V2 (rohitab.com) 监视 WinAPI 调用与光标相关的函数时。但是,在我的情况下,光标没有改变,即保持IDC_ARROW

应用程序本身根本不调用SetCursor。应用程序窗口处理WM_SETCURSOR消息如下,即不恢复光标:

case WM_SETCURSOR:
    {   
        static bool restoreCursor = false;
        if (LOWORD(lParam) != HTCLIENT)
        {
            restoreCursor = true;
        }

        if (restoreCursor)
        {
            restoreCursor = false;
            // DefWindowProc will set the cursor
            break;
        }
        return 1;
    }

谁能告诉我在这种情况下谁可以重置/更改光标形状?

更新:有趣的是,我有 2 个相似的设置产生相反的结果。

我维护的应用程序实际上在“SysListView32”上安装了一个WH_GETMESSAGE 挂钩,并启动了一个创建Flash 播放器的线程。所以设置不是那么简单。

但是,如果我只是创建一个简单的示例,基本上在 winmain 上创建一个播放器,那么上面的代码可以完美运行并且光标会发生变化。

因此,在第一种情况下,似乎有些东西确实重置了光标状态。如何找出什么重置了光标

【问题讨论】:

    标签: c++ winapi cursor reset apimonitor


    【解决方案1】:

    好的,这个问题的真正答案是非GUI线程不能直接改变光标。 请参阅页面底部的 cmets http://msdn.microsoft.com/en-us/library/windows/desktop/ms648393%28v=vs.85%29.aspx

    另一种解决方案是绕过/挂钩 SetCursor 函数到我们的函数,它只是向 GUI 线程发送用户消息,发出设置光标的信号。

    两种解决方案都有其优点,当然 :) 也各有缺点。

    【讨论】:

      【解决方案2】:

      您的窗口(父窗口)在覆盖光标时出现裂缝,返回 TRUE (1) 表示您已处理它并停止进一步处理。箭头可能来自您的 WNDCLASS 注册或 DefWindowProc。

      所以,在我看来,您可能希望返回 FALSE 以允许子按钮在实际设置光标时有所突破。或者,完全删除处理 WM_SETCURSOR。

      【讨论】:

      • 我相信 DefWindowProc 是根据 WNDCLASS 设置光标的,所以它不是一个/或两个一起工作。
      • 等一下,孩子不是先得到WM_SETCURSOR吗?因此,如果子进程不处理 WM_SETCURSOR,那么它将通过 DefWindowProc 转到父进程。 blogs.msdn.com/b/oldnewthing/archive/2006/11/21/1115695.aspx
      • 问题是,如果我使用示例应用程序并在几乎 winmain() 中创建播放器,上面的代码工作。但它在我的应用程序中不起作用,但它涉及到钩子和其他线程。此外,两个应用程序(实际和示例)在 WinAPI 监控软件中产生相同的输出。
      • 根据您的扩​​展信息,您可以尝试在 ::SetCursor() OS api 中设置断点(添加一个虚拟调用并在反汇编模式下单步执行并设置一个 bkpt)。您需要禁用断点并将其设置为条件断点,因为它会受到很多影响。但也许在你的 mousemove 代码中设置一个标志,它会触发 bkpt 然后将鼠标悬停在按钮上。
      • 我已经这样做了,但是断点只被命中一次,并且发生在 Flash.ocx 中,这是正确的。然而,光标形状并没有从默认箭头改变。我怀疑光标是由某些窗口的 DefWindowProc 重置的。而且由于没有检测到对 SetCursor 的调用,这意味着 DefWindowProc 通过另一种方法重置了光标。
      猜你喜欢
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 2021-09-18
      相关资源
      最近更新 更多