MFC第二十一天 CS架构多页面开发与数据交互、CImageList图像列表介绍 、CListCtrl-SetItem设置列表项的方法

文章目录

  • CImageList图像列表介绍
  • CListCtrl
    • 图标的原理
    • CListCtrl列表图标设置
    • CListCtrl-SetItem设置列表项的方法
  • CS架构多页面开发与数据交互
    • 添加用户实现向导多页数据交互
      • pch.h
      • CLientXq.h CApp
      • CPage1.h
      • CPage1.cpp
      • CPage2.h
      • CPage2.cpp
      • CWorkerDlg .h
      • CWorkerDlg.cpp
    • 多页数据修改
      • CModfiyDlg.h
      • CModfiyDlg.cpp
    • CListCtrl-SetItemData设置列表项数据
    • 双击列表编辑功能 下拉控件功能
      • CAdminDlg.h
      • CAdminDlg.cpp

CImageList图像列表介绍

图像列表类支持内部有动态数组的控件 CComboBox CHeaderCtrl CListCtrl CTreeCtrl
把图标做成一个列表

class CImageList : public CObject
{DECLARE_DYNCREATE(CImageList)// Constructors
public:CImageList();BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow); 创建空列表,指定每个元素的高宽。BOOL Create(UINT nBitmapID, int cx, int nGrow, COLORREF crMask);//指定带透明色的位图BOOL Create(LPCTSTR lpszBitmapID, int cx, int nGrow, COLORREF crMask);//指定带透明色的位图BOOL Create(CImageList& imagelist1, int nImage1, CImageList& imagelist2,int nImage2, int dx, int dy);//多列表BOOL Create(CImageList* pImageList);//类似于拷贝构造int GetImageCount() const; //总数int Add(HICON hIcon);int Add(CBitmap* pbmImage, CBitmap* pbmMask);int Add(CBitmap* pbmImage, COLORREF crMask);

Attributes

	HIMAGELIST m_hImageList;            // must be first data memberoperator HIMAGELIST() const;HIMAGELIST GetSafeHandle() const;static CImageList* PASCAL FromHandle(HIMAGELIST hImageList);static CImageList* PASCAL FromHandlePermanent(HIMAGELIST hImageList);static void PASCAL DeleteTempMap();BOOL Attach(HIMAGELIST hImageList);HIMAGELIST Detach();COLORREF SetBkColor(COLORREF cr);//用来透明的背景色COLORREF GetBkColor() const;BOOL GetImageInfo(int nImage, IMAGEINFO* pImageInfo) const;

Operations

	BOOL DeleteImageList();//摧毁BOOL SetImageCount(UINT uNewCount);//类似于vector:resize 或者CArray::SetSizeBOOL Remove(int nImage);//移除BOOL Replace(int nImage, CBitmap* pbmImage, CBitmap* pbmMask);int Replace(int nImage, HICON hIcon);BOOL Draw(CDC* pDC, int nImage, POINT pt, UINT nStyle);BOOL DrawEx(CDC* pDC,int nImage,POINT pt,SIZE sz,COLORREF clrBk,COLORREF clrFg,UINT nStyle);BOOL Copy(int iDst, int iSrc, UINT uFlags = ILCF_MOVE);BOOL Copy(int iDst, CImageList* pSrc, int iSrc, UINT uFlags = ILCF_MOVE);BOOL DrawIndirect(IMAGELISTDRAWPARAMS* pimldp);BOOL DrawIndirect(CDC* pDC, int nImage, POINT pt, SIZE sz, POINT ptOrigin,UINT fStyle = 			    ILD_NORMAL, DWORD dwRop = SRCCOPY,COLORREF rgbBack = CLR_DEFAULT, COLORREF rgbFore =      CLR_DEFAULT,DWORD fState = ILS_NORMAL, DWORD Frame = 0, COLORREF crEffect = CLR_DEFAULT);BOOL Read(CArchive* pArchive);BOOL Write(CArchive* pArchive);

Drag APIs

	BOOL BeginDrag(int nImage, CPoint ptHotSpot);static void PASCAL EndDrag();static BOOL PASCAL DragMove(CPoint pt);BOOL SetDragCursorImage(int nDrag, CPoint ptHotSpot);static BOOL PASCAL DragShowNolock(BOOL bShow);static CImageList* PASCAL GetDragImage(LPPOINT lpPoint, LPPOINT lpPointHotSpot);static BOOL PASCAL DragEnter(CWnd* pWndLock, CPoint point);static BOOL PASCAL DragLeave(CWnd* pWndLock);
public:			// Implementationvirtual ~CImageList();
#ifdef _DEBUGvirtual void Dump(CDumpContext& dc) const;virtual void AssertValid() const;
#endif
};

CListCtrl

图标的原理

a)高宽(x,y)和2个图片句柄
b)图片的句柄有1张彩色,另一张是黑白(Mask)

typedef struct _ICONINFO {BOOL    fIcon;DWORD   xHotspot;DWORD   yHotspot;HBITMAP hbmMask;HBITMAP hbmColor;
} ICONINFO, *PICONINFO;

CListCtrl列表图标设置

编辑列表项:默认的EditLable
列表项内部数据结构体

 struct LVITEM{UINT   mask;int    iItem;int    iSubItem;UINT   state;UINT   stateMask;LPTSTR pszText;int    cchTextMax;int    iImage;LPARAM lParam;
};

a)插入时可以指定:

int InsertItem(int nItem,LPCTSTR lpszItem,int nImage );

b)修改时指定图标:

BOOL SetItem(    int nItem, 。。。)

列表项组成分析:

int InsertItem(const LVITEM* pItem 
);int InsertItem(UINT nMask,int nItem,LPCTSTR lpszItem,UINT nState,UINT nStateMask,int nImage,LPARAM lParam
);
BOOL SetItem( int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem, int nImage, UINT nState, UINT nStateMask, LPARAM lParam  
); 
BOOL SetItem( const LVITEM* pItem  
); 

CListCtrl-SetItem设置列表项的方法

各种设置方法CListCtrl::SetItemXXX

全部数据设置:CListCtrl::SetItem Sets some or all of a list view item's attributes.CListCtrl::SetItemCountPrepares a list view control for adding a large number of items.
CListCtrl::SetItemCountEx	// Sets the item count for a virtual list view control.CListCtrl::SetItemData  Sets the item's application-specific value.设置关联数据:一个列表项背后可以关联一个结构体,或者一个double或者一个longlong数据。CListCtrl::SetItemIndexStateSets the state of an item in the current list-view control.
CListCtrl::SetItemPositionMoves an item to a specified position in a list view control.CListCtrl::SetItemState Changes the state of an item in a list view control.

状态种类有哪些?

#define LVIS_FOCUSED            0x0001  虚线
#define LVIS_SELECTED           0x0002 蓝色
LVITEM lvi = { LVIF_STATE };lvi.iItem = 1;lvi.state = LVIS_FOCUSED| LVIS_SELECTED;lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;m_list.SetItem(&lvi);//等价于 m_list.SetItemState(2, LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
CListCtrl::SetItemText  Changes the text of a list view item or subitem.
等价与SetItem 指定{ LVIF_TEXT }LVITEM lvi = { LVIF_TEXT };lvi.iItem = 1;lvi.iSubItem = 2;lvi.pszText = (LPTSTR)(LPCTSTR)str;m_list.SetItem(&lvi);

CS架构多页面开发与数据交互

主要有五个窗口 组成
Page1基本信息工号 工资等 对其都采用关联性数据变量 方便操作
Page2 扩展信息 性别 学历等 同样采用关联性数据变量 方便操作
修改窗口 采用Tab Ctrl控件,
数据录入窗口
主窗口

在这里插入图片描述

添加用户实现向导多页数据交互

pch.h

enum {L_ENGL=1,L_RUSS =2,L_JPAN =4,L_KREA=8};
struct SInfo
{int nNumb;char sName[20];float fSala;char sDate[20];bool bSex;char cLang;	//1 2 4 8代表四种语言int nEduc;
};

CLientXq.h CApp

class CApp : public CWinApp
{void InitImageList();
public:CApp();CString m_sName, m_sPass;CImageList m_imageList;int m_nPrior{ -1 };LPCTSTR m_es[6]{ _T("初中"),_T("高中"),_T("大专") ,_T("本科") ,_T("硕士") ,_T("博士") };static int GetEduc(CString& str);CSocket m_sock;
// 重写
}

CPage1.h

class CPage1 : public CDialogEx
{DECLARE_DYNAMIC(CPage1)void OnOK();
public:CPage1(CWnd* pParent = nullptr);   // 标准构造函数virtual ~CPage1();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_PAGE1 };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:int m_nNumb;CString m_sName;float m_fSalary;
//	CDateTimeCtrl m_date;COleDateTime m_date;
};

CPage1.cpp

#include "pch.h"
#include "CLientXq.h"
#include "afxdialogex.h"
#include "CPage1.h"
IMPLEMENT_DYNAMIC(CPage1, CDialogEx)void CPage1::OnOK()
{auto pWnd = GetFocus();int nID = pWnd->GetDlgCtrlID();if (nID == IDC_DATETIME || nID == IDOK)GetParent()->PostMessage(WM_COMMAND, IDOK);elseNextDlgCtrl();
}CPage1::CPage1(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_PAGE1, pParent), m_nNumb(1000), m_sName(_T("")), m_fSalary(0), m_date(COleDateTime::GetCurrentTime())
{}CPage1::~CPage1()
{
}void CPage1::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Text(pDX, IDC_NUMB, m_nNumb);DDX_Text(pDX, IDC_NAME, m_sName);DDX_Text(pDX, IDC_SALARY, m_fSalary);//  DDX_Control(pDX, IDC_DATETIME, m_date);DDX_DateTimeCtrl(pDX, IDC_DATETIME, m_date);
}BEGIN_MESSAGE_MAP(CPage1, CDialogEx)
END_MESSAGE_MAP()

CPage2.h

#pragma once
#include "afxdialogex.h"
class CPage2 : public CDialogEx
{DECLARE_DYNAMIC(CPage2)void OnOK(){GetParent()->PostMessage(WM_COMMAND, IDC_FINISH);}void OnCancel(){GetParent()->PostMessage(WM_COMMAND, IDCANCEL);}
public:CPage2(CWnd* pParent = nullptr);   // 标准构造函数virtual ~CPage2();char GetLang()const;// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_PAGE2 };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:int m_nEdu;BOOL m_bEng;BOOL m_bJpan;BOOL m_bKrea;BOOL m_bRuss;BOOL m_bSex;
};

CPage2.cpp

#include "pch.h"
#include "CLientXq.h"
#include "afxdialogex.h"
#include "CPage2.h"IMPLEMENT_DYNAMIC(CPage2, CDialogEx)CPage2::CPage2(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_PAGE2, pParent), m_nEdu(3), m_bEng(FALSE), m_bJpan(FALSE), m_bKrea(FALSE), m_bRuss(FALSE), m_bSex(FALSE)
{}CPage2::~CPage2()
{
}char CPage2::GetLang() const  //通过或运算 结合数据库 判断其勾选了那门外语
{char c;if (m_bEng)c |= L_ENGL;if (m_bRuss)c |= L_RUSS;if (m_bJpan)c |= L_JPAN;if (m_bKrea)c |= L_KREA;return c;
}void CPage2::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Radio(pDX, IDC_EDUC, m_nEdu);DDX_Check(pDX, IDC_ENGL, m_bEng);DDX_Check(pDX, IDC_JPEN, m_bJpan);DDX_Check(pDX, IDC_KREA, m_bKrea);DDX_Check(pDX, IDC_RUSS, m_bRuss);DDX_Radio(pDX, IDC_SEX, m_bSex);
}BEGIN_MESSAGE_MAP(CPage2, CDialogEx)
END_MESSAGE_MAP()

CWorkerDlg .h

#pragma once
#include "afxdialogex.h"
class CWorkerDlg : public CDialogEx
{DECLARE_DYNAMIC(CWorkerDlg)CImageList m_hList;//HeaderCString	GetLine(int nIndex);CSocket& m_sock {theApp.m_sock};void Refresh(int nOrder =-1);CListCtrl m_list;CString GetLang(int cLang);LPCTSTR m_es[6]{ _T("初中"),_T("高中"),_T("大专") ,_T("本科") ,_T("硕士") ,_T("博士") };public:CWorkerDlg(CWnd* pParent = nullptr);   // 标准构造函数virtual ~CWorkerDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_WORKER_DIG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:virtual BOOL OnInitDialog();afx_msg void OnBnClickedDel();afx_msg void OnBnClickedModeify();afx_msg void OnBnClickedAdd();afx_msg void OnItemclickList(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnTimer(UINT_PTR nIDEvent);afx_msg void OnBnClickedTest();afx_msg void OnBnClickedTest2();afx_msg void OnDestroy();
};

CWorkerDlg.cpp

#include "pch.h"
#include "CLientXq.h"
#include "afxdialogex.h"
#include "CWorkerDlg.h"
#include "CInputDlg.h"
#include "CModfiyDlg.h"
IMPLEMENT_DYNAMIC(CWorkerDlg, CDialogEx)
CWorkerDlg::CWorkerDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_WORKER_DIG, pParent)
{}CWorkerDlg::~CWorkerDlg()
{m_list.Detach();
}void CWorkerDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CWorkerDlg, CDialogEx)ON_BN_CLICKED(IDC_DEL, &CWorkerDlg::OnBnClickedDel)ON_BN_CLICKED(IDC_MODEIFY, &CWorkerDlg::OnBnClickedModeify)ON_BN_CLICKED(IDC_ADD, &CWorkerDlg::OnBnClickedAdd)ON_NOTIFY(HDN_ITEMCLICK, 0, &CWorkerDlg::OnItemclickList)ON_NOTIFY(NM_DBLCLK, IDC_LIST, &CWorkerDlg::OnDblclkList)ON_WM_TIMER()ON_BN_CLICKED(IDC_TEST, &CWorkerDlg::OnBnClickedTest)ON_BN_CLICKED(IDC_TEST2, &CWorkerDlg::OnBnClickedTest2)ON_WM_DESTROY()
END_MESSAGE_MAP()CString CWorkerDlg::GetLine(int nIndex)
{CString str;if (nIndex >= m_list.GetItemCount())return str;//return CString();int i = -1;while (++i < 4){if (i > 0)str += _T(",");str += m_list.GetItemText(nIndex, i);}return str;
}
void CWorkerDlg::Refresh(int nOrder)  
{m_list.DeleteAllItems();int nCmd = WK_PRINT;m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(&nOrder, sizeof(nOrder));SInfo d;CString str;int i = 0;while (m_sock.Receive(&d, sizeof(d)) == sizeof(d)){str.Format(_T("%d"), d.nNumb);m_list.InsertItem(i, str,i%3);m_list.SetItemText(i, 1, _bstr_t(d.sName));str.Format(_T("%g"), d.fSala);m_list.SetItemText(i, 2, str);m_list.SetItemText(i, 3, _bstr_t(d.sDate));m_list.SetItemText(i, 4, d.bSex ? _T("女") : _T("男"));m_list.SetItemText(i, 5, m_es[d.nEduc]);m_list.SetItemText(i, 6, GetLang(d.cLang));auto p = new SInfo{ d };m_list.SetItemData(i, (DWORD_PTR)p); //给每个数据背后设置了数据++i;}
}CString CWorkerDlg::GetLang(int cLang)
{CString str;if (cLang & L_ENGL)str += ("英语");if (cLang & L_JPAN)str += _T("日语|");if (cLang & L_RUSS)str += _T("俄语|");if (cLang & L_KREA)str += _T("韩语|");return str;
}
BOOL CWorkerDlg::OnInitDialog()
{CDialogEx::OnInitDialog();m_list.Attach(::GetDlgItem(m_hWnd, IDC_LIST)); //attach一处就可以了m_hList.Create(IDB_BITMAP2, 16, 8, RGB(255, 255, 255)); //创造图标2 列表头int n = m_hList.GetImageCount();m_list.SetImageList(&theApp.m_imageList, LVSIL_SMALL);auto pHeard = m_list.GetHeaderCtrl();pHeard->SetImageList(&m_hList);m_list.InsertColumn(0, _T("工号"),  LVCFMT_CENTER, 80);m_list.InsertColumn(1, _T("姓名"), LVCFMT_CENTER, 120);m_list.InsertColumn(2, _T("工资"), LVCFMT_CENTER, 130);m_list.InsertColumn(3, _T("入职日期"), LVCFMT_CENTER, 150);m_list.InsertColumn(4, _T("性别"), LVCFMT_LEFT, 80);m_list.InsertColumn(5, _T("教育程度"), LVCFMT_LEFT, 100);m_list.InsertColumn(6, _T("外语"), LVCFMT_LEFT, 150);m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);m_list.SetBkColor(RGB(207, 152, 225));m_list.SetTextBkColor(RGB(162, 182, 100));Refresh();SetTimer(1, 500, NULL);//InitTitle();return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}
void CWorkerDlg::OnBnClickedDel()
{  POSITION pos = m_list.GetFirstSelectedItemPosition();if (!pos){MessageBox(_T("请至少选中一行再删除!"), _T("提示"));return;}while (pos){int i = m_list.GetNextSelectedItem(pos);CString str = GetLine(i);if (MessageBox(str + _T("\r\n你确定要删除这一行吗?"), _T("提示"), MB_YESNO) == IDYES){int nCmd = WK_DELETE;//int nNumb = atoi(_bstr_t(m_list.GetItemText(i, 0)));int nNumb = _tstoi(m_list.GetItemText(i, 0));m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(&nNumb, sizeof(nNumb));if (m_sock.Receive(&nNumb, sizeof(nNumb)) != sizeof(nNumb)){MessageBox(_T("网络中断!"));return;}if (nNumb < 1){MessageBox(_T("删除失败!"));}}}Refresh();
}void CWorkerDlg::OnBnClickedModeify()
{POSITION pos = m_list.GetFirstSelectedItemPosition();if (!pos){MessageBox(_T("请选中一行再修改!"), _T("提示"));return;}CModfiyDlg dlg(m_list);if (dlg.DoModal() == IDOK){Refresh();}
}void CWorkerDlg::OnBnClickedAdd()
{CInputDlg dlg(this);  //这里需要一个指针指向这个CWorkerDlg类面向对象管理if (dlg.DoModal() == IDCANCEL)return;Refresh();
}
void CWorkerDlg::OnItemclickList(NMHDR* pNMHDR, LRESULT* pResult)  //给列表 头上面设置图标
{LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);HDITEM hdItem;hdItem.mask = HDI_IMAGE;hdItem.iImage = 0;m_list.GetHeaderCtrl()->SetItem(0, & hdItem);Refresh(phdr->iItem);*pResult = 0;}
void CWorkerDlg::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) //双击列表
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);*pResult = 0;OnBnClickedModeify();
}
static int i = -1;
if (++i > 3)i = 0;
CString	str;
str.Format(_T("HAHHA=%d"), i + 1000);
m_list.SetItemText(0, 2, str);static int i = -1;	//等价于上面if (++i > 3)	i = 0;CString	str;str.Format(_T("HAHHA=%d"), i + 1000);LVITEM lvi = { LVIF_TEXT }; //用于设置文字lvi.iItem = 1;	lvi.iSubItem = 2;lvi.pszText = (LPTSTR)(LPCTSTR)str;m_list.SetItem(&lvi);
void CWorkerDlg::OnTimer(UINT_PTR nIDEvent)  //使加载的图标进行切换
{static int i = -1;if (++i > 3)i = 0;CString	str;str.Format(_T("HAHHA=%d"), i + 1000);LVITEM lvi = { LVIF_IMAGE }; //用于设置图标lvi.iItem = 1;lvi.iSubItem = 0;lvi.iImage = i;lvi.pszText = (LPTSTR)(LPCTSTR)str;m_list.SetItem(&lvi);//m_list.SetItemText(0, 2, str);CDialogEx::OnTimer(nIDEvent);
}
void CWorkerDlg::OnBnClickedTest()
{m_list.SetFocus();m_list.SetItemState(2, 0, LVIS_FOCUSED | LVIS_SELECTED); //参数2 设置目标 参数3 开关//m_list.SetItemState(2, LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); //参数2 设置目标 去掉虚线留下蓝色  参数3 开关
}void CWorkerDlg::OnBnClickedTest2()
{auto  p = m_list.GetItemData(3);m_list.SetItemData(3, 666);
}

在这里插入图片描述

多页数据修改

CModfiyDlg.h

#pragma once
#include "afxdialogex.h"
#include"CPage1.h"
#include "CPage2.h"
class CModfiyDlg : public CDialogEx
{DECLARE_DYNAMIC(CModfiyDlg)CPage1 m_p1;CPage2 m_p2;void ChangePage();void InitData();CListCtrl& m_list;
public:CModfiyDlg(CListCtrl& list);   // 标准构造函数virtual ~CModfiyDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_MODIFY_DLG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:virtual BOOL OnInitDialog();CTabCtrl m_tab;afx_msg void OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult);
};

CModfiyDlg.cpp

#include "pch.h"
#include "CLientXq.h"
#include "afxdialogex.h"
#include "CModfiyDlg.h"
IMPLEMENT_DYNAMIC(CModfiyDlg, CDialogEx)CModfiyDlg::CModfiyDlg(CListCtrl& list): CDialogEx(IDD_MODIFY_DLG, nullptr), m_list(list)
{}CModfiyDlg::~CModfiyDlg()
{
}
void CModfiyDlg::ChangePage()
{CWnd* ps[] = { &m_p1,&m_p2 };int i = -1;int nIndex = m_tab.GetCurSel();while (++i < _countof(ps))ps[i]->ShowWindow(i == nIndex ? SW_SHOW : SW_HIDE);ps[nIndex]->SetFocus();
}
void CModfiyDlg::InitData()
{POSITION pos = m_list.GetFirstSelectedItemPosition();if (!pos)return;int nItem = m_list.GetNextSelectedItem(pos);SInfo* p = (SInfo*)m_list.GetItemData(nItem);ASSERT(p != NULL);if (!p)return;m_p1.m_nNumb = p->nNumb;m_p1.m_sName = p->sName;m_p1.m_fSalary = p->fSala;m_p1.m_date.ParseDateTime(m_list.GetItemText(nItem, 3));m_p2.m_bSex = m_list.GetItemText(nItem, 4)==_T("女");m_p2.m_nEdu = CApp::GetEduc(m_list.GetItemText(nItem, 5));CString str =m_list.GetItemText(nItem, 6);m_p2.m_bEng = str.Find(_T("英语")) > -1;m_p2.m_bRuss = str.Find(_T("俄语")) > -1;m_p2.m_bJpan = str.Find(_T("日语")) > -1;m_p2.m_bKrea = str.Find(_T("韩语")) > -1;
}void CModfiyDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_TAB, m_tab);
}BEGIN_MESSAGE_MAP(CModfiyDlg, CDialogEx)ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, &CModfiyDlg::OnSelchangeTab)
END_MESSAGE_MAP()
BOOL CModfiyDlg::OnInitDialog()
{CDialogEx::OnInitDialog();InitData();m_p1.Create(IDD_PAGE1, this);m_p2.Create(IDD_PAGE2, this);CEdit* pEDIT = (CEdit*)m_p1.GetDlgItem(IDC_NUMB);pEDIT->SetReadOnly();m_tab.SetImageList(&theApp.m_imageList);m_tab.InsertItem(0, _T("基本信息"),1);m_tab.InsertItem(1, _T("其他信息"),2);CRect rect;m_tab.GetWindowRect(rect);ScreenToClient(rect);m_p1.SetWindowPos(nullptr, rect.left, rect.bottom , 0, 0, SWP_NOSIZE | SWP_NOZORDER);//父子关系将它放进去m_p2.SetWindowPos(nullptr, rect.left, rect.bottom , 0, 0, SWP_NOSIZE | SWP_NOZORDER);//兄弟关系 要把那个框拉上去 然后将分页move Windows在它的下面ChangePage();return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}

在这里插入图片描述

void CModfiyDlg::OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult)
{*pResult = 0;ChangePage();
}

CListCtrl-SetItemData设置列表项数据

void CWorkerDlg::Refresh(int nOrder){m_list.DeleteAllItems();int nCmd = WK_PRINT;m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(&nOrder, sizeof(nOrder));SInfo d;CString str;int i = 0;while (m_sock.Receive(&d, sizeof(d)) == sizeof(d)){str.Format(_T("%d"), d.nNumb);m_list.InsertItem(i, str,i%3);m_list.SetItemText(i, 1, _bstr_t(d.sName));str.Format(_T("%g"), d.fSala);m_list.SetItemText(i, 2, str);m_list.SetItemText(i, 3, _bstr_t(d.sDate));m_list.SetItemText(i, 4, d.bSex ? _T("女") : _T("男"));m_list.SetItemText(i, 5, m_es[d.nEduc]);m_list.SetItemText(i, 6, GetLang(d.cLang));auto p = new SInfo{ d };m_list.SetItemData(i, (DWORD_PTR)p); //给每个数据背后设置了数据++i;}
}
void CModfiyDlg::InitData()
{POSITION pos = m_list.GetFirstSelectedItemPosition();if (!pos){ return;}int nItem = m_list.GetNextSelectedItem(pos);SInfo* p = (SInfo*)m_list.GetItemData(nItem);ASSERT(p != NULL);if (!p)return;m_p1.m_nNumb = p->nNumb;m_p1.m_sName = p->sName;m_p1.m_fSalary = p->fSala;m_p1.m_date.ParseDateTime(m_list.GetItemText(nItem, 3));m_p2.m_bSex = m_list.GetItemText(nItem, 4)==_T("女");m_p2.m_nEdu = CApp::GetEduc(m_list.GetItemText(nItem, 5));CString str =m_list.GetItemText(nItem, 6);m_p2.m_bEng = str.Find(_T("英语")) > -1;m_p2.m_bRuss = str.Find(_T("俄语")) > -1;m_p2.m_bJpan = str.Find(_T("日语")) > -1;m_p2.m_bKrea = str.Find(_T("韩语")) > -1;
}
void CWorkerDlg::OnDestroy()
{CDialogEx::OnDestroy();int i = -1, nCount = m_list.GetItemCount();while (++i<nCount){SInfo* p = (SInfo*)m_list.GetItemData(i);delete p;}
}

双击列表编辑功能 下拉控件功能

在这里插入图片描述

CAdminDlg.h

#pragma once
#include "afxdialogex.h"
class CAdminDlg : public CDialogEx
{DECLARE_DYNAMIC(CAdminDlg)BOOL CheckUser(CString sName, SAdmin& a);void Refresh();void DeleteUser(CString sName);CSocket& m_sock{ theApp.m_sock };CListCtrl m_list;CComboBox m_combox;CComboBox m_combox2; //隐藏在表面 当选择时出现CEdit m_pass2;void OnOK();void OnCancel();BOOL ChangePass(CString sName,CString sPass);
public:CAdminDlg(CWnd* pParent = nullptr);   // 标准构造函数virtual ~CAdminDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_COUNT };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:virtual BOOL OnInitDialog();afx_msg void OnBnClickedAdd();afx_msg void OnBnClickedDel();afx_msg void OnBnClickedUpdate();afx_msg void OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult); //双击列表afx_msg void OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult);// 只能编辑第一个 afx_msg void OnSelchangePrior2();
};

CAdminDlg.cpp

#include "pch.h"
#include "CLientXq.h"
#include "afxdialogex.h"
#include "CAdminDlg.h"
IMPLEMENT_DYNAMIC(CAdminDlg, CDialogEx)
CAdminDlg::CAdminDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_COUNT, pParent)
{}
CAdminDlg::~CAdminDlg()
{m_list.Detach();m_combox.Detach();
}
void CAdminDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_PRIOR, m_combox);DDX_Control(pDX, IDC_PRIOR2, m_combox2);DDX_Control(pDX, IDC_PASS2, m_pass2);
}BEGIN_MESSAGE_MAP(CAdminDlg, CDialogEx)ON_BN_CLICKED(IDC_ADD, &CAdminDlg::OnBnClickedAdd)ON_BN_CLICKED(IDC_DEL, &CAdminDlg::OnBnClickedDel)ON_BN_CLICKED(IDC_UPDATE, &CAdminDlg::OnBnClickedUpdate)ON_NOTIFY(NM_DBLCLK, IDC_LIST, &CAdminDlg::OnDblclkList)ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST, &CAdminDlg::OnEndlabeleditList)ON_CBN_SELCHANGE(IDC_PRIOR2, &CAdminDlg::OnSelchangePrior2)
END_MESSAGE_MAP()
BOOL CAdminDlg::OnInitDialog()
{CDialogEx::OnInitDialog();m_combox.SetCurSel(1);m_combox2.SetCurSel(1);m_list.Attach(::GetDlgItem(m_hWnd, IDC_LIST));m_list.InsertColumn(0, _T("账号"), LVCFMT_LEFT, 120);m_list.InsertColumn(0, _T("密码"), LVCFMT_LEFT, 140);m_list.InsertColumn(0, _T("权限"), LVCFMT_LEFT, 150);m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);Refresh();return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}
BOOL CAdminDlg::CheckUser(CString sName,SAdmin& a)
{int nCmd = AD_CHECK;_bstr_t bstr = sName;LPCSTR p = bstr;m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(p, (int)sizeof(p));int nCount = 0;if (m_sock.Receive(&nCount, sizeof(nCount)) != sizeof(nCount)){AfxMessageBox(_T("网络中断"));return FALSE;}bool b = nCount > 0;if(b){if (m_sock.Receive(&a, sizeof(a)) != sizeof(a)){AfxMessageBox(_T("网络中断"));return FALSE;}}return b;
}void CAdminDlg::Refresh()
{int nCmd = AD_PRINT;int nCount = 0;m_sock.Send(&nCmd, sizeof(nCmd));if (m_sock.Receive(&nCount, sizeof(nCount))!=sizeof(nCount)){AfxMessageBox(_T("网络中断"));return;}SAdmin a;m_list.DeleteAllItems();int i = 0;while (nCount-->0){if (m_sock.Receive(&a, sizeof(a)) != sizeof(a)){AfxMessageBox(_T("网络中断"));break;}m_list.InsertItem(i, _bstr_t(a.sName));m_list.SetItemText(i, 1, _bstr_t(a.sPass));m_list.SetItemText(i, 2, a.nPrior ? _T("普通") : _T("高级"));++i;}
}void CAdminDlg::DeleteUser(CString sName)
{int nCmd = AD_DELETE;_bstr_t bstr = sName;LPCSTR p = bstr;m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(p, (int)sizeof(p));Refresh();
}void CAdminDlg::OnBnClickedAdd()
{SAdmin a;int nCmd = AD_INPUT;CString str;GetDlgItemText(IDC_NAEM, str);if (CheckUser(str, a)){CString str = CString(a.sName) + _T(",") + a.sPass + _T(",") + (a.nPrior ? _T("普通") : _T("高级"));AfxMessageBox(_T("账号已经存在"));return;}strcpy_s(a.sName, sizeof(a.sName), (_bstr_t)str);GetDlgItemText(IDC_PASS, str);strcpy_s(a.sPass, sizeof(a.sPass), (_bstr_t)str);a.nPrior = m_combox.GetCurSel();m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(&a, sizeof(a));Refresh();}void CAdminDlg::OnBnClickedDel()
{POSITION pos = m_list.GetFirstSelectedItemPosition();if (!pos){AfxMessageBox(_T("请选中一行再进行删除!"));return;}int nItem = m_list.GetNextSelectedItem(pos);CString sName = m_list.GetItemText(nItem, 0);SAdmin a;if (!CheckUser(sName,a)){AfxMessageBox(_T("账号不存在"));return;}CString str = sName + _T(",") + a.sPass + _T(",") + (a.nPrior ? _T("普通") : _T("高级"));if (AfxMessageBox(str+_T("\r\n你确定要删除这条记录?"),MB_YESNO)==IDNO)return;DeleteUser(sName);
}void CAdminDlg::OnBnClickedUpdate()
{POSITION pos = m_list.GetFirstSelectedItemPosition();if (!pos){AfxMessageBox(_T("请选中一行再进行修改!"));return;}int nItem = m_list.GetNextSelectedItem(pos);SAdmin a;strcpy_s(a.sName, sizeof(a.sName), _bstr_t(m_list.GetItemText(nItem, 0)));CString str;GetDlgItemText(IDC_PASS, str);strcpy_s(a.sPass, sizeof(a.sPass), (_bstr_t)str);int nCmd = AD_CHPASS;m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(&a, sizeof(a));int nRes = 0;if (m_sock.Receive(&nRes,sizeof(nRes))!=sizeof(nRes)){AfxMessageBox(_T("网络中断"));return;}if (nRes>0){AfxMessageBox(CString(a.sName)+_T("密码修改成功!"));Refresh();}elseAfxMessageBox(CString(a.sName) + _T("密码修改失败!"));
}
BOOL CAdminDlg::ChangePass(CString sName, CString sPass)
{SAdmin a;strcpy_s(a.sName, sizeof(a.sName), _bstr_t(sName));strcpy_s(a.sPass, sizeof(a.sPass), _bstr_t(sPass));int nCmd = AD_CHPASS;m_sock.Send(&nCmd, sizeof(nCmd));m_sock.Send(&a, sizeof(a));int nRes = 0;if (m_sock.Receive(&nRes, sizeof(nRes)) != sizeof(nRes)){AfxMessageBox(_T("网络中断!"));return FALSE;}return TRUE;
}
void CAdminDlg::OnOK()
{if (!m_pass2.IsWindowVisible())return;CString sPass;m_pass2.GetWindowText(sPass);m_pass2.ShowWindow(SW_HIDE); //设置隐藏数据int nItem = (int)GetWindowLongPtr(m_pass2.GetSafeHwnd(), GWLP_USERDATA); //取出第几行if (nItem < 0)return;CString str = m_list.GetItemText(nItem, 0);if(ChangePass(str,sPass)){Refresh();AfxMessageBox(str + _T(" 密码修改成功!"));}elseAfxMessageBox(str + _T(" 密码修改失败!"));
}
void CAdminDlg::OnCancel()
{if (m_pass2.IsWindowVisible()){m_pass2.ShowWindow(SW_HIDE);return;}if (m_combox2.IsWindowVisible()){m_combox2.ShowWindow(SW_HIDE);return;}EndDialog(IDCANCEL);
}
void CAdminDlg::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) //双击列表
{LPNMITEMACTIVATE p = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);*pResult = 0;int nItem = p->iItem; //第几行int nSubItem = p->iSubItem; //第几列CRect rect;CString str = m_list.GetItemText(nItem, nSubItem);m_list.GetSubItemRect(nItem, nSubItem, 0, rect);  //回去第几行第几列的 图标在哪个位置 把它移动上去switch (nSubItem)  {case 1:m_pass2.SetParent(&m_list); //设置父亲m_pass2.MoveWindow(rect, FALSE);m_pass2.ShowWindow(SW_SHOW);m_pass2.SetWindowText(str);m_pass2.SetFocus();m_pass2.SetSel(0, -1);				//  设置一个数据,可用来修改GWL_STYLE,设置隐藏数据SetWindowLongPtr(m_pass2.GetSafeHwnd(), GWLP_USERDATA, nItem);  //取出第几行break; case 2:m_combox2.ShowWindow(SW_HIDE);m_combox2.SetParent(&m_list);  m_combox2.MoveWindow(rect, FALSE);m_combox2.ShowWindow(SW_SHOW);m_combox2.SetFocus();m_combox2.SetCurSel(str == _T("普通"));SetWindowLongPtr(m_pass2.GetSafeHwnd(), GWLP_USERDATA, nItem);  break; }//m_list.EditLabel(p->iItem); //用于编辑首行 
}
void CAdminDlg::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult) //编辑完成之后只能编辑第一个 
{NMLVDISPINFO* pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);*pResult = 0;auto pEdit = m_list.GetEditControl();if (!pEdit)return;CString str;pEdit->GetWindowText(str); //可以取出编辑之后的文字
}
void CAdminDlg::OnSelchangePrior2()	{ m_combox2.ShowWindow(SW_HIDE);AfxMessageBox(_T("修改权限")); //做网络协议发送
}

最终效果:
在这里插入图片描述

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

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

相关文章

【高危】Atlassian Confluence 远程代码执行漏洞

漏洞描述 Confluence 是由 Atlassian 开发的知识管理与协同软件&#xff0c;通常在企业内部用作wiki系统。 Confluence 7.19.8到8.2.0之前的版本中存在远程代码执行漏洞&#xff0c;具有登录权限的攻击者无需用户交互即可在 Confluence 服务器中执行任意命令。 漏洞名称Atlass…

【Boost搜索引擎项目】

文章目录 一、项目流程二、项目展示 一、项目流程 1.编写数据去标签模块–parser.cc 将去标签之后干净文档以title\3content\3url\ntitle\3content\3url\n格式放入同一文件中。 2.建立索引模块–index.hpp 读取处理好的行文本文件进行分词、权重计算等操作&#xff0c;在内存中…

【云驻共创】CodeArts Repo ---高效代码协同开发之旅

目录 一、代码托管发展史 1.1 第一代 1.2 第二代 1.3 第三代 二、CodeArts Repo 介绍 二、CodeArts Repo 功能架构 2.1 研发协同 2.2 代码管理功能 2.3 代码存储特性 三、CodeArts Repo 技术能力 三、华为云代码托管技术发展历程 四、CodeAr…

ubuntu挂载ext4文件系统

文章目录 1.虚拟机分配10G磁盘用来挂载ext4文件系统2.磁盘分区3.创建文件系统4.挂载文件系统5.卸载文件系统6.使用ior测试ext4三种日志模式&#xff08;1&#xff09;ordered&#xff08;2&#xff09;journal&#xff08;3&#xff09;writeback 1.虚拟机分配10G磁盘用来挂载e…

SpringBoot项目修改Tomcat版本号

SpringBoot项目修改Tomcat版本号 前言如果项目是以jar包形式打包部署如果项目是以war包形式打包部署示例 仰天大笑出门去&#xff0c;我辈岂是蓬蒿人 前言 Springboot项目,默认是使用内嵌Tomcat servlet容器形式打包部署。关于怎么修改默认的版本号&#xff0c;捣鼓了好久终于…

PostgreSQL 设置时区,时间/日期函数汇总

文章目录 前言查看时区修改时区时间/日期操作符和函数时间/日期操作符日期/时间函数&#xff1a;extract&#xff0c;date_part函数支持的field 数据类型格式化函数用于日期/时间格式化的模式&#xff1a; 扩展 前言 本文基于 PostgreSQL 12.6 版本&#xff0c;不同版本的函数…

基于STM32设计的人体健康监护系统(华为云IOT)

一、设计需求 1.1 设计需求总结 根据需求,要求设计一款基于 STM32 的人体健康监护系统。采用系统模块化思路进行,将多个数模传感器收集到的数据和操作指令一并送至 STM32 中心处理器进行处理分析。 该系统可以实时监测被测者的心率、体温以及周围环境的温度,也同时可以通…

(vue)vue项目中引入外部字体

(vue)vue项目中引入外部字体 效果&#xff1a; 第一步 放置字体包&#xff0c;在assets下创建一个fonts文件夹&#xff0c;放入下载的字体文件 第二步 创建一个font.css文件用于定义这个字体包的名字 第三步 在App.vue的css中将这个css文件引入 第四步 页面使用 font-famil…

Qt : day1

1.聊天界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {qDebug() << this->size(); //获取当前页面尺寸this->setFixedSize(500, 600); //设置固定尺寸this->setWindowTitle("聊天框"); //设置窗口…

单Bank OTA升级:STM32G071 APP (二)

接上一篇文章&#xff1a;单Bank OTA升级&#xff1a;STM32G071 BootLoader (一)&#xff1a;跳转链接 什么是单Bank升级&#xff1a;将Flash划分为以下3个区域。 BootLoader区&#xff1a;程序进行升级的引导程序&#xff0c;根据Upade_Flag来判断跳转Bank区运行程序或是接收…

安卓开发后台应用周期循环获取位置信息上报服务器

问题背景 最近有需求&#xff0c;在APP启动后&#xff0c;退到后台&#xff0c;还要能实现周期获取位置信息上报服务器&#xff0c;研究了一下实现方案。 问题分析 一、APP退到后台后网络请求实现 APP退到后台后&#xff0c;实现周期循环发送网络请求。目前尝试了两种方案是…

Spring 中一个少见的引介增强 IntroductionAdvisor

我们平时做 AOP 开发的时候&#xff0c;基本上都是增强某一个方法&#xff0c;在某一个方法执行之前或者执行之后做一些事情&#xff0c;这种叫做 PointcutAdvisor&#xff0c;实际上&#xff0c;Spring 中的 Advisor 大致可以分为两种类型&#xff0c;除了 PointcutAdvisor 之…

Openlayers实战,Openlayers实现一个车辆转向运动轨迹动画,支持根据轨迹运动方向自动改变车头转向角度,无需定时器,丝滑小车转向运动效果

专栏目录: OpenLayers入门教程汇总目录 前言 本章作为OpenLayers入门文章《OpenLayers入门,OpenLayers动画效果实现,OpenLayers实现轨迹运动动画》的的增强进阶篇章,实现了入门教程中没有实现的小车车头方向根据运动方向自动转向的功能。 本章代码不使用任何setTimeout和…

金融中的数学:贝叶斯公式

1.贝叶斯定理 贝叶斯定理是概率论中的一项重要定理&#xff0c;用于在已知某一事件的条件下&#xff0c;求另一事件发生的概率。它是根据条件概率推导出来的&#xff0c;得名于英国数学家托马斯贝叶斯。 贝叶斯定理可以表示为&#xff1a; 这个式子就是贝叶斯公式&#xff0c…

解决FLink:Missing required options are: slot.name

[ERROR] Could not execute SQL statement. Reason: org.apache.flink.table.api.ValidationException: One or more required options are missing.Missing required options are:slot.name解决 https://ververica.github.io/flink-cdc-connectors/release-2.4/content/connec…

提升 API 可靠性的五种方法

API 在我们的数字世界中发挥着关键的作用&#xff0c;使各种不同的应用能够相互通信。然而&#xff0c;这些 API 的可靠性是保证依赖它们的应用程序功能正常、性能稳定的关键因素。本文&#xff0c;我们将探讨提高 API 可靠性的五种主要策略。 1.全面测试 要确保 API 的可靠性…

Seata部署(Centos和Docker)

一、简介 Seata 是一款开源的分布式事务框架。致力于在微服务架构下提供高性能和简单易用的分布式事务服 务。在 Seata 开源之前&#xff0c;Seata 对应的内部版本在阿里经济体内部一直扮演着分布式一致性中间件的⻆ 色&#xff0c;帮助经济体平稳的度过历年的双11&#xff0c…

11 spring-boot的MVC配置原理

11.1 spring-boot为MVC提供的自动配置 1.ContentNegotiatingViewResolver视图解析器&#xff1b; 2.静态资源或者支持WebJars&#xff1b; 3.自动注册类型转换器&#xff1a;比如说前台提交user的字段&#xff0c;后台自动封装的意思&#xff1b; 4.HttpMessageConverters&…

Vue中TodoList案例_勾选

与上一篇Vue中TodoList案例_添加有三个文件变化了 App.vue&#xff1a;中加了checkTodo方法 <template><div id"root"><div class"todo-container"><div class"todo-wrap"><MyHeader :addTodo"addTodo"/&…

Linux学习之case

case的格式如下&#xff1a; case "变量" in值1)指令集1;;值2)指令集2;;*)指令集n;; esaccase会将变量的值跟值1、值2等进行比较&#xff0c;符合就执行后边对应的指令集&#xff0c;注意)只是一个标识&#xff0c;表明这是一个分支&#xff0c;;;是一个分支结束&am…