Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633

Необработанное исключение по адресу

21.03.2023, 16:46. Показов 6221. Ответов 50
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Мне нужно сделать следующее: На диалоговой панели расположить временное окно. В центре этого окна нарисовать мишень из 10 полей и в каждом поле вывести его значение (от 1 до 10). Поля выделять различными цветами, выбранными с помощью стандартной диалоговой панели выбора цвета.

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

Но при запуске стандартной диалоговая панель выбора цвета вылетает ошибка, причём ошибка указывает на функцию DialogBoxIndirect(), ошибка такая:
Вызвано исключение по адресу 0x76F66EB1 (comdlg32.dll) в Ex6_10.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000000.
Что вообще происходит?

Код:
CreateDlg
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
int CreateDlg(HWND hwnd)
{
    const TCHAR szCaption[] = TEXT("TARGET...");
 
    WORD* p, * pdlgTempl;
    p = pdlgTempl = (LPWORD)LocalAlloc(LPTR, 1024);
    if (!p)
    {
        MessageBox(NULL, TEXT("Can't allocated memory"),
            TEXT("Error"), MB_OK);
        return 1;
    }
    int cxChar, cyChar;
    {
        TEXTMETRIC tm;
        HDC hdc = GetDC(hwnd);
        GetTextMetrics(hdc, &tm);
        ReleaseDC(hwnd, hdc);
        cxChar = tm.tmAveCharWidth + 1;
        cyChar = tm.tmHeight + tm.tmExternalLeading;
    }
    DWORD dwBaseUnit = GetDialogBaseUnits();
    cxChar = cxChar * 4 / LOWORD(dwBaseUnit);
    cyChar = cyChar * 8 / HIWORD(dwBaseUnit);
 
    DWORD lStyle = DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION;
    int wDlg, hDlg, cxWnd, cyWnd, left, top;
    wDlg = 320;
    hDlg = 240;
    RECT rc;
    GetClientRect(hwnd, &rc);
    left = ((rc.right * 4 / LOWORD(dwBaseUnit)) >> 1) - (wDlg >> 1);
    top = ((rc.bottom * 8 / HIWORD(dwBaseUnit)) >> 1) - (hDlg >> 1);
 
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWSTR szDst;
    LPCWSTR szSrc;
    lpdt = (LPDLGTEMPLATE)p;
    lpdt->style = lStyle;
    lpdt->dwExtendedStyle = 0;
    lpdt->cdit = 1;
    lpdt->x = left;
    lpdt->y = top;
    lpdt->cx = wDlg;
    lpdt->cy = hDlg;
    p = (LPWORD)(lpdt + 1);
    *p++ = 0;
    *p++ = 0;
    szDst = (LPWSTR)(p);
    szSrc = szCaption;
    for (; *szDst++ = *szSrc++;)
        ;
    p = (LPWORD)szDst;
    p = lpwAlign((LPWORD)p);
 
    //1
    left = 10;
    top = 10;
    cxWnd = wDlg - 20;
    cyWnd = hDlg - 20;
    lStyle = WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_BORDER | WS_DLGFRAME;
 
    lpdit = (LPDLGITEMTEMPLATE)p;
    lpdit->style = lStyle;
    lpdit->dwExtendedStyle = 0;
    lpdit->x = left;
    lpdit->y = top;
    lpdit->cx = cxWnd;
    lpdit->cy = cyWnd;
    lpdit->id = ID_POPUPWINDOW;
    szDst = (LPWSTR)(lpdit + 1);
    szSrc = szPopupClass;
    for (; *szDst++ = *szSrc++;)
        ;
    szSrc = TEXT("\0");
    for (; *szDst++ = *szSrc++;)
        ;
    p = (LPWORD)szDst;
    *p++ = 0;
    p = lpwAlign((LPWORD)p);
 
    int ret;
//Когда пытаюсь открыть стандартную диалоговую панель выбора цвета, попадаю сюда,
//с ошибкой "Вызвано исключение по адресу 0x76F66EB1 (comdlg32.dll) в Ex6_10.exe: //0xC0000005: нарушение прав доступа при чтении по адресу 0x00000000."
 
    ret = DialogBoxIndirect(hInstance, (LPCDLGTEMPLATE)pdlgTempl,
        hwnd, (DLGPROC)DlgProc);
    if (ret == -1)
        DWORD er = GetLastError();
    LocalFree(LocalHandle(pdlgTempl));
 
    return ret;
}


WndProc,DlgProc
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
LRESULT CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HWND hPop;
    switch (msg)
    {
        case WM_INITDIALOG:
        {
            hPop = GetDlgItem(hDlg, ID_POPUPWINDOW);
            return TRUE;
        }
        case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
                case IDCANCEL:
                {
                    EndDialog(hDlg, TRUE);
                    return TRUE;
                }
                default:
                    break;
            }
        }
    }
    return FALSE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HMENU hMainMenu, hPopMenu;
    static MENUITEMINFO mii;
    switch (msg)
    {
    case WM_CREATE:
    {
        hMainMenu = CreateMenu();
        hPopMenu = CreatePopupMenu();
        SetMenu(hwnd, hMainMenu);
        mii.cbSize = sizeof(mii);
        mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU;
        mii.fType = MFT_STRING;
        mii.fState = MFS_ENABLED;
        mii.wID = CM_TARGET_OPEN;
        mii.hSubMenu = NULL;
        mii.dwTypeData = (LPTSTR)TEXT("Open target");
        mii.cch = _tcslen(TEXT("Open target"));
 
        InsertMenuItem(hPopMenu, CM_TARGET_OPEN, FALSE, &mii);
 
        mii.fType = MFT_SEPARATOR;
        mii.fState = MFS_ENABLED;
        mii.wID = 0;
        mii.hSubMenu = NULL;
        mii.dwTypeData = (LPTSTR)NULL;
        mii.cch = 0;
        InsertMenuItem(hPopMenu, 0, FALSE, &mii);
 
        mii.fType = MFT_STRING;
        mii.fState = MFS_ENABLED;
        mii.wID = CM_TARGET_QUIT;
        mii.hSubMenu = NULL;
        mii.dwTypeData = (LPTSTR)TEXT("Exit");
        mii.cch = _tcslen(TEXT("Exit"));
        InsertMenuItem(hPopMenu, CM_TARGET_QUIT, FALSE, &mii);
 
        mii.fType = MFT_STRING;
        mii.fState = MFS_ENABLED;
        mii.wID = 0;
        mii.hSubMenu = hPopMenu;
        mii.dwTypeData = (LPTSTR)TEXT("TARGET");
        mii.cch = _tcslen(TEXT("TARGET"));
        InsertMenuItem(hMainMenu, 0, TRUE, &mii);
 
        DrawMenuBar(hwnd);
 
        return 0;
    }
    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {
        case CM_TARGET_OPEN:
        {
            CreateDlg(hwnd);
            return 0;
        }
        case CM_TARGET_QUIT:
        {
            DestroyWindow(hwnd);
            return 0;
        }
        }
        return 0;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}


PopProc
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
LRESULT CALLBACK PopProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static int cxClient, cyClient;
    static HRGN hRgn[10];
    static RECT rcRgn[10];
    static HPEN hPen, hOldPen;
    const int indent = 0;
    static int radius, rad;
    static COLORREF lpCustColors[16], rgbResult = RGB(255, 255, 255);
    static COLORREF crCellTarget[10]; //Здесь цвет для каждого поля мишени
    static CHOOSECOLOR cc;
    static POINT ptCenter;
 
    switch (msg)
    {
    case WM_CREATE:
    {
        ZeroMemory(&cc, sizeof(CHOOSECOLOR));
        cc.lStructSize = sizeof(cc);
        cc.hwndOwner = hwnd;
        cc.hInstance = NULL;
        cc.rgbResult = rgbResult;
        cc.Flags = CC_ANYCOLOR | CC_RGBINIT;
 
        for (int i = 0; i < 10; ++i)
        {
            //hRgn[i] = CreateEllipticRgn(0, 0, 0, 0);
            crCellTarget[i] = GetClassLong(hwnd, GCL_HBRBACKGROUND);
        }
        return 0;
    }
    case WM_SIZE:
    {
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        int d = (cxClient > cyClient) ? cyClient : cxClient;
        rad = radius = (d >> 1);
        rad /= 10; //Значение промежутка между эллипсами(или регионами, как удобнее).
        ptCenter.x = (cxClient >> 1);
        ptCenter.y = (cyClient >> 1);
 
        int l = (cxClient >> 1) - (d >> 1);
        int t = indent;
        int r = (cxClient >> 1) + (d >> 1);
        int b = cyClient - indent;
        for (int i = 0; i < 10; ++i)
        {
            SetRect(&rcRgn[i], l, t, r, b);
            hRgn[i] = CreateEllipticRgn(l, t, r, b);
            l += rad;
            t += rad;
            r -= rad;
            b -= rad;
        }
        return 0;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
 
        int OldBk = SetBkMode(hdc, TRANSPARENT);
        //int OldBkColor = SetBkColor(hdc, crColorRgn);
        hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
        hOldPen = (HPEN)SelectObject(hdc, hPen);
        TCHAR szNum = '1';
        HBRUSH hBrush, hOldBrush;
        for (int i = 0; i < 10; ++i)
        {
            Ellipse(hdc, rcRgn[i].left, rcRgn[i].top,
                rcRgn[i].right, rcRgn[i].bottom);
            
            int OldAlign = SetTextAlign(hdc, TA_CENTER);
//Если это последняя ячейка-поле, то нужно сместить rad так чтобы 10-как была по середине 
//последнего эллипса. 
            if (i == 9)
                TextOut(hdc, rcRgn[i].left + rad,
                    ptCenter.y, (LPCTSTR)szNums[i], 2);
            else
            {
                TextOut(hdc, rcRgn[i].left + (rad >> 1),
                    ptCenter.y, (LPCTSTR)szNums[i], 1);
                TextOut(hdc, rcRgn[i].right - (rad >> 1),
                    ptCenter.y, (LPCTSTR)szNums[i], 1);
            }
 
            SetTextAlign(hdc, OldAlign);
        }
        for (int i = 0; i < 10; ++i)
        {
            hBrush = CreateSolidBrush(crCellTarget[i]);
            hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
 
            /*ExtFloodFill(hdc, (rcRgn[i].right >> 1),
                rcRgn[i].top + (rad >> 1),
                RGB(0, 0, 0), FLOODFILLBORDER);*/
 
            SelectObject(hdc, hOldBrush);
            DeleteObject(hBrush);
        }
        SetBkMode(hdc, OldBk);
        //SetBkColor(hdc, OldBkColor);
        SelectObject(hdc, hOldPen);
 
 
        EndPaint(hwnd, &ps);
        return 0;
    }
    case WM_LBUTTONDOWN:
    {
        int x = LOWORD(lParam);
        int y = HIWORD(lParam);
        int iMaxRad = radius;
        int iMinRad = iMaxRad - rad;
 
        int iPowMaxRad = iMaxRad * iMaxRad;
        int iPowMinRad = iMinRad * iMinRad;
        x -= ptCenter.x;
        y -= ptCenter.y;
        int i;
        int len = x * x + y * y;
        for (i = 0; i < 10; ++i)
        {
            if (len >= iPowMinRad && len <= iPowMaxRad)
            {
                break;
            }
            else
            {
                iMaxRad = iMinRad;
                iMinRad -= rad;
 
                iPowMaxRad = iMaxRad * iMaxRad;
                iPowMinRad = iMinRad * iMinRad;
 
            }
        }
        if (i < 10)
        {
            //Ошибка вылезает отсюда, как эта диалоговая панель связана с
            //моим шаблоном, не понимаю. 
            if (ChooseColor(&cc) == TRUE)
            {
                crCellTarget[i] = cc.rgbResult;
                InvalidateRect(hwnd, &rcRgn[0], TRUE);
            }
            
        /*else
        {
            TCHAR szStr[64];
            _stprintf_s(szStr, 64,
            TEXT("Point(x = %d, y = %d) In not a Region"),
            x, y);
            MessageBox(NULL, szStr, TEXT("Message"), MB_OK);
        }*/
        }
        return 0;
    }
        case WM_DESTROY:
        {
            for (int i = 0; i < 10; ++i)
                DeleteObject(hRgn[i]);
            //PostQuitMessage(0);
            return 0;
        }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.03.2023, 16:46
Ответы с готовыми решениями:

Необработанное исключение по адресу на х86, на х64 работает норм
ParWin = new Wnd (WS_EX_ACCEPTFILES, &quot;FRM_TEXTEDIT&quot;, &quot;Flat Assembler&quot;, WS_OVERLAPPEDWINDOW, 365,120,480,520, NULL,NULL, hInstance,...

Необработанное исключение и тд
Не вижу в чем ошибка, необработанное исключение. Вылетает где то в WM_PAINT. Плюс переменная indexfile, не индексируется. #define...

Необработанное исключение
Необработанное исключение Работало нормально. Компилятор ошибок не выдает. Что это может быть ? Необработанное исключение у...

50
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
22.03.2023, 06:03
Студворк — интернет-сервис помощи студентам
Liss29, прицепи текущий вариант проекта (только сразу в ZIP)
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
23.03.2023, 04:58  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
прицепи текущий вариант проекта (только сразу в ZIP)
Вот проект.
Ex6_10.rar
При запуске диалогового окна вижу такую картину.


Хотя указываю цвета по умолчанию:
Code
1
crCellTarget[i] = GetClassLong(hwnd, GCL_HBRBACKGROUND);
Но при выборе цвета все же нужные области закрашиваются.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
23.03.2023, 20:59  [ТС]
Алексей1153, Ну и, теперь что не нравится? Всё, что просили, прикрепил.
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
23.03.2023, 21:02
Liss29, сделай ZIP, завтра гляну Или кто-то уже глянет
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
23.03.2023, 21:22  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
сделай ZIP, завтра гляну
zip, rar какая разница... Что там глядеть, проблема в выборе цвета по умолчанию, хотя, если я создаю белую кисть явно,
Code
1
hBrush = CreateSolidBrush(RGB(255, 255, 255));
, то всё работает так как я того хочу, но, если я пытаюсь инициализировать кисть так
Code
1
crCellTarget[i] = GetClassLong(hwnd, GCL_HBRBACKGROUND);
или так
Code
1
crCellTarget[i] = COLOR_WINDOW;
, то результат получается, как на скрине выше. Хз, почему, COLOR_WINDOW, точно не чёрная...
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
23.03.2023, 21:25  [ТС]
Ex6_10.zip
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
23.03.2023, 21:35  [ТС]
Хотя, если COLOR_WINDOW = 5, то, по сути - это чёрный цвет, если выбрать любое табличное значение цвета COLOR_... и создать с ним кисть, то, получается, цвет этой кисти будет чёрным.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
23.03.2023, 22:32  [ТС]
По сути, то, что требовалось я реализовал, но есть одно но, скорее эстетическое замечание, когда цвет выбран и область мишени закрашена выбранным цветом, цифры 8, 9 в их пустых местах цвет остаётся белым, хотя режим фона установлен как TRANSPARENT, как сделать так, чтобы отверстия-пустые места были того же цвета т.е. цвета, которым закрашена данная область мишени.
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
24.03.2023, 08:38
Цитата Сообщение от Liss29 Посмотреть сообщение
Хотя, если COLOR_WINDOW = 5, то, по сути - это чёрный цвет
потому что GetSysColor

Добавлено через 13 минут
SetBkMode(hdc, TRANSPARENT); - это работает, просто ты после вывода текста заливаешь область ExtFloodFill , вот и остаются карманы. Текст надо выводить поверх всего

и ещё момент - чтобы не ковыряться с восстановлением старых объектов SelectObject(hdc, hOldBrush);, используй SaveDC / RestoreDC
1
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
24.03.2023, 21:34  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
потому что GetSysColor
Что это значит, то что значения цветов не превышают 20-ти?! А это значит, что создаётся чёрная кисть...

Цитата Сообщение от Алексей1153 Посмотреть сообщение
используй SaveDC / RestoreDC
Насколько я понял нужно делать приблизительно так:
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
for (int i = 0; i < 10; ++i)
            {
                Ellipse(hdc, rcRgn[i].left, rcRgn[i].top,
                    rcRgn[i].right, rcRgn[i].bottom);
            
            }
            for (int i = 0; i < 10; ++i)
            {
                hBrush = CreateSolidBrush(crCellTarget[i]);
                
                SaveDC(hdc);
 
                ExtFloodFill(hdc, ptCenter.x,
                    rcRgn[i].top + (rad >> 1),
                    RGB(0,0,0), FLOODFILLBORDER);
 
                if (i == 9)
                    TextOut(hdc, rcRgn[i].left + rad,
                        ptCenter.y, (LPCTSTR)szNums[i], 2);
                else
                {
                    TextOut(hdc, rcRgn[i].left + (rad >> 1),
                        ptCenter.y, (LPCTSTR)szNums[i], 1);
                    TextOut(hdc, rcRgn[i].right - (rad >> 1),
                        ptCenter.y, (LPCTSTR)szNums[i], 1);
                }
                RestoreDC(hdc, -1);
                                //Удалять созданную кисть разве не нужно?
                        DeleteObject(hBrush);       
 
            }
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
24.03.2023, 21:49
Цитата Сообщение от Liss29 Посмотреть сообщение
Что это значит, то что значения цветов не превышают 20-ти?! А это значит, что создаётся чёрная кисть...
это псевдонимы для системных цветов (текущая цветовая палитра системы). Какая разница, сколько там их? Необязательно пользоваться ими

Цитата Сообщение от Liss29 Посмотреть сообщение
Насколько я понял нужно делать приблизительно так:
нет, вот так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    for (int i = 0; i < 10; ++i)
    {
        const int saved=SaveDC(hdc);
        []
        {
            auto hBrush = CreateSolidBrush(crCellTarget[i]);
            
            SelectObject(hdc,hBrush);
            
            //тут ещё куча SelectObject
            //...
    
            DeleteObject(hBrush); 
        }();
        
        RestoreDC(hdc, saved);
    }
чтобы проверить, что нет ошибок, открываем в диспетчере задач наш процесс, смотрим колонку "текущее количество дескрипторов, открытых процессом", затем много раз вызываем перерисовку. Счётчик не должен расти постоянно, а должен колебаться возле одного значения

полагаю, SaveDc/RestoreDC в данном случае можно даже за цикл вынести (лямбду тоже). Но это нужно уточнить

Добавлено через 2 минуты
лямбду я добавил для гарантии вызова RestoreDC
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
24.03.2023, 22:20  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Какая разница, сколько там их?
Большая, когда я создаю кисть, скажем так, hBrush = CreateSolidBrush(COLOR_WINDOW);, то функция смотрит не на псевдоним, а на числовое значение этого псевдонима, нет?

Цитата Сообщение от Алексей1153 Посмотреть сообщение
Но это нужно уточнить
У кого?

Цитата Сообщение от Алексей1153 Посмотреть сообщение
полагаю, SaveDc/RestoreDC в данном случае можно даже за цикл вынести (лямбду тоже).
А без этого у..б..ства никак нельзя лямбды ...
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
24.03.2023, 22:23
Liss29, CreateSolidBrush принимает аргументом тип COLORREF, а не индекс системного цвета

Цитата Сообщение от Liss29 Посмотреть сообщение
У кого?
у отладчика и диспетчера задач

Цитата Сообщение от Liss29 Посмотреть сообщение
А без этого у..б..ства никак нельзя лямбды ...
можно. Только нужно быть внимательным и не допускать break, continue и return
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
24.03.2023, 22:30  [ТС]
Думаю, я понял SaveDC() перед изменением контекста устройства, а восстанавливаем, после всех манипуляций с контекстом устройства, только, особой выгоды не вижу, ну одна переменная устраняется, я про свой случай, ну хорошо четыре локальные переменные устраняются, разве это так ощутимо...

Добавлено через 6 минут
Цитата Сообщение от Алексей1153 Посмотреть сообщение
CreateSolidBrush принимает аргументом тип COLORREF, а не индекс системного цвета
Если я передаю CreateSolidBrush(COLOR_WINDOW), ТО ЧТО БУДЕТ ЕГО ПАРАМЕТРОМ, COLORREF = 0x? Раве не 0x5...

Цитата Сообщение от Алексей1153 Посмотреть сообщение
у отладчика и диспетчера задач
Эти пассажиры мутные и не особо разговорчивые.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
можно. Только нужно быть внимательным и не допускать break, continue и return
У меня в цикле итак их нет
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
24.03.2023, 22:35
Цитата Сообщение от Liss29 Посмотреть сообщение
особой выгоды не вижу
выгода в упрощении кода и уменьшении вероятности ошибок

Цитата Сообщение от Liss29 Посмотреть сообщение
Если я передаю CreateSolidBrush(COLOR_WINDOW), ТО ЧТО БУДЕТ ЕГО ПАРАМЕТРОМ
будет интерпретация значения COLOR_WINDOW как значения COLORREF. И это неправильно, просто не делай так и всё

Добавлено через 30 секунд
Цитата Сообщение от Liss29 Посмотреть сообщение
У меня в цикле итак их нет
это сегодня нет Моё дело - предупредить, а там решай сам
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
24.03.2023, 23:18  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
чтобы проверить, что нет ошибок, открываем в диспетчере задач наш процесс, смотрим колонку "текущее количество дескрипторов, открытых процессом", затем много раз вызываем перерисовку
Что это у тебя за диспетчер задач такой?

Добавлено через 19 минут
Цитата Сообщение от Алексей1153 Посмотреть сообщение
выгода в упрощении кода и уменьшении вероятности ошибок
Серьёзно,
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
case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    //Если функцию SelectObject() вызвать здесь, тогда да,
    //есть ощутимые преимущества.
    SaveDC(hdc);
    
    SetBkMode(hdc, TRANSPARENT);
    
    hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
    //hOldPen = (HPEN)SelectObject(hdc, hPen);
    HBRUSH hBrush;
    SetTextAlign(hdc, TA_CENTER);
    for (int i = 0; i < 10; ++i)
    {
        Ellipse(hdc, rcRgn[i].left, rcRgn[i].top,
            rcRgn[i].right, rcRgn[i].bottom);
    
    }
    for (int i = 0; i < 10; ++i)
    {
        SaveDC(hdc);
        hBrush = CreateSolidBrush(crCellTarget[i]);
        //А если здесь SaveDC(), то не особо ощутимо 
        SelectObject(hdc, hBrush);
 
        ExtFloodFill(hdc, ptCenter.x,
            rcRgn[i].top + (rad >> 1),
            RGB(0,0,0), FLOODFILLBORDER);
 
        if (i == 9)
            TextOut(hdc, rcRgn[i].left + rad,
                ptCenter.y, (LPCTSTR)szNums[i], 2);
        else
        {
            TextOut(hdc, rcRgn[i].left + (rad >> 1),
                ptCenter.y, (LPCTSTR)szNums[i], 1);
            TextOut(hdc, rcRgn[i].right - (rad >> 1),
                ptCenter.y, (LPCTSTR)szNums[i], 1);
        }
        //Здесь нет SelectObject()
        //SelectObject(hdc, hOldBrush);
        DeleteObject(hBrush);
        //А здесь RestoreDC(hdc, -1);
    }
    //SetBkMode(hdc, OldBk);
    //SelectObject(hdc, hOldPen);
    //SetTextAlign(hdc, OldAlign);
 
    //RestoreDC(hdc, -1), но не будет ли тогда утечки ресурсов?
    EndPaint(hwnd, &ps);
    return 0;
}
Цитата Сообщение от Алексей1153 Посмотреть сообщение
будет интерпретация значения COLOR_WINDOW как значения COLORREF. И это неправильно, просто не делай так и всё
Как так, а как тогда делать GetSysColorBrush(), так что ли?

Цитата Сообщение от Алексей1153 Посмотреть сообщение
Моё дело - предупредить
Понял, буду надеяться, что запомню.

Цитата Сообщение от Liss29 Посмотреть сообщение
диспетчере задач наш процесс, смотрим колонку "текущее количество дескрипторов, открытых процессом"
Process Explorer показывает следующее, сразу после старта программы GDI Handles 13, после запуска диалогового окна 29, после закрытия 19, после повторного открытия диалогового окна и выбора, замены в нескольких полях мишени цветов 35, после закрытия диалогового окна 25, как сие трактовать, утечка?
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
25.03.2023, 08:39
Цитата Сообщение от Liss29 Посмотреть сообщение
Что это у тебя за диспетчер задач такой?
стандартный из винды. На семёрке уже точно такая колонка была, а, скорее всего, и раньше

Цитата Сообщение от Liss29 Посмотреть сообщение
Серьёзно
тогда уж:
1) в строке 23 убрать SaveDC.
2) в строке 51 вызвать RestoreDC с индексом, который был получен из SaveDC в строке 7

Цитата Сообщение от Liss29 Посмотреть сообщение
но не будет ли тогда утечки ресурсов
- наблюдаем через диспетчер за счётчиком хендлов

Цитата Сообщение от Liss29 Посмотреть сообщение
Как так, а как тогда делать GetSysColorBrush(), так что ли?
C
1
CreateSolidBrush(GetSysColor(COLOR_WINDOW));
Добавлено через 1 минуту
ну, или, да
C
1
GetSysColorBrush(COLOR_WINDOW);
Добавлено через 54 секунды
Цитата Сообщение от Liss29 Посмотреть сообщение
буду надеяться, что запомню
с лямбдой можно не запоминать - ошибку такую сделать физически не получится
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
25.03.2023, 08:46
Цитата Сообщение от Liss29 Посмотреть сообщение
как сие трактовать, утечка
открываем диспетчер (там циферка меняется динамически). Запускаем свою приложение. Каким-нибудь левым окном возюкаем по морде приложения, чтобы провоцировать постоянную перерисовку. Следим за счётчиком в диспетчере

0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,633
25.03.2023, 21:23  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
стандартный из винды. На семёрке уже точно такая колонка была, а, скорее всего, и раньше
У меня 10-ка, но такого нет, если добавить столбцы, но там есть из того о чём говорили "Объекты GDI" и "Дескрипторы". А чем процесс хакер плох или процесс експлорер в таком случае...

Цитата Сообщение от Алексей1153 Посмотреть сообщение
в строке 51 вызвать RestoreDC с индексом, который был получен из SaveDC в строке 7
Что этот индекс означает, почему не -1?

Цитата Сообщение от Алексей1153 Посмотреть сообщение
с лямбдой можно не запоминать - ошибку такую сделать физически не получится
Да, но тогда нужно разобраться с лямбдой, понять как это работает, а я не понимаю, да и синтаксис этих лямбд меня убивает

Добавлено через 1 минуту
Цитата Сообщение от Алексей1153 Посмотреть сообщение
открываем диспетчер (там циферка меняется динамически).
Ага... только ты забыл добавить, что эти столбцы нужно включать дополнительно, ну, это так, мелочь.
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
25.03.2023, 22:12
Цитата Сообщение от Liss29 Посмотреть сообщение
но тогда нужно разобраться с лямбдой, понять как это работает
level up )

Цитата Сообщение от Liss29 Посмотреть сообщение
Что этот индекс означает, почему не -1?
в доке написано
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.03.2023, 22:12

Необработанное исключение
Всем здрасьте. При компиляции кода , программа запускается нормально , но сразу же зависает! При закрытии программы пишет вот что : ...

Необработанное исключение
Добрый день, первый раз пишу. Вот такая ошибка вылезла, когда писал ЭГА Необработанное исключение по адресу 0x0124D42E в...

Необработанное исключение: Нарушение прав доступа при чтении
Работала с игрой &quot;Крестики-нолики&quot;. При компиляции выдает сообщение &quot;Необработанное исключение в &quot;0x0086297b&quot; в...

Необработанное исключение. Нарушение прав доступа при чтении
Здравствуйте! Пишу привязку программы к конкретному компьютеру, и получаю информацию о железе через WMI, но при сохранении данных...

Вызвано необработанное исключение: нарушение доступа для чтения. lpnmhdr было nullptr
Ошибка в фрагменте (см.скрин) после нажатия на кнопку &quot;ждать 5 сек&quot;. Строки 183-191 из общего кода: case WM_NOTIFY: LPNMHDR lpnmhdr =...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Сезонность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru