(MFC)の点滅を解決し、問題を追跡することはできません水平スクロールバーをドラッグしてCListCtrlの

       以下に示すようにCPropertySheetのビューの上に持って、プロジェクトで使用される画面は、CPropertyPageに少数れている、情報を表示するには、ユーザーのためのページあたりのプロパティCListCtrlのを持っています。CListCtrlの中の情報は、すべて200ミリ秒後に更新されますので、リージョンを点滅を停止につながります。我々は、データの複数の列を見て背中の真ん中までスクロールしたいとき同時に、スペース不足のため、あなたが原因リフレッシュ開始点にわずか引くと引き戻され、CListCtrlの上に水平スクロールバーがあり、それはデータの列の後ろに見ることが困難になります我々は、水平スクロールバーが問題を追跡することはできません。この問題に言及しました。このレビューは、関連するソリューションを記録するために、これらの2つの点に焦点を当てています。

(1)修正フリッカ

      私たちは、それぞれの再描画の呼び出しは、視覚的ちらつき引き起こし、画像の前後の間にあまりにも多くのコントラストが得られ、消去領域(デフォルトは白)の背景色でOnEraseBkgnd前に、グラフィックスが点滅しているので理由があることを知っています。点滅を削除するには、このコントラストを減少させることにあります。より良い方法は、すなわちグラフィックスメモリにキャンバスを開き、グラフィックスに良いコピー表示装置(描画する、ダブルバッファリングのグラフィックスを使用することですhttp://www.diybl.com/course/3_program/をC ++ / cppjs / 200867 / 123361.html)。また、CListCtrlのフリッカの問題を防ぐために、ユーザーもまとめ(http://blog.sina.com.cn/s/blog_5ee42ba30100g50j.html)。

     問題自体と組み合わせる上記の情報へのアクセスでは、次のソリューションの設計は、フリッカの問題を解決します。

    まず、すべてのデータが表示CListCtrlの上で更新されるため、ビュー、CPropertySheetの、CPropertyPageに、そして何の変化のために、それは、背景色であなたが再描画するたびに消去エリアを禁止し、コントラストを低下させることができます。過負荷メッセージは、それぞれこれらの三つの機能、変更OnEraseBkgnd 戻りFALSEを;

    第二に、CListCtrlのちらつきの問題のためにダブルバッファリングを使用して解決することができます。次のとおりです。

void CMyListCtrl::OnPaint()
{
	//使用双缓冲的方法绘制背景
	CPaintDC dc(this); // device context for painting
	CRect rect;
	CRect headerRect;
	CDC MenDC;		//内存DC   
	CBitmap MemMap;

	GetClientRect(&rect);    
	GetDlgItem(0)->GetWindowRect(&headerRect);   
	MenDC.CreateCompatibleDC(&dc);   
	MemMap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); 
	MenDC.SelectObject(&MemMap);
	MenDC.FillSolidRect(&rect,RGB(255,255,255));   

	//调用默认的OnPaint(),把图形画在内存DC表上   
	DefWindowProc(WM_PAINT,(WPARAM)MenDC.m_hDC,(LPARAM)0);   

	//输出到显示设备
	dc.BitBlt(0,
		headerRect.Height(),   
		rect.Width(),   
		rect.Height(),   
		&MenDC,   
		0,     
		headerRect.Height(),   
		SRCCOPY);   
	MenDC.DeleteDC();
	MemMap.DeleteObject();
}

BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default

	//return CListCtrl::OnEraseBkgnd(pDC);
	return FALSE;
}
     この時点で、ちらつきの全体的な問題を解決します。

(2)水平スクロールバーは、問題の追跡を解決することはできません

      この問題のために、私はオンライン検索から、解決する方法がわからない、もっと混乱し始め、私はGetScrollPos +スクロールで育った、それはEnsureVisibleによって示唆されました。私が試した最初の方法、主にスクロールバーの現在の位置を記録し、その後、リフレッシュ後に記録された位置に設定され、この方法が良いレコードバックの位置ではなく、そうするためには、(フリッカー問題を再導入う開始位置へのスクロールバーの位置からして、記録位置、素晴らしいコントラスト)を記録します。それはないと思われるための第二のアプローチは、マルチラインのみ、複数列のために使用することが見えます。

     だから、私はこの問題を再考します。私はたびに更新され、プログラムのアプローチにいたとき、最初の行項目のすべてを削除し、再挿入新しいデータ情報が含まれているラインアイテム。私はいつもちょうど新しい行の項目がある場合を除き、行項目と再挿入操作を消去せずにデータを更新できるようにしたかったことができないので、実際には、行の数は、依然として、それぞれの更新のみ項目の内容の一部のみ、同じままこの操作の前に参加。あなたは、スクロールバーの位置に戻ることができない場合は、その都度、データがすべてのアイテムの列項目、現在のビューのビュー内の領域だけではありませんが更新され、現在の項目CListCtrlのアイテムを更新するための計算の必要性に基づいて、現在のビューのサイズを表示することができますコンテンツが更新された(後に最初の点で問題が解決することができましたしていないようにこれを行うにしているました)。

      変更後は、水平スクロールバーを達成することができ、トラッキング、プログラムに作られています。

void UpdateItem()
{
   //......
     CString str;
     BOOL bInsertItem = FALSE;
     if(m_bInsertItem)
     {
        m_bInsertItem = FALSE;
	bInsertItem = TRUE;
	m_listInfo.DeleteAllItems();		//删除原有的数据
     }
     for(i=0; i<CNT; i++)
     {  
        str.Format(_T("%d"), i+1);			//序号
	if(bInsertItem)
	    m_listInfo.InsertItem(i, str);		//插入行,显示序号
	str.Format(_T("ID=%d"), xxx);
	m_listInfo.SetItemText(i, 1, str);
       //插入其他内容......
       //......
     }
} 



发布了37 篇原创文章 · 获赞 204 · 访问量 44万+

おすすめ

転載: blog.csdn.net/zwgdft/article/details/7394318