MFC第十九天 记事本项目功能完善和开发、CTabCtrl类与分页模式开发

文章目录

  • 记事本项目功能完善和开发
    • 查找界面的记忆功能 、使用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);
}

实际效果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/6225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频对比工具(基于python+ffmpeg+airtest实现视频抽帧比较工具)

VideoDiff&#xff1a;基于ffmpeg&#xff0c;实现视频抽帧比较工具 使用场景&#xff1a;在视频渲染模块发生迭代&#xff0c;快速回归测试其产出的视频是否存在问题&#xff0c;从而节省人工回归成本 源码地址&#xff1a;https://github.com/jiangliuer32/VideoDiff 原理图…

centos7中MySQL备份还原策略

目录 一、直接拷贝数据库文件 1.1在shangke主机上停止服务并且打包压缩数据库文件 1.2 在shangke主机上把数据库文件传输到localhost主机上(ip为192.168.33.157) 1.3在localhost主机上停止服务&#xff0c;解压数据库文件 1.4 在localhost主机上开启服务 1.5 测试 二、m…

JVM-Java虚拟机

JVM——Java虚拟机&#xff0c;是Java实现平台无关性的基石。 基本概念&#xff1a;JVM 是可运行 Java 代码的假想计算机 &#xff0c;包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收&#xff0c;堆 和 一个存储方法域。JVM 是运行在操作系统之上的&#xff0c;它与…

【Docker】基本概念和底层技术

Docker 1 什么是 Docker Docker 是一种容器技术。只要开发者将其应用和依赖包进行打包&#xff0c;放入到一个轻量级的、可移植的容器中&#xff0c;就能发布到任何流行的 linux 机器上。 Docker 的要素&#xff1a; image 镜像&#xff1a;静态的container 容器&#xff1a…

android studio 新建项目没有R文件

android studio 新建项目没有R文件&#xff0c;处理步骤 1&#xff0c;找一个能打开的项目替换根目录下的settings.gradle 2,改app 目录下的build.gradle文件 3&#xff0c;改gradle版本 4&#xff0c;改AndroidManifest.xml 5&#xff0c;改theme 改为&#xff0c;ok.

【Python】数据分析+数据挖掘——变量列的相关操作

前言 在Python和Pandas中&#xff0c;变量列操作指的是对DataFrame中的列进行操作&#xff0c;包括但不限于选择列、重命名列、添加新列、删除列、修改列数据等操作。这些操作可以帮助我们处理数据、分析数据和进行特征工程等。 变量列的相关操作 概述 下面将会列出一些基本…

Jmeter-使用http proxy代理录制脚本

Jmeter-使用http proxy代理录制脚本 第1步&#xff1a;打卡jmeter工具新增1个线程组 第2步&#xff1a;给线程组添加1个HTTP请求默认值 第3步&#xff1a;设置下HTTP请求默认值第4步&#xff1a;在工作台中新增1个----HTTP代理服务器 第5步&#xff1a;设置HTTP代理服务器…

2023华为OD统一考试(B卷)题库清单(持续收录中)以及考点说明

目录 专栏导读2023 B卷 “新加题”&#xff08;100分值&#xff09;2023Q2 100分2023Q2 200分2023Q1 100分2023Q1 200分2022Q4 100分2022Q4 200分牛客练习题 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#xff09;》。 刷的越多&…

卷积神经网络识别人脸项目—使用百度飞桨ai计算

卷积神经网络识别人脸项目的详细过程 整个项目需要的准备文件&#xff1a; 下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1WEndfi14EhVh-8Vvt62I_w 提取码&#xff1a;7777 链接&#xff1a;https://pan.baidu.com/s/10weqx3r_zbS5gNEq-xGrzg 提取码&#x…

pnpm 与monorepo架构

软链接与硬链接 创建方式&#xff1a; mklink &#xff08;windows&#xff09; 软链接 &#xff1a; a、b指向同一个文件 b相当于一个快捷方式 硬链接&#xff1a; a、b指向同一个内存地址 某一文件修改&#xff0c;其他文件跟这变化 上图所示&#xff1a;安装某依赖&…

分布式光伏电站监控及集中运维管理-安科瑞黄安南

前言&#xff1a;今年以来&#xff0c;在政策利好推动下光伏、风力发电、电化学储能及抽水蓄能等新能源行业发展迅速&#xff0c;装机容量均大幅度增长&#xff0c;新能源发电已经成为新型电力系统重要的组成部分&#xff0c;同时这也导致新型电力系统比传统的电力系统更为复杂…

【C++】多态(举例+详解,超级详细)

本篇文章会对C中的多态进行详解。希望本篇文章会对你有所帮助。 文章目录 一、多态的定义及实现 1、1 多态的概念 1、2 多态的构成条件 1、2、1 虚函数 1、2、2 虚函数的重写 1、2、3 析构函数构成重写特例原因 1、3 多态的实例练习 1、3、1 例1 1、3、2 例2 1、3、3 例3 1、4…

linux安装conda

linux安装conda 卸载conda 在主目录下&#xff0c;使用普通权限安装&#xff1a; ./Anaconda3-2023.03-1-Linux-x86_64.shanaconda的目录是ENTER

python_day13

reduceByKey算子&#xff0c;聚合 列表中存放二元元组&#xff0c;元组中第一个为key&#xff0c;此算子按key聚合&#xff0c;传入计算逻辑 from pyspark import SparkConf, SparkContext import osos.environ["PYSPARK_PYTHON"] "D:/dev/python/python3.10…

【分布式】1、CAP 理论 | 一致性、可用性、分区容忍性

文章目录 一、CAP 理论1.1 Consistency 一致性1.2 Availbility 可用性1.3 Partition Tolerance 分区容忍性1.4 CAP 应用1.4.1 CP1.4.2 AP 二、CAP 实践2.1 ACID2.2 BASE 一、CAP 理论 是 2002 年证明的定理&#xff0c;原文&#xff0c;内容如下&#xff1a; In a distributed…

喜报|英码科技联合广师大荣获“智芯杯”AI芯片应用创新创业大赛两大奖项

7月15日&#xff0c;由中国仪器仪表学会主办的全国首届“智芯杯”AI芯片应用创新创业大赛总决赛暨颁奖典礼圆满结束&#xff0c;英码科技联合广东技术师范大学设计开发的“AI视觉&#xff0c;让工厂建设更智慧”和“基于AI的智慧校园无感考勤系统”创新项目均荣获三等奖。 ​ 自…

springcloudAlibaba之nacos集群部署和nginx负载均衡

1.环境准备 nacos server安装包&#xff1a;https://github.com/alibaba/nacos nginx安装包&#xff1a;https://nginx.org/en/download.html 2、nacos配置 将下载好的nacos-server的压缩包解压好以后&#xff0c;复制出N份&#xff08;这里取决于你集群的数量&#xff09;&…

设计模式之模板方法模式

例子&#xff1a;登陆&#xff08;普通用户&#xff0c;工作人员&#xff09; 没有使用设计模式实现用户登陆 package com.tao.YanMoDesignPattern.template.notPattern;/*** Author Mi_Tao* Date 2023/7/22* Description* Version 1.0**/ public class LoginModel {private …

Grafana中table的使用技巧

将多个指标数据显示在同一个Table中&#xff0c;需要用到Transform功能&#xff0c;利用Transform功能可以将数据进行处理只显示想要的数据&#xff1a;

【VTK】VTK 让小球动起来,在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 版本环境A.uiA.hA.cppRef. 本文主要目的是在 Qt 界面中&#xff0c;显示出来使用 VTK 构建的小球&#xff0c;并让小球能够动起来。同时为了方便对比…