用vs2017 enterprise 2017寫了一個程式
問題1
雙緩沖繪圖,但是發現界面內容變化的時候還是會閃爍
正常不是應該在memdc中繪圖然后bitblt SRCCOPY程式會把畫完的界面統一提交到顯存再顯示么,不應該有閃爍了啊。
不知道哪里有問題。
問題2
怎么感覺vs的專案屬性改了不管用呢。一個是改了專案的unicode/多位元組屬性,結果發現里面的字符默認還是unicode的,也rebuild了,編譯的專案的配置debug/x86和編譯的版本是一樣的。不知為何
另外用了個jsoncpp決議json ,本來把專案的原始碼加到工程中,并且把json這個目錄放到了工程目錄 下面
json->1. src 2.json(include) 把這個頭檔案目錄也放到了專案屬性中的include路徑下,結果怎么也不管用。include <json/xx.h> 編譯提示找不到檔案,明明vs va都能識別出檔案路徑。最后都改成 include "json/json/xx.h" 才好使。正常加到include目錄的設定里后可以直接<>包含。 好奇怪的問題。按理說不能不好使啊。vc也用過好多版本了。應該也不是沒整明白。
畫界面的代碼如下OnPaint 閃爍
CRect rc;
GetClientRect(&rc);
CPaintDC dc(this); // 螢屏 DC
CDC memDC; // 記憶體 DC ,構造一個 DC
CBitmap memBitmap; // 構造 一個 bmp物件
memDC.CreateCompatibleDC(&dc); // 產生兼容的記憶體dc, 這是雙緩沖的 繪制方法,先繪制到 記憶體dc
memBitmap.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height()); // 產生 一個 bmp 物件 ,m_nWidth,m_nHeight 是大小
memDC.SelectObject(&memBitmap); // 把 bmp 放入 記憶體dc , 不能用螢屏 DC
memDC.SetBkMode(TRANSPARENT); // 讓 文本 的背景是透明的
HDC hDC = memDC.m_hDC;
//-------------------------
if (::GetProp(m_hWnd, _T("SERVER_STATUS_DC"))) { // 取出CacheDC
::SelectObject(m_hCacheDC, m_hOldCacheBitmap);
::DeleteObject((HGDIOBJ)m_hCacheBitmap);
}
else {
::SetProp(m_hWnd, _T("SERVER_STATUS_DC"), (HANDLE)m_hCacheDC); //主視窗增加了一個屬性 cacheDC
}
m_hCacheBitmap = CreateCompatibleBitmap(dc.m_hDC, rc.Width(), rc.Height());
m_hOldCacheBitmap = (HBITMAP)::SelectObject(m_hCacheDC, m_hCacheBitmap);
// move to onerasebackground
memDC.FillSolidRect(&rc, m_bgcolor );
int i;
for (i = 0; i < m_regions.size(); i++)
{
PaintRegion(rc, memDC, m_regions[i]);
}
::BitBlt(m_hCacheDC, 0, 0, rc.Width(), rc.Height(), hDC, 0, 0, SRCCOPY);
dc.BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY);
uj5u.com熱心網友回復:
1 BOOL Cxxxx::OnEraseBkgnd(CDC* pDC){
return TRUE;
}
uj5u.com熱心網友回復:
貌似不太行,有個static 上面的文本會閃。其它自繪的部分好像好些。
uj5u.com熱心網友回復:
OnPaint 只 繪制 自己 同時 Invalidate 各 子視窗。1 所有 在 OnPaint 中 繪制 子視窗 的 代碼 將 無效。
2 所有 子視窗的 繪制 必須 繪制到 memDC
uj5u.com熱心網友回復:
@schlafenhamster沒太明白 如果界面上有一部分圖是自己繪制的,一部分是用的現有控制元件,需要怎么做
自繪肯定是畫到memdc 現成控制元件需要怎么改繪也繪到memdc ?
有個說法是加上WS_CLIPCHILDREN 屬性。 可行?
uj5u.com熱心網友回復:
void CxxxxDlg::CopyPictures(HWND hWnd,CPoint point){// TODO: Add your message handler code here
UINT ID=::GetDlgCtrlID(hWnd);
// afxDump << ID << " ID\n";
// size
CRect rc;
if(hWnd==0)
{
ID=0;
GetWindowRect(&rc);// the dialog
}
else
{
::GetWindowRect(hWnd,&rc);
}
// create dc
CClientDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
// create empty bmp
HBITMAP bmp=CreateCompatibleBitmap(dc /* not dcMem */, rc.Width(),rc.Height());
dcMem.SelectObject(bmp);
//
CString prompt;
switch (ID)
{
case IDOK:// "Exit"
m_Ok.SendMessage(WM_PAINT,(WPARAM)dcMem.m_hDC,0);
prompt="\"Exit\" button has been copied to clipbroad!";
break;
case IDC_SCROLLBAR1:// "H bar"
m_hBar.SendMessage(WM_PAINT,(WPARAM)dcMem.m_hDC,0);
prompt="\"Horizontal\" scrollbar has been copied to clipbroad!";
break;
case IDC_SCROLLBAR2:// "V bar"
m_vBar.SendMessage(WM_PAINT,(WPARAM)dcMem.m_hDC,0);
prompt="\"Vertical\" scrollbar has been copied to clipbroad!";
break;
case IDC_SHOW:// "Open"
m_Open.SendMessage(WM_PAINT,(WPARAM)dcMem.m_hDC,0);
prompt="\"Open\" button has been copied to clipbroad!";
break;
case IDC_PICTURE:// m_Pic
OnMyPaint((WPARAM)dcMem.m_hDC,0);
prompt="\"CStatic Picture\" has been copied to clipbroad!";
break;
case 0:// the dialog
this->SendMessage(WM_PRINT,(WPARAM)dcMem.m_hDC,
(LPARAM)(PRF_NONCLIENT | PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_OWNED));
prompt="\"The whole dialog\" has been copied to clipbroad!";
break;
}
// move bmp to clipboard
CBitmap *pbmp=dcMem.GetCurrentBitmap();
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,pbmp->GetSafeHandle());
CloseClipboard();
//
DeleteObject(bmp);
//
AfxMessageBox(prompt);
}
通常 OnPaint 沒有 引數, 所以 用
m_Ok.SendMessage(WM_PAINT,(WPARAM)dcMem.m_hDC,0);
uj5u.com熱心網友回復:
在 對話框中繪制 控制元件
CDialog::OnPaint(); 發Invalidate到子視窗,子視窗無效
// CStatic m_Pic2;
m_Pic2.UpdateWindow(); 使子視窗有效 !
CDC *picDC=m_Pic2.GetDC(); 取 子視窗 dc
CRect rc;
m_Pic2.GetClientRect(rc); 取子視窗客戶區
//
FillPoints(picDC,rc,0,RGB(0,255,255));
//
// picDC->SelectObject(old);
ReleaseDC(picDC);
uj5u.com熱心網友回復:
/* InvalidateRect 的作用是無效視窗客戶區,發送低優先級的WM_PAINT訊息 UpdateWindow的作用是馬上重繪同時使客戶區有效。
注意下面的PaintWindow 函式,函式用GetDC得到設備環境句柄,這里就是關鍵 。
GetDC和BeginPaint不同,從GetDC回傳句柄之后 你可以用此句柄在客戶區任何地方繪圖,
不管是有效區還是無效區,同時GetDC不會使無效區有效化。所以 你把 UpdateWindow去掉了,
下面的PaintWindow仍然執行,只不過畫完圖之后你的子視窗控制元件客戶區已然是無效的,
這就導致系統發送一條WM_PAINT訊息到子視窗的視窗程序,默認的視窗程序會用畫刷填充,
這里應該是和背景色相同的畫刷 所以什么都顯示不了。
*/
void PaintTheBlock (HWND hCtrl, int iColor, int iFigure)
{
InvalidateRect (hCtrl, NULL, FALSE);//TRUE) ;
UpdateWindow (hCtrl) ;
PaintWindow (hCtrl, iColor, iFigure) ;
}
uj5u.com熱心網友回復:
創建視窗時設定成不重畫背景uj5u.com熱心網友回復:
不要讓框架重繪背景uj5u.com熱心網友回復:
dc.ExcludeClipRect(靜態控制元件區域)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/61043.html
標籤:界面
