文章目录
- 记事本项目功能完善和开发
- 查找界面的记忆功能 、使用F3快捷键自动向下查找功能 的开发
- 单次替换的算法研究
- CFileDialog 构造函数详解 应用另存为时选择编码 (三种方案)
- vista 样式文件对话框 bVistaStyle 为TRUE时 1
- pch.h
- CApp NotePad.cpp 对编码的解析 以及对编码格式的转换
- CMainDlg.h
- CMainDlg.cpp
- 派生类 vista 样式文件对话框 bVistaStyle 为FALSE时 2
- CMainDlg.h
- CMainDlg.cpp
- CFileDialogXq.h
- CFileDialogXq.cpp
- 子对话框 3
- CMainDlg.h
- CMainDlg.cpp
- CFileDialogXq.h
- CFileDialogXq.cpp
- CFileDlg.h
- CFileDlg.cpp
- CTabCtrl类与分页模式开发
- CTabCtrl类简介
- CTabCtrl的风格
- 分页模式开发
- 演示向导模式的多页窗口开发
记事本项目功能完善和开发
查找界面的记忆功能 、使用F3快捷键自动向下查找功能 的开发
获取选择的文字
CString CMainDlg::GetSelText()
{CString str;m_edit.GetWindowText(str);int nStart, nEnd;m_edit.GetSel(nStart, nEnd);if(nEnd<=nStart)return CString();return str.Mid(nStart, nEnd - nStart);
}
向下查找
void CMainDlg::OnEditNext()
{if (m_sFind.IsEmpty())OnEditFind();else{CString sText;m_edit.GetWindowText(sText);if (m_sFind.GetLength() > 0)m_sFind = theApp.GetProfileString(_T("SETTINGS"), _T("Search"));CString str = m_sFind;if (!theApp.GetProfileInt(_T("SETTINGS"),_T("Mathcase"),0)){str.MakeLower();sText.MakeLower(); }int nStart, nEnd;m_edit.GetSel(nStart, nEnd);int n = sText.Find(str, nEnd);if (n < 0){AfxMessageBox(_T("找不到 ") + str);return;}m_edit.SetSel(n, n + str.GetLength());m_edit.GetFocus();}
}
单次替换的算法研究
查找替换功能
LRESULT CMainDlg::OnFindReplace(WPARAM wParam, LPARAM lParam)
{if (m_pFRDlg->IsTerminating()) return false;if (m_pFRDlg->ReplaceAll()){ReplaceAll();}if (m_pFRDlg->ReplaceCurrent()){ReplaceCurrent();}if (m_pFRDlg->FindNext()){theApp.WriteProfileString(_T("SETTINGS"), _T("SEARCH"), m_pFRDlg->GetFindString());theApp.WriteProfileInt(_T("SETTINGS"), _T("MatchCase"), m_pFRDlg->MatchCase());theApp.WriteProfileInt(_T("SETTINGS"), _T("MatchWholeWord"), m_pFRDlg->MatchWholeWord());theApp.WriteProfileInt(_T("SETTINGS"), _T("SearchDown"), m_pFRDlg->SearchDown());if (m_pFRDlg->SearchDown())SerachDown();elseSerachUp();}return LRESULT();
}
向下
void CMainDlg::SerachDown()
{if (!IsWindow(m_pFRDlg->GetSafeHwnd()))return;CString sText;m_edit.GetWindowText(sText);CString str = m_pFRDlg->GetFindString();int nStart, nEnd;m_edit.GetSel(nStart, nEnd);int n = sText.Find(str, nEnd);if (n<0){AfxMessageBox(_T("找不到 ") + str);return;}m_edit.SetSel(n, n + str.GetLength());m_edit.GetFocus();
}
向上
void CMainDlg::SerachUp()
{if (!IsWindow(m_pFRDlg->GetSafeHwnd()))return;CString sText;m_edit.GetWindowText(sText);CString str = m_pFRDlg->GetFindString();if (!m_pFRDlg->MatchCase()) //区分大小写, 设置之后只能查找小写{str.MakeLower();sText.MakeLower();}int nStart, nEnd;m_edit.GetSel(nStart, nEnd);str.MakeReverse();sText.MakeReverse();int nLen = sText.GetLength();int n = sText.Find(str, nLen-nStart);if (n < 0){AfxMessageBox(_T("找不到 ") + str);return;}nEnd = nLen - n;nStart = nEnd - str.GetLength();m_edit.SetSel(nStart, nEnd);m_edit.GetFocus();
}
不区分大小写的
int CMainDlg::FindNoCase(const CString& str, TCHAR s1, int i)
{TCHAR s2 = s1 ^ 32;int nLen = str.GetLength();while (++i < nLen){TCHAR s = str[i];if (s == s1 || s == s2)return i;}return -1;
}
替换当前选中
void CMainDlg::ReplaceCurrent()
{CString sText, sOld, sNew;sOld = m_pFRDlg->GetFindString();sNew = m_pFRDlg->GetReplaceString();m_edit.GetWindowText(sText);BOOL bMatchCase = m_pFRDlg->MatchCase();int nStart, nEnd;m_edit.GetSel(nStart, nEnd);CString str = sText.Mid(nStart, nEnd - nStart);if (str.CompareNoCase(sOld))nStart += nEnd;else{m_edit.ReplaceSel(sNew);m_edit.GetWindowText(sText);nStart += sNew.GetLength();}if (!m_pFRDlg->MatchCase()){sText.MakeLower();sOld.MakeLower();}nStart = sText.Find(sOld, nStart);//因为替换过了sOld = m_pFRDlg->GetFindString();if (nStart < 0){AfxMessageBox(_T("没有找到 “") + sOld + _T("”"));}elsem_edit.SetSel(nStart, nStart + sOld.GetLength());
}
替换全部
void CMainDlg::ReplaceAll()
{CString sText, sOld, sNew;sOld = m_pFRDlg->GetFindString();sNew = m_pFRDlg->GetReplaceString();m_edit.GetWindowText(sText);BOOL bMathCase = m_pFRDlg->MatchCase(); //确定用户是否希望完全匹配搜索字符串的大小写 成功返回非零int nStart, nEnd;m_edit.GetSel(nStart, nEnd);if (bMathCase){sText.Replace(sOld, sNew);}else{ReplaceNoCase(sText, sOld, sNew);}m_edit.SetWindowText(sText);m_edit.SetSel(nStart, nEnd);
}
打开查找编辑框需要加载的
void CMainDlg::OnEditFind()
{if (IsWindow(m_pFRDlg->GetSafeHwnd()))m_pFRDlg->DestroyWindow();m_pFRDlg = new CFindReplaceDialog;CString str = GetSelText();if (str.IsEmpty())str = theApp.GetProfileString(_T("SETTINGS"), _T("SEARCH"));elsetheApp.WriteProfileString(_T("SETTINGS"), _T("SEARCH"),str);DWORD dw = 0;if (theApp.GetProfileInt(_T("SETTINGS"), _T("MatchCase"), 0))dw |= FR_MATCHCASE;if (theApp.GetProfileInt(_T("SETTINGS"), _T("MatchWholeWord"), 0))dw |= FR_WHOLEWORD;if (theApp.GetProfileInt(_T("SETTINGS"), _T("SearchDown"), 0))dw |= FR_DOWN;if (str.GetLength() > 0)m_sFind = str;m_pFRDlg->Create(TRUE,str,NULL,dw);}
CFileDialog 构造函数详解 应用另存为时选择编码 (三种方案)
CFileDialog 构造函数详解
explicit CFileDialog(BOOL bOpenFileDialog, //指定是否为打开文件对话框//该参数为TRUE,创建一个打开文件对话框;如果该参数为 FALSE,则创建一个保存文件对话框LPCTSTR lpszDefExt = NULL, //指定默认文件扩展名。如果用户没有指定文件扩展名,则自动添加该扩展名LPCTSTR lpszFileName = NULL, //指定默认文件名。如果用户没有指定文件名,则将显示此默认文件名。DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,//用于指定文件对话框的标志。可以使用位操作符 | 来组合多个标志LPCTSTR lpszFilter = NULL, //指定文件过滤器。文件过滤器用于限制用户可以选择的文件类型CWnd* pParentWnd = NULL,//指定文件对话框的父窗口。如果为 NULL,文件对话框将没有父窗口。DWORD dwSize = 0, //指定文件对话框的大小。如果为 0,则使用默认大小BOOL bVistaStyle = TRUE//用于指定是否在 Windows Vista 或更高版本的操作系统上使用 Vista 风格的文件对话框。如果该参数为 TRUE,则文件对话框将使用 Vista 风格;如果该参数为 FALSE,则文件对话框将使用旧版样式
);
vista 样式文件对话框 bVistaStyle 为TRUE时 1
pch.h
enum EType
{T_ANSI = 0,T_U16LE,T_U16BE,T_U8,T_U8BOM,
};
CApp NotePad.cpp 对编码的解析 以及对编码格式的转换
EType CApp::ParseText(CEdit& edit, LPSTR p)
{wchar_t* q = nullptr;switch (*(WORD*)p){case 0xFFFE:theApp.ConvertBig(p);edit.SetWindowText((LPCWSTR)(p + 2));return T_U16BE;case 0xFEFF:edit.SetWindowText((LPCWSTR)(p + 2));delete[]q;return T_U16LE;case 0xBBEF:if (p[2] == (char)0xBF){q = theApp.UTF8ToUnicode(p + 3);edit.SetWindowText(q);delete[]q;return T_U8BOM;}}if (theApp.CheckUtf8(p)){q = theApp.UTF8ToUnicode(p);edit.SetWindowText(q);delete[]q;return T_U8;}q = ANSIToUnicode(p);edit.SetWindowText(q);//ANSIdelete[]q;return T_ANSI;}
bool CApp::CheckUtf8(LPCSTR p){auto q = p;while (*p){BYTE c = *p; int n = 0;while ((c & 0x80) == 0x80)++n, c <<= 1;if (n == 1 || n > 4)return false;++p;while (--n > 0) {c = *p++;if (c >> 6 != 2)//00000010return false; }}return true;
}
void CApp::ConvertBig(LPSTR p)
{while (*(WORD*)p){*p = *p ^ p[1];p[1] = *p ^ p[1];*p = *p ^ p[1];p += 2;}
}
wchar_t* CApp::UTF8ToUnicode(const char* str)
{int n = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);auto p = new wchar_t[n + 1];n = MultiByteToWideChar(CP_UTF8, 0, str, -1, p, n);p[n] = 0;return p;
}
wchar_t* CApp::ANSIToUnicode(const char* str)
{int n = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);auto p = new wchar_t[n + 1];MultiByteToWideChar(CP_ACP, 0, str, -1, p, n);return p;
}
char* CApp::UnicodeToANSI(const wchar_t* str)
{int n = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0,NULL,NULL);auto p = new char[n + 1];n= WideCharToMultiByte(CP_ACP, 0, str, -1, p, n,NULL,NULL);p[n] = 0;return p;
}char* CApp::UnicodeToUTF8(const wchar_t* str)
{int n = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);auto p = new char[n + 1];n = WideCharToMultiByte(CP_UTF8, 0, str, -1, p, n, NULL, NULL);return p;
}
CMainDlg.h
LPCTSTR m_szFilter = _T("文本文件 (*.txt)|*.txt|配置文件 (*.ini;*.inf)|*.ini;*.inf|")_T("代码文件(*.h;*.c;*.cpp)|*.h;*.c;*.cpp|所有文件(*.*)|*.*||");
CString m_sFile; //isEmpty代表没有关联(无标题)
EType m_eType{ T_U8 };
CMainDlg.cpp
void CMainDlg::OnFileSaveAs()
{enum { IDC_COMBO = 888 };CFileDialog dlg(FALSE,_T("txt"), NULL,OFN_OVERWRITEPROMPT,m_szFilter);dlg.AddComboBox(IDC_COMBO);dlg.AddControlItem(IDC_COMBO, 0, _T("ANSI"));dlg.AddControlItem(IDC_COMBO, 1, _T("Utf-16 LE"));dlg.AddControlItem(IDC_COMBO, 2, _T("Utf-16 BE"));dlg.AddControlItem(IDC_COMBO, 3, _T("Utf-8"));dlg.AddControlItem(IDC_COMBO, 4, _T("带Bom头的Utf-8"));dlg.SetSelectedControlItem(IDC_COMBO, m_eType);if (IDCANCEL == dlg.DoModal())return;dlg.GetSelectedControlItem(IDC_COMBO, (DWORD&)m_eType);m_sFile =dlg.GetPathName();OnFileSave();
}
派生类 vista 样式文件对话框 bVistaStyle 为FALSE时 2
CMainDlg.h
LPCTSTR m_szFilter = _T("文本文件 (*.txt)|*.txt|配置文件 (*.ini;*.inf)|*.ini;*.inf|")_T("代码文件(*.h;*.c;*.cpp)|*.h;*.c;*.cpp|所有文件(*.*)|*.*||");
CString m_sFile; //isEmpty代表没有关联(无标题)
CMainDlg.cpp
void CMainDlg::OnFileSaveAs()
{enum { IDC_COMBO = 888 };CFileDialogXq dlg(FALSE,_T("txt"), NULL,OFN_OVERWRITEPROMPT,m_szFilter);if (IDCANCEL == dlg.DoModal())return;m_sFile =dlg.GetPathName();OnFileSave();
}
CFileDialogXq.h
class CFileDialogXq : public CFileDialog{DECLARE_DYNAMIC(CFileDialogXq)CComboBox m_combo; //派生类 //CFileDlg m_dlg;
public:CFileDialogXq(BOOL bOpenFileDialog, // 对于 FileOpen 为 TRUE,对于 FileSaveAs 为 FALSELPCTSTR lpszDefExt = nullptr, LPCTSTR lpszFileName = nullptr,DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,LPCTSTR lpszFilter = nullptr, CWnd* pParentWnd = nullptr);virtual ~CFileDialogXq();
protected:DECLARE_MESSAGE_MAP()
public: virtual BOOL OnInitDialog();
};
CFileDialogXq.cpp
#include "pch.h"
#include "NotePad.h"
#include "CFileDialogXq.h"// CFileDialogXq
IMPLEMENT_DYNAMIC(CFileDialogXq, CFileDialog)CFileDialogXq::CFileDialogXq(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, 0, FALSE) 构造函数的一个参数
{}
CWnd* FindDlgItem(CWnd* p, int nID) //遍历
{p = p->GetWindow(GW_HWNDFIRST);// 兄弟的第一个while (p){CString str;p->GetWindowText(str);int n = p->GetDlgCtrlID();if (n == nID)return p; //查找到要找到控件p = p->GetWindow(GW_HWNDNEXT);}return nullptr;
}
BOOL CFileDialogXq::OnInitDialog(){
CWnd* pStatic = FindDlgItem(this, 0x441);if (!IsWindow(pStatic->GetSafeHwnd()))return FALSE;CRect rect;pStatic->GetWindowRect(rect);auto p = GetParent();p->ScreenToClient(rect);rect.OffsetRect(0, rect.Height());m_combo.Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, rect, p, 990);m_combo.AddString(_T("ANSI"));m_combo.AddString(_T("UTF16 LE"));m_combo.AddString(_T("UTF16 BE"));m_combo.AddString(_T("UTF8"));m_combo.AddString(_T("UTF8 BOM"));m_combo.SetFont(p->GetFont());m_combo.SetCurSel(0);
}
子对话框 3
CMainDlg.h
LPCTSTR m_szFilter = _T("文本文件 (*.txt)|*.txt|配置文件 (*.ini;*.inf)|*.ini;*.inf|")_T("代码文件(*.h;*.c;*.cpp)|*.h;*.c;*.cpp|所有文件(*.*)|*.*||");
CString m_sFile; //isEmpty代表没有关联(无标题)
CMainDlg.cpp
void CMainDlg::OnFileSaveAs()
{enum { IDC_COMBO = 888 };CFileDialogXq dlg(FALSE,_T("txt"), NULL,OFN_OVERWRITEPROMPT,m_szFilter);if (IDCANCEL == dlg.DoModal())return;m_sFile =dlg.GetPathName();OnFileSave();
}
CFileDialogXq.h
#include "CFileDlg.h"
class CFileDialogXq : public CFileDialog{DECLARE_DYNAMIC(CFileDialogXq)//派生类 CComboBox m_combo; CFileDlg m_dlg;
public:CFileDialogXq(BOOL bOpenFileDialog, // 对于 FileOpen 为 TRUE,对于 FileSaveAs 为 FALSELPCTSTR lpszDefExt = nullptr, LPCTSTR lpszFileName = nullptr,DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,LPCTSTR lpszFilter = nullptr, CWnd* pParentWnd = nullptr);virtual ~CFileDialogXq();public: virtual BOOL OnInitDialog();
};
CFileDialogXq.cpp
#include "pch.h"
#include "NotePad.h"
#include "CFileDialogXq.h"// CFileDialogXq
IMPLEMENT_DYNAMIC(CFileDialogXq, CFileDialog)CFileDialogXq::CFileDialogXq(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, 0, FALSE) 构造函数的一个参数
{}
CWnd* FindDlgItem(CWnd* p, int nID) //遍历
{p = p->GetWindow(GW_HWNDFIRST);// 兄弟的第一个while (p){CString str;p->GetWindowText(str);int n = p->GetDlgCtrlID();if (n == nID)return p; //查找到要找到控件p = p->GetWindow(GW_HWNDNEXT);}return nullptr;
}
BOOL CFileDialogXq::OnInitDialog(){
CFileDialog::OnInitDialog();CWnd* pStatic = FindDlgItem(this, 0x441);if (!IsWindow(pStatic->GetSafeHwnd()))return FALSE;CRect rect,rc;pStatic->GetWindowRect(rect);auto p = GetParent();p->ScreenToClient(rect);p->GetClientRect(rc);rc.left = rect.left;rc.top = rect.bottom + 8;rc.bottom += 32;m_dlg.Create(IDD_FILE_DLG, p);m_dlg.MoveWindow(rc);m_dlg.ShowWindow(SW_SHOW);GetWindowRect(rect);rect.bottom += 32;SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);rect.OffsetRect(0, rect.Height());return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}
CFileDlg.h
#include "afxdialogex.h"
class CFileDlg : public CDialogEx{DECLARE_DYNAMIC(CFileDlg)
public:CFileDlg(CWnd* pParent = nullptr); // 标准构造函数virtual ~CFileDlg();#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_FILE_DLG };// 对话框数据
#endif
public:CComboBox m_combo;virtual BOOL OnInitDialog();afx_msg void OnSelchangeCode();
};
CFileDlg.cpp
CFileDlg::CFileDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_FILE_DLG, pParent)
{}
void CFileDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_CODE, m_combo);
}
void CFileDlg::OnSelchangeCode()
{m_combo.GetCurSel();
}
BOOL CFileDlg::OnInitDialog()
{CDialogEx::OnInitDialog();m_combo.AddString(_T("ANSI"));m_combo.AddString(_T("UTF16 LE"));m_combo.AddString(_T("UTF16 BE"));m_combo.AddString(_T("UTF8"));m_combo.AddString(_T("UTF8 BOM"));m_combo.SetFont(GetFont());m_combo.SetCurSel(0);return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}
CTabCtrl类与分页模式开发
CTabCtrl类简介
CTabCtrl 用于创建和管理标签控件(Tab Control),也称为选项卡控件。
class CTabCtrl : public CWnd
{
public:CTabCtrl();// Generic creatorvirtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);// Generic creator allowing extended style bits
virtual BOOL CreateEx(DWORD dwExStyle,DWORD dwStyle,const RECT& rect,CWnd*pParentWnd,UINT nID);// AttributesCImageList* GetImageList() const; //获取图像列表。CImageList* SetImageList(_In_ CImageList* pImageList);//设置图像列表// Retrieves the number of tabs in the tab control.int GetItemCount() const;// Retrieves information about the specified tab in the tab control.BOOL GetItem(_In_ int nItem, _Out_ TCITEM* pTabCtrlItem) const;// Sets some or all attributes of the specified tab in the tab control.BOOL SetItem(_In_ int nItem, _In_ TCITEM* pTabCtrlItem);// Sets the number of bytes per tab reserved for application-defined data in the tab BOOL GetItemRect(_In_ int nItem, _Out_ LPRECT lpRect) const;// Determines the currently selected tab in the tab control.int GetCurSel() const; 获取当前选中// Selects the specified tab in the tab control.int SetCurSel(_In_ int nItem); 设置当前选中// Sets the focus to the specified tab in the tab control.void SetCurFocus(_In_ int nItem);// Sets the width and height of tabs in a fixed-width or owner-drawn tab control.CSize SetItemSize(_In_ CSize size);// Sets the amount of space (padding) around each tab's icon and label in the tab control.void SetPadding(_In_ CSize size);// Retrieves the current number of rows of tabs in the tab control.int GetRowCount() const;// Retrieves the ToolTip control associated with the tab control.CToolTipCtrl* GetToolTips() const;// Assigns a ToolTip control to the tab control.void SetToolTips(_In_ CToolTipCtrl* pWndTip);// Returns the index of the tab that has the focus in a tab control.int GetCurFocus() const;// Sets the minimum width of tabs in the tab control.int SetMinTabWidth(_In_ int cx);// Retrieves the extended styles that are currently in use for the tab control.DWORD GetExtendedStyle() const;// Sets the extended styles that the tab control will use.DWORD SetExtendedStyle(_In_ DWORD dwNewStyle, _In_ DWORD dwExMask = 0);// Retrieves state of a tab in the tab control.DWORD GetItemState(_In_ int nItem, _In_ DWORD dwMask) const;// Sets state for a tab in the tab control.BOOL SetItemState(_In_ int nItem, _In_ DWORD dwMask, _In_ DWORD dwState);// Operations// Inserts a new tab in the tab control.LONG InsertItem(_In_ int nItem, _In_ TCITEM* pTabCtrlItem);LONG InsertItem(_In_ int nItem, _In_z_ LPCTSTR lpszItem);LONG InsertItem(_In_ int nItem, _In_z_ LPCTSTR lpszItem, _In_ int nImage);LONG InsertItem(_In_ UINT nMask, _In_ int nItem, _In_z_ LPCTSTR lpszItem,_In_ int nImage, _In_ LPARAM lParam);LONG InsertItem(_In_ UINT nMask, _In_ int nItem, _In_z_ LPCTSTR lpszItem,_In_ int nImage, _In_ LPARAM lParam, _In_ DWORD dwState, _In_ DWORD dwStateMask);// Removes a tab from the tab control.BOOL DeleteItem(_In_ int nItem);// Removes all tabs from the tab control.BOOL DeleteAllItems();// Calculates the tab control's display area given a window rectangle.void AdjustRect(_In_ BOOL bLarger, _Inout_ LPRECT lpRect);// Removes an image from the tab control's image list.void RemoveImage(_In_ int nImage);// Determines which tab, if any, is at a specified screen position.int HitTest(_In_ TCHITTESTINFO* pHitTestInfo) const;// Resets tabs in the tab control, clearing any that were in the pressed state.void DeselectAll(_In_ BOOL fExcludeFocus)// Sets the highlight state of a tab in the tab control.BOOL HighlightItem(_In_ int idItem, _In_ BOOL fHighlight = TRUE);// Implementation
public:virtual ~CTabCtrl();
protected:virtual BOOL OnChildNotify(UINT, WPARAM, LPARAM, LRESULT*);afx_msg void OnDestroy();DECLARE_MESSAGE_MAP()
};
CTabCtrl的风格
#define TCS_SCROLLOPPOSITE 0x0001 // assumes multiline tab
#define TCS_BOTTOM 0x0002 底部
#define TCS_RIGHT 0x0002
#define TCS_MULTISELECT 0x0004 多选// allow multi-select in button mode
#define TCS_FLATBUTTONS 0x0008
#define TCS_FORCEICONLEFT 0x0010
#define TCS_FORCELABELLEFT 0x0020
#define TCS_HOTTRACK 0x0040 追踪
#define TCS_VERTICAL 0x0080
#define TCS_TABS 0x0000
#define TCS_BUTTONS 0x0100 按钮风格
#define TCS_SINGLELINE 0x0000
#define TCS_MULTILINE 0x0200 多行
#define TCS_RIGHTJUSTIFY 0x0000
#define TCS_FIXEDWIDTH 0x0400
#define TCS_RAGGEDRIGHT 0x0800
#define TCS_FOCUSONBUTTONDOWN 0x1000
#define TCS_OWNERDRAWFIXED 0x2000
#define TCS_TOOLTIPS 0x4000
#define TCS_FOCUSNEVER 0x8000
分页模式开发
MainDlg.h: 头文件
#pragma once
#include "CPage1.h"
#include "CPage2.h"
#include "CPage3.h"
class CMainDlg : public CDialogEx
{
// 构造CPage1 m_p1;CPage2 m_p2;CPage3 m_p3;
public:CMainDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_PAGING_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:CTabCtrl m_tab;afx_msg void OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult);
};
MainDlg.cpp: 实现文件
创建标签,将三个分页创建在这里面进行显示
BOOL CMainDlg::OnInitDialog()
{CDialogEx::OnInitDialog();m_tab.InsertItem(0, _T("基础信息"));m_tab.InsertItem(1, _T("联系信息"));m_tab.InsertItem(2, _T("其他信息"));m_p1.Create(IDD_PAGE1, &m_tab);//把三个分页创建在这里面 父子关系 Create 一个对象只能创建一次m_p2.Create(IDD_PAGE2, &m_tab); m_p3.Create(IDD_PAGE3, &m_tab);m_p1.ShowWindow(SW_SHOW); m_p2.ShowWindow(SW_SHOW); m_p3.ShowWindow(SW_SHOW);CRect rect, rc;m_tab.GetClientRect(rect); //将分页窗口的位置向下平移了 要不然回覆盖掉原窗口m_tab.GetItemRect(0, rc); rect.top = rc.bottom;m_p1.MoveWindow(rect); m_p2.MoveWindow(rect); m_p3.MoveWindow(rect);return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
当选择不同的标签时对不同的窗口进行隐藏或者显示
void CMainDlg::OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult)
{*pResult = 0;int nIndex = m_tab.GetCurSel();int nCount = m_tab.GetItemCount();CWnd* ps[] = { &m_p1,&m_p2,&m_p3 };int i = -1;while (++i<nCount){if (nIndex == i) ps[i]->ShowWindow(SW_SHOW);elseps[i]->ShowWindow(SW_HIDE);}
}
实际效果:
演示向导模式的多页窗口开发
MainDlg.h: 头文件 定义相关的变量和函数
#pragma once
#include "CPage1.h"
#include "CPage2.h"
#include "CPage3.h"
class CMainDlg : public CDialogEx
{
// 构造CPage1 m_p1;CPage2 m_p2;CPage3 m_p3;int m_nIndex{};void ChangePage();
public:CMainDlg(CWnd* pParent = nullptr); // 标准构造函数// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_PAGING_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:CTabCtrl m_tab;
// afx_msg void OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnBnClickedBack();afx_msg void OnBnClickedNext();afx_msg void OnBnClickedFinish();
};
MainDlg.cpp: 实现文件
void CMainDlg::ChangePage()
{CWnd* ps[] = { &m_p1,&m_p2,&m_p3 };int i = -1;while (++i < _countof(ps))ps[i]->ShowWindow(i == m_nIndex ? SW_SHOW : SW_HIDE);GetDlgItem(IDC_BACK)->EnableWindow(m_nIndex != 0); GetDlgItem(IDC_NEXT)->EnableWindow(m_nIndex != _countof(ps)-1);
}
BOOL CMainDlg::OnInitDialog()
{CDialogEx::OnInitDialog();m_p1.Create(IDD_PAGE1, this);//把三个分页创建在这里面 父子关系 Create 一个对象只能创建一次m_p2.Create(IDD_PAGE2, this);m_p3.Create(IDD_PAGE3, this);ChangePage();return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CMainDlg::OnBnClickedBack() //上一步
{if (m_nIndex >0)--m_nIndex;ChangePage();
}void CMainDlg::OnBnClickedNext()//下一步
{if (m_nIndex<3)++m_nIndex;ChangePage();
}void CMainDlg::OnBnClickedFinish() //完成
{EndDialog(IDOK);
}
实际效果: