Duilib登录窗口

先上效果图(自己感觉还不错):

Duilib登录窗口_第1张图片

功能不完善,一是为了熟悉xml的写法,手写,不建议使用编辑器,二了为了理顺程序的流程,加入了部分注释。

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Window size="300,220" roundcorner="4,4">
	<Font name="楷体" size="14" default="true" />
	<Container bkimage="bk_image.png" >
		<Label text="用户登录" float="true" pos="5, 5, 80, 20"/>
		<Button name="closebtn" float="true" pos="275, 0, 300, 20" tooltip="退出程序" normalimage="file='frame_btn_close_normal.bmp' mask='#FFFF00FF'" hotimage="file='frame_btn_close_hot.bmp' mask='#FFFF00FF'" pushedimage="file='frame_btn_close_down.bmp' mask='#FFFF00FF'"/>
		<Label text="{b}账号:{/b}" float="true" showhtml="true" pos="60, 105, 100, 125" />
		<Label text="{b}密码:{/b}" float="true" showhtml="true" pos="60, 140, 100, 160" />
		<Edit name="nameedit" float="true" pos="120, 105, 240, 125" />
		<Edit name="passwdedit" password="true" float="true" pos="120, 140, 240, 160" />
		<Button name="registerbtn" text="注册" float="true" bordercolor="#e50010" bordersize="1" bkcolor="#bcc1b4" tooltip="注册新帐号" pos="90,185,130,205" />
		<Button name="loginbtn" text="登录" float="true" bordercolor="#e50010" bordersize="1" bkcolor="#bcc1b4" tooltip="登录帐号" pos="170,185,210,205" />
	</Container>
</Window>

程序代码:

//2012.10.16     by l0g1n。
#include "stdafx.h"

class CFrameWindowWnd:public CWindowWnd,public INotifyUI
{
public:
	CFrameWindowWnd(){};
	LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); }
	void OnPrepare() 
	{
	}
	void Notify(TNotifyUI& msg)
	{
		if(msg.sType==_T("windowinit"))
			OnPrepare();
		else if(msg.sType==_T("click"))
		{
			if(msg.pSender==m_pCloseBtn)
			{
				PostQuitMessage(0);
				return;
			}else if(msg.pSender==m_pRegisterBtn)
			{
				MessageBox(NULL,m_pNameEdit->GetText()+_T("\n")+m_pPasswdEdit->GetText(),_T("注册"),MB_OK);
				return;
			}else if(msg.pSender==m_pLoginBtn)
			{
				MessageBox(NULL,m_pNameEdit->GetText()+_T("\n")+m_pPasswdEdit->GetText(),_T("登录"),MB_OK);
				return;
			}
		}
	}
	void Init()
	{
		 m_pCloseBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("closebtn")));
		 m_pRegisterBtn=static_cast<CButtonUI*>(m_pm.FindControl(_T("registerbtn")));
		 m_pLoginBtn=static_cast<CButtonUI*>(m_pm.FindControl(_T("loginbtn")));
		 m_pNameEdit=static_cast<CEditUI*>(m_pm.FindControl(_T("nameedit")));
		 m_pPasswdEdit=static_cast<CEditUI*>(m_pm.FindControl(_T("passwdedit")));
	}

    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
        styleValue &= ~WS_CAPTION;
        ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
        m_pm.Init(m_hWnd);
        //m_pm.SetTransparent(100);
        CDialogBuilder builder;
        CControlUI* pRoot = builder.Create(_T("login.xml"), (UINT)0, NULL, &m_pm);
        ASSERT(pRoot && "Failed to parse XML");
        m_pm.AttachDialog(pRoot);
        m_pm.AddNotifier(this);
        Init();
        return 0;
    }
    LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        SIZE szRoundCorner = m_pm.GetRoundCorner();//这个是圆角,是椭圆的半径
		//这里有个很巧妙的用法,在xml文件中一定要设置圆角(roundcorner),
		//不然不会进入下面的if,也就会出现标题栏。
        if( !::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0) ) {
            CRect rcWnd;
            ::GetWindowRect(*this, &rcWnd);
            rcWnd.Offset(-rcWnd.left, -rcWnd.top);
            rcWnd.right++; rcWnd.bottom++;
            RECT rc = { rcWnd.left, rcWnd.top + szRoundCorner.cx, rcWnd.right, rcWnd.bottom };
            HRGN hRgn1 = ::CreateRectRgnIndirect( &rc );
            HRGN hRgn2 = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom - szRoundCorner.cx, szRoundCorner.cx, szRoundCorner.cy);
            ::CombineRgn( hRgn1, hRgn1, hRgn2, RGN_OR );
            ::SetWindowRgn(*this, hRgn1, TRUE);
            ::DeleteObject(hRgn1);
            ::DeleteObject(hRgn2);
        }

        bHandled = FALSE;
        return 0;
    }
    LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        MONITORINFO oMonitor = {};
        oMonitor.cbSize = sizeof(oMonitor);
        ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
        CRect rcWork = oMonitor.rcWork;
        rcWork.Offset(-rcWork.left, -rcWork.top);

        LPMINMAXINFO lpMMI = (LPMINMAXINFO) lParam;
        lpMMI->ptMaxPosition.x	= rcWork.left;
        lpMMI->ptMaxPosition.y	= rcWork.top;
        lpMMI->ptMaxSize.x		= rcWork.right;
        lpMMI->ptMaxSize.y		= rcWork.bottom;

        bHandled = FALSE;
        return 0;
    }
	LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
        if( ::IsIconic(*this) ) bHandled = FALSE;
        return (wParam == 0) ? TRUE : FALSE;
	}
    LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        return 0;
    }
	LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		POINT pt;
		pt.x=GET_X_LPARAM(lParam);
		pt.y=GET_Y_LPARAM(lParam);
		::ScreenToClient(*this, &pt);
		CControlUI* pControl=static_cast<CControlUI*>(m_pm.FindControl(pt));
		if(pControl && _tcscmp(pControl->GetClass(),_T("ButtonUI"))!=0 && _tcscmp(pControl->GetClass(),_T("EditUI"))!=0)
			return HTCAPTION;
		return HTCLIENT;
	}
	LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		LRESULT lRes=0;
		BOOL bHandled=TRUE;
		switch(uMsg)
		{
		case WM_CREATE:        lRes=OnCreate(uMsg,wParam,lParam,bHandled);break;
		//能去除边框
		case WM_NCCALCSIZE:    lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled);break;
		//去除显示的标题栏
		case WM_SIZE:          lRes=OnSize(uMsg,wParam,lParam,bHandled);break;
		//解决按住左键或右键时会出现边框的问题
		case WM_NCACTIVATE:    lRes = OnNcActivate(uMsg, wParam, lParam, bHandled); break;
		//实现按住窗口(除按钮外)拖动窗口
		case WM_NCHITTEST:     lRes=OnNcHitTest(uMsg,wParam,lParam,bHandled);break;
		//获取边框最大最小值
		case WM_GETMINMAXINFO: lRes=OnGetMinMaxInfo(uMsg,wParam,lParam,bHandled);break;
		case WM_DESTROY:       ::PostQuitMessage(0);break;
		default:               bHandled=FALSE;
		}
		if(bHandled)
			return lRes;
		if(m_pm.MessageHandler(uMsg,wParam,lParam,lRes))
			return lRes;
		return CWindowWnd::HandleMessage(uMsg,wParam,lParam);
	}
public:
	CPaintManagerUI m_pm;
private:
	CButtonUI* m_pCloseBtn;
	CButtonUI* m_pRegisterBtn;
	CButtonUI* m_pLoginBtn;
	CEditUI* m_pNameEdit;
	CEditUI* m_pPasswdEdit;
};

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iCmdShow)
{
	CPaintManagerUI::SetInstance(hInstance);
	CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()+_T("skin"));
	CPaintManagerUI::SetResourceZip(_T("skinRes"));

	HRESULT hr=::CoInitialize(NULL);
	if(FAILED(hr))
		return 0;
	CFrameWindowWnd* pFrame = new CFrameWindowWnd();
	if(pFrame==NULL)
		return 0;
	pFrame->Create(NULL, NULL, UI_WNDSTYLE_FRAME,WS_EX_STATICEDGE | WS_EX_APPWINDOW,0,0,400,400);
	pFrame->CenterWindow();
	::ShowWindow(*pFrame,SW_SHOW);

	CPaintManagerUI::MessageLoop();
	::CoUninitialize();
	return 0;
}

完整文件下载地址:

http://download.csdn.net/detail/l0g1n/4654004

你可能感兴趣的:(xml,File,null,float,encoding,winapi)