CCombobox控制元件修改編輯框游標顯示位置,呈現:上下垂直狀態
使用MFC中系統CCombobox控制元件中CBN_DROPDWON風格時,edit編輯控制元件的高度的游標一直處於左上角位置。
效果如下圖所示:
其實,想要實現游標處於垂直狀態,如下圖所示:
這種效果看著就比較順眼了。
在此,有人想要問,怎麼改變編輯框的高度呢?
有人使用系統的MoveWindow,居然不生效?這個問題我也遇到過。具體為什麼不生效,我無法解釋,但是我知道如何改變edit編輯框的高度
SetItemHeight(-1 , 60); --- >>>>設定edit編輯框的高度 === 60
SetItemHeight(1 , 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);
}
再次執行,就沒有陰影區域了。如此就設定成功了。
如果有疑問,歡迎博友發郵件討論。共同學習,共同進步。