Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191

CS_SAVEBITS не отменяет WM_PAINT?

26.07.2021, 14:54. Показов 3597. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть у стилей классов окон Windows флаг CS_SAVEBITS. Согласно документации, при выводе такого окна на экран Windows запоминает накрытую им часть экрана в виде картинки, а при убирании окна не посылает нижележащим окнам сообщение WM_PAINT, а просто восстанавливает запомненную картинку.

Проверяю:
Написал примитивнейшую тестовую программу, в которой выставлено CS_HREDRAW+CS_VREDRAW+CS_SAVEBITS, и которая единственное что делает - это выводит в центре своего окна и в его заголовке счётчик пришедших WM_PAINT. Запускаю эту программу два раза, одно из окон сильно уменьшаю и накрываю им счётчик в центре второго окна, после чего, щелкая мышкой по Панели задач, маленькое окно сворачиваю-восстанавливаю, сворачиваю-восстанавливаю, сворачиваю-восстанавливаю... И обнаруживаю, что после каждого сворачивания счётчик у большого окна увеличивается на 1. То есть, сообщение WM_PAINT этому окну приходит! Почему?

(Для полноты картины: если маленькое окно не сворачивать, а просто закрыть всю программу (хоть крестиком, хоть через Панель задач), то счётчик тоже увеличивается.)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.07.2021, 14:54
Ответы с готовыми решениями:

Яндекс отменяет .... интернет?!
5 декабря сего года, известный всем господин А.Садовский сделал очередное заявление, которое как пишут некоторые особо нервные интернет...

webkit отменяет скрипт
В общем ситуация такова. После перезагрузки (через простую кнопку обновить страницу или через F5, ctrl+F5) у браузеров на webkit (В Safari...

Кнопка, которая отменяет последнее действие
Доброе время суток))) Нужна помочь.... Нужно создать кнопку которая отменяет последнее действие. Так же кнопку которая возвращает...

11
Brainsbreaker
 Аватар для Digit@ll
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
26.07.2021, 21:20
Примерно воспроизвел всё по написанному в теме, счетчик увеличивается только у сворачиваемого окна при разворачивании, при изменении его размеров, при возврате его после выхода за экранную область.
При перекрытии одного окна другим, да хоть полностью развернутым любым другим, со стилем CS_SAVEBITS или без него счетчик не изменятся.
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.07.2021, 02:29  [ТС]
Я не большой знаток C++ и обычно пишу на совершенно другом языке, но сейчас залез в VisualStudio и, как сумел, соорудил там аналог того теста, с которым работал изначально.
("Как сумел" - это значит: преобразование из числа в строку по-человечески сделать так и не смог, строка тупо наращивается новыми значениями.)

Но результат работы этой программы такой же - при сворачивании второго (маленького) экземпляра у первого (большого) счётчик растёт.

Где у меня в программе ошибка?

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "stdafx.h"
#include "Win32Project1.h"
#include <string>
#include <sstream>
 
HINSTANCE hInst;
const WCHAR* szTitle = L"SAVEBITS Test";
const WCHAR* szWindowClass = L"SAVEBITS";
 
UINT Counter = 0;
const CHAR* CounterStr;
std::string Str;
std::stringstream out;
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
RECT rect;
HDC hdc;
HBRUSH hBrush;
 
    switch (message) {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            hBrush = CreateSolidBrush(RGB(0, 255, 0));
            GetClientRect(hWnd, &rect);
            FillRect(hdc, &rect, hBrush);
            DeleteObject(hBrush);
            SetTextColor(hdc, RGB(255, 255, 255));
            SetBkMode(hdc, TRANSPARENT);
            out << ++Counter;
            Str = out.str();
            CounterStr = Str.c_str();
            DrawTextA(hdc, (LPCSTR) CounterStr, -1, &rect, DT_CENTER + DT_VCENTER + DT_SINGLELINE);
            EndPaint(hWnd, &ps);
            SetWindowTextA(hWnd, (LPCSTR) CounterStr);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
ATOM MyRegisterClass(HINSTANCE hInstance) {
    WNDCLASSEXW wcex;
 
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = nullptr;
    wcex.lpszMenuName = nullptr;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    return RegisterClassExW(&wcex);
}
 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {
 
    hInst = hInstance;
 
    HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
                                               CW_USEDEFAULT, 0,
                                               CW_USEDEFAULT, 0,
                                               nullptr, nullptr, hInstance, nullptr);
 
   if (!hWnd) return FALSE;
 
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
 
   return TRUE;
}
 
 
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                                _In_opt_ HINSTANCE hPrevInstance,
                                _In_ LPWSTR lpCmdLine,
                                _In_ int nCmdShow)
{
    MSG msg;
 
    if (MyRegisterClass(hInstance) && InitInstance (hInstance, nCmdShow)) {
        while (GetMessage(&msg, nullptr, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}


Добавлено через 6 минут
Цитата Сообщение от Digit@ll Посмотреть сообщение
При перекрытии одного окна другим, да хоть полностью развернутым любым другим, со стилем CS_SAVEBITS или без него счетчик не изменятся.
Логично. Счётчик же увеличивается не когда окно перекрывают, а когда перекрывающее окно исчезает.

Добавлено через 1 час 42 минуты
Я тут присмотрелся повнимательнее к тому, что происходит при моих сворачиваниях-разворачиваниях, и появилось подозрение, что CS_SAVEBITS я несколько "переоценил": после первого сворачивания окна сообщение WM_PAINT и в самом деле не приходит, но стабильно идёт после всех последующих.

Выходит, флаг CS_SAVEBITS "одноразовый"? И картинка запоминается не при каждом появлении окна на экране, а только при самом первом?
0
Just Do It!
 Аватар для XLAT
4211 / 2670 / 655
Регистрация: 23.09.2014
Сообщений: 9,083
Записей в блоге: 3
27.07.2021, 10:52
Цитата Сообщение от tiun Посмотреть сообщение
преобразование из числа в строку по-человечески сделать так и не смог, строка тупо наращивается новыми значениями
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <sstream>
 
int main()
{   std::stringstream out;
    int  cnt = 0;
 
    while(true)
    {   out.str("");
        out << cnt++;
 
        std::cout << out.str() << "\r             \r";
    }
}
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
27.07.2021, 18:28  [ТС]
XLAT,
Спасибо. "Буду знать."

Добавлено через 14 минут
Кстати, может кому будет полезно:

Я разобрался, что происходит.
Для окон с флагом CS_SAVEBITS есть кучка условий (событий), при которых запомненное изображение становится для Windows недействительным, и потом при убирании окна потребуется перерисовка подложки. Среди этих событий: перемещение окна или изменение его размера.
А при сворачивании/разворачивании окна в него приходят сообщения WM_MOVE и WM_SIZE. Дальше понятно.

Так что да, флаг "одноразовый": картинка запоминается при создании окна, а не при каждом его появлении.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
30.07.2021, 13:31
Если вам нужно «отключить» WM_PAINT и рисовать окно самостоятельно, то сделайте окна слоёным, указав стиль WS_EX_LAYERED.
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
30.07.2021, 13:50  [ТС]
Нет-нет, мне было нужно, чтобы при исчезновении моего окна с экрана нижележащие окна не получали WM_PAINT.

Но вся идея с исчезновением окна - это попытка (способ) решения другой задачи: добраться до пикселов изображения в области экрана, лежащей под окном моей программы. Причём идея изначально корявая. А я уже нашёл другой, идеальный способ получить желаемое.
К моему удивлению - именно с использованием WS_EX_LAYERED.
(К удивлению - потому что это побочный эффект данного флага, в документации не описанный.)
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
30.07.2021, 18:04
Начиная с Висты, сообщение WM_PAINT при перекрытии окон не отправляется: система хранит картинку окна и показывает её самостоятельно.
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
30.07.2021, 18:10  [ТС]
Да? А как в таком случае можно объяснить результаты эксперимента, о котором говорится в моём первом сообщении?
0
фрилансер
 Аватар для Алексей1153
6465 / 5678 / 1131
Регистрация: 11.10.2019
Сообщений: 15,118
30.07.2021, 18:24
Цитата Сообщение от Замабувараев Посмотреть сообщение
Начиная с Висты, сообщение WM_PAINT
да ладно? А я на семёрке и десятке не один раз в отладке (в MFC-шном проекте) проводил калькулятором поверх окна, чтобы спровоцировать попадание в OnPaint. Как же так ? Не сходится история
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
30.07.2021, 20:28
Цитата Сообщение от Педивикия
В Windows Vista появилась модель драйверов WDDM, в которой была отменена возможность использования аппаратуры двухмерной графики. При использовании WDDM все GDI-приложения (то есть все обычные системные части Windows UI — заголовки и рамки окон, рабочий стол, панель задач и другое) используют GDI-драйвер cdd.dll (Canonical Display Driver)[1], который рисует на некоторых битмапах в памяти, своих для каждого окна (содержимое окна стало запоминаться в памяти, до того Windows никогда так не делала и всегда перерисовывала окна заново, кроме неких специальных окон с флагом CS_SAVEBITS). Изображения из cdd.dll извлекаются процессом dwm.exe (Desktop Window Manager), который является Direct3D-приложением и отрисовывает «картинки окон» на физическом экране через Direct3D.
https://ru.wikipedia.org/wiki/GDI
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
30.07.2021, 20:55  [ТС]
А вот что по поводу WDDM говорит https://en.wikipedia.org/wiki/... iver_Model
It is a replacement for the previous Windows 2000 and Windows XP display driver model XDDM/XPDM and is aimed at enabling better performance graphics and new graphics functionality and stability. Display drivers in Windows Vista and Windows 7 can choose to either adhere to WDDM or to XDDM.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.07.2021, 20:55
Помогаю со студенческими работами здесь

СМА: indesit WIUL 83, Не отменяет программу
Здравствуйте, помогите пожалуйста, СМА: indesit WIUL 83, модуль Evo2 , нажимаешь кнопку вкл, включается сразу только одна программа стирки,...

Обработчик события не отменяет действия по умолчанию.
&lt;script type=&quot;text/javascript&quot;&gt; function checkNULL() { if(document.forms.add_menu.title_add.value == &quot;&quot;) ...

Отмена вложенной задачи отменяет задачу-родителя
Приветствую, Коллеги, Разбираюсь с отменой задач, при отмене (передаче токена) в Task.Delay, задача &quot;t&quot; получает статус...

Wordpress самостоятельно отменяет мои правки в коде?
Добрый день. На этой странице внизу видно что кнопка поломалась и текст ссылки находится не внутри тега a....

Яндекс.Директ отменяет "входную плату" в контекстн
Стоимость входа в рекламные показы на Яндекс.Директе с 22 сентября стала равной шагу торгов - 30 копеек (около 1 цента). По сути, отменена...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Программный отбор значения справочника
Maks 21.03.2026
Процедура ВодителиНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка) / / Отключаем стандартную обработку (стандартное открытие формы выбора без фильтров) . . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru