3.8 编码工作
2006年10月16日,阳光明媚
经过前几天的通宵达旦,我终于可以开始具体设计编码的工作了。在开始之前,我又看了一遍系统需求分析和模块划分,整个窗体的设计任务就很明确了。
3.8.1 设计员工模块(1)
2006年10月16日,下午
作为人事管理系统,员工是其管理的对象,也是整个系统管理的基础和前提,有了员工这个核心的实体,工资、考勤等信息才能进行相应的管理。员工管理设计的好坏将会直接影响整个系统功能的完善。员工模块功能主要实现了员工信息的录入、修改、删除等操作,当用户登录系统后通过选择相应的菜单显示员工信息界面,继而可以实现增添、修改、查询、删除等模块功能。在添加数据时我将借助picture控件和DateTimePicker控件实现员工相片和出生日期数据添加,并保存到数据库中。
员工模块的功能是通过对数据表emp执行相应的操作来实现的。照片显示用picture控件实现,员工生日日期用DateTimePicker控件设置或获取。通过相应的SQL语句完成各模块功能,其中相片的添加操作涉及如何向SQL Server数据库中存取长二进制数据。另外,通过树形控件和列表控件来显示员工的信息,通过这两个控件信息的交互来完成相应的查询操作。
1. 添加员工
在具体实现之前,首先要进行ADO的初始化工作,具体的细节在前面的章节中已经有了详细的介绍,读者可以参考前面的内容来完成ADO的初始化。接下来连接数据库,可以在应用类的头文件中定义一个_ConnectionPtr型的变量m_pConnection,用来连接数据库和执行相应的SQL语句。具体实现流程如下。
(1) 添加一个对话框资源,将ID号改为IDD_EMP_ADD_DLG,在对话框上添加如图3-7所示的控件。
|
| 图3-7 添加员工信息设计界面 |
(2) 双击对话框为对话框资源创建一个新类CEmpAddDlg。在头文件中定义变量。头文件中相应的代码如下:
- class CEmpAddDlg : public CDialog
- {
- public:
- CEmpAddDlg(CWnd* pParent = NULL); //构造函数
- HBITMAP m_hBitmap; //定义位图的句柄
- DWORD m_nFileLen; //定义双字变量
- char *m_pBMPBuffer; //定义字符指针
- _RecordsetPtr m_pRecordset; //定义记录集指针
- HBITMAP m_hPhotoBitmap;
//定义位图的句柄 - }
上面的代码为CEmpAddDlg类中自定义的成员变量,其中m_hPhotoBitMap保存位图的句柄,m_nFileLen保存位图文件二进制代码的长度,m_pBMPBuffer为位图文件提供存储空间。
(3) 通过类向导为控件添加相应的变量。并为对话框添加WM_INITDIALOG消息响应函数。OnInitDialog()中的代码如下:
- BOOL CEmpAddDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- CString strSQL;
//定义字符串变量 - strSQL.Format("select name from dep"); //格式化SQL语句
- try
- {
- m_pRecordset = theApp.m_pConnection->Execute
- ((_bstr_t)strSQL, NULL, adCmdText);
- while(!m_pRecordset->adoEOF)
//如果记录没有到末尾 - {
- m_DepartCtrl.AddString((char*)_bstr_t(m_pRecordset-
- >GetCollect (_variant_t((long)0))));
- m_pRecordset->MoveNext();
//移动到下一条记录 - }
- }
- CATCH_ERROR;
- m_SexCtrl.SetCurSel(0);
//选中下拉列表第一项 - m_DepartCtrl.SetCurSel(0);
- return TRUE;
- }
通过上述代码完成了对话框初始化工作,借助Format( )函数构造SQL语句,查询dep表中所有数据的name字段值,再遍历记录集将查询到的所有数据插入组合框中。其中m_SexCtrl与m_DepartCtrl为CComboBox类型的变量,其成员函数AddString( )实现了将字符串插入组合框中。
(4) 通过类向导为对话框添加WM_PAINT消息响应函数。该函数主要完成员工照片的显示。
- void CEmpAddDlg::OnPaint()
- {
- CPaintDC dc(this);
- CStatic *pStaic = (CStatic*)GetDlgItem(IDC_PHOTO);
//获取控件的指针 - CBitmap bmp;
//定义位图变量 - bmp.Attach(m_hPhotoBitmap);
- BITMAP bm;
//定义一个位图结构 - bmp.GetBitmap(&bm);
- CDC dcMem;
- dcMem.CreateCompatibleDC(GetDC());
//创建一个兼容的DC - CBitmap *poldBitmap=(CBitmap*)dcMem.SelectObject(bmp);
- /将位图选入设备环境
- CRect lRect;
//定义一个区域 - pStaic->GetClientRect(&lRect);
//获取控件的客户区域 - lRect.NormalizeRect();
- pStaic->GetDC()->StretchBlt(lRect.left, lRect.top, lRect.Width(),
- lRect. Height(),&dcMem,0 ,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
- //显示位图
- dcMem.SelectObject(&poldBitmap);
//将句柄选入设备环境 - }
通过上述代码完成了照片的显示,通过GetDlgItem( )函数获取Picture控件的指针,并创建一个兼容的DC。借助GetDC( )函数获取控件的绘图指针,然后再借助StretchBit( )函数来显示位图。
(5) 通过类向导为对话框添加WM_LBUTTONDOWN消息响应函数。该函数主要通过判断鼠标左键是否在Picture控件上单击,调用打开文件对话框。相关代码如下:
- void CEmpAddDlg::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CRect Rect;
//定义一个区域 - GetDlgItem(IDC_PHOTO)->GetWindowRect(&Rect);
//获取区域 - ScreenToClient(&Rect);
//转换客户坐标 - if(Rect.PtInRect(point))
//如果在这个区域内 - {
- CFileDialog FileDlg(TRUE, "BMP", NULL,
//定义文件对话框 - OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"位图文件(*.BMP)|*.BMP||"); - if(FileDlg.DoModal() != IDOK)
//打开文件对话框 - return ;
- CString pathname = FileDlg.GetPathName();
//获取选中文件的路径 - CFile file;
//定义一个文件变量 - if(!file.Open(pathname, CFile::modeRead) )
//只读方式打开文件 - return ;
- m_nFileLen = file.GetLength();
//获取文件的长度 - m_pBMPBuffer = new char[m_nFileLen + 1];
//开辟符数组 - if(!m_pBMPBuffer)
//如果空间不够大 - return ;
- if(file.ReadHuge(m_pBMPBuffer,m_nFileLen)
!= m_nFileLen) //读取文件 - return ;
- LPSTR hDIB,lpBuffer = m_pBMPBuffer;
- LPVOID lpDIBBits;
- BITMAPFILEHEADER bmfHeader;
//保存bmp文件头 - DWORD bmfHeaderLen;
//保存文件头的长度 - bmfHeaderLen = sizeof(bmfHeader);
//读取文件头的长度 - strncpy((LPSTR)&bmfHeader,(LPSTR)lpBuffer,bmfHeaderLen);
- /文件的赋值
- if (bmfHeader.bfType != (*(WORD*)"BM"))
//如果文件类型不对 - return ;
- hDIB = lpBuffer + bmfHeaderLen;
//指针移动文件头后 - BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
- BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
- lpDIBBits=(lpBuffer)+((BITMAPFILEHEADER *)
lpBuffer)->bfOffBits; - CClientDC dc(this);
- m_hPhotoBitmap = CreateDIBitmap(dc.m_hDC,
&bmiHeader, //创建位图 - CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);
- Invalidate(); //刷新
- }
- CDialog::OnLButtonDown(nFlags, point);
- }
通过上述代码完成了图片文件的读取。GetWindowRect( )函数获取控件区域的大小,通过ScreenToClient( )函数转换成客户区域,函数PtInRect( )实现判断当前鼠标的位置是否在控件的区域中。借助CFile类的ReadHuge( )函数实现读取照片数据,将照片文件转换成二进制代码。