先上效果图(自己感觉还不错):
功能不完善,一是为了熟悉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