Q?Q?如何改变H口的图?
向窗口发?WM_SECTION消息?br />Example:
HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON)
ASSERT(hIcon)
AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon)
Call Function CWnd::CenterWindows()
Example(1):
Center Window( ) //Relative to it's parent
// Relative to Screen
Example(2):
CenterWindow(CWnd:: GetDesktopWindow( ))
//Relative to Application's MainWindow
AfxGetMainWnd( ) ->CenterWindow( )
Q?2Q?如何创徏一个字回绕的CEditView
重蝲CWnd : : PreCreateWindow和修改CREATESTRUCTl构Q关闭CEditView对象的ES_AUTOHSCROLL和WS_HSCROLL风格位, ׃CEditView : : PreCreateWindow昄讄cs. styleQ调用基cd数后要修改cs . style?br />
BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&cs)
{
//First call basse class function .
BOOL bResutl =CEditView : : PreCreateWindow (cs)
// Now specify the new window style .
cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL)
return bResult
}
Q?7Q?如何单击除了H口标题栏以外的区域使窗口移?br />当窗口需要确定鼠标位|时Windows向窗口发送WM_NCHITTEST信息Q可以处理该信息使Windows认ؓ鼠标在窗口标题上。对于对话框和基于对话的应用E序Q可以用ClassWizard处理该信息ƈ调用基类函数Q?如果函数q回HTCLIENT 则表明鼠标在客房区域Q返回HTCAPTION表明鼠标在Windows的标题栏中?br />UINT CSampleDialog : : OnNcHitTest (Cpoint point )
{
UINT nHitTest =Cdialog: : OnNcHitTest (point )
return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest
}
上述技术有两点不利之处Q?br />其一是在H口的客户区域双LQ窗口将极大Q?br />其二Q?它不适合包含几个视窗的主框窗口?br />q有一U方法,当用h下鼠标左键LH口认ؓ鼠标在其H口标题上,使用ClassWizard在视H中处理WM_LBUTTODOWN信息q向LH口发送一个WM_NCLBUTTONDOWN信息和一个单L试HTCAPTION?br />void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point
)
{
CView : : OnLButtonDow (nFlags , pont )
//Fool frame window into thinking somene clicked
on
its caption bar .
GetParentFrame ( ) ?gt; PostMessage (
WM_NCLBUTTONDOWN ,
HTCAPTION , MAKELPARAM (poitn .x , point .y) )
}
该技术也适用于对话框和基于对的应用程序,只是不必调用
CWnd: :GetParentFrame ?br />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
) )
}
Q?8Q?如何改变视窗的背景颜?br />Windows向窗口发送一个WM_ERASEBKGND消息通知该窗口擦除背景,可以使用ClassWizard重蝲该消息的~省处理E序来擦除背景(实际是画Q,q返回TRUE以防止Windows擦除H口?br />//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?gt;SelcetObject (&brush)
// Get the area that needs to be erased .
CRect reClip
pDC?gt;GetCilpBox (&rcClip)
//Paint the area.
pDC?gt; PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )
//Unselect brush out of device context .
pDC?gt;SelectObject (pOldBrush )
// Return nonzero to half fruther processing .
return TRUE
}
Q?0Q?如何防止LH口在其说明中显C活动的文档?br />创徏LH口和MDI子窗口进通常hFWS_ADDTOTITLE风格位,如果不希望在说明中自动添加文档名Q?必须止该风gQ?可以使用ClassWizard重置
CWnd: : PreCreateWindowq关闭FWS_ADDTOTITLE风格?br />BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in main frame .
cs.styel & = ~FWS_ADDTOTITLE
return CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口的FWS _ADDTOTITLE风格创Z个具有空标题的窗口,可以调用CWnd: : SetWindowText来设|标题。记住自p|标题时要遵循接口风格指南?/p>
Q?1Q?如何获取有关H口正在处理的当前消息的信息
调用CWnd: : GetCurrentMessage可以获取一个MSG指针。例如,可以使用ClassWizard几个菜单项处理E序映射C个函CQ然后调用GetCurrentMessage来确定所选中的菜单项?br />viod CMainFrame : : OnCommmonMenuHandler ( )
{
//Display selected menu item in debug window .
TRACE ("Menu item %u was selected . \n" ,
Q?2Q?如何在代码中获取工具条和状态条的指?br />~省Ӟ 工作框创建状态条和工h时将它们作ؓLH口的子H口Q状态条有一个AFX_IDW_STATUS_BAR标识W,工具条有一个AFX_IDW_TOOLBAR标识W,下例说明了如何通过一赯用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子H口的指针:
//Get pointer to status bar .
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )
?gt; GetDescendantWindow(AFX_IDW_STUTUS_BAR)
//Get pointer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
?gt; GetDescendantWindow(AFX_IDW_TOOLBAR)
Q?3Q?如何使能和禁止工h的工hC?br />如果讄了CBRS_TOOLTIPS风格位,工具条将昄工具提示Q要使能或者禁止工hC,需要设|或者清除该风格位。下例通过调用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函敎ͼ
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)
DWORD dwStyle = m _wndToolBar.GetBarStyle ( )
if (bDisplayTips) dwStyle ?CBRS_TOOLTIPS
else
dwStyle & = ~CBRS_TOOLTIPS
m_wndToolBar.SetBarStyle (dwStyle )
}
Q?4Q?如何创徏一个不规则形状的窗?br />可以使用新的SDK函数SetWindowRgn。该函数绘d鼠标消息限定在窗口的一个指定的区域Q实际上使窗口成为指定的不规则Ş状?使用AppWizard创徏一个基于对的应用程序ƈ使用资源~辑器从d话资源中删除所在的~省控g、标题以及边界?br />l对话类增加一个CRgn数据成员Q以后要使用该数据成员徏立窗口区域?br />Class CRoundDlg : public CDialog
{
?br />private :
Crgn m_rgn : // window region
?br />}
修改OnInitDialog函数建立一个椭圆区域ƈ调用SetWindowRgn该区域分配l窗口:
BOOL CRoundDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//Get size of dialog .
CRect rcDialog
GetClientRect (rcDialog )
// Create region and assign to window .
m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )
SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE )
return TRUE
}
通过建立区域和调用SetWindowRgnQ已l徏立一个不规则形状的窗口,下面的例子程序是修改OnPaint函数使窗口Ş状看h象一个球形体?br />voik CRoundDlg : : OnPaint ( )
{
CPaintDC de (this) // device context for painting
.
//draw ellipse with out any border
dc. SelecStockObject (NULL_PEN)
//get the RGB colour components of the sphere color
COLORREF color= RGB( 0 , 0 , 255)
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
int 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
int nEllipse = nUnits/3 // calculate how many to
draw
int nIndex
// current ellipse that is being draw
CBrush brush
// bursh used for ellipse fill color
CBrush *pBrushOld // previous
brush that was selected into 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 into dc
pBrushOld= dc .SelectObject (&brhsh)
//draw ellipse
dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex ,
rect. right -( (int) fltStepHorz * nIndex )+ 1,
rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)
//delete the brush
brush.DelecteObject ( )
}
}
最后,处理WM_NCHITTEST消息Q当击打窗口的M位置时能UdH口?br />UINT CRoundDlg : : OnNchitTest (Cpoint point )
{
//Let user move window by clickign anywhere on thewindow .
UINT nHitTest = CDialog : : OnNcHitTest (point)
rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest
}
Q?7Q?如何创徏和用无模式对话?br />MFC模式和无模式对话封装在同一个类中,但是使用无模式对话需要几个对话需要几个额处的步骤。首先,使用资源~辑器徏立对话资源ƈ使用ClassWizard创徏一个CDialog的派生类。模式和无模式对话的中止是不一LQ模式对话通过调用CDialog : : EndDialog 来中止,无模式对话则是调用CWnd: : DestroyWindow来中止的Q函数CDialog : : OnOK和CDialog : : OnCancel调用EndDialog ,所以需要调用DestroyWindowq|无模式对话的函数?br />void CSampleDialog : : OnOK ( )
{
// Retrieve and validate dialog data .
if (! UpdateData (TRUE) )
{
// the UpdateData rountine
will set focus to correct item TRACEO (" UpdateData failed during dialog termination .\n")
return
}
//Call DestroyWindow instead of EndDialog .
DestroyWindow ( )
}
void CSampleDialog : : OnCancel ( )
{
//Call DestroyWindow instead of EndDialog .
DestroyWindow ( )
}
其次Q需要正删除表C对话的C++对象。对于模式对来说Q这很容易,需要创建函数返回后卛_删除C++对象Q无模式对话不是同步的,创徏函数调用后立卌回,因而用户不知道何时删除C++对象。撤销H口时工作框调用CWnd : : PostNcDestroyQ可以重|该函数q执行清除操作,诸如删除this指针?br />void CSampleDialog : : PostNcDestroy ( )
{
// Declete the C++ object that represents this dialog.
delete this
}
最后,要创建无模式对话。可以调用CDialog : : DoModal创徏一个模式对放,要创Z个无模式对话则要调用CDialog: : Create。下面的例子说明 了应用程序是如何创徏无模式对话的Q?象;无模式对话不是同步的Q创建函数调用后立即q回Q?br />void CMainFrame : : OnSampleDialog ( )
{
//Allocate a modeless dialog object .
CSampleDilog * pDialog =new CSampleDialog
ASSERT_VALID (pDialog) Destroy ( )
//Create the modeless dialog . represents this dialog.
BOOL bResult = pDialog ?gt; Create (IDD_IDALOG)
ASSERT (bResult )
}
Q?8Q?如何防止LH口在其说明中显C活动的文档?br />创徏LH口和MDI子窗口进通常hFWS_ADDTOTITLE风格位,如果不希望在说明中自动添加文档名Q?必须止该风gQ?可以使用ClassWizard重置
CWnd: : PreCreateWindowq关闭FWS_ADDTOTITLE风格?br />BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)
{
//Turn off FWS_ADDTOTITLE in main frame .
cs.styel & = ~FWS_ADDTOTITLE
return CMDIFrameWnd : : PreCreateWindow (cs )
}
关闭MDI子窗口的FWS _ADDTOTITLE风格创Z个具有空标题的窗口,可以调用CWnd: : SetWindowText来设|标题。记住自p|标题时要遵循接口风格指南?/p>
Q?0Q?怎样加蝲其他的应用程?
三个SDK函数 winexec, shellexecute,createprocess可以使用?br />WinExec最单,两个参数Q前一个指定\径,后一个指定显C方?后一个参数值得说一下,比如泥用 SW_SHOWMAXMIZED方式d载一个无最大化按钮的程序,是Neterm,calc{等Q就不会出现正常的窗体,但是已经被加CQ务列表里了?br />
ShellExecute?WinExex灉|一点,可以指定工作目录,下面的Example是直接打开 c:\temp\1.txt,而不用加载与 txt文g兌的应用程?很多安装E序完成后都会打开一个窗口,来显CReadme or Faq,我猜是q么作的?
ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:\\temp"),SW_SHOWMAXMIZED)
CreateProcess最复杂Q一共有十个参数Q不q大部分都可以用NULL代替Q它可以指定q程的安全属性,l承信息Q类的优先{等.来看个很单的Example:
STARTUPINFO stinfo
//启动H口的信?br />PROCESSINFO procinfo //q程的信?br />
CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,
NORMAL_PRIORITY_
CLASS,NULL,NULL, &stinfo,&procinfo)
Q?2Q?如何使能和禁止工h的工hC?br />如果讄了CBRS_TOOLTIPS风格位,工具条将昄工具提示Q要使能或者禁止工hC,需要设|或者清除该风格位。下例通过调用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函敎ͼ
void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )
{
ASSERT_VALID (m_wndToolBar)
DWORD dwStyle = m _wndToolBar.GetBarStyle ( )
if (bDisplayTips) dwStyle ?CBRS_TOOLTIPS
else
dwStyle & = ~CBRS_TOOLTIPS
m_wndToolBar.SetBarStyle (dwStyle )
}
//Get pointer to toolbar .
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )
?gt; GetDescendantWindow(AFX_IDW_TOOLBAR)
Q?3Q?如何讄工具条标?br />工具条是一个窗口,所以可以在调用CWnd : : SetWindowText来设|标题,例子如下Q?br />int CMainFrame : : OnCreate (LPCREATESTRUCT lpCreateStruct )
{
?br />// Set the caption of the toolbar .
m_wndToolBar.SetWindowText (_T "Standdard")
}
Q?6Q?如何改变对话或窗体视H的背景颜色
调用CWinApp : : SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色Q第二个参数指定了文本颜艌Ӏ下例将应用E序对话讄色背景和黄色文本?br />BOOL CSampleApp : : InitInstance ( )
{
?br />//use blue dialog with yellow text .
SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 ,255 , 0 ) )
?br />}
需要重d话(或对话的子控ӞӞWindows向对话发送消息WM_CTLCOLORQ通常用户可以让Windows选择l画背景的刷子,也可重置该消息指定刷子。下例说明了创徏一个红色背景对话的步骤?br />
首先Q给对话基类增加一人成员变?br />CBursh :class CMyFormView : public CFormView
{
?br />
private :
CBrush m_ brush // background brush
?br />}
其次Q?在类的构造函C刷子初始化为所需要的背景颜色?br />CMyFormView : : CMyFormView ( )
{
// Initialize background brush .
m_brush .CreateSolidBrush (RGB ( 0, 0, 255) )
}
最后,使用ClassWizard处理WM_CTLCOLOR消息q返回一个用来绘d话背景的刷子句柄。注意:׃当重d话控件时也要调用该函敎ͼ所以要nCtlColor参量?br />HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor
)
{
// Determine if drawing a dialog box . If we are, return +handle to
//our own background brush . Otherwise let windows handle it .
if (nCtlColor = = CTLCOLOR _ DLG )
return (HBRUSH) m_brush.GetSafeHandle ( )
return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor
)
}
Q?9Q?如何改变控g的字?br />׃控g是也是窗口,用户可以调用CWnd: : SetFont指定新字体。该函数用一个Cfont指针Q要保证在控件撤消之前不能撤消字体对象。下例将下压按钮的字体改?点Arial字体Q?br />//Declare font object in class declaration (.H file ).
private : Cfont m_font
// Set font in class implementation (.Cpp file ). Note m_wndButton is a
//member variable added by ClassWizard.DDX routines hook the member
//variable to a dialog button contrlo.
BOOL CSampleDialog : : OnInitDialog ( )
{
?br />//Create an 8-point Arial font
m_font . CreateFont (MulDiv (8 , -pDC
?gt; GetDeviceCaps(LOGPIXELSY) ,72). 0 , 0 , 0 , FW_NORMAL , 0 , 0,0, ANSI_CHARSER, OUT_STROKE_PRECIS ,
CLIP_STROKE _PRECIS , DRAFT _QUALITY
VARIABLE_PITCH |FF_SWISS, _T("Arial") )
//Set font for push button .
m_wndButton . SetFont (&m _font )
?br />}
Q?0Q?如何在OLE控g中用OLE_COLOR数据cd
诸如COleControl : : GetFortColor和COleControl : : GetBackColor{函数返回OLE _COLOR数据cd的颜Ԍ而GDI对象诸如W和刷子使用的是COLORREF数据cdQ调用COleControl : : TranslateColor可以很容易地OLE_COLORcd改ؓCOLORREFcd。下例创Z一个当前背景颜色的刷子Q?br />
void CSampleControl : : OnDraw (CDC* pdc
const Crect& rcBounds , const Crect& rcInvalid
)
{
//Create a brush of the cuttent background color.
CBrush brushBack (TranslateColor (GetBackColor () ) )
//Paint the background using the current backgroundcolor .
pdc?gt; FilllRect (rcBounds , &brushBack)
//other drawign commands
?br />}
Q?2Q?Z么旋转按钮控件看h倒{
需要调用CSpinCtrl : : SetRange 讄旋{按钮控g的范_旋{按钮控g的缺省上限ؓ0Q缺省下限ؓ100Q这意味着增加时旋转按控g的值由100变ؓ0。下例将旋{按钮控g的范围设|ؓ0?00Q?br />BOOL CAboutDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//set the lower and upper limit of the spin button
m_wndSpin . SetRange ( 0 ,100 )
return TRUE
}
Visual C++ 4.0 Print对话中的Copise旋{按钮控g也有同样的问题:按下Up按钮时拷贝的数目减少Q而按下Down 按钮时拷贝的数目增加?/p>
Q?3Q?Z么旋转按钮控件不能自动地更新它下面的~辑控g
如果使用旋{按钮的autu buddyҎ, 则必M证在对话的标记顺序中buddyH口优先于旋转按钮控件。从Layout菜单中选择Tab Order菜单(或者按下Crtl+DQ可以设|对话的标签序?/p>
Q?4Q?如何用位图显CZ压按?br />Windows 95按钮有几处新的创建风|其是BS_BITMAP和BS_ICONQ要惛_有位图按钮,创徏按钮和调用CButton : : SetBitmap或CButton : : SetIcon时要指定BS_BITMAP或BS_ICON风格?br />
首先Q设|按钮的图标属性。然后,当对话初始化时调用CButton: : SetIcon。注意:下例用图标代替位图,使用位图时要心Q因Z知道背景所有的颜色——ƈ非每个h都用浅灰色?br />
BOOL CSampleDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//set the images for the push buttons .
BOOL CSampleDlg : : OnInitDialog ( )
{
CDialog : : OnInitDialog ( )
//set the images for the push buttons .
m_wndButton1.SetIcon (AfxGetApp ( ) ?gt; LoadIcon (IDI _ IPTION1))
m_wndButton2.SetIcon (AfxGetApp ( ) ?gt; LoadIcon (IDI _ IPTION2))
m_wndButton3.SetIcon (AfxGetApp ( ) ?gt; LoadIcon (IDI _ IPTION3))
return TRUE
}
Q?5Q?如何一个创Z态下压按?br />可以使用新的BS_PUSHBUTTON 风格位和框以及按钮来创Z个三态下压按钮。这很容易,只需检框和按钮拖拉到对话中ƈ指定属性Push—like卛_。不用Q何附加程序就可以成ؓ三态下压按钮?/p>
Q?6Q?如何动态创建控?br />分配一个控件对象的实例q调用其Create成员函数。开发者最Ҏ忽略两g事:忘记指定WS_VISBLE标签和在栈中分配控g对象。下例动态地创徏一个下压按钮控Ӟ
//In class declaration (.H file ).
private : CButton* m _pButton
//In class implementation (.cpp file ) .
m_pButton =new CButton
ASSERT_VALID (m_pButton)
m_pButton ?gt;Create (_T ("Button Title ") , WS_CHILD |WS_VISIBLE |BS_PUSHBUTTON. Crect ( 0, 0, 100 , 24) , this , IDC _MYBUTTON )
Q?7Q?如何限制~辑框中的准许字W?br />如果用户在编辑控件中只允许接收数字,可以使用一个标准的~辑控gq指定新的创建标志ES_NUMBERS,它是Windows 95新增加的标志Q该标志限制 ~辑控g只按收数字字W。如果用户需要复杂的~辑控gQ可以用Microsoft 的屏蔽编辑控Ӟ它是一个很有用的OLE定制控g?br />如果希望不用OLE 定制控g自己处理字符Q可以派生一个CEditcdƈ处理WM_CHAR消息Q然后从~辑控g中过滤出特定的字W。首先,使用ClassWizard建立一?CEdit的派生类Q其ơ,在对话类中指定一个成员变量将~辑控g分类在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 ( )
{
?br />
//Subclass the edit lontrod .
m_wndEdit .SubclassDlgItem (IDC_EDIT,this)
?br />}
使用ClassWizard处理WM_CHAR消息Q计nChar参量q决定所执行的操作,用户可以定是否修改、传送字W。下例说明了如何昄字母字符Q如果字W是字母字符Q则调用CWnd OnCharQ否则不调用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 )
}
如果要修改字W,则不能仅仅简单地用修改过的nChar调用CEdit: : OnCharQ然后CEdit: : OnChar调用CWnd: : Default获取原来的wParam 和lParam 的|q样是不行的。要修改一个字W,需要首先修改nCharQ然后用修改q的nChar调用CWnd: : DefWindowProc。下例说明了如何字W{变ؓ大写Q?br />//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 ))
}
Q?8Q?如何改变控g的颜?br />有两U方法。其一Q可以在父类中指定控件的颜色Q或者利用MFC4.0新的消息反射在控件类中指定颜艌Ӏ?当控仉要重新着色时Q工作框调用父窗口(通常是对话框Q的CWnd: : OnCrtlColor,可以在父H口cM重置该函数ƈ指定控g的新的绘d性。例如,下述代码对话中的所有编辑控件文本颜色改为红Ԍ
HBRUSH CAboutDig : : OnCtlColor (CDC * pDCM , CWnd * pWnd , UINT nCtlColor)
{
HBRUSH hbr = CDialog : : OnCtlColor (pDC, pWnd , nCtlColor )
//Draw red text for all edit controls .
if (nCtlColor= = CTLCOLOR_EDIT )
pDC ?gt; SetTextColor (RGB (255, 0 , 0 , ) )
return hbr
}
然而,׃每个父窗口必d理通知消息q指定每个控件的l画属性,所以,q种Ҏ不是完全的面向对象的Ҏ。控件处理该消息q指定绘d性更合情合理。消息反允许用戯样做。通知消息首先发送给父窗口,如果父窗口没有处理则发送给控g。创Z个定制彩色列表框控g必须遵@下述步骤?br />
首先Q用ClassWizard 创徏一个CListBox 的派生类qؓ该类d下述数据成员?br />class CMyListBox publilc CListBox
{
?br />private
COLORREF m_clrFor // foreground color
COLORREF m_clrBack //background color
Cbrush m_brush //background brush
?br />}
其次Q在cȝ构造函CQ初始化数据中?br />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)消息q指定新的绘d性?br />HBRUSH CMyListBox : : CtlColor (CDC* pDC, UINT nCtlColor )
{
pDC?gt;SetTextColor (m_clrFore)
pDC?gt;SetBkColor (m_clrBack)
return (HBRUSH) m_brush.GetSafeHandle ()
}
现在Q控件可以自己决定如何绘画,与父H口无关?/p>
Q?9Q?当向列表框中d多个Ҏ如何防止闪烁
调用CWnd::SetRedraw 清除重画标志可以止CListBoxQ或者窗口)重画。当向列表框d几个ҎQ用户可以清除重L志,然后d,最后恢复重L志。ؓ保重画列表框的新项Q调用SetRedraw (TRUE) 之后调用CWnd::Invalidate?br />//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 ()
Q?0Q?如何向编辑控件中d文本
׃没有CEdit:: AppendText函数Q用户只好自己做此项工作。调用CEdit:: SetSelUd到编辑控件末,然后调用CEdit:: ReplaceSeld文本。下例是AppendText 的一U实现方法:
void CMyEdit:: AppendText (LPCSTR pText)
{
int nLen=GetWindowTextLength ()
SetFocus ()
SetSel (nLen, nLen)
ReplaceSel (pText)
}
Q?1Q?如何讉K预定义的GDI对象
可以通过调用CDC:: SlectStockObject使用Windows的几个预定义的对象,诸如刷子、笔以及字体。下例用了Windows预定义的W和刷子GDI对象在视H中M个椭圆?br />//Draw ellipse using stock black pen and gray brush.
void CSampleView:: OnDraw (CDC* pDC)
{
//Determine size of view.
CRect rcView
GetClientRect (rcView)
//Use stock black pen and stock gray brush to draw ellipse.
pDC->SelectStockObject (BLACK_PEN)
pDC->SelectStockObject (GRAY_BRUSH)
//Draw the ellipse.
pDC->Ellipse (reView)
}
也可以调用新的SDK函数GetSysColorBrush获取一个系l颜色刷子,下例用背景色在视H中M个椭圆:
void CsampleView:: OnDraw (CDC* pDC)
{
//Determine size of view.
CRect rcView
GetClientRect (rcView)
//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)
}
Q?2Q?如何获取GDI对象的属性信?br />可以调用GDIObject:: GetObject。这个函数将指定图表讑֤的消息写入到~冲区。下例创Z几个有用的辅助函数?br />//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)
}
Q?3Q?如何实现一个橡皮区矩Ş
CRectTracker是一个很有用的类Q可以通过调用CRectTracker::TrackRubberBand 响应WM_LBUTTONDOWN消息来创Z个橡皮区矩Ş?br />下例表明使用CRectTrackerUd和重|视H中的蓝色椭圆的大小是很Ҏ的事情?br />
首先Q在文g档中声明一个CRectTracker数据成员Q?br />class CSampleView : Public CView
{
?br />public :
CrectTracker m_tracker
?br />}
其次Q在文cȝ构造函C初始化CRectTracker 对象Q?br />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
}
然后Q在OnDraw函数中画椭圆和踪q矩形:
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消息Qƈ增加下述代码。该D代码根据鼠标击键情况可以拖放、移动或者重|椭圆的大小?br />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)
}
Q?4Q?如何更新{背景颜色的文?br />调用CDC:: SetBkmodeq传送OPAQUE用当前的背景颜色填充背景Q或者调用CDC::SetBkModeq传送TRANSPAARENT使背景保持不变,q两U方法都可以讄背景模式。下例设|背景模式ؓTRANSPARENTQ可以两ơ更CQ用p带黑阴媄更新文本。黑色串在红色串之后Q但׃讄了背景模式仍然可见?br />
void CSampleView:: OnDraw (CDC* pDC)
{
//Determint size of view.
CRect rcView
GetClientRect (rcVieew)
//Create sample string to display.
CString str (_T ("Awesome Shadow TextQ.Q?))
//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)
}
Q?5Q?如何创徏一个具有特定点大小的字?br />可以指定字体逻辑单位的大,但有时指定字体的点的大小可能会更方便一些。可以如下将字体的点转换为字体的高度Q?br />
int nHeigth=mulDiv (nPointSize, -dc.GetDeviceCaps (LOGPIXELSY), 72)
下例创徏了一?点的Apial字体Q?br />?br />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"))
Q?6Q?如何计算一个串的大?br />函数CDC:: Det text Extent Ҏ当前选择的字体计一个串的高度和宽度。如果用的不是pȝ字体而是其他字体Q则在调用GetTextExtent之前字体选进讑֤上下文中是很重要的,否则计算高度和宽度时依据系l字体,由此得出的结果当然是不正的。下q样板程序当改变下压按钮的标题时动态调整按钮的大小Q按钮的大小由按钮的字体和标题的大小而定。响应消息WM_SETTEXT时调用OnSetTextQ该消息使用ON_MESSAE宏指令定义的用户自定义消息?br />
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
}
Q?7Q?如何昄旋{文本
只要用户使用TrueType或者GDIW或字体可以显C旋转文?有些g讑֤也支持旋转光栅字体)。LOGFONTl构中的ifEscapement成员指定了文本行和x轴的角度Q角度的单位是十分之一度而不是度Q例如,ifEscapement?50表示字体旋{45度。ؓ保所有的字体沿坐标系l的同一方向旋{Q一定要讄ifEscapement成员的CLIP_LH_ANGLES位,否则Q有些字体可能反向旋转。下例用了14点Arial字体每间?5度画一个串?br />void CSampleView:: OnDraw (CDC* pDC)
{
//Determine the size of the window.
CRect rcClient
GetClientRect (rcClient)
//Create sample string.
CString str (_T ("WheeeeQ.QI 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()
}
}
Q?8Q?如何正确昄包含标签字符的串
调用GDI文本l画函数旉要展开标签字符Q这可以通过调用CDC:: TabbedTextOut或者CDC:: DrawTextq指定DT_EXPANDTABS标志来完成。TabbedTextOut函数允许指定标签位的数组Q下例指定每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)
}
Q?9Q?如何快速地格式化一个CString对象
调用CString:: FormatQ该函数和printf函数h相同的参敎ͼ下例说明了如何用Format函数Q?br />
//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)
Q?0Q?串太长时如何在其末尾昄一个省略号
调用CDC:: DrawTextq指定DT_END_ELLIPSIS标志Q这样就可以用小略号取代串末字符使其适合于指定的边界矩Ş。如果要昄路径信息Q指定DT_END_ELLIPSIS标志q省略号取代串中间的字符?br />
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)
}
Q?1Q?Z么即使调用EnableMenuItem菜单后Q菜单项q处于禁止状?br />需要将CFrameWnd:: m_bAutomenuEnable讄为FALSEQ如果该数据成员为TRUEQ缺省|Q工作框自动地止没有ON_UPDATE_COMMAND_UI或者ON_COMMAND的菜单项?br />
//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)
Q?2Q?如何l系l菜单添加一个菜单项
l系l菜单添加一个菜单项需要进行下qC个步骤:
首先Q用Resource Symbols对话Q在View菜单中选择Resource SymbolsQ.Q可以显C对话Q定义菜单项IDQ该ID应大?x0F而小?xF000Q?br />其次Q调用CWnd::GetSystemMenu获取pȝ菜单的指针ƈ调用CWnd:: Appendmenu菜单项d到菜单中。下例给pȝ菜单d两个新的
int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)
{
?br />//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)
?br />}
现在Q选择pȝ菜单Ҏ用户应进行检。用ClassWizard处理WM_SYSCOMMAND消息q检用戯单的nID参数Q?br />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
}
else
CMDIFrameWnd ::OnSysCommand (nID, lParam)
}
最后,一个设计良好的UI应用E序应当在系l菜单项加亮时在状态条昄一个帮助信息,q可以通过增加一个包含系l菜单基ID的串表的入口来实现?/p>
Q?3Q?如何定层菜单所占据的菜单行?br />q可以通过单的减法和除法来实现。首先,用户需要计主框窗口的高度和客户区Q其ơ,从主框窗口的高度中减d户区、框边界以及标题的高度;最后,除以菜单栏的高度。下例成员函数是一个计主框菜单所占据的行数的代码实现?br />
int CMainFrame:: GetMenuRows ()
{
CRect rcFrame,rcClient
GetWindowRect (rcFrame)
GetClientRect (rcClient)
return (rcFrame.Height () -rcClient.Height () - :: GetSystemMetrics(SM_CYCAPTION) - (:: getSystemMetrics(SM_CYFRAME) *2)) / :: GetSystemMetrics(SM_CYMENU)
}
Q?4Q?在用L境中如何定pȝ昄元素的颜?br />调用SDK函数GetSysColor可以获取一个特定显C元素的颜色。下例说明了如何在MFC函数CMainFrameWnd:: OnNcPaint中调用该函数讄H口标题颜色?br />
void CMiniFrameWnd:: OnNcPaint ()
{
?br />dc.SetTextColor (:: GetSysColor (m_bActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT))
?/p>
Q?5Q?如何查询和设|系l参?br />在Windows 3.1 SDK中介l过SDK函数SystemParametersInfoQ调用该函数可以查询和设|系l参敎ͼ诸如按键的重复速率讄、鼠标双dgq时间、图标字体以及桌面覆盖位囄{?br />
//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)
Q?6Q?如何定当前屏幕分L?br />调用SDK函数GetSystemMetricsQ该函数可以索有关windows昄信息Q诸如标题大、边界大以及滚动条大小{等?br />
//Initialize CSize object with screen size.
CSize sizeScreen (GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN))
Q?7Q?如何使用一个预定义的Windows光标
调用CWinApp:: LoadStandardCursorq传送光标标识符?br />BOOL CSampleDialog:: OnSetCursor (CWnd* pWnd,
UINT nHitTest, UINT
message)
{
//Display wait cursor if busy.
if (m_bBusy)
{
SetCursor (AfxGetApp () ->LoadStandardCursor (IDC_WAIT))
return TRUE
}
return CDialog:: OnSetCursor (pWnd. nHitTest,message)
}
Q?8Q?如何索原先的Task Manager应用E序使用的Q务列?br />原先的Task Manager应用E序昄层H口的列表。ؓ了显C列表Q窗口必d见、包含一个标题以及不能被其他H口拥有。调用CWnd:: GetWindow可以索顶层窗口的列表Q调用IsWindowVisible、GetWindowTextLength以及GetOwner可以定H口是否应该在列表中。下例将把TaskManagerH口的标题填充到列表中?br />
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)
}
}
Q?9Q?如何定Windows和Windowspȝ目录
有两个SDK函数可以完成该功能。GetWindowsDirectory和GetSystemDirectoryQ下例说明了如何使用q两个函敎ͼ
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)
Q?0Q?在哪儿创Z文g
调用SDK函数GetTemPath可以定临时文g的目录,该函数首先ؓ临时路径TMP环境变量Q如果没有指定TMPQ检TMP环境变量Q然后返回到当前目录。下例说明了如何创徏一个时文件?br />
?br />//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
?br />
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
}
Q?1Q?我怎样才能建立一个等待光?
??BeginWaitCursor ?????{???标,??EndWaitCursor ???l??{???标。要 ?意,??????app ????敎ͼ??所 C?
AfxGetApp()->BeginWaitCursor();
// 要做的事
AfxGetApp()->EndWaitCursor();
Q?2Q?我在MDI框架中有?form 视窗。它有个取消按钮Q我需要当用户按取消按钮时可关闭form视窗。我应该如何关闭该文?
??OnCloseDocument ?数?/p>
Q?3Q?如何讉K桌面H口
静态函数CWnd:: GetDesktopWindow q回桌面H口的指针。下例说明了MFC函数CFrameWnd::BeginModalStae是如何用该函数q入内部H口列表的?br />
void CFrameWnd::BeginModalState ()
{
?br />//first count all windows that need to be disabled
UINT nCount=0
HWND hWnd= :: GetWindow (:: GetDesktopWindow(), GW_CHILD)
while (hWnd!=NULL)
{
if (:: IsWindowEnabled (hwnd)
&& CWnd::FromHandlePermanent (hWnd)!=NULL
&& AfxIsDescendant (pParent->m_hWnd, hWnd)
&& :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)==0)
{
++nCount
}
hWnd=:: GetWindow (hWnd, GW_HWNDNEXT)
}
?/p>
Q?6Q?我在我的E序中是了CDWordArray。我向它d了约10,000个整敎ͼq得它变得非常非常慢。ؓ什么会q么p?
CDWordArray ????的,??????????l?的最大尺寸。因 此,???????Ӟ?c?????????I?间。不 q??是,?c??????????????l?????I?间。如 ???????????素,所 ?q????????l??????????慢。解 ???????是,?????SetSize ???W????????q?U???????率。例 如,????????|??500Q则 ???l?I???????????q???500 ??I?_???1 个。这 ?一 来,????????????????499 ???I?_q???????E???q???度?/p>
Q?7Q?我该如何改变MDI框架H口的子H口的大以使在H口以一定的大小打开?
????OnInitialUpdate ?????GetParentFrame ?数。GetParentFrame ?q??一 ??一 ????????H????针。然 ??????H?????MoveWindow?/p>
Q?8Q?在我的程序的某些部分Q我可以调用 MessageBox 函数来徏立一个信息对话框Q例如在视类中。但是,在其它部分我却不能,如文档类中。ؓ什么?我怎样才能在我的应用程序类中徏立一个信息对话框Q?br />MessageBox ????CWnd c,所 ??????CWnd l???c?( ?CView ) ???它。但 是,MFC ????AfxMessageBox ?敎ͼ??????????它?/p>
Q?9Q?我需要在我的E序中设|全局变量Q以使文中的所有类都能讉K。我应该吧它攑ֈ哪儿?
?????????E??c???????attribute 处。然 后,?E??????方,???????????????量:
CMyApp *app = (CMyApp *)AfxGetApp();
app->MyGlobalVariable = ...
Q?1Q?我怎样才能在我的应用程序中循环览已经打开的文?
使用CDocTemplate中未公开的GetFirstDocPosition()和GetNextDoc()函数?
Q?2Q才能在我的应用E序中@环浏览已l打开的视?
??CDocument ???开 ?GetFirstViewPosition() ?GetNextView() ?数?/p>
Q?3Q数PreCreateWindow是干什么用?
PreCreateWindow ??????CreateWindow ?????H???性?/p>
Q?4Q该怎样防止MFC在窗口标题栏上把文名预|成应用E序?
?PreCreateWindow ?????FWS_PREFIXTITLE ???H???式:
cs.style &= ~FWS_PREFIXTITLE;
Q?5Q?我应该怎样防止MFC在窗口标题栏上添加文名?
?PreCreateWindow ?????FWS_ADDTOTITLE ???H???式:
cs.style &= ~FWS_ADDTOTITLE ;
Q?6Q?我应该如何改变视H口的大?
???H????????H????H?口,所 ????????H????,??????H?口。 ?CView c???GetParentFrame() ????????H????针,????MoveWindow() ?????????。这 ???????????H?口?/p>
Q?7Q?我有一无模式对话框。我怎样才能在窗口退出时删除CDialog对象?
把“delete this”加 ?PostNcDestroy 中。这 ????需 ?????????合?/p>
Q?8Q?Z么把“delete this”放在PostNcDestroy中而不是OnNcDestroy?
OnNcDestroy ??????H???用。如 ???H????( ?PreCreateWindow )Q则 ??H??????WM_NCDESTROY ?息。PostNcDestroy ????H??????除,?OnNcDestroy 后,???H??????????的?/p>
Q?9Q?File菜单中的MRU列表是从哪儿来的Q列表中的名字放在哪儿了Q我怎样才能改变列表中项目的最大|
???E??c??InitInstance ????LoadStdProfileSettings ???中。该 ????一 ???( ?~??????????????4 )。MRU ?????INI ?????的。如 ?????ID_FILE_MRU_FILE1 ?ID ????,??????MRU ??所 ?换。如 ??????l?LoadStdProfileSettings ???( 最 ??16 )Q则 ?????所 ??????最 ?倹{?/p>
Q?0Q?我在菜单中添加了新的V但是,当我选该ҎQ在状态栏上没有出CQ何提CZ息。ؓ什?
?开 ?????????ѝ打 开 ??????????框。在 ???????Prompt ~????Q你 ????????????C??????????C???( ????l?????????):
Status bar string\nFlying tag
Q?2Q?我徏立了一个对话框。但是当我显C对话框时Q第一个编辑框L不能获得焦点Q我必须单击它来使它获得焦点。我怎样才能使第一个编辑框在对话框打开时就获得焦点?
?开 ??~?????????ѝ在 Layout 菜单 ???Tab Order ?V按 ??需 ???????????????q?????tab ?序?/p>
Q?3Q?我怎样才能使一个窗口具有“always on top”特?
???OnFileNew 后,???InitInstance ?????????码:
m_pMainWnd->SetWindowPos(&CWnd::wndTopMost,0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
(94) 我要为我的form viewd文模板。我先徏立了对话框模板,然后使用ClassWizard建立了基于CFormView的新c,它也是从CDocumentl承来的。我q徏立了相应的资源ƈ在InitInstance中添加了新的文模板。但是,当我试图q行该程序时Q出CAssertion信息。ؓ什?
form ??????需 ???D??|??????CFromView。确 ?q???|??最 ??????AppWizard ???CFormView ??E?序,q???AppWizard 所 ????????所 ??的Styles Properties。你 ??????????????式:????栏、不 ??和“Child”。把 ??form view ????????q?????了?br />
(95) 我在一对话框中有一列表框,我需要tabbed列表框中的项目。但是,当我处理含有tab字符(用AddStringd?的列表项Ӟtab被显C成黑块而没有展开。哪儿出错了?
??????中,?开 ?????性。确 ???了“Use Tabstops??式。然 后,??????c??OnInitDialog ?????SetTabStops?br />
(96) 我徏立了一个应用程序,q用了CRecordsetcR但是,当我q行该程序时Q它试图要访问数据库Qƈl出“Internal Application Error”对话框。我应该怎样?
????下,???E????????????SQL ?????????????框。例 如,??????子:
set.m_strFilter = "(ZipCode = '27111')";
??ZipCode ??????W????????题,?????longQ则 ??现“Internal Application Error”对 ?框,q????c??????~?故。如 ????27111 ???P??????题。当 ??到“Internal Application Error”时Q最 ? ?一 ??????l?????SQL ?句?br />
(98) 当我打开应用E序中的H口Ӟ我要传递该H口的矩形尺寸。该矩Ş指定了窗口的外围大小Q但是当我调用GetClientRectӞ所得到的尺寸要比所希望的D?因ؓ工具栏和H口Ҏ的缘?。有其它Ҏ来计窗口的寸?
??CWnd::CalcWindowRect?br />
(99) 我在文cM讄了一个整型变量。但是,当我试图把该变量写入Serialize函数中的archive文g中时Q出Ccd错误。而文中的其它变量没有问题。ؓ什?
archive c??????c???>> ?<< ??W。“int”类 ?????中,?????int ???Windows 3.1 ?Windows NT/95 ?所 ???~??吧。“long”类 ?????持,所 ?????int c????long 型。参 ?MFC ?????CArchive cR?br />
(100) 如何控制菜单的大?
我用MFC的CMenu生成了一个动态菜?例如File,Edit,View...Help), 我想控制q个菜单的大???.
Ҏ一:查找 WM_MEASUREITEM ?MEASUREITEMSTRUCT.
Ҏ?查询pȝ::GetSystemMetric(SM_CXMENUSIZE).
/* 你可以通过如下代码来获得文本的大小:
(A)获得被用的字体 */
NONCLIENTMETRICS ncm;
HFONT hFontMenu;
SIZE size;
size.cy = size.cy = 0;
memset(&ncm, 0, sizeof(NONCLIENTMETRICS));
ncm.cbSize = sizeof(NONCLIENTMETRICS);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(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);
GetTextExtentPoint32(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提供的公共控?允许有你自己的代?
Ҏ?生成一个draw控g,然后在DrawItem中处理文本颜?
(102) 如何只存储文的某一部分?
我只惛_储文的某一部分,能否象用文件一样用文?(也就是有定位函数).每个CArchivec设|ؓCFilecȝzc?q样你就能用Seek{成员函?
(103) 保存工具条菜单有bug?
使用动菜单条时,SaveBarState和LoadBarState出现了问?如果菜单是Q动的,重v应用E序时它会出现在左上?而它固定在屏q其它位|时,下一ơ启动就会出现在该位|?q是什么原?你试试这个PToolBar->Create(this,...,ID_MYTOOLBAR);
你的工具条需要包括id,而不是象默认的工h那样.
(104) Tip of the day的bug
我创Z一个简单的mdi应用E序,使用.BSF(自定义的文扩展?作ؓ它的文我保存一个foo.bsf文?可以在资源管理器中双击该文g打开mdi应用E序同时打开foo.bsf文.但当我给mdi应用E序加上a tip of the daylg之后,从资源管理器中双击foo.bsf?׃l我一个警?ASSERT(::IsWindow(m_hWnd)),然后mdi应用E序死那了.
当从dde启动应用E序(例如:双击相关文)?"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);
if (
cmdInfo.m_bShowSplash &&
cmdInfo.m_nShellCommand != CCommandLineInf:FileDDE
)
{
CTipDlg dlg;
if (dlg.m_bStartup)
dlg.DoModal();
}
}
如果q有其它bug,你可以设定cmdInfo.m_nShellCommand的过?
(105) 如何可以让我的程序可以显C在其它的窗口上?
让用户选择"L在最上面"最好是在系l菜单里加入一个选项.可以通过修改WM_SYSCOMMAND消息来发送用L选择.菜单的命令标?id)会作Z个参ClOnSysCommand().要定义标?id),如下代码加入到CMainFrame.CPP?
#define WM_ALWAYSONTOP WM_USER + 1
?d最上面"的菜单项加入到系l菜单中,如下代码加入到函数CMainFrame::OnCreate()?
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, WM_ALWAYSONTOP,
"&Always On Top");
使用ClassWizard,加入对WM_SYSCOMMAND消息的处?你应该改变消息过滤器,使用pȝ可以处理q个消息.
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
switch ( nID )
{
case WM_ALWAYSONTOP:
if ( GetExStyle() & WS_EX_TOPMOST )
{
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
GetSystemMenu(FALSE)->CheckMenuItem(WM_ALWAYSONTOP,
MF_UNCHECKED);
}
else
{
SetWindowPos(&wndTopMost, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
GetSystemMenu(FALSE)->CheckMenuItem(WM_ALWAYSONTOP,MF_CHECKED);
}
break;
default:
CFrameWnd::OnSysCommand(nID, lParam);
}
}
(106) 如何控制H口框架的最大最尺?
要控制一个框架的的最大最尺?你需要做两g事情.在CFrameWnd的承类中处理消息WM_GETMINMAXINFO,l构MINMAXINFO讄了整个窗口类的限?因此C要考虑工具?卷动条等{的大小.
// 最大最尺寸的象素?- CZ
#define MINX 200
#define MINY 300
#define MAXX 300
#define MAXY 400
void CMyFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
CRect rectWindow;
GetWindowRect(&rectWindow);
CRect rectClient;
GetClientRect(&rectClient);
// get offset of toolbars, scrollbars, etc.
int nWidthOffset = rectWindow.Width() - rectClient.Width();
int nHeightOffset = rectWindow.Height() - rectClient.Height();
lpMMI->ptMinTrackSize.x = MINX + nWidthOffset;
lpMMI->ptMinTrackSize.y = MINY + nHeightOffset;
lpMMI->ptMaxTrackSize.x = MAXX + nWidthOffset;
lpMMI->ptMaxTrackSize.y = MAXY + nHeightOffset;
}
W二?在CFrameWnd的承类的PreCreateWindow函数中去掉WS_MAXIMIZEBOX消息,否则在最大化时你得不到预料的结?
BOOL CMyFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~WS_MAXIMIZEBOX;
return CFrameWnd::PreCreateWindow(cs);
}
(107) 如何改变H口框架的颜?
MDI框架的客户区被另一个窗口的框架所覆盖.Z改变客户区的背景?你需要重画这个客L?Z做到q点,你要处理消息WM_ERASEBKND产生一个新c?从CWndl承,姑且UC为CMDIClient.l它加上一个成员变?
#include "MDIClient.h"
class CMainFrame : public CMDIFrameWnd
{
...
protected:
CMDIClient m_wndMDIClient;
}
在CMainFrame中重载CMDIFrameWnd::OnCreateClient
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if ( CMDIFrameWnd::OnCreateClient(lpcs, pContext) )
{
m_wndMDIClient.SubclassWindow(m_hWndMDIClient);
return TRUE;
}
else
return FALSE;
}
然后可以加入对消息WM_ERASEBKGND的处理了.
(108) 如何应用程序窗口置于屏q正?
要将你的应用E序H口攄在屏q正中央,只须在MainFrame的OnCreate函数中加?
CenterWindow( GetDesktopWindow() );