【问题标题】:Creating a windows with WS_POPUP style创建具有 WS_POPUP 样式的窗口
【发布时间】:2021-08-17 07:36:57
【问题描述】:

我正在使用GDI+ WinAPI 实现一个在屏幕上显示图像的简单程序。

这是我目前的代码:

#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib, "Gdiplus.lib")

void Example_DrawImage9(HDC hdc) {
  Graphics graphics(hdc);
  Image image(L"C:/test.bmp");
  graphics.DrawImage(&image, 0, 0);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR pCmdLine, int nCmdShow) {
  ULONG_PTR token;
  GdiplusStartupInput input = { 0 };
  input.GdiplusVersion = 1;
  GdiplusStartup(&token, &input, NULL);
  const wchar_t CLASS_NAME[] = L"Sample Window Class";
  WNDCLASS wc = {};
  wc.lpfnWndProc = &WindowProc;
  wc.hInstance = hInstance; 
  wc.lpszClassName = CLASS_NAME;
  RegisterClass(&wc);

  HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"Learn to Program Windows", WS_POPUP, 0, 0, 190, 110, NULL, NULL, hInstance, NULL);

  if (hwnd != NULL) {
    ShowWindow(hwnd, nCmdShow);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  GdiplusShutdown(token);
  return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;

  case WM_PAINT: {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
    Example_DrawImage9(hdc);
    EndPaint(hwnd, &ps);
    return 0;
  }
  }

  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

因为我只想显示图像本身(没有非客户区),所以我使用WS_POPUP 样式创建的窗口。 但显然有某事。窗口有问题 - 当我将鼠标移到应用程序窗口上时,我得到“加载/忙碌”(动画蓝色圆圈)。此外,我不能'移动窗口。当我将样式更改为例如WS_CAPTION 时,一切正常 - 鼠标光标是“正常的”(通常只是箭头),我可以移动/拖动窗口。我怎样才能使用WS_POPUP 风格而没有我所描述的这种奇怪的副作用?

【问题讨论】:

  • 如果您想将窗口的任意部分设为“拖动句柄”,您可以处理 WM_NCHITTEST 并返回 HTCAPTION

标签: c++ visual-studio winapi gdi+


【解决方案1】:

尝试设置WNDCLASS::hCursor。这解决了光标问题。

    WNDCLASS wc = {};
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);  // <<<< HERE
    wc.lpfnWndProc = &WindowProc;
    wc.hInstance = hInstance; 
    //...

找到here

而且我不能'移动窗口

要解决这个问题,你必须实现WM_NCHITTEST 处理程序。见链接above

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
{  
    HDC hdc;  
    PAINTSTRUCT ps;  
    HWND minimize_button, close_button, demo_button;  
    static int X, Y;  
    LRESULT move = NULL;  
    LPDRAWITEMSTRUCT pdis;  
    HICON hIcon;  
    RECT rc;  
    POINT pt;  

    switch (message)  
    {
    case WM_NCHITTEST:  
        GetCursorPos(&pt);  
        GetWindowRect(hwnd, &rc);  
        rc.bottom = rc.bottom - 466;  

        //if cursor position is within top layered drawn rectangle then  
        //set move to HTCAPTION for moving the window from its client  
        if (pt.x <= rc.right && pt.x >= rc.left 
                             && pt.y <= rc.bottom 
                             && pt.y >= rc.top)  
        {  
            move = DefWindowProc(hwnd, message, wParam, lParam);  
            if (move == HTCLIENT)  
            {  
                move = HTCAPTION;  
            }  
        }  

        return move;  
// ... 

【讨论】:

    猜你喜欢
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 2012-07-17
    • 2012-10-11
    • 2011-06-21
    相关资源
    最近更新 更多