“閃爍”的原因是擦除背景(用背景色重新填充)與繪制前景圖像之間有時間差,而且背景和前景顏色有差異,導致眼睛看上去好像在閃爍。
“閃爍”并不主要是因為GDI或GDI+效率低造成的。
解決這個問題需從兩個方面入手:1.縮短(或消除)前后景繪圖時間差,2.減少繪制次數
1.縮短(或消除)前后景繪圖時間差
OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
實際上背景填充是必須,否則前景圖像與殘留的背景混在一起非常雜亂,
這里取消的步驟,其實移到繪圖過程了(見2.),合成一張完整圖像。
2.減少繪制次數
采用“雙緩沖”技術,先在內存緩沖區中完成繪圖,再貼到屏幕上
另外如果緩沖圖像內容不是變化的,應存為成員對象之類,不要每次去畫
一般在OnDraw(CDC* pDC)中完成
///////////////////////////--GDI --////////////////////////////////////
int nWidth=1000;
int nHeight=1000;
CDC MemDC; //首先定義一個顯示設備對象
CBitmap MemBitmap;//定義一個位圖對象
//隨后建立與屏幕顯示兼容的內存顯示設備
MemDC.CreateCompatibleDC(pDC); //這時還不能繪圖,因為沒有地方畫 ^_^
//下面建立一個與屏幕顯示兼容的位圖,至于位圖的大小嘛,可以用窗口的大小
//,也可以自己定義(如:有滾動條時就要大于當前窗口的大小,在BitBlt時決定拷貝內存的哪部分到屏幕上)
MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
//將位圖選入到內存顯示設備中
//只有選入了位圖的內存顯示設備才有地方繪圖,畫到指定的位圖上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
//先用背景色將位圖清除干凈,這里用原背景色作為背景
//你也可以用自己應該用的顏色
MemDC.FillSolidRect(0,0,nWidth,nHeight,pDC->GetBkColor());
//繪圖
CBrush brush(RGB(0,255,0));
for(int i=0;i<50;i++)
{
for(int j=0;j<80;j++)
{
//MemDC.Rectangle(10*j,10*i,9,9);
CRect rc(10*j,10*i,10*j+8,10*i+8);
MemDC.FillRect(&rc,&brush);
}
}
//將內存中的圖拷貝到屏幕上進行顯示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//繪圖完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();
///////////////////////////--GDI+ --////////////////////////////////////
Bitmap* buf=new Bitmap(2000,2000) ;
Graphics gc(buf);//Graphics.FromImage(buf);
//反鋸齒
//gc.SetSmoothingMode(SmoothingModeAntiAlias);
SolidBrush bgbrush(Color(255,255,255,255));
gc.FillRectangle(&bgbrush,0,0,2000,2000);//背景填充
Pen pen(Color(255, 0, 0, 255));
SolidBrush sbrush(Color(255,0,255,255));
for(int i=0;i<60;i++)
{
for(int j=0;j<60;j++)
gc.FillRectangle(&sbrush,10*j,10*i,9,9);
}
Graphics G(pDC->GetSafeHdc());
G.DrawImage(buf ,0,0);
首先,這是一個MFC的Bug
http://connect.microsoft.com/VisualStudio/feedback/details/505466/mfc-visual-style-font-size-too-small-to-display-chinese-character-clearly-on-windows-xp
解決時間暫時還不確定,臨時的方案如下:
App在InitInstance中加入:
LOGFONT logfont = {0};
:: SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &logfont, 0);
afxGlobalData.SetMenuFont(&logfont,true);
注釋:
字體的設置保存在一個全局變量afxGlobalData中,此變量定義AfxGlobals.h中。
AFX_GLOBAL_DATA中有一個SetMenuFont可以設定字體屬性,影響Menu、Toolbar、Dock Pane等的caption字體。
但是這個設置對tooltip無影響,臨時解決:在上面代碼基礎上在加入
if(afxGlobalData.fontTooltip.GetSafeHandle() != NULL)
{
::DeleteObject(afxGlobalData.fontTooltip.Detach());
}
afxGlobalData.fontTooltip.CreateFontIndirect(&logfont);
根據調整管的工作狀態,我們常把穩壓電源分成兩類:線性穩壓電源和開關穩壓電源。
線性穩壓電源,是指調整管工作在線性狀態下的穩壓電源。而在開關電源中則不一樣,開關管(在開關電源中,我們一般把調整管叫做開關管)是工作在開、關兩種狀態下的:開——電阻很小;關——電阻很大。
開關電源是一種比較新型的電源。它具有效率高,重量輕,可升、降壓,輸出功率大等優點。但是由于電路工作在開關狀態,所以噪聲比較大。 通過下圖,我們來簡單的說說降壓型開關電源的工作原理。如圖所示,電路由開關K(實際電路中為三極管或者場效應管),續流二極管D,儲能電感L,濾波電容C等構成。當開關閉合時,電源通過開關K、電感L給負載供電,并將部分電能儲存在電感L以及電容C中。由于電感L的自感,在開關接通后,電流增大得比較緩慢,即輸出不能立刻達到電源電壓值。一定時間后,開關斷開,由于電感L的自感作用(可以比較形象的認為電感中的電流有慣性作用),將保持電路中的電流不變,即從左往右繼續流。這電流流過負載,從地線返回,流到續流二極管D的正極,經過二極管D,返回電感L的左端,從而形成了一個回路。通過控制開關閉合跟斷開的時間(即PWM——脈沖寬度調制),就可以控制輸出電壓。如果通過檢測輸出電壓來控制開、關的時間,以保持輸出電壓不變,這就實現了穩壓的目的。
500)this.width=500" border="0">
在開關閉合期間,電感存儲能量;在開關斷開期間,電感釋放能量,所以電感L叫做儲能電感。二極管D在開關斷開期間,負責給電感L提供電流通路,所以二極管D叫做續流二極管。
在實際的開關電源中,開關K由三極管或場效應管代替。當開關斷開時,電流很小;當開關閉合時,電壓很小,所以發熱功率U×I就會很小。這就是開關電源效率高的原因。
看過完兩個關于電源的FAQ后,大家可能對電源的效率計算還不了解。在后面的FAQ中,我們將專門給大家介紹。
摘自網絡.