将Aero Glass效果与SWT结合使用

6
作为一个个人项目,我一直在探索将Aero Glass效果整合到我的SWT应用程序中的概念。Łukasz Milewski有一篇优秀的博客文章,解释了如何实现这一点,基本上归结为以下内容:
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FormLayout());
final MARGINS margins = new MARGINS();
margins.cyTopHeight = -1;

final Composite c = new Composite(shell, SWT.NORMAL);
c.setBackground(new Color(shell.getDisplay(), new RGB(0, 0, 0)));
final FormData fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.left = new FormAttachment(0, 0);
fd.right = new FormAttachment(100, 0);
fd.bottom = new FormAttachment(100, 0);
c.setLayoutData(fd);

OS.DwmExtendFrameIntoClientArea(shell.handle, margins);

shell.open();
while (!shell.isDisposed()) {
    if (!display.readAndDispatch()) {
        display.sleep();
    }
}

这个很好用,但是如果你想添加一个控件就会出现问题,会导致黑色保持透明状态:

Transparent shell with control

一篇后续文章也展示了如何实现这一点,但需要修改SWT库。(至少我认为是这样,因为私有的SWT函数被@Override覆盖。)

如何避免控件变得透明?更好的做法是:如何受益于透明度(例如,像这样放置图像),但以明智的方式使用它?

3个回答

2
被覆盖的方法是“包私有”的。为了在不编译时出现错误的情况下覆盖它们,您必须将您的类放入与超类相同的包中,即org.eclipse.swtorg.eclipse.swt.widgets包中。您引用的博客实际上在结尾处提到了这个实现细节,所以我不知道这是否真正回答了您的问题。

我只是匆匆地阅读了那段代码。足够的是,这样做可以让一切都编译成功,但仍有很多问题没有得到正确解决。一个完全可行的例子会非常好,因为只有通过在callWindowProc()中设置一些常量和额外的情况,我才能让OpaqueText确实显示不透明文本。我将在明天早上更新我的问题并附上我的当前代码。 - Paul Lammertsma
由于赏金即将到期,我会授予给你。 - Paul Lammertsma

0
将您的控件放置在玻璃区域之外,或尝试为控件使用背景颜色。

将我的控件放在玻璃区域之外或多或少地会破坏效果的目的。我也不认为“避免黑色”是一个现实的选项。我知道有一种正确的做法(一位同事提到过用C#解决了类似的问题),所以我将继续努力解决它。 - Paul Lammertsma

0

你对覆盖内部方法的解决方案感到担忧,但首先你就在使用一个内部 SWT 类。这似乎是一种非常脆弱的方式(至少在当前 SWT 实现中),来为你的应用添加一些视觉效果… 我希望你不要在生产代码中这样做。


将其包装在 try { ... } catch (Throwable e) {} 中肯定不会有害。这只是一种装饰性的写法,如果失败了,也没什么大不了的,对吧?当前生产代码中有一些像这样实现的 OS 引用。这真的是非常糟糕的做法吗? - Paul Lammertsma
这也不是我特别担心覆盖私有方法的问题;更多的是,我在没有编译错误的情况下无法完成它。我做错了什么? - Paul Lammertsma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接