本文参考网上一些网友的文章后改进而成,下面的代码不做详细的说明,只是简单的说明一下。
1、定义一个自绘按钮绘制动作的接口OwnerDrawButtonStyleImp ,代码如下:
package org.eclipse.swt.widgets;
/**
* 自绘按钮绘制接口
*
*
*/
public interface OwnerDrawButtonStyleImp {
public void drawButton(OwnerDrawButton button,int wParam, int lParam);
}
2、创建一个OwnerDrawButton类来作为自绘按钮类,构造为:
public OwnerDrawButton(Composite parent,OwnerDrawButtonStyleImp buttonStyle)
其中OwnerDrawButtonStyleImp 为具体实现绘制工作的接口,完整代码如下:
package org.eclipse.swt.widgets;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.internal.win32.*;
/**
* 使用此类来生成一个自绘按钮,根据构造中OwnerDrawButtonStyleImp按钮样式的不同画出不一样的按钮
*
*
*/
public final class OwnerDrawButton extends Button
{
OwnerDrawButtonStyleImp buttonStyle = null;
public OwnerDrawButton(Composite parent,OwnerDrawButtonStyleImp buttonStyle){
super( parent, SWT.DBCS );
this.buttonStyle = buttonStyle;
int osStyle = OS.GetWindowLong( handle, OS.GWL_STYLE );
osStyle |= OS.BS_OWNERDRAW;
OS.SetWindowLong( handle, OS.GWL_STYLE, osStyle );
}
public void setImage(Image image){
this.image = image;
}
public void setText(String text){
this.text = text;
}
LRESULT wmDrawChild( int wParam, int lParam )
{
super.wmDrawChild( wParam, lParam );
buttonStyle.drawButton(this,wParam, lParam);
return null;
}
}
3、实现一个自绘按钮的样式,代码如下:
package org.eclipse.swt.widgets;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.win32.*;
/**
* 一个自绘按钮的测试样式,实现自绘按钮绘制接口
*
*
*/
public class TestButtonStyle implements OwnerDrawButtonStyleImp {
OwnerDrawButton button;
int wParam;
int lParam;
private void initParam(OwnerDrawButton button,int wParam, int lParam){
this.button = button;
this.wParam = wParam;
this.lParam = lParam;
}
public void drawButton(OwnerDrawButton button,int wParam, int lParam){
this.initParam(button, wParam, lParam);
DRAWITEMSTRUCT dis = new DRAWITEMSTRUCT();
OS.MoveMemory( dis, lParam, DRAWITEMSTRUCT.sizeof );
Rectangle rc = new Rectangle( dis.left, dis.top, dis.right - dis.left,dis.bottom - dis.top );
Color clr1 = new Color( button.display, 255, 255, 255 );
Color clr2 = new Color( button.display, 203, 224, 221 );
fillGradientRectangle( dis.hDC, rc, true, clr1, clr2 );
clr1.dispose();
clr2.dispose();
Rectangle leftBorder = new Rectangle( rc.x, rc.y, 1,rc.height );
Rectangle topBorder = new Rectangle( rc.x, rc.y, rc.width,1 );
Rectangle rightBorder = new Rectangle( rc.width-1, rc.y, 1,rc.height );
Rectangle bottomBorder = new Rectangle( rc.x, rc.height-1, rc.width,1 );
Color clr3 = new Color( button.display, 69, 134, 134 );
fillGradientRectangle( dis.hDC, leftBorder, true, clr3, clr3 );
fillGradientRectangle( dis.hDC, topBorder, true, clr3, clr3 );
fillGradientRectangle( dis.hDC, rightBorder, true, clr3, clr3 );
fillGradientRectangle( dis.hDC, bottomBorder, true, clr3, clr3 );
clr3.dispose();
leftBorder = new Rectangle( rc.x+1, rc.y+1, 1,rc.height-2 );
topBorder = new Rectangle( rc.x+1, rc.y+1, rc.width-2,1 );
rightBorder = new Rectangle( rc.width-2, rc.y+1, 1,rc.height-2 );
bottomBorder = new Rectangle( rc.x+1, rc.height-2, rc.width-2,1 );
Color clr4 = new Color( button.display, 231, 231, 231 );
fillGradientRectangle( dis.hDC, leftBorder, true, clr4, clr4 );
fillGradientRectangle( dis.hDC, topBorder, true, clr4, clr4 );
fillGradientRectangle( dis.hDC, rightBorder, true, clr4, clr4 );
fillGradientRectangle( dis.hDC, bottomBorder, true, clr4, clr4 );
clr4.dispose();
Image image = button.getImage();
int x = 0, y =0 ,wh = 0;
if(image!=null){
x = 10;
y = 4;
wh = dis.bottom - dis.top-4-4;
OS.DrawIconEx(dis.hDC, x, y, image.handle, wh, wh, 0, dis.hDC, SWT.IMAGE_BMP);
}
SIZE size = new SIZE();
char[] chars = button.text.toCharArray();
int oldFont = OS.SelectObject( dis.hDC, button.getFont().handle );
OS.GetTextExtentPoint32W( dis.hDC, chars, chars.length, size );
RECT rcText = new RECT();
rcText.left = rc.x+wh+x;
rcText.top = rc.y;
rcText.right = rc.x + rc.width;
rcText.bottom = rc.y + rc.height;
if ( (dis.itemState & OS.ODS_SELECTED) != 0 ){
OS.OffsetRect( rcText, 1, 1 );
}
OS.SetBkMode( dis.hDC, OS.TRANSPARENT );
OS.DrawTextW( dis.hDC, chars, -1, rcText, OS.DT_SINGLELINE | OS.DT_CENTER | OS.DT_VCENTER );
RECT focusRect = new RECT();
focusRect.left = rc.x;
focusRect.top = rc.y;
focusRect.right = rc.x + rc.width;
focusRect.bottom = rc.y + rc.height;
if(button.isFocusControl()){
focusRect.left = rc.x+2;
focusRect.top = rc.y+2;
focusRect.right = rc.x + rc.width-2;
focusRect.bottom = rc.y + rc.height-2;
}
OS.DrawFocusRect(dis.hDC, focusRect);
OS.SelectObject( dis.hDC, oldFont );
}
private void fillGradientRectangle( int handle, Rectangle rc,
boolean vertical, Color clr1, Color clr2 )
{
final int hHeap = OS.GetProcessHeap();
final int pMesh = OS.HeapAlloc( hHeap, OS.HEAP_ZERO_MEMORY,
GRADIENT_RECT.sizeof + TRIVERTEX.sizeof * 2 );
final int pVertex = pMesh + GRADIENT_RECT.sizeof;
GRADIENT_RECT gradientRect = new GRADIENT_RECT();
gradientRect.UpperLeft = 0;
gradientRect.LowerRight = 1;
OS.MoveMemory( pMesh, gradientRect, GRADIENT_RECT.sizeof );
TRIVERTEX trivertex = new TRIVERTEX();
trivertex.x = rc.x;
trivertex.y = rc.y;
trivertex.Red = (short)(clr1.getRed() << 8);
trivertex.Green = (short)(clr1.getGreen() << 8);
trivertex.Blue = (short)(clr1.getBlue() << 8);
trivertex.Alpha = -1;
OS.MoveMemory( pVertex, trivertex, TRIVERTEX.sizeof );
trivertex.x = rc.x + rc.width;
trivertex.y = rc.y + rc.height;
trivertex.Red = (short)(clr2.getRed() << 8);
trivertex.Green = (short)(clr2.getGreen() << 8);
trivertex.Blue = (short)(clr2.getBlue() << 8);
trivertex.Alpha = -1;
OS.MoveMemory( pVertex + TRIVERTEX.sizeof, trivertex, TRIVERTEX.sizeof );
OS.GradientFill( handle, pVertex, 2, pMesh, 1, vertical ? OS.GRADIENT_FILL_RECT_V : OS.GRADIENT_FILL_RECT_H );
OS.HeapFree( hHeap, 0, pMesh );
}
}
4、使用自绘按钮,代码如下:
package com.gu.control.swt;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;
public class Window{
private final static Display display = new Display();;
private Shell shell;
public Window(){
shell = new Shell(display);
shell.setLayout(null);
init();
//使窗口永远在最前面
OS.SetWindowPos(shell.handle , OS.HWND_TOPMOST, 0 , 0 , 800 , 600 , SWT.NULL);
shell.open();
while(!shell.isDisposed()){
if(!display.readAndDispatch()){
display.sleep();
}
}
display.dispose();
}
private void init(){
Button button;
button = new OwnerDrawButton(shell,new TestButtonStyle());
button.setBounds(new Rectangle(20,20,180,25));
button.setText("Click Me");
button.setImage(image);
button.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent event){
shell.setText("你好啊,你点了自绘按钮了!");
}
public void widgetDefaultSelected(SelectionEvent event){
widgetSelected(event);
}
}
);
}
}
5、效果:


