一、 一次只運行一個程序實例
下列兩種方式都可以實現,建議采用第二種方式:
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 uppercase
void 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 申請的變量。只能釋放指針型的變量。而檢測內存時,照樣會出現內存泄漏現象。所以,這種內存檢測方式局限性還是很大。因為我們無法釋放非指針型變量。