?? visual c++編程技巧.txt
字號:
//Create a pen with the same color as a brush.
BOOL CreatePenFromBrush (Cpen&pen, cost Cbrush&brush)
{
LOGBRUSH stBrush;
brush.Getobject (sizeof (LOGBRUSH), &stBrush);
return pen. Createpen (PS_SOLID, 0, stBrush.ibColor);
}
--------------------------------------------------------------------------------
Visual C++編程技巧之七
49、如何實現一個橡皮區矩形
50、如何更新翻轉背景顏色的文本
51、如何創建一個具有特定點大小的字體
52、如何計算一個串的大小
53、如何顯示旋轉文本
54、如何正確顯示包含標簽字符的串
55、串太長時如何在其末尾顯示一個省略號
56、如何快速地格式化一個CString對象
49、如何實現一個橡皮區矩形
CRectTracker是一個很有用的類,可以通過調用CRectTracker:: TrackRubberBand響應WM_LBUTTONDOWN消息來創建一個橡皮區矩形。下例表明使用CRectTracker移動和重置視窗中的藍色橢圓的大小是很容易的事情。
首先,在文件檔中聲明一個CRectTracker數據成員:
class CSampleView : Public CView
{
…
public :
CrectTracker m_tracker;
…
};
其次,在文檔類的構造函數中初始化CRectTracker 對象:
CSampleDoc:: CSampleDOC ()
{
//Initialize tracker position, size and style.
m_tracker.m_rect.SetRect (0, 0, 10, 10);
m_tracker.m_nStyle=CRectTracker:: resizeInside |
CRectTracker:: dottedLine;
}
然后,在OnDraw函數中畫橢圓和蹤跡矩形:
void CSampleView:: OnDraw (CDC* pDC)
{
CSampleDoc* 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);
}
最后,使用ClassWizard處理WM_LBUTTONDOWN消息,并增加下述代碼。該段代碼根據鼠標擊鍵情況可以拖放、移動或者重置橢圓的大小。
void CSampleView::OnLButtonDown (UINT nFlags, CPoint point)
{
//Get pointer to document.
CSampleDoc* 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);
}
50、如何更新翻轉背景顏色的文本
調用CDC:: SetBkmode并傳送OPAQUE用當前的背景顏色填充背景,或者調用CDC::SetBkMode并傳送TRANSPAARENT使背景保持不變,這兩種方法都可以設置背景模式。下例設置背景模式為TRANSPARENT,可以兩次更新串,用花色帶黑陰影更新文本。黑色串在紅色串之后,但由于設置了背景模式仍然可見。
void CSampleView:: OnDraw (CDC* pDC)
{
//Determint size of view.
CRect rcView;
GetClientRect (rcVieew);
//Create sample string to display.
CString str (_T ("Awesome Shadow Text..."));
//Set the background mode to transparent.
pDC->SetBKMode (TRANSPARENT);
//Draw black shadow text.
rcView.OffsetRect (1, 1);
pDc->SetTextColor (RGB (0, 0, 0));
pDC->DrawText (str, str.GetLength (), rcView,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
//Draw red text.
rcView.OffsetRect (-1,-1);
pDc->SetTextColor (RGB (255, 0, 0));
pDC->DrawText (str, str.GetLength (), rcView,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
51、如何創建一個具有特定點大小的字體
可以指定字體邏輯單位的大小,但有時指定字體的點的大小可能會更方便一些。可以如下將字體的點轉換為字體的高度:
int nHeigth=mulDiv (nPointSize, -dc.GetDeviceCaps (LOGPIXELSY), 72);
下例創建了一個8點的Apial字體:
CClientDC dc (AqfxGetMainWnd ());
m_font. CreateFont (MulDiv (8, -dc.GetDeviceCaps (LOGPIXELSY),
72),0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,
OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY,
VARIABLE_PITCH | FF-SWISS,_T ("Arial"));
52、如何計算一個串的大小
函數CDC:: Det text Extent 根據當前選擇的字體計算一個串的高度和寬度。如果使用的不是系統字體而是其他字體,則在調用GetTextExtent之前將字體選進設備上下文中是很重要的,否則計算高度和寬度時將依據系統字體,由此得出的結果當然是不正確的。下述樣板程序當改變下壓按鈕的標題時動態調整按鈕的大小,按鈕的大小由按鈕的字體和標題的大小而定。響應消息WM_SETTEXT時調用OnSetText,該消息使用ON_MESSAE宏指令定義的用戶自定義消息。
LRESULT CMyButton:: OnSettext (WPARAM wParam, LPARAM lParam)
{
//Pass message to window procedure.
LRESULT bResult=CallWindowProc (*GetSuperWndProcAddr (),
m_hWnd, GetCurrentMessage () ->message,wParam,lParam);
//Get title of push button.
CString strTitle;
GetWindowText (strTitle);
//Select current font into device context.
CDC* pDC=GetDc ();
CFont*pFont=GetFont ();
CFont*pOldFont=pDC->SelectObject (pFont);
//Calculate size of title.
CSize size=pDC->GetTextExent (strTitle,strTitle.GetLength ());
//Adjust the button's size based on its title.
//Add a 5-pixel border around the button.
SetWindowPos (NULL, 0, 0, size.cx+10, size.cy+10,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
//Clean up.
pDC->SelectFont (pOldFont);
ReleaseDC (pDC);
return bResult;
}
53、如何顯示旋轉文本
只要用戶使用TrueType或者GDI筆或字體就可以顯示旋轉文本(有些硬件設備也支持旋轉光柵字體)。LOGFONT結構中的ifEscapement成員指定了文本行和x軸的角度,角度的單位是十分之一度而不是度,例如,ifEscapement為450表示字體旋轉45度。為確保所有的字體沿坐標系統的同一方向旋轉,一定要設置ifEscapement成員的CLIP_LH_ANGLES位,否則,有些字體可能反向旋轉。下例使用了14點Arial字體每間隔15度畫一個串。
void CSampleView:: OnDraw (CDC* pDC)
{
//Determine the size of the window.
CRect rcClient;
GetClientRect (rcClient);
//Create sample string.
CString str (_T ("Wheeee...I am rotating!"));
//Draw transparent, red text.
pDC->SetBkMode (TRANSPARENT);
pDC->SetTextColor (RGB (255,0,0));
CFont font; //font object
LOGFONT stFont; //font definition
//Set font attributes that will not change.
memset (&stFont, 0, sizeof (LOGFONT));
stFont.ifheight=MulDiv (14, -pDC->GetDeviceCaps (LOGPIXELSY), 72);
stFont.ifWeight=FW_NORMAL;
stFont.ifClipPrecision=LCIP_LH_ANGLES;
strcpy (stFont.lfFaceName, "Arial");
//Draw text at 15degree intervals.
for (int nAngle=0; nAngle<3600; nAngle+=150)
{
//Specify new angle.
stFont.lfEscapement=nAngle;
//Create and select font into dc.
font.CreateFontIndirect (&stfont);
CFont* pOldFont=pDC->SelectObject (&font);
//Draw the text.
pDC->SelectObject (pOldFont);
font.DelectObjext ();
}
}
54、如何正確顯示包含標簽字符的串
調用GDI文本繪畫函數時需要展開標簽字符,這可以通過調用CDC:: TabbedTextOut或者CDC:: DrawText并指定DT_EXPANDTABS標志來完成。TabbedTextOut函數允許指定標簽位的數組,下例指定每20設備單位展開一個標簽:
void CSampleView:: OnDraw (CDC* pDC)
{
CTestDoc* pDoc=GetDocument ();
ASSERT_VALID (pDoC);
CString str;
str.Format (_T ("Cathy\tNorman\tOliver"));
int nTabStop=20; //tabs are every 20 pixels
pDC->TabbedtextOut (10, 10, str, 1, &nTabStop, 10);
}
55、串太長時如何在其末尾顯示一個省略號
調用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);
}
56、如何快速地格式化一個CString對象
調用CString:: Format,該函數和printf函數具有相同的參數,下例說明了如何使用Format函數:
//Get size of window.
CRect rcWindow;
GetWindowRect (rcWindow);
//Format message string.
CString strMessage;
strMessage.Format (_T ("Window Size (%d, %d)"),
rcWindow.Width (), rcWindow.Height ());
//Display the message.
MessageBox (strmessage);
--------------------------------------------------------------------------------
Visual C++編程技巧之八
57、為什么即使調用EnableMenuItem菜單項后,菜單項還處于禁止狀態
58、如何給系統菜單添加一個菜單項
59、如何確定頂層菜單所占據的菜單行數
60、在用戶環境中如何確定系統顯示元素的顏色
61、如何查詢和設置系統參數
62、如何使用一個預定義的Windows光標
63、如何確定當前屏幕分辨率
64、如何檢索原先的Task Manager應用程序使用的任務列表
65、如何確定Windows和Windows系統目錄
66、在哪兒創建臨文件
67、如何訪問桌面窗口
57、為什么即使調用EnableMenuItem菜單項后,菜單項還處于禁止狀態
需要將CFrameWnd:: m_bAutomenuEnable設置為FALSE,如果該數據成員為TRUE(缺省值),工作框將自動地禁止沒有ON_UPDATE_COMMAND_UI或者ON_COMMAND的菜單項。
//Disable MFC from automatically disabling menu items.
m_bAuoMenuEnable=FALSE;
//Now enable the menu item.
CMenu* pMenu=GetMenu ();
ASSERT_VALID (pMenu);
pMenu->EnableMenuItem (ID_MENU_ITEM,MF_BYCOMMAND | MF_ENABLED);
58、如何給系統菜單添加一個菜單項
給系統菜單添加一個菜單項需要進行下述三個步驟:
首先,使用Resource Symbols對話(在View菜單中選擇Resource Symbols...
可以顯示該對話)定義菜單項ID,該ID應大于0x0F而小于0xF000;
其次,調用CWnd::GetSystemMenu獲取系統菜單的指針并調用CWnd:: Appendmenu將菜單項添加到菜單中。下例給系統菜單添加兩個新的菜單項:
int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)
{
…
//Make sure system menu item is in the right range.
ASSERT (IDM_MYSYSITEM &0xFFF0)==IDM_MYSYSITEM);
ASSERT (IDM-MYSYSITEM<0xF000);
//Get pointer to system menu.
CMenu* pSysmenu=GetSystemmenu (FALSE);
ASSERT_VALID (pSysMenu);
//Add a separator and our menu item to system menu.
CString StrMenuItem (_T ("New menu item"));
pSysMenu->Appendmenu (MF_SEPARATOR);
pSysMenu->AppendMenu (MF_STRING, IDM_MYSYSITEM, strMenuitem);
…
}
現在,選擇系統菜單項時用戶應進行檢測。使用ClassWizard處理
WM_SYSCOMMAND消息并檢測用戶菜單的nID參數:
void CMainFrame:: OnSysCommand (UINT nID,LPARAM lParam)
{
//Determine if our system menu item was selected.
if ( (nID & 0xFFF0)==IDM_MYSYSITEM)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -