1

Тема: Змінити колір вікна Winapi

Змінити колір вікна заливки на червоний жовтий синій зелений та чорний
P.S. HBRUSH COLOR WINDOW +1 пробував міняти на +9 синій

2

Re: Змінити колір вікна Winapi

22y написав:

Змінити колір вікна заливки

Саме якого вікна, та відносно чого визначаємо подію зміни кольорів?

3

Re: Змінити колір вікна Winapi

Не визначаємо а призначаємо. Відносно того що вибере в меню користувач.
Вікно створюється із програми. Ну стандартний шаблон  Windows Application в  DevCpp

4

Re: Змінити колір вікна Winapi

Буде відповідь чи ні? В інших темах хоч якісь відповіді є

5 Востаннє редагувалося wander (13.10.2020 16:10:09)

Re: Змінити колір вікна Winapi

22y написав:

Буде відповідь чи ні? В інших темах хоч якісь відповіді є

Так, ви надайте адекватний опис проблеми, що пробували, чого не пробували, можливо, якийсь уривок коду.
Що це за вікно діалогове чи ви самі реєструєте своє, якщо так, то як саме?

Чи ви спробували один варіант, у вас не вийшло і ви вирішили здатися?

P.S. - тут не сидять Ванги.
P.S.S. - ви пробували обробляти повідомлення WM_ERASEBKGND?

Подякували: Yola1

6

Re: Змінити колір вікна Winapi

Спробуйте додати оцей обробник у вашу WindowProc

case WM_ERASEBKGND: 
    hdc = (HDC) wParam; 
    GetClientRect(hwnd, &rc); 
    SetMapMode(hdc, MM_ANISOTROPIC); 
    SetWindowExtEx(hdc, 100, 100, NULL); 
    SetViewportExtEx(hdc, rc.right, rc.bottom, NULL); 
    FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH)); 

  return 1L; 

Не забудьте повернути ненульове значення, якщо ви обробили це повідомлення.

Або ось ще варіант:

case WM_PAINT:
{
    LPPAINTSTRUCT lpps = new PAINTSTRUCT;
    HDC hdc = BeginPaint(hWnd, lpps);
    hbrBackground = CreateSolidBrush(RGB(241, 245, 251));
    FillRect(hdc, &lpps->rcPaint, hbrBackground);
}
Подякували: 22y, leofun012

7

Re: Змінити колір вікна Winapi

Дякую, але насправді коду в мене немає.
Я пробував поки що в WindowsApplication Dev-Cpp   в функції int winapi winmain, в wndclassex
hbrBackground=(HBRUSH) COLOR_WINDOW+1;
поміняв на
hbrBackground=(HBRUSH) COLOR_WINDOW+9;
і після компіляції вікно стало синім. А треба додати туди щось замість COLOR_WINDOW+1,   щоб воно стало зеленим, жовтим та червоним.
Потім треба створити кнопки за допомогою функції CreateWindow у WM_CREATE та розмістити їх в ряд по горизонталі. А потім треба у WM_COMMAND switch LOWORD iParam  обробляти натискання тих кнопок і перестворювати вікно. Викликати DestroyWindow, RegisterClassEx та  CreateWindow, ShowWindow.
Спочатку треба створити  def.h:
#define BUTTON_RED 1
#define BUTTON_YELLOW 2
#define BUTTON_GREEN 3
#define BUTTON_BLUE 4
А потім в CreateWindow   вказати (HMENU) BUTTON_RED
А в switch LOWORD  iParam
case BUTTON_RED:   перестворити вікно з красним фоном

8

Re: Змінити колір вікна Winapi

Короче я не знаю як те зробити, колись робив та забув, ось по пам'яті все з того коду що пригадав, з коду створення кнопок. Гуглив гуглив довго але не знайшов

9

Re: Змінити колір вікна Winapi

COLOR_WINDOW+1 - це якийсь брудний хак; значення COLOR_WINDOW 5, і цим номером кодується звичайний колір вікна; 6 - це COLOR_WINDOWFRAME, колір рамки, а 14 - колір виділеного тексту COLOR_HIGHLIGHTTEXT.

https://docs.microsoft.com/uk-ua/window … etsyscolor

Якщо вам треба саме зелений колір, то

hbrBackground= CreateSolidBrush(RGB(0,255,0));
...
//коли вже не треба
DeleteObject(hBrush);

https://docs.microsoft.com/uk-ua/window … solidbrush

Але це якщо задавати тло на початку. Якщо вам треба саме змінювати під час роботи програми, то треба WM_ERASEBKGND обробляти.

Подякували: 22y, leofun012

10

Re: Змінити колір вікна Winapi

Щоб задати вікну конкретний колір, використовуйте функцію CreateSolidBrush: https://docs.microsoft.com/uk-ua/window … solidbrush Там де ви присвоюєте hbrBackground.

Подякували: 22y1

11

Re: Змінити колір вікна Winapi

О, одночасно з koala написав.

22y
А для чого воно взагалі треба? Це якась лаба, чи ви хочете, щоб програма робила щось корисне?

12

Re: Змінити колір вікна Winapi

Дякую. Це я зробив.
WNDCLASSEX wc;
wc.hbrBackground=CreateSolidBrush(RGB(255, 0, 0));
і вікно стало червоним. А RGB (0, 255, 0) зеленим.
Потім створив функцію.

HWND CreateNewWindow(int BgColor, HINSTANCE hInstance)
{
HWND hWnd;
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize=sizeof(WNDCLASSEX);
wc.lpfnWndProc=WndProc;
wc.hInstance=hInstance;
wc.hCursor=LoadCursor(NULL, IDC_ARROW);
switch(BgColor)
{
case 1:
 wc.hbrBackground=CreateSolidBrush(RGB(255, 0, 0));
break;
case 2:
 wc.hbrBackground=CreateSolidBrush(RGB(0, 255, 0));
break;
case 3:
 wc.hbrBackground=CreateSolidBrush(RGB(0, 0, 255));
break;
}
wc.lpszClassName="Window Class";
//далі йде довгий текст який лінь набирати
RegisterClassEx(&wc);
hWnd=CreateWindow();//довгий текст
return hWnd;
}

Так от я викликаю HWND h=CreateNewWindow(1, hInstance); Вікно червоне . Sleep(10000);
DestroyWindow(h); Далі знову CreateNewWindow(2, hInstance);
А вікна немає! Використовую ShowWindow() і немає. Може не можна повторно реєструвати  WNDCLASSEX але як його розреєструвати?


P.S. Пишу з поламаної напівживої мобіли, яка постійно сама по собі вимикається, тож нервів написати щось більше нема!!! Так ви ні в чому не винні просто так сталося.. А з компа зайти не можу бо чомусь не конектиться до нього цей телефон, а ще недавно конектився пару днів назад. Фото намагався завантажити - теж не вийшло.
Не для користі і не для лаби. Просто хочу пригадати як це робиться. Десь пів року тому C++  закинув і зовсім розучився, навіть з довідником тепер не можу

13 Востаннє редагувалося koala (14.10.2020 20:33:18)

Re: Змінити колір вікна Winapi

Це не C++, це WinAPI.
Ви створюєте клас вікон з потрібним вам тлом (RegisterClassEx), а потім вікно цього класу (CreateWindow). При другому виклику CreateNewWindow ви вдруге намагаєтеся створити той самий клас - звісно, невдало, бо такий клас вже зареєстрований вами.

https://docs.microsoft.com/uk-ua/window … erclassexa

Якщо ви дійсно хочете йти цим шляхом, можете реєструвати одразу кілька класів і створювати такі вікна. Приблизно так:

/*перед першим викликом CreateWindow*/
char WINDOW_CLASS_NAMES[3][20] = {"Window Class Red","Window Class Green", "Window Class Blue"};
for(int BgColor=1;BgColor<=3;++BgColor){
    WNDCLASSEX wc;
    ...
    switch(BgColor)
   {
   case 1:
      wc.hbrBackground=CreateSolidBrush(RGB(255, 0, 0));
    break;
    ...
    }
    wc.lpszClassName=WINDOW_CLASS_NAMES[BgColor-1]; //беремо з масиву назв
    ...
    RegisterClassEx(&wc);
}
...
HWND CreateNewWindow(int BgColor, HINSTANCE hInstance)
{
    HWND hWnd=CreateWindow(WINDOW_CLASS_NAMES[BgColor-1], ...);
    ...
Подякували: leofun01, 22y, Torbins3

14

Re: Змінити колір вікна Winapi

Нарешті, підключився до ноута... ...
Ну короче ось код:

#include <windows.h>
#define RED 1
#define YELLOW 2
#define BLUE 3
#define GREEN 4
char* alphabet="QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
char* clname=new char[10];
int counter[10]={0,};
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
HWND CreateNewWindow(int BgColor, HINSTANCE hInstance)
{
    int len=strlen(alphabet);
    for (int i=9; i>=0; i--)
    {
        if(counter[i]<len) {
            counter[i]++; break;
        }
    }
    for (int i=0; i<10; i++)
    {
        clname[i]=alphabet[counter[i]];
    }
    MessageBox(0, clname, clname, 0);
    HWND hWnd;
    WNDCLASSEX wc;
    memset(&wc,0,sizeof(wc));
    wc.cbSize         = sizeof(WNDCLASSEX);
    wc.lpfnWndProc     = WndProc; 
    wc.hInstance     = hInstance;
    wc.hCursor         = LoadCursor(NULL, IDC_ARROW);
    
    
    switch(BgColor)
    {
       case RED:
               wc.hbrBackground = CreateSolidBrush(RGB(255, 0, 0));
               break;
       case GREEN:
               wc.hbrBackground = CreateSolidBrush(RGB(0, 255, 0));
               break;
       case BLUE:
               wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));
               break;
       default:
            wc.hbrBackground = CreateSolidBrush(RGB(255, 0, 0));    
        
    }
    wc.lpszClassName=clname;
    wc.hIcon= LoadIcon(NULL, IDI_APPLICATION); 
    wc.hIconSm= LoadIcon(NULL, IDI_APPLICATION); 

    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }
       
       hWnd=CreateWindowEx(WS_EX_CLIENTEDGE,clname,"Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, /* x */
        CW_USEDEFAULT, /* y */
        640, /* width */
        480, /* height */
        NULL,NULL,hInstance,NULL);
        
ShowWindow(hWnd, SW_SHOW);
    return hWnd;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch(Message) {
        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }
        
        
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    MSG msg; 

    Sleep(10000);
    HWND h=CreateNewWindow(RED, hInstance);
    
    Sleep(10000);
    DestroyWindow(h);
    
    h=CreateNewWindow(BLUE, hInstance); 
    
    Sleep(10000);
    DestroyWindow(h);
    
    h=CreateNewWindow(GREEN, hInstance);
    
    while(GetMessage(&msg, NULL, 0, 0) > 0) { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
    return msg.wParam;
}

І знову не працює. Повідомлення: QQQQQQQQQW (все норм), далі з'являється червоне вікно, далі з'являється чорне вікно - замість повідомлення QQQQQQQQQE і завершення програми без видимого вильоту.
Це я зробив щоб реєструвати клас під час роботи, а не до. А також щоб можна було понастворювати купу різних кольорів фону під час роботи програми (введених користувачем), а не чекати 3 години генерації тих класів (у 255*255*255 варіантах).
Мені потрібно розібратися, чому метод такої генерації імен класів не працює. Бо такий метод я міг би використовувати не тільки для фону, а просто для перестворення вікон (це окрема тема)
Проте для цього я його вирішив не використовувати. Буду використовувати ваш варіант. Прошу пояснити, як використовувати ваш варіант (WM_ERASEBKGND це системне повідомлення з приставкою WM, до чого тут дії користувача)?

15

Re: Змінити колір вікна Winapi

Стрічка має закінчуватися на нульовий символ, і це варто вивчити до того, як лізти в WinAPI.
І це - не дії користувача, це - системні повідомлення. Вам треба перемальовувати вікно - в Windows це треба робити в обробниках відповідних подій. Захочете потім перемалювати - створите подію.

16

Re: Змінити колір вікна Winapi

22y написав:

А також щоб можна було понастворювати купу різних кольорів фону під час роботи програми (введених користувачем), а не чекати 3 години генерації тих класів (у 255*255*255 варіантах).

Сумніваюся, що система дасть вам створити стільки класів. Якщо уже хочеться мати можливість налаштовування, то треба просто перемальовувати вікно потрібним кольором. Тут вище уже писали про це.

Але взагалі, я не бачу сенсу витрачати час на WinAPI. Якщо хочеться повправлятися у програмуванні, то поставте собі Qt Creator або C++Builder Community Edition. Там ви зможете нормально кодити, не витрачаючи час на усілякі дурниці.