怪异的光标行为:几乎总是调整大小光标。 (Win32 API)

发布于 2025-01-30 01:51:41 字数 3845 浏览 4 评论 0 原文

我正在使用Win32 API,并且正在使用它来制作窗口。这个窗口可行,但是当我打开它时,光标是一个加载光标,每当我将光标带到边缘调整大小时,光标都会“卡住”,因为调整光标尺寸的光标都不会恢复正常。这是一个视频来解释我在说什么:

#undef UNICODE
#undef _UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

bool isRunning = true;

void *buffer;   // buffer memory
BITMAPINFO bmi; // bit map information, needed for rendering

int width, height; // main window's width and height

LRESULT __stdcall WindowProc(HWND, UINT, WPARAM, LPARAM);

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR pCmdLine, int nCmdShow) {
  LPCSTR CLASS_NAME = "Class Name";

  WNDCLASS wc = {};

  wc.lpfnWndProc = WindowProc;
  wc.hInstance = hInstance;
  wc.lpszClassName = CLASS_NAME;

  RegisterClass(&wc);

  // Create the window.

  HWND hwnd = CreateWindowExA(0,                   // Optional window styles.
                              "Class Name",        // Window class
                              "Window",            // Window text
                              WS_OVERLAPPEDWINDOW, // Window style

                              // Size and position
                              CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720,

                              NULL,      // Parent window
                              NULL,      // Menu
                              hInstance, // Instance handle
                              NULL       // Additional application data
  );

  if (hwnd == NULL)
    return 0;

  ShowWindow(hwnd, nCmdShow);

  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = 32;
  bmi.bmiHeader.biCompression = BI_RGB;

  // Run the message loop.
  HDC hdc = GetDC(hwnd);
  while (isRunning) {
    MSG msg;
    if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE) > 0) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    StretchDIBits(hdc, 0, 0, width, height, 0, 0, width, height, buffer, &bmi,
                  DIB_RGB_COLORS, SRCCOPY);
  }
  ReleaseDC(hwnd, hdc);
  return 0;
}

LRESULT __stdcall WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                             LPARAM lParam) {
  switch (uMsg) {
  case WM_DESTROY:
    isRunning = false;
    return 0;
  case WM_SIZE: {
    // Calculate window height and width
    width = LOWORD(lParam);
    height = HIWORD(lParam);

    if (buffer) // If memory already exists
                // free it
      VirtualFree(buffer, 0, MEM_RELEASE);

    // Allocate buffer memory
    buffer = VirtualAlloc(0, width * height * sizeof(unsigned int),
                          MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = height;
  }
    return 0;
  }
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

​一些奇怪的Windows错误,绝对是我的代码,因为它不会在我打开的其他应用中发生,而且当我使用SFML制作同等窗口时也不会发生这种情况(可能是因为Windows API和SFML完全是不同的事情)。该窗口的代码:

#include <SFML/Graphics.hpp>

int main() {
  sf::RenderWindow window(sf::VideoMode(1280, 720), "Window");
  while (window.isOpen()) {
    sf::Event event;
    while (window.pollEvent(event)) {
      if (event.type == sf::Event::Closed) {
        window.close();
      }

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
        window.close();
      }
    }
    window.clear();
    window.display();
  }
}

我希望第一个窗口像第二个窗口一样行动,但是光标是我能找到的一个差异。我尝试过谷歌搜索,但无济于事。我跟随a “ nofollow noreferrer”> youtube tutibe系列我的窗口我对我有问题。另外,在下载教程的源代码并删除一些代码时,该代码使其全屏并隐藏了光标,则具有相同的问题。我该如何解决?先感谢您。

I'm working with the win32 API, and am using it to make a window. This window works, but when I open it, the cursor is a loading cursor, and every time I bring my cursor to the edge to resize it, the cursor gets 'stuck' as that resizing cursor, it doesn't go back to normal. Here's a video to explain what I'm talking about:

video

Here's the reproducible example (compile with g++ reproducible_example.cpp -mwindows -O3 -o reproducible_example.exe):

#undef UNICODE
#undef _UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

bool isRunning = true;

void *buffer;   // buffer memory
BITMAPINFO bmi; // bit map information, needed for rendering

int width, height; // main window's width and height

LRESULT __stdcall WindowProc(HWND, UINT, WPARAM, LPARAM);

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR pCmdLine, int nCmdShow) {
  LPCSTR CLASS_NAME = "Class Name";

  WNDCLASS wc = {};

  wc.lpfnWndProc = WindowProc;
  wc.hInstance = hInstance;
  wc.lpszClassName = CLASS_NAME;

  RegisterClass(&wc);

  // Create the window.

  HWND hwnd = CreateWindowExA(0,                   // Optional window styles.
                              "Class Name",        // Window class
                              "Window",            // Window text
                              WS_OVERLAPPEDWINDOW, // Window style

                              // Size and position
                              CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720,

                              NULL,      // Parent window
                              NULL,      // Menu
                              hInstance, // Instance handle
                              NULL       // Additional application data
  );

  if (hwnd == NULL)
    return 0;

  ShowWindow(hwnd, nCmdShow);

  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = 32;
  bmi.bmiHeader.biCompression = BI_RGB;

  // Run the message loop.
  HDC hdc = GetDC(hwnd);
  while (isRunning) {
    MSG msg;
    if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE) > 0) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    StretchDIBits(hdc, 0, 0, width, height, 0, 0, width, height, buffer, &bmi,
                  DIB_RGB_COLORS, SRCCOPY);
  }
  ReleaseDC(hwnd, hdc);
  return 0;
}

LRESULT __stdcall WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                             LPARAM lParam) {
  switch (uMsg) {
  case WM_DESTROY:
    isRunning = false;
    return 0;
  case WM_SIZE: {
    // Calculate window height and width
    width = LOWORD(lParam);
    height = HIWORD(lParam);

    if (buffer) // If memory already exists
                // free it
      VirtualFree(buffer, 0, MEM_RELEASE);

    // Allocate buffer memory
    buffer = VirtualAlloc(0, width * height * sizeof(unsigned int),
                          MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = height;
  }
    return 0;
  }
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Now, I know this isn't some weird windows bug and is definitely something with my code, because it doesn't happen in other apps which I open, and it also didn't happen when I made an equivalent window with SFML (probably because the windows api and SFML are entirely different things). Code for that window:

#include <SFML/Graphics.hpp>

int main() {
  sf::RenderWindow window(sf::VideoMode(1280, 720), "Window");
  while (window.isOpen()) {
    sf::Event event;
    while (window.pollEvent(event)) {
      if (event.type == sf::Event::Closed) {
        window.close();
      }

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
        window.close();
      }
    }
    window.clear();
    window.display();
  }
}

I want the first window to act like the second window, but the cursor is the one discrepancy I can find. I've tried googling this, but to no avail. I followed a youtube tutorial series for the window I'm having problems with. Also, on downloading the tutorial's source code and removing some code which makes it full screen and hides the cursor, it has the same problem. How do I fix this? Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

她说她爱他 2025-02-06 01:51:42

wc.hcursor 设置为null以外的其他东西。 当它进入窗口时,您应该将其设置为所需的光标。

很可能您想要无聊的旧箭头光标。您可以获得光标

Set wc.hCursor to something other than null. If it's null, the operating system will leave the cursor alone when it enters your window, and you're supposed to set it to the cursor you want.

Most likely you want the boring old arrow cursor. You can get that cursor by calling LoadCursor(NULL, IDC_ARROW).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文