① 推薦本C++或者VC++的編程實例教程給我
Windows API for 2000/XP實例精解
Visual C++的使用及面向對象軟體工程實例分析
Visual C++實效編程百例
Visual C++編程技巧精選500例
② 如何用VC++編C窗口程序
你要的win32窗口程序嗎?
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
); //窗口過程函數聲明
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
//設計一個窗口類
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=CreateSolidBrush(RGB(12,172,59));//畫刷
wndcls.hCursor=NULL;
wndcls.hIcon=NULL;
wndcls.hInstance=hInstance; //應用程序實例句柄由WinMain函數傳進來
wndcls.lpfnWndProc=WinSunProc; //定義窗口處理函數
wndcls.lpszClassName="windowclass";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
//創建窗口,定義一個變數用來保存成功創建窗口後返回的句柄
HWND hwnd;
hwnd=CreateWindow("windowclass","first window",
WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);
//顯示及刷新窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//定義消息結構體,開始消息循環
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//編寫窗口過程函數
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CLOSE:
DestroyWindow(hwnd); //銷毀窗口,並發送WM_DESTROY消息給自身窗口
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
③ 求用vc++編程實現顯示灰度直方圖的詳細步驟,越詳細越好
步驟和程序:
打開VC程序——文件——新建——工程中的MFC AppWizard(exe),在工程下面的框中輸入工程名(假定工程名為111),點確定——選多重文檔,點下一個——後面都點下一個直到完成確定,基本框架就完成了,下面就加代碼。
這時VC界面上左邊框的下面有三個按鈕:ClassView、ResourceView和FileView,ClassView裡面是工程111的類:CAdoutDlg、CChildFrame、CMy111App、CMy111Doc、CMy111View和Globals;點ResourceView裡面是資源類:Accelerator、Dialog、Icon、Menu、String Table、Toolbar和Version;點開FileView裡面是文件類:Source File、Header Files、Resource Files和ReadMe.txt。
點界面的「工程」按鈕——添加工程——新建——選C++ Source File,在文件下面的框里輸入文件名(如DIBAPI),點「結束」,這樣在FileView中的Source Files裡面就多了一個DIBAPI.cpp文件,所有的代碼都加在該文件中。再點界面的「工程」按鈕——添加工程——新建——選C/C++ Header File,在文件下面的框里輸入文件名(和前面的文件名必須一致),點「結束」,這樣在FileView中的Header Files裡面就多了一個DIBAPI.h文件,該文件是DIBAPI.cpp的頭文件。
點開DIBAPI.h文件,裡面是空白的,把如下代碼考入文件中:
//DIBAPI.h
#ifndef _INC_DIBAPI
#define _INC_DIBAPI
DECLARE_HANDLE(HDIB);
#define PALVERSION 0x300
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi))==sizeof(BITMAPINFOHEADER))
#define RECTWIDTH(lpRect) ((lpRect)->right-(lpRect)->left)
#define RECTHEIGHT(lpRect) ((lpRect)->bottom-(lpRect)->top)
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define DIB_HEADER_MARKER ((WORD)('M'<<8)|'B')
BOOL WINAPI PaintDIB(HDC,LPRECT,HDIB,LPRECT,CPalette* pPal);
BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette* cPal);
LPSTR WINAPI FindDIBBits(LPSTR lpbi);
DWORD WINAPI DIBWidth(LPSTR lpDIB);
DWORD WINAPI DIBHeight(LPSTR lpDIB);
WORD WINAPI PaletteSize(LPSTR lpbi);
WORD WINAPI DIBNumColors(LPSTR lpbi);
HGLOBAL WINAPI CopyHandle(HGLOBAL h);
BOOL WINAPI SaveDIB(HDIB hDib,CFile& file);
HDIB WINAPI ReadDIBFile(CFile& file);
//在此處輸入自己的函數聲明
#endif//!_INC_DIBAPI
上面這些函數是實現圖像的讀取、存儲等圖像處理的基本功能的,你將自己需要的函數也輸入到「//在此處輸入自己的函數聲明」的下面。
點開DIBAPI.cpp文件,裡面是空白的,將如下代碼加入其中:
//DIBAPI.cpp
#include "stdafx.h"
#include "DIBAPI.h"
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
if(IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if(dwClrUsed)
return (WORD)dwClrUsed;
}
if(IS_WIN30_DIB(lpbi))
wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
else
wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
WORD WINAPI PaletteSize(LPSTR lpbi)
{
if(IS_WIN30_DIB(lpbi))
return (WORD)(DIBNumColors(lpbi)*sizeof(RGBQUAD));
else
return (WORD)(DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
}
LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
return (lpbi+*(LPDWORD)lpbi+::PaletteSize(lpbi));
}
DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
return lpbmi->biWidth;
else
return (DWORD)lpbmc->bcWidth;
}
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
return lpbmi->biHeight;
else
return (DWORD)lpbmc->bcHeight;
}
BOOL WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette* pPal)
{
LPSTR lpDIBHdr;
LPSTR lpDIBBits;
BOOL bSuccess=FALSE;
HPALETTE hPal=NULL;
HPALETTE hOldPal=NULL;
if(hDIB==NULL)
return FALSE;
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpDIBBits=FindDIBBits(lpDIBHdr);
if(pPal!=NULL)
{
hPal=(HPALETTE)pPal->m_hObject;
hOldPal=::SelectPalette(hDC,hPal,TRUE);
}
::SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
{
bSuccess=::SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->left,\
(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),0,(WORD)DIBHeight(lpDIBHdr),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
}
else
{
bSuccess=::StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->left,\
lpDIBRect->top,RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
}
::GlobalUnlock((HGLOBAL)hDIB);
if(hOldPal)
::SelectPalette(hDC,hOldPal,TRUE);
GlobalUnlock(hDIB);
return bSuccess;
}
BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette* pPal)
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal=NULL;
LPSTR lpbi;
LPBITMAPINFO lpbmi;
LPBITMAPCOREINFO lpbmc;
BOOL bWinStyleDIB;
int i;
WORD wNumColors;
BOOL bResult=FALSE;
if(hDIB==NULL)
return FALSE;
lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
wNumColors=DIBNumColors(lpbi);
bWinStyleDIB=IS_WIN30_DIB(lpbi);
if(wNumColors!=0)
{
hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(hLogPal==0)
{
::GlobalUnlock((HGLOBAL)hDIB);
return FALSE;
}
lpPal=(LPLOGPALETTE)::GlobalLock(hLogPal);
lpPal->palVersion=PALVERSION;
lpPal->palNumEntries=(WORD)wNumColors;
bWinStyleDIB=IS_WIN30_DIB(lpbi);
for(i=0;i<(int)wNumColors;i++)
{
if(bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags=0;
}
else
{
lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags=0;
}
}
bResult=pPal->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL)hLogPal);
::GlobalFree((HGLOBAL)hLogPal);
}
::GlobalUnlock((HGLOBAL)hDIB);
return bResult;
}
HGLOBAL WINAPI CopyHandle(HGLOBAL h)
{
if(h==NULL)
return NULL;
DWORD dwLen=::GlobalSize((HGLOBAL)h);
HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);
if(hCopy!=NULL)
{
void* lpCopy=::GlobalLock((HGLOBAL)hCopy);
void* lp=::GlobalLock((HGLOBAL)h);
memcpy(lpCopy,lp,dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
BOOL WINAPI SaveDIB(HDIB hDib,CFile& file)
{
BITMAPFILEHEADER bmfHdr;
LPBITMAPINFOHEADER lpBI;
DWORD dwDIBSize;
if(!hDib)
return FALSE;
lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
if(lpBI==NULL)
return FALSE;
if(!IS_WIN30_DIB(lpBI))
{
::GlobalUnlock((HGLOBAL)hDib);
return FALSE;
}
bmfHdr.bfType=DIB_HEADER_MARKER;
dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);
if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
dwDIBSize+=lpBI->biSizeImage;
else
{
DWORD dwBmBitsSize;
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;
dwDIBSize+=dwBmBitsSize;
lpBI->biSizeImage=dwBmBitsSize;
}
bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize+::PaletteSize((LPSTR)lpBI);
TRY
{
file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
file.WriteHuge(lpBI,dwDIBSize);
}
CATCH(CFileException,e)
{
::GlobalUnlock((HGLOBAL)hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL)hDib);
return TRUE;
}
HDIB WINAPI ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
dwBitsSize=file.GetLength();
if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
return NULL;
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
return NULL;
hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
if(hDIB==0)
return NULL;
pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
{
::GlobalUnlock((HGLOBAL)hDIB);
::GlobalFree((HGLOBAL)hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL)hDIB);
return hDIB;
}
//在此處輸入自己的函數定義
上面是DIBAPI.h頭文件中聲明的函數的定義,你將自己的函數定義加到「//在此處輸入自己的函數定義」後面。
下面加相應的消息映射函數,點Ctrl+W鍵,會出現MFC ClassWizard對話框,點Message Maps,在Class name下面的框中選擇CMy111Doc,在Messages裡面選中OnOpenDocument,然後點擊Add Function按鈕就加入了相應的消息映射函數,同樣的方法以此加入OnSaveDocument、DeleteContents、CanCloseFrame相應的消息函數,點「確定」即可。
點開111Doc.cpp文件,裡面有相應的消息映射函數定義位置,在函數CMy111Doc::CMy111Doc()里輸入以下代碼:
m_refColorBKG=0x00808080;
m_hDIB=NULL;
m_palDIB=NULL;
m_sizeDoc=CSize(1,1);
在函數CMy111Doc::~CMy111Doc()里輸入以下代碼:
if(m_hDIB!=NULL)
::GlobalFree((HGLOBAL)m_hDIB);
if(m_palDIB!=NULL)
delete m_palDIB;
在函數BOOL CMy111Doc::OnOpenDocument(LPCTSTR lpszPathName)里/ TODO: Add your specialized creation code here下面添加如下代碼:
CFile file;
CFileException fe;
if(!file.Open(lpszPathName,CFile::modeRead|CFile::shareDenyWrite,&fe))
{
ReportSaveLoadException(lpszPathName,&fe,FALSE,AFX_IDP_FAILED_TO_OPEN_DOC);
return FALSE;
}
DeleteContents();
BeginWaitCursor();
TRY
{
m_hDIB=::ReadDIBFile(file);
}
CATCH(CFileException,eLoad)
{
file.Abort();
EndWaitCursor();
ReportSaveLoadException(lpszPathName,eLoad,FALSE,AFX_IDP_FAILED_TO_OPEN_DOC);
m_hDIB=NULL;
return FALSE;
}
END_CATCH
InitDIBData();
EndWaitCursor();
if(m_hDIB==NULL)
{
CString strMsg;
strMsg="讀取圖像時出錯!可能是不支持該類型的圖像文件!";
MessageBox(NULL,strMsg,NULL,MB_ICONINFORMATION|MB_OK);
return FALSE;
}
SetPathName(lpszPathName);
SetModifiedFlag(FALSE);
在函數BOOL CMy111Doc::OnSaveDocument(LPCTSTR lpszPathName)里// TODO: Add your specialized code here and/or call the base class後面添加如下代碼:
CFile file;
CFileException fe;
if(!file.Open(lpszPathName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareExclusive,&fe))
{
ReportSaveLoadException(lpszPathName,&fe,TRUE,AFX_IDP_INVALID_FILENAME);
return FALSE;
}
BOOL bSuccess=FALSE;
TRY
{
BeginWaitCursor();
bSuccess=::SaveDIB(m_hDIB,file);
file.Close();
}
CATCH(CException,eSave)
{
file.Abort();
EndWaitCursor();
ReportSaveLoadException(lpszPathName,eSave,TRUE,AFX_IDP_FAILED_TO_SAVE_DOC);
return FALSE;
}
END_CATCH
EndWaitCursor();
SetModifiedFlag(FALSE);
if(!bSuccess)
{
CString strMsg;
strMsg="無法保存BMP圖像";
MessageBox(NULL,strMsg,NULL,MB_ICONINFORMATION|MB_OK);
}
點開ClassView,右鍵點擊CMy111Doc類,點Add Member Variable出現添加成員變數對話框,在Variable Type下的框中輸入變數類型名HDIB,在Variable Name中輸入變數名m_hDIB,在Access中選中Public就在CMy111Doc中加入了公共成員變數m_hDIB;同樣加入int類型的m_nColorIndex、COLORREF類型的m_refColorBKG公共成員變數,再添加保護成員變數(在Access中選中Protected)CSize類的m_sizeDoc、CPalette*類的m_palDIB變數。右鍵點擊CMy111Doc類,點Add Member Function出現添加成員函數對話框,在Function Type下的框中輸入函數類型名void,在Function Declaration中輸入函數名InitDIBData(),在Access中選中Public就在CMy111Doc中加入了公共成員函數InitDIBData();同樣方法加入void類型的公共成員函數ReplaceHDIB(HDIB hDIB)。在111Doc.cpp中加入函數的代碼,InitDIBData()里加如下代碼:
if(m_palDIB!=NULL)
{
delete m_palDIB;
m_palDIB=NULL;
}
if(m_hDIB==NULL)
return;
LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
if(::DIBWidth(lpDIB)>INT_MAX||::DIBHeight(lpDIB)>INT_MAX)
{
::GlobalUnlock((HGLOBAL)m_hDIB);
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=NULL;
CString strMsg;
strMsg="BMP圖像太大!";
MessageBox(NULL,strMsg,NULL,MB_ICONINFORMATION|MB_OK);
return;
}
m_sizeDoc=CSize((int)::DIBWidth(lpDIB),(int)::DIBHeight(lpDIB));
::GlobalUnlock((HGLOBAL)m_hDIB);
m_palDIB=new CPalette;
if(m_palDIB==NULL)
{
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=NULL;
return;
}
if(::CreateDIBPalette(m_hDIB,m_palDIB)==NULL)
{
delete m_palDIB;
m_palDIB=NULL;
return;
}
在函數ReplaceHDIB(HDIB hDIB)中加入如下代碼:
if(m_hDIB!=NULL)
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=hDIB;
在CMy111doc.h的
// Attributes
public:
下面加入如下代碼:
HDIB GetHDIB() const
{
return m_hDIB;
}
CPalette* GetDocPalette() const
{
return m_palDIB;
}
CSize GetDocSize() const
{
return m_sizeDoc;
}
注意要在111Doc.h前加上#include "DIBAPI.h"語句(在class CMy111Doc:public CDocument語句前)
下面為CMy111View中的函數 void CMy111View::OnDraw(CDC* pDC)中添加如下代碼:
BeginWaitCursor();
CMy111* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
HDIB hDIB=pDoc->GetHDIB();
if(hDIB!=NULL)
{
LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
int cxDIB=(int)::DIBWidth(lpDIB);
int cyDIB=(int)::DIBHeight(lpDIB);
::GlobalUnlock((HGLOBAL)hDIB);
CRect rcDIB;
rcDIB.top=rcDIB.left=0;
rcDIB.right=cxDIB;
rcDIB.bottom=cyDIB;
CRect rcDest;
if(pDC->IsPrinting())
{
int cxPage=pDC->GetDeviceCaps(HORZRES);
int cyPage=pDC->GetDeviceCaps(VERTRES);
int cxInch=pDC->GetDeviceCaps(LOGPIXELSX);
int cyInch=pDC->GetDeviceCaps(LOGPIXELSY);
rcDest.top=rcDest.left=0;
rcDest.bottom=(int)(((double)cyDIB*cxPage*cyInch)/((double)cxDIB*cxInch));
rcDest.right=cxPage;
int temp=cyPage-(rcDest.bottom-rcDest.top);
rcDest.bottom+=temp/2;
rcDest.top+=temp/2;
}
else
{
rcDest=rcDIB;
}
::PaintDIB(pDC->m_hDC,&rcDest,pDoc->GetHDIB(),&rcDIB,pDoc->GetDocPalette());
}
EndWaitCursor();
以上是關於圖像打開、顯示、保存的有關步驟和代碼。
在111.cpp文件的InitInstance()函數的ParseCommandLine(cmdInfo);語句下輸入語句
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
則啟動時不自動打開一個空文檔。
顯示圖像直方圖步驟:
1、 點擊ResourceView,右鍵點擊Dialog,選Insert Dialog 在屬性對話框中將ID改為ID_HIST,對話框名稱改為「直方圖」
2、 在工具欄中點「插入」-「新建類」,輸入類名,並選Base Class為CDialog,Dialog ID為ID_HIST。這樣就將對話框和類聯系起來了,在該對話框中拖入一Edit控制項,將其ID設為IDC_HISTSHOW;
3、 快捷鍵「Ctrl+W」,出現MFC ClassWizard對話框,在Messages欄中分別選WM_INITDIALOG和WM_Paint,再點擊「Add Function」,即將對話框初始化和畫圖函數加入對話框類之中。
4、 在Hist.h文件「public:」下面輸入如下變數定義:
LONG m_lCount[256];
char* m_lpDIBBits;
LONG m_lWidth;
LONG m_lHeight;
int m_iIsDraging;
CDlgIntensity(CWnd* pParent = NULL);
5、 打開Hist.cpp程序,在CHist::OnInitDialog()函數中「// TODO: Add extra initialization here」前將如下代碼拷貝進去:
unsigned char* lpSrc;
LONG i;
LONG j;
6、 在「// TODO: Add extra initialization here」後將如下代碼拷貝進去:
CWnd* pWnd=GetDlgItem(IDC_HISTSHOW);
CRect rect;
GetClientRect(rect);
ClientToScreen(&rect);
for(i=0;i<256;i++)
{
m_lCount[i]=0;
}
LONG lLineBytes;
lLineBytes=WIDTHBYTES(m_lWidth*8);
for(i=0;i<m_lHeight;i++)
{
for(j=0;j<m_lWidth;j++)
{
lpSrc=(unsigned char*)m_lpDIBBits+lLineBytes*i+j;
m_lCount[*(lpSrc)]++;
}
}
m_iIsDraging=0;
7、在CHist::OnPaint()函數「CPaintDC dc(this);」前將如下代碼拷如其中:
CString str;
LONG i;
LONG lMaxCount=0;
LONG m_iLowGray=0;
LONG m_iUpGray=255;
在CHist::OnPaint()函數「// TODO: Add your message handler code here」後將如下代碼拷如其中:
CWnd* pWnd=GetDlgItem(IDC_ HISTSHOW);
CDC* pDC=pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
pDC->Rectangle(0,0,330,300);
CPen* pPenRed=new CPen;
pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
CPen* pPenBlue=new CPen;
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0,255));
CPen* pPenGreen=new CPen;
pPenGreen->CreatePen(PS_SOLID,1,RGB(0,255,0));
CGdiObject* pOldPen=pDC->SelectObject(pPenRed);
pDC->MoveTo(10,10);
pDC->LineTo(10,280);
pDC->LineTo(320,280);
str.Format("0");
pDC->TextOut(10,283,str);
str.Format("50");
pDC->TextOut(60,283,str);
str.Format("100");
pDC->TextOut(110,283,str);
str.Format("150");
pDC->TextOut(160,283,str);
str.Format("200");
pDC->TextOut(210,283,str);
str.Format("255");
pDC->TextOut(265,283,str);
for(i=0;i<256;i+=5)
{
if((i&1)==0)
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,284);
}
else
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,282);
}
}
pDC->MoveTo(315,275);
pDC->LineTo(320,280);
pDC->LineTo(315,285);
pDC->MoveTo(10,10);
pDC->LineTo(5,15);
pDC->MoveTo(10,10);
pDC->LineTo(15,15);
for(i=m_iLowGray;i<=m_iUpGray;i++)
{
if(m_lCount[i]>lMaxCount)
{
lMaxCount=m_lCount[i];
}
}
pDC->MoveTo(10,25);
pDC->LineTo(14,25);
str.Format("%d",lMaxCount);
pDC->TextOut(11,26,str);
pDC->SelectObject(pPenGreen);
pDC->MoveTo(m_iLowGray+10,25);
pDC->LineTo(m_iLowGray+10,280);
pDC->MoveTo(m_iUpGray+10,25);
pDC->LineTo(m_iUpGray+10,280);
pDC->SelectObject(pPenBlue);
if(lMaxCount>0)
{
for(i=m_iLowGray;i<=m_iUpGray;i++)
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,281-(int)(m_lCount[i]*256/lMaxCount));
}
}
pDC->SelectObject(pOldPen);
delete pPenRed;
delete pPenBlue;
delete pPenGreen;
8、點開ResourceView中的Menu,出現IDR_MAINFRAME和 IDR_MY111TYPE,雙擊IDR_MY111TYPE就出現了程序界面,有文件、編輯、查看、窗口、幫助按鈕。點「查看」下面的虛線框右鍵——點「屬性」,輸入標題(直方圖),和ID(大寫英文,如ID_VIEW_HIST),這樣就將按鈕和程序通過ID聯系起來了,點擊該按鈕,就會執行相應的程序。下面為該按鈕添加函數:點Ctrl+W ,出現MFC ClassWizard對話框,選Class name為CMy111View,在Object IDs對應的選項中選中設置的ID(如為ID_VIEW_HIST),在Messages選項中選中COMMAND,然後點擊「Add Function」按鈕,選默認設置,就為ID_VIEW_HIST添加了相應的函數OnViewHist()。該函數在111View.cpp文件中定義,在函數void CMy111View:: OnViewHist()添加如下代碼:
// TODO: Add your command handler code here
CMy111Doc* pDoc=GetDocument();
if(pDoc->m_hDIB==NULL)
{
MessageBox("請先打開一幅256色的BMP圖像!","系統提示",MB_ICONINFORMATION|MB_OK);
return;
}
LPSTR lpDIB;
LPSTR lpDIBBits;
lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
lpDIBBits=::FindDIBBits(lpDIB);
if(::DIBNumColors(lpDIB)!=256)
{
MessageBox("目前只支持查看256色點陣圖灰度直方圖!","系統提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
return;
}
BeginWaitCursor();
CHist dlgPara;
dlgPara.m_lpDIBBits=lpDIBBits;
dlgPara.m_lWidth=::DIBWidth(lpDIB);
dlgPara.m_lHeight=::DIBHeight(lpDIB);
// dlgPara.m_iLowGray=0;
// dlgPara.m_iUpGray=255;
if(dlgPara.DoModal()!=IDOK)
{
return;
}
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
EndWaitCursor();
④ vc 如何操作 excel2003(注意一定是2003) 編程
1.製作應用軟體的時候,經常要把結果以報表的形式輸出,當前使用較為廣泛的當然是Excel表格,本文簡略介紹在VC++6.0中如何使用Excel2003的庫函數並對其進行編程。先創建一個對話框工程,命名為VCExcel。在對話框中添加一個按鈕,控制項ID為2.ID_RUNEXCEL(是不是很搞笑哇,不過沒關系,它照樣能實現強大的功能)。
再在該按鈕上添加消息BN_CLICKED,其消息映射函數為OnRunexcel(),下面工作就是要完成這個OnRunexcel()函數。在這里我們通過一個實例來說明VC是如何調用Excel2003的介面編程的。
3.要編程輸出一個如下表格。
格式如下:
1)表頭的字體為宋體,加粗,顏色為白色,底色為深藍,垂直水平居中對齊;
2)表中正文內容字體為宋體,顏色為深藍,底色為灰色,垂直水平居中對齊;
3)全部邊框,文本自動換行。
在BOOL CVCExcelApp::InitInstance()之中,int nResponse = dlg.DoModal()語句之後加入如下代碼:
if(CoInitialize(NULL)==0)//初始化COM庫
{
AfxMessageBox("初始化COM失敗!");
exit(1);
}
在return FALSE;語句之前加入:::CoUninitialize();//釋放COM庫。
4.為了能調用Excel的介面我們打開MFC ClassWizard->Automation->Add Class->From a type library,選擇[Excel的安裝路徑]/EXCEL.exe,然後把所有的類都添加進去,頭文件為excel.h,源文件為excel.cpp。當然,你也可以只把一些比較常用的類如_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range加進去,因為網上流傳的絕大部分教程都只添加這幾個類,這完全根據個人的需要。至少還要用到Interior類(設置底色),Font類(設置字體),而且這樣做又簡單又方便擴展功能,不管三七二十一全部弄進去吧!但這樣做會有一個問題,有可能產生類的名字沖突,例如本來你自己寫了一個類叫Font,當你全部添加時又再次加入了Font類,這樣就重復定義了,不過可以通過名字空間來解決這個問題。再在VCExcelDlg.cpp文件的頭部添加(如果系統已經自動添加就不要重復添加了):
#include "VCExcel.h"
#include "comdef.h"
這樣一來程序就可以自由調用EXCEL了,一切准備就緒。
5.下面先在CVCExcelDlg中添加如下成員變數,用來操控Excel應用程序、工作簿和單元格。
Range m_ExlRge;
_Worksheet m_ExlSheet;
Worksheets m_ExlSheets;
_Workbook m_ExlBook;
Workbooks m_ExlBooks;
_Application m_ExlApp;
我們利用載入Excel模板來生成要求的表格,在本工程Debug文件夾中建立一個Excel文件,命名為Template.xls。我們的OnRunexcel()代碼如下(詳見注釋):
void CVCExcelDlg::OnRunexcel()
{
// TODO: Add your control notification handler code here
//用m_ExlApp對象創建Excel2003進程
if(!m_ExlApp.CreateDispatch("Excel.Application",NULL))
{
AfxMessageBox("創建Excel服務失敗!");
return;
}
//設置為可見
m_ExlApp.SetVisible(TRUE);
///////////////////下面得到應用程序所在的路徑///////////////////
CString theAppPath,theAppName;
char Path[MAX_PATH];
GetMoleFileName(NULL,Path,MAX_PATH);//得到應用程序的全路徑
theAppPath=(CString)Path;
theAppName=AfxGetApp()->m_pszAppName;
theAppName+=".exe";
//把最後的文件名去掉
int length1,length2;
length1=theAppPath.GetLength();
length2=theAppName.GetLength();
theAppPath.Delete(length1-length2,length2);
////////////////////////////////////////////////////////////////
CString TempPath="";
TempPath=theAppPath+"Template.xls";//EXCEL模板的路徑
m_ExlBooks.AttachDispatch(m_ExlApp.GetWorkbooks(),TRUE);
m_ExlBook.AttachDispatch(m_ExlBooks.Add((_variant_t)TempPath),TRUE);//載入EXCEL模板
m_ExlSheets.AttachDispatch(m_ExlBook.GetSheets(),TRUE);//載入Sheet頁面
//添加新的Sheet頁面
m_ExlSheets.Add(vtMissing,vtMissing,_variant_t((long)1),vtMissing);
//刪除第二個Sheet頁面
m_ExlSheet.AttachDispatch(m_ExlSheets.GetItem(_variant_t((long)2)),TRUE);
m_ExlSheet.Delete();
//把第一個Sheet頁面的名字改變為TestSheet
m_ExlSheet.AttachDispatch(m_ExlSheets.GetItem(_variant_t((long)1)),TRUE);
m_ExlSheet.SetName("TestSheet");
///////合並第一行單元格A1至D1//////
//載入要合並的單元格 m_ExlRge.AttachDispatch(m_ExlSheet.GetRange(_variant_t("A1"),_variant_t("D1")),TRUE);
m_ExlRge.Merge(_variant_t((long)0));
////////設置表格內容////////
m_ExlRge.AttachDispatch(m_ExlSheet.GetCells(),TRUE);//載入所有單元格
m_ExlRge.SetItem(_variant_t((long)1),_variant_t((long)1),_variant_t("數學系研究生課程統計"));
m_ExlRge.SetItem(_variant_t((long)2),_variant_t((long)1),_variant_t("課程名"));
m_ExlRge.SetItem(_variant_t((long)2),_variant_t((long)2),_variant_t("課時"));
m_ExlRge.SetItem(_variant_t((long)2),_variant_t((long)3),_variant_t("難度"));
m_ExlRge.SetItem(_variant_t((long)2),_variant_t((long)4),_variant_t("教學方式"));
m_ExlRge.SetItem(_variant_t((long)3),_variant_t((long)1),_variant_t("泛函分析"));
m_ExlRge.SetItem(_variant_t((long)3),_variant_t((long)2),_variant_t("60"));
m_ExlRge.SetItem(_variant_t((long)3),_variant_t((long)3),_variant_t("普通"));
m_ExlRge.SetItem(_variant_t((long)3),_variant_t((long)4),_variant_t("老師講課"));
m_ExlRge.SetItem(_variant_t((long)4),_variant_t((long)1),_variant_t("微分流形"));
m_ExlRge.SetItem(_variant_t((long)4),_variant_t((long)2),_variant_t("40"));
m_ExlRge.SetItem(_variant_t((long)4),_variant_t((long)3),_variant_t("變態難"));
m_ExlRge.SetItem(_variant_t((long)4),_variant_t((long)4),_variant_t("自學"));
m_ExlRge.SetItem(_variant_t((long)5),_variant_t((long)1),_variant_t("二階橢圓型方程與方程組"));
m_ExlRge.SetItem(_variant_t((long)5),_variant_t((long)2),_variant_t("60"));
m_ExlRge.SetItem(_variant_t((long)5),_variant_t((long)3),_variant_t("很難"));
m_ExlRge.SetItem(_variant_t((long)5),_variant_t((long)4),_variant_t("討論"));
m_ExlRge.AttachDispatch(m_ExlSheet.GetUsedRange());//載入已使用的單元格
m_ExlRge.SetWrapText(_variant_t((long)1));//設置單元格內的文本為自動換行
//設置齊方式為水平垂直居中
//水平對齊:默認=1,居中=-4108,左=-4131,右=-4152
//垂直對齊:默認=2,居中=-4108,左=-4160,右=-4107
m_ExlRge.SetHorizontalAlignment(_variant_t((long)-4108));
m_ExlRge.SetVerticalAlignment(_variant_t((long)-4108));
///////設置整體的字體、字型大小及顏色//////
Font ft;
ft.AttachDispatch(m_ExlRge.GetFont());
ft.SetName(_variant_t("宋體"));//字體
ft.SetColorIndex(_variant_t((long)11));//字的顏色
ft.SetSize(_variant_t((long)12));//字型大小
///////////設置標題字體及顏色////////// m_ExlRge.AttachDispatch(m_ExlSheet.GetRange(_variant_t("A1"),_variant_t("D1")));
ft.AttachDispatch(m_ExlRge.GetFont());
ft.SetBold(_variant_t((long)1));//粗體
ft.SetSize(_variant_t((long)13));
ft.SetColorIndex(_variant_t((long)2));
CellFormat cf;
cf.AttachDispatch(m_ExlRge.GetCells());
//////////////設置底色/////////////////
Interior it;
it.AttachDispatch(m_ExlRge.GetInterior());
it.SetColorIndex(_variant_t((long)11));//標題底色
////表格內容的底色//// m_ExlRge.AttachDispatch(m_ExlSheet.GetRange(_variant_t("A2"),_variant_t("D5")));
it.AttachDispatch(m_ExlRge.GetInterior());
it.SetColorIndex(_variant_t((long)15));
//////////////為表格設置邊框/////////////
Range UnitRge;
CString CellName;
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
CellName.Format("%c%d",j+64,i);//單元格的名稱 UnitRge.AttachDispatch(m_ExlRge.GetRange(_variant_t(CellName),_variant_t(CellName)));//載入單元格
//LineStyle=線型 Weight=線寬 ColorIndex=線的顏色(-4105為自動) UnitRge.BorderAround(_variant_t((long)1),_variant_t((long)2),_variant_t((long)-4105),vtMissing);//設置邊框
}
}
//釋放對象(相當重要!)
m_ExlRge.ReleaseDispatch();
m_ExlSheet.ReleaseDispatch();
m_ExlSheets.ReleaseDispatch();
m_ExlBook.ReleaseDispatch();
m_ExlBooks.ReleaseDispatch();
//m_ExlApp一定要釋放,否則程序結束後還會有一個Excel進程駐留在內存中,而且程序重復運行的時候會出錯
m_ExlApp.ReleaseDispatch();
//退出程序 m_ExlApp.Quit();
}
⑤ vc++6.0操作方法
VC++6.0上機操作指南
貴州大學計算機科學與技術學院
張志明
2006年9月
目錄
1. Visual C++ 控制台應用程序上機實現步驟
2. MFC對話框應用程序實現舉例
3. MFC單文檔應用程序實現舉例
4. 用32位調試程序了解類和對象的內存映象
1. Visual C++控制台應用程序(Win32 Console Application Project)
上機實現步驟
一. 單文件程序的實現
本教材中的程序在Visual C++環境下都是以Win32 Console Application 項目實現,而且都是單文件程序,即只含有一個源程序(.cpp)文件的C++程序。
一個單文件程序在Visual C++ IDE中的實現主要步驟是:(1)建立新項目(2)建立新文件(3)輸入源代碼(4)編譯、連接,生成可執行程序文件。以上步驟均可在Visual C++的Wizard指導下通過對話框交互輸入完成。
1. 建立新項目:
每個C++程序的實現都要建立一個項目。所謂項目是一個文件生成過程的管理單位,項目名稱就是最後實現的可執行文件的名稱,一個項目就是與生成這個可執行程序文件相關的所有源文件和中間文件的集合,存放在以項目名稱命名的文件夾中。
圖1 Microsoft Visual C++ 6.0系統初始界面
執行菜單命令File>New,打開New對話框:
圖2 打開New對話框
在New對話框的Project選項卡中選擇Win32 Console Application選項,然後輸入項目存放位置項目名稱後確定。
圖3 輸入項目位置和名稱
在Win32 ConsoleApplication-Step 1 of 1對話框中選擇An empty project,完成後返回。系統彈出新建項目信息報告對話框。
圖4 Win32 ConsoleApplication-Step 1 of 1對話框
圖5 新建項目信息報告
2. 建立新文件:
再一次執行菜單命令File>New,打開New對話框,在File選項卡中選擇C++ Sourse File選項,然後輸入源程序文件名。完成後系統打開源程序(.cpp)文件編輯窗口。
圖6 在New對話框輸入源程序文件名
3. 輸入源代碼:
此時即可在源程序(.cpp)文件編輯窗口輸入源程序代碼。
圖7 源程序(.cpp)文件編輯窗口
4. 生成和運行可執行程序文件:
11從源程序文件生成可執行文件,需要經歷編譯,連接兩步,在VC++6.0編程環境中可以有以下幾種操作方式:
(1)打開Build (編譯)菜單,先執行Compile命令,接著再執行Build命令。
(2)打開Build (編譯)菜單,執行Rebuilde All命令。
(3)打開Build (編譯)菜單,直接發出Execute 執行命令,一次性完成編譯、連接和啟動程序執行的任務。
(4)直接單擊「!」(BuildExecute)命令按鈕,一次性完成編譯、連接和啟動程序執行的任務。
圖8 Build (編譯)菜單
圖9 程序運行結果
打開工程文件夾可以找到該工程的所有工作文件。
打開工程文件夾中的Debug子文件夾,可以找到生成的可執行(.exe)文件。
二. 多文件程序的實現
一個較大型C++程序,有時需要包含多個源程序文件。一種常見的情況是將類的定義放在頭(.h)文件中,將類的實現或對類的訪問放在源(.cpp)文件中。
多文件程序的實現與單文件程序的實現方式需要經歷同樣的步驟,不同的是,在編譯之前需要利用新建文件對話框逐一將所有需要的文件追加到項目中。
1. 建立新項目:
2. 建立新文件:
(1)加入和編輯頭文件:
在New對話框,在File選項卡中選擇C/C++ Header File選項,然後輸入頭文件名。完成後系統將打開源程序(.h)文件編輯窗口。
(2)加入和編輯源程序文件
打開New對話框,在File選項卡中選擇C++ Sourse File選項,然後輸入源程序文件名。完成後系統打開源程序(.cpp)文件編輯窗口。
注意:在源程序文件中應該用文件包含命令將頭文件包含進來。如下例源程序文件s719.cpp的第一行:#include"h719.h"
3. 生成和運行可執行程序文件:
步驟同單文件程序的生成和執行。
#
2.MFC對話框應用程序實現舉例
本指導書給出3個MFC對話框應用程序的實現實例,例1為求三科平均成績的簡單程序,例2為實現一個具有四則運算功能的簡單計算器,例3為一個彩票機程序(提供手動搖號和自動搖號兩個彩票機程序版本)。
通過這些程序可以達到以下目的:
掌握AppWizard的使用方法。
掌握Workshop中各種視圖的使用和在不同視圖之間切換的方法。
學會利用控制項工具箱中的控制項定製對話框界面。
學會控制項變數及其他類成員變數的設置。
學會消息映射的概念和操作方法。
學會查看和編輯代碼。
學習編譯、運行和調試對話框應用程序。
例1.實現一個求三科平均成績的MFC對話框應用程序。假設運行時的界面如下:
實現步驟:
1. 在Visual C++ 6.0工作開發環境中,New對話框中選擇MFC AppWizard [exe]項目,輸入項目名稱並指定存放位置。
2. 在MFC Wizard Step1選擇Dialog(基本對話)程序類型,在MFC Wizard Step2中輸入對話框標題「求平均成績」。
AppWizard對話結束後打開對話框編輯窗口如下:
3. 定製界面:添加控制項、設置屬性
刪除對話框模板中原有的「確定」按鈕和內容為「TODO: 在這里設置對話控制。」的Static Text控制項。
在控制項工具箱中取一個Group Box控制項,調整適當大小,滑鼠右鍵單擊該控制項邊框,在彈出的下拉菜單中打開屬性對話框。將Group Box控制項標題由「Static」改為「求平均分」。
在Group Box中添加4個Static Text控制項,按同樣方法修改它們的標題屬性為「成績1」、「成績2」、「成績3」和「平均分」。
在Group Box中添加4個Edit Box控制項,打開屬性對話框的Extended Styles選項卡中將它們設置為文本右對齊(Right Aligend Text)方式。其中第4 個Edit Box控制項的Styles屬性設置為Read-only。
在Group Box中添加一個按鈕Button1,打開屬性對話框將按鈕的標題屬性改為 「計算平均分」。
滑鼠右鍵單擊「取消」按鈕邊框,在彈出的下拉菜單中打開屬性對話框。將按鈕標題改為「退出」。
設計完成的界面如圖,其中控制項屬性列表如下:
控制項
ID號
標題
屬性
Group Box
IDC_STATIC
求平均分
Static Text
IDC_STATIC
成績1
Static Text
IDC_STATIC
成績2
Static Text
IDC_STATIC
成績3
Static Text
IDC_STATIC
平均分
Edit Box
IDC_EDIT1
Align text:Right
Edit Box
IDC_EDIT2
Align text:Right
Edit Box
IDC_EDIT3
Align text:Right
Edit Box
IDC_EDIT4
Align text:Right;Read-only
Button
IDC_BUTTON1
計算平均分
Button
IDCANCEL
退出
4. 添加成員變數
單擊View(查看)>ClassWizard(建立類向導)菜單進入ClassWizard,打開Member Variables選項卡:為4 個Edit Box控制項設置對應的變數:
同樣的方法為其它3個Edit Box控制項設置變數:
控制項ID
變數名
變數類型
數值范圍
IDC_EDIT1
m_S1
int
0~100
IDC_EDIT2
m_S2
int
0~100
IDC_EDIT3
m_S3
int
0~100
IDC_EDIT4
m_Sav
CString
5. 添加消息映射(兩條消息)
進入ClassWizard,打開Messages Maps選項卡,在Object Ids中選擇CAverageDlg,在Messages中滑鼠單擊WM_INIDIALOG,在Member functions中出現生成的消息映射成員函數OnInitDialog提示:
在Object Ids中選擇IDC_BUTTON1,在Messages中滑鼠單擊BN_CLIKED,在彈出對話框中單擊OK按鈕:在Member functions中出現第二個生成的消息映射成員函數OnButton1。
6. 添加代碼
在ClassWizard中雙擊OnInitDialog函數,打開代碼編輯器中的OnInitDialog()函數代碼,找到其中的 // TODO: Add extra initialization here,加入下面的黑體字給出的3行代碼:
BOOL CDlgDlg::OnInitDialog()
{
CDialog::OnInitDialog();
…;
// TODO: Add extra initialization here
m_Sav="0.00";
m_S1=m_S2=m_S3;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
在ClassWizard中雙擊OnButton1()函數,打開代碼編輯器中的OnButton1()函數代碼,找到其中的 // TODO: Add extra initialization here,加入下面的黑體字給出的4行代碼:
void CDlgDlg::OnButton1()
{
// TODO: Add extra initialization here
UpdateData();
double ave=(double)(m_S1+m_S2+m_S3)/3.0;
m_Sav.Format("%6.2f",ave);
UpdateData(FALSE);
}
7. 編譯運行程序:
注釋:
UpdateData()函數的作用是允許更新控制項變數,
UpdateData(FALSE) 禁止更新控制項變數的值。
例2.設計MFC對話框應用程序,實現一個具有四則運算功能的簡單計算器。
1. 新建項目:
2. 定製界面:
(1) 修改MFC AppWizard自動創建的對話框項目模板。刪除模板上自動創建的三個控制項。
(2) 加入「簡單計算器」、「請輸入數據:」、「結果」三個靜態文本框和相應的3個編輯框。
(3) 加入一個Group Box,標題修改為「請選擇運算符:」,並在其中放入4個Radio Button將標題分別改為「+」、「-」、「*」、「/」。
(4) 繼續用滑鼠從工具箱中向對話框添加和3個按鈕控制項,更改按鈕的標題為「計算」、「清除」、「關閉」。
3. 添加變數
本例中用到以下4個CSimpleCalcDlg類的成員變數:
變數類型
名稱
float
m_N1
float
m_N2
float
m_ Result
char
Operator
用ClassWizard為編輯框添加變數:m_N1, m_N2, m_Result
變數char Operator的添加方法:
在WorkSpace中進入ClassView視圖, 滑鼠右鍵單擊CSimpleCalcDlg, 在菜單中選擇「Add Member Variable…」
然後在彈出的對話框的輸入變數類型和名稱:
4. 添加消息映射
用ClassWizard為按鈕控制項添加消息映射:
繼續用ClassWizard為Radio Button控制項添加消息映射:
5. 加入單擊按鈕時的事件響應代碼
在實現文件(cpp文件)中加入單擊按鈕時的事件響應代碼。(雙擊一個按鈕可直接進入函數編輯)
//選擇運算符
void CSimpleCalcDlg::OnRadio1()
{ Operator='+'; }
void CSimpleCalcDlg::OnRadio2()
{ Operator='-'; }
void CSimpleCalcDlg::OnRadio3()
{ Operator='*'; }
void CSimpleCalcDlg::OnRadio4()
{ Operator='/'; }
//計算
void CSimpleCalcDlg::OnButton1()
{
UpdateData();
switch(Operator)
{
case '+':
m_Result=m_N1+m_N2;
break;
case '-':
m_Result=m_N1-m_N2;
break;
case '*':
m_Result=m_N1*m_N2;
break;
case '/':
if(m_N2 == 0 )
MessageBox("除數不能為零!");
else
{
m_Result = m_N1/m_N2;
break;
}
default:
m_Result=m_N1+m_N2;
}
UpdateData(FALSE);
}
//清除
void CSimpleCalcDlg::OnButton2()
{
UpdateData();
m_N1=0;
m_N2=0;
m_Result=0;
UpdateData(FALSE);
}
//關閉
void CSimpleCalcDlg::OnButton3()
{ CDialog::OnOK(); }
6. 編譯運行程序
例3. 彩票機程序:
本例給出手動搖號和自動搖號兩個彩票機程序版本。
1. 彩票機界面:
定製含有7個Edit Box 、1個Progress(進度條)和3偵探按鈕控制項的對話框界面如下:
2. 設置變數:
(1) 設置進度條變數:
(2) 設置7個編輯框變數:
(3)添加類成員變數m_x:
3. 消息映射:
在ClassWizard中產生OnInitDialog、OnButton1、OnButton2、OnOK四個消息映射函數:
4. 添加代碼:
//初始化
BOOL CLotusDlg::OnInitDialog()
{
CDialog::OnInitDialog();
……
// TODO: Add extra initialization here
m_x=0;
m_pProg.SetRange(0,70);
srand((unsigned)time(NULL));
return TRUE; // return TRUE unless you set the focus to a control
}
(一)手動搖號
//手動搖號,每按一次搖號按鈕出一個號
void CLotusDlg::OnButton1()
{
// TODO: Add your control notification handler code here
switch(m_x/10)
{
case 0:
m_N1=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 1:
m_N2=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 2:
m_N3=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 3:
m_N4=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 4:
m_N5=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 5:
m_N6=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 6:
m_N7=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
}
UpdateData(FALSE);
}
void CLotusDlg::OnButton2()
{
// TODO: Add your control notification handler code here
m_x=0;
m_N1=0;
m_N2=0;
m_N3=0;
m_N4=0;
m_N5=0;
m_N6=0;
m_N7=0;
UpdateData(FALSE);
m_pProg.SetPos(1);
}
void CLotusDlg::OnOK()
{
CDialog::OnOK();
}
(二)自動搖號
將前面實現的手動搖號程序修改為自動定時搖號。
添加OnTimer消息映射函數:
//按搖號按鈕啟動搖號
void CLotusDlg::OnButton1()
{
SetTimer(1,2000,NULL);
}
void CLotusDlg::OnButton2()
{
m_x=0;
m_N1=0;
m_N2=0;
m_N3=0;
m_N4=0;
m_N5=0;
m_N6=0;
m_N7=0;
UpdateData(FALSE);
m_pProg.SetPos(0);
KillTimer(1);
}
void CLotusDlg::OnTimer(UINT nIDEvent)
{
switch(m_x/10)
{
case 0:
m_N1=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 1:
m_N2=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 2:
m_N3=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 3:
m_N4=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 4:
m_N5=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 5:
m_N6=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
case 6:
m_N7=rand()%36+1;
m_pProg.SetPos(m_x+=10);
break;
}
UpdateData(FALSE);
CDialog::OnTimer(nIDEvent);
}
void CLotusDlg::OnOK()
{
KillTimer(1);
CDialog::OnOK();
}
5. 注釋:
(1)產生隨機數的方法
函數unsigned int rand() 產生隨機數。
函數void srand(unsigned int seed) 設定隨機數產生器的種子,其中seed為隨機數產生器的種子,本例中用系統時鍾當前值作隨機數種子:
srand((unsigned)time(NULL));函數的
表達式rand()%36+1產生1-36之間的隨機數
(3) 定時器的使用方法
定時器的使用涉及OnTimer、SetTimer、KillTimer三個函數。
SetTimer用於設定定時時間和啟動定時器,其中第一個參數是定時編號,第二個參數是定時的毫秒數。本例中將1號定時器定時時間設定為2秒:
SetTimer(1,2000,NULL);
定時器啟動以後將持續工作,每到達一次定時時間即啟動一次OnTimer消息函數的執行。KillTimer的作用是停止指定定時器的工作。
3.
MFC單文檔應用程序實現舉例
創建單文檔應用程序的一般步驟:
利用AppWizard創建單文檔應用程序框架。
在文檔類中聲明保存文檔數據所需要數據對象。
完成文檔類的OnNewDocument函數,初始化新文檔。
完成文檔類的Serialize函數,保持和載入文檔數據。
完成視類的OnInitialUpdate函數,初始化顯示。
完成視類的OnDraw函數,顯示當前文檔內容。
在視類中加入可以使用戶編輯文檔數據所需的代碼。
本實驗指導通過以下4 個實驗循序漸進演示創建單文檔應用程序的基本操作,在前一個例子中演練過的操作,在後面的中出現時不再重復描述。
例1 一個簡單的單文檔應用程序——記事本程序
例2 簡單文本和圖形輸出
例3 利用定時器輸出滾動字幕
例4 文檔串列化編程
例1.
一個簡單的單文檔應用程序——記事本程序
1. 只要在AppWizard的Step 6將Base Class設置為EditView,AppWizard就自動完成了一個記事本程序的設計:
2. 運行程序,即可測試記事本的各種功能:
3.說明:
(1)打開Workshop中的Class視圖,可以看到,一個簡單的單文檔應用程序向導自動建立五個類:
向導自動建立的類
相應源文件
其他源文件
相應頭文件
其他頭文
⑥ 簡述在VC++6.0環境下運行一個C++源程序的步驟
可以參考下面方法處理:
1、首先,打開我們的VC++6.0編程軟體,點擊左上角的「文件」菜單,並選擇「新建」。
⑦ 用vc++實現usb介面通信編程的一般步驟
我來說下我做過的USB通信,我沒有做過DSP跟上位機的通信,我只做過ARM類的STM32跟上位機的數據傳遞,雖然做過但是也不是很 懂,只是略知一二,我來說說我怎麼做的吧,我是這么實現的:
USB是個很復雜的協議,你如果完全搞懂,我估計沒有幾個月專心鑽研是不行的,但是如果只是能實現你的這個功能,我估計不是很復雜。
首先來說說USB通信:
USB通信傳輸方式分為四種:控制,中斷,批量,同步傳輸四種,這個你可以看看網上資料,然後我用STM32通信,因為數據量不是很大,我用的是中斷傳輸方式,但是DSP數據量應該會比較大,不知道中斷傳輸行不行,但是一般問題不大。
傳輸方式說完了,再說說USB設備類型,你每次插usb設備到電腦上的時候就會有提示,這是一個什麼設備,USB設備類型就是說的這個意思,是滑鼠還是鍵盤還是別的什麼的,如果你選用標準的類,你就不用自己寫上位機(PC)的驅動程序,但是如果不用標準的類,就是用自定義的類就要自己寫上層的設備驅動程序,就是所謂的DDK,WDM,WDF什麼的,你沒寫過這方面的還真有點棘手,但是也不一定要寫驅動程序,你可以試試有個類叫HID類,這個類在USB通信的時候用的還挺多的,不過這個類也有缺點,這個地方還要說一點,USB還分低速,全速,高速三種,不太了解DSP,不知道他支持什麼模式,但是USB2.0的全速應該至少可以支持的。
USB2.0全速模式HID用中斷方式每秒最多可以傳輸64KB的數據,不知道能不能達到你的要求,但是我估計一般問題不大了,如果你這歀DSP能支持高速模式,每秒用這種方式可以傳輸高達22MB的數據,這個速度一般問題不大了。
你可以照著我說的思路,去網上搜搜人家寫好的程序,肯定有人做過DSP的USB通信,然後你按照自己的要求改一改,主要應該是USB的設備描述符部分要自己修改,然後可能還要根據自己的電路改改配置什麼的,上位機軟體網上有源代碼的多的是,然後自己摸索摸索,我估計你要是編程水平還可以的話,只是摸索USB,一兩個星期完全沒有問題,祝你好運!