1. 程式人生 > >當CTreeCtrl控制元件失去焦點後,保持選中狀態的方法(總結)

當CTreeCtrl控制元件失去焦點後,保持選中狀態的方法(總結)

一. 設定控制元件屬性或樣式

       1. 控制元件屬性

 控制元件Always Show Selection屬性設定為True。

       2. 修改樣式

如果控制元件是動態生成的,那麼在Create時給dwStyle增加一個屬性TVS_SHOWSELALWAYS;

或者呼叫ModifyStyle函式修改:ctreectrl.ModifyStyle(0, TVS_SHOWSELALWAYS);

以上兩種方法當控制元件失去焦點後被選項的背景顏色會成灰色,不同的系統主題顯示不一樣,有時候與未選中項很像,仔細看不太明顯,因此可以用下面的方法自己設定各種顏色

二. 過載OnNMCustomdraw或OnCustomdraw函式

直接上程式碼比較直觀

if (this->m_hWnd != pNMHDR->hwndFrom)
		return;

	LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)pNMHDR;
	switch (pCustomDraw->nmcd.dwDrawStage)
	{
	case CDDS_PREPAINT:
		// Need to process this case and set pResult to CDRF_NOTIFYITEMDRAW, 
		// otherwise parent will never receive CDDS_ITEMPREPAINT notification. (GGH) 
		*pResult = CDRF_NOTIFYITEMDRAW;
		return;

	case CDDS_ITEMPREPAINT: //失去焦點後被選項各種顏色
		if (this->IsWindowEnabled() == 1)
		{
			if ((pCustomDraw->nmcd.uItemState & (CDIS_FOCUS)) == 0
				&& (pCustomDraw->nmcd.uItemState & (CDIS_SELECTED)) == CDIS_SELECTED) // selected
			{
				pCustomDraw->clrTextBk = RGB(0, 128, 220); //失去焦點後被選項背景顏色
				pCustomDraw->clrText = RGB(255, 255, 255); //失去焦點後被選項文字顏色
			}
			*pResult = CDRF_NOTIFYPOSTPAINT;
			return;
		}
		else {
			*pResult = CDRF_DODEFAULT;
			return;
		}
	case CDDS_ITEMPOSTPAINT:  //失去焦點後給被選項畫一個外框,這個case根據需要可有可無
		if (this->IsWindowEnabled() == 1)
		{
			if ((pCustomDraw->nmcd.uItemState & (CDIS_FOCUS)) == 0
				&& (pCustomDraw->nmcd.uItemState & (CDIS_SELECTED)) == CDIS_SELECTED) // selected
			{
				CRect   rcText;
				HTREEITEM hItem = (HTREEITEM)pCustomDraw->nmcd.dwItemSpec;
				this->GetItemRect(hItem, &rcText, true);
				CPen penBlue(PS_SOLID, 1, RGB(255, 0, 0)); //失去焦點後被選項的外框顏色
				CDC* pDC = CDC::FromHandle(pCustomDraw->nmcd.hdc);
				CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
				CBrush* pOldBrush = pDC->SelectObject(pBrush);
				CPen* pOldPen = pDC->SelectObject(&penBlue);
				pDC->Rectangle(&rcText);
				pDC->SelectObject(pOldBrush);
				pDC->SelectObject(pOldPen);
			}
			*pResult = CDRF_SKIPDEFAULT;
			return;
		}
		else {
			*pResult = CDRF_DODEFAULT;
			return;
		}
	}

推薦第二種方法