新建一个工程,MFC单文档,名字为Test,单文档。
改变应用程序外观,应该在窗口创建之前修改。改变框架窗口的大小和外观,在BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)中修改。
下面的程序是在窗口创建之前修改:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.cx=200;
cs.cy=300;
cs.style &=~ FWS_ADDTOTITLE;
//cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;//或者这样也可以。
cs.lpszName="标题";//将文档标题改为自己的标题,因为系统的SDI的style=WS_OVERLAPPEDWINDOW and FWS_ADDTOTITLE
return TRUE;
}
下面的代码是在窗口创建之后修改:
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)&~WS_MAXIMIZEBOX );//没有了最大化框。
修改窗口的图标,光标,背景。
在BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)中添加:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
WNDCLASS wdcls;
wdcls.cbClsExtra=0;
wdcls.cbWndExtra=0;
wdcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wdcls.hCursor=LoadCursor(NULL,IDC_HELP);
wdcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wdcls.hInstance=AfxGetInstanceHandle( );
wdcls.lpfnWndProc=::DefWindowProc;
wdcls.lpszClassName="newclass";
wdcls.lpszMenuName=NULL;//不会影响菜单的创建
wdcls.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wdcls);
cs.lpszClass="newclass";
return TRUE;
}
运行结果,仅ICON改变。背景和光标没有改变。(它们是VIEW类的,不是框架类的,要改变应该在VIEW类中);
下面代码:
BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.lpszClass="newclass";
return CView::PreCreateWindow(cs);
}
在框架类中只能修改图标,下面是另一种方法:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
cs.lpszClass=AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,0,0,
::LoadIcon(NULL, IDI_APPLICATION));
return TRUE;
}
在VIEW类中修改光标,背景色。
BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.lpszClass=AfxRegisterWndClass(
CS_VREDRAW | CS_HREDRAW,
::LoadCursor(NULL, IDC_HELP),
(HBRUSH) ::GetStockObject(BLACK_BRUSH),0);
return CView::PreCreateWindow(cs);
}
在窗口创建之后,修改也可以用下面的方法:
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
在int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
return 0;
}
下面完成一个不断变化的图标:
创建三个ICON。
为框架类添加:
private:
HICON m_hicon[3];
准备三幅图标:
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
前添加:
extern CTestApp theApp;
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
m_hicon[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
m_hicon[1]=LoadIcon(AfxGetApp( )->m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
m_hicon[2]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
SetTimer(1,1000,NULL);
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
static int i=0;
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hicon[0]);
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hicon[++i%3]);
CFrameWnd::OnTimer(nIDEvent);
}
下面是工具栏的编程:
为框架栏增加:
CToolBar m_newToolBar;
在资源中增加一个新的工具栏。
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加下列代码:
if (!m_newToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_newToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("Failed to create toolbar/n");
return -1; // fail to create
}
m_newToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_newToolBar);
添加一个显示新工具栏的菜单项。并加上标记。
void CMainFrame::OnNewToolbar()
{
// TODO: Add your command handler code here
if (m_newToolBar.IsVisible())
{
ShowControlBar( &m_newToolBar,FALSE,FALSE);// ShowControlBar可以显示一个控件在原先的位置上。
}
else
{
//m_newToolBar.ShowWindow(SW_SHOW);
ShowControlBar( &m_newToolBar,TRUE,FALSE);
}
}
或者:
void CMainFrame::OnNewToolbar()
{
// TODO: Add your command handler code here
CRect rect; //rect是用来存贮工具栏浮动时的位置的
CFrameWnd* pParentFrame = m_newToolBar.GetDockingFrame();
if(m_newToolBar.IsFloating())
{
pParentFrame->GetWindowRect(&rect);//获取工具栏位置,并存贮在rect中
}
if(m_newToolBar.IsWindowVisible())
{
m_newToolBar.ShowWindow(SW_HIDE);
}
else
{
m_newToolBar.ShowWindow(SW_SHOW);
}
RecalcLayout();
DockControlBar(&m_newToolBar);
if(!rect.IsRectEmpty())
{
FloatControlBar(&m_newToolBar,CPoint(rect.left,rect.top));//使工具栏浮动到
}
}
//上面对比一下,就可以知道ShowControlBar的使用方便了。
void CMainFrame::OnUpdateNewToolbar(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (m_newToolBar.IsVisible())
{
pCmdUI->SetCheck(1);
}
else
{
pCmdUI->SetCheck(0);
}
}
下面是状态栏的编程:
在框架中:
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
ID_TIME,//show time
ID_PROCESS//show process
};
在资源视图中的STRING中加入对ID_TIME和ID_PROCESS的说明;
创建一个定时器,来显示时间。
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CString str;
CTime t = CTime::GetCurrentTime();
str=t.Format("%H:%M:%S");
m_wndStatusBar.SetPaneText( 4, str);
CFrameWnd::OnTimer(nIDEvent);
}
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
CString str;
CTime t = CTime::GetCurrentTime();
str=t.Format("%H:%M:%S");
CClientDC dc(this);
CSize size=dc.GetTextExtent(str) ;
m_wndStatusBar.SetPaneInfo( 4, ID_TIME, SBPS_NORMAL, size.cx );
m_wndStatusBar.SetPaneText( 4, str);
下面创建一个进度栏:
为框架类增加:CProgressCtrl myCtrl;
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
CRect rect;
m_wndStatusBar.GetItemRect( 5, &rect );
myCtrl.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH, rect, &m_wndStatusBar, 1);
//这样得到的rect是得不到的。因为在这时窗口在创建,是得不到窗口的区域大小的。
myCtrl.SetPos(50);
myCtrl.SetRange( 0, 100 );
为此代码修改如下:
在头文件中:#define UM_PROCRESS WM_USER+1(2:02)
afx_msg void OnProgress();
在。CPP中添加:
ON_MESSAGE(UM_PROCRESS,OnProgress)
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
PostMessage(UM_PROCRESS);
void CMainFrame::OnProgress()
{
CRect rect;
m_wndStatusBar.GetItemRect( 5, &rect );
myCtrl.Create(WS_CHILD|WS_VISIBLE/*|PBS_SMOOTH*/, rect, &m_wndStatusBar, 1);
//这样得到的rect是得不到的。因为在这时窗口在创建,是得不到窗口的区域大小的。
myCtrl.SetPos(50);
myCtrl.SetRange( 0, 100 );
}
上面的代码,当窗口变化的时候,进度栏会变化。下面是改进的代码:
PostMessage(UM_PROCRESS);这句代码不要了。
OnProgress()消息删除。
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rect;
m_wndStatusBar.GetItemRect( 5, &rect );
if (!myCtrl.m_hWnd)
{
myCtrl.Create(WS_CHILD|WS_VISIBLE/*|PBS_SMOOTH*/, rect, &m_wndStatusBar, 1);
myCtrl.SetPos(50);
myCtrl.SetRange( 0, 100 );
}
else
{
myCtrl.MoveWindow(rect);
}
}
让进度栏动起来:
在OnTimer中添加:
myCtrl.SetStep(10);
myCtrl.StepIt();
下面将鼠标的坐标点在状态栏的第一个PANE显示出来。
在框架中包含#include "MainFrm.h"
将框架中的状态栏的成员变成公有的。
void CTestView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CString str;
str.Format("x=%d,y=%d",point.x,point.y);
((CMainFrame*)GetParent())->m_wndStatusBar.SetPaneText(0,str);
//((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
// ((CMainFrame*)GetParent())->SetMessageText(str);
// ((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);
//((CMainFrame*)GetParent())->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);
CView::OnMouseMove(nFlags, point);
}
CStatusBar::Create
BOOL Create( CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR );
下面创建一个窗口起动画面。
利用VC添加的走动画面的类CSplashWnd。
可以在这个类中做相应的修改。