0

正如MSDN 所描述的

当鼠标在窗口上移动时,该窗口会收到一条WM_SETCURSOR消息(除非另一个窗口已经捕获了鼠标)。

如果应用程序传递WM_SETCURSORDefWindowProc,该DefWindowProc函数使用以下算法来设置光标图像:

  1. 如果窗口有父窗口,则将WM_SETCURSOR消息转发给父窗口处理。
  2. 否则,如果窗口有类光标,则将光标设置为类光标。
  3. 如果没有类光标,则将光标设置为箭头光标。

这是我的源代码:

#include <tchar.h>
#include <Windows.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInsTance, LPTSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wcex = { 0 };
  HWND hWnd;
  BOOL ret;
  MSG msg;

  wcex.cbSize = sizeof(wcex);
  wcex.lpfnWndProc = WndProc;
  wcex.hInstance = hInstance;
  wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  // wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcex.lpszClassName = TEXT("MainWindow");
  wcex.hIconSm = wcex.hIcon;

  RegisterClassEx(&wcex);
  hWnd = CreateWindow(wcex.lpszClassName, TEXT("Test"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  while (ret = GetMessage(&msg, NULL, 0, 0))
  {
    if (ret == -1)
    {
      return EXIT_FAILURE;
    }
    else
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
  return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
  case WM_DESTROY:
    PostQuitMessage(EXIT_SUCCESS);
    break;
  default:
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
  return 0;
}

当我在窗口上快速移动光标时,光标不会变成箭头,而是变成了调整大小的箭头;如果我设置wcex.hCursorLoadCursor(NULL, IDC_ARROW),一切都会好起来的。我的问题是:为什么我的代码不像 MSDN 所说的那样工作?

我的意思是,如果我不设置wcex.hCursor,并且我不处理WM_SETCURSOR消息,则DefWindowProc应该“将光标设置为箭头光标”,但似乎没有。这是为什么?

4

1 回答 1

4

请参阅hCursor成员的描述WNDCLASSEX

类游标的句柄。此成员必须是游标资源的句柄。如果此成员为 NULL,则应用程序必须在鼠标移入应用程序窗口时显式设置光标形状。

WNDCLASSEX 结构

于 2012-07-02T08:22:56.813 回答