【问题标题】:Windows API Background GlitchWindows API 背景故障
【发布时间】:2016-10-05 01:14:15
【问题描述】:

在设置窗口类的背景时,我遇到了一个奇怪的故障。我是这样设置的:

wcWndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

但是,当我测试我的游戏时,我看到的是:

背景故障图像

这是 Windows API 或我的代码的故障吗?感谢您的帮助。

编辑:我发现背景只绘制到标题。所以如果我向上或向下移动文本控件,背景也会向上或向下移动。

// Game
// Destroyable!

#include "Game.h"


HRESULT Game::Initialize(INT nCmdShow) {

  WNDCLASSEX wcWndClass;
  RECT rcSettingsClientRect;

  wcWndClass.style = CS_HREDRAW | CS_VREDRAW;
  wcWndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wcWndClass.cbSize = sizeof(WNDCLASSEX);
  wcWndClass.cbWndExtra = sizeof(LONG_PTR);
  wcWndClass.cbClsExtra = 0;
  wcWndClass.lpszClassName = L"wcWndClass";
  wcWndClass.lpszMenuName = NULL;
  wcWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wcWndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  wcWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcWndClass.hInstance = GetModuleHandle(NULL);
  wcWndClass.lpfnWndProc = Game::WindowProcedure;

  HRESULT hResult = RegisterClassEx(&wcWndClass) ? S_OK : E_UNEXPECTED;

  if (SUCCEEDED(hResult)) {

    RECT rcSettingsWndRect = {0, 0, 300, 300};
    AdjustWindowRectEx(&rcSettingsWndRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_WINDOWEDGE);
    m_hSettingsWnd = CreateWindowEx(WS_EX_WINDOWEDGE, L"wcWndClass", L"Game Settings", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, rcSettingsWndRect.right - rcSettingsWndRect.left, rcSettingsWndRect.bottom - rcSettingsWndRect.top, NULL, NULL, GetModuleHandle(NULL), this);
    hResult = m_hSettingsWnd ? S_OK : E_UNEXPECTED;

  }

  if (SUCCEEDED(hResult)) {

    RECT rcGameWndRect = {0, 0, 300, 300};
    AdjustWindowRectEx(&rcGameWndRect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE, WS_EX_WINDOWEDGE);
    m_hGameWnd = CreateWindowEx(WS_EX_WINDOWEDGE, L"wcWndClass", L"Gee Yoo Aye", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, rcGameWndRect.right - rcGameWndRect.left, rcGameWndRect.bottom - rcGameWndRect.top, NULL, NULL, GetModuleHandle(NULL), this);
    hResult = m_hGameWnd ? S_OK : E_UNEXPECTED;

  }

  if (SUCCEEDED(hResult)) {

    GetClientRect(m_hSettingsWnd, &rcSettingsClientRect);
    InitCommonControls();
    m_hTitleWnd = CreateWindowEx(NULL, L"Static", L"Gee Yoo Aye", WS_VISIBLE | WS_CHILD | SS_CENTER, 0, rcSettingsClientRect.bottom / 7, rcSettingsClientRect.right, rcSettingsClientRect.bottom, m_hSettingsWnd, (HMENU) TITLE, GetModuleHandle(NULL), NULL);
    hResult = m_hTitleWnd ? S_OK : E_UNEXPECTED;

  }

  if (SUCCEEDED(hResult)) {

    SendMessage(m_hTitleWnd, WM_SETFONT, (WPARAM) CreateFont(36, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, NULL), TRUE);
    m_hSizeSliderWnd = CreateWindowEx(NULL, TRACKBAR_CLASS, L"Board Size", WS_VISIBLE | WS_CHILD | TBS_AUTOTICKS, rcSettingsClientRect.right / 6, rcSettingsClientRect.bottom / 2, rcSettingsClientRect.right * 2 / 3, 25, m_hSettingsWnd, (HMENU) SIZE_SLIDER, GetModuleHandle(NULL), NULL);
    hResult = m_hSizeSliderWnd ? S_OK : E_UNEXPECTED;

  }

  if (SUCCEEDED(hResult)) {

    ShowWindow(m_hSettingsWnd, nCmdShow);
    UpdateWindow(m_hSettingsWnd);

  }

  return hResult;

}


WPARAM Game::RunMessageLoop() {

  MSG mMsg;

  while (GetMessage(&mMsg, NULL, 0, 0)) {

    TranslateMessage(&mMsg);
    DispatchMessage(&mMsg);

  }

  return mMsg.wParam;

}


LRESULT CALLBACK Game::WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

  LRESULT lResult;

  if (uMsg == WM_CREATE) {

    LPCREATESTRUCT lpCreateStruct = (LPCREATESTRUCT) lParam;
    Game* pGame = (Game*) lpCreateStruct -> lpCreateParams;
    ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pGame));
    lResult = 1;

  } else {

    Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)));
    BOOL bHandled = FALSE;

    if (pGame) {

      switch (uMsg) {

        case WM_DESTROY:

        {

          PostQuitMessage(0);
          bHandled = TRUE;
          lResult = 1;
          break;

        }

      }

    }

    if (!bHandled) {

      return DefWindowProc(hWnd, uMsg, wParam, lParam);

    }

  }

  return lResult;

}
Struct = (LPCREATESTRUCT) lParam;
    Game* pGame = (Game*) lpCreateStruct -> lpCreateParams;
    ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pGame));
    lResult = 1;

  } else {

    Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)));
    BOOL bHandled = FALSE;

    if (pGame) {

      switch (uMsg) {

        case WM_DESTROY:

        {

          PostQuitMessage(0);
          bHandled = TRUE;
          lResult = 1;
          break;

        }

      }

    }

    if (!bHandled) {

      return DefWindowProc(hWnd, uMsg, wParam, lParam);

    }

  }

  return lResult;

}

【问题讨论】:

  • 因为你没有展示你的代码,所以不可能知道。但是 Windows API 已经存在很长时间了,您的代码相当少。
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及重现它所需的最短代码在问题本身。没有明确的问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example
  • 代码太长,无法提出一个问题,我看不出有任何问题。只是我创建了两个控件,仅此而已。但无论如何都在这里:shorttext.com/7a1a71c1
  • @OlegAprelikov 看来你已经错过了“最小”和“问题本身”。
  • 我不知道故障在哪里,也不知道如何重现。我不能把我的整个游戏都放在一个问题上,因为 StackOverflow 不允许这样做。

标签: c++ winapi background


【解决方案1】:

我发现了问题所在。文本控件绘制自己的背景,我将文本的宽度和高度设置得非常宽和高,几乎占据了整个窗口。

【讨论】:

  • 那么,不是 Windows API。
  • 如果你想改变一个 STATIC 控件的颜色,在父窗口过程中处理 WM_CTLCOLORSTATIC 并返回一个适当颜色的画笔(例如,GetSysColorBrush(COLOR_WINDOW))。有一个关于here的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多