孙鑫VC++深入详解:Lesson8 Part2---属性表单
2013-07-09 19:58
501 查看
1. Insert-->Dialog 插入IDD_LARGER...Page....3个 Style:Child, Disable
注意:修改Page的语言属性(不是字体)必须只能在Resource View中选Dialog单独选IDD_PROP1的右键属性,而不是在资源编辑器中选择右键的属性(那里只能选择字体).
2 分别给三个属性表单页Page1,Page2,Page3 用ClassWizard创建3个类,CPage1,CPage2,CPage3
3. 属性表单页CPropertyPage实际是要附加在CPropertySheet上才能显示
(1)CPropertyPage必须加载到CPropertySheet
(2) Sheet调用DoModal去创建表单sheet,这样才能把3个page显示
4 Insert--New class 创建一个新的基于CPropertySheet的类,用来操作3个Page,这个新类叫CPropSheet
5. 向导模式 SetWizardMode
6 SetWizardButtons 解决sheet上buttons显示的问题:
要在CPage1中覆盖基类的OnSetActive() 的实现代码中解决Sheet的WizardButtons问题,为什么不直接在CPropSheet中解决?
7 在View视中定义一个CPropSheet propSheet变量,用propSheet来操作Page1,Page2,Page3
//---------CPage1类的实现
头文件Page1.h
类成员实现:Page1.cpp
//------CPage2类的实现
头文件Page2.h
类的实现 Page2.cpp
//---CPage3 类的实现
头文件Page3.h
类的实现:Page3.cpp
//------类CPropSheet : public CPropertySheet 的实现
头文件
实现:
在程序的View视中实现输出:
头文件CPropView.h
实现:
//---
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/25/8797572032ec07ecbba4e040c0c0b12e)
//---
//---
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/25/d373d0868b823a09832e166c7ea72084)
总体感觉VC做这种向导属性表单非常繁琐....远不如Delphi的结构清晰.
注意:修改Page的语言属性(不是字体)必须只能在Resource View中选Dialog单独选IDD_PROP1的右键属性,而不是在资源编辑器中选择右键的属性(那里只能选择字体).
2 分别给三个属性表单页Page1,Page2,Page3 用ClassWizard创建3个类,CPage1,CPage2,CPage3
3. 属性表单页CPropertyPage实际是要附加在CPropertySheet上才能显示
(1)CPropertyPage必须加载到CPropertySheet
(2) Sheet调用DoModal去创建表单sheet,这样才能把3个page显示
4 Insert--New class 创建一个新的基于CPropertySheet的类,用来操作3个Page,这个新类叫CPropSheet
5. 向导模式 SetWizardMode
6 SetWizardButtons 解决sheet上buttons显示的问题:
要在CPage1中覆盖基类的OnSetActive() 的实现代码中解决Sheet的WizardButtons问题,为什么不直接在CPropSheet中解决?
7 在View视中定义一个CPropSheet propSheet变量,用propSheet来操作Page1,Page2,Page3
//---------CPage1类的实现
头文件Page1.h
#if !defined(AFX_PAGE1_H__2430209C_79B9_43D5_AB82_3ADD0B3D1AA8__INCLUDED_) #define AFX_PAGE1_H__2430209C_79B9_43D5_AB82_3ADD0B3D1AA8__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Page1.h : header file // ///////////////////////////////////////////////////////////////////////////// // CPage1 dialog class CPage1 : public CPropertyPage { DECLARE_DYNCREATE(CPage1) // Construction public: CPage1(); ~CPage1(); // Dialog Data //{{AFX_DATA(CPage1) enum { IDD = IDD_PROP1 }; int m_occupation; CString m_workAddr; //}}AFX_DATA // Overrides // ClassWizard generate virtual function overrides //{{AFX_VIRTUAL(CPage1) public: virtual BOOL OnSetActive(); virtual LRESULT OnWizardNext(); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CPage1) virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_PAGE1_H__2430209C_79B9_43D5_AB82_3ADD0B3D1AA8__INCLUDED_)
类成员实现:Page1.cpp
// Page1.cpp : implementation file // #include "stdafx.h" #include "prop.h" #include "Page1.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPage1 property page IMPLEMENT_DYNCREATE(CPage1, CPropertyPage) CPage1::CPage1() : CPropertyPage(CPage1::IDD) { //{{AFX_DATA_INIT(CPage1) m_occupation = -1; m_workAddr = _T(""); //}}AFX_DATA_INIT } CPage1::~CPage1() { } void CPage1::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPage1) DDX_Radio(pDX, IDC_RADIO1, m_occupation); DDX_LBString(pDX, IDC_LIST1, m_workAddr); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPage1, CPropertyPage) //{{AFX_MSG_MAP(CPage1) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPage1 message handlers // 覆盖基类的虚函数:设置sheet上哪个WiZard button 要显示 BOOL CPage1::OnSetActive() { // TODO: Add your specialized code here and/or call the base class ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT); return CPropertyPage::OnSetActive(); } // 覆盖基类的虚函数:在点击"next"按钮前,获得m_occupation的值 LRESULT CPage1::OnWizardNext() { // TODO: Add your specialized code here and/or call the base class UpdateData(true); if(m_occupation==-1) { MessageBox("请选择你的职业"); return -1; } if(m_workAddr=="") { MessageBox("请选择你的工作地点"); return -1; } return CPropertyPage::OnWizardNext(); } // 这个消息是CPage在显示之前发送的. BOOL CPage1::OnInitDialog() { CPropertyPage::OnInitDialog(); // TODO: Add extra initialization here ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("上海"); ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("北京"); ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("天津"); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
//------CPage2类的实现
头文件Page2.h
#if !defined(AFX_PAGE2_H__58B69281_180E_4981_A868_2AED621B7D48__INCLUDED_) #define AFX_PAGE2_H__58B69281_180E_4981_A868_2AED621B7D48__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Page2.h : header file // ///////////////////////////////////////////////////////////////////////////// // CPage2 dialog class CPage2 : public CPropertyPage { DECLARE_DYNCREATE(CPage2) // Construction public: CPage2(); ~CPage2(); // Dialog Data //{{AFX_DATA(CPage2) enum { IDD = IDD_PROP2 }; BOOL m_football; BOOL m_basketball; BOOL m_volleyball; BOOL m_swim; //}}AFX_DATA // Overrides // ClassWizard generate virtual function overrides //{{AFX_VIRTUAL(CPage2) public: virtual BOOL OnSetActive(); virtual LRESULT OnWizardNext(); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CPage2) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_PAGE2_H__58B69281_180E_4981_A868_2AED621B7D48__INCLUDED_)
类的实现 Page2.cpp
// Page2.cpp : implementation file // #include "stdafx.h" #include "prop.h" #include "Page2.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPage2 property page IMPLEMENT_DYNCREATE(CPage2, CPropertyPage) CPage2::CPage2() : CPropertyPage(CPage2::IDD) { //{{AFX_DATA_INIT(CPage2) m_football = FALSE; m_basketball = FALSE; m_volleyball = FALSE; m_swim = FALSE; //}}AFX_DATA_INIT } CPage2::~CPage2() { } void CPage2::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPage2) DDX_Check(pDX, IDC_CHECK1, m_football); DDX_Check(pDX, IDC_CHECK2, m_basketball); DDX_Check(pDX, IDC_CHECK3, m_volleyball); DDX_Check(pDX, IDC_CHECK4, m_swim); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPage2, CPropertyPage) //{{AFX_MSG_MAP(CPage2) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPage2 message handlers BOOL CPage2::OnSetActive() { // TODO: Add your specialized code here and/or call the base class ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT); return CPropertyPage::OnSetActive(); } LRESULT CPage2::OnWizardNext() { // TODO: Add your specialized code here and/or call the base class UpdateData(true);// 取得控件关联的值 if(m_football||m_basketball||m_volleyball||m_swim) { return CPropertyPage::OnWizardNext(); } else { MessageBox("请选择你的兴趣爱好"); return -1; } }
//---CPage3 类的实现
头文件Page3.h
#if !defined(AFX_PAGE3_H__BFD081AC_E2AB_4685_A974_1FB0B946D8F7__INCLUDED_) #define AFX_PAGE3_H__BFD081AC_E2AB_4685_A974_1FB0B946D8F7__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Page3.h : header file // ///////////////////////////////////////////////////////////////////////////// // CPage3 dialog class CPage3 : public CPropertyPage { DECLARE_DYNCREATE(CPage3) // Construction public: CString m_strSalary; CPage3(); ~CPage3(); // Dialog Data //{{AFX_DATA(CPage3) enum { IDD = IDD_PROP3 }; // NOTE - ClassWizard will add data members here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_DATA // Overrides // ClassWizard generate virtual function overrides //{{AFX_VIRTUAL(CPage3) public: virtual BOOL OnSetActive(); virtual BOOL OnWizardFinish(); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CPage3) virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_PAGE3_H__BFD081AC_E2AB_4685_A974_1FB0B946D8F7__INCLUDED_)
类的实现:Page3.cpp
// Page3.cpp : implementation file // #include "stdafx.h" #include "prop.h" #include "Page3.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPage3 property page IMPLEMENT_DYNCREATE(CPage3, CPropertyPage) CPage3::CPage3() : CPropertyPage(CPage3::IDD) { //{{AFX_DATA_INIT(CPage3) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } CPage3::~CPage3() { } void CPage3::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPage3) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPage3, CPropertyPage) //{{AFX_MSG_MAP(CPage3) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPage3 message handlers BOOL CPage3::OnSetActive() { // TODO: Add your specialized code here and/or call the base class ((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT| PSWIZB_FINISH); return CPropertyPage::OnSetActive(); } BOOL CPage3::OnInitDialog() { CPropertyPage::OnInitDialog(); // TODO: Add extra initialization here ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("1000元以下"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("1000--2000元"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("2000--3000元"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("3000元以上"); ((CComboBox*)GetDlgItem(IDC_COMBO1))->SetCurSel(0); //设置默认选项 1000元以下 return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } // 在点击 finish按钮时,获得用户薪资的选择 BOOL CPage3::OnWizardFinish() { // TODO: Add your specialized code here and/or call the base class int index; index = ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel(); ((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strSalary); return CPropertyPage::OnWizardFinish(); }
//------类CPropSheet : public CPropertySheet 的实现
头文件
#if !defined(AFX_PROPSHEET_H__1B859A0A_9314_4803_A031_F70427A6925A__INCLUDED_) #define AFX_PROPSHEET_H__1B859A0A_9314_4803_A031_F70427A6925A__INCLUDED_ #include "Page2.h" // Added by ClassView #include "Page1.h" // Added by ClassView #include "Page3.h" // Added by ClassView #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // PropSheet.h : header file // ///////////////////////////////////////////////////////////////////////////// // CPropSheet class CPropSheet : public CPropertySheet { DECLARE_DYNAMIC(CPropSheet) // Construction public: CPropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0); CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CPropSheet) //}}AFX_VIRTUAL // Implementation public: CPage3 m_Page3; CPage2 m_Page2; CPage1 m_Page1; virtual ~CPropSheet(); // Generated message map functions protected: //{{AFX_MSG(CPropSheet) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_PROPSHEET_H__1B859A0A_9314_4803_A031_F70427A6925A__INCLUDED_)
实现:
// PropSheet.cpp : implementation file // #include "stdafx.h" #include "Prop.h" #include "PropSheet.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPropSheet IMPLEMENT_DYNAMIC(CPropSheet, CPropertySheet) //在2个构造函数中加载page CPropSheet::CPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(nIDCaption, pParentWnd, iSelectPage) { // 加载page AddPage(&m_Page1); AddPage(&m_Page2); AddPage(&m_Page3); // SetWizardMode(); // 这条语句的作于就是把page搞成向导模式 } CPropSheet::CPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) { // 加载page AddPage(&m_Page1); AddPage(&m_Page2); AddPage(&m_Page3); // SetWizardMode(); } CPropSheet::~CPropSheet() { } BEGIN_MESSAGE_MAP(CPropSheet, CPropertySheet) //{{AFX_MSG_MAP(CPropSheet) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPropSheet message handlers
在程序的View视中实现输出:
头文件CPropView.h
// PropView.h : interface of the CPropView class // ///////////////////////////////////////////////////////////////////////////// #if !defined(AFX_PROPVIEW_H__F5F57441_99E9_4B4C_9F3A_E41E7646095E__INCLUDED_) #define AFX_PROPVIEW_H__F5F57441_99E9_4B4C_9F3A_E41E7646095E__INCLUDED_ #include "Page1.h" // Added by ClassView #include "Page2.h" // Added by ClassView #include "Page3.h" // Added by ClassView #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CPropView : public CView { protected: // create from serialization only CPropView(); DECLARE_DYNCREATE(CPropView) // Attributes public: CPropDoc* GetDocument(); // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CPropView) public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: //}}AFX_VIRTUAL // Implementation public: virtual ~CPropView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // Generated message map functions protected: //{{AFX_MSG(CPropView) afx_msg void OnPropertysheet(); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: int m_iOccupation; CString m_strWorkAddr; BOOL bLike[4]; CString m_strSalary; }; #ifndef _DEBUG // debug version in PropView.cpp inline CPropDoc* CPropView::GetDocument() { return (CPropDoc*)m_pDocument; } #endif ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_PROPVIEW_H__F5F57441_99E9_4B4C_9F3A_E41E7646095E__INCLUDED_)
实现:
// PropView.cpp : implementation of the CPropView class // #include "stdafx.h" #include "Prop.h" #include "PropDoc.h" #include "PropView.h" #include "PropSheet.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPropView IMPLEMENT_DYNCREATE(CPropView, CView) BEGIN_MESSAGE_MAP(CPropView, CView) //{{AFX_MSG_MAP(CPropView) ON_COMMAND(IDM_PROPERTYSHEET, OnPropertysheet) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPropView construction/destruction CPropView::CPropView() { // TODO: add construction code here m_iOccupation=-1; m_strWorkAddr=""; memset(bLike,0,sizeof(bLike)); m_strSalary=""; } CPropView::~CPropView() { } BOOL CPropView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CPropView drawing void CPropView::OnDraw(CDC* pDC) { CPropDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CFont font; font.CreatePointFont(300,"华文楷体"); CFont *pOldPen; pOldPen = pDC->SelectObject(&font); CString strTemp; strTemp = "你的职业: "; switch(m_iOccupation) { case 0: strTemp+="程序员"; break; case 1: strTemp+="系统工程师"; break; case 2: strTemp+="项目经理"; break; default:break; } pDC->TextOut(0,0,strTemp); strTemp ="你的工作地点: "; strTemp +=m_strWorkAddr; TEXTMETRIC tm; pDC->GetTextMetrics(&tm); pDC->TextOut(0,tm.tmHeight,strTemp); strTemp = "你的兴趣爱好: "; if(bLike[0])strTemp +="足球"; if(bLike[1])strTemp +="篮球"; if(bLike[2])strTemp +="排球"; if(bLike[3])strTemp +="游泳"; pDC->TextOut(0,tm.tmHeight*2,strTemp); strTemp = "你的薪资水平: "; strTemp +=m_strSalary; pDC->TextOut(0,tm.tmHeight*3,strTemp); pDC->SelectObject(pOldPen); } ///////////////////////////////////////////////////////////////////////////// // CPropView diagnostics #ifdef _DEBUG void CPropView::AssertValid() const { CView::AssertValid(); } void CPropView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CPropDoc* CPropView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPropDoc))); return (CPropDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CPropView message handlers void CPropView::OnPropertysheet() { // TODO: Add your command handler code here CPropSheet propSheet("微信属性表单程序"); //创建一个CPropSheet对象 // 表单要显示,还必须调用domodal或者create propSheet.SetWizardMode(); //设置成向导模式 //创建一个模态的对话框 if(ID_WIZFINISH ==propSheet.DoModal()) { m_iOccupation = propSheet.m_Page1.m_occupation; m_strWorkAddr = propSheet.m_Page1.m_workAddr; bLike[0]= propSheet.m_Page2.m_football; bLike[1]= propSheet.m_Page2.m_basketball; bLike[2]= propSheet.m_Page2.m_volleyball; bLike[3]= propSheet.m_Page2.m_swim; m_strSalary = propSheet.m_Page3.m_strSalary; Invalidate(); } }
//---
//---
//---
总体感觉VC做这种向导属性表单非常繁琐....远不如Delphi的结构清晰.
相关文章推荐
- 孙鑫VC++深入详解:Lesson9 Part2---修改窗口光标,图表,背景
- 孙鑫VC++深入详解:Lesson5 Part2 路径层 CDC::BeginPath,BeginPath
- 孙鑫VC++深入详解:Lesson8 Part3---如何让对话框捕获WM_KEYDOWN消息?
- 孙鑫vc++ 8 对话框(2) 属性表单和向导的创建
- 孙鑫VC++深入详解:Lesson8 Part1---"逃跑"按钮的实现
- 孙鑫VC++深入详解:Lesson9 Part1---修改应用程序窗口
- 孙鑫VC++深入详解:Lesson5 Part4 屏幕字符串滚动输出,DrawText,SetTimer,WM_Timer消息
- 孙鑫VC++深入详解:Lesson9 Part4---工具栏编程
- 孙鑫VC++深入详解:Lesson6 Part3 ---创建右键弹出菜单 TrackPopupMenu
- 孙鑫VC++深入详解:Lesson7 Part3---对话框伸缩功能的实现
- 孙鑫VC++深入详解:Lesson9 Part7---在状态栏中显示鼠标的位置
- 孙鑫VC++深入详解:Lesson6 Part4 ---CMenu 类的应用:添加子菜单项AppendMenu,插入子菜单项InsertMenu,删除菜单DeleteMenu
- 孙鑫VC++深入详解:Lesson8 Part3---如何让对话框捕获WM_KEYDOWN消息?
- 孙鑫VC++深入详解:Lesson9 Part5---状态栏编程
- 孙鑫VC++深入详解:Lesson9 Part8---给程序加个启动画面
- 孙鑫VC++深入详解:Lesson5 Part1 文本插入符Caret,位图插入符,窗口重绘
- 孙鑫VC++深入详解:Lesson6 Part6--- 电话本示例程序 动态添加子菜单 框架类窗口截获命令消息
- 孙鑫VC++深入详解:Lesson3
- 孙鑫VC++深入详解:Lesson5 Part3 文字输入: 处理回车键,空格键,CFont的使用
- 孙鑫VC++深入详解:Lesson1