Как нарисовать дочернее окно с помощью FillRect ()?

У меня есть главное окно, которое создано со следующими стилями
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_TABSTOP | WS_GROUP | WS_VISIBLE
и с бывшими
WS_EX_ACCEPTFILES | WS_EX_CONTROLPARENT | WS_EX_LEFT | WS_EX_LTRREADING,

Это главное окно имеет дочернее окно, которое является элементом управления редактирования, созданным со стилями.
WS_VISIBLE | WS_CHILD | ES_READONLY
и бывший стиль
WS_EX_CLIENTEDGE,

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

Я могу нарисовать любой регион главного окна следующим кодом:

// hWnd: Handle of the main window
case WM_PAINT:
hDc = BeginPaint(hWnd, &Ps);
Rect = AFunctionToGetCornerThePointsOfTheEditControl();
Rect.right = Rect.left + 3 * (Rect.right - Rect.left) / 4; // Fill 3/4 (75%) of it
Rect.left   -= 10; // Enlarge the paint region a little
Rect.top    -= 10; // so that we can see it if it stays
Rect.bottom += 10; // under the edit control.
hBrush = CreateSolidBrush(RGB(50,100,255));
ret = FillRect(hDc, &Rect, hBrush); // ret = 1 always
ler = GetLastError();               // ler = 0
EndPaint(hWnd, &Ps);
break;

Это выглядит так:
внешний вид окрашенного окна

Я немного изменил этот код, чтобы вместо этого нарисовать дочерний элемент управления:

// hWndEdit: Handle of the edit control
case WM_PAINT:
hDc = BeginPaint(hWndEdit, &Ps);
Rect = AFunctionToGetCornerThePointsOfTheEditControl();
Rect.right = Rect.left + 3 * (Rect.right - Rect.left) / 4; // Fill 3/4 (75%) of it
Rect.left   -= 10;
Rect.top    -= 10;
Rect.bottom += 10;
hBrush = CreateSolidBrush(RGB(50,100,255));
ret = FillRect(hDc, &Rect, hBrush); // ret = 0 always
ler = GetLastError();               // ler = 6 (ERROR_INVALID_HANDLE)
EndPaint(hWndEdit, &Ps);
break;

На этот раз это не работает. Основные окна полностью исчезают, как только я перетаскиваю какую-то часть из области экрана, и он становится полностью не отвечающим. Иконки рабочего стола под ним видны, но не кликабельны.

Итак, что мне нужно сделать, чтобы нарисовать дочернее окно (элемент управления редактирования)?

3

Решение

Эта статья мне очень помогла: Управление подклассами

Сначала я создаю отдельную функцию обработки сообщений для обработки дочерних сообщений.

LRESULT CALLBACK MyClass::ChildWindowProc(  HWND        hWnd,
UINT        uMsg,
WPARAM      wParam,
LPARAM      lParam,
UINT_PTR    uIdSubclass,
DWORD_PTR   dwRefData)
{
static PAINTSTRUCT Ps;
static RECT Rect;
static HBRUSH hBrush1 = CreateSolidBrush(RGB(50,100,255));
static HBRUSH hBrush2 = CreateSolidBrush(RGB(255,100,50));
HDC hDc;
LRESULT lResult;
switch (uMsg)
{
case WM_PAINT:
switch (uIdSubclass)
{
case 1:
hDc = BeginPaint(hWnd, &Ps);
Rect.left   = 0;
Rect.right  = (LONG) (((double) ITEM2_WIDTH) * Status::GI()->Get_JobCurPercentage());
Rect.top    = 0;
Rect.bottom = ITEM_HEIGHT - 3;
FillRect(hDc, &Rect, hBrush1);
EndPaint(hWnd, &Ps);
break;
case 2:
hDc = BeginPaint(hWnd, &Ps);
Rect.left   = 0;
Rect.right  = (LONG) (((double) ITEM2_WIDTH) * Status::GI()->Get_JobTotPercentage());
Rect.top    = 0;
Rect.bottom = ITEM_HEIGHT - 3;
FillRect(hDc, &Rect, hBrush2);
EndPaint(hWnd, &Ps);
break;
default:
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
break;
case WM_NCDESTROY:
//ReleaseDC(hWnd, hDc);
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
break;
default:
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}

Далее я связываю эту функцию с элементами управления:

SetWindowSubclass(  /*_In_  HWND            hWnd*/          ed_cur_Progress.hWnd,
/*_In_  SUBCLASSPROC    pfnSubclass*/   ChildWindowProc,
/*_In_  UINT_PTR        uIdSubclass*/   1,
/*_In_  DWORD_PTR       dwRefData*/     (DWORD_PTR) NULL);
SetWindowSubclass(  /*_In_  HWND            hWnd*/          ed_tot_Progress.hWnd,
/*_In_  SUBCLASSPROC    pfnSubclass*/   ChildWindowProc,
/*_In_  UINT_PTR        uIdSubclass*/   2,
/*_In_  DWORD_PTR       dwRefData*/     (DWORD_PTR) NULL);

И это все! Результат потрясающий.

внешний вид

1

Другие решения

WM_PAINT, с которым вы работаете, это главное окно. вам нужно нарисовать поле ввода в его сообщении WM_PAINT владельца. Я предполагаю, что вы получаете ошибку от «hDc = BeginPaint (hWndEdit, &Ps); «, можете проверить.

-1

По вопросам рекламы [email protected]