文章目录
- 记事本项目功能完善和开发
- 查找界面的记忆功能 、使用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();
else
SerachUp();
}
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("”"));
}
else
m_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"));
else
theApp.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);//ANSI
delete[]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)//00000010
return 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 为 FALSE
LPCTSTR 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 为 FALSE
LPCTSTR 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_TIME
enum { 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 creator
virtual 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);
// Attributes
CImageList* 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_TIME
enum { IDD = IDD_PAGING_DIALOG };
#endif
protected:
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);
else
ps[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_TIME
enum { IDD = IDD_PAGING_DIALOG };
#endif
protected:
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);
}
实际效果: