Winapi can't draw after the first draw function call

-1

so i tried to create a little graphic interface with Windows GDI. I created a Window and made two functions that draw to the client area clearClientRect() which should fill the client area whith a color and drawShape() which might not be the most fitting name but it's okay for me. drawShape() should receive a list of Dot objects i defined in geometry.hpp and a flag which should determine how they shall be interpreted.

Now the problem is if i call them in the message loop or in the WM_PAINT message (i tried both separately) only the first called function of them will draw to my window once; and after that it seems like no function can draw to my window again. I now wonder if i mishandled some of the handles or haven't freed a resource which now locks other resourcess but i can not figure out the problem.

Also my program seems to mess up the command prompt i'm using it from; thats why i think i'm mishandling some handles. The prompt's text overlaps and seems to lose all formatting and also clear or cls won't fix it until i restart it.

Please feel free to criticize my code as well since it helps to improve it. Below my code:

main.cpp

#include <iostream>
#include <windows.h>
#include "geometry.hpp"


using namespace std;


HWND init(HINSTANCE hInstance, const int x, const int y, const int w, const int h);
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void drawShape(HWND hWnd, const DotBuffer & dots, const uint8_t shapeType);
void clearClientRect(HWND hWnd, const COLORREF color);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow) {
    HWND window = init(hInstance, 100, 100, 800, 600);
    if(window == NULL) {
        cout << "Error while initializing: " << GetLastError() << endl;
        return 1;
    }
    ShowWindow(window, cmdShow);
    UpdateWindow(window);

    DotBuffer dots;
    dots.push_back(Dot(100, 100, 0x00FF0000, 3));
    dots.push_back(Dot(200, 100, 0x00FF0000, 10));
    dots.push_back(Dot(100, 500, 0x00FF0000, 30));
    MSG msg;
    while(msg.message != WM_QUIT) {
        if(PeekMessage(&msg, window, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        } else {
            clearClientRect(window, 0x00000000);
            drawShape(window, dots, ST_DOTLIST);
        }
    }

    return 0;
}


LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_KEYDOWN:
            switch(wParam) {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    break;
            }
            return 0;
    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}


void drawShape(HWND hWnd, const DotBuffer & dots, const uint8_t shapeType) {
    if(shapeType & ST_DOTLIST) {
        PAINTSTRUCT ps;
        HDC dc;

        dc = BeginPaint(hWnd, &ps);
            for(DotBuffer::const_iterator dot = dots.begin(); dot != dots.end(); dot++) {
                RECT dotRect;
                dotRect.left = dot->x;
                dotRect.top = dot->y;
                dotRect.right = dot->x + dot->thickness;
                dotRect.bottom = dot->y + dot->thickness;
                HBRUSH brush = CreateSolidBrush(dot->color);
                FillRect(dc, &dotRect, brush);
            }
        EndPaint(hWnd, &ps);
    }

}


void clearClientRect(HWND hWnd, const COLORREF color) {
    PAINTSTRUCT ps;
    RECT clientRect;
    GetClientRect(hWnd, &clientRect);
    HBRUSH solidBrush = CreateSolidBrush(color);
    HDC dc = BeginPaint(hWnd, &ps);
        FillRect(dc, &clientRect, solidBrush);
    EndPaint(hWnd, &ps);
}


HWND init(HINSTANCE hInstance, const int x, const int y, const int w, const int h) {
    WNDCLASSEX windowClass = {
        sizeof(WNDCLASSEX),
        CS_HREDRAW | CS_VREDRAW,
        windowProc,
        0,
        0,
        hInstance,
        NULL,
        NULL,
        (HBRUSH)COLOR_WINDOW,
        "windowClass",
        "windowClass",
        NULL
    };
    if(RegisterClassEx(&windowClass) == 0) {
        cout << "Error while registering class: " << GetLastError() << endl;
        return NULL;
    }

    return CreateWindowEx(
        WS_EX_TOPMOST,
        "windowClass",
        "Window",
        WS_POPUP,
        x, y,
        w, h,
        NULL,
        NULL,
        hInstance,
        NULL
    );
}

geometry.hpp

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP


#include <vector>
#include <windows.h>


enum {
    ST_DOTLIST = 0x01,
    ST_DOTSTRIP = 0x02,
    ST_TRIANGLELIST = 0x03,
    ST_TRIANGLESTRIP = 0x04
};


struct Dot {
    int x;
    int y;

    COLORREF color;
    int thickness;

    Dot(const int x, const int y, const COLORREF color, const int thickness):
        x(x),
        y(y),
        color(color),
        thickness(thickness)
    {}
};


typedef std::vector<Dot> DotBuffer;


#endif /* GEOMETRY_HPP */
c++
winapi
gdi
asked on Stack Overflow Sep 13, 2018 by Yastanub

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0