孙鑫VC++笔记(六)

来源:互联网 发布:数据库查询分析器 编辑:程序博客网 时间:2024/05/01 12:00
一、菜单
1.菜单响应
添加菜单IDM_TEST---类试图中选中该ID的COMMAND---添加函数即可
2.菜单命令
CMenuApp和CMenuDoc类不是由CWnd派生而来,所以没有MessageBox函数,可以用::MessageBox或者AfxMessageBox。
响应菜单命令顺序:视图类---文档类---框架类---应用程序类
删除函数在classview中直接删除比较方便
3.消息分类
标准消息:除了WM_COMMAND外所有WM开头的消息
命令消息:以WM_COMMAND呈现的来自菜单、加速键和工具栏按钮的消息(MFC中用菜单项标识ID区分,  在SDK中通过消息参数wParam区分)
通知消息:控件产生的消息,以向父窗口或对话框通知事件
注:从CWnd派生的类可以接收所有消息,从CCmdTarget派生的类只能接收命令消息和通知消息
4.添加标记菜单
GetMenu()------获得指向菜单栏的指针
GetSubMenu(nPos)----获得菜单栏的某一列(由nPos决定)
CheckMenuItem()----添加或移除标记
注:CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED)  其中 0 与MF_POSITION保持一致,根据位置访问
       CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_UNCHECKED) 其中ID与MF_BYCOMMAND保持一致,由菜单命令访问
Example:
MainFrame中的OnCreate函数中
    GetMenu()->GetSubMenu(0)->CheckMenuItem(0, MF_POSITION | MF_CHECKED);
5.默认菜单项
    SetDefaltItem(ID_FILE_NEW, FALSE)---FALSE表明第一个参数是菜单项标识
    SetDefaltItem(1, TRUE)---TRUE表明第一个参数是位置索引
说明: 分隔栏在子菜单中是占据索引位置的
           一个子菜单中只能由一个默认菜单项
6.图形标记菜单
    CBitmap  m_bitmap;  //成员变量而不能是局部变量
    m_bitmap.LoadBitmap(IDB_BITMAP1);
    SetMenuItemBitmaps(0, MF_BYPOSITION, &m_bitmap, &m_bitmap);
补充: 获得默认图形大小
    CString str;
    str.Format("x = %d, y = %d", GetSystemMetries(SM_CXMENUCHECK), GetSystemMetries(SM_CYMENUCHECK));
    MessagxBox(str);
7.禁用菜单项
    GetMenu()->GetSubMenu(0)->EnableMenuItem(0, MF_POSITION | MF_DISABLED | MF_GRAYED);
注:更改菜单项状态,需要在CMainFrame构造函数中 m_bAutoMenuEnable = FALSE;
8.移除和加载菜单
移除当前菜单:
    SetMenu(NULL);  
 加载菜单:
    CMenu menu;   
    menu.LoadMenu(IDR_MAINFRAME);
    SetMenu(&menu);
    menu.Detach();  无此函数则需要把menu定义为成员变量   此函数作用是分离菜单句柄和菜单对象
9.MFC命令更新
    类向导---菜单ID---ON_UPDATE_COMMAND_UI添加响应函数
把工具栏的一个工具按钮和某个菜单项关联,只要保持他们的ID一致就可以了
CCmdUI的成员变量
pCmdUI->Enable();
pCmdUI->m_nID  菜单项标识(跟工具栏一致)
pCmdUI->m_nIndex 菜单项索引(跟工具栏单独)
10.快捷菜单
1.添加控件
project--->Add to project--->Components and controls--->VC++controls--->pop-up menu
2.添加WM_RBUTTONDOWN响应函数(CMenuView)
    CMenu menu;
    menu.LoadMenu(IDR_MENU1);
    ClientToScreen(&point); 或者 CPoint Point;  GetCursorPos(&Point);
    menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
注:在view和frame同时添加pop响应函数时,只有在view类中响应。
如果要在frame类中响应,需要先去掉view中响应函数(必须的),然后TrackPopupMenu最后一个参数改为GetParent()

11.动态菜单操纵(code)
添加
GetMenu()->AppendMenu(MF_POPUP, (UINT)menu.m_hMenu,“Test”);  末尾添加顶层菜单
menu.AppendMenu(MF_STRING, 1201,“Test1”); 添加子菜单
插入
GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,“Test”); 插入顶层菜单
GetMenu()->GetSubMenu(0)->InsertMenu(3,MF_BYPOSITION | MF_STRING, 1201,“TEST”);插入子菜单
GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_NEW, MF_STRING | MF_COMMAND,1201,“Test”);插入子菜单
删除
GetMenu()->DeleteMenu(2,MF_POSITION);
GetMenu()->GetSubMenu(0)->DeleteMenu(ID_FILE_NEW,MF_COMMAND); 或者1203
命令响应
在resources.h中定义响应菜单的ID,然后同MFC命令响应一样。现在对应头文件中afx_msg 然后在对应cpp文件中ON_COMMAND
最后添加响应函数即可。

说明:
    主要看调用对象从而决定在哪里操作菜单
    插入的位置是由插入后的元素决定,删除时是元素本身
    位置索引和MF_BYPOSITION对应,菜单项ID(包括ID和ID数)和MF_COMMAND对应

电话本程序:
1.响应键盘消息,在视类中添加WM_CHAR响应消息函数
2.MainFrame类中OnCreate函数是创建并显示窗口,所以对其的修改会立即生效。但是视类实在之后做的修改,所以要立即显示修改需要重绘
    DrawMenuBar()函数,并且需要框架类去实现。GetParent()->DrawMenuBar();
3.显示输出字符就需要一个成员变量去保存输入的数据m_strLine
    m_strLine.Empty();  清除上次输入,否则是从上次输入的后边开始
    Invalidate();    重绘并清除背景,否则实在上次输入的上边开始
4.创建子菜单
    menu.AppendMenu(MF_STRING, IDM_PHONE + Index, m_strLine.Left(m_strLine.Find(" ")));
5.CStringArray 集合类,作用类似于数组,可以动态增加或删除元素
    重要成员函数:
    GetAt(n)取得第n-1个元素的值
    GetSzie()获得元素个数
    Add()增加元素