首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Win32 API调整窗口大小

用Win32 API调整窗口大小
EN

Stack Overflow用户
提问于 2016-07-01 14:19:19
回答 1查看 5.6K关注 0票数 0

我正在用Win32 API编写一个程序,只是为了了解它的诀窍,并遇到了这个恼人的问题。经过一段时间的调整后,窗口最小化,在再次打开它之后,它是可见的,但是不可点击,点击它只会激活它下面的窗口上的内容。唯一的解决办法就是退出程序。

起初,我认为这是因为我定制了窗口大小的函数(我使用自定义gui,不想要默认的窗口sizebox边框),但后来我重新激活了默认的sizebox,问题仍然存在。这很难说,但问题似乎总是发生在大致相同的时间/滴答调整大小之后。

我以前也有一个类似的问题,窗口会最小化,当再次打开时会变成完全白色,由于某种原因,这是由调整大小的函数中的for循环引起的。

我已经排除了代码中尽可能多的潜在问题,但仍然没有找到解决方案。下面是源文件,处理如何绘制窗口的所有代码都位于源文件(带有默认大小框)。

我很感激我能得到的任何帮助。

Ps。我对任何糟糕的语言(非母语人士)、错误使用的术语或糟糕的语法表示歉意(第一次深入到API中)。

代码语言:javascript
复制
//WinMain.cpp

#include <Windows.h>

#include "Utility.h"
#include "Mouse.h"
#include "AppInfo.h"
#include "Buttons.h"

//Function prototypes
ATOM MainRegister();
bool MainInit(HWND &hWnd, int nCmdShow);
void MatchRectToWnd(RECT &rect);

//Variables define in AppInfo.h
HRGN rgnMain, rgnCaptionbar;
bool _APPRUNNING = true;
const char _APPTITLE[] = "Dark";

//Variables
bool WIREFRAME = false;

//Pointers to buttons (singelton design)
btnCloseClass * btnCloseClass::s_Instance = 0;
btnMaximizeClass * btnMaximizeClass::s_Instance = 0;
btnMinimizeClass * btnMinimizeClass::s_Instance = 0;

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_LBUTTONDBLCLK: //Left mouse button double-clicked
        Mouse.CheckDblClick(hWnd, wParam);
        Mouse.m_Pressed = false;
    break;
    case WM_LBUTTONDOWN: //Left mouse button clicked
        //Update the mouse position variables
        GetCursorPos(&Mouse.prevPt);
        GetCursorPos(&Mouse.m_LastClick);

        Mouse.m_Pressed = true; 

        Mouse.CheckClickDown(hWnd);
    break;
    case WM_LBUTTONUP: //Left mouse button released
    {
        GetCursorPos(&Mouse.prevPt);
        Mouse.CheckClickUp(hWnd);
        Mouse.m_Pressed = false;
    }
    break;
    case WM_SIZE: //Check if the window has been resized
    {
        //Update the buttons
        btnClose->Update(hWnd);
        btnMaximize->Update(hWnd);
        btnMinimize->Update(hWnd);

        //Update the regions
        RECT rect; GetWindowRect(hWnd, &rect);
        rgnMain = CreateRectRgn(0, 0, rect.right - rect.left, rect.bottom- rect.top);
        rgnCaptionbar = CreateRectRgn(0, 0, rect.right - rect.left, CAPTIONBAR_HEIGHT);

    }
    break;
    case WM_PAINT: //Draw the window
    {
        HDC hdc;
        PAINTSTRUCT ps;
        HBRUSH hBrush;

        hdc = BeginPaint(hWnd, &ps);

        //Color the mainregion
        hBrush = CreateSolidBrush(COLOR_MAIN);
        FillRgn(hdc, rgnMain, hBrush);

        //Color the captionbarregion
        hBrush = CreateSolidBrush(COLOR_CAPTIONBAR);
        FillRgn(hdc, rgnCaptionbar, hBrush);

        //Color the button backgrounds
        hBrush = CreateSolidBrush(COLOR_BUTTON_BACKGROUND);
        FillRgn(hdc, btnClose->GetRegion(), hBrush);
        FillRgn(hdc, btnMinimize->GetRegion(), hBrush);
        FillRgn(hdc, btnMaximize->GetRegion(), hBrush);

        //Color the button icons
        hBrush = CreateSolidBrush(COLOR_BUTTON_ICON);
        FillRgn(hdc, btnClose->GetIcon(), hBrush);
        FillRgn(hdc, btnMinimize->GetIcon(), hBrush);
        FillRgn(hdc, btnMaximize->GetIcon(), hBrush);

        //Paint the wireframe
        if (WIREFRAME)
        {
            hBrush = CreateSolidBrush(COLOR_WIREFRAME);
            FrameRgn(hdc, rgnMain, hBrush, 1, 1);
            FrameRgn(hdc, rgnCaptionbar, hBrush, 1, 1);
            FrameRgn(hdc, btnClose->GetRegion(), hBrush, 1, 1);
            FrameRgn(hdc, btnMaximize->GetRegion(), hBrush, 1, 1);
            FrameRgn(hdc, btnMinimize->GetRegion(), hBrush, 1, 1);
            FrameRgn(hdc, btnClose->GetIcon(), hBrush, 1, 1);
            FrameRgn(hdc, btnMaximize->GetIcon(), hBrush, 1, 1);
            FrameRgn(hdc, btnMinimize->GetIcon(), hBrush, 1, 1);
        }

        //Free up memomry
        DeleteObject(hBrush);
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_TAB: //If TAB is pressed
        {
            if (WIREFRAME) //Activate the wireframe
                WIREFRAME = false;
            else
                WIREFRAME = true;
            InvalidateRgn(hWnd, NULL, true);
        }
            break;
        case VK_ESCAPE: //If the ESCAPE is pressed
            PostMessage(hWnd, WM_DESTROY, 0, 0);
            break;
        }
    }
    break;
    case WM_DESTROY: //Free up memory and exit the program
        _APPRUNNING = false;
        DeleteObject(rgnMain);
        DeleteObject(rgnCaptionbar);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);
        break;
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hWnd;
    MSG msg;
    _APPRUNNING = true;

    //Register the main window
    if (!MainRegister())
    {
        MessageBox(hWnd, "Error registering main window!", "Error", MB_ICONERROR);
        return false;
    }

    //Initialize the main window
    MainInit(hWnd, nCmdShow);

    //App-loop
    while (_APPRUNNING)
    {
        if ((GetKeyState(VK_LBUTTON) & 0x80) == 0) //Make sure the mouse's status gets updated
        {
            Mouse.m_Pressed = false;
        }
        Mouse.Update(hWnd);

        //Message-loop
        if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
}

bool MainInit(HWND &hWnd, int nCmdShow)
{
    //Create the window
    hWnd = CreateWindowEx(
        WS_EX_LAYERED,
        _APPTITLE,
        _APPTITLE,
        WS_OVERLAPPEDWINDOW,
        0, 0, //Starting positons (x,y)
        START_WIDTH, START_HEIGHT, //Width and height
        NULL, //Parent-handle
        NULL, //Menu-handle
        GetModuleHandle(NULL),
        NULL);

    //Make sure the window was created properly
    if (hWnd == NULL)
    {
        MessageBox(hWnd, "Error initializing main window!", "Error!", MB_ICONERROR);
        return false;
    }

    SetLayeredWindowAttributes(hWnd, NULL, NULL, NULL);

    //Get and set the window's style
    DWORD wndStyle = GetWindowLong(hWnd, GWL_STYLE);
    wndStyle &= ~(WS_CAPTION);
    SetWindowLong(hWnd, GWL_STYLE, wndStyle);

    //Create regions
    rgnMain = CreateRectRgn(0, 0, START_WIDTH, START_HEIGHT);
    rgnCaptionbar = CreateRectRgn(0, 0, START_WIDTH, CAPTIONBAR_HEIGHT);

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

    return true;
}

ATOM MainRegister()
{
    //Create the window's classEx (extended class)
    WNDCLASSEX wc;
    wc.cbClsExtra = 0;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = NULL;
    wc.hIconSm = NULL;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = MainWndProc;
    wc.lpszClassName = _APPTITLE;
    wc.lpszMenuName = NULL;
    wc.style = CS_DBLCLKS;

    //Register the classEx
    return RegisterClassEx(&wc);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-03 07:24:21

正如@CodyGray建议的那样,这是工作代码、类和处理释放区域内存的函数,现在也是刷子。

编辑:这个问题是由于创建而不是删除画笔(HBRUSH)时WM_PAINT中的内存泄漏造成的。

代码语言:javascript
复制
//WinMain.cpp

#include <Windows.h>

#include "Utility.h"
#include "Mouse.h"
#include "AppInfo.h"
#include "Buttons.h"

//Function prototypes
ATOM MainRegister();
bool MainInit(HWND &hWnd, int nCmdShow);
void MatchRectToWnd(RECT &rect);

//Variables define in AppInfo.h
HRGN rgnMain, rgnCaptionbar;
bool _APPRUNNING = true;
const char _APPTITLE[] = "Dark";

//Variables
bool WIREFRAME = false;

//Pointers to buttons (singelton design)
btnCloseClass * btnCloseClass::s_Instance = 0;
btnMaximizeClass * btnMaximizeClass::s_Instance = 0;
btnMinimizeClass * btnMinimizeClass::s_Instance = 0;

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_LBUTTONDBLCLK: //Left mouse button double-clicked
        Mouse.CheckDblClick(hWnd, wParam);
        Mouse.m_Pressed = false;
    break;
    case WM_LBUTTONDOWN: //Left mouse button clicked
        //Update the mouse position variables
        GetCursorPos(&Mouse.prevPt);
        GetCursorPos(&Mouse.m_LastClick);

        Mouse.m_Pressed = true; 

        Mouse.CheckClickDown(hWnd);
    break;
    case WM_LBUTTONUP: //Left mouse button released
    {
        GetCursorPos(&Mouse.prevPt);
        Mouse.CheckClickUp(hWnd);
        Mouse.m_Pressed = false;
    }
    break;
    case WM_SIZE: //Check if the window has been resized
    {
        DeleteObject(rgnMain);
        DeleteObject(rgnCaptionbar);

        //Update the buttons
        btnClose->Update(hWnd);
        btnMaximize->Update(hWnd);
        btnMinimize->Update(hWnd);

        //Update the regions
        RECT rect; GetWindowRect(hWnd, &rect);
        rgnMain = CreateRectRgn(0, 0, rect.right - rect.left, rect.bottom- rect.top);
        rgnCaptionbar = CreateRectRgn(0, 0, rect.right - rect.left, CAPTIONBAR_HEIGHT);
    }
    break;
    case WM_PAINT: //Draw the window
    {

        HDC hdc;
        PAINTSTRUCT ps;
        HBRUSH hBrush;

        hdc = BeginPaint(hWnd, &ps);

        //Color the mainregion
        hBrush = CreateSolidBrush(COLOR_MAIN);
        FillRgn(hdc, rgnMain, hBrush);
        DeleteObject(hBrush);

        //Color the captionbarregion
        hBrush = CreateSolidBrush(COLOR_CAPTIONBAR);
        FillRgn(hdc, rgnCaptionbar, hBrush);
        DeleteObject(hBrush);

        //Color the button backgrounds
        FillRgn(hdc, btnClose->GetRegion(), btnClose->GetBrush());
        FillRgn(hdc, btnMinimize->GetRegion(), btnMinimize->GetBrush());
        FillRgn(hdc, btnMaximize->GetRegion(), btnMaximize->GetBrush());

        //Color the button icons
        FillRgn(hdc, btnClose->GetIcon(), btnClose->GetBrushIcon());
        FillRgn(hdc, btnMinimize->GetIcon(), btnMinimize->GetBrushIcon());
        FillRgn(hdc, btnMaximize->GetIcon(), btnMaximize->GetBrushIcon());

        //Paint the wireframe
        if (WIREFRAME)
        {
            hBrush = CreateSolidBrush(COLOR_WIREFRAME);
            FrameRgn(hdc, rgnMain, hBrush, 1, 1);
            FrameRgn(hdc, rgnCaptionbar, hBrush, 1, 1);
            FrameRgn(hdc, btnClose->GetRegion(), hBrush, 1, 1);
            FrameRgn(hdc, btnMaximize->GetRegion(), hBrush, 1, 1);
            FrameRgn(hdc, btnMinimize->GetRegion(), hBrush, 1, 1);
            FrameRgn(hdc, btnClose->GetIcon(), hBrush, 1, 1);
            FrameRgn(hdc, btnMaximize->GetIcon(), hBrush, 1, 1);
            FrameRgn(hdc, btnMinimize->GetIcon(), hBrush, 1, 1);
            DeleteObject(hBrush);
        }

        //Free up memomry
        DeleteObject(hBrush);
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_TAB: //If TAB is pressed
        {
            if (WIREFRAME) //Activate the wireframe
                WIREFRAME = false;
            else
                WIREFRAME = true;
            InvalidateRgn(hWnd, NULL, true);
        }
        break;
        case VK_ESCAPE: //If the ESCAPE is pressed
            PostMessage(hWnd, WM_DESTROY, 0, 0);
        break;
        }
    }
    break;
    case WM_DESTROY: //Free up memory and exit the program
        _APPRUNNING = false;
        DeleteObject(rgnMain);
        DeleteObject(rgnCaptionbar);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);
        break;
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hWnd;
    MSG msg;
    _APPRUNNING = true;

    //Register the main window
    if (!MainRegister())
    {
        MessageBox(hWnd, "Error registering main window!", "Error", MB_ICONERROR);
        return false;
    }

    //Initialize the main window
    MainInit(hWnd, nCmdShow);

    //App-loop
    while (_APPRUNNING)
    {
        if ((GetKeyState(VK_LBUTTON) & 0x80) == 0) //Make sure the mouse's status gets updated
        {
            Mouse.m_Pressed = false;
        }
        Mouse.Update(hWnd);

        //Message-loop
        if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
}

bool MainInit(HWND &hWnd, int nCmdShow)
{
    //Create the window
    hWnd = CreateWindowEx(
        WS_EX_LAYERED,
        _APPTITLE,
        _APPTITLE,
        WS_OVERLAPPEDWINDOW,
        0, 0, //Starting positons (x,y)
        START_WIDTH, START_HEIGHT, //Width and height
        NULL, //Parent-handle
        NULL, //Menu-handle
        GetModuleHandle(NULL),
        NULL);

    //Make sure the window was created properly
    if (hWnd == NULL)
    {
        MessageBox(hWnd, "Error initializing main window!", "Error!", MB_ICONERROR);
        return false;
    }

    SetLayeredWindowAttributes(hWnd, NULL, NULL, NULL);

    //Get and set the window's style
    DWORD wndStyle = GetWindowLong(hWnd, GWL_STYLE);
    wndStyle &= ~(WS_CAPTION | WS_SIZEBOX);
    SetWindowLong(hWnd, GWL_STYLE, wndStyle);

    //Create regions
    rgnMain = CreateRectRgn(0, 0, START_WIDTH, START_HEIGHT);
    rgnCaptionbar = CreateRectRgn(0, 0, START_WIDTH, CAPTIONBAR_HEIGHT);

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

    return true;
}

ATOM MainRegister()
{
    //Create the window's classEx (extended class)
    WNDCLASSEX wc;
    wc.cbClsExtra = 0;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = NULL;
    wc.hIconSm = NULL;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = MainWndProc;
    wc.lpszClassName = _APPTITLE;
    wc.lpszMenuName = NULL;
    wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

    //Register the classEx
    return RegisterClassEx(&wc);
}

//Button.h
//Header file for the class responsible for handling the memory of the
//regions and brushes
class Button
{
protected:
    //Protected default constructor
    Button();

    //Protected default destructor
    ~Button();

    //Protected variables
    HRGN m_Rgn;
    HRGN m_Icon;
    HBRUSH m_hBrush;
    HBRUSH m_hBrush_Icon;
    bool m_Hovered;
public:
    //Public functions
    virtual void CreateIcon() = 0;
    virtual void Update(HWND hWnd) = 0;
    bool Clicked(POINT pt);
    bool CheckIfHovered(HWND hWnd);
    HRGN GetRegion() { return m_Rgn; }
    HRGN GetIcon() { return m_Icon; }
    HBRUSH GetBrush() { return m_hBrush; }
    HBRUSH GetBrushIcon() { return m_hBrush_Icon; }
};

//Button.cpp
//Default constructor
Button::Button()
{
    m_hBrush = CreateSolidBrush(COLOR_BUTTON_BACKGROUND);
    m_hBrush_Icon = CreateSolidBrush(COLOR_BUTTON_ICON);
    m_Hovered = false;
}

//Default destructor
Button::~Button()
{
    //Free up memory
    DeleteObject(m_Rgn);
    DeleteObject(m_Icon);
    DeleteObject(m_hBrush);
    DeleteObject(m_hBrush_Icon);
}

再次感谢“CodyGray”和“阿德里安·麦卡锡”!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38147766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档