使用MFC中系統CCombobox控件中CBN_DROPDWON風格時,edit編輯控件的高度的光標一直處於左上角位置。
效果如下圖所示:
其實,想要實現光標處於垂直狀態,如下圖所示:
這種效果看着就比較順眼了。
在此,有人想要問,怎麼改變編輯框的高度呢?
有人使用系統的MoveWindow,居然不生效?這個問題我也遇到過。具體爲什麼不生效,我無法解釋,但是我知道如何改變edit編輯框的高度
SetItemHeight(-1 , 60); --- >>>>設置edit編輯框的高度 === 60
SetItemHeight(1 , 60); ---- >>>>設置下拉文本的高度 === 60
如果有需要可以使用兩句代碼進行設置。
下面,就要說說如何改變edit光標的位置。
第一種方案:
我最開始打算在 PreSubclassWindow 消息中,將我自己繪製的MyEdit 與CCombobx控件中的編輯控件進行關聯,希望可以用
CEdit::SetRectNP修改Edit控件的顯示區域。
代碼如下,主要是做關聯
void MyComboBox::PreSubclassWindow()
{
CComboBox::PreSubclassWindow();
COMBOBOXINFO comboInfo;
//獲取控件信息
comboInfo.cbSize = sizeof(COMBOBOXINFO);
GetComboBoxInfo(&comboInfo);
//子類化編輯框
if (comboInfo.hwndItem != nullptr )
{
if ( !((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST))
m_editCtrl.SubclassWindow(comboInfo.hwndItem);
}
}
其中,主要用到的是GetComboBoxInfo函數獲取。
獲取到的edit的區域 comboInfo.rcItem。
再使用m_editCtrl.SetRectNP(處理後的edit區域)。
結果發現,不能修改光標的位置。
該方案准備放棄。
後來,我看別的博友說使用 OnNcCalcSize 消息做處理。在這裏處理edit區域設置。
我就嘗試着使用該消息
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
BEGIN_MESSAGE_MAP(MyComboBox, CComboBox)
ON_WM_NCCALCSIZE()
END_MESSAGE_MAP()
void MyComboBox::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
//獲取字體的屬性
CFont *font = GetFont();
LOGFONT lf;
font->GetLogFont(&lf);
LONG nFontHeight = 0;
nFontHeight = lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight;
COMBOBOXINFO comboInfo;
//獲取控件信息
comboInfo.cbSize = sizeof(COMBOBOXINFO);
GetComboBoxInfo(&comboInfo);
CRect rectEdit = comboInfo.rcItem;
rectEdit.top += (rectEdit.Height()-nFontHeight)/2 -3;
m_editCtrl.MoveWindow(rectEdit);
CComboBox::OnNcCalcSize(bCalcValidRects , lpncsp);
}
根據上述我貼出的代碼可以將光標的位置進行改變。
對OnNcCalcSize函數的解析:
第一步:
獲取當前自繪類中,設置的字體的屬性。
在獲取的時候,有可能lf.lfHeight爲負數。所以,這裏我使用了三目運算符進行轉換。如果是負數,轉成正數。
第二步:
獲取當前控件的所有屬性。
根據上一步獲取的字體的高度,移動關聯上edit控件。這裏的m_editCtrl控件的關聯,和我的列出的第一種方案的關聯是一樣的。
根據上述代碼,可以實現的效果,如下:
實現的效果居然如上圖所示,和我展示的效果有些不同,有一塊不明確區域。
後來我想着在該控件的顏色反射消息中獲取,是不是在OnNcCalcSize中改變了edit區域後,以後的都變了?
經過測試後,發現。edit的區域沒有改變,但是這一塊陰影是怎麼來的?我很是不明白。
後來,恍然大悟!因爲我修改了edit的顯示區域,但是系統認爲還是原來的區域。所有上面的內容就呈現爲CCombobox的非客戶區域。
我需要刷新combobox的背景
afx_msg BOOL OnEraseBkgnd(CDC *pDC);
BEGIN_MESSAGE_MAP(MyComboBox, CComboBox)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
BOOL MyComboBox::OnEraseBkgnd(CDC *pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillSolidRect(&rect , RGB(255 , 255 , 255));
return FALSE;
//return CComboBox::OnEraseBkgnd(pDC);
}
再次運行,就沒有陰影區域了。如此就設置成功了。
如果有疑問,歡迎博友發郵件討論。共同學習,共同進步。