Когда я включаю поддержку визуального стиля общего элемента управления (InitCommonControls ()) и использую любую тему, кроме классической темы Windows, кнопки внутри группового поля отображаются с черной рамкой с квадратными углами.
Классическая тема Windows выглядит нормально, как и при отключении визуального стиля.
Я использую следующий код:
group_box = CreateWindow(TEXT("BUTTON"), TEXT("BS_GROUPBOX"),
WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_GROUP,
10, 10, 200, 300,
hwnd, NULL, hInstance, 0);
push_button = CreateWindow(TEXT("BUTTON"), TEXT("BS_PUSHBUTTON"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
40, 40, 100, 22,
group_box, NULL, hInstance, 0);
Обновлено: проблема возникает и с переключателями
Обновлено: я не использую никаких диалогов / ресурсов, только CreateWindow / Ex.
Я компилирую под Visual C++ 2008 Express SP1 с общим файлом манифест
Все кнопки. Если я использую классическую тему Windows, они выглядят как обычно.
Как выглядит вызов CreateWindow для самого родительского диалога? Просто интересно, происходит ли какое-то наследование.
hwnd = CreateWindow (appName, TEXT («Скелет окна»), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 435,360, NULL, NULL, hInstance, 0);
Хм. Это происходит, если кнопки тоже находятся за пределами группового поля?
Нет, только когда они находятся внутри группового поля, другими словами, когда я использую group_box в качестве родительского hwnd.
Я попробую повторить завтра вечером и посмотрю, смогу ли я найти решение
Проблема заключается в использовании группового ящика в качестве родительского. Не стоит этого делать;) Я тестировал и получаю такие же черные границы. См. Мой ответ для более подробной информации.
WS_CLIBSIBLINGS на Group Box тоже стоит попробовать.




Просто предположение, но похоже, что вы наследуете стиль Static Edge или Client Edge от своей темы. Я создаю большинство своих диалогов из редактора ресурсов и устанавливаю там эти свойства.
В вашем случае вы можете заменить CreateWindow на CreateWindowEx, чтобы установить эти расширенные стили, которые, вероятно, используются по умолчанию в CreateWindow. Конкретно проверьте WS_EX_STATICEDGE, WS_EX_WINDOWEDGE and WS_EX_CLIENTEDGE
Обновлено: я предполагаю, что этого не происходит, потому что кнопка является элементом управления по умолчанию в диалоговом окне, что также дает черный край.
По-видимому, групповые поля не предназначены для группировки элементов управления (быть родительским hwnd)
Итак, чтобы избавиться от черных границ / проблем с рисованием, мне пришлось бы создать подкласс группового блока и реализовать WM_PAINT и WM_PRINTCLIENT
Ах да, черный фон с переключателями и групповыми блоками. Хотя я не уверен, будет ли это работать для VC++ 2008, но в те времена решение для тематических приложений VB6 состояло в том, чтобы сначала поместить элементы управления радио в PictureBox (на самом деле общий контейнер), а затем добавить это в групповое поле.
Стоит попробовать!
Проблема заключается в том, что групповой ящик является родительским элементом управления. У групповых ящиков не должно быть дочерних элементов, и использование их в качестве родителей вызовет всевозможные ошибки (включая рисование, навигацию с клавиатуры и распространение сообщений). Просто измените родительский элемент в вызове кнопок CreateWindow с group_box на hwnd (т.е. диалог).
Я предполагаю, что вы использовали групповой ящик в качестве родителя, чтобы легко разместить в нем другие элементы управления. Правильный способ сделать это - получить позицию клиентской области группового окна и сопоставить ее с клиентской областью диалога. Все, что помещено в результирующий RECT, появится внутри группового окна. Поскольку у групповых ящиков на самом деле нет клиентской области, ее можно рассчитать примерно так:
// Calculate the client area of a dialog that corresponds to the perceived
// client area of a groupbox control. An extra padding in dialog units can
// be specified (preferably in multiples of 4).
//
RECT getClientAreaInGroupBox(HWND dlg, int id, int padding = 0) {
HWND group = GetDlgItem(dlg, id);
RECT rc;
GetWindowRect(group, &rc);
MapWindowPoints(0, dlg, (POINT*)&rc, 2);
// Note that the top DUs should be 9 to completely avoid overlapping the
// groupbox label, but 8 is used instead for better alignment on a 4x4
// design grid.
RECT border = { 4, 8, 4, 4 };
OffsetRect(&border, padding, padding);
MapDialogRect(dlg, &border);
rc.left += border.left;
rc.right -= border.right;
rc.top += border.top;
rc.bottom -= border.bottom;
return rc;
}
Обратите внимание, что то же самое относится к элементам управления Tab. Они тоже не созданы для того, чтобы быть родителями, и будут демонстрировать подобное поведение.
Как именно вы "получаете позицию клиентской области группового ящика"? GetClientRect дает область, включая границы и заголовок, что не позволяет размещать без рисования поверх чего-либо.
@nwp, хороший вопрос. Мне не удалось найти исходную реализацию, но я добавил в свой ответ возможное решение. По сути, это взлом с использованием диалоговых модулей.
Появляется ли черная рамка вокруг всех кнопок или только на изображении, которое вы предоставили?