posts - 0, comments - 0, trackbacks - 0, articles - 4
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

SWT 中实现自绘按钮

Posted on 2007-02-13 15:34 gyb 阅读(993) 评论(0)  编辑  收藏 所属分类: JAVA SWT
本文参考网上一些网友的文章后改进而成,下面的代码不做详细的说明,只是简单的说明一下。
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, 255255255 );
        Color clr2 
= new Color( button.display, 203224221 );
        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, 69134134 );
        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+11,rc.height-2 );
        topBorder 
= new Rectangle( rc.x+1, rc.y+1, rc.width-2,1 );
        rightBorder 
= new Rectangle( rc.width-2, rc.y+11,rc.height-2 );
        bottomBorder 
= new Rectangle( rc.x+1, rc.height-2, rc.width-2,1 );
        Color clr4 
= new Color( button.display, 231231231 );
        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, 
11 );
        }
        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、效果:6.JPG7.JPG