1. 程式人生 > >CCombobox控制元件修改編輯框游標顯示位置,呈現:上下垂直狀態

CCombobox控制元件修改編輯框游標顯示位置,呈現:上下垂直狀態

使用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);
}

再次執行,就沒有陰影區域了。如此就設定成功了。

如果有疑問,歡迎博友發郵件討論。共同學習,共同進步。