mfc如何修饰mainframe类
MFC如何在文档(CXXXDoc)类或框架(CMainFrame)类中获得视类(CMyView)指针
文档模板 GetDocTemplate
CView 对象 文档对象 GetDocument
边框窗口 GetParentFrame
如何在OnDraw函数或***Dlg函数中获得View类的指针(this)或整个对话框的指针?
在单文档中你可以采用如下方法:
现在要获得指针的文件开始处包含两个文件:
视图的主框架类头文件,即#include "MainFrm.h"
视图类头文件,即#include "XXView.h"
在CDocument类中,调用GetFirstViewPosition()和GetNextView()得到所有的view。
在其它类中,一种方法先是把指针传进去,以备调用的时候使用。另外就要用AfxGetApp()得到CWinApp,然后再用GetFirstDocTemplatePosition()和GetNextDocTemplate()得到doc template,然后调用GetFirstDocPosition()和GetNextDoc()得到doc。
在文档类中(CMainFrame*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
MFC中怎么在CMainFrame下获得View类的指针
使用GetActiveView()函数
MFC中普通类如何获取view类的指针?
在普通类(Generic class)中怎么得到view类的指针?我试过这样:
然后在要访问m_pSet处添加如下语句
CMainFrame* frm=(CMainFrame*)AfxGetApp()->m_pMainWnd;
MFC的窗口分割实例以及CSplitterWnd类
3 分割窗口ቤተ መጻሕፍቲ ባይዱ
如图 1,把窗口分成三个视图,左视图基于 CView 类,可用来作几何图形;右上视图基 于 CEditView 类,用于显示文本消息;右下视图基于 CFormView 类,在此视图中做一个文 本框及发送、清除按钮,发送按钮用来向右上视图传送消息。
图 1 设计样式 打开 Microsoft VC++ 6.0,通过 MFC AppWizard(exe)新建名为 SplitWnd 的单文档(SDI) 工程,新建工程时所有选项均按默认设定。 工程建好后,把工程中的 CSplitWndView 视图类作为左视图所对应的类(该类的实现 与本文重点无关,故不阐述,有兴趣读者可与作者联系),由于需要三个视图窗口对应三个
视图类,因此需要手动创建右上视图、右下视图对应的类,可以通过 MFC 向导向应用程序 添加两个 MFC 类(菜单“Insert | New Class>”),因为在右上视图用于显示文本,故其基类选 CEditView,类名为 CLeftTopView;另一个 MFC 类的基类选 CFormView 类,取类名为 CLeftBttmView,该类即对应右下视图(由于该类基于 CFormView 类,需要有对话框与之对 应,故应先在资源中新建对话框,对话框中的控件如图 1)。
void CLeftBttmView::OnSendMsg() { UpdateData();//更新控件变量数据,文本框对应的变量为 m_sText //通过 CMainFrame 类中的 m_wndSplitterRight 变量获得右上视图类指针 CMainFrame * pMainFrm = (CMainFrame *)AfxGetApp()->GetMainWnd(); CWnd * pWnd = pMainFrm->m_wndSplitterRight.GetPane(0, 0); CLeftTopView* pLeftTopView = DYNAMIC_DOWNCAST(CLeftTopView, pWnd); pLeftTopView ->GetMsg( m_sText + "\r\n" );//CLeftTopView 成员函数,接收数据 } 右上视图类 CLeftTopView 的成员函数 GetMsg 则需保存接收到的消息并显示,主要代 码如下: void CLeftTopView::GetMsg(CString sMsg) { m_sAllMsg += sMsg; // m_sAllMsg 为成员变量,记录所有消息 int nTextLen = GetWindowTextLength(); GetEditCtrl().SetSel(nTextLen, nTextLen); GetEditCtrl().ReplaceSel( sMsg );//显示新消息 } 有了上面两个函数就可以实现右上视图类 CLeftTopView 与右上视图类 CLeftBttmView 之间的简单通讯,类似地,可以实现所有视图之间任意的数据传递。
mfc中好用的自定义控件使用方式
MFC中自定义控件的使用方式如下:1. 创建一个新的类,继承自CWnd或CButton等需要扩展的控件类。
2. 重载控件类的消息处理函数,如OnPaint、OnLButtonDown等。
3. 在需要使用自定义控件的地方,实例化该控件类并调用其Create成员函数进行创建。
4. 将创建好的控件添加到窗口或其他容器中。
以下是一个简单的自定义控件示例:```cpp// MyCustomControl.h#pragma onceclass CMyCustomControl : public CButton{public:CMyCustomControl();virtual ~CMyCustomControl();protected:afx_msg void OnPaint();DECLARE_MESSAGE_MAP()};``````cpp// MyCustomControl.cpp#include "MyCustomControl.h"CMyCustomControl::CMyCustomControl(){}CMyCustomControl::~CMyCustomControl(){}BEGIN_MESSAGE_MAP(CMyCustomControl, CButton)ON_WM_PAINT()END_MESSAGE_MAP()void CMyCustomControl::OnPaint(){CPaintDC dc(this); // device context for paintingCRect rect;GetClientRect(&rect); // get client area rectangleCDC memDC; // create memory device contextmemDC.CreateCompatibleDC(&dc); // create compatible DC with paint DCCBitmap bitmap; // create bitmap objectbitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); // create bitmap with client area sizeCBitmap* pOldBitmap = memDC.SelectObject(&bitmap); // select bitmap into memory DC for drawing// draw your custom content here using memDC and bitmap objects// ...memDC.SelectObject(pOldBitmap); // restore old bitmap object from memory DCbitmap.DeleteObject(); // delete bitmap object when done with itmemDC.DeleteDC(); // delete memory DC when done with it}```在需要使用自定义控件的地方:```cpp// MainFrm.cpp or other relevant file#include "MyCustomControl.h"// ...CMyCustomControl* pCtrl = new CMyCustomControl(); // create custom control instancepCtrl->Create(WS_CHILD | WS_VISIBLE, CRect(10, 10, 100, 50), this, IDC_MYCUSTOMCTRL); // create custom control and add to parent window or container (e.g., CFrameWnd) as child control with ID IDC_MYCUSTOMCTRL```。
MFC教程(4)
MFC教程(4)但是在当前例子中,当前对象的类CTview没有覆盖该函数,所以CWnd的WindowProc被调用。
这个函数把下一步的工作交给OnWndMsg函数来处理。
如果OnWndMsg没有处理,则交给DefWindowProc来处理。
OnWndMsg和DefWindowProc都是CWnd类的虚拟函数。
OnWndMsg的原型如下:BOOL CWnd::OnWndMsg( UINT message,WPARAM wParam, LPARAM lParam,RESULT*pResult ); 该函数是虚拟函数。
和WindowProc一样,由于当前对象的类CTview没有覆盖该函数,所以CWnd的OnWndMsg被调用。
在CWnd中,MFC使用OnWndMsg来分别处理各类消息:如果是WM_COMMAND消息,交给OnCommand处理;然后返回。
如果是WM_NOTIFY消息,交给OnNotify处理;然后返回。
如果是WM_ACTIVATE消息,先交给_AfxHandleActivate 处理(后面5.3.3.7节会解释它的处理),再继续下面的处理。
如果是WM_SETCURSOR消息,先交给_AfxHandleSetCursor处理;然后返回。
如果是其他的Windows消息(包括WM_ACTIVATE),则首先在消息缓冲池进行消息匹配,若匹配成功,则调用相应的消息处理函数;若不成功,则在消息目标的消息映射数组中进行查找匹配,看它是否处理当前消息。
这里,消息目标即CTview对象。
如果消息目标处理了该消息,则会匹配到消息处理函数,调用它进行处理;否则,该消息没有被应用程序处理,OnWndMsg返回FALSE。
关于Windows消息和消息处理函数的匹配,见下一节。
缺省处理函数DefWindowProc将在讨论对话框等的实现时具体分析。
Windows消息的查找和匹配CWnd或者派生类的对象调用OnWndMsg搜索本对象或者基类的消息映射数组,寻找当前消息的消息处理函数。
MFC常用控件使用
MFC常用控件使用MFC(Microsoft Foundation Classes)是一个用于Windows平台的C++类库,用于开发基于Windows的图形用户界面应用程序。
MFC提供了许多常用的控件,开发人员可以使用这些控件来构建各种类型的Windows应用程序。
下面是一些常用的MFC控件和它们的使用方法:1. Button控件:Button控件用于创建按钮。
创建Button控件的方法是通过调用CButton类的Create函数,指定按钮的风格、位置和大小等参数。
之后,可以使用CButton类的成员函数来设置按钮的文本、图片和事件处理程序等。
3. List Box控件:List Box控件用于创建列表框,用于显示列表项。
创建List Box控件的方法是通过调用CListBox类的Create函数,指定列表框的风格、位置和大小等参数。
之后,可以使用CListBox类的成员函数来添加、删除和获取列表项等。
5. Static控件:Static控件用于显示静态文本。
创建Static控件的方法是通过调用CStatic类的Create函数,指定静态文本的风格、位置和大小等参数。
之后,可以使用CStatic类的成员函数来设置静态文本的内容、字体和颜色等。
6. Slider控件:Slider控件用于创建滑动条。
创建Slider控件的方法是通过调用CSliderCtrl类的Create函数,指定滑动条的风格、位置和大小等参数。
之后,可以使用CSliderCtrl类的成员函数来设置滑动条的范围、当前位置和事件处理程序等。
7. Progress控件:Progress控件用于显示进度条。
创建Progress 控件的方法是通过调用CProgressCtrl类的Create函数,指定进度条的风格、位置和大小等参数。
之后,可以使用CProgressCtrl类的成员函数来设置进度条的范围、当前位置和事件处理程序等。
8. Tree Control控件:Tree Control控件用于显示树形结构。
MFC基类调用方法及格式
关于MFC自动生成的各个类的指针访问经常看到有朋友在问这个问题,在MFC自动生成的类中,如果想从一个类中,直接访问另一个类中的成员函数与成员变量该怎么办呢?今天我就这个问题来详细的说明一下.以下为例,如果说我给工程取的名称为PanelBuilder,如果我选的是单视图(这里主要是将要生成的CLeftView区分,指仅仅是一个视图没有分割窗体),那么MFC会生成以下几个名称的类:1.CPanelBuilderApp 这个是应用程序的入口类2.CPanelBuilderView 这个是视图类3.CPanelBuilderDoc 这个是与视图交互信息的文档类4.CMainFrame 这个是主框架类当然还自动生成了一个about对话框类,用来显示版本信息,这里我们不讨论这个类.下面切入正题.1.如何从其他类中访问CPanelBuilderView的方法?((CPanelBuilderView *)(AfxGetApp()->m_pMainWnd))->Function();对于单视图来说m_pMainWnd就是指的这个视图的指针,然后强制转换后即可用2.对于多视图的怎么办呢?比如说我左边有一个CLeftView的怎么办?2.1如何从CLeftView中访问CPanelBuilderView的方法?这样的话,是用到了分割窗体,所以在CMainFrame中会有一个私有的成员变量叫做m_SpliterWnd,这个指针指的是整个的视图,我们先要将其改成公有的,然后再CLeftView中这样写:((CPanelBuilderView*)(((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_SpliterWnd).GetPane(0,1))->Fun ction()即可;呵呵,是不是很晕?让我来解释一下吧.AfxGetApp()->m_pMainWnd得到CMainFrame的指针,强制转换后调用m_Spliter Wnd这个成员变量的方法GetPane(int,int),在分割窗体中,窗体的标识是从上到下,从左到右的顺序按(0,0), (0,1)等等标识的,我们要得到的CPanelBuilderView这个窗体的指针是(0,1)得到后再强制转换一次即可.2.2那么从别的类中访问CLeftView怎么办呢?((CPanelBuilderView*)(((CMainFrame*) (AfxGetApp()->m_pMainWnd))->m_SpliterWnd).GetPane(0,0))->Fu nction()即可。
MFC控件使用详细教程
使用Windows标准控件我们在前面曾提到过,控件是一些行为标准化了的窗口,一般用于对话框或其它窗口中充当与用户交互的元素。
在Visual C++中,可以使用的控件分成三类:(1) Windows标准控件Windows标准控件由Windows操作系统提供,在Windows 95中还提供了一些新增的控件。
所有这些控件对象都是可编程的,我们可以使用Visual C++提供的对话框编辑器把它们添加到对话框中。
Microsoft基础类库(MFC)提供了封装这些控件的类,它们列于表6.1。
表6.1 Windows标准控件续表6.1前面提到过,在MFC中,类CWnd是所有窗口类的基类,很自然的,它也是所有控件类的基类。
Windows标准控件在以下环境下提供:•Windows 95•Windows NT 3.51及以后版本•Win32s 1.3•注意:•Visual C++ 4.2及以后版本不再支持Win32s。
(2) ActiveX控件ActiveX控件可用于对话框中,也可用于HTML文档中。
这种控件过去被称为OLE 控件。
本书将在专门的章节中来讲述关于ActiveX控件的知识。
这里仅指出ActiveX控件使用了与标准控件完全不同的接口和实现方法。
(3) 其它MFC控件类除了Windows标准控件和自己编写的或者来自于第三方软件开发商的ActiveX 控件以外,MFC还提供了另外三种控件,它们由下面的三个类进行封装:•类CBitmapButton用于创建以位图作为标签的按钮,位图按钮最多可以包括四个位图图片,分别代表按钮的四种不同状态。
•类CCheckListBox用于创建选择列表框,这种列表框中的每一项前面有一个复选框,以决定该项是否被选中。
•类CDragListBox用于创建一种特殊的列表框,这种列表框允许用户移动列表项。
在本章我们仅讲述第一类控件,即Windows标准控件。
所涉及的内容包括各个控件的使用及相应的技巧。
MFC 小技巧(更换皮肤,背景,标题栏,透明)
1.背景透明在MainFrame.Cpp中找到int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数添加代码SetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE)^0x80000);// 添加库HINSTANCE hInst = LoadLibrary("User32.DLL");if(hInst){typedef BOOL (WINAPI *ShowLayer)(HWND,COLORREF,BYTE,DWORD);ShowLayer fun = NULL;// 读取函数指针fun = (ShowLayer)GetProcAddress(hInst, "SetLayeredWindowAttributes");if (fun)fun(this->GetSafeHwnd(), 0, 230, 2);FreeLibrary(hInst);}HBITMAP startpic;CStaticstartPics;startpic=(HBITMAP) ::LoadImage(NULL,"snakeNet.bmp",IMAGE_BITMAP,110,50,LR_LOADFROMF ILE|LR_DEFAULTSIZE);startPics.Create(NULL,WS_CHILD|WS_VISIBLE|SS_BITMAP|SS_CENTERIMAGE,CRect(200,457,20 0+110,457+50),this,NULL);startPics.SetBitmap(startpic);GetSafeHwnd(), 0, 230, 2);里面的参数230是改变透明度对话框的函数好像不一样2.更换背景图片首先先找一张图片将其格式转换成.Bmp格式然后在VC中ctrl+R 新建一个bitmap资源然后在资源栏中右击选择引入然后选择你的那张BMP格式图片出现这个不用理然后在View类中添加CBrush类型的m_brushBackground变量然后在View的构造函数中添加代码CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP2); ///加载位图m_brushBackground.CreatePatternBrush(&bmp); ///创建位图画刷其中IDB_BITMAP2是你图片的ID号然后在OnDraw(CDC* pDC)函数中添加代码CRectrect;GetClientRect(rect);///取得客户区域pDC->FillRect(rect,&m_brushBackground); ///用背景画刷填充区域然后调试就发现背景好看多了3.标题栏标题栏图标找一个IOC格式的图片直接把名字改成工程文件夹中rs文件夹中的ico格式图片的名字直接替换就行了标题栏名字在App。
mfc clistctrl折叠和展开实施方法
MFC CListCtrl折叠和展开实施方法一、简介本文将详细介绍如何在MFC中使用CListCtrl实现折叠和展开功能。
CListCtrl 是一个功能强大的列表控件,可以显示不同样式的列表项,如图标、文本等。
通过实现折叠和展开功能,可以使用户更方便地浏览和管理列表项。
二、准备工作在开始实现折叠和展开功能之前,需要先创建一个MFC项目,并在项目中添加一个CListCtrl控件。
具体步骤如下:1. 打开Visual Studio,创建一个新的MFC项目。
2. 在资源视图中,双击IDD_MAINFRAME对话框,将其打开。
3. 从工具箱中拖放一个CListCtrl控件到对话框上,并将其ID设置为IDC_LIST1。
三、实现折叠和展开功能要实现CListCtrl的折叠和展开功能,需要重载CListCtrl的一些消息处理函数。
具体步骤如下:3.1 重载OnItemExpanding()函数OnItemExpanding()函数用于处理列表项展开事件。
在此函数中,可以根据需要自定义展开操作。
以下是一个简单的示例:void CMyDialog::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult){LPNMITEMACTIVATE pItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// 获取当前选中的列表项int nItem = pItemActivate->iItem;// 判断是否为展开操作if (pItemActivate->iSubItem == -1){// 在这里执行展开操作,例如添加子项// ...// 设置返回结果,表示已处理此事件*pResult = TRUE;}else{// 如果是其他子项被点击,不处理此事件*pResult = FALSE;}}3.2 重载OnItemActivate()函数OnItemActivate()函数用于处理列表项被激活(点击)事件。
VC6MFC菜单详解
一、消息路由1、消息的路由:MFC在后台把窗口过程函数替换成了AfxWndProc函数,由这个函数对所有的消息进行处理,该函数内部将调用AfxCallWndProc函数,AfxCallWndProc函数又将调用WindowProc函数(CWnd类的成员函数),应用程序所有类型的消息都会进入到这个函数中。
WindowProc函数又将调用OnWndMsg函数,该函数会对到来的消息进行一个类型判断:若是标准消息,OnWndMsg函数查找相应的消息映射函数进行处理;若是命令消息,就交由OnCommand函数来处理,该函数将完成命令消息的路由;若是通告消息,将交由OnNotify 函数来处理,该函数将完成通告消息的路由。
OnCommand函数和OnNotify函数最后都会调用OnCmdMsg函数。
如下图所示:2、菜单命令消息路由的具体过程:当单击某个菜单项时,最先接收到这个菜单命令消息的是框架类(Frame类)。
框架类将把接收到的这个消息交给它的子窗口,即视类(View类)。
视类首先根据命令消息映射机制查找自身是否对此消息进行了响应,若响应了,就调用相应响应函数对这个消息进行处理,消息路由结束;若视类没有对此命令消息做出响应,就交由文档类。
文档类同样查找自身是否对这个菜单命令进行了响应,若响应了,就由文档类的命令消息响应函数进行处理,路由过程结束。
若文档类也未做出响应,就把这个命令消息交还给视类,视类又把该消息交还给框架类。
框架类查看自己是否对这个命令消息进行了响应,若它也没有做出响应。
就把这个菜单命令消息交给应用程序类来处理。
因此菜单命令的响应顺序依次是:视类、文档类、框架类、应用程序类。
二、菜单1、菜单项前添加标记”√”(1)、通过菜单项位置索引,在Frame类的OnCreate函数中添加:GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED);说明:GetMenu()获得菜单栏,GetSubMenu(0)获得第一个子菜单,CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED)为子菜单的第一个菜单项添加标记。
MFC学习小范例(编辑框控件的使用)
大家所熟知的编辑框即是QQ聊天窗口的输入编辑框,同样,MFC中的编辑框也是类似的东西,下面请看这个程序实现之后的截图分为上下两个编辑框窗口,上面的窗口实现输入,而点击显示后实现的是下面窗口的显示,类似于QQ聊天窗口的发送,确定和取消实现的是关闭程序。
请看截图:第一个截图是我在编辑框中输入一行语句,当然可以实现多行输入,也可以实现汉语的输入,下面的截图是我点击显示之后出现的运行画面。
源代码如下:编辑框控件的使用.cpp// 编辑框控件的使用.cpp : 定义应用程序的类行为。
//#include "stdafx.h"#include "编辑框控件的使用.h"#include "编辑框控件的使用Dlg.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// C编辑框控件的使用AppBEGIN_MESSAGE_MAP(C编辑框控件的使用App, CWinApp) ON_COMMAND(ID_HELP, &CWinApp::OnHelp)END_MESSAGE_MAP()// C编辑框控件的使用App 构造C编辑框控件的使用App::C编辑框控件的使用App(){// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在InitInstance中}// 唯一的一个C编辑框控件的使用App 对象C编辑框控件的使用App theApp;// C编辑框控件的使用App 初始化BOOL C编辑框控件的使用App::InitInstance(){// 如果一个运行在Windows XP 上的应用程序清单指定要// 使用ComCtl32.dll 版本 6 或更高版本来启用可视化方式,//则需要InitCommonControlsEx()。
否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = sizeof(InitCtrls);// 将它设置为包括所有要在应用程序中使用的// 公共控件类。
MFC如何给工具条上的按钮添加提示功能
MFC如何给工具条上的按钮添加提示功能在MFC中,可以通过重载工具条按钮的OnUpdateCmdUI函数来添加按钮提示功能。
下面是一种实现方法:1.创建一个新的MFC应用程序,并在资源视图中添加一个工具条。
在工具条中添加需要添加提示功能的按钮。
2. 打开工具栏的相关代码文件。
通常是MainFrm.cpp文件。
3. 找到CToolBar类的相关函数,例如OnCreate、OnEraseBkgnd等函数。
4. 在OnCreate函数中,找到以下代码:```cpp//注释掉默认的按钮提示文本设置// m_wndToolBar.SetWindowText(...)```5. 在OnEraseBkgnd函数中,找到以下代码:```cpp//注释掉默认的按钮提示文本设置// CFrameWnd::OnEraseBkgnd(pDC);```6.在该文件的末尾,添加以下代码:```cppvoid CMainFrame::OnUpdateCmdUI(CCmdUI* pCmdUI)if (pCmdUI->m_nID >= ID_FILE_NEW && pCmdUI->m_nID <= ID_FILE_PRINT)//替换按钮提示文本CString strToolTip;switch (pCmdUI->m_nID)case ID_FILE_NEW:strToolTip = _T("New"); break;case ID_FILE_OPEN:strToolTip = _T("Open"); break;case ID_FILE_SAVE:strToolTip = _T("Save"); break;case ID_FILE_PRINT:strToolTip = _T("Print"); break;//添加其他按钮的提示文本}//设置按钮的提示文本pCmdUI->SetText(strToolTip);pCmdUI->m_pMenu->SetMenuItemText(pCmdUI->m_nIndex, strToolTip);pCmdUI->m_pOther->SetText(strToolTip);}else//将其他命令消息传给父类处理CFrameWnd::OnUpdateCmdUI(pCmdUI);}```7.重新编译并运行应用程序,鼠标放置在工具条按钮上,将会显示相应的提示文本。
mfc调用active控件
mfc调用active控件
MFC(Microsoft Foundation Class)是一种用于开发Windows 应用程序的C++类库,而ActiveX控件是一种可重用的软件组件,通常用于在Web浏览器或其他容器应用程序中显示交互式内容。
在MFC中调用ActiveX控件可以通过以下步骤实现:
1. 首先,你需要在MFC应用程序中创建一个对话框或视图来容纳ActiveX控件。
你可以在资源编辑器中添加一个ActiveX控件,或者在代码中动态创建和添加ActiveX控件。
2. 然后,你需要在MFC应用程序中使用类向导来生成ActiveX 控件的包装类。
在Visual Studio中,你可以使用“添加类”对话框来生成包装类。
3. 生成包装类后,你可以在对话框或视图类的代码中实例化ActiveX控件的包装类对象,并调用其方法或设置其属性。
例如,你可以使用Create函数创建ActiveX控件的实例,并使用其提供的方法来实现所需的功能。
4. 最后,在MFC应用程序的消息映射函数中处理ActiveX控件
的事件,例如按钮点击事件或文本框内容改变事件。
你可以通过包装类提供的事件映射功能来实现对ActiveX控件事件的处理。
总的来说,MFC调用ActiveX控件涉及到创建包装类、实例化控件对象、调用控件方法和处理控件事件等步骤。
通过这些步骤,你可以在MFC应用程序中有效地使用ActiveX控件实现丰富的交互式功能。
MFC编辑框、静态文本框相关的常用函数
《1》GetDlgItemText(ID ,str)作用:从对话框中获取文本第一个参数为要获取的编辑框(或者静态文本框、单选按钮等可以显示内容的控件)的ID,第二个参数为字符串(Cstring 类型)的变量,获取的文本存储在str中。
《2》SetDlgItemText(ID,str)作用:将字符串显示在控件中第一个参数为要显示的编辑框(或者静态文本框、单选按钮、组合框等可以显示内容的控件)的ID,第二个参数为字符串(Cstring 类型)的变量,显示的文本存储在str中。
如果要显示的变量的类型不是Cstring,则通过Format函数强制转换。
通常还要加一个UpDateData(FALSE)。
《3》UINT nID=GetCheckedRadioButton(IDC1, IDC2);作用:获取单选框的选项的ID第一个参数为该组合框中第一个单选按钮的ID,第二个参数为该组合框中最后一个按钮的ID。
《4》CheckRadioButton(IDC1, IDC2, IDC3);作用:初始化单选按钮第一个参数为该组合框中第一个单选按钮的ID,第二个参数为该组合框中最后一个按钮的ID,第三个参数为为缺省选项的ID。
《5》m_scrollBar.SetScrollRange(0, 500) ;作用:设置水平滚动条的取值范围,m_scrollBar为水平滚动条的控制类型的变量,0为设置最小值,500为设置的最大值。
《6》m_nAmount = m_slider.GetPos() ;作用:获取滑块的当前位置。
《7》m_slider.SetRange(0,1000) ;作用://设置滑块取值范围第一个参数为设置的最小值,第二个参数为设置的最大值。
《8》double Volum = atof(strCtrl);作用:将字符串strCtl转换成浮点型的Volum《9》int Volum = atof(strCtrl);作用:将字符串strCtl转换成整型的Volum《10》MessageBox(str) ;(局部函数)作用:输出字符串str《11》AfxMessageBox(str) ;(全局函数)作用:输出字符串str《12》tempt = m_time2.Format("%H:%m:%S") ;作用:将时间转化成字符型(时、分、秒)m_time2为日历时间选取器的变量,tempt为CString型变量《13》tempt = m_time.Format("%Y-%m-%d") ;//将时间转化成字符型作用:将时间转化成字符型(年、月、日)m_time2为日历时间选取器的变量,tempt为CString型变量《14》m_time = CTime::GetCurrentTime();作用:获取系统当前时间m_time为Ctime类型的变量。
修改MFC应用程序的图标、光标、托盘图标、窗口风格的方法
其中,hIcon用来指定要删除的图标句柄。 3. 图标的显示 图标的显示一般有两种方法:一是通过静态图片控件来显示,或在其他(如按钮) 控件设置显示;二是通过函数CDC::DrawIcon用来将一个图标绘制在指定设备的位置处 (这一方法以后再讨论)。 4. 图标示例 下面来看一个示例,如图5.5所示,单击[开始]按钮,3个图标就会每隔100ms随机显示, 且此时[开始]按钮变成[停止]。单击[停止]按钮,图标停止更新,按钮的名称变成“开 始”,如果3个图标的图案都是一样的,则弹出消息对话框,显示“恭喜你!”,否则 显示“失败!”。
5.2图标
(4)在CMainFrame::OnCreate函数的最后添加计时器设置代码:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; ... SetTimer(1, 500, NULL); return 0; }
其中,lpszResourceName和nIDResource分别表示图标资源的字符串名和标识。函 数返回的是一个图标句柄。 如果不想使用新的图标资源,也可使用系统中预定义好的标准图标,这时需调用 CWinApp::LoadStandardIcon 函数,其原型如下:
HICON LoadStandardIcon( LPCTSTR lpszIconName ) const;
图5.6 添加并设计的图标
5.2图标
(4)在ResourceView页面中,双击“Dialog”下的IDD_EX_RANDICON_DIALOG, 打开对话框资源模板。将对话框的标题设为“图标使用”。删除“TODO: 在这里设置对 话控制。”静态文本控件和[取消]按钮,将[确定]按钮标题改为“退出”。 (5)打开对话框网格,参照图5.5所示,调整对话框大小,分别依次添加3个静态图 片控件,ID号分别设置为IDC_STATIC_1、IDC_STATIC_2和IDC_STATIC_3,类型选择 为“图标”,图像依次选择为IDI_ICON1、IDI_ICON2和IDI_ICON3,在样式属性中,分 别选中“图像居中”。 (6)添加一个按钮控件,ID号为IDC_BUTTON_START,标题为“开始”。 (7)按Ctrl+W键,打开MFC ClassWizard的Member Variables页面,依次为 IDC_STATIC_1、IDC_STATIC_2和IDC_STATIC_3设置CStatic类的Control变量 m_wndIcon1、m_wndIcon2和m_wndIcon3。 (8)切换到Messsage Maps页面,为按钮IDC_BUTTON_START添加 BN_CLICKED消息映射,保留默认的映射函数名,添加下列代码: (9)再次打开MFC ClassWizard的Messsage Maps页面,为CEx_RandIconDlg类 添加WM_TIMER消息映射,并在映射函数中添加下列代码: (10)编译运行并测试。
MFC原理与方法
编程时如果MFC某个类能完成所需要的功能,可以直接调用已 有类的方法(成员函数)。否则,可以利用面向对象技术中的 “继承”方法对MFC类的行为进行扩充和修改,从MFC中已有 的类派生出自己需要的类。
Hale Waihona Puke CMainFrame类类 CMainFrame 是由 MFC 中的 CFrameWnd 派生的,所 以它也是一个框架窗口。CMainFrame 是类 CXXView 的 父类,即 CXXView 类的对象显示在主框架窗口的客户 区中。在类 CMainFrame 中,系统已经从类 CFrameWnd 中继承了处理窗口的一般事件的 Windows 消息,如改变窗口的大小、窗口最小化等的成员函数 ,因此编程时程序员不必关心此类消息的处理,从而 减轻了程序员的负担。当然,如果确实需要重新编写 此类消息的成员函数,则需要对原有的成员函数进行 重载。
MFC 中的大部分类都是从基类 CObject 中继承的,该 类包含大部分 MFC 类所通用的数据成员和成员函数;
CWinApp 类是在建立应用程序时需要用到的,并且在 任何程序中都只用一次;
CWnd 类汇集了 Windows 中的所有通用特性、对话框 和控制。
CFrameWnd 类是从 CWnd 中继承的,并实现了标准的 框架应用程序;
CDialog 可分别处理无模式和有模式两种类型的对话框 。
CView 用于让用户通过窗口来访问文档。
MFC应用程序的生与死
在MFC应用程序的CWinApp派生类对象theApp是一个全局变 量,代表了应用程序运行的主线程。它在程序整个运行期 间都存在,它的销毁意味着运行程序的消亡。
MFC标题栏及边框的自绘
MFC标题栏及边框的自绘SDI 和MDI 程序中对非客户区(标题栏、左右下边界)的美化基本思路是重载CMainFrame 类的DefWindowProc()函数,并判断消息为:WM_NCPAINT,WM_NCACTIV A TE,WM_NOTIFY的时候,调用自己的绘制窗口标题栏的函数。
用GetSystemMetrics(SM_CSFRAME)和GetSystemMetrics(SM_CYFRAME)可以取得标题栏的左上角的坐标。
最大化,最小化的按钮自己画,如果不是在标准的位置,一定要记录下他们的位置,并且在WM_NCLBUTTONDOWN消息处理函数中判断是否是点击了按钮,以做出相应的处理。
系统图标也可以自己重新画。
主要任务有贴图(包括标题栏、左边界、右边界、下边界、系统图标、最大化、最小化、关闭按钮)、处理消息(屏蔽系统自带按钮、双击状态栏改变大小、鼠标停放在三个自绘按钮上时改变按钮图标、单击自绘按钮时作出相应反应)。
一、响应的消息及重载的函数响应的消息及重载的函数都在CMainFrame 类中。
响应DefWindowProc 函数,在其中判断消息是不是WM_NCPAINT、WM_MOVE、WM_NCACTIV A TE、WM_NOTIFY,若是则重画标题栏、左框架、右框架、下框架、最大化、最小化、关闭按钮(放在一个函数里)。
响应消息WM_NCHITTEST,使鼠标位于自绘按钮时返回相应hittest 值,同时屏蔽自带按钮的鼠标事件。
简言之,当鼠标位于自绘按钮时,让系统误以为鼠标位于相应按钮,而当鼠标位于系统自带按钮时,让系统误以为鼠标只是位于标题栏。
自绘图标与之类似,不再赘述。
响应消息WM_NCMOUSEMOVE,判断光标是不是位于自绘最大化、最小化、关闭按钮区域,如是则重画相应的按钮。
响应消息WM_NCLBUTTONDOWN,判断单击左键时鼠标是否位于自绘制的最大化、最小化、关闭按钮或图标区域,如是则执行相应的按钮操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1:如何修改单文档应用程序的窗口标题,查阅MSDC文章:Changing the styles of a window created by MFC.要在CMainFrame的PrecreatWindow()中加入如下代码:cs.style&=~FWS_ADDTOTITLE;cs.lpszName="This is a test!";可以先不要上一句试一试!另一种方法是 :cs.style=WS_OVERLAPPEDWINDOW;再进行修改,也可以不修改,那么是去掉默认文档标题,而只显示原程序标题!另一类方法是在窗口创建后再修改,因为在OnCreate中,开始的这些代码: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; // 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 don't want the toolbar to// be dockablem_wndToolBar.EnableDocking (CBRS_ALIGN_ANY);EnableDocking (CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);完成了窗口创建,工具栏,状态栏的创建等工作,可以在后面利用一个系统全局函数SetWindowLong()函数进行修改:加入代码为:SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);与此相对,还有一个GetWindowLong()函数可供使用!如下面代码去掉了窗口上的最大化按钮: SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~MAXIMIZEBOX); 当然SetWindowLon()还可以做别的修改.与SetWindowLong()相类似的另一个系统全局函数为SetClassLong();2:如何完成一个动画图标其实就是准备好几个图标,在定时器消息响应中更改图标即可完成.第一步是准备好几个(如三个)图标.第二步是在CMainFrame类中做三个图标类的相关对象的成员变量,或者是一个大小为3的HICON 数组.第三步是在CMainFrame类的OnCreate()函数中LoadIcon()进行对三个图标的加载.其中用到的实例句柄的获取有三种方法:一:用全局函数AfxGetInstanceHandle()获取,二:先在CMainFrame类中用extern声明一下全局对象theApp,然后使用theApp.hInstance; 三:使用全局函数AfxGetApp()获取全局对象theApp对象的指针,然后用AfxGetApp()->hInstance;第二个参数是一个字符指针,可我们只有图标的资源ID,所以要进行必要的转换:用MAKEINTRESOURCE宏!第四步是设置定时器,也在OnCreate()函数中定义:SetTimer(1,1000,NULL);第五步是在CMainFrame中添加WM_TIMER消息响应,在其中加入代码:static int index=0;SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[index]);index=++index%3;3:在工具栏上新加一个按钮,要让它与前一个按钮之间有一个分隔符,只需要将它轻轻向一旁拖动一点点再放开即可,而要删除工具栏上的一个按钮,你只是选中它再按DEL键是完不成的,它只是将按钮上的图案删除,所以删除一个按钮要将它拖动到工具栏之外,再松手!4:如何创建一个工具栏在MSDN的关于CToolBar的讲解页有详细说明!一:插入工具栏资源,二:在CMainFrame中加入一个CToolBar类对象的成员变量,三:在CMainFrame的OnCreate()中加入:if (!m_MyToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||! m_MyToolBar.LoadToolBar(IDR_MYTOOLBAR)){TRACE0("Failed to create toolbarn");return -1; // fail to create}m_MyToolBar.EnableDocking (CBRS_ALIGN_ANY);DockControlBar(&m_MyToolBar);各个函数调用及参数传递查看MSDN!5:如何让一个工具栏隐藏或显示:if(m_MyToolBar.IsWindowVisible()){m_MyToolBar.ShowWindow(SW_HIDE);}else{m_MyToolBar.ShowWindow(SW_SHOW);}但这样做的结果是工具栏虽说隐藏了, 但是工具条还在,所以还要在后面加上一句:ReCalcLayout();这样做还是有问题,如果工具栏没有停靠在边上而是一个单独的小窗口,那么只做上面的工作只使得工具栏上的按钮不见了,而那个小窗口还在,所以,还要调用一个函数:DockControlBar (&m_MyToolBar);经过上面这句,小窗口也如愿消失了,但问题还有一点,就是当用户将工具栏放置为一个小窗口时,再点击菜单,要让这个工具栏显示出来,当然我们应该将工具栏仍按用户先前的小窗口样式显示出来比较好,可是这次工具栏又自动停靠在客户区顶部了?这个功能如何实现呢?孙老师只是提示可以查MSDN中CToolBar的成员函数解决这个问题,并没细讲,所以我看了MSDN,发现有两个函数:CToolBar::IsFloating()利用这个函数可以判断一个工具栏是否处于浮动状态,另一个是CFrameWnd::FloatControlBar()这个函数可以让一个控制栏处于浮动状态,然后我在CMainFrame中加入了一个BOOL型的成员变量,在每次判断工具栏是否可见时用来记录工具栏是否处于浮动状态,然后在重新生成工具栏时根据它的置决定是否将工具栏设为浮动状态,但是第二个函数好像不太好使,所以我又换用了SetWindowPos()成员函数,可是也不能将它放置为一个独立的小窗口.显示和隐藏工具栏的第二种方法:用一个函数:CFrameWnd::ShowControlBar(),因为这个函数的固有特性,上面是if...else...判断就可以简化为一句代码:ShowControlBar(&m_MyToolBar,!m_MyToolBar.IsWindowVisible(),FALSE);并且我惊讶的发现,用这个函数时,上面提到的浮动工具栏让它在恢复的时候仍回复为浮动的问题自动解决了!哈哈,好.6:状态栏相关编程因为MFC自动生成的系统已经包含了一个状态栏,所以我们暂时仅限于已有状态栏的修改,而不是另外生成一个状态栏.状态栏最左边的那一长条,就是经常显示一些提示字符串的那部分叫做提示行,而右侧那三个小窗口是用来指示 CapsLock,ScrollLock,NumLock开关的状态,称为状态指示器.状态栏跟工具栏一样,也是在CMainFrame类中定义并在OnCreate()中创建的.下面的代码在状态指示器的最左边放置了两个小窗口,并在第一个小窗口中放置了一个时钟:同样的CMainFrame的OnCreate() 中,CTime tm=CTime::GetCurrentTime();CString strTime=tm.Format("%H:%M:%S");CClientDC dc(this);CSize sz=dc.GetTextExtent(strTime);m_wndStatusBar.SetPaneInfo (1,IDS_TIMER,SBPS_NORMAL,sz.cx);//调整窗口大小m_wndStatusBar.SetPaneText(1,strTime);SetTimer(2,1000,NULL);当然要先有准备工作,在字符串资源中添加两个字符串,ID分别为:IDS_TIMER,IDS_PROGRESS,交将之添加到MainFrm.cpp的static UINT indicators[] ={ID_SEPARATOR, // status line indicatorIDS_TIMER,IDS_PROGRESS,ID_INDICATOR_CAP S,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};这个数组中,并且上面SetPaneInfo()中的第一个参数就是相应ID在indicators[]数组中的索引值,显然最后三个ID是大小写,数字锁及ScroolLock的标识.做完上面这些工作,这个时钟还不能变化,只是显示了一个定值,我们还要在定时器的响应函数中再刷新该值:if (2==nIDEvent){CTime tm=CTime::GetCurrentTime();CString strTime=tm.Format("%H:%M:%S");m_wndStatusBar.SetPaneText (1,strTime);}这样就完成了一个在状态栏中显示的,可以动态变化的时钟!7:如何创建一个进度条并将之放置在状态栏中的某个位置?与MFC中其它标准资源一样,进度条也有一个专门的类与之相对应:CProgressCtrl类.先在CMainFrame中放置一个成员变量:CProgressCtrl m_ProgBar;然后在OnCreate()中加入:m_ProgBar.Create(WS_CHILD | WS_VISIBLE,CRect (300,100,500,120),this,88888);就可以在窗口中显示一个进度条.至于要将之放置于状态栏上的某个窗格之中,就要先得到窗格所在的矩形区域,然后在上面是第二个参数中进行指定,故将上面一句改为如下:CRect rect;m_wndStatusBar.GetItemRect (2,&rect);m_ProgBar.Create(WS_CHILD | WS_VISIBLE,rect,this,88888);可是这样并未实现设置,所以我们在上面设置断点,发现到达m_ProgBar.Create()时矩形区域的值并不正常,原来在OnCreate()未结束时,状态栏的设置无法完成,无法获得矩形区域位置,所以,就要想办法在OnCreate()结束时做上面的工作,可以做一个自定义消息,在OnCreate()末尾发送一个该消息,并做一个消息响应函数,然后将上面的代码放置在其中即可.要自定义消息,首先要在CMainFrame的头文件首部做:#define UM_PROGRESS WM_USER+1 //注意,没有;WM_USER是一个系统定义宏,详细情况查MSDN.然后在CMainFrame的头文件的消息响应中加入消息响应函数的声明:afx_msg void OnProgress();再加入消息映射:ON_MESSAGE(UM_PROGRESS,OnProgress)再实现消息响应函数:void CMainFrame::OnProgress(){CRect rect;m_wndStatusBar.GetItemRect(2,&rect);m_ProgBar.Create(WS_CHILD | WS_VISIBLE,rect,&m_wndStatusBar,123);//注意,这里父窗口就不能设置为this了, 而要是状态栏!m_ProgBar.SetPos(50);}当然,不能忘了在OnCreate()最后发送消息:PostMessage(UM_PROGRESS);这样就可以了!但是问题还是有的,你会发现当你拉动窗口改变其大小时,状态栏的位置发生了变化,不再覆盖在先关状态栏的那个小窗口上了,怎么办呢?你会想到在窗口大小改变时,系统会接受到一个WM_PAINT消息,只要在那个消息的响应函数中实时获取小窗口的矩形区域,再改变进度条的位置,不就可以了吧,没错,这样的确可以,又因为WM_PAINT消息当窗口显示时,也就是说OnCreate()之后就会马上收到,所以我们也不用像上面那样麻烦的自定义什么消息啦,直接在CMainFrame中加入WM_PAINT的消息响应函数,并在其中加入:CRect rect;m_wndStatusBar.GetItemRect(2,&rect);m_ProgBar.Create(WS_CHILD | WS_VISIBLE,rect,&m_wndStatusBar,123);m_ProgBar.SetPos(50);即可了,但是问题又来了,当窗口大小一改变时,程序发生了一个致使错误,原来我们不能在每一次响应时都创建进度条,进度条对象只有一个,哪能多次使用呢?所以,改为如下代码:CRect rect;m_wndStatusBar.GetItemRect(2,&rect);if(!m_ProgBar.m_hWnd){m_ProgBar.Create(WS_CHILD | WS_VISIBLE,rect,&m_wndStatusBar,88888);}else{m_ProgBar.MoveWindow(&rect);}m_ProgBar.SetPos(50);这下,无论怎么拖,也不会发生异常现象了!那么,如何让进度条动起来呢?相关的成员函数为SetStep(),以及StepIt();8:下面的代码将鼠标当前的位置坐标显示在状态栏的提示行中:在View类中响应WM_MOUSEMOVE消息,在其中加入代码如下:CString str;str.Format("x=%d,y=% d",point.x,point.y);((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);这段代码要正常运行的前提是首先CMainFrame在View文件中不可见,所以要先包含一个MainFrm.h头文件,然后,因为m_wndStatusBar在CMainFrame中是一个protected变量,所以不能在View类中访问,所以我们要手动把它的访问权限改为public.然后就OK了!其实还有一种更方便的方法:调用CFrameWnd::SetMessageText()所以上面的代码就可以改为:CString str;str.Format("x=%d,y=% d",point.x,point.y);((CMainFrame*)GetParent())->SetMessageText (str);这样子,就不用取得状态栏指针了,也就不用去修改其访问权限了!关于这个工作,还有第三种方法,也不用去修改状态栏的访问权限,这是应用了另一个函数:CHtmlView::GetStatusBar(),上面的代码就可以是:CString str;str.Format("x=%d,y=%d",point.x,point.y);((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);下面还有第四种方式:这是应用了又一个函数:CWnd::GetDescendantWindow(),这个函数可以根据窗口ID来从调用它的窗口出发找到与该ID相同的一个子孙窗口的指针:CString str;str.Format("x=%d,y=%d",point.x,point.y);GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);至于上面那个ID号,是从CStatusBar::Create()中看到它!关于GetDescendantWindow()的调用,要注意其第二个参数在MSDN中关于临时窗口及持久窗口的讲解!9:关于程序的启动画面的制作这个跟往程序中加入右键PopUp菜单一样,可以使用VC的组件库中的组件.找到一个叫SplashScreen的东西,加入它到工程中,别的什么也别动,先编译运行一下,你会发现程序已经有一个启动画面了,不过是很简陋的.这个组件在我们的程序中加入了一副默认位图,并加入了一个叫CSplashWnd的类,并且在CMainFrame的OnCreate()函数中加入了一句:CSplashWnd::ShowSplashScreen(this),进行了相应的启动工作.在CSplashWnd的成员函数OnCreate()中有一句SetTimer(1, 750, NULL);其消息响应函数中进行了启动画面的隐藏,所以,修改其中的时间值可以修改启动画面显示的时间长度!另外,可以发现窗口的显示与启动画面的显示是同时进行的,如何才能让画面消失时窗口才显示出来呢?至于启动画面的改变,可以自己插入位图,然后将它的ID修改为IDB_SPLASH 然后RebuildAll,也可以在其源文件中LoadBitmap()中将ID改为自己想要加载的位图的ID。