图像列表类支持内部有动态数组的控件 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 member
operator 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::SetSize
BOOL 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: // Implementation
virtual ~CImageList();
#ifdef _DEBUG
virtual void Dump(CDumpContext& dc) const;
virtual void AssertValid() const;
#endif
};
a)高宽(x,y)和2个图片句柄
b)图片的句柄有1张彩色,另一张是黑白(Mask)
typedef struct _ICONINFO {
BOOL fIcon;
DWORD xHotspot;
DWORD yHotspot;
HBITMAP hbmMask;
HBITMAP hbmColor;
} ICONINFO, *PICONINFO;
编辑列表项:默认的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::SetItemXXX
全部数据设置:CListCtrl::SetItem Sets some or all of a list view item's attributes.
CListCtrl::SetItemCount
Prepares 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::SetItemIndexState
Sets the state of an item in the current list-view control.
CListCtrl::SetItemPosition
Moves 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);
主要有五个窗口 组成
Page1基本信息工号 工资等 对其都采用关联性数据变量 方便操作
Page2 扩展信息 性别 学历等 同样采用关联性数据变量 方便操作
修改窗口 采用Tab Ctrl控件,
数据录入窗口
主窗口
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;
};
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;
// 重写
}
class CPage1 : public CDialogEx
{
DECLARE_DYNAMIC(CPage1)
void OnOK();
public:
CPage1(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CPage1();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_PAGE1 };
#endif
protected:
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;
};
#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);
else
NextDlgCtrl();
}
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()
#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_TIME
enum { IDD = IDD_PAGE2 };
#endif
protected:
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;
};
#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()
#pragma once
#include "afxdialogex.h"
class CWorkerDlg : public CDialogEx
{
DECLARE_DYNAMIC(CWorkerDlg)
CImageList m_hList;//Header
CString 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_TIME
enum { IDD = IDD_WORKER_DIG };
#endif
protected:
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();
};
#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);
}
#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_TIME
enum { IDD = IDD_MODIFY_DLG };
#endif
protected:
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);
};
#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();
}
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;
}
}
#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_TIME
enum { IDD = IDD_COUNT };
#endif
protected:
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();
};
#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();
}
else
AfxMessageBox(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(" 密码修改成功!"));
}
else
AfxMessageBox(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("修改权限")); //做网络协议发送
}