Filed under: 界面设计
Windows的菜单我们每天都在使用,一般情况下,如果需要美化菜单,例如改变字体、背景颜色等,都是直接在菜单的AdvancedDrawItem事件里面进行自绘即可。但如果想实现一些特殊效果,比如说菜单半透明,就的自己实现整个菜单了。 实现一个菜单大概需要处理这些问题:(1)绘制各个菜单项。(2)菜单窗口弹出来后,所属窗口不应该失去焦点。(3)点击了菜单项后应该关闭菜单。对于问题1,我们可以简单的根据菜单项的数量,然后判断状态(比如说鼠标现在是否位于该项目上面)进行绘制;对于问题3,需要判断鼠标点击事件。对于问题2,我们可以类似实现自定义Combobox一样,响应弹出窗口的WM_ACTIVATE
...阅读更多
2019-05-20
我们的透明皮肤控件设计系列到此告一段落了,想进一步学习的朋友,可以找一些当前流行的DirectUI的资料来看看。 所谓DirectUI,意思是直接画的,例如QQ之类,除了窗口外,全部控件都是画出来的,没有单独的句柄。DirectUI的好处在于没有句柄外,因为全部控件都是画在一张画布上面,所以闪烁的机会更加少。实际上,Delphi本身所有从TGraphicControl继承下来的控件也是无句柄的,例如TLabel。另外有一个控件包叫DXScene(应该就是FireMonkey的前身)也是基于DirectUI的,除了全部控件都是画的外,它还是基于3D坐标系的,而且是直接在显存里面显示的: 1、原始
...阅读更多
2013-08-18
除了第二讲里面的平均颜色之外,实际上一个真正成熟的界面涉及的东西还是很多的。 一、九宫格算法 例如按钮,假如说,图片使用拉伸方式的话,按钮变大后会很难看,这种情况下一般使用九宫格算法。 所谓九宫格算法,就是把图片分成1~9个区域,针对不同区域作不同处理: A---------B---------C--------D | | | | |1不变 | 2只变宽 | 3不变 | E------LtPt-----RTPt--------F | |
...阅读更多
2013-08-18
滚动条对于界面来说也是非常重要的。修改系统默认滚动条一般有三种方法: 一、覆盖法 覆盖法顾名思义就是创建一个跟滚动条大小一样的控件,覆盖在原来的滚动条上面,当有消息的时候,直接“漏”下去给原来真正的滚动条: [sourcecode language="delphi"] procedure TWinScroll.WMNCHitTest(var Msg: TWMNCHitTest); begin Msg.Result := HTTRANSPARENT; end; [/sourcecode] 优点:不用自己计算变化范围。 缺点:大小无法改变。例如比系统原来的滚动条小的化,就盖不住原来的了。 二、控件
...阅读更多
2013-08-14
现在我们有了透明窗口,那么所有控件也应该是透明的。 控件透明,原理其实很简单,就是把父控件的图像复制到自己上面即可。例如,常用的方法是给父控件发送背景重画的消息,同时把自己的DC传递过去: SendMessage(Parent.Handle, WM_ERASEBKGND, DC, 0); TCtrl(Parent).PaintControls(DC, nil); 这种方法对于非自己设计的皮肤窗口也有效,但缺点是会因为父窗口重画造成闪烁。 现在因为透明窗口也是我们自己制作的,所以方法就简单多了:根据自己的坐标位置,直接从图片拷贝即可。以CheckBox为例,代码段如下: Buffer := TB
...阅读更多
2013-08-11
经过上面的几篇文章的介绍,相信大家已经会自己做一个透明皮肤窗口了,但是要记住,上文因为是基础教程,所以很多细节仍然是需要处理的,例如: 1、为了加快速度,实际上可以先用MakeBmp函数制作好皮肤图片,平均颜色就是取图片右下角的一个点即可。例如QQ的皮肤包就是这么干的。 2、如果实在想运行时计算,那么可以先将图片缩小,再计算平均颜色。这样一来,循环的次数就减少了,而效果是一样的。 3、为了美观,边框可以画个线条上去,这样一来立体感就强很多: 另外,还要其它一些细节,例如 Caption,如果平均颜色是黑色,那么字体应该自动换成白色。我在这里偷了个懒,直接使用了Blur算法,根据字
...阅读更多
2013-08-11
前文的窗口如果最大化,你会发现它把任务栏也覆盖了,原因是我们窗口的 BorderStyle 设置成了 bsNone,所以要处理一下WM_GETMINMAXINFO消息: procedure TForm1.WMGETMINMAXINFO(var Message: TMessage); var Rect: TRect; begin SystemParametersInfo(SPI_GETWORKAREA, 0, @Rect, 0); with PMINMAXINFO(Message.LParam)^ do begin //ptReserved: TPoint;//保留不用 ptMaxSize.X
...阅读更多
2013-08-07
Windows将窗口分为客户区和非客户区,例如对于标准的Windows窗口,标题栏和边框都属于非客户区,又称为NC区。对于客户区的绘制,应用程序会收到WM_PAINT消息,而非客户区,对应的消息是WM_NCPAINT。要实现皮肤窗口,需要三个步骤: 第一步:定义非客户区的大小。 要自定义非客户区的大小,程序就要响应WM_NCCALCSIZE消息。假设我们的标题高度为60(像素,下同),边框为10,那么对应的代码应该类似这样: const xTitleHeight: Integer = 50; //标题栏的高度 xFramWidth: Integer = 10; //左、右、下边框的厚度 pro
...阅读更多
2013-08-05
Delphi的皮肤控件非常多,例如DynamicSkinForm等等。以前都是习惯直接使用第三方皮肤控件,后来在开发一个内部IM聊天工具的时候,发现没有现成的IM控件,网上有一些介绍模仿QQ界面的文章,但不成系列,重要的是都是“看起来像”,离”实际能使用”差的很远,于是自己开发了一个。老实说,因为以前都是依赖第三方控件,所以开始的时候发现困难很多。不过经过几个星期断断续续的学习,终于搞完了第一个界面库处女作,效果如下: 因为我是设计成设计期可见效果,下面是IDE设计期的效果(点击图片查看大图): 其中第一个控件面板分类就是该系列的控件。 本讲座将详细介
...阅读更多
2013-08-02