(4) 获得各种目录信息 Windows目录: Use "GetWindowsDirectory" Windows下的system目录: Use "GetSystemDirectory" temp目录: Use "GetTempPath" 当前目录: Use "GetCurrentDirectory"
请注意前两个函数的第一个参数为目录变量名,后一个为缓冲区后两个相反.
(5) 如何自定义消息 1) 手工定义消息,可以这么写 #define WM_MY_MESSAGE(WM_USER+100), MS 推荐的至少是 WM_USER+100
(8) 如何将窗口居中显示? Call Function CWnd:: Center Windows
Example(1): Center Window( ) //Relative to it's parent // Relative to Screen Example(2): Center Window(CWnd:: GetDesktopWindow( )) //Relative to Application's MainWindow AfxGetMainWnd( ) -> Center Window( )
//Fool frame window into thinking somene clicked on its caption bar . GetParentFrame ( ) —> PostMessage ( WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARAM (poitn .x , point .y) )
} 该技术也适用于对话框和基于对的应用程序,只是不必调用 CWnd: :GetParentFrame 。 void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point ) { Cdialog : : OnLButtonDow (nFlags, goint ) //Fool dialog into thinking simeone clicked on its caption bar . PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x , point. y ) ) }
(18) 如何改变视窗的背景颜色 Windows向窗口发送一个WM_ERASEBKGND消息通知该窗口擦除背景,可以使用ClassWizard重载该消息的缺省处理程序来擦除背景(实际是画),并返回TRUE以防止Windows擦除窗口。 //Paint area that needs to be erased. BOOL CSampleView : : OnEraseBkgnd (CDC* pDC) { // Create a pruple brush. CBrush Brush (RGB (128 , 0 , 128) )
// Select the brush into the device context . CBrush* pOldBrush = pDC—>SelcetObject (&brush)
// Get the area that needs to be erased . CRect reClip pDC—>GetCilpBox (&rcClip) //Paint the area. pDC—> PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )
//Unselect brush out of device context . pDC—>SelectObject (pOldBrush )
其次,需要正确删除表示对话的C++对象。对于模式对来说,这很容易,需要创建函数返回后即可删除C++对象;无模式对话不是同步的,创建函数调用后立即返回,因而用户不知道何时删除C++对象。撤销窗口时工作框调用CWnd : : PostNcDestroy,可以重置该函数并执行清除操作,诸如删除this指针。 void CSampleDialog : : PostNcDestroy ( ) { // Declete the C++ object that represents this dialog. delete this
//Use background color for tooltips brush. CBrush * pOrgBrush=pDC->SelectObject ( CBrush ::FromHandle( ::GetSysColorBrush (COLOR_INFOBK)))
//Draw the ellipse. pDC->Ellipse (rcView)
//Restore original brush. pDC->SelectObject (pOrgBrush) }
(52) 如何获取GDI对象的属性信息 可以调用GDIObject:: GetObject。这个函数将指定图表设备的消息写入到缓冲区。下例创建了几个有用的辅助函数。 //Determine if font is bold. BOOL IsFontBold (const CFont&font) { LOGFONT stFont font.GetObject (sizeof (LOGFONT), &stFont) return (stFont.lfBold)? TRUE: FALSE }
//Return the size of a bitmap. CSize GetBitmapSize (const CBitmap&bitmap) { BITMAP stBitmap bitmap.GetObject (sizeof (BITMAP), &stBitmap) return CSize (stBitmap.bmWidth, stBitmap.bmHeight) }
//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) }
//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) }
(56) 如何计算一个串的大小 函数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)
//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) }
(62) 如何给系统菜单添加一个菜单项 给系统菜单添加一个菜单项需要进行下述三个步骤: 首先,使用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) { //TODO-process system menu item }
//Create a font that is used for icon titles. LOGFONT stFont ∶: SystemParametersInfo (SPIF_GETICONTITLELOGFONT, sizeof (LOGFONT), &stFont, SPIF_SENDWININICHANGE) m_font.CreateFontIndirect (&stFont)
//Change the wallpaper to leaves.bmp. ∶ : SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, _T (" forest.bmp"), SPIF_UPDATEINIFILE)
void GetTadkList (CListBox&list) { CString strCaption //Caption of window.
list.ResetContent () //Clear list box.
//Get first Window in window list. ASSERT_VALID (AfxGetMainWnd ()) CWnd* pWnd=AfxGetMainWnd () ->GetWindow (GW_HWNDFIRST)
//Walk window list. while (pWnd) { // I window visible, has a caption, and does not have an owner? if (pWnd ->IsWindowVisible() && pWnd ->GetWindowTextLength () &&! pWnd ->GetOwner ()) {
//Add caption o window to list box.
pWnd ->GetWindowText (strCaption)
list.AddString (strCaption) } //Get next window in window list. pWnd=pWnd ->GetWindow(GW_HWNDNEXT) } }
TCHAR szDir [MAX_PATH] //Get the full path of the windows directory. ∶ : GetWindowsDirectory (szDir, MAX_PATH) TRACE ("Windows directory %s\n", szDir) //Get the full path of the windows system directory. ∶ : GetSystemDirectory (szDir, MAX_PATH) TRACE ("Windows system directory %s\n", szDir)
我创建了一个简单的mdi应用程序,使用.BSF(自定义的文档扩展名)作为它的文档我保存一个foo.bsf文档后,可以在资源管理器中双击该文件打开mdi应用程序同时打开foo.bsf文档.但当我给mdi应用程序加上a tip of the day组件之后,从资源管理器中双击foo.bsf后,就会给我一个警告:ASSERT(::IsWindow(m_hWnd)),然后mdi应用程序就死那了.
当从dde启动应用程序(例如:双击相关文档)时,"Tip of the Day"是有bug的.你可以看看函数"ShowTipAtStartup",它在"InitInstance"中调用,可以看到tip of the day作为一个模式对话框显示,在处理其它消息时它一直进行消息循环你可心修改ShowTipAtStartup使其从dde启动时不出现tip of the day. void CTipOfApp::ShowTipAtStartup(void) { // CG: This function added by 'Tip of the Day' component.