侧边栏壁纸
博主头像
拾荒的小海螺博主等级

只有想不到的,没有做不到的

  • 累计撰写 140 篇文章
  • 累计创建 15 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录
WIN

C++:使用 DuiLib 开发一个简易的登录功能

拾荒的小海螺
2024-04-20 / 0 评论 / 0 点赞 / 7 阅读 / 12482 字

1、简述

Duilib是一个Windows下免费开源的DirectUI界面库,由于简约易扩展的设计以及稳定高效的实现被各大互联网公司普遍接受,广泛应用于包括IM、视频客户端、股票行情软件、导航软件、手机辅助软件、安全软件等多个行业的众多pc客户端软件。Duilib还在不断的发展中,在文档、例子、动画、渲染引擎等多个方面将持续改进。以下是一个示例,展示了如何使用DuiLib创建一个简单的登录界面。

首先,确保你已经配置好了DuiLib的开发环境,包括安装了Visual Studio和DuiLib库。然后,创建一个新的C++项目,并按照以下步骤进行操作。

添加DUILIB Lib 关联:

  • 在项目属性中链接器->常规->附加库依赖项中 添加lib的关联本地目录
  • 在项目属性中链接器->输入->附加库依赖项中 添加DuiLib.lib

代码Github:https://github.com/lmengi/login_demo.git

官网地址:https://github.com/duilib/duilib

gitcode地址:https://gitcode.com/duilib/duilib/tree/master

腾讯duilib版:https://github.com/tencentyun/TIMSDK/tree/master/cross-platform/Windows/IMApp/Basic/duilib

网易duilib版:https://github.com/netease-im/NIM_Duilib_Framework/tree/master/duilib

1713583924131.jpg

2、创建项目

下面是一个简单的示例代码,用于创建登录界面,首先新建登陆窗口类去继承WindowImplBase窗口基类:

/*登录窗口类*/
class CLoginWindowUI : public WindowImplBase
{
public:
    CLoginWindowUI();
    virtual ~CLoginWindowUI();

	UIBEGIN_MSG_MAP
	EVENT_BUTTON_CLICK(_T("minbtn"),OnBtnMinClick);
	EVENT_BUTTON_CLICK(_T("closebtn"),OnBtnCloseClick);
	EVENT_BUTTON_CLICK(_T("loginBtn"),OnBtnLoginClick);
	EVENT_BUTTON_CLICK(_T("cancelBtn"),OnBtnCancelClick);
	UIEND_MSG_MAP

private:
	//登录按钮事件响应
	void OnBtnLoginClick(TNotifyUI& msg);
	//关闭按钮事件响应
	void OnBtnCloseClick(TNotifyUI& msg);
	//最小化按钮事件响应
	void OnBtnMinClick(TNotifyUI& msg);
	//取消按钮事件响应
	void OnBtnCancelClick(TNotifyUI& msg);


public:
	//创建窗口
	void ShowUI();

protected:
    virtual LPCTSTR GetWindowClassName() const;
    virtual CDuiString GetSkinFile();
    virtual void InitWindow();
    virtual CDuiString GetSkinFolder();
   // void Notify(TNotifyUI& msg);

	virtual LRESULT		HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	/*登录回调函数*/
	static bool LoginCallBack(void* pObj);

	/*显示登录结果提示*/
	void ShowLoginTip(string strTip);

	/*显示个人资料窗口*/
	void ShowUserInfoWindow(string strUserId);

	/*设置用户ID*/
	void SetUserId(string strUserId);
private:

	CEditUI*   m_userNameEdit;
	CEditUI*   m_passWordEdit;

	CVerticalLayoutUI*	m_pLoginLayout;
	CVerticalLayoutUI*	m_pLoginTipLayout;

	string	   m_strUserId;
};

事件通过UIBEGIN_MSG_MAP消息来管理一般按钮事件:

	UIBEGIN_MSG_MAP
	EVENT_BUTTON_CLICK(_T("minbtn"),OnBtnMinClick);
	EVENT_BUTTON_CLICK(_T("closebtn"),OnBtnCloseClick);
	EVENT_BUTTON_CLICK(_T("loginBtn"),OnBtnLoginClick);
	EVENT_BUTTON_CLICK(_T("cancelBtn"),OnBtnCancelClick);
	UIEND_MSG_MAP

其他的UI控件可以在InitWindow初始化窗口去绑定:

m_userNameEdit = dynamic_cast<CEditUI*>(m_PaintManager.FindControl(_T("Username")));
m_passWordEdit = dynamic_cast<CEditUI*>(m_PaintManager.FindControl(_T("Password")));

m_pLoginLayout = static_cast<CVerticalLayoutUI *>(m_PaintManager.FindControl(_T("loginLayout")));
m_pLoginTipLayout = static_cast<CVerticalLayoutUI *>(m_PaintManager.FindControl(_T("loginTipLayout")));

3、创建布局文件

在项目中创建一个名为LoginWindowUI.xml的XML布局文件,用于定义登录界面的UI布局,布局自己可以通过VerticalLayout 垂直方向和HorizontalLayout水平方向来控制整体的UI布局,例如:

<?xml version="1.0" encoding="UTF-8"?>
  
<!-- 窗口的尺寸(宽315,高723) -->
<Window size="315,723" caption="0,0,0,723">
	<!-- 字体定义 -->
	<Font id="120000" name="微软雅黑" size="12" shared="true" bold="false"></Font>
	<Font id="140000" name="微软雅黑" size="12" shared="true" bold="false"></Font>

	<VerticalLayout bkcolor="#FF3795F3" bkcolor2="#FFFFFFFF" bordercolor="FF000000" bordersize="1"> <!-- 整个窗口的背景色 -->
        <!-- 标题栏区 -->
        <HorizontalLayout height="32">
			<Control width="12"/>
			<Label name="title" text="网龙99游" font="120000" autosize="true" textcolor="#FFFFFFFF"/>
			<Control />
			<Button name="minbtn" tooltip="最小化" height="19" width="23" normalimage="file='LoginWindow\MinNormal.bmp'" hotimage=" file='LoginWindow\MinFocus.bmp'" pushedimage="file='LoginWindow\MinFocus.bmp'"/>
			<Button name="closebtn" tooltip="关闭" width="28" height="19" normalimage=" file='LoginWindow\CloseNormal.bmp'" hotimage=" file='LoginWindow\CloseFocus.bmp'" pushedimage="file='LoginWindow\CloseFocus.bmp'"/>   
        </HorizontalLayout>
    
        <!-- 客户区 -->
        <VerticalLayout>
			<!-- 头像 -->
			<Control height="48"/>
			<HorizontalLayout height="100">
				<Control />
				<Label name="HeadPic" bkimage="LoginWindow\headIcon.png" width="100" height="100"/>
				<Control />
			</HorizontalLayout>
		
			<Control height="42"/>
	
			<Container>
				<!-- 登录界面 -->
				<VerticalLayout name="loginLayout">
					<HorizontalLayout height="40">
						<Control />
						<Label text="用户名" width="42" font="120000" autosize="true" textcolor="#FFFFFFFF"/>
						<Edit name="Username" width="245" height="40" font="120000" bkimage="file='LoginWindow\\edit_rename_bk.png' corner='10,3,10,3'"/>
						<Control />
					</HorizontalLayout>
		
					<Control height="22"/>
		
					<HorizontalLayout height="40">
						<Control />
						<Label text="密码" width="42" font="120000" autosize="true" textcolor="#FFFFFFFF"/>
						<Edit name="Password" width="245" height="40" password="true" font="120000" bkimage="file='LoginWindow\\edit_rename_bk.png' corner='10,3,10,3'"/>
						<Control />
					</HorizontalLayout>
			
					<Control height="55"/>
		
					<HorizontalLayout height="20">
						<Control />
						<Label name="loginTip" text="" height="20" width="60" font="120000" autosize="true" textcolor="#FFFF0000" visible="false"/>
						<Control />
					</HorizontalLayout>
		
					<Control height="55"/>
		
					<HorizontalLayout height="25">
						<Control />
						<Button name="loginBtn" text="登录" font="120000" width="100" height="25" textcolor="#FF000000" normalimage="file='LoginWindow\btnLogin_normal.png' corner='4,4,4,4'" hotimage="file='LoginWindow\btnLogin_hot.png' corner='4,4,4,4'" pushedimage="file='LoginWindow\btnLogin_pushed.png' corner='4,4,4,4'"/>
						<Control />
					</HorizontalLayout>
				</VerticalLayout>
		
				<!-- 登录进行时 -->
				<VerticalLayout name="loginTipLayout" visible="false">
					<HorizontalLayout  height="25">
						<Control />
						<Label text="正在登录..." font="120000" autosize="true" textcolor="#FF000000"/>
						<Control />
					</HorizontalLayout>
			
					<Control height="185"/>
			
					<HorizontalLayout height="25">
						<Control />
						<Button name="cancelBtn" text="取消" width="245" height="25" bkcolor="#FFFF0000" textcolor="#FF000000"/>
						<Control />
					</HorizontalLayout>
				</VerticalLayout>
			</Container>

		</VerticalLayout>
    </VerticalLayout>
</Window>   

窗口UI跟XML绑定,这个自己在duilib里面解析根目录的路径。通过本地重载GetSkinFile指定具体的本地xml目录:

CDuiString CLoginWindowUI::GetSkinFile()
{
   return _T("LoginWindow\\LoginWindowUI.xml");
}

4、准备SQLite3

使用SQLite3来实现用户登录功能涉及创建数据库、表格和编写查询语句以验证用户身份。以下是一个简单的示例,展示如何使用SQLite3和C++来实现基本的用户登录功能:

#include "stdafx.h"
#include "DataBaseOperation.h"
#include "Util.h"

#pragma comment(lib, "sqlite3.lib")

CDataBaseOperateion::CDataBaseOperateion( void )
{
	m_pSqlite3 = NULL;
}

CDataBaseOperateion::~CDataBaseOperateion( void )
{
	if(m_pSqlite3)
		DataBaseClose();
}

bool CDataBaseOperateion::DataBaseOpen()
{
	TCHAR szDir[MAX_PATH];
	GetModuleFileName(NULL, szDir, MAX_PATH);

	TCHAR* p = _tcsrchr(szDir, _T('\\'));
	*(p + 1) = '\0';

	wstring wstrDBPath = szDir;
	wstrDBPath += L"Login.db3";

	bool bRet = false;
	int nRet = sqlite3_open16(wstrDBPath.c_str(), &m_pSqlite3);
	if (nRet == SQLITE_OK)  
	{  
		bRet = true;
	}  

	return bRet;
}

bool CDataBaseOperateion::DataBaseInsert( string& strSQLJson )
{
	bool bRet = false;
	if(m_pSqlite3 == NULL)
		DataBaseOpen();
	if(m_pSqlite3)
	{
		char* szErrMsg;  
		int nRes = sqlite3_exec(m_pSqlite3 , strSQLJson.c_str() ,0 ,0, &szErrMsg);  
		if (nRes == SQLITE_OK)  
		{  
			bRet = true;
		}  
	}

	return bRet;
}

bool CDataBaseOperateion::DataBaseFind( string& strInSQLJson, string& strOutSQLJson )
{
	bool bRet = false;
	char** pszResult;
	char* szErrMsg;
	int nRow;
	int nCol;
	if(m_pSqlite3 == NULL)
		DataBaseOpen();
	if(m_pSqlite3)
	{
		int nRes = sqlite3_get_table(m_pSqlite3, strInSQLJson.c_str(), &pszResult, &nRow, &nCol, &szErrMsg);  
		if (nRes == SQLITE_OK)  
		{  
			bRet = true;
			if(nRow > 0)
			{
				Json::Value root;
				Json::FastWriter writer;
				int nIndex = nCol;
				for(int i = 0; i < nRow ; i++)
				{
					Json::Value value;
					for(int j = 0; j < nCol; j++)
					{
						value[pszResult[j]] = pszResult[nIndex];		
						++nIndex;
					}
					root.append(value);
				}
				//			root["Count"] = nIndex;
				sqlite3_free_table(pszResult);
				strOutSQLJson = writer.write(root);
			}
		}  
	}
	 
	return bRet;
}

bool CDataBaseOperateion::DataBaseClose()
{
	int nRes = sqlite3_close(m_pSqlite3);
	if (nRes == SQLITE_OK)  
	{  
		m_pSqlite3 = NULL;
	}

	return true;
}

在代码中,首先打开了名为Login.db3的数据库文件。然后,通过输入用户名和密码,构造了一个查询语句,用于检查是否存在与输入匹配的用户。通过CDataBaseOperateion类用于执行SQL增删改查。最后,关闭数据库连接。

5、结论

将代码编译成可执行文件,并运行该程序,你将看到一个简单的登录界面博客。用户可以输入用户名和密码,然后点击登录按钮。这只是一个基本的示例,你可以根据自己的需求进一步扩展和优化界面,添加更多的交互功能和登录验证逻辑。希望这能帮助你入门使用DuiLib开发Windows桌面应用程序!

0

评论区