Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как изменить размер верхней части CComboBox, содержащей CEdit

32K
14 октября 2008 года
Denis1986
27 / / 25.08.2008
Я работаю над прикручиванием скинов к комбобоксу. Для этого, в частности, после создания комбобокса мне нужно изменить его высоту (без ниспадающего списка, только верхней части, содержащей CEdit) в соответствии с высотой скина. Я пытаюсь сделать это так:
 
Код:
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
}

Но 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);
    }
}
//...

Но этот вариант оказался также неэффективен, как и первый.
Вопрос: как динамически изменить высоту комбобокса (без ниспадающего списка, только верхней части, содержащей CEdit)?
288
14 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Denis1986

Вопрос: как динамически изменить высоту комбобокса (без ниспадающего списка, только верхней части, содержащей CEdit)?



Проблема. Насколько я знаю, сам виндовый control ComboBox (на котором и построен MFC-шный компонент) не позволяет изменять высоту своего Edit'а таким способом. Зато изменяет ее при изменении размера шрифта. Может в вашей ситуации это поможет.

32K
15 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
Я попробовал варьировать размер шрифта для 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);
}

Я попробовал устанавливать размер шрифта 12, 14, 16, но высота CEdit и комбобокса от этого не менялась.
288
15 октября 2008 года
nikitozz
1.2K / / 09.03.2007
А если изменять размер шрифта не у Edit'а, а у самого ComboBox'а. Например вот этот код у меня работает (высота изменяется)
 
Код:
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);
32K
18 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
Я столкнулся с интересным эффектом: когда я изменил размер шрифта для обычного комбобокса, то высота комбобокса действительно изменилась (как ты и говорил).
Но когда я попробовал также поменять размер шрифта для своего комбобокса (снаследованного от CComboBox), то его размер остался неизменным.
Если тебе не сложно, посмотри, пожалуйста, проект, в котором я тестирую свой класс CSkinnedComboBox.
В методе
void CTestSkinnableArchitectureDlg::DoDataExchange(CDataExchange* pDX)
вызывается метод SetlFont() для m_skinned_combo2, после чего меняется шрифт, а размер комбобокса не меняется.
288
18 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Пока твой исходник не смотрел. Руки не дошли :)
Зато заметил следующее, если создать ComboBox со стилем CBS_OWNERDRAWVARIABLE, то его функция MeasureItem вызовется и для edit'а. В этом случае lpmis->itemID будет равен (UINT)-1. Так вот если в этом вызове выставить itemHeight в необходимую высоту для edit'а, то edit свою высоту имзменит.
Вообщем попробуй пока так, а я вечерком покопаюсь в твоем исходнике.

P.S. А в какой версии MSVS писал?
32K
20 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
Спасибо! Мне действительно удалось задать нужную высоту для edit в MeasureItem(). При этом высота самого комбобокса изменилась в соответствии с новой высотой edit.
Кстати, такой подход вполне применим и при использовании стиля CBS_OWNERDRAWFIXED.

Правда, была одна проблема: если создавать комбобокс с ID = 1000, то MeasureItem() не вызывается. Я об этом не знал и недоумевал, почему в тестовом проекте MeasureItem() вызывается, а в основном приложении нет. Интересно, почему 1000 является таким магическим числом для комбобокса :)

P.S.: Проблему можно считать решённой.
288
20 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: Denis1986

Правда, была одна проблема: если создавать комбобокс с ID = 1000, то MeasureItem() не вызывается. Я об этом не знал и недоумевал, почему в тестовом проекте MeasureItem() вызывается, а в основном приложении нет. Интересно, почему 1000 является таким магическим числом для комбобокса :)



Может просто в проекте уже существует элемент управления с таким ID?

32K
24 октября 2008 года
Denis1986
27 / / 25.08.2008
nikitozz
Да, ты оказался прав относительно элемента управления с таким же id :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог