1. 專案加入 memdc.h
from Here
2. 在 stdafx.h加入下一行
#include "memdc.h"
3. 修改訊息 WM_ERASEBKGND的回應 如下:
BOOL CExampleView::OnEraseBkgnd(CDC* pDC) { return FALSE; }
4.修改OnDrae的程式碼,如下
void CExampleView::OnDraw(CDC* dc) { CMemDC pDC(dc); CExampleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here - use pDC //as the device context to draw to }
星期日, 11月 27, 2011
[MFC] 繪圖時去除閃爍
星期二, 12月 14, 2010
[MFC] CImage 直接存取記憶體
//for 8-bit 影像
byte* pRealData=(byte*)m_Image.GetBits(); //取得記憶體開頭
int pit=m_Image.GetPitch(); //每一行的記憶體寬度
for (int y=0; y< Height;y++){
for (int x=0; x< Width;x++){
pRealData[ pit*y + x] = Intensity;
}}
//for 24-bit 影像
byte* pRealData=(byte*)SaveImg.GetBits();
int pit=SaveImg.GetPitch();
int bitCount=3;
for (int y=0; y< height; y++) {
for (int x=0; x< width; x++) {
pRealData [ pit*y + x*bitCount] = R ;
pRealData [ pit*y + x*bitCount+1] = G ;
pRealData [ pit*y + x*bitCount+2] = B;
}}
byte* pRealData=(byte*)m_Image.GetBits(); //取得記憶體開頭
int pit=m_Image.GetPitch(); //每一行的記憶體寬度
for (int y=0; y< Height;y++){
for (int x=0; x< Width;x++){
pRealData[ pit*y + x] = Intensity;
}}
//for 24-bit 影像
byte* pRealData=(byte*)SaveImg.GetBits();
int pit=SaveImg.GetPitch();
int bitCount=3;
for (int y=0; y< height; y++) {
for (int x=0; x< width; x++) {
pRealData [ pit*y + x*bitCount] = R ;
pRealData [ pit*y + x*bitCount+1] = G ;
pRealData [ pit*y + x*bitCount+2] = B;
}}
星期一, 11月 29, 2010
[MFC] Multithread
//Thread function 內容
UINT MyThreadFun(LPVOID LParam)
{
MyThreadInfo *pInfo1=(MyThreadInfo*) LParam;
CTESTDlg *hWnd=(CTESTDlg*)CWnd::FromHandle(pInfo1->Wnd);
CSliderCtrl *slider=(CSliderCtrl*)hWnd->GetDlgItem(IDC_SLIDER1);
slider->SetLineSize(100); // 設定 slider 大小
for(int i=0;i<100;i++){
slider->SetPos(i); // 移動 slider
Sleep(100); // 暫停 thread
}
return(0);
}
//Dialog按鈕程式碼
//開始 Tread
struct MyThreadInfo{
HWND hWnd; // 紀錄產生 thread 的視窗物件
}Info1;
void CTESTDlg::OnBnClickedOk()
{
Info1.hWnd=this->m_hWnd; // 紀錄 Dialog 的window handle
AfxBeginThread(MyThreadFun, (LPVOID)&Info1);
}
UINT MyThreadFun(LPVOID LParam)
{
MyThreadInfo *pInfo1=(MyThreadInfo*) LParam;
CTESTDlg *hWnd=(CTESTDlg*)CWnd::FromHandle(pInfo1->Wnd);
CSliderCtrl *slider=(CSliderCtrl*)hWnd->GetDlgItem(IDC_SLIDER1);
slider->SetLineSize(100); // 設定 slider 大小
for(int i=0;i<100;i++){
slider->SetPos(i); // 移動 slider
Sleep(100); // 暫停 thread
}
return(0);
}
//如果希望 thread function 能放在 class 中, 請宣告它為 static
class CTESTDlg : public CDialog {
static UINT MyThreadFun(LPVOID LParam);
};
///////////////////////////////////////////////////////////////
//Dialog按鈕程式碼
//開始 Tread
struct MyThreadInfo{
HWND hWnd; // 紀錄產生 thread 的視窗物件
}Info1;
void CTESTDlg::OnBnClickedOk()
{
Info1.hWnd=this->m_hWnd; // 紀錄 Dialog 的window handle
AfxBeginThread(MyThreadFun, (LPVOID)&Info1);
}
星期二, 11月 16, 2010
[MFC] Unicode環境下使用CStdioFile來存取中文檔案
因為CStdioFile並不支援Unicode所以無法存取Uncode檔案,而當存取ANSI檔案時又因為Unicode環境下而造成無法使用CStdioFile::ReadString()所讀到的CString。所以加入下面一行程式碼來設定讀入的檔案的地區編碼。
Windows环境下Unicode编程总结和将ANSI转换到Unicode 将Unicode转换到ANSI
setlocale( LC_CTYPE,"cht" );
如果是簡體中文則將cht改為chs。
其他參考文章:解决UNICODE字符集下CStdioFile的Writestring无法写入中文的问题
Windows环境下Unicode编程总结和将ANSI转换到Unicode 将Unicode转换到ANSI
[MFC] CImage的簡單複製方法 (Copy CImage)
BOOL ImageCopy(const CImage &srcImage, CImage &destImage) { int i,j;//循環變量 if(srcImage.IsNull()) return FALSE; //原始影像參數 BYTE* srcPtr=(BYTE*)srcImage.GetBits(); int srcBitsCount=srcImage.GetBPP(); int srcWidth=srcImage.GetWidth(); int srcHeight=srcImage.GetHeight(); int srcPitch=srcImage.GetPitch(); //銷毀原有圖像 if( !destImage.IsNull()) { destImage.Destroy(); } //創建新圖像 if(srcBitsCount==32) //支援alpha通道 { destImage.Create(srcWidth,srcHeight,srcBitsCount,1); } else { destImage.Create(srcWidth,srcHeight,srcBitsCount,0); } //加載調色板 if(srcBitsCount<=8&&srcImage.IsIndexed())//需要調色盤 { RGBQUAD pal[256]; int nColors=srcImage.GetMaxColorTableEntries(); if(nColors>0) { srcImage.GetColorTable(0,nColors,pal); destImage.SetColorTable(0,nColors,pal);//複製調色盤 } } //目標影像參數 BYTE *destPtr=(BYTE*)destImage.GetBits(); int destPitch=destImage.GetPitch(); //複製影像數據 for(i=0 ; i<srcHeight;i++) { memcpy( destPtr+i*destPitch, srcPtr+i*srcPitch, abs(srcPitch) ); } return TRUE; }
星期日, 1月 04, 2009
[MFC] CSrollView的 ScrollBar
1 OnInitialUpdate()函式裡的sizeTotal.cx=sizeTotal.cy 值要設定
2. CSize sizeTotal(Getx(),Gety());
SetScrollSizes(MM_TEXT, sizeTotal);
2. CSize sizeTotal(Getx(),Gety());
SetScrollSizes(MM_TEXT, sizeTotal);
星期六, 1月 03, 2009
[MFC] 全螢幕功能-開始工作列未消失
原因是OnGetMinMaxInfo這個函式沒有被OverRide,
,最好是用ClassWizard,不要用手動。因為很可能會沒有效果。
要重寫此函式的原因如下:
程序中有一個地方要說明一下,那就是OnGetMinMaxInfo函數的作用。你可以試一下,如果把這個函數去掉,則當你按下工具欄中的全屏顯示按鈕時,框架視圖確實變大了,但沒有想像的那樣實現全屏顯示,底邊留下一個狀態欄——一個有些發育不良的全屏顯示窗口。為什麼會這樣呢?經過調試後,發現問題出在WM_GETMINMAXINFO消息的處理上。在Windows中,無論什麼時候以何種方式改變窗口的尺寸或大小,是拖拽窗口邊緣也好,或是在代碼中調用改變窗口尺寸的函數也好,總之不管你用什麼方法,Windows都會首先發送WM_GETMINMAXINFO消息。這個消息的意思是說:「嘿,如果你要強迫我的尺寸變大或變小,就附上詳細的MINMAXINFO結構信息,否則我用默認值處理。」大多數應用程序都不用顯式處理這個 WM_GETMINMAXINFO消息(也就是說讓DefWindowProc窗口過程進行缺省處理),而Windows在進行缺省處理時是不會讓一個窗口視圖比屏幕還大的,所以我們會碰上前面講的那個問題。解決的方法是:不要讓Windows對WM_GETMINMAXINFO消息進行缺省處理,而是由我們自己處理,方法如下:
,最好是用ClassWizard,不要用手動。因為很可能會沒有效果。
要重寫此函式的原因如下:
程序中有一個地方要說明一下,那就是OnGetMinMaxInfo函數的作用。你可以試一下,如果把這個函數去掉,則當你按下工具欄中的全屏顯示按鈕時,框架視圖確實變大了,但沒有想像的那樣實現全屏顯示,底邊留下一個狀態欄——一個有些發育不良的全屏顯示窗口。為什麼會這樣呢?經過調試後,發現問題出在WM_GETMINMAXINFO消息的處理上。在Windows中,無論什麼時候以何種方式改變窗口的尺寸或大小,是拖拽窗口邊緣也好,或是在代碼中調用改變窗口尺寸的函數也好,總之不管你用什麼方法,Windows都會首先發送WM_GETMINMAXINFO消息。這個消息的意思是說:「嘿,如果你要強迫我的尺寸變大或變小,就附上詳細的MINMAXINFO結構信息,否則我用默認值處理。」大多數應用程序都不用顯式處理這個 WM_GETMINMAXINFO消息(也就是說讓DefWindowProc窗口過程進行缺省處理),而Windows在進行缺省處理時是不會讓一個窗口視圖比屏幕還大的,所以我們會碰上前面講的那個問題。解決的方法是:不要讓Windows對WM_GETMINMAXINFO消息進行缺省處理,而是由我們自己處理,方法如下:
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { if (m_bFullScreen) { lpMMI->ptMaxSize.y = m_FullScreenWindowRect.Height(); lpMMI->ptMaxTrackSize.y = lpMMI->ptMaxSize.y; lpMMI->ptMaxSize.x = m_FullScreenWindowRect.Width(); lpMMI->ptMaxTrackSize.x = lpMMI->ptMaxSize.x; } //CFrameWnd::OnGetMinMaxInfo(lpMMI); }
星期三, 5月 07, 2008
[MFC] 攔截 ESC 鍵 或是其他鍵盤指令
基於Cdialog類別所寫出的視窗類別,預設當使用者按下Enter或Esc鍵時,會關閉視窗程式。如果要關閉此功能,需重載PreTranslateMessage函式。改寫如下:
BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->message==WM_KEYDOWN) { switch(pMsg->wParam) { case VK_RETURN: case VK_ESCAPE: return TRUE; break; default: break; } } return CDialog::PreTranslateMessage(pMsg); }
星期三, 4月 09, 2008
[MFC] GDI+ 使用
在 stdafx.h中加入下列code
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include "include\gdiplus.h"
using namespace Gdiplus;
星期一, 1月 28, 2008
[MFC] 一次Double Click 所包含的滑鼠訊息到底是哪些?
根據實驗所得,一次Doulbe Click包含 一次Down、一次Double Click以及兩次Up訊息。
利用Spy++得到的結果也是一樣。順序是"Down -> Up -> Double Click -> Up" 。
經過實際測試程式後,發現應該是Windows根據滑鼠第二次Click跟上一次Click的位置有無相同與時間有無接近來決定發出哪一個訊息,如果都兩個條件都成立則第二次Click就不會發出Button Down訊息,而改發DoubleClick訊息,但Button Up訊息則不受影響。所以說,如果視窗接收到Double Click訊息,就表示前面一定已經發出一個Button Down訊息。
利用Spy++得到的結果也是一樣。順序是"Down -> Up -> Double Click -> Up" 。
經過實際測試程式後,發現應該是Windows根據滑鼠第二次Click跟上一次Click的位置有無相同與時間有無接近來決定發出哪一個訊息,如果都兩個條件都成立則第二次Click就不會發出Button Down訊息,而改發DoubleClick訊息,但Button Up訊息則不受影響。所以說,如果視窗接收到Double Click訊息,就表示前面一定已經發出一個Button Down訊息。
星期三, 7月 18, 2007
[MFC] Disable 關閉按鈕
有三種方法
1. 重載 CMainFrame::PreTranslateMessage 如下
缺點:按鈕還是顯示Enable
優點:可屏蔽雙擊標題列
(m_pMainWnd->GetSystemMenu(FALSE))->RemoveMenu(SC_CLOSE,MF_BYCOMMAND);
優點:簡單, 標題列按鈕會顯示Disable
缺點: 只能屏蔽系統選單及標題列
3.::SetClassLong(m_pMainWnd->GetSafeHwnd(),GCL_STYLE,::GetClassLong(m_pMainWnd->GetSafeHwnd(),GCL_STYLE) |CS_NOCLOSE);
優點:簡單, 標題列按鈕會顯示Disable
缺點:系統選單不會消失
1. 重載 CMainFrame::PreTranslateMessage 如下
缺點:按鈕還是顯示Enable
優點:可屏蔽雙擊標題列
2.加在初始化函式
if(pMsg->hwnd == this->m_hWnd )
{
if (pMsg->message == WM_SYSCOMMAND)
{
if (pMsg->wParam == SC_MINIMIZE)
return true;
if (pMsg->wParam == SC_CLOSE)
return true;
}
if (pMsg->message == WM_NCLBUTTONDBLCLK)
return true;
if (pMsg->message == WM_NCLBUTTONDOWN)
{
if (pMsg->wParam == HTMINBUTTON)
return true;
if (pMsg->wParam == HTSIZE)
return true;
if (pMsg->wParam == HTCLOSE)
return true;
}
}
(m_pMainWnd->GetSystemMenu(FALSE))->RemoveMenu(SC_CLOSE,MF_BYCOMMAND);
優點:簡單, 標題列按鈕會顯示Disable
缺點: 只能屏蔽系統選單及標題列
3.::SetClassLong(m_pMainWnd->GetSafeHwnd(),GCL_STYLE,::GetClassLong(m_pMainWnd->GetSafeHwnd(),GCL_STYLE) |CS_NOCLOSE);
優點:簡單, 標題列按鈕會顯示Disable
缺點:系統選單不會消失
星期一, 7月 16, 2007
星期五, 6月 15, 2007
[MFC] Image/ Color Bottons 連結整理
要讓一個程式好看又好用,有時漂亮的按鈕不可少。以下為從兩個國外有名的VC程式站抓來的相關連結。因為實在懶得再一個一個去找了。
1. Colored buttons
2. Enhanced Colored Button
3. ImageTextButton
4. Colored Buttons
5. Image Button Control
6. Transparant Image Button (BMP, GIF, JPG...)
1. Colored buttons
2. Enhanced Colored Button
3. ImageTextButton
4. Colored Buttons
5. Image Button Control
6. Transparant Image Button (BMP, GIF, JPG...)
星期四, 5月 24, 2007
[MFC] 抓取全螢幕 存成 BMP
//***********************************************************// //抓取全螢幕 存成 BMP CDC dc; dc.CreateDC("DISPLAY",NULL,NULL,NULL); CBitmap bm; int Width=GetSystemMetrics(SM_CXSCREEN);//螢幕寬 int Height=GetSystemMetrics(SM_CYSCREEN);//螢幕高 bm.CreateCompatibleBitmap(&dc,Width,Height); CDC tdc; tdc.CreateCompatibleDC(&dc); CBitmap*pOld=tdc.SelectObject(&bm); tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY); tdc.SelectObject(pOld); BITMAP btm; bm.GetBitmap(&btm); DWORD size=btm.bmWidthBytes*btm.bmHeight; LPSTR lpData=(LPSTR)GlobalAlloc(GPTR,size); BITMAPINFOHEADER bih; bih.biBitCount=btm.bmBitsPixel; bih.biClrImportant=0; bih.biClrUsed=0; bih.biCompression=0; bih.biHeight=btm.bmHeight; bih.biPlanes=1; bih.biSize=sizeof(BITMAPINFOHEADER); bih.biSizeImage=size; bih.biWidth=btm.bmWidth; bih.biXPelsPerMeter=0; bih.biYPelsPerMeter=0; GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS); static int filecount=0; CString name; name.Format("pict%04d.bmp",filecount++); name="C:\\IDP3\\"+name; BITMAPFILEHEADER bfh; bfh.bfReserved1=bfh.bfReserved2=0; bfh.bfType=((WORD)('M'<< 8)|'B'); bfh.bfSize=54+size; bfh.bfOffBits=54; CFile bf; if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)) { bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER)); bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER)); bf.WriteHuge(lpData,size); bf.Close(); nCount++; } //GlobalFreePtr(lpData); GlobalFree((HGLOBAL)lpData); UpdateData(FALSE);
訂閱:
文章 (Atom)