写了个库,就像很多软件都使用悬浮窗体基本框架,其实还可以实现一些如:利用图片生成异形窗体、透明窗体之类。

//悬浮窗口
/************************************
Author : wudijushi
Date : 2011.01.09
************************************/

namespace win.util;

import win.ui;
import gdip;
import gdip.bitmap;

class float{
ctor( parentwinform, linkimage, shownow, tab){
if(!tab){ arg = {bottom=50;right=50;imgPathWnd=false;color=null}; }
else { arg = tab; }

this.winform = ..win.form(parent=parentwinform; exmode="none";title=false;min=false;max=false;
sysmenu=false;image=linkimage;border="none";bottom=arg["bottom"];right=arg["right"];mode="popup" );
this.winform.add( );

//成员变量
this.hWnd = this.winform.hwnd;

//窗体消息
this.winform.wndproc = function(hwnd,message,wparam,lparam){
select(message) {//判断消息类型
case 0x10/*_WCLOSE窗口关闭消息*/{

}
case 0x2/*_WDESTROY*/{
//释放区域对象
if( this.hRgn){
::DeleteObject(topointer(this.hRgn));
this.hRgn = null;
}
//释放位图相关对象
if ( this.hMemDC){
::SelectObject(this.hMemDC, this.hOldBmp);
::DeleteDC(topointer(this.hMemDC));
this.hMemDC = null;
this.hOldBmp = null;
}
}
case 0x14/*_WERASEBKGND*/{
if(this.hMemDC){
var rect = ::RECT();
::GetClientRect(this.hWnd, rect);
var hdc = ::GetDC(this.hWnd);
::BitBlt(hdc, 0, 0, rect.right, rect.bottom, this.hMemDC, 0, 0, 0xCC0020/*_SRCCOPY*/);
::ReleaseDC(this.hWnd, hdc);
return true;
}
}
case 0x205/*_WRBUTTONUP 鼠标右键弹起,弹出菜单*/begin
var x,y = ::LOWORD(lparam), ::HIWORD(lparam)
if( this.popmenu ) //如果用户定义了弹出菜单
this.popmenu.popup(x,y);//弹出菜单
end
case 0x201/*_WLBUTTONDOWN*/{
this.winform.hitCaption();
}
case 0x203/*_WLBUTTONDBLCLK*/{
..win.show(this.winform.parent.hwnd,!..win.isVisible( this.winform.parent.hwnd ));
}
else{

}
}
//无返回值则继续调用默认回调函数
}

//悬浮置顶
..win.setTopmost( this.hWnd );
//调整位置
..win.setPos( this.hWnd,
::GetSystemMetrics(0x10/*_SCXFULLSCREEN*/) - (this.winform.rect.right - this.winform.rect.left) - 80,
::GetSystemMetrics(0x11/*_SCYFULLSCREEN*/) /10,
this.winform.rect.right - this.winform.rect.left,
this.winform.rect.right - this.winform.rect.left
);
//图片路径画窗体
if( arg["color"] !=null ){
//创建一个内存兼容DC
var hdc = ::GetDC( this.hWnd );
this.hMemDC := ::CreateCompatibleDC( hdc );
::ReleaseDC(this.hWnd, hdc);
//将内存DC和位图关联
this.hOldBmp := ::SelectObject(this.hMemDC, this.winform.hBkbitmap);
//根据位图生成区域对象
//循环中用到的临时变量
var hRgn = null;
var hRgnTemp = null;
//循环检测位图,将非透明点增加到最终区域。
var img = ..gdip.bitmap(this.winform.image);
for(x=0; img.width-1; 1){
for(y=0; img.height-1; 1){
var cr = ::GetPixel(this.hMemDC, x, y);
if (cr != arg["color"]){
hRgnTemp = CreateRectRgn(x, y, x+1, y+1);
if (hRgn){
CombineRgn(hRgn, hRgn, hRgnTemp, 0x2/*_RGN_OR*/);
::DeleteObject(topointer(hRgnTemp));
}
else{
hRgn = hRgnTemp;
}
}
}
}
this.hRgn := hRgn;
//将区域设置到窗体
SetWindowRgn(this.hWnd, this.hRgn, 0x1/*_TRUE*/);
}
//显示窗口
if( shownow ){ this.winform.show() }

} //end ctor

//成员函数
showme = function( flag ){
if( flag ){
..win.show(this.hWnd, flag);
}
else {
..win.show(this.hWnd, flag);
}
}

}

namespace float{
SetWindowRgn = ::User32.api("SetWindowRgn","int(int hWnd,int hRgn,int bRedraw)");
GetObjectAPI = ::Gdi32.api("GetObjectA","int(int hObject,int nCount,pointer& lpObject)");
CreateRectRgn = ::Gdi32.api("CreateRectRgn","int(int X1,int Y1,int X2,int Y2)");
CombineRgn = ::Gdi32.api("CombineRgn","int(int hDestRgn,int hSrcRgn1,int hSrcRgn2,int nCombineMode)");
}

/*intellisense()
win.util.float(.(parentwinform, linkimage, shownow(true|false),{可选项} ) ={可选项}\n{buttom=50;\nright=50;\ncolor= gdi.RGB( 0, 0, 0)若传入,侧使你指定的颜色透明,但是请确保是.bmp后缀的图片做背景! }
!float.showme(.(true显示 / false隐藏)
!float.hWnd = 悬浮窗句柄
!float.winform = 悬浮窗体对象
!float.popmenu = 右键菜单
?win.util.float = !float.
end intellisense*/

测试代码:

大家这样进行测试:
import win.util;
var fw = win.utill.float.createfloatwindow(winform,$"c:\1.jpg",true); //传入张50*50的图片,或根据智能提示自定义悬浮窗体的大小

原文链接:https://bbs.aardio.com/forum.php?mod=viewthread&tid=732