搬运与大家分享
使用方法:复制后保存成dock库文件,放lib里,调用使用 import dock;
class dock{ ctor(winform, acts=10/*每过程动作次数*/, isTop=false/*置顶*/, isDock=true/*吸附*/, margin=false/*留边*/){ assert(winform[["hwnd"]], "参数@1必须是窗体对象"); acts = ..math.abs(tonumber(acts) : 1); //this = win.form(); this.messageOnly(); this = winform; this.site, this.msIn = "", 0; var scrw, scrh = win.getScreen(); var wndGdi, alSign = _wndGdi(); var wndAlpha = function(v = false, w, h){ alSign = !!v; if(!alSign){ this.transparent(false); //this.hide = 1; this.hide = 0; //this.redraw(); _redrawWindow(this.hwnd, , , 0x400/*_RDW_FRAME*/ | 0x1/*_RDW_INVALIDATE*/ | 0x4/*_RDW_ERASE*/) return; } this.transparent(true); var col = margin ? 0xaad2d2d2 : 0x01d2d2d2//0xaad2d2d2 : 0x01d2d2d2 wndGdi(this.hwnd, w, h, function(mdc, w, h){ var gph = gdip.graphics(mdc) var gBru = gdip.solidBrush(col) gph.fillRectangle(gBru, 0, 0, w, h) gBru.delete() gph.delete() gdi.updateLayeredWindow(this.hwnd, mdc, ::SIZE(w, h), gdi.blendFunction(255/*透明度*/)) }) } var ap = {}; //aTimer动作定时器运行时参数 var aTimer = win.timer(, 10); aTimer.onTimer = function(hwnd,msg,id,tick){ var c = true; if(ap[["site"]] == "top"){ ap.y += ap.v; c = ap.msIn ? !(ap.y<0) : !(ap.y>4-ap.h); if(c) ap.y = !ap.msIn ? 4-ap.h : 0; } elseif(ap[["site"]] == "left"){ ap.x += ap.v; c = ap.msIn ? !(ap.x<0) : !(ap.x>4-ap.w); if(c) ap.x = !ap.msIn ? 4-ap.w : 0; } elseif(ap[["site"]] == "right"){ ap.x -= ap.v; c = ap.msIn ? !(ap.x>scrw-ap.w) : !(ap.x<scrw-4); if(c) ap.x = ap.msIn ? scrw-ap.w : scrw-4; } this.setPos(ap.x, ap.y); if(c){ if(#ap[["site"]] && !ap.msIn){ wndAlpha(1, ap.w, ap.h); if(!isTop) win.setTopmost(this.hwnd); } elseif(!isTop) win.setTopmost(this.hwnd, false); owner.disable(); } elseif(alSign) wndAlpha(, ap.w, ap.h); } var msPos = ::POINT(); var mTimer = win.timer(, 10); mTimer.onTimer = function(hwnd,msg,id,tick){ var x, y, w, h = this.getPos(); if(w >= scrw) return; //**判断窗口停靠位置 var site = "" if(x <= 0) site = "left"; elseif(x+w >= scrw) site = "right"; elseif(y <= 0) site = "top"; if(this.site != site){ this.site = site ::PostMessage(this.hwnd, 0x503, 0, 0) } //**/ //**检测鼠标进出窗口 左键状态 判断是否动作 _getMsPos(msPos) var msIn = _msIn(msPos.x, msPos.y) ? 1 : 0 var v = _getAsyncKeyState(1) if(this.msIn != msIn){ this.msIn = msIn ::PostMessage(this.hwnd, 0x5A3, 0, 0) } elseif(!v) return; if(!#site || v) return; //**/ //**执行动作 v = (site == "top") ? ..math.ceil(h/acts) : ..math.ceil(w/acts); v = msIn ? v : -v; ap.site,ap.msIn,ap.x,ap.y,ap.w,ap.h,ap.v = site,msIn,x,y,w,h,v; aTimer.enable(); //**/ } this.wndMargin = function(v = false){ margin = !!v } //**窗口呼出 this.wndDisplay = function(){ var x, y, w, h = owner.getPos(); if(x<0) x = 0 elseif(x+w>scrw) x = scrw-w if(y<0) y = 0 elseif(y+h>scrh) y = scrh-h owner.setPos(x, y) owner.transparent(false) } this.wndDisplay() //**/ //**窗口置顶 避免与aTimer里的win.setTopmost冲突 this.wndTopmost = function(v){ isTop = !!v win.setTopmost(owner.hwnd, isTop) return isTop; } this.wndTopmost(isTop) //**/ //**窗口吸附 this.wndDock = function(v = true){ isDock = !!v if(isDock) mTimer.enable(); else { mTimer.disable(); owner.wndDisplay() } return isDock; } this.wndDock(isDock) //**/ this.wndproc = { [0x7E/*_WM_DISPLAYCHANGE 屏幕分辨率改变*/] = function(hwnd,message,wParam,lParam){ scrw, scrh = win.getScreen(); owner.wndDisplay() } } ::PostMessage(this.hwnd, 0x5A3, 0, 0); }; } namespace dock{ import win.timer; import gdip.graphics; import gdip.solidBrush; import gdi; _getMsPos = ::User32.GetCursorPos; _redrawWindow = ::User32.RedrawWindow; _fromPoint = ::User32.WindowFromPoint; _getAsyncKeyState = ::User32.GetAsyncKeyState; _getWindowThreadProcessId = ::User32.GetWindowThreadProcessId; _msIn = function(x, y){ var hwnd = _fromPoint(x, y); return _getWindowThreadProcessId(hwnd, 0) == ..thread.getId(); } _wndGdi = function(){ var hdc, mdc, hbmp; var create = function(hwnd, w, h){ hdc = ::GetWindowDC(hwnd); mdc = ::CreateCompatibleDC(); hbmp = ::CreateCompatibleBitmap(hdc, w, h); ::SelectObject(mdc, hbmp); } var delete = function(hwnd){ ::ReleaseDC(hwnd, hdc); ::DeleteDC(mdc); ::DeleteObject(hbmp); } return function(hwnd, w, h, draw, ...){ create(hwnd, w, h); if(type(draw) == "function") draw(mdc, w, h, ...); delete(hwnd); } } }
已知问题(希望光大能帮助优化下):
1、窗体贴边影藏之后,无法通过点击状态栏程序图标激活,必须鼠标放到贴边位置,有时候找不到,需要鼠标围着桌面贴边找一圈;
2、贴边程序不稳定,有时候锁屏之后,再打开电脑,发现程序界面变得透明,甚至到找不到了,完全透明了;
纯属搬运,非原创
最新回复 (0)