MFC登录系统图解.docx
《MFC登录系统图解.docx》由会员分享,可在线阅读,更多相关《MFC登录系统图解.docx(52页珍藏版)》请在冰豆网上搜索。
![MFC登录系统图解.docx](https://file1.bdocx.com/fileroot1/2023-2/7/b7bf767a-dd2d-47e2-bd93-2ca3e99b10ff/b7bf767a-dd2d-47e2-bd93-2ca3e99b10ff1.gif)
MFC登录系统图解
MFC登录系统
第一步、建立一个框架结构工程
选择其它语言中的VisualC++,在中间视图中选择MFC应用程序,下面的名称中输入工程名称GzyOa,解决方案名称是你的工程目录名可以使用默认的工程名也可以修改成自己好记的名称。
点击确定。
下一步
我们选择“多个文档”“选项卡式文档”,我们不用文档视图,所以将下面的“文档/视图结构支持(V)”复选框去掉,点击完成。
这样就完成了工程的创建。
第二步,建立登录对话框。
选择“类视图”导航栏,点击右键选择“类向导”。
选择添加类
类名CLogin基类为CDialog点击完成。
在类视图中找到刚建的类,点右键
选择“转到”对话框(D)
制作如下对话框。
(确定改为“登录”,取消改为“退出”,增加“设置”按钮。
)
鼠标放在第一个编辑框点右键,选添加变量m_editName
同法定义第二个编辑框变量为m_editPassWord,同时将其属性Password设置为True,并在其头文件中手动添加两个变量:
public:
CStringcName;
CStringcPass;
双击登录按钮添加如下代码:
voidCLogin:
:
OnBnClickedOk()
{
m_editName.GetWindowTextW(cName);
m_editPassWord.GetWindowTextW(cPass);
CDialog:
:
OnOK();
}
这里是把编辑框的内容传给public变量,以便于主程序存储登录信息,这里以后还要添加认证代码。
(这是后话)
在类视图中找到CGzyOaApp类(程序入口)修改InitInstance()函数,使用程序先启动对话框后再启动框CMainFrame。
方法如下:
1.为CGzyOaApp类添加两个对应变量(用于接收登录窗口的用户信息)
CStringm_strSqlName;
CStringm_strSqlPassword;
2.先在CGzyOaApp类的源文件头添加
#include"Login.h"
3.找到InitInstance()函数定义(向下翻)添加如下代码:
红色部分
BOOLCGzyOaApp:
:
InitInstance()
{
INITCOMMONCONTROLSEXInitCtrls;
InitCtrls.dwSize=sizeof(InitCtrls);
InitCtrls.dwICC=ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinAppEx:
:
InitInstance();
if(!
AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
returnFALSE;
}
AfxEnableControlContainer();
EnableTaskbarInteraction();
SetRegistryKey(_T("应畖用?
程ì序ò向ò导?
生Θ?
成é的?
本?
地?
应畖用?
程ì序ò"));
InitContextMenuManager();
InitKeyboardManager();
InitTooltipManager();
CMFCToolTipInfottParams;
ttParams.m_bVislManagerTheme=TRUE;
theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl),&ttParams);
CLoginm_login;
if(m_login.DoModal()==IDOK)
{
m_strSqlName=m_login.cName;
m_strSqlPassword=m_login.cPass;
CMDIFrameWnd*pFrame=newCMainFrame;
if(!
pFrame)
returnFALSE;
m_pMainWnd=pFrame;
if(!
pFrame->LoadFrame(IDR_MAINFRAME))
returnFALSE;
HINSTANCEhInst=AfxGetResourceHandle();
m_hMDIMenu=:
:
LoadMenu(hInst,MAKEINTRESOURCE(IDR_GzyOaTYPE));
m_hMDIAccel=:
:
LoadAccelerators(hInst,MAKEINTRESOURCE(IDR_GzyOaTYPE));
CMainFrame*pMainFrame=newCMainFrame;
if(!
pMainFrame->LoadFrame(IDR_MAINFRAME))
returnFALSE;
m_pMainWnd=pMainFrame;
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
}
returnTRUE;
}
这样就完成了登录过程的修改,但对话框还太单调,这里我们使用绘图方法添加标题等信息,方法如下:
在类视图中找到对话框类CLogin,点右键,选择类向导。
添加消息响应函数
代码如下:
voidCLogin:
:
OnPaint()
{
CPaintDCdc(this);//devicecontextforpainting
//TODO:
在此处添加消息处理程序代码
//不为绘图消息调用CDialog:
:
OnPaint()
//CPaintDCdc(this);
CRectrc;
CPenpen;
GetClientRect(&rc);//获取客户其大小
intnHeight=rc.Height();
inti,j;
for(i=255,j=0;nHeight>=0;nHeight--,j++)
{
pen.CreatePen(PS_SOLID,1,RGB(255,i,i));//创建画笔
//通过改变RGB()函数的参数可以改变背景颜色,经过复杂的算法可以画出很复杂的背景图
CPen*pOldPen=dc.SelectObject(&pen);
dc.MoveTo(rc.left,j);//将比尖移到起点
dc.LineTo(rc.right,j);//画线到终点
dc.SelectObject(pOldPen);
pen.DeleteObject();//删除创建的画笔
i=max(0,i-1);//改变颜色值
}
dc.SetTextColor(RGB(255,0,0));
dc.SetBkMode
(1);
dc.SetTextColor(RGB(0,0,255));
dc.TextOut(50,92,L"用户:
");
dc.TextOut(50,132,L"密码:
");
CFontfont;
VERIFY(font.CreatePointFont(200,_T(""),&dc));
CFont*def_font=dc.SelectObject(&font);
dc.SetTextColor(RGB(10,10,10));
dc.TextOut(20,30,L"浩翔综合无纸办公系统");
dc.SetTextColor(RGB(255,0,0));
dc.TextOut(21,31,L"浩翔综合无纸办公系统");
}
将对话框的Border必为none效果如下:
感觉不美观可以自己重新调整以上语句。
第三步,建立设置SQL或ACCESS数据库连接设置对话框如下:
为控件添加变量如下(在控件中右击添加变量):
CComboBoxm_cmbSqlServer;
CEditm_editName;
CEditm_editPass;
CComboBoxm_editDatabase;
添加函数voidDrawGradient(CDC*pDC,constCRect&rect,COLORREFrgbBegin,COLORREFrgbEnd,constint&iStep,constint&iDirection);
代码如下:
(渐变填充背景)
voidCLinkSet:
:
DrawGradient(CDC*pDC,constCRect&rect,COLORREFrgbBegin,COLORREFrgbEnd,constint&iStep,constint&iDirection)
{
floatfStep=iStep;
if(iStep==0)
{
fStep=1.0;
}
UINTnWidth=rect.Width();
UINTnHeight=rect.Height();
CRecttempRect;
floatfSteps=0;
floatnRed=0,nGreen=0,nBlue=0;//定义颜色差
floatfRedStep=0.0,fGreenStep=0.0,fBlueStep=0.0;
//得到色差空间
nRed=(GetRValue(rgbEnd)-GetRValue(rgbBegin));
nGreen=(GetGValue(rgbEnd)-GetGValue(rgbBegin));
nBlue=(GetBValue(rgbEnd)-GetBValue(rgbBegin));
//计算分多少步填充
switch(iDirection)
{
case1:
fSteps=(float)nHeight/fStep;
break;
case2:
fSteps=(float)nWidth/fStep;
break;
case3:
case4:
fSteps=(float)max(nWidth,nHeight);//^(1/2))/fStep;
break;
default:
fSteps=(float)nHeight/fStep;
break;
}
fRedStep=nRed/fSteps;
fGreenStep=nGreen/fSteps;
fBlueStep=nBlue/fSteps;
nRed=GetRValue(rgbBegin);
nGreen=GetGValue(rgbBegin);
nBlue=GetBValue(rgbBegin);
CPenpen;
switch(iDirection)
{
case1:
for(inti=0;i<=fSteps;i++)
{
tempRect.SetRect(0,i,nWidth,i+fStep);
nRed+=fRedStep;
nGreen+=fGreenStep;
nBlue+=fBlueStep;
pDC->FillSolidRect(&tempRect,RGB(nRed,nGreen,nBlue));
}
break;
case2:
for(inti=0;i<=fSteps;i++)
{
tempRect.SetRect(i,0,i+fStep,nHeight);
nRed+=fRedStep;
nGreen+=fGreenStep;
nBlue+=fBlueStep;
pDC->FillSolidRect(&tempRect,RGB(nRed,nGreen,nBlue));}
break;
default:
for(inti=0;i<=fSteps;i++)
{
nRed+=fRedStep;
nGreen+=fGreenStep;
nBlue+=fBlueStep;
tempRect.SetRect(0,i,nWidth,i+fStep);
pDC->FillSolidRect(&tempRect,RGB(nRed,nGreen,nBlue));
}
break;
}
}
对话框响应WM_ERASEBKGND消息如下:
CRectrect;
GetWindowRect(rect);
DrawGradient(pDC,&rect,RGB(100,186,255),RGB(15,42,255),1,1);
CFontfont;
CFont*def_font;
CPaintDCdc(this);
font.CreatePointFont(130,_T("宋体"),&dc);
def_font=dc.SelectObject(&font);
dc.SetBkMode
(1);
dc.SetTextColor(RGB(0,0,0));
dc.TextOut(10,62,L"SQL服务器:
");
dc.TextOut(55,94,L"用户名:
");
dc.TextOut(55,119,L"密码:
");
dc.TextOut(10,195,L"数据库名:
");
font.DeleteObject();
font.CreatePointFont(200,L"宋体",&dc);
def_font=dc.SelectObject(&font);
dc.SetTextColor(RGB(200,0,0));
dc.TextOutW(80,10,L"SQL数据连接设置");
returnTRUE;//CDialog:
:
OnEraseBkgnd(pDC);
接下来我们创建一个类,用于获取局域网内的所有SQL数据库服务器名称
在头文件中删掉基类(红色部分)添加如下变量及函数,或者我们在创建类时使用C++类而不是MFC类。
classCGetSqlServer:
publicCObject
头文件如下:
#pragmaonce
//CGetSqlServer命令目标
classCGetSqlServer
{
public:
CGetSqlServer();
virtual~CGetSqlServer();
BOOLGetServer(DWORDServerType,CStringArray&mArray);
intm_recordcount;
};
源文件如下:
注意lm.h后面的#pragma语句必须有
//GetSqlServer.cpp:
实现文件
//
#include"stdafx.h"
#include"GzyOa.h"
#include"GetSqlServer.h"
#include"afxtempl.h"
#include
#pragmacomment(lib,"Netapi32.lib")
//CGetSqlServer
CGetSqlServer:
:
CGetSqlServer()
{
}
CGetSqlServer:
:
~CGetSqlServer()
{
}
/*************************************************
ServerType为枚举项目类别定义如下
#defineSV_TYPE_WORKSTATION0x00000001
#defineSV_TYPE_SERVER0x00000002
#defineSV_TYPE_SQLSERVER0x00000004
#defineSV_TYPE_DOMAIN_CTRL0x00000008
#defineSV_TYPE_DOMAIN_BAKCTRL0x00000010
#defineSV_TYPE_TIME_SOURCE0x00000020
#defineSV_TYPE_AFP0x00000040
#defineSV_TYPE_NOVELL0x00000080
#defineSV_TYPE_DOMAIN_MEMBER0x00000100
#defineSV_TYPE_PRINTQ_SERVER0x00000200
#defineSV_TYPE_DIALIN_SERVER0x00000400
#defineSV_TYPE_XENIX_SERVER0x00000800
#defineSV_TYPE_SERVER_UNIXSV_TYPE_XENIX_SERVER
#defineSV_TYPE_NT0x00001000
#defineSV_TYPE_WFW0x00002000
#defineSV_TYPE_SERVER_MFPN0x00004000
#defineSV_TYPE_SERVER_NT0x00008000
#defineSV_TYPE_POTENTIAL_BROWSER0x00010000
#defineSV_TYPE_BACKUP_BROWSER0x00020000
#defineSV_TYPE_MASTER_BROWSER0x00040000
#defineSV_TYPE_DOMAIN_MASTER0x00080000
#defineSV_TYPE_SERVER_OSF0x00100000
#defineSV_TYPE_SERVER_VMS0x00200000
#defineSV_TYPE_WINDOWS0x00400000//Windows95andabove
#defineSV_TYPE_DFS0x00800000//RootofaDFStree/
#defineSV_TYPE_CLUSTER_NT0x01000000//NTCluster//
#defineSV_TYPE_TERMINALSERVER0x02000000//TerminalServer(Hydra)/
#defineSV_TYPE_CLUSTER_VS_NT0x04000000//NTClusterVirtualServerName/
#defineSV_TYPE_DCE0x10000000//IBMDSS(DirectoryandSecurityServices)orequivalent/
#defineSV_TYPE_ALTERNATE_XPORT0x20000000//returnlistforalternatetransport/
#defineSV_TYPE_LOCAL_LIST_ONLY0x40000000//Returnlocallistonly/
#defineSV_TYPE_DOMAIN_ENUM0x80000000
#defineSV_TYPE_ALL0xFFFFFFFF//handyforNetServerEnum2/
*************************************************/
BOOLCGetSqlServer:
:
GetServer(DWORDServerType)
{
mArray.RemoveAll();
LPSERVER_INFO_101pBuf=NULL;
LPSERVER_INFO_101pTmpBuf;
DWORDdwLevel=101;
DWORDdwPrefMaxLen=MAX_PREFERRED_LENGTH;
DWORDdwEntriesRead=0;
DWORDdwTotalEntries=0;
DWORDdwTotalCount=0;
DWORDdwServerType=ServerType;//SV_TYPE_SERVER;//allservers
DWORDdwResumeHandle=0;
NET_API_STATUSnStatus;
LPTSTRpszServerName=NULL;
DWORDi;
nStatus=NetServerEnum(NULL,
dwLevel,
(LPBYTE*)&pBuf,
dwPrefMaxLen,
&dwEntriesRead,
&dwTotalEntries,
dwServerType,
NULL,
&dwResumeHandle);
intj=0;
if((nStatus==NERR_Success)||(nStatus==ERROR_MORE_DATA))
{
if((pTmpBuf=pBuf)!
=NULL)
{
m_recordcount=dwEntriesRead;
for(inti=0;i{
if(pBuf!
=NULL)
{
//swprintf(m_servername[i],L"%s",pTmpBuf->sv101_name);
mArray.Add(pTmpBuf->sv101_name);
j++;
}
pTmpBuf++;
dwTotalCount++;
}
}
}
if(pBuf!
=NULL)
NetApiBufferFree(pBuf);
//TODO:
Addextrainitializationhere
returnTRUE;
}
//CGetSqlServer成员函数
再建一个SQL数据库操作类CMySql头文件如下:
#pragmaonce
#import"C:
\ProgramFiles(x86)\CommonFiles\System\ado\msado15.dll"no_namespace\
rename("EOF","adoEOF")rename("BOF","adoBOF")
//CMySql命令目标
classCMySql
{
public:
CMySql();
virtual~CMySql();
//添加一个指向Connection对象的指针
_ConnectionPtrm_pConnection;
//添加一