С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878

Мерцание при смене вкладок

27.01.2015, 10:18. Показов 1333. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Короче нарисовал в программе фон, и теперь при смене вкладок сильно мерцает, тоесть очень заметно как сначала рисуется картинка в фоне, потом сверху нужный контрол. было пару вариантов какэ то справить,
1) сам отлавливаю WM_ERASEBKGND и возвращаю 1
2) поставил у главного окна стиль WS_CLIPCHILDREN, но это нечень подошло так как на страници имеются контролы без фона(тоесть за ними остаётся белый прямоугольник)
3) Когда я рисовал фон обычным GDI, то мерцание небыло так заметно, наверно потому что он работает быстрее и картинку грузит зарание, тоесть так

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HBITMAP background = (HBITMAP)LoadImage(NULL, L"img\\back.bmp", IMAGE_BITMAP, 1920, 1200, LR_SHARED|  LR_LOADFROMFILE );
 LRESULT CALLBACK WinInterface::WndProc ( HWND h_wnd,UINT msg,WPARAM wParam,LPARAM lParam){
 
if( msg == WM_PAINT ){
 PAINTSTRUCT ps;
        HDC hdc = BeginPaint(h_wnd, &ps);
 
        HDC     hMemDC  = CreateCompatibleDC(hdc);
        HBITMAP hOldBitmap;
        hOldBitmap = (HBITMAP) SelectObject(hMemDC, background);
        
        BOOL b = StretchBlt(hdc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hMemDC, 0, 0, 1920, 1200, SRCCOPY);
        HGDIOBJ h = SelectObject(hMemDC, hOldBitmap);
        b = DeleteDC(hMemDC);
    EndPaint(h_wnd, &ps);
 
} 
 
}
4) так как в обычном GDI теряется качество изображения, пришлось юзать gdi+ , но он зараза работает медленее

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LRESULT CALLBACK WinInterface::WndProc ( HWND h_wnd,UINT msg,WPARAM wParam,LPARAM lParam){
 PAINTSTRUCT ps;
 
if( msg == WM_PAINT ){
        HDC hdc = BeginPaint(h_wnd, &ps);
 
      Gdiplus::Graphics graphics(hdc);      
Gdiplus::Image image(L"img\\324733355.bmp");
graphics.DrawImage(&image,0,0,X_FullScreen,Y_FullScreen);
        
        b = DeleteDC(hMemDC);
    EndPaint(h_wnd, &ps);
 
}
}
5) исходя из кода выше можно придти к выводу что каждый раз как вызывается WM_PAINT он заново загружает изображение заново изменяет размеры, зглажиывает для качества и рисует.
6) В итоге я решил сделать следующие, создать новый контекст устройства, 1 раз при помощи gdi+ загоузить и отрисовать там кортинку, а потом в WM_PAINT просто копировать из одного dc в другой при помощи BitBlt

А теперь вопросы
1) Насколько мне это поможет уменшить заметность мерцания?
2) Что можно еще придуать получше
3) Почему неработает код? на фоне программы изображения нету

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
bool load = 1;
HDC compHdc;
LRESULT CALLBACK WinInterface::WndProc ( HWND h_wnd,UINT msg,WPARAM wParam,LPARAM lParam){
 
    
if( msg == WM_PAINT ){
 
        if(load){
        ::compHdc= CreateCompatibleDC(GetDC(h_wnd));
        Gdiplus::Graphics graphics(::compHdc);
        Gdiplus::Image image(L"img\\324733355.bmp");
        graphics.DrawImage(&image,0,0,X_FullScreen,Y_FullScreen);
        load = 0;
                           }
 
PAINTSTRUCT ps;
        HDC hdc = BeginPaint(h_wnd, &ps);
        BitBlt(hdc,0,0,X_FullScreen,Y_FullScreen,::compHdc,0,0,SRCCOPY);
EndPaint(h_wnd, &ps);
 
}
 
 
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.01.2015, 10:18
Ответы с готовыми решениями:

Как убрать анимацию при смене вкладок?
есть меню с вкладками, которые меняют содержимое меню при нажатии + некая анимация происходящего. так вот я хочу сделать чтобы все менялось...

Мерцание при перерисовке Controla в диалоге при resize.
В окно со стилем WS_OVERLAPPEDWINDOW добавлен control. При изменении размера окна пользователем control получает wm_paint и дико...

Ошибка при скрытии объектов при смене значения ComboBox
procedure TForm1.ComboBox2Change(Sender: TObject); begin case combobox2.ItemIndex of 0: DBGrid3.Visible:=true; // ХОЧУ ЗДЕСЬ...

4
 Аватар для Игорь с++
500 / 474 / 63
Регистрация: 26.01.2011
Сообщений: 2,033
27.01.2015, 13:05
Вот так у меня не моргает -
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
case WM_PAINT:
 
        hdc = BeginPaint(hwnd,&ps);
 
hdcMem = CreateCompatibleDC(hdc);
    hbmMem = CreateCompatibleBitmap(hdc, 900, 600);
    hOld   = SelectObject(hdcMem, hbmMem);
 
OnPaint(hdcMem, rc2,wc2);
 OnPaint(hdcMem, rc,wc);
SetBkMode(hdcMem,TRANSPARENT);
   SetTextColor(hdcMem,RGB(128,0,0));
TextOutA(hdcMem,0,0,N,strlen(N));
 
BitBlt(hdc, 0, 0, 900, 600, hdcMem, 0, 0, SRCCOPY);
 
SelectObject(hdcMem, hOld);
    DeleteObject(hbmMem);
    DeleteDC    (hdcMem);
 
        EndPaint(hwnd,&ps);
 
        break;
если нужна функция OnPaint
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void OnPaint(HDC hdc,RECT &rc,WCHAR *wc)
{
 
GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 
    Graphics g(hdc);
    g.SetPageUnit(UnitPixel);
    RectF bounds(rc.left, rc.top, rc.right, rc.bottom);
 
    // Загружаем фоновое изображение и растягиваем его на все окно
    Image bg(wc);
 
    g.DrawImage(&bg, bounds);
 
}
Добавлено через 1 минуту
Вырвано из рабочей программы
1
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
05.02.2015, 09:08
Цитата Сообщение от mh-coder Посмотреть сообщение
if( msg == WM_PAINT ){
if(load){
* * * * ::compHdc= CreateCompatibleDC(GetDC(h_wnd));
* * * * Gdiplus::Graphics graphics(::compHdc);
* * * * Gdiplus::Image image(L"img\\324733355.bmp");
Просто тихий ужас, не надо в WM_PAINT загружать никакие изображения, загрузи его в начале программы и рисуй.
0
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878
05.02.2015, 14:15  [ТС]
Цитата Сообщение от demmax2004 Посмотреть сообщение
Просто тихий ужас, не надо в WM_PAINT загружать никакие изображения, загрузи его в начале программы и рисуй.
а вы пробовали выность класс
C++ (Qt)
1
Gdiplus::Image image(L"img\\324733355.bmp");
за пределы функции?
я его вынес за LRESULT CALLBACK WinInterface::WndProc ( HWND h_wnd,UINT msg,WPARAM wParam,LPARAM lParam

и он почему-то ничего не рисует
0
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
06.02.2015, 09:04
Лучший ответ Сообщение было отмечено mh-coder как решение

Решение

Держи пример №1

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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//---------------------------------------------------------------------------
 
#include <windows.h>
#include <tchar.h>
#include <gdiplus.h>
#include <commctrl.h>
#pragma comment(lib, "gdiplus.lib")
 
using namespace Gdiplus;
 
HINSTANCE hInst;
BITMAPINFO BMI;
ULONG_PTR gdiplusToken;
UINT ImgHeight, ImgWidth;
Image *pImage;
 
LRESULT CALLBACK  WndProc(HWND, UINT, WPARAM, LPARAM);
 
WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
 
    GdiplusStartupInput gdiplusStartupInput;
    gdiplusStartupInput.GdiplusVersion = 1;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 
    WNDCLASSEX wcex;
    wcex.cbSize         = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_BTNSHADOW);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = _T("MyClass");
    wcex.hIconSm        = NULL;
 
    RegisterClassEx(&wcex);
 
    InitCommonControls();
 
    pImage = Image::FromFile(_T("mspaint.png"), TRUE);
    if(!pImage) return 0;
 
    ImgHeight = pImage->GetHeight();
    ImgWidth  = pImage->GetWidth();
 
    BMI.bmiHeader.biSize        = sizeof(BMI.bmiHeader);
    BMI.bmiHeader.biBitCount    = 32;
    BMI.bmiHeader.biHeight      = ImgHeight;
    BMI.bmiHeader.biWidth       = ImgWidth;
    BMI.bmiHeader.biPlanes      = 1;
    BMI.bmiHeader.biSizeImage   = ImgHeight * ImgWidth * (BMI.bmiHeader.biBitCount / 8);
 
 
    HWND hWndMain = CreateWindowEx(0, //WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
                                        wcex.lpszClassName,
                                        _T("Window as a picture"),
                                        WS_POPUP,
                                        CW_USEDEFAULT,
                                        CW_USEDEFAULT,
                                        ImgWidth,
                                        ImgHeight,
                                        0,
                                        NULL,
                                        hInstance,
                                        NULL);
 
 
    ShowWindow(hWndMain, SW_SHOW);
    UpdateWindow(hWndMain);
 
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage (&msg);
    }
 
    GdiplusShutdown(gdiplusToken);
 
    return (int)msg.wParam;
}
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_COMMAND:
        {
        }break;
 
        case WM_CREATE:
        {
 
 
            return 0;
        }
 
        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hDC = BeginPaint(hWnd,&ps);
            Graphics graphics(hDC);
            graphics.DrawImage(pImage, 0.f, 0.f, (float)ImgWidth, (float)ImgHeight);
            graphics.ReleaseHDC(hDC);
            EndPaint(hWnd,&ps);
            return 0;
        }
 
        case WM_RBUTTONDOWN:
        {
            DestroyWindow(hWnd);
        }break;
 
        case WM_LBUTTONDOWN:
        {
            ReleaseCapture();
            SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
        }break;
 
        case WM_DESTROY:
        {
            PostQuitMessage(0);
        }break;
 
     }
 
     return DefWindowProc(hWnd, message, wParam, lParam);
}
Добавлено через 5 минут
Пример №2

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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//---------------------------------------------------------------------------
 
#include <windows.h>
#include <tchar.h>
#include <gdiplus.h>
#include <commctrl.h>
#pragma comment(lib, "gdiplus.lib")
 
using namespace Gdiplus;
 
HINSTANCE hInst;
BITMAPINFO BMI;
ULONG_PTR gdiplusToken;
UINT ImgHeight, ImgWidth;
Image *pImage;
HDC hdcWnd, hdcMem;
HBITMAP hBitmap;
HBITMAP hOldObject;
 
LRESULT CALLBACK  WndProc(HWND, UINT, WPARAM, LPARAM);
 
WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
 
    GdiplusStartupInput gdiplusStartupInput;
    gdiplusStartupInput.GdiplusVersion = 1;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 
    WNDCLASSEX wcex;
    wcex.cbSize         = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_BTNSHADOW);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = _T("MyClass");
    wcex.hIconSm        = NULL;
 
    RegisterClassEx(&wcex);
 
    InitCommonControls();
 
    pImage = Image::FromFile(_T("mspaint.png"), TRUE);
    if(!pImage) return 0;
 
    ImgHeight = pImage->GetHeight();
    ImgWidth  = pImage->GetWidth();
 
    BMI.bmiHeader.biSize        = sizeof(BMI.bmiHeader);
    BMI.bmiHeader.biBitCount    = 32;
    BMI.bmiHeader.biHeight      = ImgHeight;
    BMI.bmiHeader.biWidth       = ImgWidth;
    BMI.bmiHeader.biPlanes      = 1;
    BMI.bmiHeader.biSizeImage   = ImgHeight * ImgWidth * (BMI.bmiHeader.biBitCount / 8);
 
 
    HWND hWndMain = CreateWindowEx(0, //WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
                                        wcex.lpszClassName,
                                        _T("Window as a picture"),
                                        WS_POPUP,
                                        CW_USEDEFAULT,
                                        CW_USEDEFAULT,
                                        ImgWidth,
                                        ImgHeight,
                                        0,
                                        NULL,
                                        hInstance,
                                        NULL);
 
 
    ShowWindow(hWndMain, SW_SHOW);
    UpdateWindow(hWndMain);
 
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage (&msg);
    }
 
    GdiplusShutdown(gdiplusToken);
 
    return (int)msg.wParam;
}
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_COMMAND:
        {
        }break;
 
        case WM_CREATE:
        {
 
 
 
            hdcWnd  = GetDC(hWnd);
            hdcMem = CreateCompatibleDC(hdcWnd);
 
            hBitmap         = CreateDIBSection(hdcMem, &BMI, DIB_RGB_COLORS, NULL, 0, 0);
            hOldObject     = (HBITMAP)SelectObject(hdcMem, hBitmap);
 
 
            Graphics graphics(hdcMem);
 
            graphics.DrawImage(pImage, 0.f, 0.f, (float)ImgWidth, (float)ImgHeight);
 
            graphics.ReleaseHDC(hdcMem);
 
 
 
            return 0;
        }
 
        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hDC = BeginPaint(hWnd,&ps);
            BitBlt(hDC, 0, 0, ImgWidth, ImgHeight, hdcMem, 0, 0, SRCCOPY);
            EndPaint(hWnd,&ps);
            return 0;
        }
 
        case WM_RBUTTONDOWN:
        {
            DestroyWindow(hWnd);
        }break;
 
        case WM_LBUTTONDOWN:
        {
            ReleaseCapture();
            SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
        }break;
 
        case WM_DESTROY:
        {
            SelectObject(hdcMem, hOldObject);
            DeleteObject(hBitmap);
            DeleteDC(hdcMem);
            ReleaseDC(hWnd, hdcWnd);
            PostQuitMessage(0);
        }break;
 
     }
 
     return DefWindowProc(hWnd, message, wParam, lParam);
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.02.2015, 09:04
Помогаю со студенческими работами здесь

При замене процессора винда не грузится, при смене памяти комп не включается
почитал схожие темы на форуме, ответа не нашел, поэтому моя ситуация: решил сменить процессор. Был Core 2 Duo E7500, стал Core 2 Quad...

Мерцание при заливке
Приветствую всех. Подскажите пожалуйста, чего я не дописал. Создаю свой итем,кидаю его на сцену, но при заливке - начинается мерцание. ...

Мерцание при Invalidate
(MFC) Вызываю в OnMouseMove MoveWindow(SetWindowPos (отключаю перерисовку)) и Invalidate Происходит мерцание, как избавиться? ...

Мерцание при перерисовке
Доброго времени суток. Есть несколько элементов(прямоугольников). При перетаскивании их мышью каждый раз все изображения перерисовываются....

Мерцание при загрузке
Здравствуйте! Проблема в след. (Видео - del]) При загрузке системы монитор начинает мерцать. Так продолжается несколько секунд, после...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru