搜索
查看: 2649|回复: 4

[图像] gdi+自绘的半透明窗体

[复制链接]

8

主题

45

帖子

276

积分

二级会员

Rank: 3Rank: 3

积分
276
发表于 2017-10-24 17:29:06 | 显示全部楼层 |阅读模式
源码:
  1. class createGdi{
  2.         ctor(winform){
  3.                 var make = function(){
  4.                         this.w, this.h = this.obj.width, this.obj.height
  5.                         this.hdc = ::GetDC(this.obj.hwnd)
  6.                         this.mdc = ::CreateCompatibleDC()
  7.                         this.hbmp = ::CreateCompatibleBitmap(this.hdc, this.w, this.h)
  8.                         ::SelectObject(this.mdc, this.hbmp)
  9.                 }
  10.                 var del = function(){
  11.                         ::DeleteDC(this.hdc)
  12.                         ::DeleteDC(this.mdc)
  13.                         ::DeleteObject(this.hbmp)
  14.                         //..win.msgbox("回收gdi对象")
  15.                 }
  16.                 if(winform[["hwnd"]]){
  17.                         this.obj = winform
  18.                         this.alpha = 0
  19.                         make()
  20.                 }
  21.                 ..table.gc(this,del)
  22.         }
  23.         redraw = function(drawfunc){
  24.                 if( !this[["obj"]][["hwnd"]] ) return;
  25.                 del()
  26.                 make()
  27.                 if(type(drawfunc) == "function")
  28.                         drawfunc(this);
  29.         }
  30. }

  31. import win.ui
  32. import gdip
  33. /*DSG{{*/
  34. var topBox = win.form(text="aardio form";right=759;bottom=47;bgcolor=32768;border="none")
  35. topBox.add(
  36. btnMax={cls="button";left=707;top=4;right=731;bottom=28;dr=1;dt=1;z=2};
  37. btnMin={cls="button";left=683;top=4;right=707;bottom=28;dr=1;dt=1;z=3};
  38. btnQuit={cls="button";left=731;top=4;right=755;bottom=28;dr=1;dt=1;z=1}
  39. )
  40. /*}}*/

  41. topBox.transparent(true)

  42. var font_webd = gdip.family('webdings')
  43. topBox.btnMin._mvar = {
  44.         //mc字体颜色,nc颜色索引
  45.         mc = {0xaad2d2d2;0xfeffffff}; nc = 1;
  46.         //mt文本内容,nt文本索引
  47.         mt = {'0'}; nt = 1;
  48.         //mf字体,nf字体大小
  49.         mf = font_webd; nf = 16;
  50.         //坐标偏移
  51.         po = {1;3};
  52. }
  53. topBox.btnMax._mvar = {
  54.         mc = {0xaad2d2d2;0xeeffffff}; nc = 1;
  55.         mt = {'1';'2'}; nt = 1;
  56.         mf = font_webd; nf = 16;
  57.         po = {1;3};
  58. }
  59. topBox.btnQuit._mvar = {
  60.         mc = {0xaad2d2d2;0xffff0000}; nc = 1;
  61.         mt = {'r'}; nt = 1;
  62.         mf = font_webd; nf = 16;
  63.         po = {1;3};
  64. }

  65. var ctrls = {topBox.btnMin; topBox.btnMax; topBox.btnQuit}
  66. var gGdi = createGdi(topBox)
  67. var strformat = gdip.stringformat(0)
  68. var drawAlpha = function(p, al = 255){
  69.         var gh = gdip.graphics(p.mdc)
  70.        
  71.         /**消除锯齿
  72.         gh.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/
  73.         //**/
  74.        
  75.         //**绘制渐变透明背景
  76.         var bkBru = gdip.lineBrush(::RECTF( 0, 0, p.w, p.h), 0xcc000000, 0x00000000, 1)
  77.         gh.fillRectangle(bkBru, 0, 0, p.w, p.h)
  78.         bkBru.delete()
  79.         //**/
  80.        
  81.         //**绘制控件字符
  82.         var pen = gdip.pen(0x8000ffff, 1)
  83.         var gBru = gdip.solidBrush(0xaad2d2d2)
  84.         for(i=1;#ctrls){
  85.                 var c, m = ctrls[ i ], ctrls[ i ]._mvar
  86.                 if(!m.mt[1]) continue;
  87.                 var strPath = gdip.path(0)
  88.                 var rclayout = ::RECTF(c.left+m.po[1], c.top+m.po[2], 0, 0)
  89.                 gBru.color = m.mc[m.nc]
  90.        
  91.                 strPath.addstring(m.mt[m.nt], m.mf, 1, m.nf, rclayout, strformat)
  92.                 gh.fillPath(gBru, strPath)
  93.                 gh.drawRectangle(pen, c.left, c.top, c.width, c.height)//边框
  94.                 strPath.delete()
  95.         }
  96.         pen.delete()
  97.         gBru.delete()
  98.         //**/
  99.        
  100.         gh.delete()
  101.         ..gdi.updateLayeredWindow( topBox.hwnd, p.mdc, ::SIZE(p.w, p.h), ..gdi.blendFunction(al/*透明度*/)  )
  102. }

  103. var onMsg = {
  104.         [0x200/*_WM_MOUSEMOVE 鼠标悬停*/] = function(obj){
  105.                 if(obj.tracking) return;
  106.                 obj.tracking = 1
  107.                 obj._mvar.nc = 2
  108.                 gGdi.redraw(drawAlpha)
  109.         }
  110.         [0x2A3/*_WM_MOUSELEAVE 鼠标离开*/] = function(obj){
  111.                 obj.tracking = 0
  112.                 obj._mvar.nc = 1
  113.                 gGdi.redraw(drawAlpha)
  114.         }
  115. }
  116. topBox.btnMin.wndproc = function(hwnd,msg,wParam,lParam){
  117.         if(msg == 0x201){
  118.                 ::PostMessage(topBox.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF020/*_SC_MINIMIZE*/, 0)
  119.                 return 1
  120.         }
  121.         elseif(onMsg[msg]) onMsg[msg](owner)
  122. }
  123. topBox.btnMax.wndproc = function(hwnd,msg,wParam,lParam){
  124.         if(msg == 0x201){
  125.                 if(win.isZoomed(topBox.hwnd)){
  126.                         owner._mvar.nt = 1
  127.                         ::PostMessage(topBox.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF120/*_SC_RESTORE*/, 0)
  128.                 }
  129.                 else{
  130.                         owner._mvar.nt = 2
  131.                         ::PostMessage(topBox.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF030/*_SC_MAXIMIZE*/, 0)
  132.                 }
  133.                 return 1
  134.         }
  135.         elseif(onMsg[msg]) onMsg[msg](owner)
  136. }
  137. topBox.btnQuit.wndproc = function(hwnd,msg,wParam,lParam){
  138.         if(msg == 0x201){
  139.                 ::PostMessage(topBox.hwnd, 0x10, 0, 0)
  140.         }
  141.         elseif(onMsg[msg]) onMsg[msg](owner)
  142. }
  143. topBox.wndproc = function(hwnd,msg,wParam,lParam){
  144.         if(msg == 0x201) topBox.hitCaption();
  145.         elseif(msg == 0xf) gGdi.redraw(drawAlpha)
  146. }

  147. topBox.show()
  148. gGdi.redraw(drawAlpha)

  149. win.loopMessage();
  150. return topBox
复制代码

PS:给aplayer引擎做外壳时的附带品,嵌入到播放器画面里还像那么回事,附上效果图:

回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13974
发表于 2017-10-24 17:34:39 | 显示全部楼层
试了一下效果很棒,感谢分享。
回复

使用道具 举报

1

主题

2

帖子

39

积分

培训班

积分
39
QQ
发表于 2018-7-29 18:23:35 | 显示全部楼层
今天偶尔翻看到此贴,楼主不但代码写的简洁,而且效果确实很棒!!
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13974
发表于 2018-7-29 21:22:00 | 显示全部楼层
有些地方 - 不必要的写复杂了,即然都用到了GDI+,  一个gdip.bitmap就可以了,不用写那个createGdi。
创建双缓冲用gdi.doubleBuffer 就可以了,不过GDI+也不需要这个,分层透明窗口的绘图可以参考一下 web.kit.layeredRender, web.blink.layeredWindow,win.ui.layered的实现。

win.ui.layered 模仿了一下你上面的透明效果
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=759;bottom=47;border="none")
/*}}*/

import win.ui.layered;
var layered = win.ui.layered(winform)
layered.onDrawBackground =
function(graphics,l,t,w,h){
   
var brush = gdip.lineBrush(::RECTF(0,0,w,h), 0xcc000000,0, 1)
    graphics.fillRectangle(brush,0,0,w,h)
    brush.delete()  
}

import win.ui.simpleWindow2;
win.ui.simpleWindow2(winform);

winform.show();
win.loopMessage();
回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13974
发表于 2018-7-30 15:46:18 | 显示全部楼层
新版增加了一个库win.ui.simpleWindow3( 用 win.ui.layered 实现透明背景 ),一个例子:
import win.ui;
/*DSG{{*/
var winform = win.form(text="透明渐变标题栏";border="none")
winform.add()
/*}}*/

import inet.http;
winform.image =
"http://pic23.photophoto.cn/20120429/0027011761472219_b.jpg";

import win.ui.simpleWindow3;
win.ui.simpleWindow3(winform)

winform.show()
win.loopMessage();

sw3.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-12-15 15:23 , Processed in 0.062500 second(s), 26 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表