[置顶] Direct UI
有个坑爹的说法:其实Direct UI只是一个思想,要实现这个思想,还要靠自己。
采用windowless方式用api或gdi实现ui的绘制。
DirectUI意为直接在父窗口上绘图(Paint on parent dc directly)。
子窗口不以窗口句柄的形式创建,只是逻辑上的窗口,绘制在父窗口之上。
DirectUI技术的实现步骤和难点:
1、窗口的子类化,截获窗口的消息。
2、封装自己的控件,并将自己的控件绘制到该窗口上
3、封装窗口的消息,并分发到自己的控件上,让自己的控件根据消息进行相应和绘制
4、根据不同的行为发送自定义消息给窗口,以便程序进行调用。
5、一般窗口上控件的组织使用XML来描述
首先,要实现一个好的DirectUI,必须设计出一套逻辑性、可编程性及可扩展性非常强的层布局器(Layout Manager ),为什么这样说呢?
因为DirectUI的核心设计思想就是界面自绘,既然很多控件都要用自绘的形式表现在界面上,那么控件与控件之间,一定存在某些逻辑布局上的依赖关系,我们可以把一个app分解成3D构架,横向为X,纵向为Y,内外为Z,那么好了,A控件跟B控件的X、Y相同,但是我要实现成B为A打底,成为A的背景(当然A会绘制成透明背景模式),那么A与B之间只存在Z的关系,即层次性。由此可以看出,一个好的Layout Manager是DirectUI绘制必不可少的关键点,可以将UI所要表达的所有控件(windowless,全部需要绘制出来的)层次分明的一一展现。(题外话:你可以通过任何手段将控件的逻辑位置等信息解析到LM中)
其次,ReDraw,第一点我已经阐明了控件之间层的关系,接下来自然是要通过LM(Layout Manager)将控件一一表现到界面上。如果在你的项目中木有LM,那么你就惨了,你无法判断应该用什么顺序依次往你的程序界面上绘制控件:(,就像一张空白的画纸,而你想往上面画很多漂亮的猫猫狗狗,那究竟是先画猫还是先画狗呢。。。打住,通过LM,你完全很清楚先画什么后画什么,LM设计的时候可以要求传入控件要有父控件节点,哦可!那么在ReDraw的时候,先遍历LM,绘制父节点,再绘制子节点,这样一来,界面就基本具有逻辑雏形了。
最后,该绘制的控件已经都绘制出来了,剩下唯一需要你实现的就是如何响应用户对这些控件的操作,这个应该不用多说了,无非就是捕获用户当前LButtonDone/LButtonUp等鼠标Click事件及rect,然后根据LM反馈出属于那种控件,以及该控件对应的事件即可。
以下转载地址:http://blog.sina.com.cn/s/blog_4c3b2dc20100s8w6.html
if( uMsg == WM_CREATE ) {
m_pm.Init(m_hWnd);
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(GetDialogResource());
ASSERT(pRoot && "Failed to parse XML");
m_pm.AttachDialog(pRoot);
m_pm.AddNotifier(this);
Init();
return 0;
}
LRESULT lRes = 0;
if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
void CButtonUI::Event(TEventUI& event)
{
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )//按下
{
if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled() ) { //判断是否在区域内,调用IsEnable
m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED; //修改外观
Invalidate();
}
} if( event.Type == UIEVENT_BUTTONUP )
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
if( ::PtInRect(&m_rcItem, event.ptMouse) ) Activate();
m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
Invalidate();
}
}
bool CButtonUI::Activate()
{
if( !CControlUI::Activate() ) return false;
if( m_pManager != NULL ) m_pManager->SendNotify(this, _T("click"));
return true;
}
void CPaintManagerUI::SendNotify(CControlUI* pControl, LPCTSTR pstrMessage, WPARAM wParam , LPARAM lParam )
{
TNotifyUI Msg;
Msg.pSender = pControl;
Msg.sType = pstrMessage;
Msg.wParam = 0;
Msg.lParam = 0;
SendNotify(Msg);
} void CPaintManagerUI::SendNotify(TNotifyUI& Msg)
{
// Pre-fill some standard members
Msg.ptMouse = m_ptLastMousePos;
Msg.dwTimestamp = ::GetTickCount();
// Allow sender control to react
Msg.pSender->Notify(Msg);
// Send to all listeners
for( int i = 0; i < m_aNotifiers.GetSize(); i++ ) {
static_cast<INotifyUI*>(m_aNotifiers[i])->Notify(Msg); //发送给所有接口
}
}
void CSearchPageWnd::Notify(TNotifyUI& msg)
{
if( msg.sType == _T("click") )
{
if( msg.pSender->GetName() == _T("ok") ) {
CStandardPageWnd* pWindow = new CEditPageWnd;
pWindow->Create(m_hWnd, NULL, UI_WNDSTYLE_FRAME, 0L);
}
if( msg.pSender->GetName() == _T("cancel") ) Close();
}
CStandardPageWnd::Notify(msg);
}
[置顶] Direct UI的更多相关文章
- [置顶] Kendo UI开发教程: Kendo UI 示例及总结
前面基本介绍完Kendo UI开发的基本概念和开发步骤,Kendo UI的示例网站为http://demos.kendoui.com/ ,包含了三个部分 Web DemoMobile DemoData ...
- [置顶] 安卓UI组件之ListView详解
ListView是很常见的一个UI组件,在许多App中都很常用,其意思就是可滚动的列表,使用ListView必须使用Adapter(适配器),常用的适配器友谊ArrayAdapter,SimpleAd ...
- [置顶] Android开发笔记(成长轨迹)
分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...
- UITableView设置Cell左滑多个按钮(编辑,删除,置顶等)
一.iOS7不支持cell多个按钮这个时候可以使用一个三方库JZTableViewRowAction,引用类扩展文件并实现其代理方法 JZTableViewRowAction下载地址:http://d ...
- [置顶] Silverlight之控件应用总结(一)(3)
[置顶] Silverlight之控件应用总结(一)(3) 分类: 技术2012-04-02 20:35 2442人阅读 评论(1) 收藏 举报 silverlightradiobuttondatat ...
- 在UWP中页面滑动导航栏置顶
最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西 当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms ...
- WinFrom窗体始终置顶
调用WindowsAPI使窗体始终保持置顶效果,不被其他窗体遮盖: [DllImport("user32.dll", CharSet = CharSet.Auto)] privat ...
- winform窗体置顶
winform窗体置顶 金刚 winform 置顶 今天做了一个winform小工具.需要设置置顶功能. 网上找了下,发现百度真的很垃圾... 还是必应靠谱些. 找到一个可以链接. https://s ...
- 自定义置顶TOP按钮
简述一下,分为三个步骤: 1. 添加Html代码 2. 调整Css样式 3. 添加Jquery代码 具体代码如下: <style type="text/css"> #G ...
随机推荐
- VC使用#定义方便控制版本号的宏
一个 VC Project 中,可能有很多地方需要用到版本号,比如 About 对话框.版本资源等.如果每次版本更改都一一去改变这些值,不但非常麻烦,而且有悖唯一原则. 巧妙地使用宏定义,可以很好地解 ...
- 操作系统基本概念(内核态与用户态、操作系统结构)-by sixleaves
内核态与用户态(为什么存在这种机制.程序应处于哪个状态.如何判断当前所处状态.哪些功能需要内核态.如何实现这种机制) 1.首先我们应该思考清楚为什么会有内核态和用户态?(为什么存在这种机制) 因为计算 ...
- 【bzoj1031】[JSOI2007]字符加密Cipher
题目描述 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作:JSOI07 ...
- Google Go 语言从入门到应用必备开源项目
Go 语言于 2009 年 11 月正式宣布推出,成为开放源代码项目,发展至今已经具有越来越广泛的影响力,今年更是在 TIOBE 编程语言排行榜中跻身 20 强.很多开发者也逐渐将目光投向这门语言,本 ...
- 3第一周课后练习·阅读计划(3)-使用函数来访问私有数据成员
/* * Copyright (c) 2015, 计算机科学学院,烟台大学 * All rights reserved. * 文件名:test.cpp * 作 靠:刘畅 * 完成日期:2015年 3 ...
- 多线程:pthread_exit,pthread_join,pthread_self
/*exit_join_id.c*/ #include<pthread.h> #include<stdio.h> void* eji(void* agr) { printf(& ...
- Git使用过程
Git-------目前世界上最先进的分布式版本控制系统(没有之一) 什么是版本控制系统? 说简单点,就是一个文件,对其增加.删除.修改都可以被记录下来,不仅自己可以修改,其他人也可以进行修改 每次对 ...
- Hadoop 安装(1) CENTOS 安装与配置
配置虚拟机,名字 Hadoop_Slave4,内存为1024MB,15GB. 进入安装centos. 配置Hostname: Slave4.Hadoop 配置网络,设置静态IP:192.168.1.2 ...
- 分享一个手机端好用的jquery ajax分页类
分享一个手机端好用的jquery ajax分页类 jquery-ias.min.js 1,引入jquery-ias.min.js 2,调用ajax分页 <script type="te ...
- JSP 实现 之 读取数据库显示图片
用JSP从数据库中读取图片并显示在网页上 环境mysql+tomcat: <1>先在mysql下建立如下的table. 并insert图像. mysql.sql文件如下: ) unsign ...