zoukankan      html  css  js  c++  java
  • MFC界面程序

    目录

    一、MFC简介... 4

    1.MFC的组织结构... 4

    (1)根类... 4

    (2)应用程序体系结构类... 4

    (3)可视对象类... 6

    (4)通用类... 7

    (5)OLE类... 8

    (6)ODBC数据库类... 8

    2.全局变量和函数... 9

    3应用程序向导Wizard. 9

    二、windows标准控件... 9

    1.按钮... 9

    (1)创建按钮... 9

    (2)和按钮有关的消息... 10

    (3)可能用到的成员函数... 11

    2.滚动条... 11

    (1)创建滚动条... 11

    (2)和滚动条有关的消息... 12

    (3)可能用到的方法... 12

    3.静态控件... 13

    (1)创建方法... 13

    (2)和该控件有关的消息... 13

    (3)可能用到的函数... 13

    4.列表框... 13

    (1)创建列表框... 13

    (2)和列表框有关的消息... 14

    (3)可能用到的函数... 14

    5.编辑框... 16

    (1)Cedit的样式... 17

    (2)和编辑框有关的消息... 17

    (3)可能用到的函数... 18

    6.组合框... 19

    (1)组合框的样式... 20

    (2)和组合框有关的消息... 20

    7.对话框通用控件... 22

    (1)Picture. 22

    (2)Spin. 22

    (3)Progress 23

    (5)Date Time Picker 25

    (6)List Control 25

    (7)Tree Control 28

    (8)Extended Combo Box. 33

    三、资源... 35

    1.菜单... 35

    (1)程序主菜单... 35

    (2)快捷菜单... 37

    (3)工具栏菜单... 39

    2.加速键... 42

    3.字符串... 42

    4.对话框... 43

    (1)CDialog可能用到的函数... 44

    (2)在资源视图中插入新的Dialog,编辑需要的控件... 44

    (3)为这个对话框建立关联的类... 44

    (4)在对话框类中为需要的控件添加需要的数据变量... 44

    (5)在需要的源文件中使用这个对话框类... 44

    5.图标... 45

    6.位图... 45

    四、单文档SDI和多文档MDI界面... 46

    1.可能用到的概念... 46

    2.消息映射... 47

    3.核心类... 49

    (1)CWinApp. 49

    (2)CDocument 49

    (3)CView.. 51

    (4)CDocTemplate. 52

    (5)CFrameWnd. 53

    (6)5个核心类的相互访问... 54

    4.在程序向导上创建SDI和MDI程序... 54

    (1)SDI 54

    (2)MDI 54

    5.MFC多线程... 58

    五、数据库... 58

    1.有关数据库的基础知识... 58

    (1)CRecordView.. 58

    (2)CRecordSet 58

    (3)CDatabase. 60

    (4)RFX.. 61

    (5)CDBException. 61

    2.建立ODBC数据源... 61

    3.显示数据库中的数据... 62

    4.对记录进行排序... 62

    5.增添记录... 63

    6.删除记录... 64

    7.查询记录... 66

    8.修改记录... 67

    9.移动到指定的位置... 68

    六、多媒体... 69

    1.音频播放... 69

    (1)使用音频函数的方式... 69

    (2)使用MCI的方式... 70

    2.视频播放... 78

    3.图片显示... 79

    (1) 创建SDI工程... 79

    (2) 在View类中添加数据成员:... 79

    (3) 新数据成员的初始化和销毁:... 79

    (4) 通过菜单项打开文件:... 80

    (5) 对图片进行绘制:... 82

    七、网络编程... 84

    1.利用WinInet抓取网页... 84

    八、附录... 86

    1.vs的快捷键... 86

    正文

    一、MFC简介

    MFC即Microsoft Foundation Class,封装了很多windows api和windows控件,可以明显的缩短程序设计的周期(填充框架、添加功能即可)

    1.MFC的组织结构

    按照结构和功能上分类

    (1)根类

    CObject是MFC中大多数类的基类,这个类有序列化、查询对象运行时信息等功能,序列化是指将对象的数据存储下来;更详细的资料需要查看MSDN文档

    Serialize()

     

    IsSerializable()

     

    IsKindof()

    是否是某个类或者派生类

    GetRuntimeClass()

    包括它的类名、基类名等信息

    (2)应用程序体系结构类

    CWinApp和程序的结构框架有关,基于MFC的应用程序几乎从它派生而来

    ①CCmdTarget

    功能上是消息映射,当对象收到消息后决定应该调用哪一个函数,其他和CCmdTarget有关的类:窗口类CWnd、文档模板类CDocTemplate、文档类CDocument、视类CView、框架窗口类CFrameWnd

    ②CWinThread

    创建和控制线程

    CreateThread()

     

    SetThreadPriority()

     

    SuspendThread()

     

    ③CWinApp

    即应用程序对象,继承自CWinThread、CWinThread又继承自CCmdTarget、CCmdTarget继承自CObject,CWinApp的对象在每个应用程序中都是唯一的

    部分数据成员

    m_pszAppName

    应用程序的名称

    m_hInstance

    当前应用程序的实例

    m_lpCmdLine

    指向命令行参数的指针

    m_nCmdShow

    窗口开始的显示风格

    m_bHelpMode

    用户按下shift+f1时是否做出帮助响应

    m_pActiveWnd

    指向应用程序主窗口的指针

    m_pszExeName

    应用程序可执行文件的名称

    m_pszHelpFilePath

    帮助文档的路径

    m_pszProfileName

    .ini初始化文件名

    m_pszRegistryKey

    初始化文件存放的位置

    部分函数成员

    DoMessageBox()

    弹出一个对话框

       
       

    ④文档/视类

    CDocument负责管理文档的操作,文档模板对象可以创建不同文档类型的文档对象,并且每个文档对象都有一个指向其文档模板对象的指针

    CDocTemplate

    文档模板基类

    CSingleDocTemplate

    单文档界面的文档模板

    CMultiDocTemplate

    多文档界面的文档模板

    CDocument

    文档操作

    CView

    文档数据显示的基类,继承自CWnd

    CView的派生类

    CScrollView

    有滚动条的视图

    CCtrlView

    有树、列表框等控件的视图

    CDaoRecordView

    显示数据库记录的视图,多用于DAO的查询结果

    CEditView

    多行文本编辑器的视图

    CFormView

    表单模板的视图

    CListView

    列表框控件的视图

    CRecordView

    显示数据库记录的视图

    CRichEditView

    富文本编辑控件的视图

    CTreeView

    树控件的视图

    CPreviewView

    支持打印预览

    (3)可视对象类

    ①CWnd

    窗口类,它的派生类有:SDI应用程序框架窗口类CFrameWnd、MDI应用程序框架窗口类CMIDFrameWnd、MDI应用程序文档框架窗口类CMDIChildWnd

    ②CMenu

    对基础api对象HMenu的封装,负责和菜单有关的操作

    ③CDialog

    对话框类,它的派生类有:文件标准对话框CFileDialog、颜色标准对话框CColorDialog、字体标准对话框CFontDialog、文件打印标准对话框CPrintDialog、查询替换标准对话框CFindReplaceDialog、用户自定义的对话框CDialog

    ④控件类

    静态控件

    CStatic

     

    按钮

    CButton

     

    编辑框

    CEdit

     

    富文本编辑框

    CRichEditCtrl

     

    滚动条

    CScrollBar

     

    进度条

    CProgressCtrl

     

    游标

    CSliderCtrl

     

    列表框

    CListBox

     

    组合框

    CComboBox

     

    位图按钮

    CBitmapButton

     

    数值调整框spin

    CSpinButtonCtrl

     

    动画显示控件

    CAnimateCtrl

     

    弹出式说明

    CToolTipCtrl

     

    热键控件窗口

    CHotKeyCtrl

    用户可以创建“热键”,使某个操作使用更方便

    ⑤控件条类CControlBar

    通常充当工具条、状态条等身份,它的基类有:窗口的基类CStatusBar、工具条上的按钮命令CToolbgar、非模态对话框CDialogBar

    ⑥绘画对象类CGdiObject

    和绘画有关,它的子类有:提供操作GDI位图接口的CBitmap、GDI画刷的CBrush、GDI字体的CFont、GDI调色板的CPalette、GDI画笔的CPen、用于剪裁的GDI域CRgn

    ⑦设备描述表CDC

    和绘画有关,它的子类有:

    CPaintDC

    简化了BeginPaint和EndPaint的过程,OnPaint、OnDraw对象的成员函数会用到

    CClientDC

    用户窗口的设备描述表

    CWindowDC

    整个窗口的设备描述表,包括用户区和框架区

    CMetaFileDC

    windows元文件的设备描述表,和图形设备接口GDI有关

    (4)通用类

    ①文件类

    CFile

    提供二进制磁盘文件的总接口,通过CArchive对象被间接访问

    CMemFile

    提供访问内存文件的总接口

    CStdioFile

    提供访问缓存磁盘文件的总接口,通常是文本的方式

    CArchive

    与CFile对象一起实现对象的持久化

    ②异常类CException

    不能直接建立CException对象,通常使用它的派生类;产生异常的描述在异常对象的m_cause成员数据中

    CNotSupportedException

    不支持服务

    CMemoryException

    内存异常

    CFileException

    文件异常

    CResourceException

    资源异常

    COleException

    OLE异常

    CArchiveException

    档案异常

    CDaoException

    DAO数据库类异常

    CDBException

    数据库存取异常

    CUserException

    用户操作异常

    ③模板收集类

    CArray、CMap、CList类使用的是全局帮助函数,可能需要编写特定的帮助函数

    CArray

    元素存储在数组中

    CMap

    将键映射到值

    CList

    元素存储到链表中

    CTypedPtrList

    将对象指针存储在链表中

    CTypedPtrArray

    将对象指针存储在数组中

    CTypedPtrMap

    将键映射到值,键和值都是指针

    (5)OLE

    OLE指的是对象连接和嵌入,和复合文档的处理有关(通常见到的word、excel),ActiveX在网络编程方面对OLE做了进一步的扩展

    普通类

    COleDocument、COleItem、COleException

    用户类

    COleClientDoc、COleClientItem

    服务类

    COleServer、COleTemplate、COleServerDoc、COleServerItem

    可视编辑容器类

    COleClientItem、COleLinkingDOC

    数据传输类

    COleDropSource、COleDropTarget、COleDataSource、COleDataObject

    对话类

    COleInsertDialog

    其他

    CRectTracker为复合文档中的某项建立边框,使之可移动和可调整大小

    (6)ODBC数据库类

    CDatabase

    面向ODBC驱动程序的一种标准界面

    CRecordset

    面向ODBC驱动程序的一种标准界面

    CRecordView

    CFormView的子类,将查询集和显示的字段关联起来,便于直观操作

    CFieldExchange

    提供上下文信息,支持记录字段交换

    CLongBinary

    用于存储二进制对象,比如位图

    CDBException

    数据库存取异常

    2.全局变量和函数

    一般以Afx开头,函数中不包括数据库类的函数和Dialog Data Exchange的内容

    AfxMessageBox()

    弹出一个对话框

    AfxGetApp()

    获取一个指向CWinApp对象的指针

    AfxGetInstanceHandle()

    获取当前实例的句柄

    AfxGetResourceHandle()

    获取一个应用程序资源的句柄

    AfxGetAppName()

    获取一个指向应用程序名称的字符串指针

    AfxAbort()

    无条件终止一个应用程序

    AfxBeginThread()

    启动一个新线程

    AfxEndThread()

    终止当前线程

    AfxFormatString()

    格式化字符串

    AfxRegisterWndClass()

    注册windows窗口类

    3应用程序向导Wizard

    使用特定的框架或者添加一些内置的功能

    二、windows标准控件

    控件几乎都继承了CWnd类具有窗口的属性,因此具有一些通用的方法,比如显示或隐藏控件MoveWindow()、改变控件的位置SetWindowPos()、设置文本内容SetWindowText(),用代码或者在资源视图中拖拽都可以创建控件;在资源视图中右击控件可以添加变量、根据控件的消息添加一些消息处理的代码;格式->Tab键顺序,依次点击可以得到一个想要的tab键切换顺序;项目上右键选择“MFC类”可以扩展出自定义的控件类

    1.按钮

    (1)创建按钮

    BOOL Create(

    //按钮上的文本

    LPCTSTR lpszCaption,

    //按钮的风格

    DWORD dwStyle,

    //位置和大小

    const RECT& rect,

    //父窗口的指针

    CWnd* pParentWnd,

    //按钮的ID

    UINT nID);

    按钮的风格

    BS_AUTOCHECKBOX

    同BS_CHECKBOX,只是单击时按钮会自动反转

    BS_AUTORADIOBUTTON

    同BS_RADIOBUTTON,只是单击时按钮会自动反转

    BS_AUTO3STATE

    同BS_3STATE,只是单击按钮时会改变状态

    BS_DEFPUSHBUTTON

    默认的命令按钮,回车可以直接选中该按钮

    BS_GROUPBOX

    组框

    BS_LEFTTEXT

    按钮上的文本左对齐

    BS_CHECKBOX

    矩形的可选择框

    BS_RADIOBUTTON

    圆形的可选择按钮

    BS_3STATE

    同BS_CHECKBOX,只是有三种选择的状态

    BS_PUSHBUTTON

    指定一个命令按钮

    BS_OWNERDRAW

    指定一个自绘制按钮

    (2)和按钮有关的消息

    BN_CLICKED

    单击

    BN_DOUBLECLICKED

    双击

    (3)可能用到的成员函数

    CButton类的成员函数

    GetCheck()

    获取check类型按钮的选中状态,未选择0、选择1、不确定2

    SetCheck()

    设置check类型按钮的选中状态

    GetBitmap()

    获取位图

    SetBitmap()

    设置位图

    GetButtonStyle()

    获取按钮的样式

    SetButtonStyle()

    设置按钮的样式

    GetCursor()

    获取光标

    SetCursor()

    设置按钮上的光标

    GetIcon()

    获取按钮上的图标

    SetIcon()

    设置按钮上的图标

    GetState()

    获取按钮的状态,选中、选择、聚焦

    SetState()

    设置按钮的状态

    继承自CButton类的CBitmapButton

    LoadBitmaps()

    载入位图

    SizeToContent()

    改变位图的大小以适应按钮

    CWnd类的成员函数

    CheckDlgButton()

    设置按钮的选中状态

    CheckRadioButton()

    选择组中的一个按钮

    GetCheckedRadioButton()

    选择组中的一个已被选中的按钮

    IsDlgButtonChecked()

    返回按钮的选中状态

    GetWindowText()、GetWindowTextLength()、SetWindowText()

    和按钮上的文字有关

    2.滚动条

    (1)创建滚动条

    BOOL Create(

    DWORD dwStyle,

    const RECT& rect,

    CWnd* pParentWnd,

    UINT nID);

    (2)和滚动条有关的消息

    SB_TOP

    滚动到最顶部

    SB_BOTTOM

    滚动到最底部

    SB_RIGHT

    滚动到右边

    SB_LEFT

    滚动到左边

    SB_PAGEUP

    向上滚动一页

    SB_PAGEDOWN

    向下滚动一页

    SB_PAGELEFT

    向左滚动一页

    SB_PAGERIGHT

    向右滚动一页

    SB_LINEDOWN

    向下滚动一行

    SB_LINEUP

    向上滚动一行

    SB_LINELEFT

    向左滚动一行

    SB_LINERIGHT

    向右滚动一行

    SB_THUMBPOSITION

    滚动框移动到最新位置

    SB_THUMBTRACK

    滚动框被拖动

    SB_ENDSCROLL

    滚动到最终位置

    (3)可能用到的方法

    EnableScrollBar()

    使滚动条的一个或两个箭头有效或无效

    GetScrollInfo()

    获取滚动条的消息

    GetScrollLimit()

    获取滚动条的范围

    GetScrollPos()

    获取滚动条的当前位置

    GetScrollRange()

    获取滚动条的滚动范围

    SetScrollInfo()

    设置滚动条的消息

    SetScrollPos()

    设置滚动滑块的位置

    SetScrollRange()

    设置滚动条的滚动范围

    ShowScrollBar()

    显示或隐藏滚动条

    3.静态控件

    一般用在不发送消息也不接收消息的文本或图形上,但是也能想超文本链接那样响应用户的操作,这就要用到SS_NOTIFY样式向父窗口发送WM_COMMAND消息(记事本查看Visual C++ 2008编写的.rc文件可以发现这个问题)

    (1)创建方法

    Win32的做法或者在资源视图中通过拖拽添加

    (2)和该控件有关的消息

    STN_CLICKED

    单击静态控件

    STN_DBLCLK

    双击静态控件

    STN_ENABLE

    激活静态控件

    STN_DISABLE

    禁用静态控件

    (3)可能用到的函数

    ModifyStyle(0,SS_BITMAP);

    控件是位图风格

    SetBitmap();

    设置位图

    HBITMAP bBmp=LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(位图的ID));

    位图资源转换成HBITMAP

    GetObject(m_bmp.GetBitmap(),sizeof(BITMAP),&bmp);

    位图资源转换成BITMAP

    4.列表框

    CListBox可以展示像数组一样的数据,允许单选和多选、自带滚动条;

    (1)创建列表框

    BOOL Create(

    DWORD dwStyle,

    const Rect& rect,

    CWnd* pParentWnd,

    UINT nID);

    (2)和列表框有关的消息

    列表框向应用可能发送的消息

    LBN_SELCHANGE

    用户的选择发生了改变

    LBN_DBCLK

    双击

    LBN_SELCANCLE

    取消选择

    LBN_SETFOCUS

    获取输入焦点

    LBN_KILLFOCUS

    失去输入焦点

    应用向列表框可能发送的消息

    LB_ADDFILE

    在文件列表中插入指定文件

    LB_ADDSTRING

    加入项

    LB_DELETESTRING

    删除项

    LB_DIR

    在列表框中列出指定文件

    LB_FINDSTRING

    在列表框中查找指定项

    LB_GETCOUNT

    获取多选列表框中项的数目

    LB_GETCURSEL

    获取当前选中项的索引值

    LB_GETSEL

    获取指定项的选中状态

    LB_GETSELCOUNT

    获取多选列表框中选中的项数

    LB_GETTEXT

    获取指定项的文本

    LB_GETTEXTLEN

    获取指定项的文本的长度

    LB_GETTOPINDEX

    获取列表框中第一项的索引值

    LB_INSERTSTRING

    在指定位置加入项

    LB_RESETCONTENT

    清空所有项

    LB_SETSEL

    设置多选列表框中指定项的选中状态

    LB_SETCURSEL

    设置单选列表框中指定项的选中状态

    LB_SETTOPINDEX

    设置列表框中第一项的索引值

    (3)可能用到的函数

    获取当前目录中的所有条目

    //tchBuffer是长度为MAX_PAH的TCHAR类型数组

    GetCurrentDirectory(MAX_PATH,tchBuffer);

    //设置列表框的显示内容

    DlgDirList(tchBuffer,列表框的ID,用于显示路径的静态控件ID,0);

    通用方法

    GetHorizontalExtent()

    获取水平滚动的宽度

    SetHorizontalExtent()

    设置水平滚动的宽度

    GetItemData()

    获取与列表框项有关的32位数值

    SetItemData()

    设置与列表框项有关的32位数值

    GetItemDataPtr()

    获取某一项的指针

    SetItemDataPtr()

    设置某一项的指针

    GetItemHeight()

    获取某一项的高度

    SetItemHeight()

    设置某一项的高度

    GetItemRect()

    获取列表框的矩形

    GetLocale()

    获取列表框的位置局部标识LCID

    SetLocale()

    设置列表框的位置标识LCID

    GetSel()

    确定某一项的选择状态

    GetText()

    获取某一项的文本内容

    GetTextLen()

    返回列表框字符串的长度

    GetTopIndex()

    获取第一个项的下标,不一定为0

    GetCount()

    获取项的数目

    ItemFromPoint()

    获取和某点最近的某一项的下标

    SetColumnWidth()

    设置多列列表框的列宽度

    SetTabStops()

    设置列表框的制表位位置

    SetTopIndex()

    设置第一个可见项的下标

    单项选择

    GetCurSel()

    获取当前选择项的下标

    SetCurSel()

    设置当前选择项的下标

    多项选择

    GetAnchorIndex()

    获取当前定位项的下标

    SetAnchorIndex()

    扩充选择设置开始项(定位项)

    GetCaretIndex()

    获取具有光标矩形的项的下标

    SetCaretIndex()

    指定下标项设置光标矩形

    GetSelCount()

    获取当前所选项的数目

    GetSelItems()

    获取被选项的下标装入数组

    SelItemRange()

    切换项范围的选择状态

    SetSel()

    切换项的选择状态

    操作字符串

    AddString()

    向列表框中加入一个字符串

    DeleteString()

    向列表框中删除一个字符串

    Dir()

    从当前目录加文件名装入列表框

    FindString()

    搜索一字符串

    FindStringExact()

    搜索第一个符合的字符串

    InsertString()

    在指定下标处插入字符串

    ResetContent()

    清空所有项

    SelectString()

    在单选列表框中搜索并选择一字符串

    可以自定义的虚方法

    CharToItem()

    自绘制列表框处理WM_CHAR

    CompareItem()

    自绘制列表框项的比较方法

    DeleteItem()

    自绘制列表框删除一项

    DrawItem()

    自绘制列表框重绘时的方法

    MeasureItem()

    自绘制列表框创建时,MFC可以获取列表框的维数

    VKeyToItem()

    处理具有LBS_WANTKEYBOARDINPUT样式的WM_KEYDOWN消息

    5.编辑框

    可以是多行文本的矩形窗口,比如windows中的记事本;UpdateData()针对含有编辑框部分的代码更新

    (1)Cedit的样式

    资源视图中根据属性设置后,可以在.rc文件中找到这些样式

    ES_AUTOHSCROLL

    用户在末尾输入字符时,文本向右滚动

    ES_AUTOVSCROLL

    用户在末尾输入回车时,光标可以向下移动

    ES_CENTER

    文本居中

    ES_LEFT

    文本左对齐

    ES_LOWERCASE

    编辑框中的字符全部小写

    ES_MULTILINE

    指定是多行编辑框

    ES_NOHIDESEL

    失去输入焦点后依然选中文本

    ES_NUMBER

    Windows95上的编辑框中只能输入数字

    ES_OEMCONVERT

    字符类型转换

    ES_PASSWORD

    密码框的形式

    ES_READONLY

    只读

    ES_RIGHT

    文本右对齐

    ES_UPPERCASE

    编辑框中的字符全部大写

    ES_WANTRETURN

    多行编辑框可以回车换行

    (2)和编辑框有关的消息

    低字节是控件的标识,高字节是通知码

    编辑框向应用程序发送通知码

    EN_SETFOCUS

    获取输入焦点

    EN_KILLFOCUS

    失去输入焦点

    EN_CHANGE

    内容发生改变

    EN_UPDATE

    内容被更新

    EN_MAXTEXT

    用户输入已达到最大限度

    EN_HSCROLL

    内容水平滚动

    EN_VSCROLL

    内容垂直滚动

    应用程序向编辑框发送操作码

    EM_GETRECT

    获取矩形尺寸

    EM_SETRECT

    设置矩形尺寸

    EM_LINESCROLL

    设置滚动条的步长

    EM_SETHANDLE

    设置输入内容缓冲区句柄

    EM_GETHANDLE

    获取输入内容缓冲区句柄

    EM_LINELENGTH

    获取文本的长度

    EM_GETFONT

    获取编辑框使用的字体

    EM_GETLINECOUNT

    获取多行文本款的文本行数

    EM_REPLACESEL

    替换编辑框中选中的文本

    EM_SETPASSWORDCHAR

    设置密码编辑框中的替代字符

    EM_GETPASSWORDCHAR

    获取密码编辑框中的替代字符

    EM_SETREADONLY

    编辑框只读

    EM_GETSEL

    获取选中的字体

    EM_SETSEL

    设置选中的字体

    (3)可能用到的函数

    通用方法

    CanUndo()

    编辑操作是否可撤销

    Clear()

    删除当前的选择

    Copy()

    以CF_TEXT格式复制选择到剪切板中

    Cut()

    以CF_TEXT格式剪切选择到剪切板中

    EmptyUndoBuffer()

    消除一个编辑框控件的“撤销”标志

    GetFirstVisibleLine()

    确定编辑框控件中的最上面的可视行

    GetModify()

    确定一个编辑框控件的内容是否可修改

    GetPasswordChar()

    当用户输入文本时,编辑框控件中显示的密码字符

    GetRect()

    获取编辑框的矩形

    GetSel()

    获取当前选择的开始和结束字符的位置

    LimitText()

    限定用户文本输入的长度

    LineFromChar()

    获取包含指定字符下标的行的行号

    LineLength()

    获取编辑框控件中一行的长度

    LineScroll()

    滚动多行编辑框控件的文本

    Paste()

    将剪切板中的数据粘贴到光标位置

    ReplaceSel()

    用指定文本替换选中的部分

    SetModify()

    设置或清除编辑框控件的修改标志

    SetPasswordChar()

    当用户输入文本时设置或删除一个显示于编辑框控件中的密码字符

    SetReadOnly()

    只读

    SetSel()

    选择字符的范围

    Undo()

    取消最后一个编辑框控件的操作

    UpdateData()

    更新编辑框及其他控件

    多行编辑框支持的方法

    FmtLines()

    包含软分行符

    GetHandle()

    获取控件的句柄

    GetLine()

    获取一行文本

    GetLineCount()

    获取文本行的数目

    LineIndex()

    设置一行的字符下标

    SetHandle()

    设置多行文本框将要用到的句柄

    SetRect()

    设置多行文本框的矩形并更新控件

    SetRectNP()

    设置多行文本框的矩形,但是不重绘控件窗口

    SetTabStops()

    设置制表位tab

    6.组合框

    CComboBox是一种即可以输入又可以进行选择的控件,看起来像是编辑框和列表框的组合;资源视图上,一组单选按钮的ID值必须连续、第一个按钮选上Group,而且每一组只有第一个按钮能够创建变量

    (1)组合框的样式

    CBS_DROPDOWN

    由列表框和编辑框组成,列表框平时不可见

    CBS_DROPDOWNLIST

    由列表框和静态文本组成,列表框平时不可见

    CBS_AUTOHSCROLL

    编辑框自动水平滚动

    CBS_SORT

    列表框中各项按字母序排列

    CBS_SIMPLE

    列表框可见

    (2)和组合框有关的消息

    组合框向应用程序发送消息

    CBN_SELCHANGE

    列表框中的选中项发生改变

    CBN_DBLCLK

    双击

    CBN_SETFOCUS

    组合框获得焦点

    CBN_KILLFOCUS

    组合框失去焦点

    CBN_EDITCHANGE

    编辑框中的文本发生改变

    CBN_EDITUPDATE

    编辑框将显示修改过的文本

    CBN_DROPDOWN

    列表框将下拉

    CBN_CLOSEUP

    列表框将隐藏

    应用程序向组合框发送消息

    CB_SHOWDROPDWON

    显示下拉列表框

    CB_ADDSTRING

    添加新项

    CB_DELETESTRING

    删除一项

    CB_INSERTSTRING

    插入新项

    CB_FINDSTRING

    查询列表项

    CB_RESETCONTENT

    清空列表框

    CB_DIR

    在列表框中显示指定目录及文件

    CB_SETCURSEL

    设置列表框中选中项的索引值,并在编辑框中显示

    CB_GETCURSEL

    获取列表框中选中项的索引值

    CB_GETCOUNT

    获取列表框中项的数目

    CB_GETLBTEXT

    获取列边框中指定项的文本

    CB_GETLBTEXTLEN

    获取列边框中指定项的文本长度

    CB_LIMITEXT

    限制编辑框中的字符串长度

    CB_GETEDITSEL

    获取编辑框中的选择

    CB_SETEDITSEL

    设置编辑框中的选择

    (3)可能用到的函数

    Clear()

    删除当前选项,清空编辑框中的内容

    Copy()

    以CF_TEXT格式将选中内容复制到粘贴板

    Cut()

    以CF_TEXT格式将选中内容剪切到粘贴板

    GetComboBoxInfo()

    返回CCombox对象的信息

    GetCount()

    获取列表框项的数目

    GetCurSel()

    返回所选列表框条目的顺序号

    GetEditSel()

    返回DWORD数据,低字节是编辑框中选中文字的开始位置,高字节是结束位置

    GetItemHeight()

    返回组合框中表示列表条目数

    GetLBText()

    返回组合框的列表中指定条目的字符串

    GetLBTextLen()

    返回组合框的列表中指定条目的字符串的长度

    Paste()

    将粘贴板的内容复制到编辑框

    SetCurSel()

    选中组合框的指定条目

    SetMinVisibleItems()

    设置下拉列表中可见条目数

    SetTopIndex()

    指定下拉列表的第一个可见条目

    AddString()

    在列表条目中添加一字符串

    DeleteString()

    从列表项中删除一字符串条目

    FindString()

    查找第一个和指定字符串匹配的字符串序号

    InsertString()

    将一字符串插入到指定位置

    ResetString()

    清空组合空中的所有内容

    SelectString()

    从列表中查找指定字符串,如果找到将其放到编辑框中

    用CTime类获取本地时间

    CTime tNow =CTime::GetCurrentTime();

    CString sNow=tNow.Format("%y/%m/%d");

    获取对话框中的某个对象

    GetDlgItem();

    //使对象有效或无效,选择TRUE、FALSE

    EnableWindow();

    //是对象显示或隐藏,选择SW_SHOW、SW_HIDE

    ShowWindow();

    _tcscpy()、_tcscat()、_tcslen()

    单选按钮组的状态

    //初始化按钮组的状态

    CheckedRadioButton(开始的ID,结束的ID,选中的ID);

    //获取单选按钮组的选择状态,得到的值和各单选按钮的ID进行比较即可

    iAgeRadio=GetCheckedRadioButton(IDC_AGE1_RADIO, IDC_AGE3_RADIO);

    7.对话框通用控件

    (1)Picture

    分隔线

    Color属性选择Etched

    图片

    Type选择Icon或者Bitmap,设置Image属性为对应资源的ID时可以显示图片

    (2)Spin

    需要和其他控件组合使用,比如Edit控件;Spin适合在一个范围内选择精确值

    设置Edit控件只读,Spin控件的Allignment选择Right Align、Auto buddy为TRUE

    初始化

    CSpinButtonCtrl* pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);

    pSpin->SetRange(0,100);

    pSpin->SetPos(50);

    pSpin->GetBuddy()->SetWindowTextW(L"5.0");

    事件响应

    //响应对话框的VM_VSCROLL消息

    if(pScrollBar->GetDlgCtrlID()==IDC_SPIN1)

    {

    CString strValue;

    //Spin上下移动变化只是1,除以10.0表示这个步长是0.1

    strValue.Format(L"%3.1f",nPos/10.0);

    ((CSpinButtonCtrl*)pScrollBar)->GetBuddy()->SetWindowTextW(strValue);

    }

    (3)Progress

    进度条

    初始化

    CProgressCtrl* pProg=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);

    pProg->SetRange(0,100);

    pProg->SetPos(50);

    启动进度条

    //比如某个按钮按下

    CProgressCtrl* pProg=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);

    pProg->SetPos(0);

    SetTimer(2008,100,NULL);

    事件响应

    //响应对话框的VM_TIMER消息

    if(nIDEvent==2008)

    {

    CProgressCtrl* pProg=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);

    pProg->SetPos(pProg->GetPos()+1);

    if(pProg->GetPos()>=100)

    {

    KillTimer(nIDEvent);

    AfxMessageBox(L"进行完毕");

    }

    }

    (4)Slider

    滑块比较方便在一个范围内选择大致的数值

    初始化

    CString strText1;

    CSliderCtrl* pSlider1=(CSliderCtrl*)GetDlgItem(IDC_SLIDER1);

    pSlider1->SetRange(0,100);

    pSlider1->SetPos(50);

    strText1.Format(L"%d",pSlider1->GetPos());

    SetDlgItemText(IDC_STATIC_SLIDER,strText1);

    事件响应

    //响应对话框的WM_HSCROLL消息

    if(pScrollBar->GetDlgCtrlID()==IDC_SLIDER1)

    {

    CSliderCtrl* pSlide=(CSliderCtrl*)pScrollBar;

    CString strText;

    strText.Format(L"%d",pSlide->GetPos());

    SetDlgItemText(IDC_STATIC_SLIDER,strText);

    }

    (5)Date Time Picker

    用户对时间的输入形式是多样的,这就导致了时间不好解析的问题,这时候选择Date Time Picker是很有意义的

    初始化

    CDateTimeCtrl* pDT=(CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER1);

    CString str=_T("'今天是:'yyyy'/'MM'/'dd");

    pDT->SetFormat(str);

    对日期时间的解析

    CDateTimeCtrl* pDT=(CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER1);

    CTime t;

    pDT->GetTime(t);

    CString str=t.Format(L"%Y/%m/%d %A %H:%M:%S");

    AfxMessageBox(str);

    (6)List Control

    类似文件管理器的文件列表;回调项可能会节省程序的存储空间

    CListCtrl可能用到的函数

    Create()

    创建列表控件

    SetBkColor()

    设置背景颜色

    SetImageList()

    设置图像列表

    SetItem()

    设置列表项数据

    GetItemRect()

    获取列表项的矩形

    GetEditControl()

    获取正在编辑的列表项的Edit控件

    SetTextColor()

    设置文本颜色

    SetTextBkColor()

    设置文本背景颜色

    SetItemText()

    设置列表项的标签文字

    GetHotItem()

    获取鼠标指向的列表项

    GetSelectionMark()

    获取当前选中的列表项

    SubItemHitTest()

    获取指定点下的列表项

    SetBkImage()

    设置背景图片

    InsertItem()

    插入列表项

    EditLabel()

    启动显示编辑标签文字

    CreateDragImage()

    创建用于拖放的图片

    列表控件的风格

    图标:每项显示32*32图标,图标下面显示标签,可以拖动到视图内任意位置;小图标:每项显示16*16图标,图标右边显示标签,可以拖动到视图内任意位置;列表:每项显示16*16图标、按列排列,图标右边显示标签,不能任意拖动图标;报表:每项占一行,第一列显示16*16的图标,图标右边显示标签,再右边的列显示子项由具体程序决定

    Windows控件风格

     

    hover selection

    鼠标在某一项上停留一定时间就自动选择该项

    虚拟列表视图

    可以使用DWORD类型的项,是管理数据交给具体程序,控件只负责焦点和选择功能

    单击和双击激活

    允许热点跟踪、单击和双击激活高亮选项

    拖放列排序

    在报表中允许通过拖放重新排序各项的顺序

    列表控件支持的四种图片类型

    大图标

    图标风格的时候使用

    小图标

    小图标、列表、报表风格使用

    应用程序状态

    用于在图标旁边显示应用程序状体的图片

    标题栏项

    在报表风格中用于标题栏的显示

    设置Edit Labels为TRUE,View的属性为Small Icon,在对话框类中添加变量CImageList m_imageList;

    初始化

    HICON hIcon[8];

    int n;

    m_imageList.Create(16,16,0,8,8);

    hIcon[0]=AfxGetApp()->LoadIcon(IDI_ICON_WHITE);

    hIcon[1]=AfxGetApp()->LoadIcon(IDI_ICON_BLACK);

    hIcon[2]=AfxGetApp()->LoadIcon(IDI_ICON_RED);

    hIcon[3]=AfxGetApp()->LoadIcon(IDI_ICON_BLUE);

    hIcon[4]=AfxGetApp()->LoadIcon(IDI_ICON_YELLOW);

    hIcon[5]=AfxGetApp()->LoadIcon(IDI_ICON_CYAN);

    hIcon[6]=AfxGetApp()->LoadIcon(IDI_ICON_PURPLE);

    hIcon[7]=AfxGetApp()->LoadIcon(IDI_ICON_GREEN);

    for(n=0;n<8;++n)

    m_imageList.Add(hIcon[n]);

    //创建标签资源

    static TCHAR* color[]={L"white",L"black",L"red",L"blue",L"yellow",L"cyan",L"purple",L"green"};

    //创建控件

    CListCtrl* pList=(CListCtrl*)GetDlgItem(IDC_LIST1);

    pList->SetImageList(&m_imageList,LVSIL_SMALL);

    for(n=0;n<8;++n)

    pList->InsertItem(n,color[n],n);

    pList->SetBkColor(RGB(0,255,255));

    pList->SetTextBkColor(RGB(255,0,255));

    在列表LVN_ITEMCHANGED消息中添加代码,获取选中的内容

    CListCtrl* pList=(CListCtrl*)GetDlgItem(IDC_LIST1);

    int nSelected=pNMLV->iItem;

    if(nSelected>=0)

    {

    CString strItem=pList->GetItemText(nSelected,0);

    SetDlgItemText(IDC_STATIC_LIST,strItem);

    }

    在列表NM_RCLICK消息中添加代码,编辑右键选中的内容

    //LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE>(pNMHDR);

    // TODO: 在此添加控件通知处理程序代码

    NM_LISTVIEW* pNMListView=(NM_LISTVIEW*)pNMHDR;

    CListCtrl* pList=(CListCtrl*)GetDlgItem(IDC_LIST1);

    int nSelected=pNMListView->iItem;

    if(nSelected>=0)

    pList->EditLabel(nSelected);

    在列表LVN_ENDLABELEDIT消息中添加代码,更新列表的编辑结果

    LVITEM item=pDispInfo->item;

    CString str=item.pszText;

    str.TrimLeft();

    str.TrimRight();

    if(str.GetLength()>0)

    {

    CListCtrl* pList=(CListCtrl*)GetDlgItem(IDC_LIST1);

    pList->SetItemText(item.iItem,item.iSubItem,item.pszText);

    }

    (7)Tree Control

    CTreeCtrl可能用到的函数

    Create()

    创建树控件

    GetCount()

    获取结点的数目

    SetIndent()

    设置每层缩进距离

    SetIamgeList()

    设置图片列表

    GetNextItem()

    获取指定结点指定方式下的下一个节点

    InsertItem()

    插入节点

    GetChildItem()

    获取子节点

    GetNextSiblingItem()

    获取下一个兄弟节点

    GetPrevSiblingItem()

    获取上一个兄弟节点

    GetParentItem()

    获取父节点

    GetSelectedItem()

    获取选中的节点

    GetDropHilightItem()

    获取当前释放目标节点

    GetRootItem()

    获取根节点

    GetItem()

    获取指定结点的信息

    GetEditControl()

    获取编辑框控件

    SetBkColor()

    设置背景颜色

    ItemHasChildren()

    判断是否有子节点

    DeleteItem()

    删除节点

    DeleteAllItems()

    删除所有节点

    Expand()

    打开或折叠节点

    CreateDragImage()

    创建用于拖放的图片

    SortChildren()

    将某节点下的子节点排序

    设置Has Buttons为TRUE、这样每个展开项之前就有“+”“-”按钮,设置Has Lines为TRUE、这样每个展开项之前就有虚线连接,设置Lines At Root为TRUE、这样第一层节点之间也有虚线连接,设置Edit Labels为TRUE、是标签可编辑

    VERIFY()是个类似assert()的东西

    初始化

    HICON hIcon[8];

    int n;

    m_imageList.Create(16,16,0,8,8);

    //图标icon资源需要提前制作

    hIcon[0]=AfxGetApp()->LoadIcon(IDI_ICON_WHITE);

    hIcon[1]=AfxGetApp()->LoadIcon(IDI_ICON_BLACK);

    hIcon[2]=AfxGetApp()->LoadIcon(IDI_ICON_RED);

    hIcon[3]=AfxGetApp()->LoadIcon(IDI_ICON_BLUE);

    hIcon[4]=AfxGetApp()->LoadIcon(IDI_ICON_YELLOW);

    hIcon[5]=AfxGetApp()->LoadIcon(IDI_ICON_CYAN);

    hIcon[6]=AfxGetApp()->LoadIcon(IDI_ICON_PURPLE);

    hIcon[7]=AfxGetApp()->LoadIcon(IDI_ICON_GREEN);

    for(n=0;n<8;++n)

    m_imageList.Add(hIcon[n]);

    CTreeCtrl* pTree=(CTreeCtrl*)GetDlgItem(IDC_TREE1);

    //包含有图片的形式

    pTree->SetImageList(&m_imageList,TVSIL_NORMAL);

    //建树的一种结构

    TV_INSERTSTRUCT tvinsert;

    //没有父节点

    tvinsert.hParent=NULL;

    //插入到本层最后

    tvinsert.hInsertAfter=TVI_LAST;

    //掩码:图标、选中图标、文字

    tvinsert.item.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;

    tvinsert.item.hItem=NULL;

    tvinsert.item.state=0;

    tvinsert.item.stateMask=0;

    //文字的最大长度,编译器忽略该参数、但是写程序的人可以获取到

    tvinsert.item.cchTextMax=6;

    //选中的时候是黑色

    tvinsert.item.iSelectedImage=1;

    tvinsert.item.cChildren=0;

    tvinsert.item.lParam=0;

    //创建第一层

    tvinsert.item.iImage=1;

    tvinsert.item.pszText=L"father";

    HTREEITEM hDad=pTree->InsertItem(&tvinsert);

    tvinsert.item.iImage=2;

    tvinsert.item.pszText=L"mother";

    //表示还有子节点

    HTREEITEM hMom=pTree->InsertItem(&tvinsert);

    //创建第二层

    tvinsert.hParent=hDad;

    tvinsert.item.iImage=3;

    tvinsert.item.pszText=L"son";

    //下面没有子节点

    pTree->InsertItem(&tvinsert);

    tvinsert.item.pszText=L"daughter";

    pTree->InsertItem(&tvinsert);

    tvinsert.hParent=hMom;

    tvinsert.item.iImage=4;

    tvinsert.item.pszText=L"son";

    pTree->InsertItem(&tvinsert);

    tvinsert.item.pszText=L"daughter";

    pTree->InsertItem(&tvinsert);

    tvinsert.item.pszText=L"cartoon";

    HTREEITEM hOther=pTree->InsertItem(&tvinsert);

    //创建第三层

    tvinsert.hParent=hOther;

    tvinsert.item.iImage=7;

    tvinsert.item.pszText=L"Tom";

    pTree->InsertItem(&tvinsert);

    tvinsert.item.pszText=L"Jerry";

    pTree->InsertItem(&tvinsert);

    在树控件的TVN_SELCHANGED消息中添加代码,实现获取选中的内容

    CTreeCtrl* pTree=(CTreeCtrl*)GetDlgItem(IDC_TREE1);

    HTREEITEM hSelected=pNMTreeView->itemNew.hItem;

    if(hSelected!=NULL)

    {

    //总长是9个字符,包括最后的''

    TCHAR text[9];

    TV_ITEM item;

    item.mask=TVIF_HANDLE|TVIF_TEXT;

    item.hItem=hSelected;

    item.pszText=text;

    item.cchTextMax=8;

    VERIFY(pTree->GetItem(&item));

    SetDlgItemText(IDC_STATIC_TREE,item.pszText);

    }

    在树控件的TVN_ENDLABELEDIT消息中添加代码,三击实现编辑选中的内容

    TVITEM item=pTVDispInfo->item;

    CString str=item.pszText;

    //换成Trim()、中间输入些空格到底行不行?

    str.TrimLeft();

    str.TrimRight();

    if(str.GetLength()>0)

    {

    CTreeCtrl* pTree=(CTreeCtrl*)GetDlgItem(IDC_TREE1);

    pTree->SetItemText(item.hItem,item.pszText);

    }

    (8)Extended Combo Box

    扩展出来的组合框,实现列表项图标和标签的组合显示

    CComboBoxEx可能用到的函数

    Create()

    创建扩展组合框控件

    DeleteItem()

    删除一项

    GetItem()

    获取指定项信息

    InsertItem()

    插入一项

    SetImageList()

    设置图片列表

    GetEditCtrl()

    获取其中的Edit控件

    GetComboBoxCtrl()

    获取其中的组合框控件

    初始化

    HICON hIcon[8];

    int n;

    //这是对话框添加的CImageList变量

    m_imageList.Create(16,16,0,8,8);

    //图标icon资源需要提前制作

    hIcon[0]=AfxGetApp()->LoadIcon(IDI_ICON_WHITE);

    hIcon[1]=AfxGetApp()->LoadIcon(IDI_ICON_BLACK);

    hIcon[2]=AfxGetApp()->LoadIcon(IDI_ICON_RED);

    hIcon[3]=AfxGetApp()->LoadIcon(IDI_ICON_BLUE);

    hIcon[4]=AfxGetApp()->LoadIcon(IDI_ICON_YELLOW);

    hIcon[5]=AfxGetApp()->LoadIcon(IDI_ICON_CYAN);

    hIcon[6]=AfxGetApp()->LoadIcon(IDI_ICON_PURPLE);

    hIcon[7]=AfxGetApp()->LoadIcon(IDI_ICON_GREEN);

    for(n=0;n<8;++n)

    m_imageList.Add(hIcon[n]);

    static TCHAR* color[]={L"white",L"black",L"red",L"blue",L"yellow",L"cyan",L"purple",L"green"};

    CComboBoxEx* pComboEx=(CComboBoxEx*)GetDlgItem(IDC_COMBOBOXEX1);

    pComboEx->SetImageList(&m_imageList);

    COMBOBOXEXITEM comboItem;

    //和下面的操作有关

    comboItem.mask=CBEIF_IMAGE|CBEIF_INDENT|CBEIF_SELECTEDIMAGE|CBEIF_TEXT;

    for(n=0;n<3;++n)

    {

    //该项的索引

    comboItem.iItem=n;

    //项的图标

    comboItem.iImage=n;

    //选中时候的图标

    comboItem.iSelectedImage=n;

    //缩进

    comboItem.iIndent=n;

    comboItem.pszText=color[n];

    pComboEx->InsertItem(&comboItem);

    }

    三、资源

    资源和代码是独立的,资源可以是某个.dll、.exe等二进制文件;另存为.res资源文件,在需要的时候可以导入

    1.菜单

    (1)程序主菜单

    出现在界面的最上方,不可以拖动和删除;在View的构造函数和OnDraw函数中填写代码

    ①菜单编辑器中的属性

    Seperator

    分割线

    Popup

    弹出式窗口

    Enabled

    已激活

    Checked

    被选中

    Grayed

    被禁用

    Prompt

    提示信息

    ②COMMAND消息

    用户点击菜单项的时候会产生该消息

    ③UPDATE_COMMAND_UI消息

    窗口刷新菜单项的时候产生该消息,会用到CCmdUI对象

    Enable()

    禁止或启动该菜单项

    SetCheck()

    菜单项或工具条前面是否有√

    SetRadio()

    菜单项或工具条前面是否有·

    SetText()

    设置菜单项的显示文字

    ④ON_COMMAND_RANGE消息

    也可以用COMMAND消息一个一个的对菜单项添加代码,但是如果菜单项的ID是连续的话,用ON_COMMAND_RANGE会方便很多;引导程序不支持该消息的自动映射、需要动手写代码完成

    a.在View的头文件中填写代码

    afx_msg void OnOperColorChange(UINT nID);

    b.在View的源文件中填写代码

    BEGIN_MESSAGE_MAP(CMy0View, CView)

    ON_COMMAND_RANGE(ID_OPER_RED,ID_OPER_BLUE,OnOperColorChange)

    END_MESSAGE_MAP()

    void CMy0View::OnOperColorChange(UINT nID)

    {

    m_nColorIndex=nID-ID_OPER_RED;

    //强制刷新,会重新调用OnDraw函数

    Invalidate();

    }

    ⑤UPDATE_COMMAND_UI_RANGE消息

    对ID连续的菜单项进行更新;引导程序不支持该消息的自动映射、也是需要动手写代码完成

    a.在View的头文件中填写代码

    afx_msg void OnUpdateOperColorChange(CCmdUI* pCmdUI);

    b.在View的源文件中填写代码

    BEGIN_MESSAGE_MAP(CMy0View, CView)

    ON_UPDATE_COMMAND_UI_RANGE(ID_OPER_RED,ID_OPER_BLUE,OnUpdateOperColorChange)

    END_MESSAGE_MAP()

    void CMy0View::OnUpdateOperColorChange(CCmdUI* pCmdUI)

    {

    //pCmdUI和之前声明的起始ID、终止ID有关,事件触发的时候将刷新菜单项

    pCmdUI->SetRadio(m_nColorIndex==(pCmdUI->m_nID-ID_OPER_RED));

    }

    (2)快捷菜单

    程序主菜单中已经有其中的菜单项,为了方便右键时出现的一组菜单

    ①CMenu类可能会用到的方法

    构造方法

    Attach()

    把一个菜单句柄附加到CMenu对象上

    CreateMenu()

    创建一个空菜单并附加到CMenu对象上

    CreatePopupMenu()

    创建一个弹出式菜单并附加到CMenu对象上

    DeleteTempMap()

    删除由FromHandle()创建的任何临时CMenu对象

    DestroyMenu()

    销毁CMenu对象及其下面的菜单

    Deatch()

    从CMenu对象上拆出一个菜单句柄并返回

    FromHandle()

    给定菜单句柄时,返回CMenu对象的指针

    GetSafeHmenu()

    返回由CMenu对象封装的菜单句柄成员

    LoadMenu()

    从可执行文件中加载菜单资源并附加到CMenu对象上

    LoadMenuIndirect()

    从内存中加载菜单资源并附加到CMenu对象上

    操作菜单

    DeleteMenu()

    删除某个特定菜单中的菜单项

    TrackPopupMenu()

    在一个POINT对象指定的地方显示快捷菜单

    操作菜单项

    AppendMenu()

    将新项加到指定的菜单项后面

    CheckMenuItem()

    弹出式菜单中,菜单项的校验标记或取消下一项的校验标记

    CheckMenuRadioItem()

    把一个单选按钮放到菜单项旁边或取消一个已存在的单选按钮

    EnableMenuItem()

    激活/禁用一个菜单项

    GetMenuItemCount()

    获取菜单项的数目

    GetMenuItemID()

    获取指定位置的菜单项的标识符

    GetMenuState()

    获取指定菜单项的状态

    GetMenuString()

    获取指定菜单项的标记

    GetSubMenu()

    获取指向弹出式才当的指针

    InsertMenu()

    在指定位置插入新的菜单项

    ModifyMenu()

    修改指定位置的菜单项

    RemoveMenu()

    从指定菜单中删除与弹出式菜单结合的菜单项

    ②在资源视图中插入新菜单IDR_MENU_POPUP

    ③在View的头文件中添加新变量

    //快捷菜单

    CMenu m_PopMenu;

    //快捷菜单的子菜单

    CMenu* m_pPop;

    ④在View的源文件中添加代码

    CMy0View::CMy0View()

    {

    //加载菜单资源

    m_PopMenu.LoadMenu(IDR_MENU_POPUP);

    }

    CMy0View::~CMy0View()

    {

    //销毁菜单资源

    m_PopMenu.DestroyMenu();

    }

    ⑤在View的类视图、类的属性面板中选择WM_RBUTTON消息添加处理函数,填写右键后要处理的代码

    void CMy0View::OnRButtonDown(UINT nFlags, CPoint point)

    {

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    m_pPop=m_PopMenu.GetSubMenu(0);

    UINT nCheck=m_bShow?MF_CHECKED:MF_UNCHECKED;

    m_pPop->CheckMenuItem(ID_OPER_SHOW,MF_BYCOMMAND|nCheck);

    m_pPop->CheckMenuRadioItem(ID_OPER_RED,ID_OPER_BLUE,ID_OPER_RED+m_nColorIndex,MF_BYCOMMAND);

    ClientToScreen(&point);

    m_pPop->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this);

    CView::OnRButtonDown(nFlags, point);

    }

    (3)工具栏菜单

    程序主菜单中也有这些菜单项,通常出现在程序主菜单下方、由一组类似按钮的图标组成,可以拖动和关闭

    ①CToolBar可能用到的方法

    构造方法

    Create()

    创建工具条并附加到CToolBar对象上

    CreateEx()

    创建定义了边界的工具条并附加到CToolBar对象上

    SetSizes()

    设置按钮及位图大小

    SetHeight()

    设置工具条的高度

    LoadToolBar()

    加载工具条资源

    LoadBitmap()

    加载包含工具条按钮图像的位图

    SetBitmap()

    设置位图图像

    SetButtons()

    设置按钮并使每个按钮与位图图像相关

    操作工具条按钮

    CommandToIndex()

    返回给定命令的工具条按钮索引

    GetItemID()

    返回指定索引的按钮或分隔符的ID

    GetItemRect()

    返回指定索引的按钮矩形

    GetButtonStyle()

    获取按钮的风格

    SetButtonStyle()

    设置按钮的风格

    GetButtonInfo()

    获取按钮的ID、风格、图像号

    SetButtonInfo()

    设置按钮的ID、风格、图像号

    GetButtonText()

    获取按钮上的文本内容

    SetButtonText()

    设置按钮上的文本内容

    ②CToolBarCtrl也用于操作工具条,CToolBarCtrl可能用到的方法

    CToolBarCtrl()

    构造函数

    Create()

    创建工具条,这里与具体的工具条资源绑定

    GetState()

    获取指定按钮的信息,比如被按下、被禁止等

    HitTest()

    测试一点是否位于某按钮内

    AddButtons()

    添加按钮

    InsertButton()

    插入按钮

    AddStrings()

    添加按钮文字

    ③进入资源视图插入Toolbar

    ④在CMainFrame的头文件中添加工具条对象

    protected:

    //如果已经有这个对象,还想建立新工具条的话需要另外创建CToolBar对象

    CToolBar m_wndToolBar;

    ⑤在CMainFrame的源文件中编写代码,完成对工具条的加载

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

    {

    if(!m_wndToolBar.Create(this,WS_VISIBLE|CBRS_TOP)||!m_wndToolBar.LoadToolBar(IDR_TOOLBAR))

    {

    TRACE0("Fail to create toolbar.");

    return -1;

    }

    ` …

    }

    ⑥可以动态的改变工具条的风格

    //使窗口可以移动到用户区的任意位置

    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

    EnableDocking(CBRS_ALIGN_ANY);

    DockControlBar(&m_wndToolBar);

    //改变工具条的风格:Toolbar属性面板中prompt的 前面的内容显示在状态栏、后面的内容表示鼠标经过时提示的内容

    m_wndToolBar.SetBarStyle(CBRS_TOOLTIPS| CBRS_FLYBY| CBRS_SIZE_DYNAMIC);

    //使工具条显示或隐藏

    ShowControlBar(&m_wndToolBar,TRUE,FALSE);

    ⑦多列工具栏菜单

    if(!m_wndToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_FLOAT_MULTI|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

    {

    TRACE0("Failed to create toolbar");

    return -1; // fail to create

    }

    m_wndToolBar.SetWindowText(_T("标准工具栏"));

    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

    EnableDocking(CBRS_ALIGN_ANY);

    DockControlBar(&m_wndToolBar);

    if(!m_wndExtendBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_FLOAT_MULTI|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||!m_wndExtendBar.LoadToolBar(IDR_TOOLBAR))

    {

    TRACE0("Failed to create extend toolbar");

    return -1;

    }

    m_wndExtendBar.SetWindowText(_T("扩展工具栏"));

    m_wndExtendBar.EnableDocking(CBRS_ALIGN_ANY);

    CRect rect;

    m_wndExtendBar.GetWindowRect(&rect);

    rect.OffsetRect(1,0);

    this->RecalcLayout(); //关键的一步,重新排列

    DockControlBar(&m_wndExtendBar, AFX_IDW_DOCKBAR_TOP, &rect);

    ⑧多行工具栏菜单

    //默认工具栏已经加载

    if(!m_wndToolBarNew.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||

    !m_wndToolBarNew.LoadToolBar(IDR_TOOLBAR))

    {

    TRACE0("Fail to create toolbar.");

    return -1;

    }

    2.加速键

    进入资源视图的文件,双击最后一行、设置与该加速键关联的ID、在属性面板中设置加速键,编译执行

    3.字符串

    使用字符串资源并在需要的时候动态切换,可以设计出跨语言的程序;进入资源视图、打开String Table,双击最下面的空白一行、填写表示该字符串的ID值、填写字符串的内容,编译执行;CTring类.LoadString(字符串的ID值);可以加载需要的字符串资源,CString对象可以直接转换成LPCTSTR而且支持格式化.Format(L“”,…);

    //获取字符串的矩形

    CSize sizeText=pDC->GetTextExtent(str);

    //CString转换为string

    CString str = _T("CSDN");

    std::string s = (CT2A)str;

    //字符串输出

    pDC->SetBkColor(RGB(255,0,0));

    pDC->SetTextColor(RGB(0,255,0));

    CFont a;

    a.CreateFont(

    //高度和宽度

    30,0,

    //文本的倾斜度

    0,

    0,FW_NORMAL,

    //斜体、下划线、删除线

    0,0,0,

    GB2312_CHARSET,OUT_DEFAULT_PRECIS,

    CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,

    //字体名称

    L"华文行楷");

    pDC->SelectObject(a);

    HDC hdc=pDC->GetSafeHdc();

    CString str=L"无边落木萧萧下";

    TextOut(hdc,0,80,str,_tcslen(str));

    a.DeleteObject();

    4.对话框

    DDX:对话框数据交换,MFC将控件和数据建立一种绑定关系;重写OnInitDialog()函数可以初始化对话框中组件的状态;改变对话框的位置csDlg->SetWindowPos(NULL,20,10,0,0,SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);;AfxGetMainWnd()->PostMessage(WM_QUIT,0,0);或者使用Dialog::OnOk();都可以退出一个对话窗口

    (1)CDialog可能用到的函数

    Create()

    创建一个对话框,通常用于非模态对话框的创建

    Domodal()

    显示模态对话框

    EndDialog()

    关闭模态对话框

    GetDlgItem()

    获取对话框上的某个控件指针

    OnInitDialog()

    初始化对话框

    OnOk()

    OK按钮被点击,可以重载这个函数

    OnCancel()

    Cancel按钮被点击,可以重载这个函数

    (2)在资源视图中插入新的Dialog,编辑需要的控件
    (3)为这个对话框建立关联的类
    (4)在对话框类中为需要的控件添加需要的数据变量
    (5)在需要的源文件中使用这个对话框类

    //一个ID为ID_OPER_STRING的菜单项,它的COMMAND消息响应函数OnOperString调用了这个对话框类

    //也就是点击这个菜单项的时候会出现这个对话框

    #include "InputDlg.h"

    void CMy0View::OnOperString()

    {

    // TODO: 在此添加命令处理程序代码

    InputDlg dlgInput;

    //这是模态对话框

    if(dlgInput.DoModal()==IDOK)

    {

    m_strShow=dlgInput.m_strInput;

    Invalidate();

    }

    //这是非模态对话框,现在只能用来显示一些消息并不能进行交互

    //InputDlg *dlg = new InputDlg;

    //dlg->Create(IDD_DIALOG_NEW);

    //dlg->ShowWindow(SW_SHOWNORMAL);

    }

    5.图标

    可以在资源视图Icon中可以编辑图标,通常使用的是32*32、16*16的24位图标;也可以添加自己想要的图标,如果把ID值替换成IDR_MAINFRAME,就可以改变应用程序的图标

    6.位图

    (1)在资源视图中导入.bmp视图并命名ID

    (2)在View的OnDraw()中载入位图

    //获取窗口的绝对位置,GetClientRect()获取相对位置

    CRect rect;

    GetWindowRect(&rect);

    CDC dcMemory;

    dcMemory.CreateCompatibleDC(pDC);

    CBitmap bmp1;

    bmp1.LoadBitmapW(IDB_BITMAP_24bi);

    BITMAP bmpInfo1;

    bmp1.GetBitmap(&bmpInfo1);

    CBitmap* pOldBitmap=dcMemory.SelectObject(&bmp1);

    //pDC->BitBlt(0,0,bmpInfo1.bmWidth,bmpInfo1.bmHeight,&dcMemory,0,0,SRCCOPY);

    pDC->StretchBlt(0,0,rect.right-rect.left,rect.bottom-rect.top,&dcMemory,0,0,bmpInfo1.bmWidth,bmpInfo1.bmHeight,SRCCOPY);

    dcMemory.SelectObject(pOldBitmap);

    四、单文档SDI和多文档MDI界面

    SDI只能打开一个类型的一个文档,MDI每次能打开多个类型的多个文档、MDI至少拥有两个主菜单

    1.可能用到的概念

    和CArchive有关的序列化处理,对象读写字节流的方式还方便了网络、串口传输数据

    m_pDocument

    使用该档案的文档

    Abort()

    在不发送异常的情况下关闭档案

    Close()

    关闭档案

    Flush()

    将缓冲中的数据强制写入流

    operator<<

    将基本类型写入流

    operator>>

    从流中读出基本类型

    Read()

    读取字节内容

    Write()

    写入字节内容

    ReadString()

    读取字符串

    WriteClass()

    写入类信息

    WriteString()

    写入字符串

    GetFile()

    获取底层的CFile对象

    GetObjectSchema()

    读取对象版本号

    SetObjectSchema()

    设置对象版本号

    IsLoading()

    是否处于读取状态

    IsStoring()

    是否处于保存状态

    ReadObject()

    读取序列化对象

    WriteObject()

    写入序列化对象

    ReadClass()

    读取类信息

    和文件打开保存有关的虚函数,可以重载实现对这个过程的具体控制

    文档类完整的工作是:显示获取文件名对话框,选择匹配的文件模板,创建关联的框架、文档、视图,打开文件,将文件和档案绑定,调用Serialize

    CWinApp::OnFileOpen()

    可以完成整个过程

    CWinApp::OpenDocumentFile()

    MFC帮你获取文件名

    CDocTemplate::OpenDocumentFile()

    MFC帮你获取文件名并选择一个模板

    CDocument::OnOpenDocument()

    MFC获取文件名,选择好模板,创建好关联的框架、文档、视图

    CDocument::Serialize()

    完成序列化即可

    CDocument::OnFileSave()/OnFileSaveAs()

    可以完成整个过程

    CDocument::OnSaveDocument()

    MFC帮你获取文件名

    2.消息映射

    本质是数组,数组中存储了消息传递时的关键信息;某种类型的消息会按照某种顺序从一个对象传递到另一个对象,直到该消息被处理,消息被处理后就不会再传递到后面的对象;这个优先级顺序一般是:文档对象>文档模板>框架窗口>应用程序对象;在BEGIN_MSG_MAP和END_MSG_MAP之间的用宏的方式进行声明

    宏/参数

    描述

    ON_COMMAND

    ID

    Func

    处理WM_COMMAND消息

    发出消息的控件的ID

    void func();

    ON_COMMAND_RANGE

    IDFirst

    IDLast

    func

    处理ID连续的WM_COMMAND消息

    起始控件的ID

    终止控件的ID

    void func(WORD id);

    ON_UPDATE_COMMAND_UI

    ID

    func

    处理MFC请求更新界面状态

    控件ID

    void func(CCmdUI* pCmdUI);

    ON_UPDATE_COMMAND_UI_RANGE

    IDFirst

    IDLast

    func

    处理ID连续的界面更新

    起始控件的ID

    终止控件的ID

    void func(CCmdUI* pCmdUI);

    ON_NOTIFY

    Code

    ID

    func

    处理来自新风格控件的WM_NOTIFY消息

    消息码

    控件ID

    void func(NMHDR* pNotifyStruct,LRESULT* result);

    ON_NOTIFY_RANGE

    Code

    IDFirst

    IDLast

    func

    处理ID连续的WM_NOTIFY消息

    消息码

    起始控件的ID

    终止控件的ID

    void func(UINT id,NMHDR* pNotifyStruct,LRESULT* result);

    ON_CONTROL

    Code

    ID

    func

    处理WM_COMMAND中的EN_、BN_消息

    消息码

    控件ID

    void func();

    ON_CONTROL_RANGE

    Code

    IDFirst

    IDLast

    func

    要求控件ID连续,功能和上一个一样

    消息码

    起始控件的ID

    终止控件的ID

    void func(UINT id);

    ON_MESSAGE

    Msg

    func

    处理任意消息,包括用户自定义消息

    消息ID

    LRESULT func(WPARAM wParam,LPARAM lParam);

    ON_REGISTERD_MESSAGE

    Msg

    func

    处理使用RegisterWindowMessage注册的消息

    消息ID

    LRESULT func(WPARAM wParam,LPARAM lParam);

    3.核心类

    (1)CWinApp

    代表主程序,负责维护进程的启动终止、消息循环、命令行参数、资源管理

    常用的成员;调用的方法是使用全局函数AfxGetApp()获取到指针,然后访问

    m_pszAppName

    应用程序名称

    m_lpCmdLine

    命令行参数

    m_pMainWnd

    应用程序主窗口指针

    m_pszExeName

    可执行文件的名称

    m_pszProfileName

    配置INI文件的名称

    m_pszRegistrKey

    配置注册表主键值

    LoadCursor

    加载光标

    LoadIcon

    加载图标

    GetProfileInt

    从配置读取整数

    WriteProfileInt

    从配置写入整数

    GetProfileString

    从配置读取字符串

    WriteProfileString

    从配置写入字符串

    AddDocTemplate

    添加文档模板

    AddToRecentFileList

    向“最近打开的文件”菜单项中添加一个文件

    InitInstance

    MFC程序的入口

    Run

    事件循环

    OnIdle

    空闲事件处理

    ExitInstance

    MFC程序出口

    PreTranslateMessage

    筛选消息

    DoWaitCursor

    出现“沙漏”光标

    (2)CDocument

    提供了文档所需要的最基本功能:打开保存文档、维护文档相关的视图列表、维护文档修改标志、通过电子邮件发送文档,是数据的抽象

    可能用到的方法

    一般方法

    GetTitle()

    获取文档标题

    SetTitle()

    设置文档标题

    GetPathName()

    获取文档的路径

    SetPathName()

    设置文档的路径

    GetDocTemplate()

    获取文档模板的指针

    AddView()

    对与文档相关的视图列表中添加视图

    RemoveView()

    从文档视图列表中移除视图

    UpdateAllViews()

    文档已修改,更新全部相关的视图

    DisconnectViews()

    使文档与视图相分离

    GetFile()

    获取指向CFile类型的指针

    CDocumnet的虚方法

    OnNewDocument()

    由MFC调用来创建新文档

    OnOpenDocument()

    由MFC调用来打开文档

    OnSaveDocument()

    由MFC调用来保存文档

    OnCloseDocument()

    由MFC调用来关闭文档

    CanCloseDocument()

    观察文档的框架窗口是否被允许关闭

    DeleteContents()

    在未撤销文档对象时删除文档数据

    ReleaseFile()

    释放文件以允许其他应用程序使用

    SaveModified()

    查询文档的修改状态并保存修改的文档

    IsModified ()

    文档是否被修改过

    SetModifiedFlag()

    设置文档是否被修改过的标记

    GetFirstViewPosition()

    获取视图列表头的位置

    GetNextView()

    获取视图列表的下一个视图指针

    逐个对视图进行操作

    POSITION pos=GetFirstViewPosition();

    while(pos!=NULL)

    {

    CView* pView=GetNextView(pos);

    }

    (3)CView

    继承自CWnd可以接收任何windows消息;OnDraw()除了负责绘制还处理了打印功能、Invalidate()、UpdateWindow()强制视图重绘,都不能在OnDraw()中调用,否则程序会因为递归循环调用而失去响

    可能用到的方法

    一般方法

    GetDocument()

    获取与视图相关联的文档指针

    DoPreparePrinting()

    设置文档标题

    虚方法

    IsSelected()

    文档是否被选中

    OnScroll()

    当用户滚动时触发

    OnInitialUpdate()

    类在第一次构造后由MFC调用

    OnDraw()

    由MFC调用发出文档到设备描述表

    OnUpdate()

    由MFC调用对修改的文档进行响应

    OnPrepareDC()

    调用OnDraw()前由MFC修改设备表述表

    CView的子类

    CEditView

    简单的文本编辑器

    CListView

    列表视图

    CTreeView

    树状视图

    CRichEditView

    富文档编辑器

    CScrollView

    支持滚动条的视图

    CFormView

    窗体视图,支持在之上使用对话框控件

    CRecordView

    连接到ODBC数据库的视图

    CDaoRecordView

    连接到DAO数据库的视图

    (4)CDocTemplate

    文档模板类将文档、视图和框架窗口对象联系在一起,负责一种文档类型的创建和管理;CSingleDocTemplate、CMultiDocTemplate

    可能用到的方法

    GetDocString()

    获取与文档相关的字符串

    LoadTemplate()

    加载指定模板

    AddDocument()

    给文档模板添加指定模板

    RemoveDocument()

    从文档模板列表中删除文档

    GetFirstDocPosition()

    获取与文档模板相关的第一个文档的位置

    GetNextDoc()

    获取文档即下一个文档

    CreateNewDocument()

    建立文档

    CreateNewFrame()

    建立包含文档和视图的框架窗口

    OpenDocumentFile()

    打开有路径名指定的文档

    CloseAllDocument()

    关闭所有文档

    SetDefaultTitle()

    显示文档窗口的标题栏内容

    SaveAllModified()

    查询文档模板的修改状态并存储相关的所有文档

    InitialUpdateFrame

    触发关联视图的OnInitialUpdate()

    CloseAllDocuments

    关闭所有关联的文档

    CDocTemplate文档模板中的字符串,这些是枚举类型中的数据,通过GetDocString()才能访问到字符串

    windowTitle

    应用程序的标题栏文字

    docName

    默认的新文档名

    fileNewName

    如果有多个模板,先选择模板对话框中显示

    filterName

    文件对话框中对扩展名的描述

    filterExt

    文档扩展名

    regFileTypeId

    该文档类型的注册名

    regFileTypeName

    该文档类型对应注册表中用户可见的名称

    (5)CFrameWnd

    框架窗口,维护工具条、菜单、状态栏、视图的显示和刷新等;MDI程序中使用的是它的子类CMDIFrameWnd和CMDIChildWnd

    类的成员

    m_bAutoMenuEnable

    禁用没有消息处理的菜单项

    rectDefault

    默认尺寸的矩形

    Create()

    创建窗口,可以重载改变一些窗口属性

    LoadFrame()

    从资源加载框架

    SaveBarState()

    保存工具条的状态

    LoadBarState()

    恢复工具条的状态

    ShowControlBar()

    显示工具条

    EnableDocking()

    使一个控制条可以停靠

    DockControlBar()

    停靠一个控制条

    FloatControlBar()

    浮动一个控制条

    GetControlBar()

    获取一个控制条

    RecalLayout()

    基于当前视图和控制条重新计算显示区域

    InitialUpdateFrame()

    调用所有关联视图的OnInitialUpdate()

    GetActiveFrame()

    MDI中获取活动框架

    SetActiveView()

    激活一个视图

    GetActiveView()

    获取当前激活的视图

    CreateView()

    创建一个视图

    GetActiveDocument()

    获取当前激活的文档

    GetMessageString()

    获取带有命令ID的消息

    GetMessageText()

    在状态栏显示一条消息

    GetMessageBar()

    获取指向状态栏的指针

    (6)5个核心类的相互访问

    当前对象

    要访问的对象

    访问方法

    文档

    视图

    GetFirstViewPosition()、GetNextView()

    文档

    模板

    GetDocTemplate()

    视图

    文档

    GetDocment()

    视图

    框架

    GetParentFrame()

    框架

    视图

    GetActiveView()

    框架

    文档

    GetActiveDocument()

    MDI主框架

    MDI子框架

    MDIGetActive()

    MDI子框架

    MDI主框架

    GetParentFrame()

    任何位置

    应用程序

    AfxGetApp()

    任何位置

    主框架

    AfxGetMainWnd()

    4.在程序向导上创建SDI和MDI程序

    (1)SDI

    View类中OnDraw()的填充;

    文档序列化

    (2)MDI

    在类视图中添加类MFC,输入类名和基类

    用类似的方法添加视图View类

    创建资源

    //这个ID要和上一个表示类型的ID数值上连续,如果还有多个类型、可能需要修改#define _APS_NEXT_RESOURCE_VALUE

    #define IDR_MYMDITYPE2 135

    //在MyMdi.rc文件中IDR_MYMIDTYPE “ …”后面添加类似的代码

    IDR_MYMDITYPE2 “ MyMdi2 …”

    创建主菜单资源,在MyMdi的资源视图中复制IDR_MYMIDTYPE、修改出ID为IDR_MYMDITYPE2的菜单

    创建文档模板类

    BOOL CMyMdiApp::InitInstance()

    {

    CMultiDocTemplate* pDocTemplate2;

    pDocTemplate2=new CMulitDocTemplate(

    IDR_MYMDITYP2,

    RUNTIME_CLASS(CMyMdiDoc2);

    RUNTIME_CLASS(CChildFrame);

    RUNTIME_CLASS(CMyMdiView2);

    AddDocTemplate(pDocTemplate2);

    }

    扩展CMyMdiDoc2类、菜单处理函数和文档序列化

    View视图的输出

    void CMyMdiView2::OnLButtonDown(UINT nFlags, CPoint point)

    {

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    CMyMdiDoc2* pDoc=(CMyMdiDoc2*)GetDocument();

    m_drawData=new DrawData;

    m_drawData->begin=point;

    CView::OnLButtonDown(nFlags, point);

    }

    void CMyMdiView2::OnLButtonUp(UINT nFlags, CPoint point)

    {

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    CMyMdiDoc2* pDoc=(CMyMdiDoc2*)GetDocument();

    pDoc->SetModifiedFlag(TRUE);

    m_drawData->end=point;

    CClientDC dc(this);

    CBrush* brush=CBrush::FromHandle((HBRUSH)GetStockObject(HOLLOW_BRUSH));

    dc.SelectObject(brush);

    CRect rect(m_drawData->begin,m_drawData->end);

    switch(pDoc->m_drawType)

    {

    case 0:

    dc.MoveTo(m_drawData->begin);

    dc.LineTo(m_drawData->end);

    break;

    case 1:

    dc.Ellipse(rect);

    break;

    case 2:

    dc.Rectangle(rect);

    break;

    }

    m_drawData->type=pDoc->m_drawType;

    pDoc->m_data.Add(m_drawData);

    brush->DeleteObject();

    Invalidate();

    CView::OnLButtonUp(nFlags, point);

    }

    void CMyMdiView2::OnDraw(CDC* pDC)

    {

    CMyMdiDoc2* pDoc=(CMyMdiDoc2*)GetDocument();

    // TODO: 在此添加绘制代码

    CBrush* brush=CBrush::FromHandle((HBRUSH)GetStockObject(HOLLOW_BRUSH));

    pDC->SelectObject(brush);

    int i;

    for(i=0;i<pDoc->m_data.GetCount();++i)

    {

    m_drawData=(DrawData*)(pDoc->m_data.GetAt(i));

    CRect rect(m_drawData->begin,m_drawData->end);

    switch(m_drawData->type)

    {

    case 0:

    pDC->MoveTo(m_drawData->begin);

    pDC->LineTo(m_drawData->end);

    break;

    case 1:

    pDC->Ellipse(rect);

    break;

    case 2:

    pDC->Rectangle(rect);

    break;

    }

    }

    brush->DeleteObject();

    }

    5.MFC多线程

    DWORD ThreadID;

    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&ThreadID);

    void ThreadFunc(){…}

    五、数据库

    1.有关数据库的基础知识

    (1)CRecordView

    用于显示和操作数据;可能会出现中文乱码的情况,解决的办法是文件->高级保存选项中选择utf8,资源视图中的所有视图的语言都选成简体中文

    ①可能用到的函数

    CRecordView()

    构造函数

    OnInitialUpdate()

    将CRecordView子类中的变量和数据库的数据关联起来

    IsOnFirstRecord()

    当前记录是否是数据库中的第一个记录

    IsOnLastRecord()

    当前记录是否是数据库中的最后一个记录

    OnGetRecordset()

    返回一个CRecordset类型的指针

    OnMove()

    在数据库中移动游标并将记录显示在视图控件中,有类似BOOL的返回值

    ②OnMove参数的取值

    ID_RECORD_FIRST

    移动到数据库的第一个记录

    ID_RECORD_LAST

    移动到数据库的最后一个记录

    ID_RECORD_NEXT

    向后移动一个记录

    ID_RECORD_PREV

    向前移动一个记录

    (2)CRecordSet

    表示的是数据集,有两种典型的表:动态保持数据库中的数据dynasets、静态的数据库snapshots

    ①成员

    m_hstmt

    调用Open()后包含有描述ODBC数据源的句柄

    m_nFields

    数据库的属性变量,它指示了从数据源读取的记录个数

    m_nParams

    用来指示CRecordset的派生类的参数个数,默认值是0

    m_pDatabase

    指向CDatabase的指针、指向当前数据库打开的数据源

    m_strFilter

    构造CRecordset类后、调用Open函数前,使用这个变量填写一个CString对象,就像SQL语句的WHERE条件部分

    m_strSort

    构造CRecordset类后、调用Open函数前,使用这个变量填写一个CString对象,就像SQL语句的ORDER BY部分

    ②成员函数

    Open()

    打开一个数据源,返回类似BOOL的值

    Close()

    关闭一个数据集

    CanAppend()

    判断打开的数据源是否允许加入新记录

    CanBookmark()

    判断数据源是否支持书签的功能

    CanRestart()

    判断数据源是否支持重新执行查询语句

    CanScroll()

    判断数据源是否支持翻阅的功能

    CanTransact()

    判断数据源是否支持事务

    CanUpdate()

    判断数据源是否能够更新

    GetRecordCount()

    获取数据库中记录的数目

    GetStatus()

    获取数据源的状态,这是一个CRecordsetStatus类型的指针

    GetTableName()

    获取一张表的名称

    GetSQL()

    获取一个SQL语句,这是CString类型的指针

    IsOpen()

    判断数据源是否已经打开

    IsBOF()

    判断数据库是否为空

    IsEOF()

    判断是否到了最后一条记录

    IsDeleted()

    判断指向的记录是否是一个被删除的记录

    AddNew()

    添加一个新纪录,调用Update()后记录才加入到数据源中去

    CancelUpdate()

    取消对数据源的修改,在AddNew()、Edit()之后,Update()之前才会有效

    Delete()

    删除当前指向的记录,游标移走后被删除的记录再无法恢复

    Move()

    在数据库中移动记录指针,类似的函数有MoveNext()、MovePrev()、MoveFirst()、MoveLast()、SetBookmark()、SetAbsolutePosition()

    GetDefaultConnect()

    获取一个默认连接的数据源

    GetDefaultSQL()

    获取相应的默认的SQL语句

    Requery()

    刷新snapshots数据库,调用前要使用Open()

    ③virtual BOOL Open(UINT nOpenType,LPCTSTR lpszSQL,DWORD dwOptions);的参数

    nOpenType

    默认方式AFX_DB_USE_DEFAULT_TYPE 、dynaset、snapshot、dynamic、只能向前翻阅forwardOnly

    lpszSQL

    表示SQL语句的字符串

    dwOptions

    选择数据的风格,可以填NULL

    ④dwOptions数据源的打开方式

    openReadOnly

    只读

    useCursorLib

    加载ODBC Cursor Library DLL

    noOdbcDialog

    不出现ODBC连接对话框

    forceOdbcDialog

    总要出现ODBC连接对话框

    ⑤virtual void Move(long nRows,WORD wFetchType);的参数

    nRows是要移动的行数、wFetchType是要进行的动作

    SQL_FETCH_RELATIVE

    默认值,移动到距离第一个记录的指定行上

    SQL_FETCH_NEXT

    移到下一个记录

    SQL_FETCH_PRIOR

    移到上一个记录

    SQL_FETCH_FIRST

    移到第一个记录

    SQL_FETCH_LAST

    移到最后一个记录

    SQL_FETCH_ABSOLUTE

    nRows大于0、移到nRows行后,nRows小于0、移到倒数nRows行后,否则返回BOF

    SQL_FETCH_BOOKMARK

    在指定位置设置标签

    (3)CDatabase

    用于连接一个数据源

    ①可能用到的成员函数

    Open()

    打开一个数据源,返回类似BOOL的值

    Close()

    关闭一个数据源

    ExecuteSQL()

    执行SQL语句

    CanTransact()

    判断数据源是否支持事务处理

    SetLoginTimeout()

    设置连接超时的时间,单位是s

    GetConnect()

    返回当前对象的ODBC数据源的名称

    Rollback()

    事务回滚

    GetDatabaseName()

    返回当前连接的数据源的名称,这个名称不一定是ODBC控制台登记的名称

    IsOpen()

    判断当前对象是否连接着数据源

    CanUpdate()

    判断数据源是否可修改

    BeginTrans()

    开始一个事务的操作

    CommitTrans()

    提交一个数据库事务

    ②virtual BOOL Open(LPCTSTR lpszDSN,BOOL bExclusive,BOOL bReadOnly,LPCTSTR lpszConnect,BOOL bUseCursorLib);的参数

    类似的函数是virtual BOOL OpenEX(LPCTSTR lpszConnectString,DWORD dwOptions);

    lpszDSN

    ODBC控制台中注册的数据源的名称,如果lpszConnect已经有DSN值的话可以取NULL

    bExclusive

    共享方式打开的数据源取FALSE

    bReadOnly

    只读

    lpszConnect

    包含用户和密码的描述字符串

    bUseCursorLib

    加载ODBC的Cursor Library DLL

    lpszConnectString

    包含用户和密码的描述字符串

    (4)RFX

    和DDX类似,RFX用于视图和数据源自动交换数据,有时候需要自定义的代码:带参数的查询、数据库中表之间的连接

    (5)CDBException

    抛出一个异常void AfxThrowDBException(RETCODE nRetCode,CDatabase* pdb,HSTMT hstmt);

    2.建立ODBC数据源

    进入Access创建一个空数据库、建立字段、填充数据,这个数据库默认用户名是admin密码为空,如果想要设置用户名和密码可以以独占读取.mdb文件的方式、在工具->安全中设置新的用户名和密码;

    控制面板->管理工具-> ODBC 数据源(32 位)->系统DSN->添加.mdb->命名数据源注册的名称、选择数据库文件

    3.显示数据库中的数据

    如果只是和数据库的记录打交道,在项目向导中选择“不支持文件的数据库视图”;

    在资源视图中设计表单的样式、定义各控件的ID;

    填充数据到视图的映射代码:

    void CMy3View::DoDataExchange(CDataExchange* pDX)

    {

    CRecordView::DoDataExchange(pDX);

    // 可以在此处插入 DDX_Field* 函数以将控件“连接”到数据库字段,例如

    // DDX_FieldText(pDX, IDC_MYEDITBOX, m_pSet->m_szColumn1, m_pSet);

    // DDX_FieldCheck(pDX, IDC_MYCHECKBOX, m_pSet->m_bColumn2, m_pSet);

    // 有关更多信息,请参阅 MSDN 和 ODBC 示例

    DDX_FieldText(pDX,IDC_EDIT1,m_pSet->m_Sno,m_pSet);

    DDX_FieldText(pDX,IDC_EDIT2,m_pSet->m_Sname,m_pSet);

    DDX_FieldText(pDX,IDC_EDIT3,m_pSet->m_Ssex,m_pSet);

    DDX_FieldText(pDX,IDC_EDIT4,m_pSet->m_Sage,m_pSet);

    DDX_FieldText(pDX,IDC_EDIT5,m_pSet->m_Sdept,m_pSet);

    }

    4.对记录进行排序

    可以在工具栏或菜单项中设计按钮、定义ID,为这个控件的COMMAND消息设计触发事件:

    void CMy3View::OnSortPrice()

    {

    // TODO: 在此添加命令处理程序代码

    m_pSet->Close();

    m_pSet->m_strSort=L"Sage";

    //重新使用成员变量m_strSort

    //m_pSet->Open(-1,L"SELECT * FROM Student WHERE Sdept='CS'",NULL);

    m_pSet->Open();

    //更新表单

    UpdateData(FALSE);

    }

    5.增添记录

    清空当前表单,就可以在表单中新添一些数据:

    void CMy3View::OnClearRecord()

    {

    // TODO: ?????í???ü?????í???ò?ú??

    m_pSet->SetFieldNull(NULL);

    UpdateData(FALSE);

    }

    在工具栏或菜单项中设计按钮、定义ID,为这个控件的COMMAND消息设计触发事件:

    void CMy3View::OnRecordAdd()

    {

    // TODO: ?????í???ü?????í???ò?ú??

    CRecordset* pSet=OnGetRecordset();

    if(pSet->CanUpdate() && !pSet->IsDeleted())

    {

    pSet->Edit();

    if(!UpdateData())

    return;

    pSet->Update();

    }

    m_pSet->AddNew();

    m_pSet->Update();

    m_pSet->Requery();

    m_pSet->MoveLast();

    UpdateData(FALSE);

    }

    6.删除记录

    默认情况下,用户移动一个记录就会对数据库进行修改,所以需要重载View类的OnMove():

    BOOL CMy3View::OnMove(UINT nIDMoveCommand)

    {

    // TODO: ?????í??ר???ú????/?ò?÷???ù?à

    switch(nIDMoveCommand)

    {

    case ID_RECORD_PREV:

    m_pSet->MovePrev();

    if(!m_pSet->IsBOF())

    break;

    case ID_RECORD_FIRST:

    m_pSet->MoveFirst();

    break;

    case ID_RECORD_NEXT:

    m_pSet->MoveNext();

    if(!m_pSet->IsEOF())

    break;

    if(!m_pSet->CanScroll())

    {

    m_pSet->SetFieldNull(NULL);

    break;

    }

    case ID_RECORD_LAST:

    m_pSet->MoveLast();

    break;

    default:

    ASSERT(FALSE);

    }

    UpdateData(FALSE);

    return TRUE;

    //return CRecordView::OnMove(nIDMoveCommand);

    }

    在工具栏或菜单项中设计按钮、定义ID,为这个控件的COMMAND、UPDATE_COMMAND_UI消息设计触发事件:

    void CMy3View::OnDeleteRecord()

    {

    // TODO: ?????í???ü?????í???ò?ú??

    CRecordsetStatus m_cStatus;

    try

    {

    m_pSet->Delete();

    }

    catch(CDBException* m_pEx)

    {

    AfxMessageBox(m_pEx->m_strError);

    m_pEx->Delete();

    m_pSet->MoveFirst();

    UpdateData(FALSE);

    return;

    }

    m_pSet->GetStatus(m_cStatus);

    if(m_cStatus.m_lCurrentRecord==0)

    m_pSet->MoveFirst();

    else

    m_pSet->MoveNext();

    UpdateData(FALSE);

    }

    void CMy3View::OnUpdateDeleteRecord(CCmdUI *pCmdUI)

    {

    // TODO: ?????í???ü???ü?????§???????í???ò?ú??

    pCmdUI->Enable(!m_pSet->IsEOF());

    }

    7.查询记录

    void CMy3View::OnSearch()

    {

    // TODO: 在此添加命令处理程序代码

    DoFilter(L"Sdept");

    }

    // 仅供内部重复使用的函数

    void CMy3View::DoFilter(CString col)

    {

    CSearchDlg dlg;

    if(dlg.DoModal()==IDOK)

    {

    CString str=col+L"='"+dlg.m_Edit_Search+L"'";

    m_pSet->Close();

    m_pSet->m_strFilter=str;

    m_pSet->Open();

    if(m_pSet->GetRecordCount()==0)

    {

    MessageBox(L"没有匹配的记录!");

    m_pSet->Close();

    m_pSet->m_strFilter=L"";

    m_pSet->Open();

    }

    UpdateData(FALSE);

    }

    }

    8.修改记录

    默认情况下,用户移动一个记录就会对数据库进行修改,所以需要重载View类的OnMove();

    在工具栏或菜单项中设计按钮、定义ID,为这个控件的COMMAND、UPDATE_COMMAND_UI消息设计触发事件:

    void CMy3View::OnUpdateRecord()

    {

    // TODO: ?????í???ü?????í???ò?ú??

    m_pSet->Edit();

    UpdateData(TRUE);

    if(m_pSet->CanUpdate())

    {

    m_pSet->Update();

    }

    }

    void CMy3View::OnUpdateUpdateRecord(CCmdUI *pCmdUI)

    {

    // TODO: ?????í???ü???ü?????§???????í???ò?ú??

    pCmdUI->Enable(!m_pSet->IsEOF());

    }

    9.移动到指定的位置

    在资源视图中建立对话框和相关的类、编辑框的变量m_RecordID;

    在工具栏或菜单项中设计按钮、定义ID,为这个控件的COMMAND消息设计触发事件:

    void CMy3View::OnMovetorecord()

    {

    // TODO: ?????í???ü?????í???ò?ú??

    CMoveToRecord dlgMoveTo;

    if(dlgMoveTo.DoModal()==IDOK)

    {

    CRecordset* pSet=OnGetRecordset();

    if(pSet->CanUpdate() && !pSet->IsDeleted())

    {

    pSet->Edit();

    if(!UpdateData())

    return;

    pSet->Update();

    }

    pSet->SetAbsolutePosition(dlgMoveTo.m_RecordID);

    UpdateData(FALSE);

    }

    }

    六、多媒体

    1.音频播放

    (1)使用音频函数的方式

    ①BOOL MessageBeep(UINT nType);播放系统提示音

    0xFFFFFFFF

    系统默认的声音

    MB_ICONINFORMATION或MB_ICONASTERISK

    出现信息消息框时的声音

    MB_ICONEXLAMATION或MB_ICONWARNING

    出现警告消息框时的声音

    MB_ICONHAND或MB_ICONSTOP或MB_ICONERROR

    出现错误提示框时的声音

    MB_ICONQUESTION

    出现询问对话框时的声音

    MB_OK

    系统默认声音

    ②BOOL sndPlaySound(LPCSTR lpszSound,UINT fuSound);播放指定文件名或是注册表中已有的声音

    fuSound播放标识

    SND_ASYNC

    异步播放声音,进入函数后立即返回,终止的办法是sndPlaySound(…,NULL);

    SND_LOOP

    循环播放声音,但是要和SND_ASYNC一同使用,终止办法和上一个相同

    SND_MEMORY

    第一个参数是.wav在内存中的映像

    SND_NODEFAULT

    当无法正常播放声音时不播放系统默认声音

    SND_NOSTOP

    如果有声音正在播放,则返回FALSE、终止运行

    SND_SYNC

    同步方式播放声音,只有声音播放结束才返回结果

    注册表中已有的声音

    SystemAsterisk

    出现信息消息框时的声音

    SystemExclamation

    出现警告消息框时的声音

    SystemExit

    系统退出时的提示音

    SystemHand

    出现错误提示框时的声音

    SystemQuestion

    出现询问对话框时的声音

    SystemStart

    系统启动提示音

    ③BOOL PlaySound(LPCSTR pszSound,HMODULE hmod,DWORD fdwSound);

    fdwSound指定声音的来源,如果没有指定先到注册表中找、再到文件中找;NULL表示停止当前.wav声音,SND_PURGE表示停止其他声音;hmod是资源文件的句柄。

    fdwSound的取值

    SND_ALIAS

    注册条目

    SND_RESOURCE

    来自资源

    SND_FILENAME

    来自文件

    SND_NOWAIT

    如果设备正使用,立即返回不再播放

    SND_APPLICATION

    用用应用程序制定的音频

    SND_PURGE

    停止声音播放

    SND_ALIAS_ID

    预先确定的声音标识

    (2)使用MCI的方式

    MCI指的是媒体控制接口类Media Control Interface,可以支持更复杂的音频操作:暂停、向前搜索、向后搜索、对音频文件进行编辑等;对MCI设备进行控制的两个方法,MCI命令串mciSendString()、MCI命令消息mciSendCommand(),但是发送命令消息要比发送命令字串要高效。

    ①可能用到的函数

    MCIERROR mciSendCommand(

    //接收命令消息的MCI设备ID,可以通过MCI_OPEN()获得

    // MCIERROR的低字节存储错误值、高字节存储设备标识,执行正确的返回结果MCIERROR为0

    MCIDEVICEID IDDevice,

    //要发送的命令消息

    UINT uMsg,

    //命令消息的标志集

    DWORD fdwCommand,

    //包含命令消息参数的结构体地址

    DWORD_PTR dwParam);

    要发送的命令消息uMsg

    MCI_BREAK

    为MCI设备设置终止键,默认是ctrl+break

    全部设备

    MCI_STATUS

    获取一个MCI设备的信息

    MCI_CLOSE

    释放出访问设备的通道

    MCI_SYSINFO

    获取MCI设备的信息

    MCI_GETDEVCAPS

    获取一个设备的静态信息

    MCI_INFO

    获取一个设备的字串信息

    MCI_OPEN

    初始化一个设备

    MCI_CAPTURE

    获取缓冲区中每一帧的内容并存入指定文件

    数字视频

    MCI_CONFIGURE

    显示一个对话框用于设置操作

    MCI_UNDO

    撤销最近一次操作

    MCI_LOAD

    加载一个文件

    MCI_PUT

    设置来源、目的和框架矩形

    MCI_UPDATE

    更新显示矩形

    MCI_COPY

    拷贝数据到粘贴板

    MCI_WHERE

    获取视频设备的剪切板模型

    MCI_WINDOW

    指定窗口和窗口特性用于图形设备

    MCI_CUT

    剪切数据到粘贴板

    MCI_MONITOR

    指定陈述的来源

    MCI_PASTE

    将粘贴板上的数据粘贴到文件中

    MCI_QUALITY

    指定多媒体的质量

    MCI_RESERVE

    为下面的记录分配一块磁盘空间

    MCI_RESTORE

    将一幅位图由文件拷贝到缓冲区中

    MCI_SIGNAL

    在工作区中设置一个指定位置

    MCI_PAUSE

    暂停当前播放的位置

    CD音频、数字视频、MIDI序列、录像机、影碟机、.wav文件

    MCI_PLAY

    设备开始输出数据

    MCI_SET

    设置设备信息

    MCI_STOP

    停止所有的播放记录并释放缓存

    MCI_CUE

    提示一个设备、使设备以最小的延迟进行播放或重放

    数字视频、录像机、.wav文件

    MCI_RESUME

    恢复被暂停的操作

    MCI_FREEZE

    冻结显示中的画面

    数字视频、录像机

    MCI_LIST

    获取可用于输入设备关于数量和类型方面的信息

    MCI_SETAUDIO

    设置与音频回放、捕捉相关的变量

    MCI_SETVIDEO

    设置与视频回放相关的变量

    MCI_UNFREEZE

    恢复执行了MCI_FREEZE命令的设备

    MCI_DELETE

    删除文件中的数据

    数字视频、.wav文件

    MCI_ESCAPE

    直接发送一个字串到指定设备

    影碟机

    MCI_SPIN

    使设备开始转动或停止

    MCI_INDEX

    将屏幕上的显示置为on或off

    录像机

    MCI_SETTIMECODE

    使用或禁用VCR设备录音的时间代码

    MCI_SETTUNER

    设置调制器的当前频道

    MCI_MARK

    记录或擦除以使MCI_SEEK命令获得更高的寻找速度

    MCI_RECORD

    从当前位置或指定的起始、终止位置开始记录

    录像机、.wav文件

    MCI_SAVE

    保存当前文件

    .wav文件

    MCI_SEEK

    以最快的速度改变当前内容的输出位置

    CD音频、数字视频、MIDI序列、录像机、影碟机

    MCI_STEP

    跳过一帧或多帧

    数字视频、录像机、CAV格式影碟机

    检测错误

    BOOL mciGetErrorString(

    //错误代码

    DWORD fdwError,

    //用于描述错误内容的字符串

    LPTSTR lpszErrorText,

    //错误内容的缓冲区容量

    UINT cchErrorText);

    ②环境配置:在stdafx.h中_AFX_NO_AFXCMN_SUPPORT下面添加#include <mmsystem.h>;

    右击工程->属性->链接器->输入,在附加依赖项中输入winmm.lib

    ③对话框类中添加可能用到的数据:

    // 判断正在播放的标志

    BOOL m_PSign;

    // 判断正在暂停的标志

    BOOL m_ASign;

    // 用来存储错误代码

    DWORD dwError;

    // 用来存储打开设备的ID值

    MCIDEVICEID m_MCIDeviceID;

    // 用来存储出错的内容

    char szErrorBuf[MAXERRORLENGTH];

    ④选择要播放的音乐

    void CMy0Dlg::OnOpenButton()

    {

    // TODO: 在此添加控件通知处理程序代码

    //文件名

    CString fileName;

    //文件扩展名

    CString fileExt;

    MCI_OPEN_PARMS mciOpenParms;

    DWORD dwError;

    static TCHAR szFilter[]=L"波形音频文件(*.wav)|*.wav|MIDI序列(*.mid)|*.mid||";

    CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);

    if(dlg.DoModal()==IDOK)

    {

    //这个地方可能有问题?

    fileName=dlg.GetFolderPath()+L"\"+dlg.GetFileName();

    fileExt=dlg.GetFileExt();

    //AfxMessageBox(L"fileName: "+fileName+L" fileExt: "+fileExt);

    //如果程序正在播放则关闭

    if(m_PSign)

    {

    dwError=mciSendCommand(m_MCIDeviceID,MCI_CLOSE,0,NULL);

    if(dwError)

    {

    if(mciGetErrorString(dwError,(LPTSTR)szErrorBuf,MAXERRORLENGTH))

    MessageBox((LPCTSTR)szErrorBuf,L"MCI出错0",MB_ICONWARNING);

    else

    MessageBox(L"不明错误标识",L"MCI出错0",MB_ICONWARNING);

    return;

    }

    }

    if(!_tcscmp(L"wav",fileExt))

    mciOpenParms.lpstrDeviceType=L"waveaudio";

    else if(!_tcscmp(L"mid",fileExt))

    mciOpenParms.lpstrDeviceType=L"sequencer";

    mciOpenParms.lpstrElementName=fileName;

    //将打开的文件名存入mciOpenParms结构体中

    dwError=mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);

    if(dwError)

    {

    if(mciGetErrorString(dwError,(LPTSTR)szErrorBuf,MAXERRORLENGTH))

    MessageBox((LPCTSTR)szErrorBuf,L"MCI出错1",MB_ICONWARNING);

    else

    MessageBox(L"不明错误标识",L"MCI出错1",MB_ICONWARNING);

    return;

    }

    m_MCIDeviceID=mciOpenParms.wDeviceID;

    m_PSign=FALSE;

    m_ASign=FALSE;

    }

    }

    ⑤播放音乐

    void CMy0Dlg::OnBnClickedPlayButton()

    {

    // TODO: 在此添加控件通知处理程序代码

    //存储与播放有关的信息

    MCI_PLAY_PARMS mciPlayParms;

    //如果没有正在播放的声音

    if(!m_PSign)

    {

    //为MM_MCINOTIFY消息指定窗口句柄

    mciPlayParms.dwCallback=(long)GetSafeHwnd();

    //播放位置从头开始

    mciPlayParms.dwFrom=0;

    dwError=mciSendCommand(m_MCIDeviceID,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);

    if(dwError)

    {

    if(mciGetErrorString(dwError,(LPTSTR)szErrorBuf,MAXERRORLENGTH))

    MessageBox((LPCTSTR)szErrorBuf,L"MCI出错",MB_ICONWARNING);

    else

    MessageBox(L"不明错误标识",L"MCI出错",MB_ICONWARNING);

    return;

    }

    m_PSign=TRUE;

    }

    }

    ⑥暂停/继续

    void CMy0Dlg::OnBnClickedPauseButton()

    {

    // TODO: 在此添加控件通知处理程序代码

    //有正在播放的声音

    if(m_PSign)

    {

    //不是暂停状态

    if(!m_ASign)

    {

    dwError=mciSendCommand(m_MCIDeviceID,MCI_PAUSE,0,NULL);

    if(dwError)

    {

    if(mciGetErrorString(dwError,(LPTSTR)szErrorBuf,MAXERRORLENGTH))

    MessageBox((LPCTSTR)szErrorBuf,L"MCI出错",MB_ICONWARNING);

    else

    MessageBox(L"不明错误标识",L"MCI出错",MB_ICONWARNING);

    return;

    }

    m_ASign=TRUE;

    }

    else

    {

    dwError=mciSendCommand(m_MCIDeviceID,MCI_RESUME,0,NULL);

    if(dwError)

    {

    if(mciGetErrorString(dwError,(LPTSTR)szErrorBuf,MAXERRORLENGTH))

    MessageBox((LPCTSTR)szErrorBuf,L"MCI出错",MB_ICONWARNING);

    else

    MessageBox(L"不明错误标识",L"MCI出错",MB_ICONWARNING);

    return;

    }

    m_ASign=FALSE;

    }

    }

    }

    ⑦播放结束后需要响应MM_MCINOTIFY,对类中的标记做修改

    对话框的头文件中添加

    afx_msg LRESULT MciNotify(WPARAM wParam,LPARAM lParam);

    对话框的源文件中添加消息映射

    ON_MESSAGE(MM_MCINOTIFY,MciNotify)

    定义做出响应的函数

    LRESULT CMy0Dlg::MciNotify(WPARAM wParam,LPARAM lParam)

    {

    if(wParam==MCI_NOTIFY_SUCCESSFUL)

    {

    AfxMessageBox(L"enter.");

    m_PSign=FALSE;

    m_ASign=FALSE;

    return 0;

    }

    return -1;

    }

    2.视频播放

    资源视图->右键->插入ActiveX控件->选择Windows Media Player;

    项目->添加类->ActiveX控件中的MFC类;

    来源选择“文件”,“位置”是C:windowssystem32wmp.dll,“接口”选择IWMPPlayer4;

    对话框类的头文件中加入#include “CWMPPlayer4.h”;

    再次进入资源视图,为这个ActiveX控件添加变量m_mediaPlay;

    为这个ActiveX控件添加触发事件:

    void CMy0Dlg::DoubleClickOcx1(short nButton, short nShiftState, long fX, long fY)

    {

    // TODO: 在此处添加消息处理程序代码

    CFileDialog dlg(TRUE,NULL,L"*.*",OFN_FILEMUSTEXIST,

    L"ActiveStreamingFormat(*.asf)|*.asf|"

    L"AudioVidesInterleaveFormat(*.avi)|*.avi|"

    L"RealAudio/RealVideo(*.rm)|*.rm|"

    L"WaveAudio(*wav)|*.wav|"

    L"MIDIFile(*.mid)|*.mid|"

    L"所有文件(*.*)|*.*||");

    if(dlg.DoModal()==IDOK)

    m_mediaPlay.put_URL(dlg.GetPathName());

    }

    3.图片显示

    OleLoadPicture支持加载.png、.jpg、.gif等格式的图片

    (1) 创建SDI工程
    (2) 在View类中添加数据成员:

    // 用来装载图片的变量

    LPPICTURE m_pPicture;

    // 是否压缩显示

    BOOL m_bScale;

    (3) 新数据成员的初始化和销毁:

    CMy4View::CMy4View()

    : m_bScale(FALSE)

    {

    // TODO: 在此处添加构造代码

    m_pPicture=NULL;

    m_bScale=FALSE;

    }

    CMy4View::~CMy4View()

    {

    if(m_pPicture)

    {

    m_pPicture->Release();

    }

    }

    (4) 通过菜单项打开文件:

    void CMy4View::OnOperOpen()

    {

    // TODO: 在此添加命令处理程序代码

    //保存文件名的缓冲,有必要测试下这个对象!

    TCHAR szFile[MAX_PATH];

    //初始化该缓冲

    ZeroMemory(szFile,MAX_PATH);

    //用于打开文件的结构体

    OPENFILENAME ofn;

    //初始化该结构

    ZeroMemory(&ofn,sizeof(OPENFILENAME));

    //设置结构的大小

    ofn.lStructSize=sizeof(OPENFILENAME);

    ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;

    //文件框的父窗口

    ofn.hwndOwner=m_hWnd;

    ofn.lpstrFilter=

    L"Supported Files Types(*.bmp;*.gif;*.jpg;*.ico;*.emf;*.wmf)*.bmp;*.gif;*.jpg;*.ico;*.emf;*.wmf"

    L"Bitmaps(*.bmp)*.bmp"

    L"GIF Files(*.gif)*.gif"

    L"JPEG Files(*.jpg)*.jpg"

    L"Icons(*.ico)*.ico"

    L"Enhanced Metafiles(*.emf)*.emf"

    L"Windows Metafiles(*.wmf)*.wmf";

    //文件框的标题

    ofn.lpstrTitle=L"选择图片";

    //返回文件名的缓冲

    ofn.lpstrFile=szFile;

    //设置缓冲的长度

    ofn.nMaxFile=MAX_PATH;

    if(GetOpenFileName(&ofn)==IDOK)

    loadPicture(szFile);

    }

    void CMy4View::loadPicture(CString strFile)

    {

    //打开文件

    HANDLE hFile=CreateFile(strFile,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);

    _ASSERTE(INVALID_HANDLE_VALUE!=hFile);

    //获取文件的大小

    DWORD dwFileSize=GetFileSize(hFile,NULL);

    _ASSERTE(dwFileSize!=-1);

    LPVOID pvData=NULL;

    //分配全局内存,获取内存句柄

    HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);

    _ASSERTE(hGlobal!=NULL);

    //锁定内存,获取内存指针

    pvData=GlobalLock(hGlobal);

    _ASSERTE(pvData!=NULL);

    DWORD dwBytesRead=0;

    //读取文件

    BOOL hRead=ReadFile(hFile,pvData,dwFileSize,&dwBytesRead,NULL);

    _ASSERTE(hRead!=FALSE);

    GlobalUnlock(hGlobal);

    CloseHandle(hFile);

    LPSTREAM pstm=NULL;

    //从内存数据创建IStream*

    HRESULT hr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);

    _ASSERTE(pstm&&SUCCEEDED(hr));

    if(m_pPicture)

    m_pPicture->Release();

    //赋值、全局作用域(Windows api),从IStream接口加载图片到IPicture中

    hr=::OleLoadPicture(pstm,dwFileSize,FALSE,IID_IPicture,(LPVOID*)&m_pPicture);

    _ASSERTE(m_pPicture&&SUCCEEDED(hr));

    pstm->Release();

    Invalidate();

    }

    (5) 对图片进行绘制:

    void CMy4View::OnDraw(CDC* pDC)

    {

    CMy4Doc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    if (!pDoc)

    return;

    // TODO: 在此处为本机数据添加绘制代码

    if(m_pPicture)

    {

    long hmWidth;

    long hmHeight;

    m_pPicture->get_Width(&hmWidth);

    m_pPicture->get_Height(&hmHeight);

    int nWidth=MulDiv(hmWidth,GetDeviceCaps(pDC->GetSafeHdc(),LOGPIXELSX),HIMETRIC_INCH);

    int nHeight=MulDiv(hmHeight,GetDeviceCaps(pDC->GetSafeHdc(),LOGPIXELSY),HIMETRIC_INCH);

    CRect rc;

    GetClientRect(&rc);

    if(m_bScale)

    {

    //创建内存DC

    CDC memdc;

    memdc.CreateCompatibleDC(pDC);

    //创建位图

    CBitmap bmp;

    bmp.CreateCompatibleBitmap(pDC,nWidth,nHeight);

    //将位图选入内存DC

    memdc.SelectObject(bmp);

    //将图片以原始尺寸绘制到内存DC中

    m_pPicture->Render(memdc.GetSafeHdc(),0,0,nWidth,nHeight,0,hmHeight,hmWidth,-hmHeight,&rc);

    //从内存DC缩放拷贝到显示DC

    pDC->StretchBlt(0,0,nWidth/2,nHeight/2,&memdc,0,0,nWidth,nHeight,SRCCOPY);

    }

    else

    m_pPicture->Render(pDC->GetSafeHdc(),0,0,nWidth,nHeight,0,hmHeight,hmWidth,-hmHeight,&rc);

    }

    }

    //通过菜单项控制是否缩放

    void CMy4View::OnOperSize()

    {

    // TODO: 在此添加命令处理程序代码

    m_bScale=!m_bScale;

    Invalidate();

    }

    void CMy4View::OnUpdateOperSize(CCmdUI *pCmdUI)

    {

    // TODO: 在此添加命令更新用户界面处理程序代码

    pCmdUI->SetCheck(m_bScale);

    }

    七、网络编程

    1.利用WinInet抓取网页

    对基于对话框的MFC工程设置设置属性:

    工程->属性->链接器->输入WinInet.lib

    为CInternetSession m_session;封装一个类;

    从网页获取信息:

    CString MyWinInetClass::ConnectHttp(const CString sUrl)

    {

    CString sResult;

    CInternetFile* hHttpFile=NULL;

    sResult=L"";

    sResult=sResult+L"Trying to connect Http sites: "+sUrl+L" ";

    hHttpFile=(CInternetFile*)m_session.OpenURL(sUrl);

    if(hHttpFile)

    {

    sResult=sResult+L"Connection established. ";

    CString sLine;

    while(hHttpFile->ReadString(sLine))

    sResult=sResult+sLine+L" ";

    hHttpFile->Close();

    }

    else

    sResult=sResult+L"There are some errors in finding this Http sites";

    return sResult;

    }

    更新界面UI:

    void CMy5Dlg::OnBnClickedButtonHttp()

    {

    // TODO: 在此添加控件通知处理程序代码

    UpdateData(TRUE);

    m_editResult=L"";

    m_editResult=m_editResult+m_WinInetClass.ConnectHttp(m_url);

    UpdateData(FALSE);

    }

    八、附录

    1.vs的快捷键

    f9

    设置断点

    f5

    编译

    ctrl+f5

    运行

    ctrl+k+c

    注释一行

    ctrl+k+u

    反注释一行

    ctrl+h

    快速替换

    ctrl+]

    括号匹配

    ctrl+shift+]

    选中括号匹配中的代码

    ctrl+c,ctrl+x

    可以是行操作,不用选中

    ctrl+l

    删除一行

    ctrl+tab

    子窗口切换

    alt+右箭头

    自动补全、方法提示

    ctrl+k

    添加书签

    shift+f2

    到下一个书签

    f2

    到上一个书签

    选中代码中的内容,f1

    在MSDN中查找对应的文档

    crl+a,ctrl+k+f

    格式化代码

    选中代码中的内容,f12

    转到定义

    alt+鼠标向下拖动

    编辑列

  • 相关阅读:
    Java加密AES算法及spring中应用
    IO流理解方式小结
    Spring CommonsMultipartResolver上传文件小结
    SpringMvc项目加载顺序及上下文小结
    Session学习小结
    MySql实现Oracle的row_number()over(partition by ... order by ...)
    Oracle存储过程小解
    mysql存储过程小解
    Java final关键字
    linux 同步 rsync的使用——远程服务器同步配置
  • 原文地址:https://www.cnblogs.com/guomc/p/11179373.html
Copyright © 2011-2022 走看看