Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
3 / 3 / 0
Регистрация: 03.05.2013
Сообщений: 23

Не работает перерисовка всплывающего окна после его растягивания C++, WinAPI

14.03.2015, 19:06. Показов 1316. Ответов 6
Метки нет (Все метки)

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

Функция главного диалогового окна:
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
INT_PTR WINAPI MainDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
 
    case WM_COMMAND:  return (SetDlgMsgResult(hWnd, uMsg, HANDLE_WM_COMMAND(hWnd, wParam, lParam, Dlg_OnCommand)));
        break;
    case WM_INITDIALOG: return (SetDlgMsgResult(hWnd, uMsg, HANDLE_WM_INITDIALOG(hWnd, wParam, lParam, Dlg_OnInitDialog)));
        break;
    case WM_CLOSE:
        return (SetDlgMsgResult(hWnd, uMsg, HANDLE_WM_CLOSE(hWnd, wParam, lParam, Dlg_OnClose)));
    case WM_DESTROY: PostQuitMessage(0); return(FALSE);
        break;
        //default: return (FALSE);
    }
    return(FALSE);
}
 
ATOM RegisterGraphClass() {
    WNDCLASSEX wgex = { 0 }; //Wnd Graph EX
    wgex.cbSize = sizeof(WNDCLASSEX);
    wgex.style = CS_HREDRAW | CS_VREDRAW;
    wgex.lpfnWndProc = WndGraph;
    wgex.hInstance = hInst;
    wgex.hCursor = LoadCursor(NULL, IDC_CROSS);
    wgex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wgex.lpszClassName = szGraphWndClass;
    wgex.hIconSm = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON2));
    return RegisterClassEx(&wgex);
}
 
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtrl, UINT CodeNotify) { //главное окно
    static HWND hGraph;
 
    switch (id) {
    case IDCANCEL:
        EndDialog(hwnd, id); //Destroys a modal dialog box, causing the system to end any processing for the dialog box.
        break;
 
    case IDC_FILENAME:
        EnableWindow(GetDlgItem(hwnd, IDC_PLOT), Edit_GetTextLength(hwndCtrl) > 0); //если в поле пути к файлу у нас ненулевая строка, то активируем кнопку Построить
        break;
 
    case IDC_FILESELECT: {
        OPENFILENAME ofn;
        ofn.lStructSize = sizeof(OPENFILENAME); //
        ofn.hwndOwner = hwnd;
        ofn.lpstrFilter = _TEXT("Текстовые файлы\0*.txt\0\0"); // .txt files needed
        ofn.lpstrCustomFilter = NULL;
        ofn.lpstrFile = szPathname;
        ofn.lpstrFile[0] = 0;
        ofn.nMaxFile = sizeof(szPathname) / sizeof(szPathname[0]);
        ofn.lpstrFileTitle = NULL; //
        ofn.lpstrInitialDir = NULL;
        ofn.lpstrTitle = _TEXT("Выберите файл для построения");
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
        ofn.lpstrDefExt = NULL;
        GetOpenFileName(&ofn);
        SetDlgItemText(hwnd, IDC_FILENAME, ofn.lpstrFile);
        SetFocus(GetDlgItem(hwnd, IDC_PLOT)); //выделяем кнопку "Построить"
 
    }
        break;
 
    case IDC_PLOT: //Если нажали кнопку "Построить" 
    {
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//код для чтения файла
////////////////////////////////////////////////////////////////////////////////////////////////////////////
        if (IsWindow(hGraph)) {
            InvalidateRect(hGraph, NULL, TRUE);
            UpdateWindow(hGraph);
            break;
        } //если окошко с графиком уже существует в системе, то не создаем его снова, а просто перерисовываем и выходим, иначе:
        RegisterGraphClass(); //регистрируем класс окошка с графиком
        hGraph = CreateWindow(szGraphWndClass, _TEXT("Plot"), WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_SIZEBOX | WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, 700, 700, hwnd, 0, hInst, NULL);
        break;
    }
    }
}
Оконная процедура окна с графиками:
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
LRESULT CALLBACK WndGraph(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rect;
    static HPEN hline;
    static HBRUSH hrect;
    static int sx, sy;
 
    GetClientRect(hWnd, &rect);
 
    switch (message) {
    case WM_CREATE:
        sx = LOWORD(lParam);
        sy = HIWORD(lParam);
        InvalidateRect(hWnd, &rect, TRUE);
        UpdateWindow(hWnd);
        break;
 
    
    case WM_SIZE:
        sx = LOWORD(lParam);
        sy = HIWORD(lParam);
        InvalidateRect(hWnd, NULL, TRUE);
        UpdateWindow(hWnd);
        break;
 
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        DrawGraphics(hdc, points, quant, hline, hrect, sx, sy, names);
        EndPaint(hWnd, &ps);
        break;
 
    case WM_DESTROY:
        DeleteObject(hline);
        DeleteObject(hrect);
        if (!points.empty())points.resize(0); //clear points for plotting
        if (!names.empty()) names.resize(0); //clear names array
        break;
    default: return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
Функция, которая строит графики:
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
BOOL DrawGraphics(HDC hdc, vector<dot> vec, int quantity, HPEN pen, HBRUSH brush, int sx, int sy, vector<string> names) {
    double max_x, min_x, max_y, min_y, hx, hy;
    double k_x = 1.0, k_y = 1.0;
    dot *points = new dot[quantity];
    int *flag = new int[quantity];
 
    for (int i = 0; i != quantity; i++) { //нужно для определения заполненности массива с последней точкой/ 0 - ни одной точки графика не нарисовано
        flag[i] = 0;
    }
 
    max_x = vec[0].x; max_y = vec[0].y;
    min_x = vec[0].x; min_y = vec[0].x;
 
    for (vector <dot> :: iterator i = vec.begin(); i != vec.end(); i++) {
        if ((*i).x > max_x) max_x = (*i).x;
        if ((*i).x < min_x) min_x = (*i).x;
        if ((*i).y > max_y) max_y = (*i).y;
        if ((*i).y < min_y) min_y = (*i).y;
    }
        
    hx = max_x - min_x;
    hy = max_y - min_y;
 
    ProceedNames(hdc, brush, names, quantity, sx, sy);
    DrawGrid(hdc, sx, sy, max_x, min_x, max_y, min_y, hx, hy);
 
    //for (vector <dot> ::iterator i = vec.begin(); i != vec.end(); i++) {
    //  DrawPoint(hdc, (*i), k_x, k_y, points, flag, pen, brush, max_x, min_x, max_y, min_y, hx, hy,names);
    //}
 
    
 
    delete[] flag;
    delete[] points;
    return (TRUE);
}
 
const int scaleX = 6; //число меток на оси Х
const int scaleY = 6; //чисто меток на оси У
const int indent = 25; //отступ
const int GRAPHSIZE = 1200; //размер окна в логических единицах
const int GRAPHWIDTH = 1000; //размер рабочей области окна в лог.единицах
//Объявлены глобально
//функция, выводящая на экран названия графиков, считанные из файла
void ProceedNames(HDC hdc, HBRUSH brush,vector<string> names, int quantity, int sx, int sy) {
    SetMapMode(hdc, MM_ANISOTROPIC);
    SetWindowExtEx(hdc, GRAPHSIZE, -GRAPHSIZE, NULL); //window 1200x1200 logical units
    SetViewportExtEx(hdc, sx, sy, NULL); //sx x sy client area 
    SetViewportOrgEx(hdc, 3*indent, sy-4*indent, NULL); //function specifies which window point maps to the viewport origin (0,0).
    for (int i = 0; i != quantity; i++) {
        brush = CreateSolidBrush(RGB(200,10,11));
        SelectObject(hdc, brush);
        ///////////////proceed the names////////////////////////////////////////////
        RECT namequad;
        SetRect(&namequad, i * 100 + 4, GRAPHWIDTH - 22, i * 100 + 28, GRAPHWIDTH - 48);
        FillRect(hdc, &namequad, brush);
        brush = CreateSolidBrush(RGB((170 * i % 235), (170 * i % 235), (170 * i % 235)));
        SelectObject(hdc, brush);
        SetRect(&namequad, i * 100 + 8, GRAPHWIDTH - 28, i * 100 + 22, GRAPHWIDTH - 42);
        FillRect(hdc, &namequad, brush);
        SetTextAlign(hdc, TA_LEFT | TA_TOP);
        
        wchar_t des[10];
        std::mbstowcs(des, names[i].c_str(), names[i].length());
        LPCWSTR lpcwstr = des;
        ////////////////////////////////////////////////////////////////////////////
        TextOut(hdc, (int)i * 100 + 30, (int)(GRAPHWIDTH - 35), lpcwstr, names[i].length());
    }
}
//функция рисует координатную сетку
void DrawGrid(HDC hdc, int sx, int sy, double max_x, double min_x, double max_y, double min_y, double hx, double hy) {
    HPEN pengrid;
    pengrid= CreatePen(PS_DASH, 3, RGB(120, 30, 50));
    SelectObject(hdc,pengrid);
    SetMapMode(hdc, MM_ANISOTROPIC);
    SetWindowExtEx(hdc, GRAPHSIZE, -GRAPHSIZE, NULL); //window 1200x1200 logical units
    SetViewportExtEx(hdc, sx, sy, NULL); //sx x sy client area 
    SetViewportOrgEx(hdc, 3 * indent, sy - indent, NULL); //function specifies which window point maps to the viewport origin (0,0).
    SetTextAlign(hdc, TA_CENTER | TA_TOP);
    int x_gr, y_gr, i;
    TCHAR s[20];
    double grid_x, grid_y;
    for (grid_x = min_x, i = 0; i <= 5*scaleX; grid_x += hx / (5*scaleX), i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        pengrid = CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, x_gr, 0, NULL);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    for (grid_y = min_y, i = 0; i <= 5 * scaleY; grid_y += hy / (5 * scaleY), i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        pengrid = CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, 0, y_gr, NULL);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    for (grid_x = min_x, i = 0; i <= scaleX; grid_x += hx / scaleX, i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_x);
        TextOut(hdc, x_gr, -5, s, _tcsclen(s));
        pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, x_gr, -10, NULL);
        LineTo(hdc, x_gr, 10);
        pengrid = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    SelectObject(hdc, pengrid);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, GRAPHWIDTH, 0);
    SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
    for (grid_y = min_y, i = 0; i <= scaleY; grid_y += hy / scaleY, i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_y);
        TextOut(hdc, -5, y_gr, s, _tcsclen(s));
        pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, -10, y_gr, NULL);
        LineTo(hdc, 10, y_gr);
        pengrid = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    SelectObject(hdc, pengrid);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, 0, GRAPHWIDTH);
    
    DeleteObject(pengrid);
}
Проблема заключается в том, что если потянуть за край окошка с графиками, оно растягивается до определенного размера и стопорится, содержимое окна при этом искажается. Его потом можно закрыть, но вот если попытаться после этого закрыть диалоговое окно или выбрать очередной файл с координатами для построения, то диалог выбора файла или диалог подтверждения закрытия на долю секунды мелькают на экране и исчезают, а приложение безнадежно виснет. Сворачивание и разворачивание окна на весь экран проблем не вызывают.
Миниатюры
Не работает перерисовка всплывающего окна после его растягивания C++, WinAPI   Не работает перерисовка всплывающего окна после его растягивания C++, WinAPI  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.03.2015, 19:06
Ответы с готовыми решениями:

Полная перерисовка окна на WinApi
Проблема Создаю окно с кнопками, собственно после нажатия на кнопку необходимо полностью очистить окно от старых кнопок и сделать новые,...

Перерисовка окна после сворачивания
Здраствуйте! Прошу помощи! Написал программу, которая выводит картинку .bmp ,перетаскивается мышкой и при нажатии стрелки вниз -...

Перерисовка окна после сворачивания (пропадает график)
Парни, глупый вопрос, знаю! Рисую график, сворачиваю окно, разворачиваю, понимаю что &quot;шеф усё пропало!&quot;. Рисую не через...

6
 Аватар для rao
903 / 424 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
15.03.2015, 10:41
Выкладывал бы уж весь проект. И файлы с данными графиков
0
 Аватар для casper007
71 / 71 / 58
Регистрация: 12.12.2013
Сообщений: 420
15.03.2015, 12:17
Цитата Сообщение от Liberanso Посмотреть сообщение
оно растягивается до определенного размера и стопорится
ну конечно будет "стопориться". столько циклов в WM_PAINT срабатывает не только в конечной точке растягивания, но и в процессе. Попробуйте использовать двойную буферизацию.
1
3 / 3 / 0
Регистрация: 03.05.2013
Сообщений: 23
15.03.2015, 16:44  [ТС]
casper007, спасибо за наводку, попробую.
0
3 / 3 / 0
Регистрация: 03.05.2013
Сообщений: 23
22.03.2015, 19:22  [ТС]
casper007, реализовала двойную буферизацию. Не знаю, правда, уж насколько верно. Окно теперь можно растягивать, но в какой-то момент оно превращается в то, что на втором скрине.

Код теперь выглядит так:

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
LRESULT CALLBACK WndGraph(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;
    static HDC hdc; //display context
    static HDC hMemDC;//compatible context
    static int sx, sy;
    RECT rect;
    
    switch (message) {
        
    case WM_CREATE: {
        GetClientRect(hWnd, &rect);
        sx = rect.right;
        sy = rect.bottom;
    }
        break;
 
    case WM_ERASEBKGND:
        return TRUE;
 
    case WM_SIZING: 
    case WM_SIZE: {
        sx = LOWORD(lParam);
        sy = HIWORD(lParam);
        UpdateWindow(hWnd);
        } 
        break;
 
    case WM_PAINT: {
                
        hdc = BeginPaint(hWnd, &ps);
        GetClientRect(hWnd, &rect);
        hMemDC = CreateCompatibleDC(hdc);
 
        HBITMAP hScreen;
        HBITMAP oldBmp;
        hScreen = CreateCompatibleBitmap(hdc, sx, sy);
        oldBmp = (HBITMAP)SelectObject(hMemDC, hScreen);
 
        //закраска фоновым цветом
        LOGBRUSH br;
        br.lbStyle = BS_SOLID;
        br.lbColor = 0xCCCCFF;
        HBRUSH bkgrdbr = CreateBrushIndirect(&br);
        SelectObject(hMemDC, bkgrdbr); //?
        FillRect(hMemDC, &rect, bkgrdbr);
        DeleteObject(bkgrdbr);
        
        SetMapMode(hdc, MM_ANISOTROPIC);
        SetWindowExtEx(hdc, GRAPHSIZE, -GRAPHSIZE, NULL); //window 1200x1200 logical units
        SetViewportExtEx(hdc, sx, sy, NULL); //sx x sy client area in device units
        SetViewportOrgEx(hdc, 0, sy, NULL); //function specifies which window point maps to the viewport origin (0,0). in device units
        
        DrawGraphics(hMemDC, points, quant, sx, sy, names);
    
        //copy an image to the screen
        SetStretchBltMode(hdc, COLORONCOLOR);
        BitBlt(hdc, 0, 0, GRAPHSIZE, GRAPHSIZE, hMemDC, -((GRAPHSIZE / sx) * 5 * indent), -((GRAPHSIZE / sy) * 2 * indent), SRCCOPY);
        SelectObject(hMemDC, oldBmp);
        DeleteObject(hScreen);
        DeleteDC(hMemDC);
        
        EndPaint(hWnd, &ps);
    } break;
 
    case WM_DESTROY: {
        DeleteDC(hdc);
        if (!points.empty())points.resize(0); //clear points for plotting
        if (!names.empty()) names.resize(0); //clear names array
    } break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}
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
BOOL DrawGraphics(HDC hdc, vector<dot> vec, int quantity, int sx, int sy, vector<string> names) {
    double max_x, min_x, max_y, min_y, hx, hy;
    double k_x = 1.0, k_y = 1.0;
    dot *points = new dot[quantity];
    int *flag = new int[quantity];
    
    for (int i = 0; i != quantity; i++) { //нужно для определения заполненности массива с последней точкой/ 0 - ни одной точки графика не нарисовано
        flag[i] = 0;
    }
 
    max_x = vec[0].x; max_y = vec[0].y;
    min_x = vec[0].x; min_y = vec[0].x;
 
    for (vector <dot> :: iterator i = vec.begin(); i != vec.end(); i++) {
        if ((*i).x > max_x) max_x = (*i).x;
        if ((*i).x < min_x) min_x = (*i).x;
        if ((*i).y > max_y) max_y = (*i).y;
        if ((*i).y < min_y) min_y = (*i).y;
    }
        
    hx = max_x - min_x;
    hy = max_y - min_y;
 
    
    DrawGrid(hdc, sx, sy, max_x, min_x, max_y, min_y, hx, hy);
    
 
    for (vector <dot> ::iterator i = vec.begin(); i != vec.end(); i++) {
    DrawPoint(hdc, (*i), k_x, k_y, points, flag, max_x, min_x, max_y, min_y, hx, hy,names);
    }
 
    ProceedNames(hdc, names, quantity, sx, sy);
 
    delete[] flag;
    delete[] points;
    
 
    return (TRUE);
}
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
void DrawPoint(HDC hdc, struct dot point, double k_x, double k_y, dot *mas, int *flag, double max_x, double min_x, double max_y, double min_y,double hx, double hy, vector<string> names) {
    
    //рисуем точку
    //двигаем перо в неё, рисуем линию от нее до последней нарисованной точки этого графика цветом, зависящим от номера графика, если эта точка есть
    //пишем в массив эту точку
    //flag=0, если ни одной точки этого графика ещё не было нарисовано
    
 
///////////////////draw the rectangle for point/////////////////////////////
    HPEN pen;
    HBRUSH brush;
    pen = CreatePen(PS_DASHDOTDOT, 7, RGB(120, (11+40*point.num%243), 15));
    //brush = CreateSolidBrush(RGB(120, (11 + 40 * point.num % 243), 15));
    brush = CreateSolidBrush(RGB((170 * point.num % 235), (170 * point.num % 235), (170 * point.num % 235)));
    SelectObject(hdc, pen);
    SelectObject(hdc, brush);
    RECT r;
    SetRect(&r, (int)((point.x - min_x)*GRAPHWIDTH / hx + 0.5)-5, (int)((point.y - min_y)*GRAPHWIDTH / hy + 0.5)-5, (int)((point.x - min_x)*GRAPHWIDTH / hx + 0.5)+5, (int)((point.y - min_y)*GRAPHWIDTH / hy + 0.5) + 5);
    FillRect(hdc, &r, brush);
    //SetPixel(hdc, (int)((point.x-min_x)*GRAPHWIDTH/hx+0.5),(int) ((point.y-min_y)*GRAPHWIDTH/hy+0.5), RGB((200 * point.num %235 +20), (200 * point.num %255 +20), (200 * point.num %235+20)));
////////////////////////////////////////////////////////////////////////////
        
    if (flag[point.num]) { //if there are drawn points for this graphic
        pen = CreatePen(((point.num) % 4), 3, RGB((170 * point.num %235), (170 * point.num %235), (170 * point.num %235)));
        SelectObject(hdc, pen);
        SelectObject(hdc, brush);
        MoveToEx(hdc, (int)((mas[point.num].x - min_x)*GRAPHWIDTH/hx+0.5), (int) ((mas[point.num].y - min_y)*GRAPHWIDTH/hy+0.5), NULL);
        LineTo(hdc, (int) ((point.x-min_x)*GRAPHWIDTH/hx+0.5), (int) ((point.y-min_y)*GRAPHWIDTH/hy+0.5));
    }
    else {
        flag[point.num] = 1;
    }
        mas[point.num] = point;
        DeleteObject(brush);
        DeleteObject(pen);
};
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
void ProceedNames(HDC hdc, vector<string> names, int quantity, int sx, int sy) {
    
    HBRUSH brush=CreateSolidBrush(RGB(0,0,0));
    for (int i = 0; i != quantity; i++) {
        brush = CreateSolidBrush(RGB(200,10,11));
        SelectObject(hdc, brush);
        ///////////////proceed the names////////////////////////////////////////////
        RECT namequad;
        SetRect(&namequad, i * 100 + 4, GRAPHSIZE - 92, i * 100 + 28, GRAPHSIZE - 118);
        FillRect(hdc, &namequad, brush);
        brush = CreateSolidBrush(RGB((170 * i % 235), (170 * i % 235), (170 * i % 235)));
        SelectObject(hdc, brush);
        SetRect(&namequad, i * 100 + 8, GRAPHSIZE - 98, i * 100 + 22, GRAPHSIZE - 112);
        FillRect(hdc, &namequad, brush);
        SetTextAlign(hdc, TA_LEFT | TA_TOP);
        
        wchar_t des[10];
        std::mbstowcs(des, names[i].c_str(), names[i].length());
        LPCWSTR lpcwstr = des;
        ////////////////////////////////////////////////////////////////////////////
        TextOut(hdc, (int)i * 100 + 30, (int)(GRAPHSIZE - 105), lpcwstr, names[i].length());
    }
    DeleteObject(brush);
}
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
void DrawGrid(HDC hdc, int sx, int sy, double max_x, double min_x, double max_y, double min_y, double hx, double hy) {
    HPEN pengrid;
    pengrid= CreatePen(PS_DASH, 3, RGB(120, 30, 50));
    SelectObject(hdc,pengrid);
 
    SetMapMode(hdc, MM_ANISOTROPIC);
    SetWindowExtEx(hdc, GRAPHSIZE, -GRAPHSIZE, NULL); //window 1200x1200 logical units
    SetViewportExtEx(hdc, sx, sy, NULL); //sx x sy client area in device units
    SetViewportOrgEx(hdc, 3*indent, sy-indent , NULL); //function specifies which window point maps to the viewport origin (0,0) in device units
 
    SetTextAlign(hdc, TA_CENTER | TA_TOP);
    int x_gr, y_gr, i;
    TCHAR s[20];
    double grid_x, grid_y;
    for (grid_x = min_x, i = 0; i <= 5*scaleX; grid_x += hx / (5*scaleX), i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        pengrid = CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, x_gr, 0, NULL);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    for (grid_y = min_y, i = 0; i <= 5 * scaleY; grid_y += hy / (5 * scaleY), i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        pengrid = CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, 0, y_gr, NULL);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    for (grid_x = min_x, i = 0; i <= scaleX; grid_x += hx / scaleX, i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_x);
        TextOut(hdc, x_gr, -5, s, _tcsclen(s));
        pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, x_gr, -10, NULL);
        LineTo(hdc, x_gr, 10);
        pengrid = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    SelectObject(hdc, pengrid);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, GRAPHWIDTH, 0);
    SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
    for (grid_y = min_y, i = 0; i <= scaleY; grid_y += hy / scaleY, i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_y);
        TextOut(hdc, -5, y_gr, s, _tcsclen(s));
        pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, -10, y_gr, NULL);
        LineTo(hdc, 10, y_gr);
        pengrid = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    SelectObject(hdc, pengrid);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, 0, GRAPHWIDTH);
    
    DeleteObject(pengrid);
}
Миниатюры
Не работает перерисовка всплывающего окна после его растягивания C++, WinAPI   Не работает перерисовка всплывающего окна после его растягивания C++, WinAPI  
0
 Аватар для casper007
71 / 71 / 58
Регистрация: 12.12.2013
Сообщений: 420
22.03.2015, 21:51
Liberanso, внимательно проверьте все стили, шрифты и т.п. воспользуйтесь отладчиком, и отследите на каком этапе программа начинает работать не корректно.
0
3 / 3 / 0
Регистрация: 03.05.2013
Сообщений: 23
23.03.2015, 18:59  [ТС]
Проблема была в том, что в процессе рисования в циклах с помощью CreateSolidBrush/CreatePen создавалось очень много брашей и пенов, которые при этом удалялись только один раз при завершении функции.
На коде это выглядит так:

БЫЛО:

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
//функция рисует координатную сетку
void DrawGrid(HDC hdc, int sx, int sy, double max_x, double min_x, double max_y, double min_y, double hx, double hy) {
    HPEN pengrid;
    pengrid= CreatePen(PS_DASH, 3, RGB(120, 30, 50));
    SelectObject(hdc,pengrid);
    SetMapMode(hdc, MM_ANISOTROPIC);
    SetWindowExtEx(hdc, GRAPHSIZE, -GRAPHSIZE, NULL); //window 1200x1200 logical units
    SetViewportExtEx(hdc, sx, sy, NULL); //sx x sy client area 
    SetViewportOrgEx(hdc, 3 * indent, sy - indent, NULL); //function specifies which window point maps to the viewport origin (0,0).
    SetTextAlign(hdc, TA_CENTER | TA_TOP);
    int x_gr, y_gr, i;
    TCHAR s[20];
    double grid_x, grid_y;
    for (grid_x = min_x, i = 0; i <= 5*scaleX; grid_x += hx / (5*scaleX), i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        pengrid = CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, x_gr, 0, NULL);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    for (grid_y = min_y, i = 0; i <= 5 * scaleY; grid_y += hy / (5 * scaleY), i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        pengrid = CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, 0, y_gr, NULL);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    for (grid_x = min_x, i = 0; i <= scaleX; grid_x += hx / scaleX, i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_x);
        TextOut(hdc, x_gr, -5, s, _tcsclen(s));
        pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, x_gr, -10, NULL);
        LineTo(hdc, x_gr, 10);
        pengrid = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    SelectObject(hdc, pengrid);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, GRAPHWIDTH, 0);
    SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
    for (grid_y = min_y, i = 0; i <= scaleY; grid_y += hy / scaleY, i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_y);
        TextOut(hdc, -5, y_gr, s, _tcsclen(s));
        pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
        SelectObject(hdc, pengrid);
        MoveToEx(hdc, -10, y_gr, NULL);
        LineTo(hdc, 10, y_gr);
        pengrid = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
        SelectObject(hdc, pengrid);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    pengrid = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    SelectObject(hdc, pengrid);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, 0, GRAPHWIDTH);
    
    DeleteObject(pengrid);
}
СТАЛО:

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
void DrawGrid(HDC hdc, int sx, int sy, double max_x, double min_x, double max_y, double min_y, double hx, double hy) {
    HPEN pengrid_one, pengrid_two, pengrid_dash,oldpen;
    SIZE textSize;
    pengrid_one= CreatePen(PS_SOLID, 1, RGB(120, 30, 50));
    pengrid_two = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
    pengrid_dash = CreatePen(PS_DASH, 1, RGB(120, 30, 50));
    
    SetMapMode(hdc, MM_ANISOTROPIC);
    SetWindowExtEx(hdc, GRAPHSIZE, -GRAPHSIZE, NULL); //window 1200x1200 logical units
//  GetTextExtentPoint32(hdc, _TEXT("0.0e+007"), _tcslen(_TEXT("0.0e+007")), &textSize);
//  int width_intent = textSize.cx;
//  int height_intent = textSize.cy;
    SetViewportExtEx(hdc, sx, sy, NULL); //sx x sy client area in device units
    SetViewportOrgEx(hdc, 3*indent,  sy-indent , NULL); //function specifies which window point maps to the viewport origin (0,0) in device units
    
    SetTextAlign(hdc, TA_CENTER | TA_TOP);
    int x_gr, y_gr, i;
    TCHAR s[20];
    double grid_x, grid_y;
    
    oldpen = (HPEN)SelectObject(hdc, pengrid_one);
    for (grid_x = min_x, i = 0; i <= 5 * scaleX; grid_x += hx / (5 * scaleX), i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        MoveToEx(hdc, x_gr, 0, NULL);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    for (grid_y = min_y, i = 0; i <= 5 * scaleY; grid_y += hy / (5 * scaleY), i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        MoveToEx(hdc, 0, y_gr, NULL);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    SelectObject(hdc, oldpen);
    
    for (grid_x = min_x, i = 0; i <= scaleX; grid_x += hx / scaleX, i++) {
        x_gr = (int)((grid_x - min_x)*GRAPHWIDTH / (max_x - min_x) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_x);
        TextOut(hdc, x_gr, -5, s, _tcsclen(s));
        oldpen = (HPEN)SelectObject(hdc, pengrid_one);
        MoveToEx(hdc, x_gr, -10, NULL);
        LineTo(hdc, x_gr, 10);
        oldpen = (HPEN)SelectObject(hdc, pengrid_dash);
        LineTo(hdc, x_gr, GRAPHWIDTH);
    }
    oldpen = (HPEN)SelectObject(hdc, pengrid_two);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, GRAPHWIDTH, 0);
    SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
    
    SelectObject(hdc, oldpen);
    for (grid_y = min_y+hy/scaleY, i = 0; i <= scaleY; grid_y += hy / scaleY, i++) {
        y_gr = (int)((grid_y - min_y)*GRAPHWIDTH / (max_y - min_y) + 0.5);
        _stprintf(s, _TEXT("%.1le"), grid_y);
        TextOut(hdc, -5, y_gr, s, _tcsclen(s));
        
        oldpen = (HPEN)SelectObject(hdc, pengrid_two);
        MoveToEx(hdc, -10, y_gr, NULL);
        LineTo(hdc, 10, y_gr);
        oldpen = (HPEN)SelectObject(hdc, pengrid_dash);
        LineTo(hdc, GRAPHWIDTH, y_gr);
    }
    oldpen = (HPEN)SelectObject(hdc, pengrid_two);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, 0, GRAPHWIDTH);
    SelectObject(hdc, oldpen);
    DeleteObject(pengrid_two);
    DeleteObject(pengrid_one);
    DeleteObject(pengrid_dash);
 
}
То есть на каждый CreatePen/CreateSolidBrush должен быть свой DeleteObject
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.03.2015, 18:59
Помогаю со студенческими работами здесь

Обновление содержимого окна или его перерисовка
Всем доброго вечера. Есть окно с элементами, необходимо постоянно обновлять содержимое, методы Invalidate и Refresh делают это с...

Как сделать появление всплывающего окна после отправки формы?
&lt;table width=&quot;90%&quot; border=0 align=&quot;center&quot; class=&quot;td_border&quot;&gt; &lt;tr&gt; &lt;td bgcolor='#2275AD'&gt;&lt;p align=&quot;center&quot; class=&quot;title&quot;&gt;Для отправки...

Перерисовка paintEvent после изменения размера окна
Всем привет. В paintEvent'e сначала высчитываю данные для графика, рисую его и использую размеры виджета(того в котором рисую, просто...

Вирусы после всплывающего окна "работа windows заблокирована"
Добрый день! После удаления всплывающего окна при загрузке компьютера: &quot;работа windows заблокирована, внесите деньги на телефон .....&quot;...

Вирусы после всплывающего окна " windows заблокирован"
Добрый день! После удаления всплывающего окна при загрузке компьютера: &quot;Windows заблокирован, внесите деньги на телефон .....&quot; и...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru