首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

SWT透明窗口解决办法

2012-01-19 
SWT透明窗口描述:建立一个父shell显示主线程信息,建立一个半透明的子shell线程显示消息信息,想让两个shell

SWT透明窗口
描述:
建立一个父shell显示主线程信息,建立一个半透明的子shell线程显示消息信息,想让两个shell关联起来时,让透明窗口浮动在父窗口之上,即:子shell在父shell上显示,同时两个线程继续进行。当一段时间后,子shell自动隐藏销毁,父shell继续运行。透明窗口在SWT只能用API函数调用绘制,我的要求是只需要绘制该子shell,但实际的情况是:子shell在弹出时连同父shell也同时进行了重绘!而且子shell销毁后,父shell会留下子shell绘制时绘制的父shell窗口的残影。注:我是用SWT中调用OS.CallWindowProc(fun,shell.handle, 0, 150, 2)实现的。
下面附有代码,源程序效果图见附件:

Java code
import java.awt.BorderLayout;import java.awt.Color;import java.awt.Frame;import java.awt.Panel;import org.eclipse.swt.SWT;import org.eclipse.swt.awt.SWT_AWT;import org.eclipse.swt.events.SelectionAdapter;import org.eclipse.swt.events.SelectionEvent;import org.eclipse.swt.events.ShellAdapter;import org.eclipse.swt.events.ShellEvent;import org.eclipse.swt.internal.win32.OS;import org.eclipse.swt.internal.win32.TCHAR;import org.eclipse.swt.widgets.Button;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Label;import org.eclipse.swt.widgets.Shell;import com.swtdesigner.SWTResourceManager;public class Popup extends Thread {    final Shell shell;    final Composite composite;    eventShell es;    boolean terminated = false;    boolean isEvent = false;    protected int moveStep = 2; //每次移动的pixel    protected int upPosition; //能移动到的最上面坐标    protected int downPosition; //当前popup的边框坐标    protected int leftPosition; //popup左边边框坐标             public Popup(final String message,Shell parent)     {        shell = new Shell(parent,SWT.NO_TRIM);        shell.addShellListener(new ShellAdapter() {        public void shellClosed(final ShellEvent e) {            terminated = true;        }    });    //取屏莫大小    upPosition = parent.getLocation().y+95;//计算出popup界面在屏幕显示的最高位置    downPosition = parent.getLocation().y+ 155;//计算出popup界面的初始位置    leftPosition = parent.getLocation().x+7 ;    shell.setSize(168, 78);//    shell.setAlpha(200);    //初始化popup位置    shell.setLocation(leftPosition, downPosition);    shell.open();    resetShell();     //OS.SetWindowPos(shell.handle , OS.HWND_TOPMOST, 0 , 700 , 1024 , 68 , SWT.NULL);     //透明窗体     composite = new Composite(shell, SWT.NONE);    composite.setBackground(SWTResourceManager.getColor(225, 252, 255));    composite.setBounds(0, 0, 168, 78);/*     Frame frame = SWT_AWT.new_Frame(composite);      Panel panel = new Panel(new BorderLayout()) {        public void update(java.awt.Graphics g) {                  paint(g);        }      };      panel.setForeground(Color.YELLOW);//   在容器中添加子容器      frame.add(panel); */    final Button button = new Button(composite, SWT.NONE);    button.setBounds(94, 48,60, 20);    button.addSelectionListener(new SelectionAdapter() {        public void widgetSelected(final SelectionEvent e) {             es = new eventShell(shell,"一个巨大的好消息:IBM向Open Source社群捐献了自己的Visual Editor项目,不久Eclipse将在此项目基础上发布可视化GUI编辑工具。看来,不用太久,Eclipse的用户们就不用再羡慕JBuilder的可视化GUI编辑器了——而且这还是免费的,而且这还是基于SWT的。");             isEvent = true;             es.start();        /*     if(es.isAlive())                 System.out.print("event窗口活着!");             else                 System.out.print("event窗口死亡!");*/        }    });    button.setText("点击查看");    final Button xButton = new Button(composite, SWT.NONE);    xButton.addSelectionListener(new SelectionAdapter() {        public void widgetSelected(final SelectionEvent e) {            shell.dispose();        }    });    xButton.setBounds(150, 0, 17, 14);    final Label label = new Label(composite, SWT.NONE);    label.setBackground(SWTResourceManager.getColor(225, 252, 255));    label.setBounds(10, 20, 144, 14);    label.setText(message);            }        private void resetShell()    {        //设置窗体透明        OS.SetWindowLong(shell.handle, OS.GWL_EXSTYLE, OS.GetWindowLong(                shell.handle, OS.GWL_EXSTYLE) ^ 0x80000);        // load User32.dll lib        TCHAR lpLibFileName = new TCHAR(0, "User32.dll", true);        int hInst = OS.LoadLibrary(lpLibFileName);        if (hInst != 0)        {            // 设定调用函数名称            //System.out.println("hInst!=0");            String name = "SetLayeredWindowAttributes\0";            byte[] lpProcName = new byte[name.length()];            for (int i = 0; i < lpProcName.length; i++)            {                lpProcName[i] = (byte) name.charAt(i);            }            // 检索DLL输出函数地址            int fun = OS.GetProcAddress(hInst, lpProcName);            // 当函数存在            if (fun != 0){                // 150为透明度,在0-255之间                System.out.println("透明度为50");                OS.CallWindowProc(fun,shell.handle, 0, 150, 2);            }            // 释放lib            OS.FreeLibrary(hInst);        }    }                public void run()     {                while (true)         {            try {                Thread.sleep(10);                    //判断当前位置是否小于能出现的最高位置,小于的话就说明还可以向上移动。                if ((downPosition - moveStep) > upPosition)                 {                    Display.getDefault().asyncExec(                            new Runnable(){                        public void run(){                            shell.setLocation(leftPosition, downPosition- moveStep);                        //    resetShell();                               downPosition -= moveStep;}});//判断当前位置是否小于能出现的最高位置,小于的话就说明还可以向上移动。                }                 else {                    //                             //this.resetShell();                       //OS.FreeLibrary(hInst);                      //                    Thread.sleep(5000);                    if(!isEvent)                    {                         Display.getDefault().asyncExec(new Runnable(){                             public void run(){                                 shell.dispose();}});                         terminated = true;                    }                    else if(isEvent)                    {                        try                        {                            es.join();                            isEvent = false;                             System.out.print("event窗口已经死亡!");                        }                        catch(InterruptedException e)                        {                            e.printStackTrace();                        }                        Display.getDefault().asyncExec(new Runnable(){                             public void run(){                                 shell.dispose();}});                         terminated = true;                    }                }            }            catch(InterruptedException e)            {e.printStackTrace();}                        if(terminated ==true)            {                System.out.print("Popup窗体关闭!");                return;            }        }    }            } 




[解决办法]
每次窗口状态发生变化时,对窗口重绘不行吗?

热点排行
Bad Request.