VC小技巧15个

    技术2022-05-11  124

    VC小技巧15个
    http://edu.tmn.cn (2005-2-26 1:57) (来自未知) 作者:未知   

    一、 一次只运行一个程序实例下列两种方式都可以实现,建议采用第二种方式:1、 if( FindWindow(NULL,"程序标题"))          exit(0);2、BOOL CDemoTBarEApp::InstanceIsRun(){ HANDLE m_hMutex; m_hMutex = ::CreateMutex(NULL, TRUE, _T("YourApplication")); ASSERT(m_hMutex); if (GetLastError() == ERROR_ALREADY_EXISTS) {  m_hMutex = NULL;  return TRUE;//实例已经运行 } return FALSE;//实例未运行}

    二、 装载光标SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));  其中::SetCursor()是全局函数,用来设置整个例程的光标参数是宏定义光标句柄。AfxGetApp ()是一个系统函数,它返回当前的一个CWinApp对象。其成员函数LoadStandardCursor()用来读取一个系统指针,每一种系统指针的具体宏定义如下:IDC_APPSTARTING  带小沙漏的标准箭头IDC_ARROW  标准箭头IDC_CROSS  十字光标(用于定位)IDC_HAND  Windows 2000:手型IDC_HELP  带问号的箭头IDC_IBEAM  I型标IDC_ICON  Obsolete for applications marked version 4.0 or later. IDC_NO   禁止符号IDC_SIZE  Obsolete for applications marked version 4.0 or later. Use IDC_SIZEALL. IDC_SIZEALL  十字箭头IDC_SIZENESW  指向东北和西南的双向箭头IDC_SIZENS  指向南和北的双向箭头IDC_SIZENWSE  指向西北和东南的双向箭头IDC_SIZEWE  指向东西的双向箭头IDC_UPARROW  上箭头IDC_WAIT  沙漏

    三、获得主框架: CMainFrame * pMainframe = (CMainFrame *) AfxGetApp()->m_pMainWnd;.获取应用程序的实例句柄:      Example: HANDLE hInstance=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));

    六、绘制立体字体效果的字体,很值得一看void CTestView::OnPaint() { CPaintDC dc(this); // device context for painting  CRect rect; GetWindowRect(rect);

     CFont  m_fontLogo; m_fontLogo.CreateFont(24, 0, 0, 0, FW_BOLD, true,  FALSE,0,0,0,0,0,0, "Arial"); CString m_LogoText; m_LogoText=_T("Benlux Pro3D System"); dc.SetBkMode(TRANSPARENT);

     CFont * OldFont = dc.SelectObject(&m_fontLogo);

     // draw text in DC COLORREF OldColor = 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);

     // restore old text color dc.SetTextColor( OldColor); // restore old font dc.SelectObject(OldFont);  // Do not call CView::OnPaint() for painting messages}

    七、简单的消息检索和抽取函数,能够让系统响应其它操作BOOL PeekAndPump(){ static MSG msg;

     while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {  if (!AfxGetApp()->PumpMessage()) {   ::PostQuitMessage(0);   return FALSE;  }  } return TRUE;}

    八、在你的程序中用动画光标替换默认的等待光标 (ANI光标的使用) HCURSOR m_hAniCursor=NULL; BeginWaitCursor();   //begin wait cursor for api function  //load ani cursor from file in current path TCHAR cursorPath[MAX_PATH]; GetModuleFileName(NULL,cursorPath,MAX_PATH); char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath(cursorPath, drive, dir, fname, ext ); sprintf(cursorPath,"%s%swait.ani",drive,dir);  //ani cursor file name is wait.ani  m_hAniCursor= LoadCursorFromFile(cursorPath); HCURSOR oldCursor; if(m_hAniCursor != NULL)  oldCursor=SetCursor(m_hAniCursor);  for(long i=0;i<1000;i++)    Sleep(5);  oldCursor=NULL; m_hAniCursor=NULL; EndWaitCursor();  //end wait cursor for api function

    九、如何限制编辑框中的准许字符     如果用户在编辑控件中只允许接收数字,可以使用一个标准的编辑控件并指定新的创建标志ES_NUMBERS,它是Windows 95新增加的标志,该标志限制 编辑控件只按收数字字符。如果用户需要复杂的编辑控件,可以使用Microsoft 的屏蔽编辑控件,它是一个很有用的OLE定制控件。    如果希望不使用OLE 定制控件自己处理字符,可以派生一个CEdit 类并处理WM_CHAR消息,然后从编辑控件中过滤出特定的字符。首先,使用ClassWizard 建立一个 CEdit的派生类,其次,在对话类中指定一个成员变量将编辑控件分类在OnInitdialog 中调用CWnd: : SubclassDlgItem .

    //In your dialog class declaration (.H file )private :    CMyEdit m_wndEdit ; // Instance of your new edit control .

    //In you dialog class implementation (.CPP file )BOOL CSampleDialog : : OnInitDialog ( ){

        //Subclass the edit lontrod .    m_wndEdit .SubclassDlgItem  (IDC_EDIT,this );    …}    使用ClassWizard处理WM_CHAR消息,计算nChar参量并决定所执行的操作,用户可以确定是否修改、传送字符。下例说明了如何显示字母字符,如果字符是字母字符,则调用CWnd ; OnChar,否则不调用OnChar.//Only display alphabetic dharacters .void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UITN nFlags ){    //Determine if nChar is an alphabetic character .    if (: : IsCharAlpha  ( ( TCHAR) nChar ) )        CEdit : : OnChar (nChar, nRepCnt , nFlags );}    如果要修改字符,则不能仅仅简单地用修改过的nChar调用CEdit : : OnChar。要修改一个字符,需要首先修改nChar,然后用修改过的nChar调用CWnd: : DefWindowProc。下例说明了如何将字符转变为大写://Make all characters uppercasevoid CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UINT nFlags ){    //Make sure character is uppercase .    if (: : IsCharAlpha  ( .( TCHAR) nChar)         nChar=: : CharUpper (nChar ) ;    //Bypass default OnChar processing and directly call  default window proc.    DefWindProc (WM_CHAR, nChar , MAKELPARAM (nRepCnt , nFlags )) ;}

    十、串太长时如何在其末尾显示一个省略号    调用CDC:: DrawText并指定DT_END_ELLIPSIS标志,这样就可以用小略号取代串末尾的字符使其适合于指定的边界矩形。如果要显示路径信息,指定DT_END_ELLIPSIS标志并省略号取代串中间的字符。void CSampleView:: OnDraw (CDC* pDC){     CTestDoc* pDoc=GetDocument ();     ASSERT_VALID (pDoc);                                                                                         //Add ellpsis to end of string if it does not fit     pDC->Drawtext (CString ("This is a long string"),         CRect (10, 10, 80, 30), DT_LEFT | DT_END_ELLIPSIS);

         //Add ellpsis to middle of string if it does not fit     pDC->DrawText (AfxgetApp () ->m_pszhelpfilePath,         CRect (10, 40, 200, 60), DT_LEFT | DT_PATH_ELLIPSIS);}

    十一、如何实现一个橡皮区矩形(具有踪迹矩形并可移动、缩放的矩形)     CRectTracker是一个很有用的类,可以通过调用CRectTracker:: TrackRubberBand响应WM_LBUTTONDOWN消息来创建一个橡皮区矩形。下例表明使用CRectTracker移动和重置视窗中的蓝色椭圆的大小是很容易的事情。    首先,在文档类中声明一个CRectTracker数据成员:class CTestDoc: Public CDocument{…public: CRectTracker m_tracker;…};     其次,在文档类的构造函数中初始化CRectTracker 对象:CTestDoc::CTestDoc(){ m_tracker.m_rect.SetRect (10, 10, 300, 300); m_tracker.m_nStyle=CRectTracker:: resizeInside  |  CRectTracker:: dottedLine; }     然后,在视图类的OnDraw函数中画椭圆和踪迹矩形:void CTestView::OnDraw(CDC* pDC){ CTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

    //Select blue brush into device context.     CBrush brush (RGB (0, 0, 255));     CBrush* pOldBrush=pDC->SelectObject (&brush);

         //draw ellipse in tracking rectangle.     CRect rcEllipse;     pDoc->m_tracker.GetTrueRect (rcEllipse);     pDC->Ellipse (rcEllipse);

         //Draw tracking rectangle.     pDoc->m_tracker.Draw (pDC);     //Select blue brush out of device context.     pDC->SelectObject(pOldBrush);}    最后,视图类中处理WM_LBUTTONDOWN消息,并增加下述代码。该段代码根据鼠标击键情况可以拖放、移动或者重置椭圆的大小。

    void CTestView::OnLButtonDown(UINT nFlags, CPoint point) {   //Get pointer to document.     CTestDoc* pDoc=GetDocument();     ASSERT_VALID (pDoc);

         //If clicked on ellipse, drag or resize it. Otherwise create a     //rubber-band rectangle nd create a new ellipse.     BOOL bResult=pDoc->m_tracker.HitTest (point)!=         CRectTracker::hitNothing;

         //Tracker rectangle changed so update views.     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);}

    十二、如何在临时目录创建一个临时文件如果你要在临时目录下创建临时文件,下面的代码能帮到你的忙。bool GetuniqueTempName (CString& strTempName){  strTempName="";     //Get the temporary files directory.     TCHAR szTempPath [MAX_PATH];     DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath);     if (dwResult==0)    return false;

         //Create a unique temporary file.     TCHAR szTempFile[MAX_PATH];     UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempFile);     if (dwResult==0)    return false;

         strTempName=szTempFile;  return true;}

    十三、如何限制窗口的最小范围要限制窗体的大小,下面的代码能帮到你的忙。在CMainFrame中增加WM_GETMAXMININFO消息的处理函数,然后在这个函数中写代码如下://限制主窗体的最小高度和宽度void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { lpMMI->ptMinTrackSize.x=600; lpMMI->ptMinTrackSize.y=400; CNewFrameWnd::OnGetMinMaxInfo(lpMMI);}

    十四、怎样删除文件到回收站中 要删除文件到回收站,很简单。只要用SHFileOperation函数就行了,下面的代码我将为你演示了这一个函数的用法。当然你可以直接拷贝到你的项目中。//删除文件到回收站中//pszPath  : 待删除的全路径文件名//bDelete  : TRUE 删除,不移到回收站,FALSE:移到回收站一、 //返回    : TRUE 删除成功     FALSE 删除失败BOOL CDelFileToRecycleDlg::Recycle(LPCTSTR pszPath, BOOL bDelete/*=FALSE*/){ SHFILEOPSTRUCT  shDelFile; memset(&shDelFile,0,sizeof(SHFILEOPSTRUCT)); shDelFile.fFlags |= FOF_SILENT;      // don"t report progress shDelFile.fFlags |= FOF_NOERRORUI;     // don"t report errors shDelFile.fFlags |= FOF_NOCONFIRMATION;    // don"t confirm delete // Copy pathname to double-NULL-terminated string. // TCHAR buf[_MAX_PATH + 1]; // allow one more character _tcscpy(buf, pszPath);   // copy caller"s pathname buf[_tcslen(buf)+1]=0;   // need two NULLs at end

     // Set SHFILEOPSTRUCT params for delete operation shDelFile.wFunc = FO_DELETE;       // REQUIRED: delete operation shDelFile.pFrom = buf;         // REQUIRED: which file(s) shDelFile.pTo = NULL;          // MUST be NULL if (bDelete) {         // if delete requested..  shDelFile.fFlags &= ~FOF_ALLOWUNDO;    // ..don"t use Recycle Bin }  else  {           // otherwise..  shDelFile.fFlags |= FOF_ALLOWUNDO;    // ..send to Recycle Bin }     return SHFileOperation(&shDelFile);    // do it!}

    十五、内存泄漏检查    也许你已经知道,在C++和C语言中指针问题也就是内存申请与释放是一个令人头疼的事情,假如你申请了内存,但没有释放,并且你的程序需要长时间地运行,那么,系统的资源将逐渐减少,当系统的资源全部被用完时,系统将会崩溃。所以在开发程序的过程中一定要保证资源的完全释放。下面我们来介绍内存漏洞的检查。示例如下:// do your memory allocations and deallocations... CString s = "This is a frame variable";#ifdef _DEBUG CMemoryState oldMemState, newMemState, diffMemState; oldMemState.Checkpoint();#endif // the next object is a heap object CString* p = new CString( "Smith  Alan  581_0215" ); delete p; p=NULL;#ifdef _DEBUG newMemState.Checkpoint(); BOOL b=diffMemState.Difference(oldMemState, newMemState); if (b) {  AfxMessageBox( "Memory leaked! " ); }#endif    根据试验,由于我们无法释放掉象int CString char 申请的变量。只能释放指针型的变量。而检测内存时,照样会出现内存泄漏现象。所以,这种内存检测方式局限性还是很大。因为我们无法释放非指针型变量。


    最新回复(0)