声明:此乃作者阅读笔记,对您无任何作用,请忽略,当然了,如果你非要看,那我也没有办法,但是我声明了,就没有责任了。
如果希望在应用程序窗口创建之前修改它的外观和大小,就应该在CMainFram类的PreCreateWindow成员 函数中进行: PreCreateWindow有一个CREATESTRUCT类型的参数,修改该变量里的成员变量即可。 在串钩创建之后可以利用前面介绍过得SetWindowLong这个函数来实现这种功能,为了改变窗口的类型, 该函数的第二个参数应制定为GWOL_STYLE,第三个参数应指定为新的窗口类型。可以在架构类的 OnCreate中添加具体的实现代码。 SetWindowLong( m_hWnd, GWL_STYLE, GetWindowLong( m_hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX); 修改窗口的光标图标背景: 窗口的图标、光标和背景是在设计窗口类时指定的,所以,需要编写自己的窗口类并注册,然后让随后 的窗口按照我们编写的窗口去创建。 才CMainFrame类的PreCreateWindow函数中编写一个自己的窗口类并注册。 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; WNDCLASS wndcls; wndcls.cbClsExtra = 0; wndcls.cbWndExtra = 0; wndcls.hbrBackground = (HBRUSH)GetStockObject(6); wndcls.hCursor = LoadCursor( NULL , IDC_HELP); wndcls.hIcon = LoadCursor( NULL, IDI_WARNING); wndcls.hInstance = AfxGetInstanceHandle(); wndcls.lpfnWndProc = ::DefWindowProc; wndcls.lpszClassName =_T( "sunxin.org"); wndcls.lpszMenuName = NULL; wndcls.style = CS_HREDRAW | CS_VREDRAW; RegisterClass( &wndcls ); cs.lpszClass =_T( "sunxin.org"); return TRUE; } 在视类的PreCreateWindow函数中使用刚刚注册的窗口 cs.lpszClass = "sunxin.org"; 总结:在MFC程序中,如果想要修改应用程序窗口的图标,则应在架构类中进行,因为在架构窗口中才有 标题栏,所以才能修改位于该标题栏上得图标;如果想要修改程序窗口的背景和光标,就应该在视类中 进行。 也可以通过AfxRegisterWndClass来修改窗口的图标,背景。不过,修改图标应该架构类的 PreCreateWindow中,修改背景、光标应该视类的PreCreateWindow中。 LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0 ); 即使在窗口已经创建完成以后也是可以修改窗口的光标,图标,背景的。利用SetClassLong函数即可。 DWORD SetClassLong( HWND hWnd, int nIndex, LONG dwNewLong ); hWnd 指定要设置新属性的窗口句柄 nIndex 指定要设置的属性的索引。取值: GCL_HBRBACKGROUND 设置新的背景画刷 GCL_HCURSOR 设置新的光标 GCL_HICON 设置新的图标 GCL_STYLE 设置新的窗口样式 dwNewLong 指定要设置的新值。 模拟动画图标: 新建几个资源 在架构类中定义HICON的成员变量 加载资源 m_hIcons = LoadIcon( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDB_BITMAP1));//其 中,宏MAKEINTRESOURCE将资源ID转换为相应的资源标示符字符串。 设置定时器: SetTimer(1, 1000,0); 为架构类添加定时器消息(WM_TIMER)的相应函数,并在该相应函数中调用SetClassLong[注意区分 SetWindowLong]函数改变应用程序窗口的图标 自定义工具栏: ①够着CToolBar对象 ②调用Create或CreateEx函数创建Windows工具栏,并把它与创建的CToolBar对象关联起来 ③调用LoadBitmap函数加载半酣工具栏按钮图像的位图 ④调用Setbuttons函数设置按钮样式 其实只需要替换掉部分系统为我们生成的代码即可: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { 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_TOOLBAR1)) //创建工具栏,加载自定义的工具栏 IDR_TOOLBAR1 { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);//设置工具栏的停靠位置 EnableDocking(CBRS_ALIGN_ANY);//设置架构类的停靠位置 DockControlBar(&m_wndToolBar);//使工具栏停靠在架构类之上 显示或者隐藏工具栏: void CMainFrame::OnViewNewtoolbar() { if( m_newToolBar.IsWindowVisible()) { m_newToolBar.ShowWindow( SW_HIDE ); } else { m_newToolBar.ShowWindow( SW_SHOW ); } RecalcLayout();//架构类的成员函数,通知架构窗口布局变动 DockControlBar( &m_newToolBar );//再次将工具栏置于架构之上 } 以上所有动作都可以利用ShowControlBar函数完成。 ShowControlBar( &m_newToolBar, !m_newToolBar.IsWindowVisible(), FALSE ); 修改状态栏: 在CMainFrame类中已经定义了状态栏CStatusBar m_wndStatusBar; 在OnCreate函数中有如下代码: if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))//indicators是状态栏右下角的各种状态,我 们可以修改该数组,前提是到string table中定义字符串资源 { TRACE0("Failed to create status bar\n"); return -1; // fail to create } 将字符串资源加入其中: static UINT indicators[] = { ID_SEPARATOR, // status line indicator IDS_TIMER, IDS_PROGRESS, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; 为了将字符串显示到状态栏的窗格子上,可以调用CStatusBar类的SetPaneText函数。 设置窗格的宽度SetPaneInfo CTime t = CTime::GetCurrentTime(); CString str = t.Format("%H:%M:%S"); CClientDC dc(this); CSize sz = dc.GetTextExtent( str ); m_wndStatusBar.SetPaneInfo( 1, IDS_TIMER, SBPS_NORMAL, sz.cx); m_wndStatusBar.SetPaneText(1, str); 进度条编程:如果要再程序中使用进度栏,首先需要构造一个CProgressCtrl对象,然后调用 CProgressCtrl类的Create函数创建进度栏控件。 利用CProgressCtrl类的SetPos成员函数可以设置进度栏上当前进度 m_progress.Set( 50 ); 为了在状态栏的窗格中显示进度栏,首先需要获得窗格的区域,然后将这个区域的大小作为进度栏的大 小。为了获得窗格的区域,可以利用CStatusBar类的GetItemRect【GetPaneInfo】成员函数来完成 当窗口第一次显示时会调用OnPaint,当窗口大小发生变化时,进度条的位置就不对了,但是系统会发送 WM_PAINT消息,我们可以响应此消息,然后重画。 void CMainFrame::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CFrameWnd::OnPaint() for painting messages CRect rect; m_wndStatusBar.GetItemRect( 2, &rect); if( !m_progress.m_hWnd) { m_progress.Create( WS_CHILD | WS_VISIBLE | PBS_SMOOTH , rect , &m_wndStatusBar, 123); } else { m_progress.MoveWindow(rect); } m_progress.SetPos(50); } 在状态栏上显示鼠标当前位置: ①在视类中相应VM_MOUSEMOVE消息,(CMainFram*)GetParent())->m_wndStatusBar.SetWindowText( str ); ②调用架构类的成员函数((CMainFrame*)GetParent())->SetMessageText(str); ③第一种方法和第二种方法的结合,不需要访问架构类的保护成员变量m_wndStatusBar. ((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str );