對繪制界面什么的不懂。 dc CompatibleDC CompatibleBitmap 什么的混亂,下面是個專案代碼求指教。謝謝
void CMainDlg::OnPaint()
{
CPaintDC dc(this);
CDC memDC;
CBitmap memBitmap;
memDC.CreateCompatibleDC(&dc); //畫界面都是得到當前dc然后創建一個兼容dc么? cpaintdc cdc是什么關系 為什么要有2個?
memBitmap.CreateCompatibleBitmap(&dc,m_nWidth,m_nHeight); //這是準備把一個位圖帖到dc ,通知了一下寬度高度?為什么不是memDC ?
memDC.SelectObject(&memBitmap); //這里用dc(CPaintDC)可以嗎?
memDC.SetBkMode(TRANSPARENT); //后面也沒有TransparentBlt設定transparent有什么用?有什么意義?memDC后面在drawtext的時候用了,這個是說只保留字的部分其它部分透明?
HDC hDC=memDC.m_hDC; //
//-------------------------
if(::GetProp(m_hWnd,_T("CacheDC"))){ ///為什么要把m_hOldCacheBitmap單獨保存?已經是成員變數了。在其它地方用hWnd來獲取并使用?
::SelectObject(m_hCacheDC,m_hOldCacheBitmap); ///這里是干嘛啊?
::DeleteObject((HGDIOBJ)m_hCacheBitmap);
}else{
::SetProp(m_hWnd,_T("CacheDC"),(HANDLE)m_hCacheDC); //主視窗增加了一個屬性 cacheDC
}
m_hCacheBitmap=CreateCompatibleBitmap(dc.m_hDC,m_nWidth,m_nWidth); //前面有個bitmap 了為什么還搞一套cachebitmap
m_hOldCacheBitmap=(HBITMAP)::SelectObject(m_hCacheDC,m_hCacheBitmap);
//--------------------------------------
::FillRect(hDC,m_ClientRc,m_hbrBack); //這好像是用默認的顏色把clientrect全部填滿的意思
::StretchBlt(hDC,0,0,3,m_nHeight,g_SkinDC,0,47,3,1,SRCCOPY); //這些是復制圖片內容,好理解
........
::StretchBlt(hDC,m_nWidth-3,0,3,m_nHeight,g_SkinDC,57,47,3,1,SRCCOPY);
m_MainBtn.Draw(hDC);
....
m_MinBtn.Draw(hDC);
//--------------------------------------
/// 不能直接往hDC上輸出文字 ,只能弄個memDC membitmap 指定寬度高度先往bitmap里輸出(drawtext)然后再把內容復制到dc ?
CString str;
GetWindowText(str);
memDC.DrawText(str,m_TitleRc,DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_HIDEPREFIX);
//--------------------------------------
::BitBlt(m_hCacheDC,0,0,m_nWidth,m_nHeight,hDC,0,0,SRCCOPY);//cachedc保存的是輸出的文字之前的界面?
//上面GetProp成功的兩行代碼是什么功能?
dc.BitBlt(0,0,m_nWidth,m_nHeight,&memDC,0,0,SRCCOPY);//這里用::BitBlt是一樣的吧?
}
uj5u.com熱心網友回復:
void CCustomCtrlDlg::MyPaint()
{
CPaintDC dc(this); // 螢屏 DC
CDC memDC; // 記憶體 DC ,構造一個 DC
CBitmap memBitmap; // 構造 一個 bmp物件
// 產生 兼容的 記憶體 dc, 這是 雙緩沖 的 繪制方法,先繪制到 記憶體dc
memDC.CreateCompatibleDC(&dc);
// 產生 一個 bmp 物件 ,m_nWidth,m_nHeight 是大小
memBitmap.CreateCompatibleBitmap(&dc,m_nWidth,m_nHeight);
// 把 bmp 放入 記憶體dc , 不能用螢屏 DC
memDC.SelectObject(&memBitmap);
// 讓 文本 的背景是透明的
memDC.SetBkMode(TRANSPARENT);
HDC hDC=memDC.m_hDC; //
// 取出CacheDC
if(::GetProp(m_hWnd,_T("CacheDC"))) // 存在
{ // 原cached bmp 放入m_hCacheDC ,洗掉 上次 創建的 m_hCacheBitmap
::SelectObject(m_hCacheDC,m_hOldCacheBitmap);
::DeleteObject((HGDIOBJ)m_hCacheBitmap);
}
else // 不存在
{ // 把 m_hCacheDC 存入 主視窗
::SetProp(m_hWnd,_T("CacheDC"),(HANDLE)m_hCacheDC);
}
// 創建一個 Cached Bitmap,使用 螢屏DC, dc.m_hDC
m_hCacheBitmap=CreateCompatibleBitmap(dc.m_hDC,m_nWidth,m_nWidth);
// 把 m_hCacheBitmap 放入 m_hCacheDC
m_hOldCacheBitmap=(HBITMAP)::SelectObject(m_hCacheDC,m_hCacheBitmap);
//hDC 對應記憶體dc memDC, 填充 記憶體 dc
::FillRect(hDC,m_ClientRc,m_hbrBack);
// 用 g_SkinDC, 來繪制 記憶體DC
::StretchBlt(hDC,0,0,3,m_nHeight,g_SkinDC,0,47,3,1,SRCCOPY);
::StretchBlt(hDC,m_nWidth-3,0,3,m_nHeight,g_SkinDC,57,47,3,1,SRCCOPY);
/// 不能直接往hDC上輸出文字 ,只能弄個memDC membitmap 指定寬度高度先往bitmap里輸出(drawtext)然后再把內容復制到dc ?
CString str;
GetWindowText(str);
// 把 文字 寫人 記憶體DC
memDC.DrawText(str,m_TitleRc,DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_HIDEPREFIX);
// 把記憶體dc 的內容全部復制到 m_hCacheDC
::BitBlt(m_hCacheDC,0,0,m_nWidth,m_nHeight,hDC,0,0,SRCCOPY);
// 最后把 記憶體dc的 內容 復制到 螢屏 dc , 可以使用 ::BitBlt //上面GetProp成功的兩行代碼是什么功能?
dc.BitBlt(0,0,m_nWidth,m_nHeight,&memDC,0,0,SRCCOPY);
}
uj5u.com熱心網友回復:
這是記憶體貼圖的代碼。看了下,這代碼寫的不是很好。
不過可以學習。
uj5u.com熱心網友回復:
gdi+ 記憶體貼圖,采用面向物件的類 CDC還可以用HDC win32的gdi
uj5u.com熱心網友回復:
謝謝你的回復很快很詳細。還是有困惑:
// 這里的dc每次都要用實際的繪圖dc么?可以傳memdc cachedc么? 與SelectObject用的dc,bitmap需要有對應關系嗎?還是能隨便用?
m_hCacheBitmap=CreateCompatibleBitmap(dc.m_hDC,m_nWidth,m_nWidth);
m_hOldCacheBitmap=(HBITMAP)::SelectObject(m_hCacheDC,m_hCacheBitmap);
另外,我看了下cachedc的創建,也很簡單是在dialog.create的時候執行的:
HDC hSrcDC = ::GetDC(0);
g_SkinDC=::CreateCompatibleDC(hSrcDC);
m_hCacheDC=::CreateCompatibleDC(hSrcDC);
已經有了m_hCacheDC 上面在paint的時候 還有必要memDC么?直接用這個m_hCacheDC不行么?
onpaint里的
m_hCacheBitmap=CreateCompatibleBitmap(dc.m_hDC,m_nWidth,m_nWidth);
m_hOldCacheBitmap=(HBITMAP)::SelectObject(m_hCacheDC,m_hCacheBitmap); //這里用memDC也是可以的吧
//--------------------------------------
CString str;
GetWindowText(str);
memDC.DrawText(str,m_TitleRc,DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_HIDEPREFIX);
//--------------------------------------
//這個是把memDC繪制的所有的內容保存到了cachedc 但是用處是什么呢?前面 的代碼當檢測到有快取的時候運行的是
// ::SelectObject(m_hCacheDC,m_hOldCacheBitmap);
// ::DeleteObject((HGDIOBJ)m_hCacheBitmap);
// 除了第一次運行以外GetProp都有回傳值 ,結果就是每次onpaint都會創建m_hCacheBitmap 把memdc畫好的內容保存到cachddc但不知道有什么用?
::BitBlt(m_hCacheDC,0,0,m_nWidth,m_nHeight,hDC,0,0,SRCCOPY);
dc.BitBlt(0,0,m_nWidth,m_nHeight,&memDC,0,0,SRCCOPY);
//雙緩沖不都是SelectObject再select回來實作的么?這里怎么是一個拷貝呢
上面那個cachedc查了一下代碼在下面地方使用了:
BOOL CMainDlg::OnEraseBkgnd(CDC* pDC)
{
try
{
::BitBlt(pDC->m_hDC,0,0,m_nWidth,m_nHeight,m_hCacheDC,0,0,SRCCOPY);
return true;
}
catch (...)
{
return CWnd::OnEraseBkgnd(pDC);
}
}
這么弄有意義嗎?每次繪圖需要自己保存,然后再onerase自己再畫一次?意義何在?
uj5u.com熱心網友回復:
代碼功能歸根結底不是別人幫自己看或講解或注釋出來的;而是被自己靜下心來花足夠長的時間和精力親自動手單步或設斷點或對執行到某步獲得的中間結果顯示或寫到日志檔案中一步一步分析出來的。提醒:再牛×的老師也無法代替學生自己領悟和上廁所!
單步除錯和設斷點除錯(VS IDE中編譯連接通過以后,按F10或F11鍵單步執行,按Shift+F11退出當前函式;在某行按F9設斷點后按F5執行停在該斷點處。)是程式員必須掌握的技能之一。
或者通過注釋掉/不注釋掉相關代碼看前/后運行效果的區別……
uj5u.com熱心網友回復:
“”這么弄有意義嗎?每次繪圖需要自己保存,然后再onerase自己再畫一次?意義何在?“”“”既然 擦背景 用到 , 作者的 初衷 是 加快繪制 速度 吧 ,
BOOL CCustomCtrlDlg::OnEraseBkgnd(CDC* pDC)
{
::BitBlt(pDC->m_hDC,0,0,m_nWidth,m_nHeight,m_hCacheDC,0,0,SRCCOPY);
return true;
// return CDialog::OnEraseBkgnd(pDC);
}
uj5u.com熱心網友回復:
請 給出 g_SkinDC 的 資訊uj5u.com熱心網友回復:
g_SkinDC=::CreateCompatibleDC(hSrcDC);然后selectobject 了一個bitmap bitmap是個圖片,里面有各種圖示,最大最小化按鈕tab頁等等。有普通樣式有mouseover樣式 click樣式等
uj5u.com熱心網友回復:
// 用 g_SkinDC, 來繪制 記憶體DC::StretchBlt(hDC,0,0,3,m_nHeight,g_SkinDC,0,47,3,1,SRCCOPY);
::StretchBlt(hDC,m_nWidth-3,0,3,m_nHeight,g_SkinDC,57,47,3,1,SRCCOPY);
這 2句 畫的 是 什么 ?
uj5u.com熱心網友回復:
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/85624.html
標籤:界面
上一篇:插入DATAGRID(下載)控制元件后無法打開對話框!
下一篇:復選框單擊事件的回應問題?
