VC高手的经验总结vc实用小技巧.docx
《VC高手的经验总结vc实用小技巧.docx》由会员分享,可在线阅读,更多相关《VC高手的经验总结vc实用小技巧.docx(34页珍藏版)》请在冰豆网上搜索。
![VC高手的经验总结vc实用小技巧.docx](https://file1.bdocx.com/fileroot1/2023-1/29/8487f772-6b1c-4960-9741-24fa5170996b/8487f772-6b1c-4960-9741-24fa5170996b1.gif)
VC高手的经验总结vc实用小技巧
vc实用小技巧
一、一次只运行一个程序实例下列两种方式都可以实现,
建议采用第二种方式:
1、if(FindWindow(NULL,"程序标题"))
exit(0);
2、BOOLCDemoTBarEApp:
:
InstanceIsRun()
{HANDLEm_hMutex;m_hMutex=:
:
CreateMutex(NULL,TRUE,_T("YourApplication"));ASSERT(m_hMutex);if(GetLastError()==ERROR_ALREADY_EXISTS){ m_hMutex=NULL; returnTRUE;//实例已经运行}returnFALSE;//实例未运行}
二、装载光标SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); 其中:
:
SetCursor()是全局函数,用来设置整个例程的光标参数是宏定义光标句柄。
AfxGetApp()是一个系统函数,它返回当前的一个CWinApp对象。
其成员函数LoadStandardCursor()用来读取一个系统指针,每一种系统指针的具体宏定义如下:
IDC_APPSTARTING 带小沙漏的标准箭头IDC_ARROW 标准箭头IDC_CROSS 十字光标(用于定位)IDC_HAND Windows2000:
手型IDC_HELP 带问号的箭头IDC_IBEAM I型标IDC_ICON Obsoleteforapplicationsmarkedversion4.0orlater.IDC_NO 禁止符号IDC_SIZE Obsoleteforapplicationsmarkedversion4.0orlater.UseIDC_SIZEALL.IDC_SIZEALL 十字箭头IDC_SIZENESW 指向东北和西南的双向箭头IDC_SIZENS 指向南和北的双向箭头IDC_SIZENWSE 指向西北和东南的双向箭头IDC_SIZEWE 指向东西的双向箭头IDC_UPARROW 上箭头IDC_WAIT 沙漏获得主框架:
CMpMainframe=(CMainFrame*)AfxGetApp()->m_pMainWnd;.获取应用程序的实例句柄:
Example:
HANDLEhInstance=AfxGetInstanceHandle();获得应用程序主窗口的指针:
Example:
AfxGetMainWnd()->ShowWindow(SW_SHOWMAXMIZED);//使程序最大化
四、重新建立字体的代码if(m_fontLogo.m_hObject) m_fontLogo.Detach();m_fontLogo.CreateFont(nHeight,0,0,0,nWeight,bItalic,bUnderline,0,0,0,0,0,0,Name);
五、用指定颜色填充区域dc.FillSolidRect(rect,:
:
GetSysColor(COLOR_3DFACE));
六、绘制立体字体效果的字体,很值得一看voidCTestView:
:
OnPaint(){CPaintDCdc(this);//devicecontextforpainting CRectrect;GetWindowRect(rect);CFont m_fontLogo;m_fontLogo.CreateFont(24,0,0,0,FW_BOLD,true, FALSE,0,0,0,0,0,0,"Arial");CStringm_LogoText;m_LogoText=_T("BenluxPro3DSystem");dc.SetBkMode(TRANSPARENT);CFont*OldFont=dc.SelectObject(&m_fontLogo);//drawtextinDCCOLORREFOldColor=dc.SetTextColor(:
:
GetSysColor(COLOR_3DHILIGHT));rect.right=rect.Width();rect.bottom=rect.Height();rect.left=rect.top=0;dc.FillSolidRect(rect,:
:
GetSysColor(COLOR_3DFACE));dc.DrawText(m_LogoText,rect+CPoint(1,1),DT_SINGLELINE|DT_LEFT|DT_VCENTER);dc.SetTextColor(:
:
GetSysColor(COLOR_3DSHADOW));dc.DrawText(m_LogoText,rect,DT_SINGLELINE|DT_LEFT|DT_VCENTER);//restoreoldtextcolordc.SetTextColor(OldColor);//restoreoldfontdc.SelectObject(OldFont); //DonotcallCView:
:
OnPaint()forpaintingmessages}
七、简单的消息检索和抽取函数,能够让系统响应其它操作BOOLPeekAndPump(){staticMSGmsg;while(:
:
PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){ if(!
AfxGetApp()->PumpMessage()){ :
:
PostQuitMessage(0); returnFALSE; } }returnTRUE;}
八、在你的程序中用动画光标替换默认的等待光标(ANI光标的使用)HCURSORm_hAniCursor=NULL;BeginWaitCursor(); //beginwaitcursorforapifunction //loadanicursorfromfileincurrentpathTCHARcursorPath[MAX_PATH];GetModuleFileName(NULL,cursorPath,MAX_PATH);chardrive[_MAX_DRIVE];chardir[_MAX_DIR];charfname[_MAX_FNAME];charext[_MAX_EXT];_splitpath(cursorPath,drive,dir,fname,ext);sprintf(cursorPath,"%s%s\wait.ani",drive,dir); //anicursorfilenameiswait.ani m_hAniCursor=LoadCursorFromFile(cursorPath);HCURSORoldCursor;if(m_hAniCursor!
=NULL) oldCursor=SetCursor(m_hAniCursor); for(longi=0;i<1000;i++) Sleep(5); oldCursor=NULL;m_hAniCursor=NULL;EndWaitCursor(); //endwaitcursorforapifunction
九、如何限制编辑框中的准许字符 如果用户在编辑控件中只允许接收数字,可以使用一个标准的编辑控件并指定新的创建标志ES_NUMBERS,它是Windows95新增加的标志,该标志限制编辑控件只按收数字字符。
如果用户需要复杂的编辑控件,可以使用Microsoft的屏蔽编辑控件,它是一个很有用的OLE定制控件。
如果希望不使用OLE定制控件自己处理字符,可以派生一个CEdit类并处理WM_CHAR消息,然后从编辑控件中过滤出特定的字符。
首先,使用ClassWizard建立一个CEdit的派生类,其次,在对话类中指定一个成员变量将编辑控件分类在OnInitdialog中调用CWnd:
:
SubclassDlgItem.//Inyourdialogclassdeclaration(.Hfile)private:
CMyEditm_wndEdit;//Instanceofyourneweditcontrol.//Inyoudialogclassimplementation(.CPPfile)BOOLCSampleDialog:
:
OnInitDialog(){ //Subclasstheeditlontrod. m_wndEdit.SubclassDlgItem (IDC_EDIT,this); …} 使用ClassWizard处理WM_CHAR消息,计算nChar参量并决定所执行的操作,用户可以确定是否修改、传送字符。
下例说明了如何显示字母字符,如果字符是字母字符,则调用CWnd;OnChar,否则不调用OnChar.//Onlydisplayalphabeticdharacters.voidCMyEdit:
:
OnChar(UINTnChar,UINTnRepCnt,UITNnFlags){ //DetermineifnCharisanalphabeticcharacter. if(:
:
IsCharAlpha ((TCHAR)nChar)) CEdit:
:
OnChar(nChar,nRepCnt,nFlags);} 如果要修改字符,则不能仅仅简单地用修改过的nChar调用CEdit:
:
OnChar。
要修改一个字符,需要首先修改nChar,然后用修改过的nChar调用CWnd:
:
DefWindowProc。
下例说明了如何将字符转变为大写:
//MakeallcharactersuppercasevoidCMyEdit:
:
OnChar(UINTnChar,UINTnRepCnt,UINTnFlags){ //Makesurecharacterisuppercase. if(:
:
IsCharAlpha (.(TCHAR)nChar) nChar=:
:
CharUpper(nChar); //BypassdefaultOnCharprocessinganddirectlycall defaultwindowproc. DefWindProc(WM_CHAR,nChar,MAKELPARAM(nRepCnt,nFlags));}
十、串太长时如何在其末尾显示一个省略号 调用CDC:
:
DrawText并指定DT_END_ELLIPSIS标志,这样就可以用小略号取代串末尾的字符使其适合于指定的边界矩形。
如果要显示路径信息,指定DT_END_ELLIPSIS标志并省略号取代串中间的字符。
voidCSampleView:
:
OnDraw(CDC*pDC){ CTestDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); //Addellpsistoendofstringifitdoesnotfit pDC->Drawtext(CString("Thisisalongstring"), CRect(10,10,80,30),DT_LEFT|DT_END_ELLIPSIS); //Addellpsistomiddleofstringifitdoesnotfit pDC->DrawText(AfxgetApp()->m_pszhelpfilePath, CRect(10,40,200,60),DT_LEFT|DT_PATH_ELLIPSIS);}
十一、如何实现一个橡皮区矩形(具有踪迹矩形并可移动、缩放的矩形) CRectTracker是一个很有用的类,可以通过调用CRectTracker:
:
TrackRubberBand响应WM_LBUTTONDOWN消息来创建一个橡皮区矩形。
下例表明使用CRectTracker移动和重置视窗中的蓝色椭圆的大小是很容易的事情。
首先,在文档类中声明一个CRectTracker数据成员:
classCTestDoc:
PublicCDocument{…public:
CRectTrackerm_tracker;…}; 其次,在文档类的构造函数中初始化CRectTracker对象:
CTestDoc:
:
CTestDoc(){m_tracker.m_rect.SetRect(10,10,300,300);m_tracker.m_nStyle=CRectTracker:
:
resizeInside | CRectTracker:
:
dottedLine;} 然后,在视图类的OnDraw函数中画椭圆和踪迹矩形:
voidCTestView:
:
OnDraw(CDC*pDC){CTestDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);//Selectbluebrushintodevicecontext. CBrushbrush(RGB(0,0,255)); CBrush*pOldBrush=pDC->SelectObject(&brush); //drawellipseintrackingrectangle. CRectrcEllipse; pDoc->m_tracker.GetTrueRect(rcEllipse); pDC->Ellipse(rcEllipse); //Drawtrackingrectangle. pDoc->m_tracker.Draw(pDC); //Selectbluebrushoutofdevicecontext. pDC->SelectObject(pOldBrush);} 最后,视图类中处理WM_LBUTTONDOWN消息,并增加下述代码。
该段代码根据鼠标击键情况可以拖放、移动或者重置椭圆的大小。
voidCTestView:
:
OnLButtonDown(UINTnFlags,CPointpoint){ //Getpointertodocument. CTestDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); //Ifclickedonellipse,dragorresizeit.Otherwisecreatea //rubber-bandrectanglendcreateanewellipse. BOOLbResult=pDoc->m_tracker.HitTest(point)!
= CRectTracker:
:
hitNothing; //Trackerrectanglechangedsoupdateviews. if(bResult) { pDoc->m_tracker.Track(this,point,TRUE); pDoc->SetModifiedFlag(); pDoc->UpdateAllViews(NULL); } else pDoc->m_tracker.TrackRubberBand(this,point,TRUE);CView:
:
OnLButtonDown(nFlags,point);}
十二、如何在临时目录创建一个临时文件如果你要在临时目录下创建临时文件,下面的代码能帮到你的忙。
boolGetuniqueTempName(CString&strTempName){ strTempName=""; //Getthetemporaryfilesdirectory. TCHARszTempPath[MAX_PATH]; DWORDdwResult=:
:
GetTempPath(MAX_PATH,szTempPath); if(dwResult==0) returnfalse; //Createauniquetemporaryfile. TCHARszTempFile[MAX_PATH]; UINTnResult=GetTempFileName(szTempPath,_T("~ex"),0,szTempFile); if(dwResult==0) returnfalse; strTempName=szTempFile; returntrue;}
十三、如何限制窗口的最小范围要限制窗体的大小,下面的代码能帮到你的忙。
在CMainFrame中增加WM_GETMAXMININFO消息的处理函数,然后在这个函数中写代码如下:
//限制主窗体的最小高度和宽度voidCMainFrame:
:
OnGetMinMaxInfo(MINMAXINFOFAR*lpMMI){lpMMI->ptMinTrackSize.x=600;lpMMI->ptMinTrackSize.y=400;CNewFrameWnd:
:
OnGetMinMaxInfo(lpMMI);}
十四、怎样删除文件到回收站中要删除文件到回收站,很简单。
只要用SHFileOperation函数就行了,下面的代码我将为你演示了这一个函数的用法。
当然你可以直接拷贝到你的项目中。
//删除文件到回收站中//pszPath :
待删除的全路径文件名//bDelete :
TRUE删除,不移到回收站,FALSE:
移到回收站一、//返回 :
TRUE删除成功 FALSE删除失败BOOLCDelFileToRecycleDlg:
:
Recycle(LPCTSTRpszPath,BOOLbDelete/*=FALSE*/){SHFILEOPSTRUCT shDelFile;memset(&shDelFile,0,sizeof(SHFILEOPSTRUCT));shDelFile.fFlags|=FOF_SILENT; //don'treportprogressshDelFile.fFlags|=FOF_NOERRORUI; //don'treporterrorsshDelFile.fFlags|=FOF_NOCONFIRMATION; //don'tconfirmdelete//Copypathnametodouble-NULL-terminatedstring.//TCHARbuf[_MAX_PATH+1];//allowonemorecharacter_tcscpy(buf,pszPath); //copycaller'spathnamebuf[_tcslen(buf)+1]=0; //needtwoNULLsatend//SetSHFILEOPSTRUCTparamsfordeleteoperationshDelFile.wFunc=FO_DELETE; //REQUIRED:
deleteoperationshDelFile.pFrom=buf; //REQUIRED:
whichfile(s)shDelFile.pTo=NULL; //MUSTbeNULLif(bDelete){ //ifdeleterequested.. shDelFile.fFlags&=~FOF_ALLOWUNDO; //..don'tuseRecycleBin} else { //otherwise.. shDelFile.fFlags|=FOF_ALLOWUNDO; //..sendtoRecycleBin} returnSHFileOperation(&shDelFile); //doit!
}
十五、内存泄漏检查 也许你已经知道,在C++和C语言中指针问题也就是内存申请与释放是一个令人头疼的事情,假如你申请了内存,但没有释放,并且你的程序需要长时间地运行,那么,系统的资源将逐渐减少,当系统的资源全部被用完时,系统将会崩溃。
所以在开发程序的过程中一定要保证资源的完全释放。
下面我们来介绍内存漏洞的检查。
示例如下:
//doyourmemoryallocationsanddeallocations...CStrings="Thisisaframevariable";#ifdef_DEBUGCMemoryStateoldMemState,newMemState,diffMemState;oldMemState.Checkpoint();#endif//thenextobjectisaheapobjectCString*p=newCString("Smith Alan 581_0215");deletep;p=NULL;#ifdef_DEBUGnewMemState.Checkpoint();BOOLb=diffMemState.Difference(oldMemState,newMemState);if(b){ AfxMessageBox("Memoryleaked!
\n");}#endif
根据试验,由于我们无法释放掉象intCStringchar申请的变量。
只能释放指针型的变量。
而检测内存时,照样会出现内存泄漏现象。
所以,这种内存检测方式局限性还是很大。
因为我们无法释放非指针型变量。
CString,string,char*的综合比较
(一)概述string和CString均是字符串模板类,string为标准模板类(STL)定义的字符串类,已经纳入C++标准之中;CString(typedefCStringT>CString)为