VC改变窗口大小和样式.doc_第1页
VC改变窗口大小和样式.doc_第2页
VC改变窗口大小和样式.doc_第3页
VC改变窗口大小和样式.doc_第4页
VC改变窗口大小和样式.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

改变窗口的外观和大小 改变窗口的外观和大小需要在窗口创建以前改变。 所以我们可以在CMainFrame的 PreCreateWindow中改变CREATESTRUCT 结构体的值就行了。 E.G.BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs)改变窗口的大小 - cs.cx = 300; cs.cy = 200; 改变窗口的显示位置坐标是 cs.x 和 cs.y 这里常用的一个函数是:GetSysMetrics(SM_CXSCREEN);:GetSysMetrics(SM_CYSCREEN);用来取得屏幕的大小。 要改变窗口标题栏的字符串: cs.lpszName = Seven; 会发现标题栏不会改变窗口的标题栏的上的字符串。改变单文档应用程序的标题栏的字符串 参考MSDN window styles/Frame-window styles 下面有一个Changing the styles of a window create by MFC./ The SDI Case默认的情况是WS_OVERLAPPEDWINDOW and FWS_ADDTOTITLE stylesFWS_ADDTOTITLE is add the document title to the windows caption.去掉FWS_ADDTOTITLE 就可以更改窗口标题栏字符串。 cs.style &= FWS_ADDTOTITLE;cs.lpszName = Seven; 如果我们需要改变背景, 画刷, 光标等等时候。我们可以在:PreCreateWindow中创建窗口类, WNDCLASS wndClass;把这个类里的值改变成自己想要的内容就可以了。E.G.wndClass.cbClsExtra = 0;wndClass.cbWndExtra = 0;wndClass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);wndClass.hCursor = LoadCursor(NULL, IDC_WAIT);wndClass.hIcon = LoadIcon(NULL, IDI_WARNING);wndClass.hInstance = AfxGetInstanceHandle();获取应用程序的实例句柄可用AfxGetInstanceHandle函数, 这个函数是一个全局的函数, 前面有一个AFX表示是一个应用程序框架类函数,哪里都可用。wndClass.lpfnWndProc = :DefWindowProc;我们只是想要改变窗口的图标, 光标,不想改变条用过程所以用defWindowProc函数来处理。因为在CWnd中也有一个defWindowProc函数,比全局的函数少一个参数 如果不加:的话调用就要报错。wndClass.lpszMenuName = NULL;创建菜单并不是在在设计窗口类的时候创建, 菜单的创建实在CStyleAPP:InitInstance函数中将菜单的标识传进去。wndClass.style = CS_HREDRAW | CS_VREDRAW;这里的style并不是窗口的类型而是窗口类的类型。RegisterClass(&wndClass);注册窗口类。cs.lpszClass = GL;后来把我们刚刚设计好的类赋值个cs.lpszClass。 运行程序之后我们会发现只有图标改变了, cursor 和brush都没有改变。这是因为, 我们是在frame中改变的,在frame上边还覆盖一个子窗口类。所以我要改变这些需要把在子窗口的View类中PreCreateWindow中把类名复制。E.g在CStyleView中 cs.lpszClass = GL;就可以把我们刚刚的想要的类型来改变view中的窗口类型, 因为“GL”窗口类已经在CMainFrame框架类中已经注册了, 所以我们可以直接赋值就可以了。 在frame中只可以改变ICON ,为了改变图标我们重写窗口类我很不划算, 在MFC中为我们提供了一个函数AfxRegisterWndClass 直接改变icon详见MSDNcs.lpszName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 0, 0,LoadIcon(NULL, IDI_WARNING);这样就直接改变了frame中Icon。 我们也可以在CStyleView中调用这个函数 来改变窗口的 画刷, 光标。 窗口创建之后改变外观用SetWinowLong函数 具体见MSDNLONG SetWindowLong( HWND hWnd, / handle of window int nIndex, / offset of value to set LONG dwNewLong / new value ); 在CMainFrame的OnCreate中调用SetWindowLong SetWindowLong(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);这样就可以去掉了文档标题是窗口标题了。我们可以通过GetWindowLong函数得到当前窗口的类型。 详见MSDN SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & WS_MAXIMIZEBOX);这样就可以灰掉窗口的最大化窗口了。 窗口创建之后改变窗口类上面的是改变窗口的大小和最大化最小化等等的按钮。我们可以用SetClassLong来改变创建之后的窗口类的参数 例如 光标, 鼠标, 画刷 等等。在单文档的应用程序中, 在CMainFrame类中只可以改变Icon 调用:在OnCreate函数中SetClassLong(m_hWnd, GCL_HICON, (LONG)LoadIcon(NULL, IDI_QUESTION);可以改变application的icon。 在VIEW类中改变brush cursor background。在view类中调用SetClassLong(m_hWnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(DKGRAY_BRUSH);改变了VIEW的背景为灰色。 实现一个每一秒中自动换Icon的功能。Precondition 在resources 中添加3个icon的资源。 1. 首先在CMainFrame类中添加一个数组用于存放资源的句柄。 在类中添加 HICON m_hIcon3; 的一个数组。2. 在CMainFrame 函数中加载Icon用LoadIcon这个函数。 HICON LoadIcon( HINSTANCE hInstance,/ handle to application instance LPCTSTR lpIconName / icon-name string or icon resource / identifier ); 如果用的系统的Icon话, LoadIcon这函数的第一个参数必须为NULL。 如果用的是自己定义的Iicon的话, 第一个参数是这个应用程序的一个实例句柄。 第二参数是一个是icon的icon-name string 可以通过MAKEINTRESOURCE这个宏把资源的ID号转换为资源的字符串名字。 LPTSTR MAKEINTRESOURCE( WORD wInteger / integer to convert ); 得到应用程序实例句柄我们可以通过几种方法: 第一种: AfxGetInstanceHandle() 函数获得当前应用程序的实例句柄。 第二种: 因为CStyleApp这个类是从CWinApp这个类中继承过来的所以继承了m_hInstance 这个变量, 这个变量就是应用程序的实例句柄。因为MFC在全局中建立了一个CStyleApp中变量 theApp 如果在CMainFrame中得到这个变量就可以得到应用程序的实例句柄。 在CMainFrame中用到全局变量需要声明这个变量 添加extern CStyleApp theApp; 这样就在CMainFrame中用theApp了。theApp.m_hInstance. 第三种: CWinApp* AfxGetApp( ); 返回的是一个CWinApp的指针。这样可以调用它的实例句柄。 3. 设置一个定时器在OnCreate中我们这里调用的是CWND中的定时器。 UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );第一个参数 定时器的ID 第二个参数是设置的时间 第三个参数是处理函数, 如果设置为NULL 发送WM_TIME消息让消息处理系统调来处理。 CWnd:SetTimer(1, 1000, NULL); 4. 在CMainFrame类中添加一个WM_TIME的消息处理函数。 static int index = 1;SetClassLong(m_hWnd, GCL_HICON, (LONG)m_hIconsindex);index = +index % 3;这样就可以定义出一个会随时间改变的ICON。 工具栏的编程 ToolBar工具栏在resource中添加一个工具栏Item它的ID和menu中的菜单中的一个菜单的Id一样, 那么这个工具栏的Item就代表着那个菜单。E.g在resourcesiView中在帮助的下面添加一个菜单, 叫TEST 它的ID叫ID_TEST 并且建立对应的command消息响应函数,弹出对话框。在resourcesView的ToolBar中建立一个Item他的ID 也叫ID_TEST 这样她们就关联起来了啊。Click两个都是一样的。 添加一个自己的工具栏在MSDN中查看CToolBar 提供了两种创建工具栏的方法1. 首先在resourcesView中创建一个自己的ToolBar, ToolBar上的Item自己设定。2. 在CMainFrame中添加一个CToolBar的类成员, 构造一个CToolBar的变量。3. 调用CToolBar的Create 或者CteateEX 参考MSDN 可以参考CMainFrame中构造ToolBar的方法。 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 toolbar/n);return -1; / fail to create4. 调用LoadToolBar这个函数加载资源。5. 调用CToolBar的成员函数EnableDocking(CBRS_ALIGN_ANY);设置 这个对象是可以停靠的。 如果不设置这个那么工具栏将不可以悬浮。6. 再调用CMainFrame:EnableDocking(CBRS_ALIGN_ANY);设置框架类可以被停靠。 7. 最后在调用CMainFrame中的函数DockControlBar(&m_wndToolBar);停靠工具栏。8. 我们还可以通过在菜单栏上设置一个Item并且设置command消息处理函数。在处理函数中写上if(m_toolBar.IsWindowVisible() m_toolBar.ShowWindow(SW_HIDE);elsem_toolBar.ShowWindow(SW_SHOW);CWnd:IsWindowVisible 当有WS_VISIBLE的时候 返回TRUE.用IsWindowVisible来返回ToolBar是不是可见的。 当我调用这个处理的时候 点击菜单里的Item来显示或者隐藏工具栏。但是发现虽然ToolBar消失了, 但是这个工具条还在。这个时候工具栏的停靠位子有所变化, 这个时候需要调用CFrameWnd:RecalcLayout 函数。 void RecalcLayout( BOOL bNotify = TRUE );在上面的程序后面接上RecalcLayout();当把工具栏拖出来, 处于浮空的ToolBar的时候发现, 然后点击菜单来显示或者隐藏ToolBar发现 当浮空的时候ToolBar的工具条不会隐藏。 这个时候我们还需要调用一个函数DockControlBar(&m_toolBar); 显示或隐藏工具栏的第二种方法这个时候调用一个函数ShowControlBar(&m_toolBar, !m_toolBar.IsWindowVisible(), FALSE); 具体调用参见MSDN。 ShowControlBar是CFrameWnd框架类的一个函数。 9. 我们还需要标记菜单的Item。当选中是标记, 当隐藏时取消标记。这个时候我们需要对这个Item的 UPDATE_COMMAND_UI进行响应。建立消息响应来标记活隐藏标记。 调用CCmdUI的SetCheck();这个函数。来标记或者取消标记。pCmdUI-SetCheck(m_toolBar.IsWindowVisible(); 具体用法参见MSDN。 状态栏的编写1. 首先construct 一个CStatusBar的对象。2. 然后调用变量的Create函数把状态栏窗口和一个CStatusBar的对象绑定。 CStatusBar:CreateBOOL Create( CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR );在MFC中是这样调用的:if (!m_wndStatusBar.Create(this) | !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)TRACE0(Failed to create status bar/n);return -1; / fail to createm_wndStausBar.Create(this), 其他的参数都用默认的参数。 后来条用m_wndStatusBar.Setindicators(indicators, sizeof(indicators)/sizeof(UINT);Indicators 是一个数组储存字符串ID和每一个指示符。 后面一个参数是数组里面的数是多少个。可以添加indicator 在数组中, 首先在String Table 中添加字符串ID , 然后把字符串ID添加在indicators的数组里面。这样就可以在状态栏中显示了。 有三种方法更新状态栏上的字符。1. Call CWnd:SetWindowText to update the text in pane 0 only.2. Call CCmdUI:SetText in the status bars ON_UPDATE_COMMAND_UI handler.3. Call SetPaneText to update the text for any pane. 我们可以把系统当前时间显示在状态栏上。这个时候需要用到 CTime CTime t = CTime:GetCurrentTime();CString timeStr = t.Format(%H:%M:%S);格式输出到一个字符串中。 然后调用 m_wndStatusBar.SetPaneText(1, timeStr);第一个参数是索引Index of the pane whose text is to be set。timeStr是要显示的字符串了。如果不知道要显示的索引, 我们可用调用m_wndStatusBar的一个成员函数CommandToIndex(IDS_TIMER); 括号里面的参数是表示要显示的字符串ID。 运行程序, 我们会发现时钟的秒不能显示。 这个是因为状态栏空间不够所以不能完全显示内容。 我们可以调用SetPaneInfo();CStatusBar:SetPaneInfovoid SetPaneInfo( int nIndex, UINT nID, UINT nStyle, int cxWidth ); 函数改变状态栏空间大小。 为了获得字符串的显示宽度, 我们需要调用GetTextExtent(Cstring str);来返回字符创的空间大小, CSize。CClientDC dc(this);CSize sz = dc.GetTextExtent(timeStr);之后再调用SetPaneText();来显示内容 这个时候发现时间是不动的。 需要动, 要把刚刚这段代码放到SetTimer的响应函数中不停调用显示时间。 创建一个进度栏进度栏的类是CProgressCtrl。 定义一个变量, 并且调用Create初始化一个进度栏。 CProgressCtrl:CreateBOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );第一个参数是一个窗口类, E.G WS_CHILD | WS_VISIBLE | PBS_SMOOTH 第二个参数是一个矩形区域。 CProgressCtrl m_progressCtrl;m_progressCtrl.SetPos(50); 设置到中间。 如果我们想把这个矩形区域显示在状态栏里。 首相我们在CMainFrame类中编写这样一段程序CRect rect;m_wndStatusBar.GetItemRect(2, &rect);m_progressCtrl.Create(WS_CHILD| WS_VISIBLE| PBS_SMOOTH, rect,&m_wndStatusBar, 1);注意这里的&m_wndStatusBar是进度条的父窗口。 在View类中创建进度条时, 父类窗口就是this, 代表这个对象的指针。 运行程序发现进度条并没有出现, 我们在CRect rect ; 这里设置断点, 运行函数, 看断点的值发现rect的值是一个无效的值, 这个时候我们猜想, 在OnCreat 结束钱状态栏还没有初始化好。 这样我们可以在OnCreate之后调用一个函数来处理进度条。我们可以自己定义一个消息,在OnCreate中把这个消息投递到消息队列中,来处理这个函数。首先我先定义一个消息, 在window中消息都是用一个整数来表示的,在CMainFrame的头文件中添加一个消息。 #define UM_PROGRESS WM_USER+1因为window的很多消息已经占用了很多的整数, 我们胡乱定义很可可能和系统冲突, WM_USER以下的是系统消息保留的。 以上的可以是用户自己定义的。这样我们就定义了一个UM_PROGRESS 的消息。添加完这个消息后, 要有相应的消息响应函数来处理这个消息。protected:/AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnTimer(UINT nIDEvent);afx_msg void OnTest();afx_msg void OnAppendToolbar();afx_msg void OnUpdateAppendToolbar(CCmdUI* pCmdUI);afx_msg void OnPaint();/AFX_MSG先要在头文件的这段代码后面添加 afx_msg void OnProgress();DECLARE_MESSAGE_MAP() 参考MFC的程序;然后在。CPP文件中BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)/AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()ON_WM_TIMER()ON_COMMAND(ID_TEST, OnTest)ON_COMMAND(ID_APPEND_TOOLBAR, OnAppendToolbar)ON_UPDATE_COMMAND_UI(ID_APPEND_TOOLBAR, OnUpdateAppendToolbar)ON_WM_PAINT()/AFX_MSG_MAPON_MESSAGE(UM_PROGRESS, OnProgress)END_MESSAGE_MAP()消息响应函数是通过 ON_MESSAGE() 把消息和消息处理函数关联起来的。 最后在添加消息处理函数Void CMainFrame:OnProgress() CRect rect;m_wndStatusBar.GetItemRect(2, &rect);m_progressCtrl.Create(WS_CHILD| WS_VISIBLE| PBS_SMOOTH, rect,&m_wndStatusBar, 1); 在这个函数中处理进度条。在OnCreate函数中用PostMessage();不能用SendMessage(); 因为 SendMessage是直接调用了处理函数, 这个时候状态栏还没有处理好。 现在运行应用程序, 这个时候progress显示在状态栏上, 但

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论