还剩8页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
吉林省明日科技有限公司监制吉林省明日科技有限公司监制进销存管理系统学院专业班级学号姓名指导教师教师职称年月日目录TOC\o1-3\n\p\h\z摘要【摘要】随着国家的政治经济政策的优化改革,使得国内中小企业得以蓬勃发展可是随着企业的发展,客户数量的的为断增多,财务工作繁杂化,库存产品零乱等一系列问题也接踵而至,给企业经营者运作带来了很大的困扰信息技术的迅猛发展,科学经营管理观念的迅速传播,使中小企业经营者逐渐认识到转变企业经营管理理念,改善企业经营管理模式是企业适应时代的发展急需解决的问题现代管理,应该建立在真实、有效的数据信息基础之上,应该是一种科学的、理性的管理体制,而这种管理与经营的联系与互助,又必须依赖于计算机的强大的数据统计功能,计算机管理系统便是实际的企业进销问题与计算机强大数据统计功能相结合的产物管理系统解决的了商业企业商品的进、销、存、退、换、盘、损、残、调、借、赠等一系列操作流程中的数据信息的处理问题,提供一系列的数据分析,帮助经营者合理的调整各个经营运作环节的运作节奏,并对商品流转过程进行了全程跟踪管理、相应款项流通的全程记录管理和票据信息统计的管理因此进销存管理系统的全面应用,规范业务流程、提高了企业的管理水平,提高资金流动的透明度,加快商品资金周转速度,进而全面提高了企业的经营水平、进而全面提升了企业的经济效益【关键词】进销存管理系统0引言企业经营如逆水行舟不进则退每一个努力发展的企业都明白,先进管理的重要作用,引进先进管理系统使企业经营变得规范、合理进销存管理系统无论是在功能设计还是业务流程上都尽可能做到满足经营管理运作流程的需求,并且操作方便、功能强大,即使操作者对计算机知识一窍不通也能一用就会它强化库存管理,规范业务流程,提高资金管理的透明度,加快商品资金周转,是企业经营管理中数据分析中必不可少的管理工具1系统需求分析根据市场的需求,要求系统具有以下功能实现商品入库、入库退货操作实现商品销售、销售退货操作实现库存管理(调货、盘点)操作实现信息的查询、打印功能准确地进行账款记录、账款查询2总体设计
2.1项目规划根据需求分析,设计系统框架进销存管理系统由等8部分组成设计各部分具体功能如下基础信息模块基础信息模块包括药品信息、员工信息、供应商信息和客户信息4部分销售模块销售模块由销售登记、销售退货、销售查询、销售退货查询4部分入库模块入库模块主要由入库登记、入库退货、入库查询、入库退货查询4组成调货模块调货模块包含调货登记和调货查询两部分库存模块库存模块由库存盘点、库存查询、仓库管理3部分组成结账模块结账模块主要包括销售结账、销售退货结账、入库结账、入库退货结账财务模块财务模块由日结、月结、供应商往来账、客户往来账4部分组成系统管理模块系统管理模块由修改用户密码、修改用户权限、修改用户3部分组成
2.2系统功能结构进销存管理系统的功能结构如图1所示#0;��������#0;��������������#0;#0;��������#0;��������#0;#0;#0;#0;#0;��������#0;��������#0;��������#0;��������#0;#0;#0;#0;#0;��������#0;��������#0;��������#0;��������#0;#0;��������#0;#0;������������#0;��������#0;#0;#0;��������#0;��������#0;��������#0;��������#0;��������#0;#0;��������#0;��������#0;������������#0;����������#0;#0;��������#0;#0;#0;#0;������������#0;��������#0;������������#0;#0;#0;#0;#0;#0;��������#0;����#0;����#0;������������#0;����������#0;#0;#0;#0;#0;������������#0;������������#0;������������#0;��������#0;#0;#0;#0;#0;#0;图1进销存管理系统功能架构图3设计目标本系统是根据中小企业的实际需求而开发的,完全能够实现商品入库、销售管理,通过本系统可以达到以下目标系统运行稳定,安全可靠界面设计美观,人机交互界面友好信息查询灵活、方便、快捷、准确,数据存储安全可靠强大的报表预览、打印功能信息安全保密3系统设计
3.1开发及运行环境1.硬件要求CPU300MHz以上的处理器内存128MB,推荐256MB硬盘150MB以上剩余空间显示像素最低800*600,最佳效果1024*7682.软件要求操作系统Windows2000/NT/XP/CE数据库SQLServer
20003.2数据库设计1.数据库概要说明本系统采用SQLServer2000数据库,系统数据库名为ypgl,中共包含46个表,其中作为临时表的有20个,作为数据存储表的有26个临时表lsdhinfo
0、lsdhinfo
1、lsgys
0、lsgys
1、lskcquery
0、lskcquery
1、lskh
0、lskh
1、lsrkquery
0、lsrkquery
1、lsrkthinfo
0、lsrkthinfo
1、lsxsquery
0、lsxsquery
1、lsxsthinfo
0、lsxsthinfo
1、lsyg
0、lsyg
1、lsypinfo
0、lsypinfo1数据存储表tabbf、tabck、tabdhdj、tabdhph、tabgys、tabjsfs、tabkc、tabkcpddj、tabkcpdph、tabkh、tabpurview、tabpurviewctrl、tabrkdj、tabrkjz、tabrkph、tabrkthdj、tabrkthjz、tabrkthph、tabxsdj、tabxsjz、tabxsph、tabxsthdj、tabxsthjz、tabxsthph、tabyginfo、tabypinfo图2所示的即为本系统中数据库的数据表结构图,该数据表结构图包含系统所有数据表可以清晰地反应数据库信息图2数据库概要说明2.主要数据表的结构数据库中的数据表请参见附录B4功能模块设计
4.1主窗口设计进销存管理系统主窗口由菜单、工具栏、客户区域和状态栏四部分组成,效果如图3所示图3进销存管理系统主窗口1.菜单设计
(1)在工具栏中单击按钮,或者从菜单中选择“View”/“Workspace”项,这时会弹出如图4所示的工作区窗口(Workspace窗口)在工作区窗口中,能看到该程序所使用的资源,且每种资源都有一个资源符号,主窗体也使用了一个资源符号IDD_A1_DIALOG,这是VC缺省提供的可以在这里添加或者删除各种资源图4Workspace窗口
(2)在工作区窗口(Workspace窗口)右键单击“a1resources”选项,在弹出菜单中选择“Insert...”选项,将弹出“InsertResource”对话框在该对话框中选择“Menu”选项,然后单击“New”按钮,将生成如图5所示的菜单资源图5编辑菜单资源
(3)右键双击菜单资源编辑器的虚线空白框,在弹出的菜单中选择“Properties”选项,将弹出“MenuItemProperties”对话框,在“MenuItemProperties”对话框的“caption”(标题)编辑框中键入“基础信息(I)”(符号可以使字母I有一个下划线,而且可以通过“Alt+I”访问该菜单项此时关闭“MenuItemProperties”对话框,将在菜单编辑器中生成主菜单“基础信息”双击“基础信息”菜单下的虚线空白框,在弹出的“MenuItemProperties”对话框中设计“药品信息(M)”、“员工信息(Y)”等菜单项
(4)同上,可以设计其他主菜单及菜单项最后得到如图6所示的菜单界面图6菜单界面2.工具栏设计在应用程序中要经常使用工具栏,它是最常用的界面元素,对应着应用程序的最常用功能主窗口共有9个工具栏按钮,分别是“销售登记”、“销售退货”、“销售结账”、“入库登记”、“入库退货”、“入库结账”、“调货登记”、“库存登记”、“退出”工具栏按钮创建工具栏可使用MFC类库中的CToolBarCtrl类,该类用来生成工具条本系统主窗体的工具栏将引用MSDN提供的类CStandardBar,该类派生自CToolBarCtrl操作步骤如下
(1)从基类CToolBarCtrl中派生需要的类CstandardBar选择“Insert”/“NewClass...”菜单项,在弹出来的“NewClass”对话框中设置“ClassType”为“MFCClass”,在“ClassInfomation”中的Name编辑框中键入“CstandardBar”,然后在“BaseClass”下拉列表框中选择“CtoolBarCtrl”,最后单击“OK”按钮
(2)需要9个按钮,每个按钮有相应的文本和图片所以,需要添加如图7所示的图片资源,资源长为288像素,高为32像素,资源符号为IDR_STANDARDBAR图7图片资源
(3)添加字符串资源(StringTable),如表1所示表1字符串资源资源符号值字符串资源IDSTR_XSDJ102销售登记IDSTR_XSTH103销售退货IDSTR_XSJZ104销售结账IDSTR_RKDJ105入库登记IDSTR_RKTH106入库退货IDSTR_RKJZ107入库结账IDSTR_DHDJ108调货登记IDSTR_KCPD109库存盘点IDSTR_OUT110退出
(4)程序中引入资源,创建工具栏按钮创建工具栏按钮需要重写Create函数,该函数创建工具栏的步骤如下
①先创建工具栏窗口,然后为工具栏类添加图片资源相关函数是SetBitmapSizeCSize3232;//设置单个位图的大小VERIFYAddBitmapm_nButtonCountIDR_STANDARDBAR!=-1;//添加位图m_nButtonCount是指按钮图片的个数,IDR_STANDARDBAR对应着相应的图片
②创建相应数量的按钮,并为每个按钮分配相应图片资源和文本资源,设置相关属性m_pTBButtons=newTBBUTTON[m_nButtonCount];//用来加入到工具栏里的按钮……m_pTBButtons[nIndex].iString=AddStringspString;m_pTBButtons[nIndex].fsState=TBSTATE_ENABLED;m_pTBButtons[nIndex].fsStyle=TBSTYLE_BUTTON;m_pTBButtons[nIndex].dwData=0;m_pTBButtons[nIndex].iBitmap=nIndex;//控制按钮的相关图片m_pTBButtons[nIndex].idCommand=nIndex+IDSTR_XSDJ;//用于命令消息传递在步骤
②中,要注意如下事项
①AddStringspString返回一个字符串的基于0的编号,该值用来连接字符串到按钮上,其中的字符串参数pString需要两个结束符来表示结尾,必须将字符串写成如下形式pString=Onlyonestringtoadd\0;CString类不能提供这样的功能,因为不可能在CString中保存超过一个结束符的字符串所以,将CString中的字符串取出,以char定义的字符串保存,再对该字符串添加一个结束符,做法如下CStringstring;string.LoadStringnIndex+IDSTR_XSDJ;//装载字符串资源……//取得字符串的长度为了添加一个结束符,给长度加1intnStringLength=string.GetLength+1;……TCHAR*pString=string.GetBufferSetLengthnStringLength;//按增加后的长度返回字符串pString[nStringLength]=0;函数GetBufferSetLength的过程分配了nStringLength+1长度的内存空间,并在加上结束符\0之后,复制原字符串到这个新的内存空间中,同时将原字符串的结束符也复制到新的位置,于是,该函数结束后,字符串pString已经有两个结束符了,最后一个语句略显多余或不足但为了保证该字符串确实有两个结束符,不能省略这两个结束符pString[nStringLength]=0;pString[nStringLength-1]=0;
②fsState确定按钮的状态,fsStyle确定按钮的风格若给fsStyle赋值TBSTYLE_SEP,则该按钮表现为一个间隔dwData可以是用户自定义的数据,可以将一个指针或句柄传递给它,可以在某些消息响应函数中使用iBitmap是表示基于0的图像列表的编号
③idCommand为与按钮连接的命令标识,当这个按钮被按下时,这个值将被放到WM_COMMAND中发送到父窗体如果fsStyle被设置为TBSTYLE_SEP,该值必须为0用Create函数创建工具栏的代码如下BOOLCStandardBar::CreateDWORDdwStyleconstRECTrectCWnd*pParentWndUINTnID;{BOOLbRet=CToolBarCtrl::CreatedwStylerectpParentWndnID;//记录基类的返回值m_nButtonCount=IDSTR_OUT-IDSTR_XSDJ+1;SetBitmapSizeCSize3232;//设置单个位图的大小VERIFYAddBitmapm_nButtonCountIDR_STANDARDBAR!=-1;//添加位图m_pTBButtons=newTBBUTTON[m_nButtonCount];//用来加入到工具栏里的按钮forintnIndex=0;nIndexm_nButtonCount;nIndex++//循环设定按钮属性{CStringstring;string.LoadStringnIndex+IDSTR_XSDJ;//装载字符串资源//为每一个字符串再加一个\0,用于向工具栏里加字符串intnStringLength=string.GetLength+1;TCHAR*pString=string.GetBufferSetLengthnStringLength;pString[nStringLength]=0;pString[nStringLength-1]=0;VERIFYm_pTBButtons[nIndex].iString=AddStringspString!=-1;//返回字符串的编号string.ReleaseBuffer;m_pTBButtons[nIndex].fsState=TBSTATE_ENABLED;m_pTBButtons[nIndex].fsStyle=TBSTYLE_BUTTON;m_pTBButtons[nIndex].dwData=0;m_pTBButtons[nIndex].iBitmap=nIndex;//控制按钮的相关图片m_pTBButtons[nIndex].idCommand=nIndex+IDSTR_XSDJ;//用于命令消息传递}m_pTBButtons[m_nButtonCount-1].idCommand=IDOK;//用来响应退出消息TBBUTTONsepButton;//用于分隔的按钮sepButton.idCommand=0;sepButton.fsStyle=TBSTYLE_SEP;sepButton.fsState=TBSTATE_ENABLED;sepButton.iString=0;sepButton.iBitmap=0;sepButton.dwData=0;fornIndex=0;nIndexm_nButtonCount;nIndex++{VERIFYAddButtons1m_pTBButtons[nIndex];//循环添加按钮if!nIndex+1%3{VERIFYAddButtons1sepButton;//每3个按钮为一组,两组间有一个分隔按钮}}returnbRet;//返回CToolBarCtrl::Create的返回值}
(5)调用工具栏类先在类CA1Dlg中实例化CStandardBar的对象CStandardBarm_StandardBar;别忘了在这个文件里包含CStandardBar类声明所在的头文件#includeStandardBar.h
(6)增加消息WM_CREATE的响应函数,为CStandardBar对象创建相应窗口intCA1Dlg::OnCreateLPCREATESTRUCTlpCreateStruct{ifCDialog::OnCreatelpCreateStruct==-1return-1;m_StandardBar.CreateWS_BORDER|WS_VISIBLE|WS_CHILD|TBSTYLE_WRAPABLE|CCS_TOP|CCS_ADJUSTABLECRect0000thisIDR_STANDARDBAR1;m_StandardBar.AutoSize;//重新计算控件的大小return0;}工具栏到这里就创建成功了3.为菜单和工具栏添加消息处理函数在此之前,定义了菜单和工具栏界面,单击他们并没有实质的内容,现在为他们添加消息处理函数
(1)单击菜单和工具栏按钮的两种消息都是命令消息,所以,只要让他们传递相同的消息,就能执行相同的消息处理函数从代码中可以看到对于工具栏的按钮来说,按钮的命令消息值与字符串资源符号的值相同,而且是顺序的,而对于相应的菜单项来说,消息值是随机的顺序值为了将两者对应起来,要修改菜单项的资源符号,将其改为相应的按钮的字符串资源符号例如将销售登记菜单项的资源符号改为IDSTR_XSDJ,并给它定义消息响应函数voidCA1Dlg::OnXsdj这样,无论是单击“销售登记”菜单项,还是单击“销售登记”按钮都会执行这个函数同理,完成其他的菜单项与按钮的对应
(2)还有一个问题别忘了,工具栏中有一个“退出”按钮这个退出按钮与谁对应呢?当用户按下〈Enter〉键或〈Esc〉键时,对话框就会退出,这里触发的两个消息分别是IDOK和IDCANCEL如果给“退出”按钮的命令消息值赋值为IDOK,那么单击该按钮时,对话框就会退出代码如下m_pTBButtons[m_nButtonCount-1].idCommand=IDOK;//用来响应退出消息4.状态栏设计为使应用程序操作界面更加友好,可以使用状态条显示程序当前程序的状态信息或提示信息在VC中提供了CStatusBarCtrl类显示状态栏在本程序中利用状态条显示操作者、日期、时间等信息其实还有CStatusBar类可以显示状态栏,但是这个类只能用于主框架(CFrameWnd)上分析功能显示操作员名字、公司名称及时间其中,公司名称是常量字符串,可以将其加为字符串资源;操作员名字,是登录的用户名,将其放在应用程序类中,这样,就可以在程序的任何地方都可以访问了;时间,需要设置OnTimer时间来处理当时间改变时,刷新显示
(1)解决创建状态栏的相关问题
①访问应用程序对象CA1App*app=CA1App*::AfxGetApp;//app是应用程序对象指针,可以访问应用程序对象的成员变量,例如MessageBoxapp-m_sUserName;
②访问资源字符串先在“Workspace”中的“ResourceView”选项中建立字符串资源,定义符号IDS_COMPANY,对应资源为“明日腾龙科技有限责任公司(www.mingrisoft.com)”在程序中使用如下代码CStringstr;str.LoadStringIDS_COMPANY;str保存相应的字符串资源
③将访问时间转化为字符串CTimet=CTime::GetCurrentTime;CStrings=t.Format%H:%M:%S;s=当前系统时间+s;s会显示为“当前系统时间200925”形式的字符串
④OnTimer消息响应函数为实现每隔1秒刷新一次状态栏的显示内容,可以使用WM_TIMER的消息响应函数OnTimer要创建主窗体的OnTimer函数,首先在“Workspace”工作区“ClassView”选项卡中右键单击“CA1Dlg”选项,在弹出菜单中选择“AddWindowsMessageHandle...”菜单项,将弹出“NewWindowsMessageandeventhandlesforclassCAIDlg”对话框在该对话框中,可以选择要进行处理的消息句柄,并为其添加消息响应函数步骤是从左边的列表框中双击“WM_TIMER”,将其添加到右上边的列表框中,双击该列表框中的“WM_TIMER”项,可以看到VC++创建的函数OnTimer,可以设置这个函数每隔一定的时间响应一次函数SetTimer来设置OnTimer的消息响应频率UINTSetTimerUINTnIDEventUINTnElapsevoidCALLBACKEXPORT*lpfnTimerHWNDUINTUINTDWORD;参数说明nIDEvent用来标识是哪一个Timer事件nElapse设置该Timer事件每隔多长时间发生一次,单位毫秒lpfnTimer设置回调函数,用来响应事件的发生,相当于OnTimer函数如果将其设为NULL,那么,WM_TIMER事件由窗口类来处理,即由OnTimer函数处理在本程序中,设定OnTimer函数1000毫秒响应一次SetTimer121000NULL;
⑤状态栏类CStatusBarCtrl的使用CRectrect;this-GetClientRectrect;intindicators
[3];indicators
[0]=rect.Width/2;indicators
[1]=rect.Width*3/4;indicators
[2]=rect.Width;m_StatusBarCtrl.SetParts3indicators;以上代码用来初始化状态栏,函数SetParts用来设定该状态栏由几个面板组成,每个面板的宽度实际上,该函数用整型数组作参数,数组元素的值代表面板的宽度函数SetText用来设定每个面板上显示的数据,代码如下lBOOLSetTextLPCTSTRlpszTextintnPaneintnType;参数说明lpszText是该面板的字符串nPane是面板编号(基于0)nType是面板风格,该参数一般为0
(2)创建状态栏创建状态栏的操作步骤如下
①在CA1Dlg的声明中定义CStatusBarCtrl的对象CStatusBarCtrl*m_StatusBarCtrl
②在CA1Dlg的初始化函数中初始化状态栏对象,代码如下BOOLCA1Dlg::OnInitDialog{CDialog::OnInitDialog;SetIconm_hIconTRUE;//SetbigiconSetIconm_hIconFALSE;//Setsmallicon//取得系统时间CTimet=CTime::GetCurrentTime;CStrings=t.Format%H:%M:%S;s=当前系统时间+s;//为状态栏创建窗体CRectrect;this-GetClientRectrect;m_StatusBarCtrl.CreateWS_CHILD|WS_VISIBLE|CCS_BOTTOMrectthisID_STATUS_BAR_CTRL;//设置状态栏的显示区间数,及相应宽度intindicators
[3];indicators
[0]=rect.Width/2;indicators
[1]=rect.Width*3/4;indicators
[2]=rect.Width;m_StatusBarCtrl.SetParts3indicators;//显示各区间文本str.LoadStringIDS_COMPANY;m_StatusBarCtrl.SetTextstr00;CA1App*app=CA1App*::AfxGetApp;m_StatusBarCtrl.SetText当前操作员+app-m_sUserName10;m_StatusBarCtrl.SetTexts20;//令CA1Dlg每一秒钟触发一次OnTimer事件,修改系统时间this-SetTimer121000NULL;returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}
③处理WM_TIMER消息的消息响应函数OnTimer,代码如下voidCA1Dlg::OnTimerUINTnIDEvent{CTimet=CTime::GetCurrentTime;CStrings=t.Format%H:%M:%S;s=当前系统时间+s;this-m_StatusBarCtrl.SetTexts20;CDialog::OnTimernIDEvent;}5.客户区设计一个优秀的商业管理系统,不但要有实用的功能,还要有漂亮友好的界面在本例中,设置窗体背景只需加入一个Bitmap资源,运行效果如图
3.3所示,其操作步骤如下
(1)在资源对话框上放一个Picture控件
(2)然后加入一个需要的Bitmap资源,如果图片包含的颜色超过256种,那么它会提示该图片不能在资源编辑器里编辑,不用管它,除非真的想编辑它,加进来的图片的资源符号缺省为IDB_BITMAP1
(3)设置Picture控件属性类型为Bitmap,图像为IDB_BITMAP
14.2系统登录管理1.实现目标程序启动后,首先进入系统登录程序验证用户密码系统登录程序主要实现如下功能输入密码的控件采用文本框密码如果输入正确,取得用户权限并进入系统,否则,将提示错误,并返回密码输入框记录错误次数,录入密码错误3次将自动退出系统用户按下〈Enter〉键,控制焦点的移动系统登录程序运行结果如图8所示图8系统登录窗口2.设计步骤
(1)增加对话框资源,设计窗体资源符号为IDD_DIALOG_LOGIN
(2)为该窗口连接相关的类,在资源对话框上右键单击,选择“ClassWizard...”选项,会弹出“Addaclass”对话框,提示IDD_DIALOG_LOGIN是一个新的资源,需要为这个资源创建一个类,或为它连接一个现有类在此,选择新建一个派生于CDialog的类来连接该资源,该类命名为CDlgLogin
(3)向窗口中添加图片、编辑框、静态文本、按钮等资源,设置主要资源属性,如表2所示表2相关资源设置资源名称资源符号资源对应的变量资源属性BitmapJIEMIAN无来自于文件jiemian.bmpPictureIDC_STATIC无类型Bitmap,图像JIEMIANButtonIDOK无缺省ButtonIDCANCEL无缺省StaticBoxIDC_STATIC无标题为请输入用户名和密码StaticBoxIDC_STATIC无标题为用户名StaticBoxIDC_STATIC无标题为密码EditBoxIDC_EDIT_NAMECEditm_editUserName取消Border,选上【Staticedge”EditBoxIDC_EDIT_PASSWORDCEditm_editPassWord取消Border,选上【Staticedge”和【PassWord”3.程序相关代码系统登录程序要在显示主窗体之前显示,系统登录程序代码如下BOOLCMedApp::InitInstance{......LRunSql::InitConnectPtr;//初始化COM环境,进行数据库连接CDlgLogindlg;//创建登录窗口对象ifdlg.DoModal==IDOK//显示登录窗口{CA1Dlg*pdlg=newCA1Dlg;//创建主窗体对象m_pMainWnd=pdlg;pdlg-DoModal;//显示主窗体deletepdlg;pdlg=NULL;}LRunSql::Close;//断开数据库连接returnFALSE;}当用户单击“确定”按钮时,进行密码判断和次数判断处理“确定“按钮的消息响应函数如下voidCDlgLogOn::OnOK{BOOLbLogOn=FALSE;CStringsUserPassWordsPurviewsUserNamesInputPassWord;LRunSqlm_runsql;CStringsql;_variant_tvalue;CStringsError;//更新数据变量this-m_editPassWord.GetWindowTextsInputPassWord;this-m_editUserName.GetWindowTextsUserName;CA1App*App=CA1App*AfxGetApp;sql.Formatselectadmi_passwordadmi_purviewfromtabpurviewwhereadmi_name=%ssUserName;ifm_runsql.CheckSQLResultsql{value=m_runsql.m_recordset-GetCollectadmi_password;ifvalue.vt!=VT_NULLsUserPassWord=char*_bstr_tvalue;value=m_runsql.m_recordset-GetCollectadmi_purview;ifvalue.vt!=VT_NULLsPurview=char*_bstr_tvalue;ifsUserPassWord==CCrypt::EncryptsInputPassWord123{App-m_sUserName=sUserName;App-m_sPurview=sPurview;bLogOn=TRUE;}else{sError=请重新输入密码\n注意大小写!密码错误;this-m_editPassWord.SetFocus;}}else{sError=请确认用户名大小写是否正确!无此用户;this-m_editUserName.SetFocus;}ifbLogOnEndDialogIDOK;else{m_iLogOnCount++;ifm_iLogOnCount=3this-EndDialog0;elseMessageBoxsError;}}进行焦点控制定义控制焦点的函数,该函数定义了当用户单击〈Enter〉键时,焦点改变的顺序,当需要改变焦点时,调用此函数boolCDlgLogOn::SetTheFocus{HWNDhwnd=::GetFocus;UINTid=::GetDlgCtrlIDhwnd;switchid{caseIDC_EDIT_NAME:this-m_editPassWord.SetFocus;::PostMessagem_editPassWord.GetSafeHwndWM_KEYDOWNVK_END0;returntrue;caseIDC_EDIT_PASSWORD:this-GetDlgItemIDOK-SetFocus;returntrue;caseIDOK:this-OnOK;returntrue;caseIDCANCEL:this-OnCancel;returntrue;}returnfalse;}在消息预处理函数中调用此函数BOOLCDlgLogOn::PreTranslateMessageMSG*pMsg{ifpMsg-message==WM_KEYDOWNpMsg-wParam==13{ifthis-SetTheFocusreturntrue;}returnCDialog::PreTranslateMessagepMsg;}//该函数返回True,表示该消息已被处理
4.3商品销售管理1.实现目标自动生成销售日期及销售票号确定用户输入数据完毕后,可提交数据给数据库自动核算销售金额支持打印功能销售登记模块运行结果如图9所示图9销售登记模块运行结果2.设计步骤
(1)新建一个窗口类,名称为CDlgXSDJ,对话框资源ID为IDD_DIALOG_XSDJ
(2)在窗口中添加编辑框、组合框、静态文本、按钮、时间控件等资源
(3)设置主要资源属性,如表3所示表3对话框及相关资源设置资源名称资源符号资源对应的变量资源属性DialogIDD_DIALOG_XSDJCDlgXSDJdlgtrue标题销售登记字体名称楷体_GB2312字体大小12ComboBoxIDC_COMBO1CComboBoxm_comboJsfsType DropListComboBoxIDC_COMBO2CComboBoxm_comboJsrType DropListEditBoxIDC_EDIT_KHIDCGeneralEditm_editKhId取消BorderEditBoxIDC_EDIT_KHNAMECGeneralEditm_editKhName取消BorderEditBoxIDC_EDIT1CStringm_strPhCEditm_editPh取消Border,选上ReadOnlyEditBoxIDC_EDIT_SSPictureIDC_STATICType FrameColorBlackStaticBoxIDC_STATIC_SS标题为实收StaticBoxIDC_STATIC标题为总金额StaticBoxIDC_STATIC_ZJE标题为
0.00StaticBoxIDC_STATIC_PH无标题为销售登记票号DateTimePickerIDC_DATETIMEPICKER1CDateTimeCtrlm_tcRq格式ShortDate选上StaticedgeButtonIDC_BUTTON1无标题为删除ButtonIDC_BUTTON_OKCButtonm_btnOk标题为确定ButtonIDC_BUTTON_PRINT无标题为打印...ButtonIDCANCEL无标题为退出3.程序相关代码
(1)创建左上角的标题信息
①创建白色背景以背景作父窗体,让其他的控件作它的子窗体这里需要在CDlgXSDJ的头文件中声明CWhiteFrame对象CWhiteFramem_whiteframe;在OnCreate的成员函数中创建该对象对应的窗口intCDlgXSDJ::OnCreateLPCREATESTRUCTlpCreateStruct{ifCDialog::OnCreatelpCreateStruct==-1return-1;CRectrect;this-GetClientRectrect;rect.left+=10;rect.right-=250;rect.top+=10;rect.bottom=200;m_whiteframe.CreateWS_CHILD|WS_TABSTOP|WS_VISIBLErectthis700;return0;}
②创建标题部分的控件该部分的控件都以上述的白色背景窗口为父窗口,要注意以下几点在这个背景上创建静态文本,且文本背景是白色对此,同样使用CWhiteFrame类,并用该类定义一组静态文本对象,要注意创建文本的位置,使其与相应的控件相配合例如确保静态文本“客户编号”与相应的编辑框在同一个水平高度;日期与日期控件在同一个高度由于入库与销售大部分内容是相同的,所以,用一个窗体来执行这两部分功能为此,用Bool型的变量m_bXs来表示这两种区别,并在代码中要适时修改一些属性改变设计时添加的控件的父窗体要用到其成员函数SetParent方式如下m_tcRq.SetParentm_whiteframe;对于结算方式下拉列表框和经手人下拉列表框,需要从数据库中取得相应的数据来初始化这两个窗口,并在最后为这两个下拉列表框确定初值初始化时间CTimem_dateRq=CTime::GetCurrentTime;//初始化时间this-m_tcRq.SetTimem_dateRq;创建和初始化标题部分的控件的代码如下boolCDlgXSDJ::InitBaseInfo{CRectrect;CStringstr;wf=newCWhiteFrame
[5];CStringstrs
[5];//该字符串保存静态文本ifm_bXs//判断当前是销售登记,还是入库登记{strs
[0]=客户编号;strs
[1]=客户名称;}else{this-GetDlgItemIDC_STATIC_PH-SetWindowText入库登记票号;this-SetWindowText入库登记:;strs
[0]=供应商编号;strs
[1]=供应商名称;}strs
[2]=结算方式;strs
[3]=经手人;strs
[4]=日期;rect=CRect10408055;//用来确定静态文本的位置forinti=0;i5;i++{//创建静态文本wf[i].Createstrs[i]WS_CHILD|WS_VISIBLErectm_whiteframe;wf[i].Invalidate;rect.OffsetRect028;}m_tcRq.SetParentm_whiteframe;//改变标题控件的父窗口m_comboJsr.SetParentm_whiteframe;m_editKhName.SetParentm_whiteframe;m_editKhId.SetParentm_whiteframe;m_comboJsfs.SetParentm_whiteframe;//inittime;CTimem_dateRq=CTime::GetCurrentTime;//初始化时间this-m_tcRq.SetTimem_dateRq;//initjsr;//初始化经手人下拉列表框CStringsql;sql.Formatselectyg_namefromtabyginfo;if!m_runsql.CheckSQLResultsqlreturnfalse;_variant_tvalue;while!m_runsql.m_recordset-adoEOF//从数据库取值初始化员工下拉列表框{value=m_runsql.m_recordset-GetCollectyg_name;ifvalue.vt!=VT_NULLthis-m_comboJsr.AddStringchar*_bstr_tvalue;m_runsql.m_recordset-MoveNext;}//initjsfs;sql.Formatselectjsfsfromtabjsfs;this-m_runsql.RunSQLsql;while!m_runsql.m_recordset-adoEOF//从数据库取值初始化经手人下拉列表框{value=m_runsql.m_recordset-GetCollectjsfs;ifvalue.vt!=VT_NULLthis-m_comboJsfs.AddStringchar*_bstr_tvalue;m_runsql.m_recordset-MoveNext;}this-m_comboJsfs.SetCurSel0;this-m_comboJsr.SetCurSel0;returntrue;}
③为客户编号和客户名称编辑框连接自动提示窗口对于客户信息和供应商信息,这两者信息格式大部分是相同的,并且每次是用到其中的一组数据时都需要用到自动提示窗口,所以专门作出一个类CGeneralEdit来对应着两组信息,并包含对自动提示窗口的使用该类派生自CEdit(参看类图
2.12)在此之前,请参看关键技术中的
5.
2.2关于显示自动提示窗口的介绍功能分析界面上看,需要有下划线和白色背景当把焦点移到某个编辑框上时原有弹出的自动提示窗口消失当在编辑框中进行编辑时引起EN_CHANGE事件时,弹出自动提示窗口焦点移走时,让自动提示窗口消失;但是如果焦点移动到了自动提示窗口上,则自动提示窗口不消失当父窗体移动时,自动提示窗口也跟着移动当在编辑框中进行编辑时,按〈↑〉、〈↓〉、〈PageUp〉、〈PageDown〉键,自动提示窗口会响应这些消息,且此时焦点还在编辑框中当用户在其中一个编辑框中按〈Enter〉键,表示确定了选择某一个客户(编号或名称),那么另一个编辑框中的内容也随之改变当用户在其中一个编辑框中单击〈Esc〉键,表示用户放弃进行编辑,取消自动弹出对话框为了实现功能2,写消息WM_SETFOCUS的消息响应函数OnSetFocusvoidCGeneralEdit::OnSetFocusCWnd*pOldWnd{ASSERTthis-m_poplist!=NULL;m_poplist-ShowWindowSW_HIDE;CEdit::OnSetFocuspOldWnd;}对于功能3,要写EN_CHANGE消息响应函数OnChange在编写EN_CHANGE消息响应函数OnChange时,需要注意客户编号编辑框和客户名称编辑框都是由一个类定义出来的,使用资源符号来区分这两个对象,如IDC_EDIT_KHID对应着客户编号编辑框,而IDC_EDIT_KHNAME则对应着客户名称编辑框对象当编辑编号时,直接用当前编辑框的字符串来刷新自动提示窗口,当编辑名称时,还需要参考编号编辑框的值,来显示自动提示窗口的内容如果自动提示窗口已经显示了,就没有必要重复计算显示代码如下voidCGeneralEdit::OnChange{ifm_bSetValuereturn;ASSERTthis-m_poplist!=NULL;CStringstr;this-GetWindowTextstr;//取得当前编辑框的字符串intiID=this-GetDlgCtrlID;//取得当前编辑框对象的资源符号的值ifiID==IDC_EDIT_KHID//判断是编号对象,还是名称对象{this-m_poplist-RefreshListCtrlView0str;//刷新自动提示窗口数据}elseifiID==IDC_EDIT_KHNAME{CStringid;CWnd*editid;editid=this-GetParent-GetDlgItemIDC_EDIT_KHID;editid-GetWindowTextid;m_poplist-RefreshListCtrlView1strid0;//根据两个字符串刷新自动提示窗口}if!m_poplist-IsWindowVisible//如果自动提示窗口已显示,就不用再设定位置、显示{this-GetWindowRectm_rectWindow;this-m_poplist-SetShowPositionthis-m_rectWindowthis;m_poplist-ShowListPop;}}对于功能
4、
6、
7、8,需要编写预解释函数PreTranslateMessageMSG*pMsg和WM_KILLFOCUS的消息响应函数OnKillFocus,功能分析如下编辑框失去焦点的时候,会调用函数OnKillFocusCWnd*pNewWnd,此时,需要判断是否焦点转移到了自动提示窗口上,pNewWnd就是焦点转移到的窗口指针,判断这个指针是谁就行了当用户按〈Enter〉键,缺省情况下,对话框处理这个消息并最终执行OnOk函数,关闭对话框需要在预解释函数中处理这个消息,并把它解释为WM_KILLFOCUS,并设定一个开关变量标识这个消息,在OnKillFocus函数中收到并处理这个消息当用户按〈Esc〉键时,需要让自动提示窗口消失,同时将〈Enter〉键解释为无关紧要的键如〈Ctrl〉键当用户按〈↑〉、〈↓〉、〈PageUp〉、〈PageDown〉键时,将这个消息原封不动地发送给自动提示窗口,自动提示窗口会响应这些消息(此时焦点还在编辑框中)BOOLCGeneralEdit::PreTranslateMessageMSG*pMsg{//TODO:Addyourspecializedcodehereand/orcallthebaseclassifpMsg-message==WM_KEYDOWN//捕捉键盘某个键按下事件{switchpMsg-wParam{case13://捕捉〈Enter〉键{pMsg-message=WM_KILLFOCUS;//将该消息改为WM_KILLFOCUS消息m_Kill=RETURNKILL;//设置开关变量,将在OnKillFocus中使用break;}case27://捕捉〈Esc〉键{ifm_poplist-IsWindowVisible//如果自动提示窗口处于显示状态,隐藏它{this-m_poplist-ShowWindowfalse;pMsg-wParam=VK_CONTROL;//将该消息改为〈Ctrl〉键}break;}caseVK_UP://捕捉〈↑〉、〈↓〉、〈PageUp〉、〈PageDown〉键caseVK_DOWN:caseVK_NEXT:caseVK_PRIOR:{//将这些消息由自动提示窗口处理this-m_poplist-SendTheUDNPMessagepMsg-wParam;pMsg-wParam=VK_CONTROL;//并将该消息解释为无用的键break;}}}returnCEdit::PreTranslateMessagepMsg;}下面看看自动提示窗口是如何处理〈↑〉、〈↓〉、〈PageUp〉、〈PageDown〉键的voidCListCtrlPop::SendTheUDNPMessageUINTKEY{::SendMessagethis-m_listctrl-GetSafeHwndWM_KEYDOWNKEY0;m_listctrl-SetHotItemm_listctrl-GetSelectionMark;}自动提示窗口将这些消息原封不动地发送给了其中的列表控件调用完消息与解释函数后,消息被预解释了,可以处理这些解释后的消息voidCGeneralEdit::OnKillFocusCWnd*pNewWnd{CEdit::OnKillFocuspNewWnd;intiID=this-GetDlgCtrlID;//取得当前编辑框对象的资源符号值switchm_Kill//判断是不是经过处理的〈Enter〉键按下的消息{caseRETURNKILL://〈Enter〉键按下后{ASSERTthis-m_poplist!=NULL;//判断自动提示窗口对象指针有效ifm_poplist-IsWindowVisiblem_poplist-GetSelectedMark=0{//判断自动提示窗口是可视的,并且有某个记录被选择//接下来,进行从提示对话框中取值赋值给编辑框this-m_poplist-ShowWindowSW_HIDE;CGeneralEdit*edit;//根据资源编号取得对象指针edit=CGeneralEdit*this-GetParent-GetDlgItemIDC_EDIT_KHNAME;edit-SetValueUnOnChangem_poplist-GetListCtrlSel1;edit-Invalidate;//刷新编辑框edit=CGeneralEdit*this-GetParent-GetDlgItemIDC_EDIT_KHID;edit-SetValueUnOnChangem_poplist-GetListCtrlSel0;edit-Invalidate;}this-m_poplist-ShowWindowSW_HIDE;//隐藏窗口//让对话框窗口设定焦点该由谁获得::PostMessagethis-GetParent-GetParent-GetSafeHwndMYMESSAGE_XSDJ_SETTHEFOCUS00;break;}default://此时,需要判断是否焦点转移到了自动提示窗口或自动提示窗口中的列表上,如果是,就不隐藏//自动提示窗口,否则,隐藏自动提示窗口ifpNewWnd!=NULLifpNewWnd-GetDlgCtrlID==m_poplist-GetDlgCtrlID||pNewWnd-GetDlgCtrlID==ID_POP_LISTCTRL;elsethis-m_poplist-ShowWindowSW_HIDE;break;}m_Kill=NORMALKILL;//恢复开关变量//TODO:Addyourmessagehandlercodehere}
(2)自动产生销售编号CStringCDlgXSDJ::ChanShengXSDJPH{this-UpdateData;CStringsql;_bstr_tsql_;_variant_tvalue;CStrings_value;CStrings_date;CStringph;//开始取得时间,并将其加入票号中CTimem_tRq;this-m_tcRq.GetTimem_tRq;this-m_tcRq.GetWindowTexts_date;CStringy_datem_dated_date;y_date=m_tRq.Format%Y;m_date.Format%02dm_tRq.GetMonth;d_date.Format%02dm_tRq.GetDay;ph=y_date+-+m_date+-+d_date;ifthis-m_bXs//判断是销售登记还是入库登记{ph=ph+xsd;//从数据库中取得最大的编号sql.Formatselectxs_phfromtabxsphwhererq=#%s#orderbyxs_phdescs_date;ifm_runsql.CheckSQLResultsql{value=m_runsql.m_recordset-GetCollectxs_ph;ifvalue.vt!=NULL{s_value=char*_bstr_tvalue;s_value=s_value.Mids_value.GetLength-44;}}else{s_value=0;}}else{ph=ph+rkd;sql.Formatselectrk_phfromtabrkphwhererq=#%s#orderbyrk_phdescs_date;ifm_runsql.CheckSQLResultsql{value=m_runsql.m_recordset-GetCollectrk_ph;ifvalue.vt!=NULL{s_value=char*_bstr_tvalue;s_value=s_value.Mids_value.GetLength-44;}}else{s_value=0;}}//格式化产生的新编号longl_value=atois_value+1;s_value.Format%04dl_value;ph=ph+s_value;returnph;}
(3)创建列表控件初始化列表控件,设置列表控件的大小、风格、列标题、可编辑的列号读者可参看本章
5.7节专题技术,其中详细介绍了功能强大的列表控件boolCDlgXSDJ::InitnListXSDJ{CRectrect_nlist10300700650;this-GetClientRectrect_nlist;rect_nlist.top=210;rect_nlist.bottom=480;this-m_plistXSDJ=newCListXSDJm_bXs;m_plistXSDJ-CreateWS_CHILD|WS_VISIBLE|LVS_REPORT|WS_BORDERrect_nlistthisID_NEWLISTLSXSDJ;this-m_plistXSDJ-ModifyStyleLVS_EDITLABELS0L;//禁止标题编辑m_plistXSDJ-ModifyStyle0LLVS_REPORT;//设为Report类型m_plistXSDJ-ModifyStyle0LLVS_SHOWSELALWAYS;//始终高亮显示被选中的项m_plistXSDJ-ModifyStyle0LLVS_NOSORTHEADER;m_plistXSDJ-ModifyStyleLVS_OWNERDRAWFIXED0L;m_plistXSDJ-SetExtendedStyleLVS_EX_FULLROWSELECT|//允许整行选中LVS_EX_GRIDLINES|//画出网格线LVS_EX_FLATSB//扁平风格的滚动条;CStringstr;//
1、先产生numTitle列inti=0;m_plistXSDJ-InsertColumni药品编号;m_plistXSDJ-InsertColumn1药品名称;m_plistXSDJ-InsertColumn2仓库名称;m_plistXSDJ-InsertColumn4数量;m_plistXSDJ-InsertColumn5总金额;ifm_bXs{m_plistXSDJ-InsertColumn3单价;m_plistXSDJ-InsertColumn6实收;}else{m_plistXSDJ-InsertColumn3进价;m_plistXSDJ-InsertColumn6实付;}//
2、插入1行m_plistXSDJ-InsertItem0;//
3、调整列宽RECTrect2;m_plistXSDJ-GetWindowRectrect2;intwid=rect
2.right-rect
2.left;fori=0;i7;i++{m_plistXSDJ-SetItemText0i;m_plistXSDJ-SetColumnWidthiwid/7;}m_plistXSDJ-SetSubItemCanEdited0;m_plistXSDJ-SetSubItemCanEdited1;m_plistXSDJ-SetSubItemCanEdited2;m_plistXSDJ-SetSubItemCanEdited3;m_plistXSDJ-SetSubItemCanEdited4;m_plistXSDJ-SetSubItemCanEdited5;m_plistXSDJ-SetSubItemCanEdited6;m_plistXSDJ-Invalidatefalse;returntrue;}
4.4商品入库管理1.实现目标系统自动生成入库时间及入库票号确定用户输入数据完毕后,可提交给数据库自动核算入库金额,支持打印功能删除当前指针所对应的记录信息入库登记模块运行结果如图10所示图10入库登记模块运行结果2.设计步骤
(1)新建一个对话框,对话框资源ID为IDD_DIALOG_RKDJ
(2)在窗口中添加编辑框、组合框、静态文本、按钮、时间控件等资源
(3)设置对话框标题属性为“入库登记”,其他控件属性保持默认设置3.代码分析
(1)设计对话框及相关资源对话框及相关资源设置与销售模块相同定义bool类型的变量m_bXs,在该类的构造函数中对这两个模块加以区分CDlgXSDJ::CDlgXSDJboolisxsCWnd*pParent/*=NULL*/:CDialogCDlgXSDJ::IDDpParent{……this-m_bXs=isxs;……}
(2)创建左上角的标题信息
①显示各种文本内容boolCDlgXSDJ::InitBaseInfo{CRectrect;CStringstr;wf=newCWhiteFrame
[5];CStringstrs
[5];//该字符串保存静态文本ifm_bXs//判断当前是销售登记,还是入库登记{strs
[0]=客户编号;strs
[1]=客户名称;}else{this-GetDlgItemIDC_STATIC_PH-SetWindowText入库登记票号;this-SetWindowText入库登记:;strs
[0]=供应商编号;strs
[1]=供应商名称;}……}
②为供应商编号和供应商名称编辑框连接自动提示窗口在这里的区别是提示的内容来源不同,所以要进行不同的数据初始化boolCDlgXSDJ::InitStringLists{CStringsql;_variant_tvalue;m_strlistKh=newCStringList
[2];ifm_bXs{m_strlistKh
[0].AddTail客户编号;m_strlistKh
[1].AddTail客户全称;sql.FormatselectDISTINCTkh_idkh_namefromtabkhorderbykh_idasc;if!this-m_runsql.CheckSQLResultsqlreturnfalse;while!m_runsql.m_recordset-adoEOF{value=m_runsql.m_recordset-GetCollectkh_id;ifvalue.vt!=VT_NULL{this-m_strlistKh
[0].AddTailchar*_bstr_tvalue;}value=m_runsql.m_recordset-GetCollectkh_name;ifvalue.vt!=VT_NULL{this-m_strlistKh
[1].AddTailchar*_bstr_tvalue;}m_runsql.m_recordset-MoveNext;}}else{m_strlistKh
[0].AddTail供应商编号;m_strlistKh
[1].AddTail供应商全称;sql.FormatselectDISTINCTgys_idgys_namefromtabgysorderbygys_idasc;if!this-m_runsql.CheckSQLResultsqlreturnfalse;while!m_runsql.m_recordset-adoEOF{value=m_runsql.m_recordset-GetCollectgys_id;ifvalue.vt!=VT_NULL{this-m_strlistKh
[0].AddTailchar*_bstr_tvalue;}value=m_runsql.m_recordset-GetCollectgys_name;ifvalue.vt!=VT_NULL{this-m_strlistKh
[1].AddTailchar*_bstr_tvalue;}m_runsql.m_recordset-MoveNext;}}this-m_popList.Createthis;m_popList.SelectStringList2this-m_strlistKh;this-m_editKhId.SelectPopListm_popList;this-m_editKhName.SelectPopListm_popList;returntrue;}
(3)自动产生入库票号CStringCDlgXSDJ::ChanShengXSDJPH{this-UpdateData;CStringsql;_bstr_tsql_;_variant_tvalue;CStrings_value;CStrings_date;CStringph;CTimem_tRq;//开始取得时间,并将其加入票号中this-m_tcRq.GetTimem_tRq;this-m_tcRq.GetWindowTexts_date;CStringy_datem_dated_date;y_date=m_tRq.Format%Y;m_date.Format%02dm_tRq.GetMonth;d_date.Format%02dm_tRq.GetDay;ph=y_date+-+m_date+-+d_date;ifthis-m_bXs//判断是销售登记还是入库登记{ph=ph+xsd;//从数据库中取得最大的编号sql.Formatselectxs_phfromtabxsphwhererq=’%s’orderbyxs_phdescs_date;ifm_runsql.CheckSQLResultsql{value=m_runsql.m_recordset-GetCollectxs_ph;ifvalue.vt!=NULL{s_value=char*_bstr_tvalue;s_value=s_value.Mids_value.GetLength-44;}}else{s_value=0;}}else{ph=ph+rkd;sql.Formatselectrk_phfromtabrkphwhererq=’%s’orderbyrk_phdescs_date;ifm_runsql.CheckSQLResultsql{value=m_runsql.m_recordset-GetCollectrk_ph;ifvalue.vt!=NULL{s_value=char*_bstr_tvalue;s_value=s_value.Mids_value.GetLength-44;}}else{s_value=0;}}longl_value=atois_value+1;//格式化产生的新编号s_value.Format%04dl_value;ph=ph+s_value;returnph;}
(4)创建列表控件对于列表控件,需要注意第3列标题不同boolCDlgXSDJ::InitnListXSDJ{……ifm_bXs{m_plistXSDJ-InsertColumn3单价;m_plistXSDJ-InsertColumn6实收;}else{m_plistXSDJ-InsertColumn3进价;m_plistXSDJ-InsertColumn6实付;}……returntrue;}
(5)在对话框的初始化函数中进行数据初始化BOOLCDlgXSDJ::OnInitDialog{CDialog::OnInitDialog;CRectrect;InitStringLists;InitnListXSDJ;if!this-InitBaseInfo{MessageBox初始化基本数据失败;returntrue;}this-m_sXsPh=m_strPh=this-ChanShengXSDJPH;this-UpdateDatafalse;m_editKhId.SetFocus;returnFALSE;//returnTRUEunlessyousetthefocustoacontrol//EXCEPTION:OCXPropertyPagesshouldreturnFALSE}//返回值是FALSE表示焦点已被确定
(6)实现按钮功能入库登记模块有4个功能按钮确定、打印、删除、退出其中,打印、退出按钮与销售模块相同,这里不再重复“删除”按钮将会调用列表控件的成员函数DeleteSelected,该函数找到被选的行记录,取消该临时库存的相关信息,再删除该行,最后刷新列表修改临时库存时,与销售登记的算法不同boolCListXSDJ::DeleteSelected{ifthis-m_poplist-IsWindowVisible//隐藏不必要的窗口this-m_poplist-ShowWindowSW_HIDE;ifthis-m_edit.IsWindowVisiblem_edit.ShowWindowSW_HIDE;LVITEM*item=newLVITEM;intnumber=this-GetSelectedCount;forinti=this-GetItemCount-1;i=0;i--//从最后一行开始判断是否被选上{this-m_nItem=i;item-iItem=i;item-mask=LVIF_STATE;item-stateMask=LVIS_SELECTED;GetItemitem;ifitem-state==LVIS_SELECTED{//在临时库存中取消相关信息CStrings_sl=this-GetItemTexti4;longl_sl=atois_sl;ifm_iYpKcSelected[i]0||l_sl==0continue;longkc_number=atoim_pstrlistKc
[3].GetAtthis-m_pstrlistKc
[3].FindIndexthis-m_iYpKcSelected[i];CStringleft;ifm_bXsleft.Format%dkc_number+l_sl;elseleft.Format%dkc_number-l_sl;this-m_pstrlistKc
[3].SetAtthis-m_pstrlistKc
[3].FindIndexthis-m_iYpKcSelected[i]left;DeleteItemi;this-m_iTheItemState[i]=NONE;}}ifGetItemCount==0InsertItem0;this-m_nItem=0;Invalidate;returntrue;}实现“”确定按钮,该按钮完成两个内容检查用户输入数据是否有效及以事务形式提交数据库提交数据库时,刷新的数据表不同,且刷新库存表时,算法不同voidCDlgXSDJ::OnButtonOk{if!CheckKh{this-m_editKhId.SetFocus;ifm_bXsMessageBox请输入客户信息注意;elseMessageBox请输入供应商信息注意;return;}elseif!this-m_plistXSDJ-CheckAllItem{ifm_bXsMessageBox请输入完整客户登记信息注意;elseMessageBox请输入完整供应商登记信息注意;this-m_plistXSDJ-m_edit.SetFocus;return;}CA1App*app=CA1App*AfxGetApp;this-BeginWaitCursor;CStringxs_ph=this-m_sXsPh;inti=0;CStringkh_id;this-m_editKhId.GetWindowTextkh_id;CStringkh_name;this-m_editKhName.GetWindowTextkh_name;CStringczy=app-m_sUserName;CStringjsr;this-m_comboJsr.GetWindowTextjsr;CStringrq;this-m_tcRq.GetWindowTextrq;CStringjsfs;this-m_comboJsfs.GetWindowTextjsfs;CStringyp_idyp_names_slck_names_djs_jesql;longl_sl=0;doubled_dj=0d_je=0ys=0ss=0ws=0;longpzs=0;boolis_jq=false;CStringListslist;intn=m_plistXSDJ-GetItemCount;ifn=0{MessageBox请输入登记信息注意;this-m_plistXSDJ-m_iEditedIndex=-1;m_plistXSDJ-InsertItem0;::PostMessagem_plistXSDJ-GetSafeHwndWM_SETFOCUS00;::PostMessagem_plistXSDJ-GetSafeHwndSETNEXTITEMPHFOCUS00;return;}try{m_runsql.m_recordset-Close;LRunSql::BeginTrans;}catch_com_errore{MessageBoxe.ErrorMessage;}fori=0;in;i++{yp_id=this-m_plistXSDJ-GetItemTexti0;yp_name=this-m_plistXSDJ-GetItemTexti1;ck_name=this-m_plistXSDJ-GetItemTexti2;s_dj=this-m_plistXSDJ-GetItemTexti3;d_dj=atofs_dj;s_sl=this-m_plistXSDJ-GetItemTexti4;l_sl=atois_sl;s_je=this-m_plistXSDJ-GetItemTexti5;d_je=atofs_je;ys=d_je+ys;ss=ss+atofm_plistXSDJ-GetItemTexti6;//savedj;ifslist.Findyp_id==NULLslist.AddTailyp_id;ifm_bXs{doublejinjia=0;doubleprofit=0;m_plistXSDJ-m_mapYpToJj.Lookupyp_idjinjia;profit=d_dj-jinjia*l_sl;sql.FormatINSERTINTOtabxsdjxs_phyp_idck_namesldjjeprofit\VALUES%s%s%s%d%f%f%fxs_phyp_idck_namel_sld_djd_jeprofit;}elsesql.FormatINSERTINTOtabrkdjrk_phyp_idck_namesldjje\VALUES%s%s%s%d%f%fxs_phyp_idck_namel_sld_djd_je;this-m_runsql.RunSQLsql;ifm_bXssql.Formatupdatetabkcsetkc_number=kc_number-%dwhereyp_id=%sandck_name=\%sl_slyp_idck_name;elsesql.Formatupdatetabkcsetkc_number=kc_number+%dwhereyp_id=%sandck_name=\%sl_slyp_idck_name;this-m_runsql.RunSQLsql;}ws=ys-ss;ifws=
0.0{ws=
0.0;is_jq=true;}pzs=slist.GetCount;if!m_bXssql.FormatINSERTINTOtabrkphrk_phgys_idpzsyfsfwfis_jqrqczyjsrjsfs\VALUES%s%s%d%f%f%f%d#%s#%s%s%sxs_phkh_idpzsyssswsis_jqrqczyjsrjsfs;elsesql.FormatINSERTINTOtabxsphxs_phkh_idpzsyssswsis_jqrqczyjsrjsfs\VALUES%s%s%d%f%f%f%d#%s#%s%s%sxs_phkh_idpzsyssswsis_jqrqczyjsrjsfs;this-m_runsql.RunSQLsql;this-EndWaitCursor;if!LRunSql::CommitTrans{MessageBox数据库事务提交错误医药管理系统;}elseMessageBoxOK医药管理系统;this-EndDialog0;}
(7)实现弹出提示窗口入库登记模块与销售登记模块实现弹出提示窗口的不同点是修改临时库存的算法不同主要表现在编辑框的EN_CHANGE消息处理函数上,当用户修改数量编辑框中数据时,要对临时数据库进行修改voidCListXSDJ::OnNewEditChangeconstintitemconstintsub_item{……switchsub_item{……case4://数量ifm_bXsl_left=m_edit.kc_number-atoistr+m_edit.m_dSetFocusValue;//-curshownumber+setfocusvalue=leftelsel_left=m_edit.kc_number+atoistr-m_edit.m_dSetFocusValue;//+curshownumber-setfocusvalue=left……}……}附录A参考文献1.《VisualBasic精彩编程200例》机械工业出版社赛奎春、高春艳等2003年1月2.《VisualBasic数据库开发实例解析》机械工业出版社刘志铭、高春艳等2003年8月3.《VisualFoxPro数据库开发实例解析》机械工业出版社王晶莹、王国辉等2003年9月4.《PowerBuilder数据库开发实例解析》机械工业出版社华传铭、张振坤等2003年9月5.《Delphi数据库开发实例解析》机械工业出版社赛奎春、郑骁鹏等2004年2月6.《PowerBuilder精彩编程200例》机械工业出版社张振坤、李文立等2004年9月7.《VisualFoxPro精彩编程200例》机械工业出版社王国辉、董韶华等2004年9月8.《ASP数据库开发实例解析》机械工业出版社李严、于亚芳、王国辉2004年12月9.《Delphi工程应用与项目实践》机械工业出版社宋坤、赵智勇等2005年1月10.《VisualBasic工程应用与项目实践》机械工业出版社高春艳、李俊民等2005年1月11.《VisualC++工程应用与项目实践》机械工业出版社张雨、阮伟良等2005年1月12.《JSP工程应用与项目实践》机械工业出版社陈威、白伟明、李楠2005年2月13.《ASP工程应用与项目实践》机械工业出版社王国辉、牛强、李南南2005年4月14.《VisualBasic信息系统开发实例精选》机械工业出版社高春艳、李俊民、张耀庭等2005年7月15.《ASP信息系统开发实例精选》机械工业出版社王国辉、牛强、李南南等2005年7月16.《Delphi信息系统开发实例精选》机械工业出版社宋坤、赵智勇、刘强等2005年7月17.《Visualfoxpro数据库开发关键技术与实例应用》人民邮电出版社周桓、张雨、王国辉2004年5月18.《PowerBuilder数据库开发关键技术与实例应用》人民邮电出版社刘志铭、张振坤、冯文萃2004年5月19.《Delphi数据库开发关键技术与实例应用》人民邮电出版社赛奎春、陈紫鸿、宋昆2004年5月20.《Visualbasic数据库开发关键技术与实例应用》人民邮电出版社高春艳、李艳2004年5月21.《VisualC++管理信息系统完整项目实例剖析》人民邮电出版社明日科技2005年7月22.《VisualBasic管理信息系统完整项目实例剖析》人民邮电出版社明日科技2005年7月23.《PowerBuilder管理信息系统完整项目实例剖析》人民邮电出版社明日科技2005年7月24.《VisualFoxPro管理信息系统完整项目实例剖析》人民邮电出版社明日科技2005年7月25.《SQLServer数据库开发实例解析》机械工业出版社宋昆、李严等2006年1月26.《Access数据库开发实例解析》机械工业出版社李俊民、高春燕等2006年1月27.《VisualBasic数据库系统开发完全手册》人民邮电出版社明日科技王春才、高春艳、李俊民2006年3月28.《VisualC++数据库系统开发完全手册》人民邮电出版社明日科技王端、于速、张雨2006年3月29.《Delphi数据库系统开发完全手册》人民邮电出版社明日科技宋坤、邹天思2006年3月30.《JSP数据库系统开发完全手册》人民邮电出版社明日科技王国辉、李文立、杨亮2006年3月31.《VisualBasic数据库系统开发案例精选》人民邮电出版社明日科技高春艳、李俊民、刘彬彬2006年5月32.《Delphi数据库系统开发案例精选》人民邮电出版社明日科技李文立、刘强、梁冰2006年5月33.《ASP数据库系统开发案例精选》人民邮电出版社明日科技孙明丽、邹天思、盖天宇2006年5月34.《JSP数据库系统开发案例精选》人民邮电出版社明日科技王国辉、王易2006年5月附录B数据表由于篇幅有限,只给出部分数据表下面分别介绍以下各个表的结构(临时表是为了实现在查询结果中进行查询,在这里不做具体介绍)tabdhdj表tabdhdj表用于保存调货登记信息tabdhdj表的结构如表4所示表4tabdhdj表的结构字段名称数据类型字段大小可否为空说明dh_ph文本20NotNull调货票号主键out_ck文本20NotNull调出的库外健in_ck文本20NotNull调入的库外健yp_id文本10NotNull药品编号外健sl长整型Null数量tabpurview表tabpurview表用于保存权限信息tabpurview表的结构如表5所示表5tabpurview表的结构字段名称数据类型字段大小可否为空说明admi_name文本20NotNull用户名主键admi_password文本255Null用户密码admi_purview长整型NotNull用户权限外键tabrkdj表tabrkdj表用于保存入库登记的相关信息tabrkdj表的结构如表6所示表6tabrkdj表的结构字段名称数据类型字段大小可否为空说明rk_ph文本20NotNull入库票号外键yp_id文本10NotNull药品编号外键ck_name文本30NotNull仓库名称外键sl双精度型Null数量dj双精度型Null单价je双精度型Null金额tabrkjz表tabrkjz表用于保存入库结账的相关信息tabrkjz表的结构如表7所示表7tabrkjz表的结构字段名称数据类型字段大小可否为空说明fk_ph文本20NotNull收款票号主键rk_ph文本20NotNull销售票号外键je双精度型Null收款金额fs文本10Null收款方式外键rq日期/时间NotNull结款日期czy文本20NotNull操作员外键jsr文本20NotNull经手人bz文本100Null备注tabrkph表tabrkph表用于保存入库票号tabrkph表的结构如表8所示表8tabrkph表的结构字段名称数据类型字段大小可否为空说明rk_ph文本20NotNull入库票号主键gys_id文本10NotNull供应商编号外键pzs双精度型Null品种数yf双精度型Null应付sf双精度型Null实付wf双精度型Null未付rq日期/时间NotNull日期jsfs文本10NotNull结算方式外键is_jq布尔型NotNull是否结清czy文本20NotNull操作员外键jsr文本20NotNull经手人-1-–2––3–。