Изменить цвет фона окна кнопкой с помощью winapi - PullRequest
0 голосов
/ 05 мая 2018

Я пытаюсь заставить кнопку менять цвет фона окна при нажатии. Я знаю, что мне нужно обработать это событие в WM_COMMAND, где я также проверяю идентификатор этой кнопки, но ничего не происходит. Я попытался отладить, и моя программа распознает идентификатор правильно. Часть кода, используемая для изменения цвета, хорошо работает в основном цикле, но ничего не делает в WM_COMMAND. Как мне решить эту проблему? Весь код:

#include <Windows.h>
#define BUTTON_ID 100

struct status_info {
    const char* waiting = "Waiting for connection...";
    const char* connected = "Connected.\nWaiting for frajer to copy number.";
    const char* changed = "Number changed.";

}status_info;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) {

const wchar_t CLASS_NAME[] = L"Name";

WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = (LPCSTR)CLASS_NAME;
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);

RegisterClass(&wc);
//main window
HWND hwnd = CreateWindowEx(0, (LPCSTR)CLASS_NAME, (LPCSTR)"Hacker", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL);
//number window
HWND number = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT("Static"), TEXT("Account number:\n00 1234 1234 1234 1234 1234 1234"), WS_CHILD | WS_VISIBLE, 5, 5, 240, 40, hwnd, NULL, NULL, NULL);
//status window
const char* status_message = status_info.waiting;
HWND status = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT("Static"), TEXT(status_message), WS_CHILD | WS_VISIBLE, 5, 55, 240, 40, hwnd, NULL, NULL, NULL);
//button
HWND button = CreateWindowEx(0, "BUTTON", "Nightmode", WS_CHILD | WS_VISIBLE, 100, 100, 150, 30, hwnd, (HMENU)BUTTON_ID, hInstance, NULL);
MSG msg;
WNDCLASS okno;

while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);

    SetWindowText(status, status_message);
}
return msg.wParam;

return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
    //MessageBox(hwnd, L"1", L"1", 0);
    return (0);

case WM_DESTROY:
    //MessageBox(hwnd, L"2", L"2", 0);
    PostQuitMessage(0);
    return (0);

case WM_COMMAND: {
    if (LOWORD(wParam) == BUTTON_ID) {
        PAINTSTRUCT ps;
        RECT rc;
        HDC hdc = BeginPaint(hwnd, &ps);
        GetClientRect(hwnd, &rc);
        SetBkColor(hdc, BLACK_BRUSH);
        ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, 0, 0, 0);
        EndPaint(hwnd, &ps);
    }
    break;
}

default:
    return DefWindowProc(hwnd, message, wParam, lParam);
}
}

1 Ответ

0 голосов
/ 05 мая 2018

BeginPaint / EndPaint следует использовать в ответ только на WM_PAINT.

Вы можете использовать GetDC(hwnd)/ReleaseDC(hwnd, hdc) для получения hdc для рисования в контексте устройства вне WM_PAINT, но это будет временно. Следующее сообщение об обновлении приводит к тому, что окно стирается и перерисовывается в соответствии с тем, что указано в WM_PAINT

SetDCBrushColor можно использовать, если целью является избежать создания ручки кисти.

static COLORREF bkcolor = RGB(255,255,255);
switch(message)
{
case WM_COMMAND:
    if(LOWORD(wparam) == BUTTON_ID)
    {
        bkcolor = RGB(255, 0, 0);
        InvalidateRect(hwnd, NULL, TRUE);
    }
    break;

case WM_PAINT:
{
    PAINTSTRUCT ps;
    RECT rc;
    HDC hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rc);
    SetDCBrushColor(hdc, bkcolor);
    FillRect(hdc, &rc, (HBRUSH)GetStockObject(DC_BRUSH));

    //or use ps.rcPaint to repaint only the section which requires update
    //FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(DC_BRUSH));

    EndPaint(hwnd, &ps);
    return 0;
}

case WM_ERASEBKGND:
    //return 0 means WM_PAINT handles the background
    return 0;

В качестве альтернативы используйте SetClassLongPtr для замены кисти фона:

static HBRUSH bkbrush = NULL;
switch(message)
{
case WM_COMMAND:
    if(LOWORD(wparam) == BUTTON_ID)
    {
        COLORREF bkcolor = RGB(rand() % 256, rand() % 256, rand() % 256);
        if(bkbrush)
            DeleteObject(bkbrush);
        bkbrush = CreateSolidBrush(bkcolor);
        SetClassLongPtr(hwnd, GCL_HBRBACKGROUND, (LONG)bkbrush);
        InvalidateRect(hwnd, NULL, TRUE);
    }
    break;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...