专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »博文摘选 » vc用法:VC使用方法汇总 »正文

vc用法:VC使用方法汇总

来源: 发布时间:星期一, 2009年11月30日 浏览:0次 评论:0
 

VC使用方法汇总
(1)如何通过代码获得应用主窗口指针?
主窗口指针保存在CWinThread::m_pMainWnd中,AfxGetMainWnd实现
AfxGetMainWnd ->ShowWindow(SW_SHOWMAXMIZED)
//使最大化.


(2)确定应用路径
Use GetModuleFileName 获得应用路径然后去掉可执行文件名
Example:
TCHAR
exeFullPath[MAX_PATH] // MAX_PATH在API中定义了吧好象是
128
GetModuleFileName(NULL,exeFullPath,MAX_PATH)



(3)如何在中获得其他图标?
两种思路方法:
(1) SDK SHGetFileInfo 或使用 ExtractIcon获得图标资源 handle,
(2) SDK SHGetFileInfo 获得有关文件很多信息,如大小图标,属性, 类型等.
Example(1):
窗口左上角显示 NotePad图标.
void CSampleView:
OnDraw(CDC * pDC)
{
( :: SHGetFileInfo(_T("c:""pwin95""notepad.exe"),0,
&stFileInfo,(stFileInfo),SHGFI_ICON))
{
pDC ->DrawIcon(10,10,stFileInfo.hIcon)
}
}
Example(2):同样功能,Use ExtractIcon Function
void CSampleView:: _disibledevent=>("NotePad.exe"),0)
(hIcon &&hIcon!=(HICON)-1)
pDC->DrawIcon(10,10,hIcon)
}
介绍说明: 获得notepad.exe路径正规上来说用GetWindowsDirectory得到, 如果是 win95下画笔应该用访问注册表思路方法获得其路径要作成个比较考究考虑应该全面点.

(4)获得各种目录信息
Windows目录: Use "GetWindowsDirectory"
Windows下system目录: Use "GetDirectory"
temp目录: Use "GetTempPath"
当前目录: Use "GetCurrentDirectory"

请注意前两个个参数为目录变量名个为缓冲区后两个相反.


(5)如何自定义消息
1) 手工定义消息可以这么写
# WM_MY_MESSAGE(WM_USER+100),
MS 推荐至少是 WM_USER+100

2)写消息处理,用
WPARAM,LPARAM返回LRESULT.
LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)

{
temp目录: Use "GetTempPath"
//加入你处理 irectory"
}

(6)如何改变窗口图标?
向窗口发送 WM_SETICON消息
Example:
HICON hIcon=AfxGetApp ->LoadIcon(IDI_ICON)
ASSERT(hIcon)
AfxGetMainWnd ->SendMessage(WM_SETICON,TRUE,(LPARAM)hIcon)


(7)如何改变窗口缺省风格?
重载 CWnd:: PreCreateWindow 并修改CREATESTRUCT结构来指定窗口风格和其他创建信息.
Example: Delete "Max" Button and Set Original
Window's Position and Size

BOOL CMainFrame:: PreCreateWindow
(CREATESTRUCT &cs)
{
cs.style &=~WS_MAXINIZEMOX

cs.x=cs.y=0
cs.cx=GetMetrics(SM_CXSCREEN/2)
cs.cy=GetMetrics(SM_CYSCREEN/2)

CMDIFramewnd ::PreCreateWindow(cs)
}

(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( )


(9)如何让窗口和 MDI窗口启动就最大化和最小化?
先说窗口
在 InitStance 中设定 m_nCmdShow取值.
m_nCmdShow=SW_SHOWMAXMIZED //最大化
m_nCmdShow=SW_SHOWMINMIZED //最小化
m_nCmdShow=SW_SHOWNORMAL //正常方式

MDI窗口:
如果是创建新应用,可以用MFC AppWizard Advanced 按钮并在MDI子窗口风格组中检测最大化或最小化还可以重载 MDI Window PreCreateWindow设置WS_MAXMIZE or WS_MINMIZE

如果从 CMDIChildWnd派生, _disibledevent=>
// Now specy the window style .
cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL)
bResult
}

(13)如何使保持极小状态?
这么办: 在恢复窗体大小时Windows会发送WM_QUERY-OPEN消息用 ClassWizard设置成员
OnQueryOpen ,add following code:

Bool CMainFrame:: _disibledevent=> (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest
}

上述技术有两点不利的处
是在窗口客户区域双击时窗口将极大;
其 2它不适合包含几个视窗主框窗口
还有种思路方法当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上使用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送个WM_NCLBUTTONDOWN信息和个单击测试HTCAPTION
void CSampleView : : _disibledevent=>
// Get the area that needs to be erased .
CRect reClip
pDC—>GetCilpBox (&rcClip)
//Pa the area.
pDC—> PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )

//Unselect brush out of device context .
pDC—>SelectObject (pOldBrush )

// Return nonzero to half fruther processing .
TRUE
}

(19)如何改变窗口标题
CWnd : : SetWindowText可以改变任何窗口(包括Control控件)标题
//Set title for application's frame window .
AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") )

//Set title for View's MDI child frame window .
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame title")
)

//Set title for dialog's push button control.
GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button title ") )
如果需要经常修改窗口标题(注:Control控件也是窗口)应该考虑使用半文档化AfxSetWindowText在AFXPRIV.H中介绍说明在WINUTIL.CPP中实现在联机帮助中找不到它它在AFXPRIV.H中半文档化在以后发行MFC中将文档化
AfxSetWindowText实现如下:
voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew )
{
itn nNewLen= Istrlen (Ipaz)
TCHAR szOld [256]
//fast check to see text really changes (reduces
flash in the
controls )
(nNewLen >_contof (szOld)
|| : : GetWindowText (hWndCrtl, szOld , _countof (szOld) !=nNewLen
|| Istrcmp (szOld , IpszNew)! = 0
{
//change it
: : SetWindowText(hWndCtrl , IpszNew )
}
}

(20)如何防止主框窗口在其介绍说明中显示活动文档名
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位如果不希望在介绍说明中自动添加文档名必须禁止该风格位可以使用ClassWizard重置
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in frame .
cs.styel & = ~FWS_ADDTOTITLE  
CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口FWS _ADDTOTITLE风格将创建个具有空标题窗口可以CWnd: : SetWindowText来设置标题记住自己设置标题时要遵循接口风格指南

(21)如何获取有关窗口正在处理当前消息信息
CWnd: : GetCurrentMessage可以获取个MSG指针例如可以使用ClassWizard将几个菜单项处理映射到然后GetCurrentMessage来确定所选中菜单项
viod CMainFrame : : _disibledevent=>—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

//Get poer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)

(23)如何使能和禁止工具条工具提示
如果设置了CBRS_TOOLTIPS风格位工具条将显示工具提示要使能或者禁止工具提示需要设置或者清除该风格位下例通过CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立个完成此功能成员:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)

DWORD dwStyle = m _wndToolBar.GetBarStyle ( )

(bDisplayTips) dwStyle |=CBRS_TOOLTIPS


dwStyle & = ~CBRS_TOOLTIPS

m_wndToolBar.SetBarStyle (dwStyle )
}

(24)如何创建个不规则形状窗口
可以使用新SDKSetWindowRgn将绘画和鼠标消息限定在窗口个指定区域实际上使窗口成为指定不规则形状使用AppWizard创建个基于对应用并使用资源编辑器从主对话资源中删除所在缺省Control控件、标题以及边界
给对话类增加个CRgn数据成员以后要使用该数据成员建立窗口区域
Class CRoundDlg : public CDialog
{

private :
Crgn m_rgn : // window region

}
修改OnInitDialog建立个椭圆区域并SetWindowRgn将该区域分配给窗口:
BOOL CRoundDlg : : _disibledevent=>BYTE byRed =GetRValue (color)
BYTE byGreen = GetGValue (color)
BYTE byBlue = GetBValue (color)

// get the size of the view window
Crect rect
GetClientRect (rect)

// get minimun number of units
nUnits =min (rect.right , rect.bottom )

//calculate he horiaontal and vertical step size
float fltStepHorz = (float) rect.right /nUnits
float fltStepVert = (float) rect.bottom /nUnits


nEllipse = nUnits/3 // calculate how many to
draw
nIndex
// current ellipse that is being draw

CBrush brush
// bursh used for ellipse fill color
CBrush *pBrushOld // previous
brush that was selected o dc
//draw ellipse , gradually moving towards upper-right
corner
for (nIndex = 0 nIndes < + nEllipse nIndes)
{
//creat solid brush
brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ).
( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue)
/nEllipse ) ) )

//select brush o dc
pBrushOld= dc .SelectObject (&brhsh)

//draw ellipse
dc .Ellipse ( () fltStepHorz * 2, () fltStepVert * nIndex ,
rect. right -( () fltStepHorz * nIndex )+ 1,
rect . bottom -( () fltStepVert * (nIndex *2) ) +1)

//delete the brush
brush.DelecteObject ( )
}
}

最后处理WM_NCHITTEST消息使当击打窗口任何位置时能移动窗口
UINT CRoundDlg : : _disibledevent=>rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest

}

(25)如何获取应用例子句柄?
应用例子句柄保存在CWinApp m_hInstance 中,可以这么AfxGetInstancdHandle获得句柄.
Example: HANDLE hInstance=AfxGetInstanceHandle

(26)如何编程结束应用?
这是个很简单又是编程中经常要遇到问题.
向窗口发送 WM_CLOSE消息, CWnd::OnClose成员.允许对用户提示是否保存修改过数据.
Example: AfxGetMainWindow->SendMessage(WM_CLOSE)

还可以创建个自定义 Terminate Window
void Terminate Window(LPCSTR pCaption)
{
CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption)

(pWnd)

pWnd ->SendMessage(WM_CLOSE)
}

介绍说明: FindWindow不是提倡做法它无法处理标题栏自动改变比如我们要检测 Notepad是不是已运行而事先不知道Notepad标题栏,这时FindWindow就无能为力了可以通过枚举 windows任务列表办法来实现在机械出版社"Windows 95 API开发人员指南"书有比较详细介绍,这里就不再多说乐

(27)如何创建和使用无模式对话框
MFC将模式和无模式对话封装在同个类中但是使用无模式对话需要几个对话需要几个额处步骤首先使用资源编辑器建立对话资源并使用ClassWizard创建个CDialog派生类模式和无模式对话中止是不:模式对话通过CDialog : : EndDialog 来中止无模式对话则是CWnd: : DestroyWindow来中止CDialog : : _disibledevent=>ASSERT_VALID (pDialog) Destroy ( )

//Create the modeless dialog . represents this dialog.
BOOL bResult = pDialog —> Creste (IDD_IDALOG)
ASSERT (bResult )
}

(28)如何防止主框窗口在其介绍说明中显示活动文档名
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位如果不希望在介绍说明中自动添加文档名必须禁止该风格位可以使用ClassWizard重置
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in frame .
cs.styel & = ~FWS_ADDTOTITLE  
CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口FWS _ADDTOTITLE风格将创建个具有空标题窗口可以CWnd: : SetWindowText来设置标题记住自己设置标题时要遵循接口风格指南

(29)如何在代码中获取工具条和状态条指针
缺省时工作框创建状态条和工具条时将它们作为主框窗口子窗口状态条有个AFX_IDW_STATUS_BAR标识符工具条有个AFX_IDW_TOOLBAR标识符下例介绍说明了如何通过CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口指针:
//Get poer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

//Get poer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)


(30)怎样加载其他应用?
3个SDK winexec, shellexecute,createprocess可以使用
WinExec最简单两个参数个指定路径个指定显示方式.后个参数值得说比如泥用 SW_SHOWMAXMIZED方式去加载个无最大化按钮就是Neterm,calc等等就不会出现正常窗体但是已经被加到任务列表里了

ShellExecute较 WinExex灵活可以指定工作目录,下面Example就是直接打开 c:"temp"1.txt,而不用加载和 txt文件关联应用,很多安装完成后都会打开个窗口来显示Readme or Faq,我猜就是这么作啦.

ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:""temp"),SW_SHOWMAXMIZED)

CreateProcess最复杂共有十个参数不过大部分都可以用NULL代替它可以指定进程安全属性继承信息优先级等等.来看个很简单Example:
STARTUPINFO stinfo
//启动窗口信息
PROCESSINFO procinfo //进程信息

CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,
NORMAL_PRIORITY_

CLASS,NULL,NULL, &stinfo,&procinfo)

(31)如何在代码中获取工具条和状态条指针
缺省时工作框创建状态条和工具条时将它们作为主框窗口子窗口状态条有个AFX_IDW_STATUS_BAR标识符工具条有个AFX_IDW_TOOLBAR标识符下例介绍说明了如何通过CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口指针:
//Get poer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

(32)如何使能和禁止工具条工具提示
如果设置了CBRS_TOOLTIPS风格位工具条将显示工具提示要使能或者禁止工具提示需要设置或者清除该风格位下例通过CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立个完成此功能成员:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)

DWORD dwStyle = m _wndToolBar.GetBarStyle ( )

(bDisplayTips) dwStyle |=CBRS_TOOLTIPS


dwStyle & = ~CBRS_TOOLTIPS

m_wndToolBar.SetBarStyle (dwStyle )
}

//Get poer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)

(33)如何设置工具条标题
工具条是个窗口所以可以在CWnd : : SetWindowText来设置标题例子如下:
CMainFrame : : _disibledevent=> (HBRUSH) m_brush.GetSafeHandle ( )
CFormView : : _disibledevent=> nReslt = DlgDirListComboBox (szPath, IDC_COMBO , IDC_CURIDIR, DDL_READWRITE |DDL_READONLY|DDL_HIDDEN| DDL_SYSTEM|DDL_ARCHIVE)
TRUE
}

(42)为什么旋转按钮Control控件看起来倒转
需要CSpinCtrl : : SetRange 设置旋转按钮Control控件范围旋转按钮Control控件缺省上限为0缺省下限为100这意味着增加时旋转按Control控件值由100变为0下例将旋转按钮Control控件范围设置为0到100:
BOOL CAboutDlg : : _disibledevent=>ASSERT_VALID (m_pButton)
m_pButton —>Create (_T ("Button Title ") , WS_CHILD |WS_VISIBLE |BS_PUSHBUTTON. Crect ( 0, 0, 100 , 24) , this , IDC _MYBUTTON )

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

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

//In you dialog implementation (.CPP file )
BOOL CSampleDialog : : _disibledevent=>
//Bypass default _disibledevent=>
//Draw red text for all edit controls .
(nCtlColor= = CTLCOLOR_EDIT )
pDC —> SetTextColor (RGB (255, 0 , 0 , ) )

hbr
}

然而由于每个父窗口必须处理通知消息并指定每个Control控件绘画属性所以这种思路方法不是完全面向对象思路方法Control控件处理该消息并指定绘画属性更合情合理消息反射允许用户这样做通知消息首先发送给父窗口如果父窗口没有处理则发送给Control控件创建个定制彩色列表框Control控件必须遵循下述步骤

首先使用ClassWizard 创建个CListBox 派生类并为该类添加下述数据成员
CMyListBox publilc CListBox
{

private
COLORREF m_clrFor // foreground color
COLORREF m_clrBack //background color
Cbrush m_brush //background brush

}
其次在类构造化数据中
CMyListBox : : CMyListBox
{
//Initialize data members .
m_clrFore =RGB (255 , 255 , 0) //yellow text
m_clrBack=RGB (0 , 0 , 255) // blue background
m_brush . CreateSolidBrush (m _clrBack )
}

最后使用ClassWizard处理反射WM_CTLCOLOR(=WM_CTLCOLOR)消息并指定新绘画属性
HBRUSH CMyListBox : : CtlColor (CDC* pDC, UINT nCtlColor )
{
pDC—>SetTextColor (m_clrFore)
pDC—>SetBkColor (m_clrBack)

(HBRUSH) m_brush.GetSafeHandle
}
现在Control控件可以自己决定如何绘画和父窗口无关

(49)当向列表框中添加多个项时如何防止闪烁
CWnd::SetRedraw 清除重画标志可以禁止CListBox(或者窗口)重画当向列表框添加几个项时用户可以清除重画标志然后添加项最后恢复重画标志为确保重画列表框新项SetRedraw (TRUE) 的后CWnd::Invalidate

//Disable redrawing.
pListBox->SetRedraw (FALSE)

//Fill in the list box gere
//Enable drwing and make sure list box is redrawn.
pListBox->SetRedraw (TRUE)
pListBox->Invalidate

(50)如何向编辑Control控件中添加文本
由于没有CEdit:: AppendText用户只好自己做此项工作CEdit:: SetSel移动到编辑Control控件末尾然后CEdit:: ReplaceSel添加文本下例是AppendText 种实现思路方法:

void CMyEdit:: AppendText (LPCSTR pText)
{
nLen=GetWindowTextLength
SetFocus
SetSel (nLen, nLen)

ReplaceSel (pText)
}

(51)如何访问预定义GDI对象
可以通过CDC:: SlectStockObject使用Windows几个预定义对象诸如刷子、笔以及字体下例使用了Windows预定义笔和刷子GDI对象在视窗中画个椭圆
//Draw ellipse using stock black pen and gray brush.
void CSampleView:: _disibledevent=>
//Draw the ellipse.
pDC->Ellipse (rcView)

//Restore original brush.
pDC->SelectObject (pOrgBrush)
}

(52)如何获取GDI对象属性信息
可以GDIObject:: GetObject这个将指定图表设备消息写入到缓冲区下例创建了几个有用辅助
//Determine font is bold.
BOOL IsFontBold (const CFont&font)
{
LOGFONT stFont
font.GetObject ( (LOGFONT), &stFont)
(stFont.lfBold)? TRUE: FALSE
}

//Return the size of a bitmap.
CSize GetBitmapSize (const CBitmap&bitmap)
{
BITMAP stBitmap
bitmap.GetObject ( (BITMAP), &stBitmap)
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 ( (LOGBRUSH), &stBrush)
pen. Createpen (PS_SOLID, 0, stBrush.ibColor)
}

(53)如何实现个橡皮区矩形
CRectTracker是个很有用可以通过CRectTracker::TrackRubberBand 响应WM_LBUTTONDOWN消息来创建个橡皮区矩形
下例表明使用CRectTracker移动和重置视窗中蓝色椭圆大小是很容易事情

首先在文件档中声明个CRectTracker数据成员:
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:: _disibledevent=>ASSERT_VALID (pDoc)

//Select blue brush o 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, CPo po)
{
//Get poer to document.
CSampleDoc* pDoc=GetDocument
ASSERT_VALID (pDoc)

//If clicked _disibledevent=>
//Tracker rectangle changed so update views.
(bResult)
{
pDoc->m_tracker.Track (this,po,TRue)
pDoc->SetModiedFlag
pDoc->UpdateAllViews (NULL)
}


pDoc->m-tracker.TrackRubberBand(this,po,TRUE)
CView:: _disibledevent=>下例创建了个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"))

(56)如何计算个串大小
CDC:: Det text Extent 根据当前选择字体计算个串高度和宽度如果使用不是系统字体而是其他字体则在GetTextExtent的前将字体选进设备上下文中是很重要否则计算高度和宽度时将依据系统字体由此得出结果当然是不正确下述样板当改变下压按钮标题时动态调整按钮大小按钮大小由按钮字体和标题大小而定响应消息WM_SETTEXT时OnSetText该消息使用ON_MESSAE宏指令定义用户自定义消息

LRESULT CMyButton:: _disibledevent=>//Get title of push button.
CString strTitle
GetWindowText (strTitle)

//Select current font o 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 _disibledevent=>stFont.Weight=FW_NORMAL
stFont.ClipPrecision=LCIP_LH_ANGLES
strcpy (stFont.lfFaceName, "Arial")

//Draw text at 15degree ervals.
for ( nAngle=0 nAngle<3600 nAngle150)
{
//Specy angle.
stFont.lfEscapement=nAngle

//Create and select font o dc.
font.CreateFontIndirect(&stfont)
CFont* pOldFont=pDC ->SelectObject(&font)

//Draw the text.
pDC->SelectObject(pOldFont)
font.DelectObjext
}
}

(58)如何正确显示包含标签
GDI文本绘画时需要展开标签这可以通过CDC:: TabbedTextOut或者CDC:: DrawText并指定DT_EXPANDTABS标志来完成TabbedTextOut允许指定标签位下例指定每20设备单位展开个标签:

void CSampleView:: _disibledevent=>ASSERT_VALID (pDoC)

CString str
str.Format (_T ("Cathy"tNorman"tOliver"))
nTabStop=20 //tabs are every 20 pixels
pDC->TabbedtextOut (10, 10, str, 1, &nTabStop, 10)
}

(59)如何快速地格式化个CString对象
CString:: Format和prf具有相同参数下例介绍说明了如何使用Format:

//Get size of window.
CRect rcWindow
GetWindowRect (rcWindow)
//Format message .
CString strMessage
strMessage.Format (_T ("Window Size (%d, %d)"),

rcWindow.Width , rcWindow.Height )

//Display the message.
MessageBox (strmessage)

(60)串太长时如何在其末尾显示个省略号
CDC:: DrawText并指定DT_END_ELLIPSIS标志这样就可以用小略号取代串末尾使其适合于指定边界矩形如果要显示路径信息指定DT_END_ELLIPSIS标志并省略号取代串中间

void CSampleView:: _disibledevent=>ASSERT_VALID (pDoc)

//Add ellpsis to end of it does not fit
pDC->Drawtext (CString ("This is a long "), CRect (10, 10, 80, 30), DT_LEFT | DT_END_ELLIPSIS)

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

(61)为什么即使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)

(62)如何给系统菜单添加个菜单项
给系统菜单添加个菜单项需要进行下述 3个步骤:
首先使用Resource Symbols对话(在View菜单中选择Resource Symbols...可以显示该对话)定义菜单项ID该ID应大于0x0F而小于0xF000;
其次CWnd::GetMenu获取系统菜单指针并CWnd:: Appendmenu将菜单项添加到菜单中下例给系统菜单添加两个新
CMainFrame:: _disibledevent=>ASSERT (IDM-MYSYSITEM<0xF000)

//Get poer to system menu.
CMenu* pSysmenu=Getmenu (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:: _disibledevent=>{
//TODO-process system menu item
}


CMDIFrameWnd ::OnSysCommand (nID, lParam)
}
最后个设计良好UI应用应当在系统菜单项加亮时在状态条显示个帮助信息这可以通过增加个包含系统菜单基ID串表入口来实现

(63)如何确定顶层菜单所占据菜单行数
这可以通过简单减法和除法来实现首先用户需要计算主框窗口高度和客户区;其次从主框窗口高度中减去客户区、框边界以及标题高度;最后除以菜单栏高度下例成员个计算主框菜单所占据行数代码实现

CMainFrame:: GetMenuRows
{
CRect rcFrame,rcClient
GetWindowRect (rcFrame)
GetClientRect (rcClient)
(rcFrame.Height -rcClient.Height - :: GetMetrics(SM_CYCAPTION) - (:: getMetrics(SM_CYFRAME) *2)) / :: GetMetrics(SM_CYMENU)
}

(64)在用户环境中如何确定系统显示元素颜色
SDKGetSysColor可以获取个特定显示元素颜色下例介绍说明了如何在MFCCMainFrameWnd:: _disibledevent=>
//Walk window list.
while (pWnd)
{
// I window visible, has a caption, and does not have an owner?
(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)
}
}

(69)如何确定Windows和Windows系统目录
有两个SDK可以完成该功能GetWindowsDirectory和GetDirectory下例介绍说明了如何使用这两个:

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.
∶ : GetDirectory (szDir, MAX_PATH)
TRACE ("Windows system directory %s"n", szDir)

(70)在哪儿创建临文件
SDKGetTemPath可以确定临时文件目录首先为临时路径检测TMP环境变量:如果没有指定TMP检测TMP环境变量然后返回到当前目录下例介绍说明了如何创建个临时文件


//get unique temporary file.
CString strFile
GetUniqueTempName (strFile)
TRY
{
//Create file and write data.Note that file is closed
//in the destructor of the CFile object.
CFile file (strFile,CFile ::modeCreate | CFile:: modeWrite)

//write data
}

CATCH (CFileException, e)
{
//error opening file
}
END_CATCH


Void GetuniqueTempName (CString& strTempName)
{
//Get the temporary files directory.
TCHAR szTempPath [MAX_PATH]
DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath)
ASSERT (dwResult)

//Create a unique temporary file.
TCHAR szTempFile [MAX_PATH]
UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempfile)
ASSERT (nResult)

strTempName=szTempFile
}

(71)我怎样才能建立个等待光标?
BeginWaitCursor 来启动等待光标 EndWaitCursor 来结束等待光标要注意 2者都要 app 成员如下所示:

AfxGetApp->BeginWaitCursor;
// 要做
AfxGetApp->EndWaitCursor;

(72)我在MDI框架中有个 form 视窗它有个取消按钮我需要当用户按取消按钮时可关闭form视窗我应该如何关闭该文档?
_disibledevent=>HWND hWnd= :: GetWindow (:: GetDesktopWindow, GW_CHILD)
while (hWnd!=NULL)
{
(:: IsWindowEnabled (hwnd)
&& CWnd::FromHandlePermanent (hWnd)!=NULL
&& AfxIsDescendant (pParent->m_hWnd, hWnd)
&& :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)0)
{
nCount
}
hWnd=:: GetWindow (hWnd, GW_HWNDNEXT)
}


(74)什么是COLORREF? 我该怎样用它?
COLORREF 是个 32-bit 整型数值它代表了种颜色你可以使用 RGB 化 COLORREF例如:

COLORREF color = RGB(0, 255, 0);
RGB 接收 3个 0-255 数值个代表红色个代表绿色个代表蓝色在上面例子中红色和蓝色值都为 0所以在该颜色中没有红色和蓝色绿色为最大值 255所以该颜色为绿色0,0,0 为黑色255,255,255 为白色

化 COLORREF 思路方法如下所示:

CColorDialog colorDialog;
COLORREF color;

( colorDialog.DoModal IDOK )
{
color = colorDialog.GetColor;
}
这段代码使用了 MFC 中颜色对话框它需要文件

(75)AppWizard所产生STDAFX文件是干什么用?
它主要是协助产生预编译头文件通常你是不需要修改它

(76)我在我中是了CDWordArray我向它添加了约10,000个整数这使得它变得非常非常慢为什么会这么糟?
CDWordArray 是很好用只是你没有指定最大尺寸因此当你添加新元素时该类会从堆中重新分配空间不幸该类会在每次插入新元素时都为重新分配空间如果你向它添加了很多新元素所有这些分配和复制操作会就会使它变慢解决该问题思路方法是你可以使用 SetSize 第 2个参数来改变这种重新分配频率例如如果你把该参数设置为 500则每次空间超出时它才重新分配并添加 500 个新空间而不是 1 个这样你就可以不用重新分配而添加了另外 499 个元素空间这也会大大提高运行速度

(77)我该如何改变MDI框架窗口子窗口大小以使在窗口以大小打开?
在视中 _disibledevent=>app->MyGlobalVariable = ...

(80)我听说MFC可以发现内存漏洞我怎样使用该特性?
如果你在 Debug 菜单中 Go 选项 ( 不是 Project 菜单中 Execute 选项 ) 来运行你应用MFC 应该在终止时报告内存漏洞如果没有那么试试运行 MFC Tracer 工具 ( 在 VC 组中 )并启动跟踪然后返回应用

(81)我怎样才能在我应用中循环浏览已经打开文档?
使用CDocTemplate中未公开GetFirstDocPosition和GetNextDoc

(82)才能在我应用中循环浏览已经打开视?
使用 CDocument 中未公开 GetFirstViewPosition 和 GetNextView

(83)数PreCreateWindow是干什么用?
PreCreateWindow 允许你在 CreateWindow 的前来改变窗口属性

(84)该怎样防止MFC在窗口标题栏上把文档名预置成应用名?
在 PreCreateWindow 中删除 FWS_PREFIXTITLE 标志窗口样式:

cs.style &= ~FWS_PREFIXTITLE;

(85)我应该怎样防止MFC在窗口标题栏上添加文档名?
在 PreCreateWindow 中删除 FWS_ADDTOTITLE 标志窗口样式:

cs.style &= ~FWS_ADDTOTITLE ;

(86)我应该如何改变视窗口大小?
视窗口实际上是框架窗口子窗口所以你必须改变框架窗口大小而不是改变视窗口使用 CView 类中 GetParentFrame 获得指向框架窗口指针然后 MoveWindow 来改变框架大小这会使变尺寸视充满框架窗口

(87)我有无模式对话框我怎样才能在窗口退出时删除CDialog对象?
把“delete this”加到 PostNcDestroy 中这主要用在需要自动删除对象场合

(88)为什么把“delete this”放在PostNcDestroy中而不是OnNcDestroy?
OnNcDestroy 只被已建立窗口如果建立窗口失败 ( 如 PreCreateWindow )则没有窗口处来发送 WM_NCDESTROY 消息PostNcDestroy 是在对象窗口被完全删除在 _disibledevent=>sysmenu->AppendMenu(MF_STRING, 1000, "xxx");
参见 MFC 帮助文件中 CMenu 类

(92)我建立了个对话框但是当我显示该对话框时个编辑框总是不能获得焦点我必须单击它来使它获得焦点我怎样才能使第个编辑框在对话框打开时就获得焦点?
打开资源编辑器中对话框模板在 Layout 菜单中选择 Tab Order 选项按你需求单击对话框中控制来重新排列这些控制 tab 顺序

(93)我怎样才能使个窗口具有“always _disibledevent=>如果 ZipCode 列被定义为串时不会出现问题如果定义为 long则会出现“Internal Application Error”对话框这是由于类型不匹配缘故如果你删除 27111 单引号则不会出现问题当你看到“Internal Application Error”时最好检查下试图要发送给数据库 SQL 语句

(97) 我用ClassWizard建立了个类但是我把名字取错了我想把它从项目中删除应该如何做?

在 ClassWizard 对话框关闭后用文件管理器删除新类 H 和 CPP 文件然后打开 ClassWizard它会提示丢失了两个文件并询问你该如何做你可以选择从项目中删除这两个问按钮

(98) 当我打开应用窗口时我要传递该窗口矩形尺寸该矩形指定了窗口外围大小但是当我GetClientRect时所得到尺寸要比所希望值要小(工具栏和窗口边框缘故)有其它思路方法来计算窗口尺寸吗?

参见 CWnd::CalcWindowRect

(99) 我在文档类中设置了个整型变量但是当我试图把该变量写入Serializearchive文件中时出现了类型而文档中其它变量没有问题为什么?

archive 类只重载某些类型 >> 和 << 操作符”类型没有在其中也许是 变量在 Windows 3.1 和 Windows NT/95 有所区别缘故吧“long”类型得到了支持所以你可以把 类型改成 long 型参见 MFC 帮助文件中 CArchive 类


(100) 如何控制菜单大小?
我用MFCCMenu生成了个动态菜单(例如File,Edit,View...Help), 我想控制这个菜单大小(长+高).

思路方法:查找 WM_MEASUREITEM 和 MEASUREITEMSTRUCT.
思路方法 2:查询系统::GetMetric(SM_CXMENUSIZE).

/* 你可以通过如下代码来获得文本大小:
(A)获得被使用字体 */

NONCLIENTMETRICS ncm;
HFONT hFontMenu;
SIZE size;
size.cy = size.cy = 0;

mem(&ncm, 0, (NONCLIENTMETRICS));
ncm.cbSize = (NONCLIENTMETRICS);
(ParametersInfo(SPI_GETNONCLIENTMETRICS, (NONCLIENTMETRICS), &ncm, 0))
{
hFontMenu = CreateFontIndirect(&ncm.lfMenuFont);
/*
(B) 获得菜单项文本: */
char szText[_MAX_PATH];

pMenu->GetMenuString(0, szText, _MAX_PATH, MF_BYPOSITION);
/*
然后,获得菜单项文本高度: */
HFONT hFontOld;
HDC hDC;

hDC = ::GetDC(NULL);
hFontOld = (HFONT) ::SelectObject(hDC, hFontMenu);
GetTextExtentPo32(hDC, szText, lstrlen(szText), &size);
SelectObject(hDC, hFontOld);
::ReleaseDC(NULL, hDC);
}
/*此时,size.cy即为高度,size.cx为宽度,你可以给菜单加上自定义高度和宽度,通过比较,我发现宽度为4

比较合适*/


(101) 改变LVIS_SELECTED状态颜色?
我想将CListCtrl项和CTreeCtrl项在LVIS_SELECTED状态时颜色变灰.

思路方法:查找CustomDraw,它是IE4提供公共控制,允许有你自己代码.
思路方法 2:生成个drawControl控件,然后在DrawItem中处理文本颜色.

(102) 如何只存储文档部分?
我只想存储文档部分,能否象使用文件样使用文档?(也就是有定位).将每个CArchive类设置为CFile类派生类,这样你就能使用Seek等成员.

(103) 保存工具条菜单有bug吗?

使用浮动菜单条时,SaveBarState和LoadBarState出现了问题.如果菜单是浮动,重起应用时它会出现在左上角,而它固定在屏幕其它位置时,下次启动就会出现在该位置,这是什么原因?你试试这个PToolBar->Create(this,...,ID_MYTOOLBAR);
工具条需要包括id,而不是象默认工具条那样.

(104) Tip of the daybug

我创建了个简单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.

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

(
cmdInfo.m_bShowSplash &&
cmdInfo.m_nShellCommand != CCommandLineInf:FileDDE
)
{
CTipDlg dlg;
(dlg.m_bStartup)
dlg.DoModal;
}
}
如果还有其它bug,你可以设定cmdInfo.m_nShellCommand过滤.

(105) 如何可以让我可以显示在其它窗口上面?

让用户选择"总是在最上面"最好是在系统菜单里加入个选项.可以通过修改WM_SYSCOMMAND消息来发送用户选择.菜单命令标识(id)会作为个参数传给OnSysCommand.要定义标识(id),将如下代码加入到CMainFrame.CPP中:

# WM_ALWAYSONTOP WM_USER + 1
将"总在最上面"菜单项加入到系统菜单中,将如下代码加入到CMainFrame::OnCreate中:

CMenu* pSysMenu = GetMenu(FALSE);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, WM_ALWAYSONTOP,
"&Always _disibledevent=> nHeightOff = rectWindow.Height - rectClient.Height;

lpMMI->ptMinTrackSize.x = MINX + nWidthOff;
lpMMI->ptMinTrackSize.y = MINY + nHeightOff;
lpMMI->ptMaxTrackSize.x = MAXX + nWidthOff;
lpMMI->ptMaxTrackSize.y = MAXY + nHeightOff;
}
第 2步,在CFrameWnd继承类PreCreateWindow中去掉WS_MAXIMIZEBOX消息,否则在最大化时你将得不到预料结果.

BOOL CMyFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~WS_MAXIMIZEBOX;
CFrameWnd::PreCreateWindow(cs);
}

(107) 如何改变窗口框架颜色?

MDI框架客户区被另个窗口框架所覆盖.为了改变客户区背景色,你需要重画这个客户窗口.为了做到这点,你要处理消息WM_ERASEBKND产生个新类,从CWnd继承,姑且称的为CMDIClient.给它加上个成员变量,
# "MDIClient.h"
CMainFrame : public CMDIFrameWnd
{
...
protected:
CMDIClient m_wndMDIClient;
}
在CMainFrame中重载CMDIFrameWnd::OnCreateClient
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
( CMDIFrameWnd::OnCreateClient(lpcs, pContext) )
{
m_wndMDIClient.SubWindow(m_hWndMDIClient);
TRUE;
}

FALSE;
}
然后就可以加入对消息WM_ERASEBKGND处理了.

(108) 如何将应用窗口置于屏幕正中?

要将你应用窗口放置在屏幕正中央,只须在MainFrameOnCreate中加入:
CenterWindow( GetDesktopWindow );


(2)确定应用路径
Use GetModuleFileName 获得应用路径然后去掉可执行文件名
Example:
TCHAR
exeFullPath[MAX_PATH] // MAX_PATH在API中定义了吧好象是
128
GetModuleFileName(NULL,exeFullPath,MAX_PATH)



(3)如何在中获得其他图标?
两种思路方法:
(1) SDK SHGetFileInfo 或使用 ExtractIcon获得图标资源 handle,
(2) SDK SHGetFileInfo 获得有关文件很多信息,如大小图标,属性, 类型等.
Example(1):
窗口左上角显示 NotePad图标.
void CSampleView:
OnDraw(CDC * pDC)
{
( :: SHGetFileInfo(_T("c:""pwin95""notepad.exe"),0,
&stFileInfo,(stFileInfo),SHGFI_ICON))
{
pDC ->DrawIcon(10,10,stFileInfo.hIcon)
}
}
Example(2):同样功能,Use ExtractIcon Function
void CSampleView:: _disibledevent=>("NotePad.exe"),0)
(hIcon &&hIcon!=(HICON)-1)
pDC->DrawIcon(10,10,hIcon)
}
介绍说明: 获得notepad.exe路径正规上来说用GetWindowsDirectory得到, 如果是 win95下画笔应该用访问注册表思路方法获得其路径要作成个比较考究考虑应该全面点.

(4)获得各种目录信息
Windows目录: Use "GetWindowsDirectory"
Windows下system目录: Use "GetDirectory"
temp目录: Use "GetTempPath"
当前目录: Use "GetCurrentDirectory"

请注意前两个个参数为目录变量名个为缓冲区后两个相反.


(5)如何自定义消息
1) 手工定义消息可以这么写
# WM_MY_MESSAGE(WM_USER+100),
MS 推荐至少是 WM_USER+100

(2)写消息处理,用
WPARAM,LPARAM返回LRESULT.
LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)

{
temp目录: Use "GetTempPath"
//加入你处理 irectory"
}

(6)如何改变窗口图标?
向窗口发送 WM_SECTION消息
Example:
HICON hIcon=AfxGetApp ->LoadIcon(IDI_ICON)
ASSERT(hIcon)
AfxGetMainWnd ->SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon)


(7)如何改变窗口缺省风格?
重载 CWnd:: PreCreateWindow 并修改CREATESTRUCT结构来指定窗口风格和其他创建信息.
Example: Delete "Max" Button and Set Original
Window's Position and Size

BOOL CMainFrame:: PreCreateWindow
(CREATESTRUCT &cs)
{
cs.style &=~WS_MAXINIZEMOX

cs.x=cs.y=0
cs.cx=GetMetrics(SM_CXSCREEN/2)
cs.cy=GetMetrics(SM_CYSCREEN/2)

CMDIFramewnd ::PreCreateWindow(cs)
}

(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( )


(9)如何让窗口和 MDI窗口启动就最大化和最小化?
先说窗口
在 InitStance 中设定 m_nCmdShow取值.
m_nCmdShow=SW_SHOWMAXMIZED //最大化
m_nCmdShow=SW_SHOWMINMIZED //最小化
m_nCmdShow=SW_SHOWNORMAL //正常方式

MDI窗口:
如果是创建新应用,可以用MFC AppWizard Advanced 按钮并在MDI子窗口风格组中检测最大化或最小化还可以重载 MDI Window PreCreateWindow设置WS_MAXMIZE or WS_MINMIZE

如果从 CMDIChildWnd派生, _disibledevent=>
// Now specy the window style .
cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL)
bResult
}

(13)如何使保持极小状态?
这么办: 在恢复窗体大小时Windows会发送WM_QUERY-OPEN消息用 ClassWizard设置成员
OnQueryOpen ,add following code:

Bool CMainFrame:: _disibledevent=> (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest
}

上述技术有两点不利的处
是在窗口客户区域双击时窗口将极大;
其 2它不适合包含几个视窗主框窗口
还有种思路方法当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上使用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送个WM_NCLBUTTONDOWN信息和个单击测试HTCAPTION
void CSampleView : : _disibledevent=>
// Get the area that needs to be erased .
CRect reClip
pDC—>GetCilpBox (&rcClip)
//Pa the area.
pDC—> PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )

//Unselect brush out of device context .
pDC—>SelectObject (pOldBrush )

// Return nonzero to half fruther processing .
TRUE
}

(19)如何改变窗口标题
CWnd : : SetWindowText可以改变任何窗口(包括Control控件)标题
//Set title for application's frame window .
AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") )

//Set title for View's MDI child frame window .
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame title")
)

//Set title for dialog's push button control.
GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button title ") )
如果需要经常修改窗口标题(注:Control控件也是窗口)应该考虑使用半文档化AfxSetWindowText在AFXPRIV.H中介绍说明在WINUTIL.CPP中实现在联机帮助中找不到它它在AFXPRIV.H中半文档化在以后发行MFC中将文档化
AfxSetWindowText实现如下:
voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew )
{
itn nNewLen= Istrlen (Ipaz)
TCHAR szOld [256]
//fast check to see text really changes (reduces
flash in the
controls )
(nNewLen >_contof (szOld)
|| : : GetWindowText (hWndCrtl, szOld , _countof (szOld) !=nNewLen
|| Istrcmp (szOld , IpszNew)! = 0
{
//change it
: : SetWindowText(hWndCtrl , IpszNew )
}
}

(20)如何防止主框窗口在其介绍说明中显示活动文档名
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位如果不希望在介绍说明中自动添加文档名必须禁止该风格位可以使用ClassWizard重置
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in frame .
cs.styel & = ~FWS_ADDTOTITLE  
CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口FWS _ADDTOTITLE风格将创建个具有空标题窗口可以CWnd: : SetWindowText来设置标题记住自己设置标题时要遵循接口风格指南

(21)如何获取有关窗口正在处理当前消息信息
CWnd: : GetCurrentMessage可以获取个MSG指针例如可以使用ClassWizard将几个菜单项处理映射到然后GetCurrentMessage来确定所选中菜单项
viod CMainFrame : : _disibledevent=>—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

//Get poer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)

(23)如何使能和禁止工具条工具提示
如果设置了CBRS_TOOLTIPS风格位工具条将显示工具提示要使能或者禁止工具提示需要设置或者清除该风格位下例通过CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立个完成此功能成员:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)

DWORD dwStyle = m _wndToolBar.GetBarStyle ( )

(bDisplayTips) dwStyle |=CBRS_TOOLTIPS


dwStyle & = ~CBRS_TOOLTIPS

m_wndToolBar.SetBarStyle (dwStyle )
}

(24)如何创建个不规则形状窗口
可以使用新SDKSetWindowRgn将绘画和鼠标消息限定在窗口个指定区域实际上使窗口成为指定不规则形状使用AppWizard创建个基于对应用并使用资源编辑器从主对话资源中删除所在缺省Control控件、标题以及边界
给对话类增加个CRgn数据成员以后要使用该数据成员建立窗口区域
Class CRoundDlg : public CDialog
{

private :
Crgn m_rgn : // window region

}
修改OnInitDialog建立个椭圆区域并SetWindowRgn将该区域分配给窗口:
BOOL CRoundDlg : : _disibledevent=>BYTE byRed =GetRValue (color)
BYTE byGreen = GetGValue (color)
BYTE byBlue = GetBValue (color)

// get the size of the view window
Crect rect
GetClientRect (rect)

// get minimun number of units
nUnits =min (rect.right , rect.bottom )

//calculate he horiaontal and vertical step size
float fltStepHorz = (float) rect.right /nUnits
float fltStepVert = (float) rect.bottom /nUnits


nEllipse = nUnits/3 // calculate how many to
draw
nIndex
// current ellipse that is being draw

CBrush brush
// bursh used for ellipse fill color
CBrush *pBrushOld // previous
brush that was selected o dc
//draw ellipse , gradually moving towards upper-right
corner
for (nIndex = 0 nIndes < + nEllipse nIndes)
{
//creat solid brush
brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ).
( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue)
/nEllipse ) ) )

//select brush o dc
pBrushOld= dc .SelectObject (&brhsh)

//draw ellipse
dc .Ellipse ( () fltStepHorz * 2, () fltStepVert * nIndex ,
rect. right -( () fltStepHorz * nIndex )+ 1,
rect . bottom -( () fltStepVert * (nIndex *2) ) +1)

//delete the brush
brush.DelecteObject ( )
}
}

最后处理WM_NCHITTEST消息使当击打窗口任何位置时能移动窗口
UINT CRoundDlg : : _disibledevent=>rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest

}

(25)如何获取应用例子句柄?
应用例子句柄保存在CWinApp m_hInstance 中,可以这么AfxGetInstancdHandle获得句柄.
Example: HANDLE hInstance=AfxGetInstanceHandle

(26)如何编程结束应用?
这是个很简单又是编程中经常要遇到问题.
向窗口发送 WM_CLOSE消息, CWnd::OnClose成员.允许对用户提示是否保存修改过数据.
Example: AfxGetMainWindow->SendMessage(WM_CLOSE)

还可以创建个自定义 Terminate Window
void Terminate Window(LPCSTR pCaption)
{
CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption)

(pWnd)

pWnd ->SendMessage(WM_CLOSE)
}

介绍说明: FindWindow不是提倡做法它无法处理标题栏自动改变比如我们要检测 Notepad是不是已运行而事先不知道Notepad标题栏,这时FindWindow就无能为力了可以通过枚举 windows任务列表办法来实现在机械出版社"Windows 95 API开发人员指南"书有比较详细介绍,这里就不再多说乐

(27)如何创建和使用无模式对话框
MFC将模式和无模式对话封装在同个类中但是使用无模式对话需要几个对话需要几个额处步骤首先使用资源编辑器建立对话资源并使用ClassWizard创建个CDialog派生类模式和无模式对话中止是不:模式对话通过CDialog : : EndDialog 来中止无模式对话则是CWnd: : DestroyWindow来中止CDialog : : _disibledevent=>ASSERT_VALID (pDialog) Destroy ( )

//Create the modeless dialog . represents this dialog.
BOOL bResult = pDialog —> Creste (IDD_IDALOG)
ASSERT (bResult )
}

(28)如何防止主框窗口在其介绍说明中显示活动文档名
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位如果不希望在介绍说明中自动添加文档名必须禁止该风格位可以使用ClassWizard重置
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格
BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in frame .
cs.styel & = ~FWS_ADDTOTITLE  
CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口FWS _ADDTOTITLE风格将创建个具有空标题窗口可以CWnd: : SetWindowText来设置标题记住自己设置标题时要遵循接口风格指南

(29)如何在代码中获取工具条和状态条指针
缺省时工作框创建状态条和工具条时将它们作为主框窗口子窗口状态条有个AFX_IDW_STATUS_BAR标识符工具条有个AFX_IDW_TOOLBAR标识符下例介绍说明了如何通过CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口指针:
//Get poer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

//Get poer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)


(30)怎样加载其他应用?
3个SDK winexec, shellexecute,createprocess可以使用
WinExec最简单两个参数个指定路径个指定显示方式.后个参数值得说比如泥用 SW_SHOWMAXMIZED方式去加载个无最大化按钮就是Neterm,calc等等就不会出现正常窗体但是已经被加到任务列表里了

ShellExecute较 WinExex灵活可以指定工作目录,下面Example就是直接打开 c:"temp"1.txt,而不用加载和 txt文件关联应用,很多安装完成后都会打开个窗口来显示Readme or Faq,我猜就是这么作啦.

ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:""temp"),SW_SHOWMAXMIZED)

CreateProcess最复杂共有十个参数不过大部分都可以用NULL代替它可以指定进程安全属性继承信息优先级等等.来看个很简单Example:
STARTUPINFO stinfo
//启动窗口信息
PROCESSINFO procinfo //进程信息

CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,
NORMAL_PRIORITY_

CLASS,NULL,NULL, &stinfo,&procinfo)

(31)如何在代码中获取工具条和状态条指针
缺省时工作框创建状态条和工具条时将它们作为主框窗口子窗口状态条有个AFX_IDW_STATUS_BAR标识符工具条有个AFX_IDW_TOOLBAR标识符下例介绍说明了如何通过CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口指针:
//Get poer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)

(32)如何使能和禁止工具条工具提示
如果设置了CBRS_TOOLTIPS风格位工具条将显示工具提示要使能或者禁止工具提示需要设置或者清除该风格位下例通过CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立个完成此功能成员:
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)

DWORD dwStyle = m _wndToolBar.GetBarStyle ( )

(bDisplayTips) dwStyle |=CBRS_TOOLTIPS


dwStyle & = ~CBRS_TOOLTIPS

m_wndToolBar.SetBarStyle (dwStyle )
}

//Get poer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
—> GetDescendantWindow(AFX_IDW_TOOLBAR)

(33)如何设置工具条标题
工具条是个窗口所以可以在CWnd : : SetWindowText来设置标题例子如下:
CMainFrame : : _disibledevent=> (HBRUSH) m_brush.GetSafeHandle ( )
CFormView : : _disibledevent=> nReslt = DlgDirListComboBox (szPath, IDC_COMBO , IDC_CURIDIR, DDL_READWRITE |DDL_READONLY|DDL_HIDDEN| DDL_SYSTEM|DDL_ARCHIVE)
TRUE
}

(42)为什么旋转按钮Control控件看起来倒转
需要CSpinCtrl : : SetRange 设置旋转按钮Control控件范围旋转按钮Control控件缺省上限为0缺省下限为100这意味着增加时旋转按Control控件值由100变为0下例将旋转按钮Control控件范围设置为0到100:
BOOL CAboutDlg : : _disibledevent=>ASSERT_VALID (m_pButton)
m_pButton —>Create (_T ("Button Title ") , WS_CHILD |WS_VISIBLE |BS_PUSHBUTTON. Crect ( 0, 0, 100 , 24) , this , IDC _MYBUTTON )

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

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

//In you dialog implementation (.CPP file )
BOOL CSampleDialog : : _disibledevent=>
//Bypass default _disibledevent=>
//Draw red text for all edit controls .
(nCtlColor= = CTLCOLOR_EDIT )
pDC —> SetTextColor (RGB (255, 0 , 0 , ) )

hbr
}

然而由于每个父窗口必须处理通知消息并指定每个Control控件绘画属性所以这种思路方法不是完全面向对象思路方法Control控件处理该消息并指定绘画属性更合情合理消息反射允许用户这样做通知消息首先发送给父窗口如果父窗口没有处理则发送给Control控件创建个定制彩色列表框Control控件必须遵循下述步骤

首先使用ClassWizard 创建个CListBox 派生类并为该类添加下述数据成员
CMyListBox publilc CListBox
{

private
COLORREF m_clrFor // foreground color
COLORREF m_clrBack //background color
Cbrush m_brush //background brush

}
其次在类构造化数据中
CMyListBox : : CMyListBox
{
//Initialize data members .
m_clrFore =RGB (255 , 255 , 0) //yellow text
m_clrBack=RGB (0 , 0 , 255) // blue background
m_brush . CreateSolidBrush (m _clrBack )
}

最后使用ClassWizard处理反射WM_CTLCOLOR(=WM_CTLCOLOR)消息并指定新绘画属性
HBRUSH CMyListBox : : CtlColor (CDC* pDC, UINT nCtlColor )
{
pDC—>SetTextColor (m_clrFore)
pDC—>SetBkColor (m_clrBack)

(HBRUSH) m_brush.GetSafeHandle
}
现在Control控件可以自己决定如何绘画和父窗口无关

(49)当向列表框中添加多个项时如何防止闪烁
CWnd::SetRedraw 清除重画标志可以禁止CListBox(或者窗口)重画当向列表框添加几个项时用户可以清除重画标志然后添加项最后恢复重画标志为确保重画列表框新项SetRedraw (TRUE) 的后CWnd::Invalidate

//Disable redrawing.
pListBox->SetRedraw (FALSE)

//Fill in the list box gere
//Enable drwing and make sure list box is redrawn.
pListBox->SetRedraw (TRUE)
pListBox->Invalidate

(50)如何向编辑Control控件中添加文本
由于没有CEdit:: AppendText用户只好自己做此项工作CEdit:: SetSel移动到编辑Control控件末尾然后CEdit:: ReplaceSel添加文本下例是AppendText 种实现思路方法:

void CMyEdit:: AppendText (LPCSTR pText)
{
nLen=GetWindowTextLength
SetFocus
SetSel (nLen, nLen)

ReplaceSel (pText)
}

(51)如何访问预定义GDI对象
可以通过CDC:: SlectStockObject使用Windows几个预定义对象诸如刷子、笔以及字体下例使用了Windows预定义笔和刷子GDI对象在视窗中画个椭圆
//Draw ellipse using stock black pen and gray brush.
void CSampleView:: _disibledevent=>
//Draw the ellipse.
pDC->Ellipse (rcView)

//Restore original brush.
pDC->SelectObject (pOrgBrush)
}

(52)如何获取GDI对象属性信息
可以GDIObject:: GetObject这个将指定图表设备消息写入到缓冲区下例创建了几个有用辅助
//Determine font is bold.
BOOL IsFontBold (const CFont&font)
{
LOGFONT stFont
font.GetObject ( (LOGFONT), &stFont)
(stFont.lfBold)? TRUE: FALSE
}

//Return the size of a bitmap.
CSize GetBitmapSize (const CBitmap&bitmap)
{
BITMAP stBitmap
bitmap.GetObject ( (BITMAP), &stBitmap)
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 ( (LOGBRUSH), &stBrush)
pen. Createpen (PS_SOLID, 0, stBrush.ibColor)
}

(53)如何实现个橡皮区矩形
CRectTracker是个很有用可以通过CRectTracker::TrackRubberBand 响应WM_LBUTTONDOWN消息来创建个橡皮区矩形
下例表明使用CRectTracker移动和重置视窗中蓝色椭圆大小是很容易事情

首先在文件档中声明个CRectTracker数据成员:
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:: _disibledevent=>ASSERT_VALID (pDoc)

//Select blue brush o 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, CPo po)
{
//Get poer to document.
CSampleDoc* pDoc=GetDocument
ASSERT_VALID (pDoc)

//If clicked _disibledevent=>
//Tracker rectangle changed so update views.
(bResult)
{
pDoc->m_tracker.Track (this,po,TRue)
pDoc->SetModiedFlag
pDoc->UpdateAllViews (NULL)
}


pDoc->m-tracker.TrackRubberBand(this,po,TRUE)
CView:: _disibledevent=>下例创建了个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"))

(56)如何计算个串大小
CDC:: Det text Extent 根据当前选择字体计算个串高度和宽度如果使用不是系统字体而是其他字体则在GetTextExtent的前将字体选进设备上下文中是很重要否则计算高度和宽度时将依据系统字体由此得出结果当然是不正确下述样板当改变下压按钮标题时动态调整按钮大小按钮大小由按钮字体和标题大小而定响应消息WM_SETTEXT时OnSetText该消息使用ON_MESSAE宏指令定义用户自定义消息

LRESULT CMyButton:: _disibledevent=>//Get title of push button.
CString strTitle
GetWindowText (strTitle)

//Select current font o 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 _disibledevent=>stFont.Weight=FW_NORMAL
stFont.ClipPrecision=LCIP_LH_ANGLES
strcpy (stFont.lfFaceName, "Arial")

//Draw text at 15degree ervals.
for ( nAngle=0 nAngle<3600 nAngle150)
{
//Specy angle.
stFont.lfEscapement=nAngle

//Create and select font o dc.
font.CreateFontIndirect(&stfont)
CFont* pOldFont=pDC ->SelectObject(&font)

//Draw the text.
pDC->SelectObject(pOldFont)
font.DelectObjext
}
}

(58)如何正确显示包含标签
GDI文本绘画时需要展开标签这可以通过CDC:: TabbedTextOut或者CDC:: DrawText并指定DT_EXPANDTABS标志来完成TabbedTextOut允许指定标签位下例指定每20设备单位展开个标签:

void CSampleView:: _disibledevent=>ASSERT_VALID (pDoC)

CString str
str.Format (_T ("Cathy"tNorman"tOliver"))
nTabStop=20 //tabs are every 20 pixels
pDC->TabbedtextOut (10, 10, str, 1, &nTabStop, 10)
}

(59)如何快速地格式化个CString对象
CString:: Format和prf具有相同参数下例介绍说明了如何使用Format:

//Get size of window.
CRect rcWindow
GetWindowRect (rcWindow)
//Format message .
CString strMessage
strMessage.Format (_T ("Window Size (%d, %d)"),

rcWindow.Width , rcWindow.Height )

//Display the message.
MessageBox (strmessage)

(60)串太长时如何在其末尾显示个省略号
CDC:: DrawText并指定DT_END_ELLIPSIS标志这样就可以用小略号取代串末尾使其适合于指定边界矩形如果要显示路径信息指定DT_END_ELLIPSIS标志并省略号取代串中间

void CSampleView:: _disibledevent=>ASSERT_VALID (pDoc)

//Add ellpsis to end of it does not fit
pDC->Drawtext (CString ("This is a long "), CRect (10, 10, 80, 30), DT_LEFT | DT_END_ELLIPSIS)

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

(61)为什么即使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)

(62)如何给系统菜单添加个菜单项
给系统菜单添加个菜单项需要进行下述 3个步骤:
首先使用Resource Symbols对话(在View菜单中选择Resource Symbols...可以显示该对话)定义菜单项ID该ID应大于0x0F而小于0xF000;
其次CWnd::GetMenu获取系统菜单指针并CWnd:: Appendmenu将菜单项添加到菜单中下例给系统菜单添加两个新
CMainFrame:: _disibledevent=>ASSERT (IDM-MYSYSITEM<0xF000)

//Get poer to system menu.
CMenu* pSysmenu=Getmenu (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:: _disibledevent=>{
//TODO-process system menu item
}


CMDIFrameWnd ::OnSysCommand (nID, lParam)
}
最后个设计良好UI应用应当在系统菜单项加亮时在状态条显示个帮助信息这可以通过增加个包含系统菜单基ID串表入口来实现

(63)如何确定顶层菜单所占据菜单行数
这可以通过简单减法和除法来实现首先用户需要计算主框窗口高度和客户区;其次从主框窗口高度中减去客户区、框边界以及标题高度;最后除以菜单栏高度下例成员个计算主框菜单所占据行数代码实现

CMainFrame:: GetMenuRows
{
CRect rcFrame,rcClient
GetWindowRect (rcFrame)
GetClientRect (rcClient)
(rcFrame.Height -rcClient.Height - :: GetMetrics(SM_CYCAPTION) - (:: getMetrics(SM_CYFRAME) *2)) / :: GetMetrics(SM_CYMENU)
}

(64)在用户环境中如何确定系统显示元素颜色
SDKGetSysColor可以获取个特定显示元素颜色下例介绍说明了如何在MFCCMainFrameWnd:: _disibledevent=>
//Walk window list.
while (pWnd)
{
// I window visible, has a caption, and does not have an owner?
(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)
}
}

(69)如何确定Windows和Windows系统目录
有两个SDK可以完成该功能GetWindowsDirectory和GetDirectory下例介绍说明了如何使用这两个:

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.
∶ : GetDirectory (szDir, MAX_PATH)
TRACE ("Windows system directory %s"n", szDir)

(70)在哪儿创建临文件
SDKGetTemPath可以确定临时文件目录首先为临时路径检测TMP环境变量:如果没有指定TMP检测TMP环境变量然后返回到当前目录下例介绍说明了如何创建个临时文件


//get unique temporary file.
CString strFile
GetUniqueTempName (strFile)
TRY
{
//Create file and write data.Note that file is closed
//in the destructor of the CFile object.
CFile file (strFile,CFile ::modeCreate | CFile:: modeWrite)

//write data
}

CATCH (CFileException, e)
{
//error opening file
}
END_CATCH


Void GetuniqueTempName (CString& strTempName)
{
//Get the temporary files directory.
TCHAR szTempPath [MAX_PATH]
DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath)
ASSERT (dwResult)

//Create a unique temporary file.
TCHAR szTempFile [MAX_PATH]
UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempfile)
ASSERT (nResult)

strTempName=szTempFile
}

(71)我怎样才能建立个等待光标?
BeginWaitCursor 来启动等待光标 EndWaitCursor 来结束等待光标要注意 2者都要 app 成员如下所示:

AfxGetApp->BeginWaitCursor;
// 要做
AfxGetApp->EndWaitCursor;

(72)我在MDI框架中有个 form 视窗它有个取消按钮我需要当用户按取消按钮时可关闭form视窗我应该如何关闭该文档?
_disibledevent=>HWND hWnd= :: GetWindow (:: GetDesktopWindow, GW_CHILD)
while (hWnd!=NULL)
{
(:: IsWindowEnabled (hwnd)
&& CWnd::FromHandlePermanent (hWnd)!=NULL
&& AfxIsDescendant (pParent->m_hWnd, hWnd)
&& :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)0)
{
nCount
}
hWnd=:: GetWindow (hWnd, GW_HWNDNEXT)
}


(74)什么是COLORREF? 我该怎样用它?
COLORREF是个32-bit整型数值它代表了种颜色你可以使用RGB化COLORREF例如:

COLORREF color = RGB(0, 255, 0);
RGB接收 3个0-255数值个代表红色个代表绿色个代表蓝色在上面例子中红色和蓝色值都为0所以在该颜色中没有红色和蓝色绿色为最大值255所以该颜色为绿色0,0,0为黑色255,255,255 为白色

化COLORREF思路方法如下所示:

CColorDialog colorDialog;
COLORREF color;

( colorDialog.DoModal IDOK )
{
color = colorDialog.GetColor;
}
这段代码使用了MFC中颜色对话框它需要文件

(75)AppWizard所产生STDAFX文件是干什么用?
它主要是协助产生预编译头文件通常你是不需要修改它

(76)我在我中是了CDWordArray我向它添加了约10,000个整数这使得它变得非常非常慢为什么会这么糟?
CDWordArray是很好用只是你没有指定最大尺寸因此当你添加新元素时该类会从堆中重新分配空间不幸该类会在每次插入新元素时都为重新分配空间如果你向它添加了很多新元素所有这些分配和复制操作会就会使它变慢解决该问题思路方法是你可以使用SetSize第 2个参数来改变这种重新分配频率例如如果你把该参数设置为500则每次空间超出时它才重新分配并添加500个新空间而不是1 个这样你就可以不用重新分配而添加了另外499个元素空间这也会大大提高运行速度

(77)我该如何改变MDI框架窗口子窗口大小以使在窗口以大小打开?
在视中OnInitialUpdateGetParentFrameGetParentFrame会返回指向保存有该视框架窗口指针然后在框架窗口上MoveWindow

(78)在我某些部分我可以 MessageBox 来建立个信息对话框例如在视类中但是在其它部分我却不能如文档类中为什么?我怎样才能在我应用类中建立个信息对话框?
MessageBox来自CWnd 类所以你只能在从CWnd继承类(如CView )中但是MFC也提供了AfxMessageBox你可以在任何地方

(79)我需要在我中设置全局变量以使文档中所有类都能访问我应该吧它放到哪儿?
把该变量放到该应用头文件中attribute处然后任何地方你都可以用下面思路方法来访问该变量:

CMyApp *app = (CMyApp *)AfxGetApp;
app->MyGlobalVariable = ...

(80)我听说MFC可以发现内存漏洞我怎样使用该特性?
如果你在Debug菜单中Go选项(不是Project菜单中Execute选项)来运行你应用MFC 应该在终止时报告内存漏洞如果没有那么试试运行MFC Tracer工具(在VC组中)并启动跟踪然后返回应用

(81)我怎样才能在我应用中循环浏览已经打开文档?
使用CDocTemplate中未公开GetFirstDocPosition和GetNextDoc

(82)才能在我应用中循环浏览已经打开视?
使用CDocument 中未公开GetFirstViewPosition 和GetNextView

(83)PreCreateWindow是干什么用?
PreCreateWindow允许你在 CreateWindow 的前来改变窗口属性

(84)该怎样防止MFC在窗口标题栏上把文档名预置成应用名?
在PreCreateWindow中删除FWS_PREFIXTITLE标志窗口样式:

cs.style &= ~FWS_PREFIXTITLE;

(85)我应该怎样防止MFC在窗口标题栏上添加文档名?
在PreCreateWindow中删除FWS_ADDTOTITLE 标志窗口样式:

cs.style &= ~FWS_ADDTOTITLE ;

(86)我应该如何改变视窗口大小?
视窗口实际上是框架窗口子窗口所以你必须改变框架窗口大小而不是改变视窗口使用CView类中GetParentFrame获得指向框架窗口指针然后MoveWindow来改变框架大小这会使变尺寸视充满框架窗口

(87)我有无模式对话框我怎样才能在窗口退出时删除CDialog对象?
把“delete this”加到PostNcDestroy中这主要用在需要自动删除对象场合

(88)为什么把“delete this”放在PostNcDestroy中而不是OnNcDestroy?
OnNcDestroy只被已建立窗口如果建立窗口失败(如PreCreateWindow )则没有窗口处来发送WM_NCDESTROY消息PostNcDestroy是在对象窗口被完全删除在OnNcDestroy后甚至在窗口建立失败的后

(89)File菜单中MRU列表是从哪儿来?列表中名字放在哪儿了?我怎样才能改变列表中项目最大值?
在应用InitInstance中对LoadStdProfileSettings接受个参数(在缺省情况下如果没有传递值则为4 )MRU文件名是从INI文件中如果你有带有ID_FILE_MRU_FILE1ID菜单选项它会为调入MRU列表所替换如果你改变传递给 LoadStdProfileSettings数值(最大为16 )则你就改变了所装如文件名最大值

(90)我在菜单中添加了新但是当我选该项时在状态栏上没有出现任何提示信息为什么?
打开资源文件中菜单模板打开新菜单选项属性对话框在对话框底部Prompt 编辑框中你可以如下指定状态栏上提示信息和工具栏上提示信息(如果你已经建立工具栏按钮):

Status bar "nFlying tag

(91)我怎样才能在应用缺省系统菜单中加上些东西?
系统菜单和其它菜单类似你可以添加或删除项目这需要使用CMenu类成员下面代码在你系统菜单后面添加个新菜单项:

CMenu *sysmenu;
sysmenu = m_pMainWnd->GetMenu(FALSE);
sysmenu->AppendMenu(MF_STRING, 1000, "xxx");
参见MFC帮助文件中CMenu 类

(92)我建立了个对话框但是当我显示该对话框时个编辑框总是不能获得焦点我必须单击它来使它获得焦点我怎样才能使第个编辑框在对话框打开时就获得焦点?
打开资源编辑器中对话框模板在Layout菜单中选择Tab Order 选项按你需求单击对话框中控制来重新排列这些控制tab顺序

(93)我怎样才能使个窗口具有“always _disibledevent=>如果 ZipCode 列被定义为串时不会出现问题如果定义为long则会出现“Internal Application Error”对话框这是由于类型不匹配缘故如果你删除27111单引号则不会出现问题当你看到“Internal Application Error”时最好检查下试图要发送给数据库SQL语句

(97)我用ClassWizard建立了个类但是我把名字取错了我想把它从项目中删除应该如何做?

在ClassWizard对话框关闭后用文件管理器删除新类H 和CPP文件然后打开ClassWizard它会提示丢失了两个文件并询问你该如何做你可以选择从项目中删除这两个问按钮

(98)当我打开应用窗口时我要传递该窗口矩形尺寸该矩形指定了窗口外围大小但是当我GetClientRect时所得到尺寸要比所希望值要小(工具栏和窗口边框缘故)有其它思路方法来计算窗口尺寸吗?

参见CWnd::CalcWindowRect

(99)我在文档类中设置了个整型变量但是当我试图把该变量写入Serializearchive文件中时出现了类型而文档中其它变量没有问题为什么?

archive 类只重载某些类型>>和<<操作符”类型没有在其中也许是变量在Windows 3.1和Windows NT/95有所区别缘故吧“long”类型得到了支持所以你可以把类型改成long型参见MFC帮助文件中CArchive类


(100)如何控制菜单大小?
我用MFCCMenu生成了个动态菜单(例如File,Edit,View...Help), 我想控制这个菜单大小(长+高).

思路方法:查找 WM_MEASUREITEM 和 MEASUREITEMSTRUCT.
思路方法 2:查询系统::GetMetric(SM_CXMENUSIZE).

/* 你可以通过如下代码来获得文本大小:
(A)获得被使用字体 */

NONCLIENTMETRICS ncm;
HFONT hFontMenu;
SIZE size;
size.cy = size.cy = 0;

mem(&ncm, 0, (NONCLIENTMETRICS));
ncm.cbSize = (NONCLIENTMETRICS);
(ParametersInfo(SPI_GETNONCLIENTMETRICS, (NONCLIENTMETRICS), &ncm, 0))
{
hFontMenu = CreateFontIndirect(&ncm.lfMenuFont);
/*
(B) 获得菜单项文本: */
char szText[_MAX_PATH];

pMenu->GetMenuString(0, szText, _MAX_PATH, MF_BYPOSITION);
/*
然后,获得菜单项文本高度: */
HFONT hFontOld;
HDC hDC;

hDC = ::GetDC(NULL);
hFontOld = (HFONT) ::SelectObject(hDC, hFontMenu);
GetTextExtentPo32(hDC, szText, lstrlen(szText), &size);
SelectObject(hDC, hFontOld);
::ReleaseDC(NULL, hDC);
}
/*此时,size.cy即为高度,size.cx为宽度,你可以给菜单加上自定义高度和宽度,通过比较,我发现宽度为4

比较合适*/

(101)改变LVIS_SELECTED状态颜色?
我想将CListCtrl项和CTreeCtrl项在LVIS_SELECTED状态时颜色变灰.

思路方法:查找CustomDraw,它是IE4提供公共控制,允许有你自己代码.
思路方法 2:生成个drawControl控件,然后在DrawItem中处理文本颜色.

(102)如何只存储文档部分?
我只想存储文档部分,能否象使用文件样使用文档?(也就是有定位).将每个CArchive类设置为CFile类派生类,这样你就能使用Seek等成员.

(103)保存工具条菜单有bug吗?

使用浮动菜单条时,SaveBarState和LoadBarState出现了问题.如果菜单是浮动,重起应用时它会出现在左上角,而它固定在屏幕其它位置时,下次启动就会出现在该位置,这是什么原因?你试试这个PToolBar->Create(this,...,ID_MYTOOLBAR);
工具条需要包括id,而不是象默认工具条那样.

(104)Tip of the daybug

我创建了个简单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.

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

(
cmdInfo.m_bShowSplash &&
cmdInfo.m_nShellCommand != CCommandLineInf:FileDDE
)
{
CTipDlg dlg;
(dlg.m_bStartup)
dlg.DoModal;
}
}
如果还有其它bug,你可以设定cmdInfo.m_nShellCommand过滤.

(105)如何可以让我可以显示在其它窗口上面?

让用户选择"总是在最上面"最好是在系统菜单里加入个选项.可以通过修改WM_SYSCOMMAND消息来发送用户选择.菜单命令标识(id)会作为个参数传给OnSysCommand.要定义标识(id),将如下代码加入到CMainFrame.CPP中:

# WM_ALWAYSONTOP WM_USER + 1
将"总在最上面"菜单项加入到系统菜单中,将如下代码加入到CMainFrame::OnCreate中:

CMenu* pSysMenu = GetMenu(FALSE);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, WM_ALWAYSONTOP,
"&Always _disibledevent=> nHeightOff = rectWindow.Height - rectClient.Height;

lpMMI->ptMinTrackSize.x = MINX + nWidthOff;
lpMMI->ptMinTrackSize.y = MINY + nHeightOff;
lpMMI->ptMaxTrackSize.x = MAXX + nWidthOff;
lpMMI->ptMaxTrackSize.y = MAXY + nHeightOff;
}
第 2步,在CFrameWnd继承类PreCreateWindow中去掉WS_MAXIMIZEBOX消息,否则在最大化时你将得不到预料结果.

BOOL CMyFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~WS_MAXIMIZEBOX;
CFrameWnd::PreCreateWindow(cs);
}

(107)如何改变窗口框架颜色?

MDI框架客户区被另个窗口框架所覆盖.为了改变客户区背景色,你需要重画这个客户窗口.为了做到这点,你要处理消息WM_ERASEBKND产生个新类,从CWnd继承,姑且称的为CMDIClient.给它加上个成员变量,
# "MDIClient.h"
CMainFrame : public CMDIFrameWnd
{
...
protected:
CMDIClient m_wndMDIClient;
}
在CMainFrame中重载CMDIFrameWnd::OnCreateClient
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
( CMDIFrameWnd::OnCreateClient(lpcs, pContext) )
{
m_wndMDIClient.SubWindow(m_hWndMDIClient);
TRUE;
}

FALSE;
}
然后就可以加入对消息WM_ERASEBKGND处理了.

(108)如何将应用窗口置于屏幕正中?

要将你应用窗口放置在屏幕正中央,只须在MainFrameOnCreate中加入:
CenterWindow( GetDesktopWindow );







标签:vc用法
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: