1、修改应用程序外观建立一个单文档的 MFC 应用程序,修改一个应用程序的外观和大小,要在应用程序的窗口创建之前去修改,1.在 CMainFrame 类的 PrecreateWindow()函数中去创建。BOOL CMainFrame:PreCreateWindow(CREATESTRUCT / TODO: Modify the Window class or styles here by modifying / the CREATESTRUCT cs cs.cx=300;/宽度 cs.cy=200;/高度 /cs.style /cs.style=cs.style /这两个表达式一样 cs.sty
2、le=WS_OVERLAPPEDWINDOW;/也可以直接给这个类型赋值 cs.lpszName=“维唯为为“; /窗口标题 return TRUE; 2.用 SetWindowLong在窗口创建之后改变外观,在 CMainFrame 类中的 OnCreate()函数中去编写代码。int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) if (CFrameWnd:OnCreate(lpCreateStruct) = -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, W
3、S_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) | !m_wndToolBar.LoadToolBar(IDR_MAINFRAME) TRACE0(“Failed to create toolbarn“); return -1; / fail to create if (!m_wndStatusBar.Create(this) | !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)
4、/sizeof(UINT) TRACE0(“Failed to create status barn“); return -1; / fail to create / TODO: Delete these three lines if you dont want the toolbar to / be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar( /修改窗口的外观 /SetWindowLong(m_hWnd,GWL_STYLE,WS_OVER
5、LAPPEDWINDOW); /修改现有窗口的类型 SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)/使最大化图标变灰 return 0; 3.编写自己的窗口类在 CMainFrame:PreCreateWindow(CREATESTRUCT/定义一个窗口类 wndcls.cbClsExtra=0;/类的额外内存,0,不需要 wndcls.cbWndExtra=0;/窗口的额外内存,0,不需要 wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);/背景 wn
6、dcls.hCursor=LoadCursor(NULL,IDC_HELP);/NULL,指定标准光标 /注:要改变窗口的背景和光标要在 View 类中去改变,因 View 窗口覆盖在 Frame窗口之上 wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);/图标 wndcls.hInstance=AfxGetInstanceHandle();/获取当前应用程序的句柄 wndcls.lpfnWndProc=:DefWindowProc;/窗口过程用缺省的 ,函数名指函数的地址 wndcls.lpszClassName=“luowei.org“;/类的名字 wndcls.
7、lpszMenuName=NULL; wndcls.style=CS_HREDRAW|CS_VREDRAW;/水平重画,垂直重画 RegisterClass(/注册窗口类 cs.lpszClass=“luowei.org“;在 CStyleView:PreCreateWindow(CREATESTRUCT/修改成自己定义的类return CView:PreCreateWindow(cs);4.利用 AfxRegisterWnd 函数修改在 CMainFrame:PreCreateWindow 中添加:cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_
8、VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING);/cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW)/设置成缺省值AfxRegisterWndClass LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0 ); Return ValueA null-terminated string containing the class
9、name. You can pass this class name to the Create member function in CWnd or other CWnd-derived classes to create a window. The name is generated by the Microsoft Foundation Class Library.Note The return value is a pointer to a static buffer. To save this string, assign it to a CString variable. Para
10、metersnClassStyleSpecifies the Windows class style or combination of styles, created by using the bitwise-OR (|) operator, for the window class. For a list of class styles, see the WNDCLASS structure in the Win32 SDK documentation. If NULL, the defaults will be set as follows: Sets the mouse style t
11、o CS_DBLCLKS, which sends double-click messages to the window procedure when the user double-clicks the mouse. Sets the arrow cursor style to the Windows standard IDC_ARROW. Sets the background brush to NULL, so the window will not erase its background. Sets the icon to the standard, waving-flag Win
12、dows logo icon. hCursorSpecifies a handle to the cursor resource to be installed in each window created from the window class. If you use the default of 0, you will get the standard IDC_ARROW cursor.hbrBackgroundSpecifies a handle to the brush resource to be installed in each window created from the
13、 window class. If you use the default of 0, you will have a NULL background brush, and your window will, by default, not erase its background while processing WM_ERASEBKGND.hIconSpecifies a handle to the icon resource to be installed in each window created from the window class. If you use the defau
14、lt of 0, you will get the standard, waving-flag Windows logo icon.RemarksThe Microsoft Foundation Class Library automatically registers several standard window classes for you. Call this function if you want to register your own window classes.The name registered for a class by AfxRegisterWndClass d
15、epends solely on the parameters. If you call AfxRegisterWndClass multiple times with identical parameters, it only registers a class on the first call. Subsequent calls to AfxRegisterWndClass with identical parameters simply return the already-registered classname.If you call AfxRegisterWndClass for
16、 multiple CWnd-derived classes with identical parameters, instead of getting a separate window class for each class, each class shares the same window class. This can cause problems if the CS_CLASSDC class style is used. Instead of multiple CS_CLASSDC window classes, you end up with one CS_CLASSDC w
17、indow class, and all C+ windows that use that class share the same DC. To avoid this problem, call AfxRegisterClass to register the class.在 CStyleView:PreCreateWindow(CREATESTRUCT/修改成自己定义的类 /修改背景和光标 cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockOb
18、ject(BLACK_BRUSH),0); /cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW)/设置成缺省值return CView:PreCreateWindow(cs); 5.窗口创建之后,再创建图标,光标及背景利用 SetClassLong 函数,在 CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加:/修改图标SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR);修改光标和背景,对 CStyleVi
19、ew 类添加一个 WM_CREATE 消息响应,编辑:int CStyleView: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); /修改光标 SetClassLong(m_hWnd,GCL_HCURSOR,(
20、LONG)LoadCursor(NULL,IDC_HELP); return 0; 6.实现动态图标Insert - 资源 - 导入三个图标,在 CMainFrame 类上定义三个用于存放图标句柄的数组,对 CMainFrame 类添加一个 HICON 类型的私有成员变量 m_hIcons3,并在CMainFrame:OnCreate 函数中支去加载图标:extern CStyleApp theApp; /声明这个变量是在外部定义的 int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) . . . /加载图标 m_hIcons0=Load
21、Icon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1);/方式一 m_hIcons1=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2); /方式二, theApp 是外部的全局变量,在 CMainFrame:OnCreate 函数之前要声明 m_hIcons2=LoadIcon(AfxGetApp()-m_hInstance,MAKEINTRESOURCE(IDI_ICON3); SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons0);/将图标
22、设置成引入的第一个图标/设置定时器 SetTimer(1,1000,NULL); return 0; 再给 CMainFrame 类添加 WM_TIMER 消息处理,编辑:void CMainFrame:OnTimer(UINT nIDEvent) / TODO: Add your message handler code here and/or call default static int index=1;/静态的变量是存放在数据区当中,而不是分配在栈当中 SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIconsindex); index=+index%3;
23、/让图标不断的循环变幻 CFrameWnd:OnTimer(nIDEvent); 7.工具栏的编程在菜单 Menu 下 IDR_MAINFRAME 中添加一个菜单项 Test,在图标 Toolbar 下IDR_MAINFRAME 中添加一个图标。ID 号都取为:IDC_TEST 。对 Test 菜单添加一个COMMAND 消息响应函数,编辑:void CMainFrame:OnTest() / TODO: Add your command handler code hereMessageBox(“Test“);在工具栏图标之间,添加分隔符,可以用鼠标左键拖住图标往左移一点即可; 可以用鼠标左键
24、把图标拖出工具栏外边即可!8.创建工具栏在 ToolBar 上新建一个工具栏 IDR_TOOLBAR1,并在 CMainFrame.h 中添加:protected: / control bar embedded membersCStatusBar m_wndStatusBar;CToolBar m_wndToolBar;CToolBar m_newToolBar;/创建一个 ToolBar然后在 CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)中编辑:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreat
25、eStruct) if (CFrameWnd:OnCreate(lpCreateStruct) = -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) | !m_wndToolBar.LoadToolBar(IDR_MAINFRAME) TRACE0(“Failed to create toolbarn“); return -1;
26、 / fail to create if (!m_wndStatusBar.Create(this) | !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT) TRACE0(“Failed to create status barn“); return -1; / fail to create / TODO: Delete these three lines if you dont want the toolbar to / be dockable m_wndToolBar.EnableDocking
27、(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar( /修改窗口的外观 /SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW); /修改现有窗口的类型 /SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)/使最大化图标变灰 /修改图标 /SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR); /加载图标 m_hIcons0=Loa
28、dIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1);/方式一 m_hIcons1=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2); /方式二, theApp 是外部的全局变量,在 CMainFrame:OnCreate 函数之前要声明 m_hIcons2=LoadIcon(AfxGetApp()-m_hInstance,MAKEINTRESOURCE(IDI_ICON3); SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons0);/将图
29、标设置成引入的第一个图标 /设置定时器 SetTimer(1,1000,NULL); if (!m_newToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_RIGHT | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) | !m_newToolBar.LoadToolBar(IDR_TOOLBAR1)/对 m_newToolBar 的显示操作 TRACE0(“Failed to create toolbarn“); return -1;
30、 / fail to create m_newToolBar.EnableDocking(CBRS_ALIGN_ANY); / EnableDocking(CBRS_ALIGN_ANY); DockControlBar( return 0; 9.给新加的工具栏添加菜单响应在查看菜单下新增一个菜单项,取名为:新的工具栏,ID 号:IDM_VIEW_NEWTOOL,再添加 COMMAN 消息响应函数,编辑:void CMainFrame:OnViewNewtool() / TODO: Add your command handler code here if(m_newToolBar.IsWind
31、owVisible() m_newToolBar.ShowWindow(SW_HIDE); else m_newToolBar.ShowWindow(SW_SHOW); RecalcLayout(); DockControlBar( 10利用 ShowControlBar 显示工具栏在 CMainFrame:OnViewNewtool()函数中编辑:void CMainFrame:OnViewNewtool() / TODO: Add your command handler code here /* if(m_newToolBar.IsWindowVisible() m_newToolBar
32、.ShowWindow(SW_HIDE); else m_newToolBar.ShowWindow(SW_SHOW); RecalcLayout(); DockControlBar( */ ShowControlBar( 11.给新的工具栏菜单项添加复选标记给新的工具栏添加一个 UPDATE_COMMAND_UI 消息响应,编辑:void CMainFrame:OnUpdateViewNewtool(CCmdUI* pCmdUI) / TODO: Add your command update UI handler code herepCmdUI-SetCheck(m_newToolBar.
33、IsWindowVisible();12.状态栏的编程在字符串表中添加两个字符串,IDS_TIMER(时钟)和 IDS_PROGERSS(进度条) ,然后在MainFrm.cpp 文件中修改:static UINT indicators = /指示器的数组ID_SEPARATOR, / status line indicatorIDS_TIMER, /时钟字符串IDS_PROGRESS, /进度条字符串ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,;运行,可以发现状态栏多了两个分隔符。13.在状态栏显示系统的时间在 CMainFram
34、e:OnCreate(LPCREATESTRUCT lpCreateStruct)中编辑:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) . . . /设置状态栏一时钟显示当前系统时间 CTime t=CTime:GetCurrentTime(); CString str=t.Format(“%H:%M:%S“); /方式 1: /m_wndStatusBar.SetPaneText(1,str,TRUE);/将时间到状态栏 /方式 2(IDS_TIMER 的索引号未知): int index=0; index=m_wndStatu
35、sBar.CommandToIndex(IDS_TIMER); m_wndStatusBar.SetPaneText(index,str,TRUE); /SetPaneText()函数是 CStatusBar 的成员函数 ,IDS_TIMER 在指示器中的索引为1 return 0; 14.让状态栏时钟的指示器面板宽度修改状态栏时钟的指示器面板宽度,使秒数也显示出来。同样在 CMainFrame:OnCreate函数在编辑:int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct) . . . /设置状态栏一时钟显示当前系统时间 CTime t
36、=CTime:GetCurrentTime(); CString str=t.Format(“%H:%M:%S“); CClientDC dc(this);/构造一个 DC CSize sz=dc.GetTextExtent(str);/获取符串在屏幕上显示的宽度和高度信息 /方式 1: /m_wndStatusBar.SetPaneText(1,str,TRUE);/将时间到状态栏 /方式 2(IDS_TIMER 的索引号未知): int index=0; index=m_wndStatusBar.CommandToIndex(IDS_TIMER); m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);/设置指示器面板的宽度 m_wndStatusBar.SetPaneText(index,str,TRUE);