快速业务通道

SWT:实现自我绘制的Button组件 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-21
struct = new DRAWITEMSTRUCT ();   ....

其中DRAWITEMSTRUCT结构的出现是一个明显的提示:这里就是WM_DRAWITEM消息的响应函数,很幸运它没有声明为final的,只要重载它并提供自己的实现就行了。

看起来是个小case,实际上也是。不过,还有一处小麻烦需要克服。注意wmDrawChild方法没有使用任何访问限定符,这意味着它是package friendly的——同一个包中的对象可以访问和重载此方法,其他包中的对象就没有这个权力了。也就是说,要定制按钮对象,我们新建的对象也需要放在同一个包(org.eclipse.swt.widgets)中。看起来有点像在使用Hack手段,不过为了突破SWT给我们的限制,眼下也只好稍稍将就一下。好在swt的包没有密封(Sealed),不然我就不得不再次宣称此路不通了。

既然障碍已经扫清,接下来我们可以来实现前面的想法了。这里我做了一个决定,在上述包中只加入一个抽象类,目的是把必要的接口暴露出来;至于如何绘制按钮,则留给具体的按钮对象根据应用程序的需求来决定。这样,不管你希望实现Windows XP风格的按钮、还是卡通风格的按钮、或是平面样式的,总之不论什么千奇百怪的风格,只要继承一个类并重载一个绘制方法就行了,而不必每次都要和 Button类的内部打交道。

基于这种考虑,实现自绘按钮的抽象类如下:

package org.eclipse.swt.widgets; import org.eclipse.swt.internal.win32.*; public abstract class OwnerDrawButton extends Button {   public OwnerDrawButton( Composite parent, int style )   {    super( parent, style );    int osStyle = OS.GetWindowLong( handle, OS.GWL_STYLE );    osStyle |= OS.BS_OWNERDRAW;    OS.SetWindowLong( handle, OS.GWL_STYLE, osStyle );   }   LRESULT wmDrawChild( int wParam, int lParam )   {    super.wmDrawChild( wParam, lParam );    DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT();    OS.MoveMemory( struct, lParam, DRAWITEMSTRUCT.sizeof );    ownerDraw( struct );    return null;   }   protected abstract void ownerDraw( DRAWITEMSTRUCT dis ); }

SWT:实现自我绘制的Button组件(2)

时间:2011-01-05

注意这个抽象类所作的工作。在构造函数中,它调用操作系统方法为自己加入了BS_OWNERDRAW风格。如果没有这一步,那么操作系统将不会把这个按钮视为自绘的按钮,也不会向其发送任何绘制消息。接下来是WM_DRAWITEM消息的响应函数。在这个函数中,我们简单的把必要的绘制参数提取出来,然后调用抽象方法ownerDraw去进行实际的绘制工作。任何从OwnerDrawButton类派生的按钮对象必须重载此ownerDraw方法,来决定如何绘制自身。

作为一个例子,我实现了一个具体的按钮类。这个按钮用从上至下的渐变色背景添充整个按钮,然后绘制出按钮的文字。如果当前按钮被按下,该类还调整了一下文字的位置,以显示出“按下”的外观效果。代码稍微有些长,这是因为消息函数所提供的是一个操作系统才了解的原生HDC对象,而不是我们所熟悉的GC类,因此也需要相应的用原生API进行处理。不过,其原理是相当简单的——你只需要在给出的HDC上画出你想要的任何效果就行了。

import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.win32.*; import org.eclipse.swt.widgets.*; public class TestButton extends OwnerDrawButton {   TestButton( Composite parent )   {    super( parent, SWT.PUSH );   }   @Override   protected void ownerDraw( DRAWITEMSTRUCT dis )   {    Rectangle rc = new Rectangle( dis.left, dis.

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号