搬运与大家分享
使用方法:复制后保存成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、贴边程序不稳定,有时候锁屏之后,再打开电脑,发现程序界面变得透明,甚至到找不到了,完全透明了;
纯属搬运,非原创