void CSkinnedComboBox::UpdateWindowSizeAccordingToSkinSize()
{
CRect l_window_rect;
GetWindowRect(&l_window_rect);
SetWindowPos(NULL, 0, 0, l_window_rect.Width(), m_bmp.bmHeight, SWP_NOMOVE | SWP_NOZORDER);
CRect l_rect;
GetWindowRect(&l_rect); //l_rect.Height() == l_window_rect.Height() -> error
}
Как изменить размер верхней части CComboBox, содержащей CEdit
Код:
Но l_rect.Height() == l_window_rect.Height(), то есть SetWindowPos ничего не изменила.
Я подумал, что, возможно, стоит сначала изменить размер CEdit, входящего в состав комбобокса:
Код:
HBRUSH CSkinnedComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_EDIT)
{
//Edit control
if (m_my_edit.GetSafeHwnd() == NULL)
{
m_my_edit.SubclassWindow(pWnd->GetSafeHwnd());
CRect l_edit_rect;
m_my_edit.GetWindowRect(&l_edit_rect);
m_my_edit.SetWindowPos(NULL, 0, 0, l_edit_rect.Width(), m_bmp.bmHeight - m_top_border_thickness
- m_bottom_border_thickness, SWP_NOMOVE | SWP_NOZORDER);
CRect l_my_rect;
GetWindowRect(&l_my_rect);
SetWindowPos(NULL, 0, 0, l_my_rect.Width(), m_bmp.bmHeight, SWP_NOMOVE | SWP_NOZORDER);
}
}
//...
{
if (nCtlColor == CTLCOLOR_EDIT)
{
//Edit control
if (m_my_edit.GetSafeHwnd() == NULL)
{
m_my_edit.SubclassWindow(pWnd->GetSafeHwnd());
CRect l_edit_rect;
m_my_edit.GetWindowRect(&l_edit_rect);
m_my_edit.SetWindowPos(NULL, 0, 0, l_edit_rect.Width(), m_bmp.bmHeight - m_top_border_thickness
- m_bottom_border_thickness, SWP_NOMOVE | SWP_NOZORDER);
CRect l_my_rect;
GetWindowRect(&l_my_rect);
SetWindowPos(NULL, 0, 0, l_my_rect.Width(), m_bmp.bmHeight, SWP_NOMOVE | SWP_NOZORDER);
}
}
//...
Но этот вариант оказался также неэффективен, как и первый.
Вопрос: как динамически изменить высоту комбобокса (без ниспадающего списка, только верхней части, содержащей CEdit)?
Цитата: Denis1986
Вопрос: как динамически изменить высоту комбобокса (без ниспадающего списка, только верхней части, содержащей CEdit)?
Проблема. Насколько я знаю, сам виндовый control ComboBox (на котором и построен MFC-шный компонент) не позволяет изменять высоту своего Edit'а таким способом. Зато изменяет ее при изменении размера шрифта. Может в вашей ситуации это поможет.
Я попробовал варьировать размер шрифта для CEdit, входящего в состав комбобокса, но при этом высота CEdit осталась константной. Сейчас код выглядит так:
Код:
if (nCtlColor == CTLCOLOR_EDIT)
{
//Edit control
if (m_my_edit.GetSafeHwnd() == NULL)
{
m_my_edit.SubclassWindow(pWnd->GetSafeHwnd());
SetControlFont(&m_my_edit);
CRect l_my_rect;
GetWindowRect(&l_my_rect);
CRect l_edit_rect;
m_my_edit.GetWindowRect(&l_edit_rect);
m_my_edit.SetWindowPos(NULL, m_left_border_thickness, m_top_border_thickness, l_edit_rect.Width(),
m_bmp.bmHeight - m_top_border_thickness - m_bottom_border_thickness, SWP_NOZORDER);
SetWindowPos(NULL, 0, 0, l_my_rect.Width(), m_bmp.bmHeight, SWP_NOMOVE | SWP_NOZORDER);
}
}
//...
void CSkinnedComboBox::SetControlFont(CWnd* a_edit_control)
{
//CFont l_edit_font;
m_edit_font.CreateFont(12, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL);
a_edit_control -> SetFont(&m_edit_font, FALSE);
}
{
//Edit control
if (m_my_edit.GetSafeHwnd() == NULL)
{
m_my_edit.SubclassWindow(pWnd->GetSafeHwnd());
SetControlFont(&m_my_edit);
CRect l_my_rect;
GetWindowRect(&l_my_rect);
CRect l_edit_rect;
m_my_edit.GetWindowRect(&l_edit_rect);
m_my_edit.SetWindowPos(NULL, m_left_border_thickness, m_top_border_thickness, l_edit_rect.Width(),
m_bmp.bmHeight - m_top_border_thickness - m_bottom_border_thickness, SWP_NOZORDER);
SetWindowPos(NULL, 0, 0, l_my_rect.Width(), m_bmp.bmHeight, SWP_NOMOVE | SWP_NOZORDER);
}
}
//...
void CSkinnedComboBox::SetControlFont(CWnd* a_edit_control)
{
//CFont l_edit_font;
m_edit_font.CreateFont(12, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL);
a_edit_control -> SetFont(&m_edit_font, FALSE);
}
Я попробовал устанавливать размер шрифта 12, 14, 16, но высота CEdit и комбобокса от этого не менялась.
Код:
CFont f;
CComboBox comb;
...........................................
f.CreateFont(22, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL);
comb.SetFont(&f, 1);
CComboBox comb;
...........................................
f.CreateFont(22, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL);
comb.SetFont(&f, 1);
Я столкнулся с интересным эффектом: когда я изменил размер шрифта для обычного комбобокса, то высота комбобокса действительно изменилась (как ты и говорил).
Но когда я попробовал также поменять размер шрифта для своего комбобокса (снаследованного от CComboBox), то его размер остался неизменным.
Если тебе не сложно, посмотри, пожалуйста, проект, в котором я тестирую свой класс CSkinnedComboBox.
В методе
void CTestSkinnableArchitectureDlg::DoDataExchange(CDataExchange* pDX)
вызывается метод SetlFont() для m_skinned_combo2, после чего меняется шрифт, а размер комбобокса не меняется.
Зато заметил следующее, если создать ComboBox со стилем CBS_OWNERDRAWVARIABLE, то его функция MeasureItem вызовется и для edit'а. В этом случае lpmis->itemID будет равен (UINT)-1. Так вот если в этом вызове выставить itemHeight в необходимую высоту для edit'а, то edit свою высоту имзменит.
Вообщем попробуй пока так, а я вечерком покопаюсь в твоем исходнике.
P.S. А в какой версии MSVS писал?
Спасибо! Мне действительно удалось задать нужную высоту для edit в MeasureItem(). При этом высота самого комбобокса изменилась в соответствии с новой высотой edit.
Кстати, такой подход вполне применим и при использовании стиля CBS_OWNERDRAWFIXED.
Правда, была одна проблема: если создавать комбобокс с ID = 1000, то MeasureItem() не вызывается. Я об этом не знал и недоумевал, почему в тестовом проекте MeasureItem() вызывается, а в основном приложении нет. Интересно, почему 1000 является таким магическим числом для комбобокса :)
P.S.: Проблему можно считать решённой.
Цитата: Denis1986
Правда, была одна проблема: если создавать комбобокс с ID = 1000, то MeasureItem() не вызывается. Я об этом не знал и недоумевал, почему в тестовом проекте MeasureItem() вызывается, а в основном приложении нет. Интересно, почему 1000 является таким магическим числом для комбобокса :)
Может просто в проекте уже существует элемент управления с таким ID?
Да, ты оказался прав относительно элемента управления с таким же id :)