窗口库及控件属性
//窗口库 win
//注释//注释描述
var u = ::User32;
var k = ::Kernel32;
//取高位、低位、合并
/*intellisense(::)*/
::LOWORD = function(l) {return l & 0xffff }
::HIWORD = function(l) {return (l >> 16) & 0xffff }
::MAKELONG = function(a,b){ return ( ( (b & 0xFFFF) << 16) | (a & 0xFFFF) ) & 0xFFFFFFFF }
::LOBYTE = function(l) {return l & 0xff }
::HIBYTE = function(l) {return (l >> 8) & 0xff }
::MAKEWORD = function (a,b){ return ( ( ( b & 0xFF) << 8) | ( a & 0xFF) ) & 0xFFFF }
/*end intellisense*/
/*intellisense(::)
::MAKELPARAM = @MAKELONG(__,)
::MAKEWPARAM = @MAKELONG(__,)
end intellisense*/
//结构体
/*intellisense(::)*/
::MSG = class{
int hwnd;
INT message;
int wParam;
int lParam;
INT time;
struct pt = {
INT x;
INT y;
};
}
::RECT = class{
ctor(left=0,top=0,right=0,bottom=0){
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
int left;
int top;
int right;
int bottom;
}
::POINT = class{
ctor(x=0,y=0){
this.x = x;
this.y = y;
}
int x ;
int y ;
}
::SIZE = class{
int cx=0;
int cy=0;
}
//系统 API
::GetModuleHandle = k.api( "GetModuleHandleA", "pointer(string)")
::GetSystemMetrics = u.api("GetSystemMetrics","int(int)")
::CreateWindowEx = u.api( "CreateWindowExA", " int(INT dwExStle,string IpClassName,string lpWindowName,INT dwStyle,int x,int y,int nWidth,
int nHeight,int hWndParent,int hMenu,pointer hlnstance,pointer lpParam)" )
::DestroyWindow = u.api( "DestroyWindow", "int(int hWnd )" );
//窗口 API
::CallWindowProc = u.api("CallWindowProcA","int(pointer lpPrevWndFunc,int hWnd,INT Msg,int wParam,int lParam)" )
::SetWindowPointer = u.api("SetWindowLongA","pointer(int hWnd,int nIndex,pointer ptrNew)" )
::SetWindowLong = u.api("SetWindowLongA","int(int hWnd,int nIndex,int dwNewLong)" )
::GetWindowLong = u.api("GetWindowLongA","int(int hWnd,int nIndex)" )
::UpdateWindow = u.api( "UpdateWindow", " int(int) " )
::InvalidateRect = u.api( "InvalidateRect", " int(int hWnd,struct lpRect,int bErase) " )
::RedrawWindow = u.api("RedrawWindow","int(int hwnd,struct lprcUpdate,pointer hrgnUpdate,INT flags)");
::GetWindowRect = u.api( "GetWindowRect", " int(int hWnd,struct &lpRect ) " )
::GetClientRect = u.api( "GetClientRect", " int(int hWnd,struct &lpRect ) " )
::ScreenToClient = u.api( "ScreenToClient", " int(int hWnd,struct &lpPoint ) " )
::ClientToScreen = u.api( "ClientToScreen", " int(int hWnd,struct &lpPoint ) " )
::OffsetRect = u.api( "OffsetRect", "int( struct &lprc, int dx, int dy )" );
::PtInRect = u.api( "PtInRect", "int(struct, int, int)" );
::MoveWindow = u.api( "MoveWindow", "int( int hWnd, int X,int Y,int nWidth,int nHeight, int bRepaint)" )
::SetWindowPos = u.api("SetWindowPos","boolean(int hWnd,int hWndlnsertAfter,int X,int Y,int cx,int cy,int Flags)")
//消息 API
::RegisterWindowMessage = u.api("RegisterWindowMessageA","int(string)");
::PostMessage = u.api("PostMessageA","int(int hWnd,INT msg,int wParam,int lParam)")
::PostThreadMessage = u.api("PostThreadMessageA","int(int idThread,INT msg,int wParam,int lParam)");
::SendMessage = u.api("SendMessageA","int(int hWnd,INT msg,pointer wParam,pointer lParam)")
::SendMessageInt = u.api("SendMessageA","int(int hWnd,INT msg,int wParam,int lParam)")
::SendMessageByInt = u.api("SendMessageA","int(int hWnd,INT msg,int &wParam,int &lParam)")
::SendMessageByString = u.api("SendMessageA","int(int,INT,int,string &lParam)")
::SendMessageByStr = u.api("SendMessageA","int(int,INT,int,str &lParam)")
::SendMessageByStruct = u.api("SendMessageA","int(int,INT,int,struct &lParam)")
::SendMessageTimeout = u.api("SendMessageTimeoutA","int(int hwnd,INT msg,pointer wParam,pointer lParam,INT flags,INT timeout,int & resultult)")
//图像 API
::LoadImage = u.api( "LoadImage", "ptr(ptr,string,INT uType,int cxDesired,int CyDesire,INT fuLoad)")
::CopyImage = u.api( "CopyImage", "ptr(ptr handle, INT uType,int cx,int cy,INT flags)")
::LoadBitmap = u.api( "LoadBitmap", "ptr(ptr,string)")
::LoadIcon = u.api( "LoadIconA", "ptr(ptr,string)")
::LoadCursor = u.api( "LoadCursorA", "pointer(pointer,string)")
//内存 API
::GlobalAlloc = k.api("GlobalAlloc","pointer(INT,INT)" ) ;
::GlobalLock = k.api("GlobalLock","ponter(pointer)" ) ;
::GlobalUnlock = k.api("GlobalUnlock","ponter(pointer)" )
::GlobalFree = k.api("GlobalFree","void(pointer)" )
/*end intellisense*/
//封装函数
//----------------------------------------------
namespace win
//windows回调函数
CALLBACK = {
/*intellisense(win.CALLBACK)*/
WNDPROC ="int32(int32 hwnd,INT32,int32,int32)";
DLGPROC ="int32(int32 hwnd,INT32,int32,int32)";
TIMERPROC ="void(int32 hwnd,INT32,INT32,INT32)";
GRAYSTRINGPROC ="int32(ptr,int32,int32)";
WNDENUMPROC ="int32(int32 hwnd,int32 lParam)";
HOOKPROC ="int32(int32,int32 wParam,int32 lParam)";
SENDASYNCPROC ="void(int32,INT32,INT32,int32)";
PROPENUMPROCA ="int32(int32,string,ptr)";
PROPENUMPROCW ="int32(int32,string,ptr)";
PROPENUMPROCEX ="int32(int32,string,ptr,INT32)";
EDITWORDBREAKPROC ="int32(string lpch,int32 ichCurrent,int32 cch,int32 code)";
DRAWSTATEPROC ="int32(ptr,int32,int32,int32,int32)";
/*end intellisense*/
}
/*intellisense(win)*/
GetWindow = u.api( "GetWindow", "int( int hWnd,INT uCmd)" )
/*end intellisense*/
//样式
getStyle = function(hwnd,style=~0){
return ::GetWindowLong(hwnd,0xFFFFFFF0/*_GWL_STYLE*/) & style
}
getStyleEx = function(hwnd,style=~0){
return ::GetWindowLong(hwnd,0xFFFFFFEC/*_GWL_EXSTYLE*/) & style
}
modifyStyle = function(hwnd,remove=0,add=0,flags,gwl=0xFFFFFFF0/*_GWL_STYLE*/ ){
var style = ( ::GetWindowLong(hwnd,gwl) & ~remove ) | add ;
::SetWindowLong(hwnd,gwl,style )
if(flags!==null)
::SetWindowPos(hwnd,0,0,0,0,0,flags | 0x1/*_SWP_NOSIZE*/ | 0x2/*_SWP_NOMOVE*/ | 0x4/*_SWP_NOZORDER*/ | 0x10/*_SWP_NOACTIVATE*/)
return style
}
modifyStyleEx = function(hwnd,remove,add,flags){
return modifyStyle( hwnd,remove,add,flags,0xFFFFFFEC/*_GWL_EXSTYLE*/)
}
getParent = u.api( "GetParent", "int(int hwnd)" )
setParent = u.api("SetParent","int(int hWndChild,int hWndNewParent)");
//获取设置窗口文本
getText = function(hwnd,len){
//返回窗体文本
len := ::SendMessage(hwnd,0xE/*_WM_GETTEXTLENGTH*/ ) + 1;
var re, textBuf = ::SendMessageByStr(hwnd,0xD/*_WM_GETTEXT*/,len,len);
return textBuf;
}
setText = u.api( "SetWindowText", "INT(int hwnd,string lpString )" )
//根据控件ID读取或设置文本
var getDlgItemText = u.api( "GetDlgItemTextA", "INT(int hDlg,int nIDDlgItem, str& lpString, int cchMax)" )
getTextById = function(hwnd,id,len=256){
var re, textBuf = getDlgItemText(hwnd,id,len,len);
return textBuf ;
}
setTextById = u.api( "SetDlgItemTextA", "INT(int hDlg,int nIDDlgItem, string lpString )" )
//返回窗口ID
getId = function(hwnd){
return ::GetWindowLong(hwnd,0xFFFFFFF4/*_GWL_ID*/ )
}
//返回窗口类名
var getClassName = u.api( "GetClassNameA", "int( int hWnd,str &lpClassName,int nMaxCount )" )
getClass = function(hwnd){
var re,classname = getClassName(hwnd,0x64 ,0x64/*_MAX_CLASS*/);
return classname ;
}
//返回顶层窗口句柄
getRoot = function(hwnd){
var result;
do{
result = hwnd;
..io.print( getStyle(result) )
if( getStyle(result,0x80000000/*_WS_POPUP*/) ){
break;
}
hwnd = getParent(hwnd)
}while(hwnd)
return result;
}
getLeaf = function(hwnd){
var result;
do{
result = hwnd;
hwnd = GetWindow(hwnd,0x5/*_GW_CHILD*/)
}while(hwnd)
return result;
}
getChild = function(hwnd){
return GetWindow(hwnd,0x5/*_GW_CHILD*/);
}
var getThreadProcessId_c = u.api( "GetWindowThreadProcessId", "INT(int hWnd,INT & processId)" ) ;
getThreadProcessId = function(hwnd){
return getThreadProcessId_c(hwnd,0);
}
var getEnvironmentVariable = k.api( "GetEnvironmentVariableA", "INT(str name,str &buf,INT size)");
var setEnvironmentVariable = k.api( "SetEnvironmentVariableA", "INT(str name,str value )");
getenv = function( name){ //读取环境变量
var len,val = getEnvironmentVariable(name, 256,256);
if (len > 256)
len,val = getEnvironmentVariable(name, len,len);
return val;
}
setenv = function( name,val){ //设置环境变量
return setEnvironmentVariable(name, val);
}
//win.lasterr已废弃,请使用全局函数 ..lasterr
self.lasterr = ..lasterr
/**intellisense(win)
getStyle(__/*输入窗口句柄*/) = 获取窗口样式
getStyle(__/*输入窗口句柄*/,0) = 获取指定窗口样式\n返回值非零值,则窗口具有指定样式
getStyleEx(__/*输入窗口句柄*/) = 获取窗口扩展样式
getStyleEx(__/*输入窗口句柄*/,0) = 获取指定窗口扩展样式\n返回值非零并与指定样式相同、则窗口具有指定样式
modifyStyle(.(窗口句柄,移除样式,添加样式) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
modifyStyleEx(.(窗口句柄,移除样式,添加样式) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
getClass(__/*输入窗口句柄*/) = 获取窗口类名
getId(__/*输入窗口句柄*/) = 获取控件ID
getRoot(__/*输入窗口句柄*/) = 获取最顶层父窗口、或具有_WS_POPUP样式的父窗口
getLeaf(__/*输入窗口句柄*/) = 窗口的最梢节子窗口(没有子窗口的控件窗口)
getRoot(__/*输入窗口句柄*/) = 获取顶层窗口句柄
getParent(__/*输入窗口句柄*/) = 获取父窗口句柄
setParent(.(子窗口句柄,父窗口句柄)=设置父窗口
getChild(__/*输入窗口句柄*/) = 获取子窗口句柄
getText(__/*输入窗口句柄*/,20) = 获取窗口文本,并指定缓冲区大小\n外部进程窗口请使用winex.getText()函数替代
getText(__/*输入窗口句柄*/) = 获取窗口文本\n外部进程窗口请使用winex.getText()函数替代
setText(.(hwnd,lpString) = 参数(窗口句柄,要设置的文本)\n外部进程窗口请使用winex.setText()函数替代
getThreadProcessId(__/*输入窗口句柄*/) = 返回线程ID,进程ID\nvar tid,pid=win.getThreadProcessId(hwnd)
getTextById(.(hwnd,id,len=256) = 获取窗口上控件的文本\n参数(窗口句柄,控件ID,缓冲区大小)
setTextById(.(hwnd,id,str) = 设置窗口上控件的文本\n参数(窗口句柄,控件ID,文本)
getenv("__") = 读取环璋变量
setenv("__","") = 设置环境变量
lasterr() = win.lasterr已废弃,请使用全局函数 ..lasterr
end intellisense**/
//窗口查找
getDesktop = u.api( "GetDesktopWindow", "int()" )
setTop = u.api("BringWindowToTop","boolean(int hWnd)")
getActive = u.api("GetActiveWindow","int()")
setActive = u.api("SetActiveWindow","int(int hwnd)")
getFocus = u.api("GetFocus","int()");
setFocus = u.api("SetFocus","int(int hwnd)");
enable = u.api("EnableWindow","int(int hwnd,bool enable)")
close = function(hwnd){
::SendMessage(hwnd,0x10/*_WM_CLOSE*/);
}
var showWindow = u.api( "ShowWindow", "int(int,int)" )
show = function(hwnd,flag=true) {
showWindow( hwnd,flag===true ? 0x5/*_SW_SHOW*/ : tonumber(flag) );
}
findEx = u.api( "FindWindowExA", "int(int hWndParent,int hWndChildAfter,string lpszClass,string lpszWindow)" )
find = u.api( "FindWindowA", "int( string lpszClass,string lpszWindow)" )
setTopmost = function(hwnd,top=true){
::SetWindowPos(hwnd,(top)?-1/*_HWND_TOPMOST*/:-2/*_HWND_NOTOPMOST*/,0,0,0,0,0x2/*_SWP_NOMOVE*/|0x1/*_SWP_NOSIZE*/)
}
//try{
SwitchToThisWindow = u.api( "SwitchToThisWindow", "int(int hwnd,int bRestore)" )
setForeground = function(hwnd,restore=1){
return SwitchToThisWindow(hwnd,restore);
}
/*
}
catch(e){
setForeground = u.api("SetForegroundWindow","int(int hwnd)")
}
*/
getForeground = u.api( "GetForegroundWindow", "int()" )
isVisible = u.api("IsWindowVisible","int(int hwnd)")
isWindow = u.api( "IsWindow", "int(int hwnd)" )
isIconic = u.api( "IsIconic", "int(int hwnd)" )
isZoomed = u.api("IsZoomed","int(int hwnd)")
isEnable = function(hwnd){
return ! getStyle(hwnd,0x8000000/*_WS_DISABLED*/ )
}
isChild = ::User32.api("IsChild","int(int parent,int hwnd)")
/**intellisense(win)
isChild(.(父窗口句柄,子窗口句柄) = 判断参数二指定的窗口是否参数一指定窗口的子窗口或隶属子窗口
isVisible(__/*输入窗口句柄*/) = 判断窗口是否可见
isWindow(__/*输入窗口句柄*/) = 判断是否有效窗口
isIconic(__/*输入窗口句柄*/) = 判断窗口是否最小化为任务栏图标
isZoomed(__/*输入窗口句柄*/) = 判断窗口是否最大化
isEnable(__/*输入窗口句柄*/) = 判断窗口是否启用状态
show(hwnd,__/*可选输入显示参数*/) = 显示窗口,可选输入以_SW_为前缀的显示参数
show(hwnd,false) = 隐藏窗口
close(__/*输入窗口句柄*/) = 关闭窗口\n关闭外部进程窗口请使用winex.close()替代
enable(__/*输入窗口句柄*/,true) = 启用窗口
enable(__/*输入窗口句柄*/,false) = 禁用窗口
setTop(__/*输入窗口句柄*/)=前置窗口到当前线程Z序顶部
setForeground(__/*输入窗口句柄*/)=前置窗口
getForeground()=获取前台窗口句柄
getActive()=获取当前线程激活窗口句柄,如果要获取全局激活窗口请使用win.getForeground()
setActive(__/*输入窗口句柄*/)=设置激活窗口
getFocus()=获取窗入焦点所在窗口句柄
setFocus(__/*输入窗口句柄*/)=设置输入焦点
getDesktop()=获取桌面句柄
setTopmost(__/*输入窗口句柄*/)=置顶窗口
setTopmost(__/*输入窗口句柄*/,false)=取消置顶窗口
find(.(类名,标题)=查找顶层窗口,参数都是可选参数
findEx(.(父窗口句柄,上一个窗口句柄,类名,标题)=查找子窗口\n除父窗口句柄以外,其他参数都是可选参数
end intellisense**/
setPos = function(hwnd,x,y,cx,cy,after,flag=0){
if( (x===null) || (y===null) ){
flag |= 0x2/*_SWP_NOMOVE*/
x,y = 0,0;
}
if( (cx===null) || (cy===null) ){
flag |= 0x1/*_SWP_NOSIZE*/
cx,cy = 0,0;
}
if( after === null ){
flag |= 0x4/*_SWP_NOZORDER*/
after = 0;
}
SetWindowPos(hwnd,after,x,y,cx,cy,flag);
}
//ptConv不得传出外部
var ptConv = POINT();
toScreen = function(hwnd,x,y){
ptConv.x = x;
ptConv.y = y;
ClientToScreen(hwnd,ptConv);
return ptConv.x,ptConv.y;
}
toClient = function(hwnd,x,y){
ptConv.x = x;
ptConv.y = y;
ScreenToClient(hwnd,ptConv);
return ptConv.x,ptConv.y;
}
var converRect = function(conv,parent,rc){
ptConv.x = rc.right;
ptConv.y = rc.bottom;
conv( parent,rc );
conv( parent,ptConv );
rc.right = ptConv.x;
rc.bottom = ptConv.y;
return rc;
}
toScreenRect = function(parent,rc){
return converRect( ClientToScreen,parent,rc );
}
toClientRect = function(parent,rc){
return converRect( ScreenToClient,parent,rc );
}
//返回窗口的相对坐标
getRect = function(hwnd,scr){
var rc = RECT();
GetWindowRect( hwnd,rc);
if( scr )
return rc;
var parent = ..win.getParent(hwnd)
if( parent )
toClientRect( parent,rc );
return rc;
}
getClientRect = function(hwnd){
var rc = RECT();
GetClientRect( hwnd,rc);
return rc;
}
setRect = function(hwnd,rc){
setPos(hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top)
}
getPos = function(hwnd,scr){
var rc = getRect(hwnd,scr);
return rc.left, rc.top, rc.right - rc.left ,rc.bottom - rc.top
}
/**intellisense()
?.getRect = !rect.
!rect.left = 左
!rect.top = 上
!rect.right = 右
!rect.bottom = 下
!point.x = x坐标
!point.y = y坐标
?::RECT = !rect.
?::RECT = !point.
end intellisense**/
/**intellisense(win)
toScreen(__/*输入窗口句柄*/,x,y) = 将坐标转换为屏幕坐标\n::POINT结构体请直接使用::ClientToScreen
toClient(__/*输入窗口句柄*/,x,y) = 将坐标转换为客户坐标\n::POINT结构体请直接使用::ScreenToClient
toScreenRect(__/*输入窗口句柄*/,rc) = 将::RECT结构体转换为屏幕坐标
toClientRect(__/*输入窗口句柄*/,rc) = 将::RECT结构体转换为客户坐标
getRect(__/*输入窗口句柄*/) = 返回窗体相对坐标位置\n对于顶层窗口则等同于屏幕绝对坐标位置\n如需返回屏幕坐标,可以直接使用 ::GetWindowRect
getRect(__/*输入窗口句柄*/,true) = 返回窗体屏幕坐标位置\n返回值为::RECT结构体
setRect(__/*输入窗口句柄*/,rc) = 设置窗口相对坐标位置
getClientRect(__/*输入窗口句柄*/) = 获取窗口客户区的坐标\n不包括边框等
setPos(.(窗口句柄,x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,除句柄外所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序
getPos(__/*输入窗口句柄*/) = 返回相对坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd)
getPos(__/*输入窗口句柄*/,true) = 返回屏幕坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd)
end intellisense**/
getScreen = function(){
return ::GetSystemMetrics( 0x0 ),::GetSystemMetrics( 0x1 )
}
/**intellisense(win)
getScreen() = 返回屏幕宽度、高度
end intellisense**/
var messageBox = u.api( "MessageBoxA", " int ( int hWnd, string lpText,string lpCaption ,INT uType )" )
var messageBoxTimeout = u.api("MessageBoxTimeoutA","int(int hwnd,string lpText,string lpCaption,int uType,int wlange,int dwTimeout)","stdcall") ;
msgbox = function(str,title = "AAuto" ,style ,parenthwnd=0 ){
style := 0x40 // _MB_OK|_MB_ICONINFORMATION;
if(!parenthwnd)
style |= 0x2000/*_MB_TASKMODAL*/
return messageBox( parenthwnd,tostring( str ) ,title,style | 0x10000/*_MB_SETFOREGROUND*/ );
}
msgboxTest = function(str,title ,parenthwnd=0){
return msgbox(str,title,0x1 | 0x20 /*_MB_OKCANCEL|_MB_ICONQUESTION*/ ,parenthwnd ) == 1;
}
msgboxTimeout = function(str,title = "AAuto" ,timeout =2000,style ,parenthwnd=0 ){
style := 0x40 // _MB_OK|_MB_ICONINFORMATION;
if(!parenthwnd)
style |= 0x2000/*_MB_TASKMODAL*/
return messageBoxTimeout( parenthwnd,tostring( str ) ,title,style | 0x10000/*_MB_SETFOREGROUND*/ ,0,timeout );
}
var _id_invoke = "win.invoke()" + ..thread.getId()
invoke = function( func,... ){
var h = ..thread.create(
function(func,id,...){
var ret = { func(...) }
..thread.set(id, ret)
},func,_id_invoke,...);
..thread.waitOne(h);
..raw.closehandle(h);
var ret = ..thread.get(_id_invoke)
return ..table.unpack(ret);
}
/*消息循环函数{{*/
/*
::TranslateAccelerator = u.api("TranslateAcceleratorA","int(int hWnd,int hAccTable,struct lpMsg)");
::CreateAcceleratorTable = u.api("CreateAcceleratorTableA","int(struct paccel, int cAccel)");
class ACCEL {
ctor(v,k,c){
this.fVirt = v;this.key=k;this.cmd=c ;
}
WORD fVirt;
WORD key;
INT cmd;
}
*/
isDialogMessage = u.api("IsDialogMessage","INT(int hDlg,struct IpMsgc)");
var isDialogMessage = isDialogMessage;
var peekMessage = u.api( "PeekMessage", "int(struct& lpMsg,int hwnd,INT wMsgFilterMin,INT wMsgFilterMax,INT wRemoveMsg)")
var getMessage = u.api( "GetMessage", " int(struct&,int,INT,INT) " )
var translateMessage = u.api( "TranslateMessage", " int(struct&) " )
var dispatchMessage = u.api( "DispatchMessage", " int(struct&) " )
var mapforms = { //键为控件名任意窗口句柄,值为容器form
@{ _weak = "kv"} //在元表中指定为弱引用,以自动清除不使用的元素
}
var msg_observer = {}
var parseMessage = function(msg){
if( msg_observer[[1]] ){
for(k,v in msg_observer){
var re = v(msg);
if( re !==null){
return re;
}
}
}
var hwnd = msg.hwnd;
if( hwnd && ..win.form ){
var winform = mapforms[hwnd]
if( winform === null ){
winform = ..win.form.getForm(hwnd)
if(!winform)
mapforms[hwnd] = false; //标记为false,避免重复查询父窗口
else
mapforms[hwnd] = winform;
}
if( winform ){
if(winform.pretranslate && winform.pretranslate(msg) )
return true;
if( (msg.message >= 0x100/*_WM_KEYFIRST*/) && (msg.message <= 0x108/*_WM_KEYLAST*/) ){
var isdlg = winform[["isDialogMessage"]] : isDialogMessage;
if( isdlg( winform.hwnd,msg ) )
return true;
}
}
}
translateMessage( msg);
dispatchMessage( msg);
}
var msgloop;
pumpMessage = function(){
var msg = ::MSG();
if( getMessage( msg,0,0,0) > 0 )
{
if(msg.message == 0x12 ){
quitMessage();
return null;
}
parseMessage(msg);
}
sleep(1)
}
/*
启动消息循环,即使重复调用此函数,一个线程仅启动一个循环。
参数:
observer 消息观察函数,可以为null
attach 为true则注册observer函数,为false则注销observer函数
*/
hookMessage = function(observer,attach=true){
if(type(observer) == type.function ){
if( !attach ){
for(i=#msg_observer;1){
if( msg_observer[i] == observer){
..table.remove(msg_observer,i);
return true;
}
}
return false;
}
..table.push(msg_observer,observer);
}
}
loopMessage = function(observer,attach=true){ //启动消息循环,参数为主窗体
if(type(observer) == type.function ){
hookMessage( observer,attach );
}
//排重
if(msgloop)return;
msgloop = true;
..win.closed = false;
var msg = ::MSG();
while( getMessage( msg,0,0,0) > 0 ) {
//GetMessage()函数会返回0,非0和-1。其中-1表示由于hWnd不是有效 的窗口句柄等原因而出错。
parseMessage(msg);
}
msgloop = false;
..win.closed = true;
mapforms = {};//清空缓存里的所有窗口对象
return true;
}
quitMessage = function() {
::PostThreadMessage(..thread.getId(),0x12/*_WM_QUIT*/ ,0,0);
..win.closed = true;
}
var time_tick = ..time.tick;
delay = function ( nTimeMs = 0 ) {
var msg = ::MSG();
var endTick = time_tick() + nTimeMs;
while(time_tick() < endTick)
{
if( closed )return false;
if(peekMessage(msg , 0, 0, 0, 1)) {
if(msg.message == 0x12 ){
quitMessage();
return false;
}
parseMessage(msg);
}
sleep(1)
}
return true;
}
/*}}*/
/**intellisense(win)
invoke = @.invoke(\n function(){\n import win;\n /*执行耗时函数、并正常处理窗口消息*/__\n } \n)
msgbox("__","AAuto") = 弹出对话框
msgboxTimeout("__","标题") = 弹出对话框,超时自动关闭
msgboxTimeout("__","标题",3000) = 弹出对话框,超时自动关闭
msgboxTest("",""); = @win.msgboxTest("询问用户的信息","标题")//返回布尔值表示用户是否按了“确定”按钮。
closed = 用户是否关闭了全部窗口
loopMessage(__) = 运行消息循环
quitMessage() = 退出消息循环
pumpMessage() = 处理消息
isDialogMessage(hwnd,msg) = 处理对话框控制键消息
delay(__) = 延时n毫秒\n如果不需要消息循环时,建议使用sleep函数
end intellisense**/
//注释//注释描述
var u = ::User32;
var k = ::Kernel32;
//取高位、低位、合并
/*intellisense(::)*/
::LOWORD = function(l) {return l & 0xffff }
::HIWORD = function(l) {return (l >> 16) & 0xffff }
::MAKELONG = function(a,b){ return ( ( (b & 0xFFFF) << 16) | (a & 0xFFFF) ) & 0xFFFFFFFF }
::LOBYTE = function(l) {return l & 0xff }
::HIBYTE = function(l) {return (l >> 8) & 0xff }
::MAKEWORD = function (a,b){ return ( ( ( b & 0xFF) << 8) | ( a & 0xFF) ) & 0xFFFF }
/*end intellisense*/
/*intellisense(::)
::MAKELPARAM = @MAKELONG(__,)
::MAKEWPARAM = @MAKELONG(__,)
end intellisense*/
//结构体
/*intellisense(::)*/
::MSG = class{
int hwnd;
INT message;
int wParam;
int lParam;
INT time;
struct pt = {
INT x;
INT y;
};
}
::RECT = class{
ctor(left=0,top=0,right=0,bottom=0){
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
int left;
int top;
int right;
int bottom;
}
::POINT = class{
ctor(x=0,y=0){
this.x = x;
this.y = y;
}
int x ;
int y ;
}
::SIZE = class{
int cx=0;
int cy=0;
}
//系统 API
::GetModuleHandle = k.api( "GetModuleHandleA", "pointer(string)")
::GetSystemMetrics = u.api("GetSystemMetrics","int(int)")
::CreateWindowEx = u.api( "CreateWindowExA", " int(INT dwExStle,string IpClassName,string lpWindowName,INT dwStyle,int x,int y,int nWidth,
int nHeight,int hWndParent,int hMenu,pointer hlnstance,pointer lpParam)" )
::DestroyWindow = u.api( "DestroyWindow", "int(int hWnd )" );
//窗口 API
::CallWindowProc = u.api("CallWindowProcA","int(pointer lpPrevWndFunc,int hWnd,INT Msg,int wParam,int lParam)" )
::SetWindowPointer = u.api("SetWindowLongA","pointer(int hWnd,int nIndex,pointer ptrNew)" )
::SetWindowLong = u.api("SetWindowLongA","int(int hWnd,int nIndex,int dwNewLong)" )
::GetWindowLong = u.api("GetWindowLongA","int(int hWnd,int nIndex)" )
::UpdateWindow = u.api( "UpdateWindow", " int(int) " )
::InvalidateRect = u.api( "InvalidateRect", " int(int hWnd,struct lpRect,int bErase) " )
::RedrawWindow = u.api("RedrawWindow","int(int hwnd,struct lprcUpdate,pointer hrgnUpdate,INT flags)");
::GetWindowRect = u.api( "GetWindowRect", " int(int hWnd,struct &lpRect ) " )
::GetClientRect = u.api( "GetClientRect", " int(int hWnd,struct &lpRect ) " )
::ScreenToClient = u.api( "ScreenToClient", " int(int hWnd,struct &lpPoint ) " )
::ClientToScreen = u.api( "ClientToScreen", " int(int hWnd,struct &lpPoint ) " )
::OffsetRect = u.api( "OffsetRect", "int( struct &lprc, int dx, int dy )" );
::PtInRect = u.api( "PtInRect", "int(struct, int, int)" );
::MoveWindow = u.api( "MoveWindow", "int( int hWnd, int X,int Y,int nWidth,int nHeight, int bRepaint)" )
::SetWindowPos = u.api("SetWindowPos","boolean(int hWnd,int hWndlnsertAfter,int X,int Y,int cx,int cy,int Flags)")
//消息 API
::RegisterWindowMessage = u.api("RegisterWindowMessageA","int(string)");
::PostMessage = u.api("PostMessageA","int(int hWnd,INT msg,int wParam,int lParam)")
::PostThreadMessage = u.api("PostThreadMessageA","int(int idThread,INT msg,int wParam,int lParam)");
::SendMessage = u.api("SendMessageA","int(int hWnd,INT msg,pointer wParam,pointer lParam)")
::SendMessageInt = u.api("SendMessageA","int(int hWnd,INT msg,int wParam,int lParam)")
::SendMessageByInt = u.api("SendMessageA","int(int hWnd,INT msg,int &wParam,int &lParam)")
::SendMessageByString = u.api("SendMessageA","int(int,INT,int,string &lParam)")
::SendMessageByStr = u.api("SendMessageA","int(int,INT,int,str &lParam)")
::SendMessageByStruct = u.api("SendMessageA","int(int,INT,int,struct &lParam)")
::SendMessageTimeout = u.api("SendMessageTimeoutA","int(int hwnd,INT msg,pointer wParam,pointer lParam,INT flags,INT timeout,int & resultult)")
//图像 API
::LoadImage = u.api( "LoadImage", "ptr(ptr,string,INT uType,int cxDesired,int CyDesire,INT fuLoad)")
::CopyImage = u.api( "CopyImage", "ptr(ptr handle, INT uType,int cx,int cy,INT flags)")
::LoadBitmap = u.api( "LoadBitmap", "ptr(ptr,string)")
::LoadIcon = u.api( "LoadIconA", "ptr(ptr,string)")
::LoadCursor = u.api( "LoadCursorA", "pointer(pointer,string)")
//内存 API
::GlobalAlloc = k.api("GlobalAlloc","pointer(INT,INT)" ) ;
::GlobalLock = k.api("GlobalLock","ponter(pointer)" ) ;
::GlobalUnlock = k.api("GlobalUnlock","ponter(pointer)" )
::GlobalFree = k.api("GlobalFree","void(pointer)" )
/*end intellisense*/
//封装函数
//----------------------------------------------
namespace win
//windows回调函数
CALLBACK = {
/*intellisense(win.CALLBACK)*/
WNDPROC ="int32(int32 hwnd,INT32,int32,int32)";
DLGPROC ="int32(int32 hwnd,INT32,int32,int32)";
TIMERPROC ="void(int32 hwnd,INT32,INT32,INT32)";
GRAYSTRINGPROC ="int32(ptr,int32,int32)";
WNDENUMPROC ="int32(int32 hwnd,int32 lParam)";
HOOKPROC ="int32(int32,int32 wParam,int32 lParam)";
SENDASYNCPROC ="void(int32,INT32,INT32,int32)";
PROPENUMPROCA ="int32(int32,string,ptr)";
PROPENUMPROCW ="int32(int32,string,ptr)";
PROPENUMPROCEX ="int32(int32,string,ptr,INT32)";
EDITWORDBREAKPROC ="int32(string lpch,int32 ichCurrent,int32 cch,int32 code)";
DRAWSTATEPROC ="int32(ptr,int32,int32,int32,int32)";
/*end intellisense*/
}
/*intellisense(win)*/
GetWindow = u.api( "GetWindow", "int( int hWnd,INT uCmd)" )
/*end intellisense*/
//样式
getStyle = function(hwnd,style=~0){
return ::GetWindowLong(hwnd,0xFFFFFFF0/*_GWL_STYLE*/) & style
}
getStyleEx = function(hwnd,style=~0){
return ::GetWindowLong(hwnd,0xFFFFFFEC/*_GWL_EXSTYLE*/) & style
}
modifyStyle = function(hwnd,remove=0,add=0,flags,gwl=0xFFFFFFF0/*_GWL_STYLE*/ ){
var style = ( ::GetWindowLong(hwnd,gwl) & ~remove ) | add ;
::SetWindowLong(hwnd,gwl,style )
if(flags!==null)
::SetWindowPos(hwnd,0,0,0,0,0,flags | 0x1/*_SWP_NOSIZE*/ | 0x2/*_SWP_NOMOVE*/ | 0x4/*_SWP_NOZORDER*/ | 0x10/*_SWP_NOACTIVATE*/)
return style
}
modifyStyleEx = function(hwnd,remove,add,flags){
return modifyStyle( hwnd,remove,add,flags,0xFFFFFFEC/*_GWL_EXSTYLE*/)
}
getParent = u.api( "GetParent", "int(int hwnd)" )
setParent = u.api("SetParent","int(int hWndChild,int hWndNewParent)");
//获取设置窗口文本
getText = function(hwnd,len){
//返回窗体文本
len := ::SendMessage(hwnd,0xE/*_WM_GETTEXTLENGTH*/ ) + 1;
var re, textBuf = ::SendMessageByStr(hwnd,0xD/*_WM_GETTEXT*/,len,len);
return textBuf;
}
setText = u.api( "SetWindowText", "INT(int hwnd,string lpString )" )
//根据控件ID读取或设置文本
var getDlgItemText = u.api( "GetDlgItemTextA", "INT(int hDlg,int nIDDlgItem, str& lpString, int cchMax)" )
getTextById = function(hwnd,id,len=256){
var re, textBuf = getDlgItemText(hwnd,id,len,len);
return textBuf ;
}
setTextById = u.api( "SetDlgItemTextA", "INT(int hDlg,int nIDDlgItem, string lpString )" )
//返回窗口ID
getId = function(hwnd){
return ::GetWindowLong(hwnd,0xFFFFFFF4/*_GWL_ID*/ )
}
//返回窗口类名
var getClassName = u.api( "GetClassNameA", "int( int hWnd,str &lpClassName,int nMaxCount )" )
getClass = function(hwnd){
var re,classname = getClassName(hwnd,0x64 ,0x64/*_MAX_CLASS*/);
return classname ;
}
//返回顶层窗口句柄
getRoot = function(hwnd){
var result;
do{
result = hwnd;
..io.print( getStyle(result) )
if( getStyle(result,0x80000000/*_WS_POPUP*/) ){
break;
}
hwnd = getParent(hwnd)
}while(hwnd)
return result;
}
getLeaf = function(hwnd){
var result;
do{
result = hwnd;
hwnd = GetWindow(hwnd,0x5/*_GW_CHILD*/)
}while(hwnd)
return result;
}
getChild = function(hwnd){
return GetWindow(hwnd,0x5/*_GW_CHILD*/);
}
var getThreadProcessId_c = u.api( "GetWindowThreadProcessId", "INT(int hWnd,INT & processId)" ) ;
getThreadProcessId = function(hwnd){
return getThreadProcessId_c(hwnd,0);
}
var getEnvironmentVariable = k.api( "GetEnvironmentVariableA", "INT(str name,str &buf,INT size)");
var setEnvironmentVariable = k.api( "SetEnvironmentVariableA", "INT(str name,str value )");
getenv = function( name){ //读取环境变量
var len,val = getEnvironmentVariable(name, 256,256);
if (len > 256)
len,val = getEnvironmentVariable(name, len,len);
return val;
}
setenv = function( name,val){ //设置环境变量
return setEnvironmentVariable(name, val);
}
//win.lasterr已废弃,请使用全局函数 ..lasterr
self.lasterr = ..lasterr
/**intellisense(win)
getStyle(__/*输入窗口句柄*/) = 获取窗口样式
getStyle(__/*输入窗口句柄*/,0) = 获取指定窗口样式\n返回值非零值,则窗口具有指定样式
getStyleEx(__/*输入窗口句柄*/) = 获取窗口扩展样式
getStyleEx(__/*输入窗口句柄*/,0) = 获取指定窗口扩展样式\n返回值非零并与指定样式相同、则窗口具有指定样式
modifyStyle(.(窗口句柄,移除样式,添加样式) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
modifyStyleEx(.(窗口句柄,移除样式,添加样式) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
getClass(__/*输入窗口句柄*/) = 获取窗口类名
getId(__/*输入窗口句柄*/) = 获取控件ID
getRoot(__/*输入窗口句柄*/) = 获取最顶层父窗口、或具有_WS_POPUP样式的父窗口
getLeaf(__/*输入窗口句柄*/) = 窗口的最梢节子窗口(没有子窗口的控件窗口)
getRoot(__/*输入窗口句柄*/) = 获取顶层窗口句柄
getParent(__/*输入窗口句柄*/) = 获取父窗口句柄
setParent(.(子窗口句柄,父窗口句柄)=设置父窗口
getChild(__/*输入窗口句柄*/) = 获取子窗口句柄
getText(__/*输入窗口句柄*/,20) = 获取窗口文本,并指定缓冲区大小\n外部进程窗口请使用winex.getText()函数替代
getText(__/*输入窗口句柄*/) = 获取窗口文本\n外部进程窗口请使用winex.getText()函数替代
setText(.(hwnd,lpString) = 参数(窗口句柄,要设置的文本)\n外部进程窗口请使用winex.setText()函数替代
getThreadProcessId(__/*输入窗口句柄*/) = 返回线程ID,进程ID\nvar tid,pid=win.getThreadProcessId(hwnd)
getTextById(.(hwnd,id,len=256) = 获取窗口上控件的文本\n参数(窗口句柄,控件ID,缓冲区大小)
setTextById(.(hwnd,id,str) = 设置窗口上控件的文本\n参数(窗口句柄,控件ID,文本)
getenv("__") = 读取环璋变量
setenv("__","") = 设置环境变量
lasterr() = win.lasterr已废弃,请使用全局函数 ..lasterr
end intellisense**/
//窗口查找
getDesktop = u.api( "GetDesktopWindow", "int()" )
setTop = u.api("BringWindowToTop","boolean(int hWnd)")
getActive = u.api("GetActiveWindow","int()")
setActive = u.api("SetActiveWindow","int(int hwnd)")
getFocus = u.api("GetFocus","int()");
setFocus = u.api("SetFocus","int(int hwnd)");
enable = u.api("EnableWindow","int(int hwnd,bool enable)")
close = function(hwnd){
::SendMessage(hwnd,0x10/*_WM_CLOSE*/);
}
var showWindow = u.api( "ShowWindow", "int(int,int)" )
show = function(hwnd,flag=true) {
showWindow( hwnd,flag===true ? 0x5/*_SW_SHOW*/ : tonumber(flag) );
}
findEx = u.api( "FindWindowExA", "int(int hWndParent,int hWndChildAfter,string lpszClass,string lpszWindow)" )
find = u.api( "FindWindowA", "int( string lpszClass,string lpszWindow)" )
setTopmost = function(hwnd,top=true){
::SetWindowPos(hwnd,(top)?-1/*_HWND_TOPMOST*/:-2/*_HWND_NOTOPMOST*/,0,0,0,0,0x2/*_SWP_NOMOVE*/|0x1/*_SWP_NOSIZE*/)
}
//try{
SwitchToThisWindow = u.api( "SwitchToThisWindow", "int(int hwnd,int bRestore)" )
setForeground = function(hwnd,restore=1){
return SwitchToThisWindow(hwnd,restore);
}
/*
}
catch(e){
setForeground = u.api("SetForegroundWindow","int(int hwnd)")
}
*/
getForeground = u.api( "GetForegroundWindow", "int()" )
isVisible = u.api("IsWindowVisible","int(int hwnd)")
isWindow = u.api( "IsWindow", "int(int hwnd)" )
isIconic = u.api( "IsIconic", "int(int hwnd)" )
isZoomed = u.api("IsZoomed","int(int hwnd)")
isEnable = function(hwnd){
return ! getStyle(hwnd,0x8000000/*_WS_DISABLED*/ )
}
isChild = ::User32.api("IsChild","int(int parent,int hwnd)")
/**intellisense(win)
isChild(.(父窗口句柄,子窗口句柄) = 判断参数二指定的窗口是否参数一指定窗口的子窗口或隶属子窗口
isVisible(__/*输入窗口句柄*/) = 判断窗口是否可见
isWindow(__/*输入窗口句柄*/) = 判断是否有效窗口
isIconic(__/*输入窗口句柄*/) = 判断窗口是否最小化为任务栏图标
isZoomed(__/*输入窗口句柄*/) = 判断窗口是否最大化
isEnable(__/*输入窗口句柄*/) = 判断窗口是否启用状态
show(hwnd,__/*可选输入显示参数*/) = 显示窗口,可选输入以_SW_为前缀的显示参数
show(hwnd,false) = 隐藏窗口
close(__/*输入窗口句柄*/) = 关闭窗口\n关闭外部进程窗口请使用winex.close()替代
enable(__/*输入窗口句柄*/,true) = 启用窗口
enable(__/*输入窗口句柄*/,false) = 禁用窗口
setTop(__/*输入窗口句柄*/)=前置窗口到当前线程Z序顶部
setForeground(__/*输入窗口句柄*/)=前置窗口
getForeground()=获取前台窗口句柄
getActive()=获取当前线程激活窗口句柄,如果要获取全局激活窗口请使用win.getForeground()
setActive(__/*输入窗口句柄*/)=设置激活窗口
getFocus()=获取窗入焦点所在窗口句柄
setFocus(__/*输入窗口句柄*/)=设置输入焦点
getDesktop()=获取桌面句柄
setTopmost(__/*输入窗口句柄*/)=置顶窗口
setTopmost(__/*输入窗口句柄*/,false)=取消置顶窗口
find(.(类名,标题)=查找顶层窗口,参数都是可选参数
findEx(.(父窗口句柄,上一个窗口句柄,类名,标题)=查找子窗口\n除父窗口句柄以外,其他参数都是可选参数
end intellisense**/
setPos = function(hwnd,x,y,cx,cy,after,flag=0){
if( (x===null) || (y===null) ){
flag |= 0x2/*_SWP_NOMOVE*/
x,y = 0,0;
}
if( (cx===null) || (cy===null) ){
flag |= 0x1/*_SWP_NOSIZE*/
cx,cy = 0,0;
}
if( after === null ){
flag |= 0x4/*_SWP_NOZORDER*/
after = 0;
}
SetWindowPos(hwnd,after,x,y,cx,cy,flag);
}
//ptConv不得传出外部
var ptConv = POINT();
toScreen = function(hwnd,x,y){
ptConv.x = x;
ptConv.y = y;
ClientToScreen(hwnd,ptConv);
return ptConv.x,ptConv.y;
}
toClient = function(hwnd,x,y){
ptConv.x = x;
ptConv.y = y;
ScreenToClient(hwnd,ptConv);
return ptConv.x,ptConv.y;
}
var converRect = function(conv,parent,rc){
ptConv.x = rc.right;
ptConv.y = rc.bottom;
conv( parent,rc );
conv( parent,ptConv );
rc.right = ptConv.x;
rc.bottom = ptConv.y;
return rc;
}
toScreenRect = function(parent,rc){
return converRect( ClientToScreen,parent,rc );
}
toClientRect = function(parent,rc){
return converRect( ScreenToClient,parent,rc );
}
//返回窗口的相对坐标
getRect = function(hwnd,scr){
var rc = RECT();
GetWindowRect( hwnd,rc);
if( scr )
return rc;
var parent = ..win.getParent(hwnd)
if( parent )
toClientRect( parent,rc );
return rc;
}
getClientRect = function(hwnd){
var rc = RECT();
GetClientRect( hwnd,rc);
return rc;
}
setRect = function(hwnd,rc){
setPos(hwnd,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top)
}
getPos = function(hwnd,scr){
var rc = getRect(hwnd,scr);
return rc.left, rc.top, rc.right - rc.left ,rc.bottom - rc.top
}
/**intellisense()
?.getRect = !rect.
!rect.left = 左
!rect.top = 上
!rect.right = 右
!rect.bottom = 下
!point.x = x坐标
!point.y = y坐标
?::RECT = !rect.
?::RECT = !point.
end intellisense**/
/**intellisense(win)
toScreen(__/*输入窗口句柄*/,x,y) = 将坐标转换为屏幕坐标\n::POINT结构体请直接使用::ClientToScreen
toClient(__/*输入窗口句柄*/,x,y) = 将坐标转换为客户坐标\n::POINT结构体请直接使用::ScreenToClient
toScreenRect(__/*输入窗口句柄*/,rc) = 将::RECT结构体转换为屏幕坐标
toClientRect(__/*输入窗口句柄*/,rc) = 将::RECT结构体转换为客户坐标
getRect(__/*输入窗口句柄*/) = 返回窗体相对坐标位置\n对于顶层窗口则等同于屏幕绝对坐标位置\n如需返回屏幕坐标,可以直接使用 ::GetWindowRect
getRect(__/*输入窗口句柄*/,true) = 返回窗体屏幕坐标位置\n返回值为::RECT结构体
setRect(__/*输入窗口句柄*/,rc) = 设置窗口相对坐标位置
getClientRect(__/*输入窗口句柄*/) = 获取窗口客户区的坐标\n不包括边框等
setPos(.(窗口句柄,x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,除句柄外所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序
getPos(__/*输入窗口句柄*/) = 返回相对坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd)
getPos(__/*输入窗口句柄*/,true) = 返回屏幕坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd)
end intellisense**/
getScreen = function(){
return ::GetSystemMetrics( 0x0 ),::GetSystemMetrics( 0x1 )
}
/**intellisense(win)
getScreen() = 返回屏幕宽度、高度
end intellisense**/
var messageBox = u.api( "MessageBoxA", " int ( int hWnd, string lpText,string lpCaption ,INT uType )" )
var messageBoxTimeout = u.api("MessageBoxTimeoutA","int(int hwnd,string lpText,string lpCaption,int uType,int wlange,int dwTimeout)","stdcall") ;
msgbox = function(str,title = "AAuto" ,style ,parenthwnd=0 ){
style := 0x40 // _MB_OK|_MB_ICONINFORMATION;
if(!parenthwnd)
style |= 0x2000/*_MB_TASKMODAL*/
return messageBox( parenthwnd,tostring( str ) ,title,style | 0x10000/*_MB_SETFOREGROUND*/ );
}
msgboxTest = function(str,title ,parenthwnd=0){
return msgbox(str,title,0x1 | 0x20 /*_MB_OKCANCEL|_MB_ICONQUESTION*/ ,parenthwnd ) == 1;
}
msgboxTimeout = function(str,title = "AAuto" ,timeout =2000,style ,parenthwnd=0 ){
style := 0x40 // _MB_OK|_MB_ICONINFORMATION;
if(!parenthwnd)
style |= 0x2000/*_MB_TASKMODAL*/
return messageBoxTimeout( parenthwnd,tostring( str ) ,title,style | 0x10000/*_MB_SETFOREGROUND*/ ,0,timeout );
}
var _id_invoke = "win.invoke()" + ..thread.getId()
invoke = function( func,... ){
var h = ..thread.create(
function(func,id,...){
var ret = { func(...) }
..thread.set(id, ret)
},func,_id_invoke,...);
..thread.waitOne(h);
..raw.closehandle(h);
var ret = ..thread.get(_id_invoke)
return ..table.unpack(ret);
}
/*消息循环函数{{*/
/*
::TranslateAccelerator = u.api("TranslateAcceleratorA","int(int hWnd,int hAccTable,struct lpMsg)");
::CreateAcceleratorTable = u.api("CreateAcceleratorTableA","int(struct paccel, int cAccel)");
class ACCEL {
ctor(v,k,c){
this.fVirt = v;this.key=k;this.cmd=c ;
}
WORD fVirt;
WORD key;
INT cmd;
}
*/
isDialogMessage = u.api("IsDialogMessage","INT(int hDlg,struct IpMsgc)");
var isDialogMessage = isDialogMessage;
var peekMessage = u.api( "PeekMessage", "int(struct& lpMsg,int hwnd,INT wMsgFilterMin,INT wMsgFilterMax,INT wRemoveMsg)")
var getMessage = u.api( "GetMessage", " int(struct&,int,INT,INT) " )
var translateMessage = u.api( "TranslateMessage", " int(struct&) " )
var dispatchMessage = u.api( "DispatchMessage", " int(struct&) " )
var mapforms = { //键为控件名任意窗口句柄,值为容器form
@{ _weak = "kv"} //在元表中指定为弱引用,以自动清除不使用的元素
}
var msg_observer = {}
var parseMessage = function(msg){
if( msg_observer[[1]] ){
for(k,v in msg_observer){
var re = v(msg);
if( re !==null){
return re;
}
}
}
var hwnd = msg.hwnd;
if( hwnd && ..win.form ){
var winform = mapforms[hwnd]
if( winform === null ){
winform = ..win.form.getForm(hwnd)
if(!winform)
mapforms[hwnd] = false; //标记为false,避免重复查询父窗口
else
mapforms[hwnd] = winform;
}
if( winform ){
if(winform.pretranslate && winform.pretranslate(msg) )
return true;
if( (msg.message >= 0x100/*_WM_KEYFIRST*/) && (msg.message <= 0x108/*_WM_KEYLAST*/) ){
var isdlg = winform[["isDialogMessage"]] : isDialogMessage;
if( isdlg( winform.hwnd,msg ) )
return true;
}
}
}
translateMessage( msg);
dispatchMessage( msg);
}
var msgloop;
pumpMessage = function(){
var msg = ::MSG();
if( getMessage( msg,0,0,0) > 0 )
{
if(msg.message == 0x12 ){
quitMessage();
return null;
}
parseMessage(msg);
}
sleep(1)
}
/*
启动消息循环,即使重复调用此函数,一个线程仅启动一个循环。
参数:
observer 消息观察函数,可以为null
attach 为true则注册observer函数,为false则注销observer函数
*/
hookMessage = function(observer,attach=true){
if(type(observer) == type.function ){
if( !attach ){
for(i=#msg_observer;1){
if( msg_observer[i] == observer){
..table.remove(msg_observer,i);
return true;
}
}
return false;
}
..table.push(msg_observer,observer);
}
}
loopMessage = function(observer,attach=true){ //启动消息循环,参数为主窗体
if(type(observer) == type.function ){
hookMessage( observer,attach );
}
//排重
if(msgloop)return;
msgloop = true;
..win.closed = false;
var msg = ::MSG();
while( getMessage( msg,0,0,0) > 0 ) {
//GetMessage()函数会返回0,非0和-1。其中-1表示由于hWnd不是有效 的窗口句柄等原因而出错。
parseMessage(msg);
}
msgloop = false;
..win.closed = true;
mapforms = {};//清空缓存里的所有窗口对象
return true;
}
quitMessage = function() {
::PostThreadMessage(..thread.getId(),0x12/*_WM_QUIT*/ ,0,0);
..win.closed = true;
}
var time_tick = ..time.tick;
delay = function ( nTimeMs = 0 ) {
var msg = ::MSG();
var endTick = time_tick() + nTimeMs;
while(time_tick() < endTick)
{
if( closed )return false;
if(peekMessage(msg , 0, 0, 0, 1)) {
if(msg.message == 0x12 ){
quitMessage();
return false;
}
parseMessage(msg);
}
sleep(1)
}
return true;
}
/*}}*/
/**intellisense(win)
invoke = @.invoke(\n function(){\n import win;\n /*执行耗时函数、并正常处理窗口消息*/__\n } \n)
msgbox("__","AAuto") = 弹出对话框
msgboxTimeout("__","标题") = 弹出对话框,超时自动关闭
msgboxTimeout("__","标题",3000) = 弹出对话框,超时自动关闭
msgboxTest("",""); = @win.msgboxTest("询问用户的信息","标题")//返回布尔值表示用户是否按了“确定”按钮。
closed = 用户是否关闭了全部窗口
loopMessage(__) = 运行消息循环
quitMessage() = 退出消息循环
pumpMessage() = 处理消息
isDialogMessage(hwnd,msg) = 处理对话框控制键消息
delay(__) = 延时n毫秒\n如果不需要消息循环时,建议使用sleep函数
end intellisense**/
//界面支持库win.ui
import win.ui.ctrl;
import win.gdi;
namespace win;
//下面两个函数是保护成员,禁止外部直接调用
var SetTimer = ::User32.api("SetTimer","INT(int hWnd,INT nIDEvent,INT uElapse,pointer lpTimerFunc)");
var KillTimer = ::User32.api("KillTimer","int(int hWnd,INT nIDEvent)");
var cyborder = ::GetSystemMetrics( 0x6/*_SM_CYBORDER*/ );
var cxborder = ::GetSystemMetrics( 0x5/*_SM_CXBORDER*/ );
var cycaption = ::GetSystemMetrics( 0x4/*_SM_CYCAPTION*/ );
::Shell32 := ..raw.loadDll("Shell32")
var DragQueryFile = ::Shell32.api("DragQueryFile","INT(int hDrop, INT iFile,str& lpszFile,INT cch)");
var DragFinish = ::Shell32.api("DragFinish","INT(int hDrop)");
//接收拖放文件名
getDropFile = function(wparam){
var re = DragQueryFile(wparam,0xFFFFFFFF,0x104/*_MAX_PATH*/,0x104/*_MAX_PATH*/);
var file = {};
for(i=1;re)
re,file[i] = DragQueryFile(wparam,i-1,0x104/*_MAX_PATH*/,0x104/*_MAX_PATH*/);
DragFinish( wparam );
return file;
}
/**intellisense(win)
getDropFile(wparam) = 用于消息回调函数中获取拖放文件列表
end intellisense**/
try{
uxTheme = ..raw.loadDll("UxTheme.dll")
SetWindowTheme = uxTheme.api("SetWindowTheme","void(int hwnd,string pszSubAppName,string pszSubIdList)" )
//SetWindowTheme(控件句柄," "," ")
}
catch(e){
}
ui.NMHDR = class {
int hwndFrom;
INT idFrom;
INT code; // NM_ code
}
var NMHDR_L = ui.NMHDR;
/**intellisense()
!nmhdl.hwndFrom = 发送消息的控件句柄
!nmhdl.idFrom = 发送消息的控件ID
!nmhdl.code = 通知代码
?.ui.NMHDR = !nmhdl.
end intellisense**/
var io = ..io;
var raw = ..raw;
var hInstance = ::GetModuleHandle(null);
class form{
//form类构造函数
ctor( tparam ) begin
this.hInstance = hInstance;
var wndclass = ::WNDCLASSEX();
tparam.cls := "AAU_FORM"
tparam.cls = ..string.format("%s[TID:%d]",tparam.cls , ..thread.getId() )
if(not ::GetClassInfo(this.hInstance,tparam.cls,wndclass) ) {
//创建一个新的窗口类
wndclass = ::WNDCLASSEX();
wndclass.hInstance= hInstance ;
wndclass.lpszClassName=tparam.cls;
wndclass.hIcon = ::LoadIcon(this.hInstance, topointer(130) );
wndclass.hIconSm = ::LoadIcon(this.hInstance, topointer(130) );
wndclass.hCursor = ::LoadCursor(null, topointer(0x7F00/*_IDC_ARROW*/) );
wndclass.hbrBackground = topointer(0xF/*_COLOR_BTNFACE*/ + 1) //::GetStockObject(_HOLLOW_BRUSH);
wndclass.lpfnWndProc = ::DefWindowProc;
assert( RegisterClassEx( wndclass) , ..lasterr() )
}
//创建窗口之前,不允许tvalue修改t,l,r,b位置参数,以避免容器内控件错位
if(tparam.left===null)
tparam.left= -1;
if(tparam.top===null)
tparam.top= -1;
//自定义控件
if( tparam.tvalue ){
for(k,v in tparam.tvalue){
if(tparam[k]===null){ //不允许自定义控件重写的属性,请写在这段代码前面,例如cls
tparam[k] = v;
}
}
}
else {
tparam.id = 0;
}
tparam.exstyle := 0
tparam.style := 0
//生成窗口扩展样式
//---------------------------------
//初始化为组合扩展样式
select( tparam.exmode ) {
case "toolwindow" {
tparam.exstyle |= 0x80/*_WS_EX_TOOLWINDOW*/;
}
case "none" {
tparam.exstyle |= 0;
}
else {
tparam.exstyle |= 0x40000/*_WS_EX_APPWINDOW*/;
}
}
if(tparam.acceptfiles)
tparam.exstyle |= 0x10/*_WS_EX_ACCEPTFILES*/
if(tparam.frame)
tparam.exstyle |= 0x1/*_WS_EX_DLGMODALFRAME*/
if(tparam.cp)
tparam.exstyle |= 0x10000/*_WS_EX_CONTROLPARENT*/
if(tparam.topmost)
tparam.exstyle |= 0x8/*_WS_EX_TOPMOST*/
//生成窗口样式
//---------------------------------
//初始化为组合样式
select( tparam.mode ) {
case "child" {
tparam.style |= 0x40000000/*_WS_CHILD*/
}
case "popup" {
tparam.style |= 0x80000000/*_WS_POPUP*/ ;
}
else {
tparam.style |= 0x0/*_WS_OVERLAPPED*/;
}
}
//如果窗口标题为空,则自动禁用标题栏,系统菜单
if(! (#(tparam.text)) ){
tparam.title = false;
//tparam.sysmenu = false;
}
if(tparam.title === false ) //无标题栏时不能应用_WS_OVERLAPPED样式
tparam.style := 0x80000000/*_WS_POPUP*/
//边框样式
var cyborder = CY_BORDER
var cxborder = CX_BORDER
var cycaption = CY_CAPTION
//WS_CAPTION 实际上是 _WS_BORDER 与 _WS_DLGFRAME组合而成
var deltitle = ~0xC00000/*_WS_CAPTION*/;
select( tparam.border ) {
case "resizable" {
tparam.style |= 0x40000/*_WS_SIZEBOX*/;
}
case "thin" {
tparam.style |= 0x800000/*_WS_BORDER*/;
deltitle = ~0x400000/*_WS_DLGFRAME*/;
}
case "none" {
//无边框窗口
cyborder = 0;
cxborder = 0;
//取消默认的 0x0/*_WS_OVERLAPPED* 样式
tparam.style := 0x80000000/*_WS_POPUP*/
tparam.style &= ~ 0x800000/*_WS_BORDER*/;
tparam.title = false;
}
else {
tparam.style |= 0x400000/*_WS_DLGFRAME*/;
deltitle = ~0x800000/*_WS_BORDER*/;
}
}
if(tparam.title===false) {
tparam.style &= deltitle //避免去掉标题栏时覆盖了边框设置
cycaption = 0; //如果没有标题栏,则要去掉标题栏的高度
}
else{
tparam.style |= 0xC00000/*_WS_CAPTION*/
}
if(tparam.max!==false)
tparam.style |= 0x10000/*_WS_MAXIMIZEBOX*/
else
tparam.style &= ~0x10000/*_WS_MAXIMIZEBOX*/
if(tparam.min!==false)
tparam.style |= 0x20000/*_WS_MINIMIZEBOX*/
else
tparam.style &= ~0x20000/*_WS_MINIMIZEBOX*/
if(tparam.sysmenu!==false) {
tparam.style |= 0x80000/*_WS_SYSMENU*/
}
else {
tparam.style &= ~0x80000/*_WS_SYSMENU*/
}
if( tparam.maxmize ){
tparam.style |= 0x1000000/*_WS_MAXIMIZE*/;
}
if( tparam.minmize ){
tparam.style |= 0x20000000/*_WS_MINIMIZE*/
}
this@ = metaProperty
//如果用户设置了背景图片
this.image = tparam.image
if( ( type( tparam.parent) == type.table ) ){
this.parent = tparam.parent;
tparam.parent = tparam.parent.hwnd;
}
if( type( tparam.parent ) != type.number )
tparam.parent = 0;
//计算窗体宽、高
var cx = tparam.right - tparam.left + (cxborder*2) ;
var cy = tparam.bottom - tparam.top + (cyborder*2) + cycaption;
var x = tparam.left ;
//如果为负数,计算默认坐标
if(x==-1){
var sx = ::GetSystemMetrics(0x0/*_SM_CXSCREEN*/) ;
if(sx>cx)
x = (sx-cx)/2;
else
x = 0; //0x80000000/*_CW_USEDEFAULT*/
}
var y = tparam.top ;
//如果为负数,计算默认坐标
if(y==-1){
var sy = ::GetSystemMetrics(0x1/*_SM_CYSCREEN*/ ) ;
if(sy>cy)
y = (sy-cy)/2;
else
y = 0; //0x80000000/*_CW_USEDEFAULT*/
}
//创建主窗口
this.hwnd = ::CreateWindowEx(
tparam.exstyle,
tparam.cls,
tparam.text,
tparam.style , //窗口风格
x,//x
y,//y
cx,//w
cy,//h
tparam.parent,//parent
tparam.id,//menu
hInstance,
null//param
);
//记录窗口大小
this._defClientRect = ::RECT( 0, 0, tparam.right - tparam.left, tparam.bottom - tparam.top);
this.font = LOGFONT( );//设置字体
//不要清除设置图片时设定的默认背景色
if( tparam.bgcolor)
this[["bgcolor"]] = tparam.bgcolor;
this[["scroll"]] = tparam.scroll;
this._wndproc_c = raw.tostdcall( _wndproc, ..win.CALLBACK.WNDPROC,this/*设为owner对象*/)
::SetWindowPointer(this.hwnd,0xFFFFFFFC/*_GWL_WNDPROC*/, this._wndproc_c);
_forms[this.hwnd] = this;
..win.closed = null;//通知所有消息函数,窗体正在运行
end;
_ctrlId = {};//控件ID映射关系
_ctrlHwnd = {};//控件句柄映射关系
_menuProc = { freeId = 5000 };
add = function( tparam ) begin
var zorder = {}
for name,tvalue in tparam{
for(i=1;#zorder;1){
if( zorder[i][2].z > tvalue.z ) {
..table.insert( zorder,{name;tvalue} , i)
continue 2;
}
}
..table.push( zorder,{name;tvalue} );
}
var ctrl;
for(i=1;#zorder ){
var name = zorder[i][1];
var opt = zorder[i][2];
//创建控件
opt.parent = this;
if(!opt.id) //允许显示指定控件ID
opt.id = #this._ctrlId + 1;
opt.hInstance = this.hInstance;
ctrl = ctrl_factory.create(opt);
if(!ctrl)continue ;
this[name] = ctrl;
this._ctrlId[opt.id] = ctrl
ctrl[["id"]] = opt.id;
ctrl[["parent"]] = this;
//创建控件窗口
if( !ctrl.hwnd ){
//如果不是自定义控件
ctrl.hwnd = ::CreateWindowEx (opt.exstyle, opt.cls , opt.text , opt.style ,opt.left,opt.top,opt.right - opt.left , opt.bottom - opt.top,
this.hwnd , opt.id , opt.hInstance )
}
else{
..win.setPos(ctrl.hwnd,opt.left,opt.top,opt.right - opt.left , opt.bottom - opt.top);
}
//记录所有子控件的窗口句柄
this._ctrlHwnd[ctrl.hwnd] = ctrl
//初始化控件
ctrl_factory.onCreateComplete(ctrl);
}
end;
_tTimeProc = {};//定时回调函数
_tTimeTicks = {};//定时器时间间隔
addtimer = function(elapse,func){
var freeId = #this[["_tTimeProc"]] + 1;
..table.push( this[["_tTimeProc"]] ,func);
this[["_tTimeTicks"]][freeId] = elapse;
SetTimer(this.hwnd,freeId,elapse);
return freeId;
}
settimer = function(id,elapse,func){
if( this[["_tTimeProc"]][id] ){
SetTimer(this.hwnd,id,elapse )
this[["_tTimeTicks"]][id] = elapse;
if( func ){
this[["_tTimeProc"]][id] =func;
}
return true;
}
}
killtimer = function(id){
if( this[["_tTimeProc"]][id] ){
KillTimer(this.hwnd,id);
..table.remove( this[["_tTimeProc"]],id);
..table.remove( this[["_tTimeProc"]],id);
return true;
}
}
setTimeout = function(code,elapse=100,...){
if( type(code)==type.string ) {
code,err = loadcode(code)
if(!code)error(err,2)
}
var args = {...}
return this.addtimer ( elapse,
function(hwnd,msg,id){
this.killtimer(id)
code( ..table.unpack(args) );
}
)
}
reghotkey = function( func , mod,vk ){
if(! this[["_hotkeys"]] ) this[["_hotkeys"]] = {};
var id = ..table.push( this[["_hotkeys"]] ,func); //保存回调函数
RegisterHotKey(this.hwnd,id,mod,vk);
return id;
}
unreghotkey = function(idEvent){
UnregisterHotKey(this.hwnd,idEvent);
..table.remove( this[["_hotkeys"]],idEvent);
}
pretranslate = false; //避免触发元表
}
namespace form{
ctrl_factory = ..win.ui.ctrl.factory
/*intellisense(win.form)*/
RegisterHotKey = ::User32.api("RegisterHotKey","int(int hwnd,int id,int fsModifiers,int vk)")
UnregisterHotKey = ::User32.api("UnregisterHotKey","Long(int hwnd,int id)")
SetLayeredWindowAttributes = ::User32.api("SetLayeredWindowAttributes","int(int hwnd,int crKey,BYTE bAlpha,INT dwFlags)");
DefWindowProc = User32.api( "DefWindowProc", "int(int hWnd,INT msg,int wparam,int lParam) " )
RegisterClassEx = User32.api( "RegisterClassEx", " word(struct lpWndClass) " )
GetClassInfo = User32.api( "GetClassInfoA", "int(pointer hInstance,string lpClassName,struct &lpWndClass)" )
WNDCLASSEX = class{
INT cbSize = 48;
INT style = 0x2 | 0x1 | 0x8;//_CS_HREDRAW | _CS_VREDRAW | _CS_DBLCLKS;
pointer lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
pointer hInstance;
pointer hIcon;
pointer hCursor;
pointer hbrBackground;
string lpszMenuName;
string lpszClassName;
pointer hIconSm;
}
CY_BORDER = ::GetSystemMetrics( 0x6/*_SM_CYBORDER*/ );
CX_BORDER = ::GetSystemMetrics( 0x5/*_SM_CXBORDER*/ );
CY_CAPTION = ::GetSystemMetrics( 0x4/*_SM_CYCAPTION*/ );
/*end intellisense*/
//记录所有win.form对象,创建则添加此表,销毁则从表中移除
_forms = {}
getForm = function(hwnd){
var winform = _forms[hwnd];
while(!winform){
hwnd = ..win.getParent(hwnd);
if(!hwnd)
return null;
winform = _forms[hwnd];
}
return winform
}
/**intellisense(win.form)
getForm(__/*控件或窗口句柄*/) = 返回指向或包含句柄指向窗口的form对象
end intellisense**/
/*默认消息处理函数defaultProc{{*/
var defaultProc = {
[ 0x113/*_WM_TIMER*/ ] = function(this,hwnd, message, wparam, lparam){
var proc = this._tTimeProc[wparam];
if( proc ){
var ret = proc(hwnd,message,wparam,this._tTimeTicks[wparam] )
if( (ret !== null) && ( ret!== true ) ){
var tick = tonumber(ret)
if( !tick ){
this.killtimer(wparam)//移除此定时器
}
else {
this.settimer(wparam,tick)//重新设定时间间隔
}
}
}
}
[0x14/*_WM_ERASEBKGND*/] = function(this,hwnd, message, wparam, lparam){
var rc = this[["cachClientRect"]]; //获取新的窗口区域
if(! rc ){
rc = this.clientRect;
this[["cachClientRect"]] = rc;
}
var hdc = topointer(wparam);
var erase = 0;
if( type(this[["bgcolor"]] ) == type.number && (this[["bgcolor"]]!=-1) ){ //有可能为0 - 黑色,因为0为false,因此改用类型判断
var bgbrush = ::CreateSolidBrush( this[["bgcolor"]] );
var oldbrush = ::SelectObject(hdc,bgbrush );
::PatBlt(hdc,0,0,rc.right - rc.left ,rc.bottom - rc.top,0xF00021/*_PATCOPY*/);
::SelectObject(hdc,oldbrush);
::DeleteObject(bgbrush);
erase = 1;
}
// winform的元表对于不存在的对象会返回一个空的table
if( this[[ "hBkbitmap" ]] ){
var hdcMem = ::CreateCompatibleDC(hdc);
var hBitmapStartScanBAK = ::SelectObject(hdcMem,this.hBkbitmap );
::BitBlt(hdc,0,0,rc.right - rc.left ,rc.bottom - rc.top,hdcMem,0,0, 0xCC0020/*_SRCCOPY*/);
::SelectObject(hdcMem,hBitmapStartScanBAK);
::DeleteDC(hdcMem);
erase = 1;
}
if( erase )
return 1;
};
[0x5/*_WM_SIZE*/] = function(this,hwnd, message, wparam, lparam){
if( hwnd == this.hwnd){ //主窗口
if( ..win.isIconic(hwnd) )
return;
var defDlg = this._defClientRect;
var dlg = this.clientRect;
this.cachClientRect = dlg;
//计算变化的比例
var xRate = (dlg.right-dlg.left)/(defDlg.right-defDlg.left);
var yRate = (dlg.bottom-dlg.top)/(defDlg.bottom-defDlg.top);
var defCtrl;
var l,t,r,b,w,h; //控件左,上,右,下,宽高
for(id,ctrl in this._ctrlId ){
defCtrl = ctrl._defRect;
w = defCtrl.right-defCtrl.left ;
h = defCtrl.bottom -defCtrl.top ;
if( ctrl[["dl"]] )
l = defCtrl.left;
else
l = defCtrl.left * xRate ;
if( ctrl[["dt"]] )
t = defCtrl.top ;
else
t = defCtrl.top * yRate ;
if( ctrl[["dr"]] ) {
r = dlg.right - ( defDlg.right - defCtrl.right) ;
if( ctrl[["aw"]] == false ) && ( ctrl[["dl"]] == false )
l = r - w;
}
else {
if( ctrl[["aw"]] )
r = defCtrl.right * xRate ;
else
r = l+w;
}
if( ctrl[["db"]] ) {
y = dlg.bottom - ( defDlg.bottom - defCtrl.bottom ) ;
if( ( ctrl[["ah"]] == false ) && ( ctrl[["dt"]] == false ) )
t = y - h ;
}
else{
if( ctrl[["ah"]] )
y = defCtrl.bottom * yRate ;
else
y = t + h;
}
var adjust = ctrl[["adjust"]] ;
::MoveWindow( ctrl.hwnd ,l,t, r - l, y - t ,adjust?1:0)
if( type( adjust) == type.function ){
adjust( r - l, y - t); //容器控件
}
}
this.redraw();
if( type( this[["adjust"]] ) == type.function ){
this.adjust( dlg.right-dlg.left,dlg.bottom-dlg.top);
}
}
}
[0x111/*_WM_COMMAND*/] = function(this,hwnd, message, wparam, lparam){
var wmId = ::LOWORD(wparam);
var wmEvent = ::HIWORD(wparam);
if( !lparam ){
var proc = this._menuProc[wmId];
if(type(proc)==type.function)
proc(wmId,wmEvent);
}
else{
var ctrl = this._ctrlId[wmId];
if(ctrl) {
var oncommand = ctrl.oncommand;
if(oncommand)
oncommand(wmId,wmEvent);
}
}
}
[0x004E /*_WM_NOTIFY*/] = function(this,hwnd, message, wparam, lparam){
if(lparam){
wmId = wparam;
var ctrl = this._ctrlId[wmId];
if(ctrl && (ctrl._prenotify || ctrl.onnotify) ){
var nmdr = ..raw.convert(topointer(lparam),NMHDR_L());
if( ctrl._prenotify )
ctrl._prenotify(wmId,nmdr.code,topointer(lparam) )
if( ctrl.onnotify )
ctrl.onnotify(wmId,nmdr.code,topointer(lparam) )
}
}
}
[0x312/*_WM_HOTKEY*/] = function(this,hwnd, message, wparam, lparam){
var id = wparam; //这个是注册的时候设定的ID
if( this[["_hotkeys"]] && ( type( this[["_hotkeys"]][id] ) == type.function ) ){
this[["_hotkeys"]][id] (id,::LOWORD(lparam),::HIWORD(lparam) )
}
}
[0x2/*_WM_DESTROY*/] = function(this,hwnd, message, wparam, lparam){
//删除所有定时器
var tm = this[["_tTimeProc"]]
for(id=1;#tm){
KillTimer(this.hwnd,id);
this[["_tTimeProc"]][id] = null;
this[["_tTimeTicks"]][id] = null;
}
//遍历控件
for(hwnd,ctrl in this._ctrlHwnd){
if( type(ctrl[["brush"]])==type.number){ //删除GDI对象
::DeleteObject( ctrl[["brush"]] );
}
if( ctrl.ondestroy ){
ctrl.ondestroy();
}
}
if( this[["_ondestroy"]] ){
this[["_ondestroy"]] ();
}
if( this[["uniqueId"]] ){
this.atom();//释放实例占用原子
}
this[["continueModal _"]] =null;//退出模态循环
_forms[hwnd] = null;
for(k,v in _forms ){
//只要还有一个窗口存在,就不要退出当前线程
if(type(v)==type.table)
return ::DefWindowProc(hwnd,message,wparam,lparam);
}
..win.quitMessage();
}
[0x138/*_WM_CTLCOLORSTATIC*/ ] = function(this,hwnd, message, wparam, lparam){
var ctrl = this._ctrlHwnd[ lparam ];
var hdc = topointer(wparam)
if( ctrl ){ ;
if( type(ctrl.color)==type.number )
::SetTextColor(hdc,ctrl.color ) ;
if(ctrl.transparent) {
::SetBkMode(hdc,1);
return tonumber( ::GetStockObject(5) );//NULL_BRUSH
}
else if( ( type(ctrl[["bgcolor"]]) == type.number ) && (ctrl[["bgcolor"]]!=-1)) {
//::SetBkMode(hdc,0);
::SetBkColor(hdc,ctrl.bgcolor) ;
ctrl.brush := ::CreateSolidBrush( ctrl.bgcolor ) ;
return ctrl.brush ;//返回值必须与回调函数声明完全一致
}
}
}
}
var onCtlColor = defaultProc[0x138/*_WM_CTLCOLORSTATIC*/ ];
defaultProc[0x133/*_WM_CTLCOLOREDIT*/] = onCtlColor;
defaultProc[0x135/*_WM_CTLCOLORBTN*/] = onCtlColor;
defaultProc[0x134/*_WM_CTLCOLORLISTBOX*/] = onCtlColor;
/*}}*/
_wndproc = function( hwnd, message, wparam , lparam) {
if( owner[["wndproc__"]] ) {
var result = owner[["wndproc__"]]( hwnd, message, wparam , lparam );
if( (result !== null) && ( message!=0x2/*_WM_DESTROY*/) )//用非恒等式来排除0,false等逻辑假的值
return result;
}
var proc = defaultProc[message]
if( proc ){
var result = proc(owner,hwnd,message,wparam,lparam)
if( result !== null )
return result;
}
return ::DefWindowProc(hwnd,message,wparam,lparam);
}
var loopmessage_l = loopMessage
loadForm = function(code,parent){
loopMessage = function(){ }//禁用..win.loopMessage
var f = assert( loadcode(code) );
var ret,wb = f(parent);
loopMessage = loopmessage_l;//恢复..win.loopMessage
return ret,wb;
}
metaProperty = ..win.ui.ctrl.metaProperty(
loadForm = function(path){
return ..win.form.loadForm(path,owner /*指定父窗口*/ );
}
loadcode = function(path){
return owner.loadForm(path)
}
//覆盖父类 ..win.ui.ctrl.metaProperty.common的redraw成员
redraw = function(){
//重绘窗口
if(owner[["menu"]])owner[["menu"]].redraw();
var rc = ::RECT();
::GetClientRect(owner[["hwnd"]],rc);
::InvalidateRect(owner[["hwnd"]],rc,1);
::UpdateWindow(owner[["hwnd"]]);
}
doModal = function(hwndparent){
if(!hwndparent)
hwndparent = owner[["parent"]];
if(type(hwndparent)==type.table)
hwndparent = hwndparent.hwnd;//winform.hwnd
if(hwndparent){
..win.enable(hwndparent,0x0/*_FALSE*/);
}
//设置模态对话框样式
owner.modifyStyle(0,0x80/*_DS_MODALFRAME*/)
::SendMessageInt(owner[["hwnd"]],0x110/*_WM_INITDIALOG*/,0,0);
//模态标记,加上空格等使之成为非法标识符,以避免与控件名字冲突
owner[["continueModal _"]] = true;
//显示窗体
owner.show(true);
//SetForegroundWindow(owner.hwnd);
while(owner[["continueModal _"]])
..win.pumpMessage();
//还原开始被禁用的窗体
if(hwndparent) {//启用父窗体
..win.enable(hwndparent,1/*_TRUE*/);
..win.setForeground(hwndparent)
}
::DestroyWindow(owner[["hwnd"]]);
..win.pumpMessage(); //pump exit message
return owner[["result _"]];
}
endModal = function(result){
owner[["result _"]] = result;
owner[["continueModal _"]] =null;//退出模态循环
}
msgbox = function(str,title = "AAuto" ,style){
..win.msgbox(str,title,style,owner[["hwnd"]] )
}
msgboxTest = function(str,title){
return ..win.msgboxTest(str,title,owner[["hwnd"]] )
}
transparent = function(alpha=128,clr ){
owner.modifyStyleEx(0,0x80000/*_WS_EX_LAYERED*/)
SetLayeredWindowAttributes( owner[["hwnd"]],clr:0, alpha,clr!==null?1:2)
}
image = {
_get = function(){
return owner[["image__"]];
}
_set = function( v ){
if(type(v)==type.string ){
v = ..string.trim( v );
if(v!=""){
owner[["image__"]] = v;
if( owner[["hBkbitmap"]] )
::DeleteObject( owner[["hBkbitmap"]] )
if( ! owner[["bgcolor"]] )
owner[["bgcolor"]] = ::GetSysColor(0xF/*_COLOR_BTNFACE*/);
var pic = ..win.ole.image.load(v)
owner[["hBkbitmap"]] = topointer(pic.CopyHandle());
..com.Release(pic);
}
}
else if(v===null){
if(owner[["hBkbitmap"]])
::DeleteObject( tonumber( owner[["hBkbitmap"]] ) )
owner[["image__"]] = null;
}
}
};
//无边框窗体支持
hitCaption = function () {
::PostMessage( owner.hwnd, 0xA1/*_WM_NCLBUTTONDOWN*/ , 0x2/*_HTCAPTION*/, 0 );
};
hitTopleft = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF004/*_SC_SIZE | _WMSZ_TOPLEFT*/,0xD/*_HTTOPLEFT*/)
};
hitTop = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF003 ,0xC/*_HTTOP*/)
};
hitTopright = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF005,0xE/*_HTTOPRIGHT*/)
};
hitLeft = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF001,0xA/*_HTLEFT*/)
};
hitRight = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF002,0xB/*_HTRIGHT*/)
};
hitBottomleft = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF007,0x10/*_HTBOTTOMLEFT*/)
};
hitBottom = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF006,0xF/*_HTBOTTOM*/)
};
hitBottomright = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF008,0x11/*_HTBOTTOMRIGHT*/)
};
hitmin = function () {
::PostMessage(owner.hwnd, 0x112/*_WM_SYSCOMMAND*/,0xF020/*_SC_MINIMIZE*/, 0);
};
hitmax = function(){
var zoomed = ..win.isZoomed(owner.hwnd);
if(zoomed)
::PostMessage(owner.hwnd, 0x112/*_WM_SYSCOMMAND*/,0xF120/*_SC_RESTORE*/, 0);
else
::PostMessage(owner.hwnd, 0x112/*_WM_SYSCOMMAND*/,0xF030/*_SC_MAXIMIZE*/,0);
return !zoomed;
}
)
}
import win.gdi;
namespace win;
//下面两个函数是保护成员,禁止外部直接调用
var SetTimer = ::User32.api("SetTimer","INT(int hWnd,INT nIDEvent,INT uElapse,pointer lpTimerFunc)");
var KillTimer = ::User32.api("KillTimer","int(int hWnd,INT nIDEvent)");
var cyborder = ::GetSystemMetrics( 0x6/*_SM_CYBORDER*/ );
var cxborder = ::GetSystemMetrics( 0x5/*_SM_CXBORDER*/ );
var cycaption = ::GetSystemMetrics( 0x4/*_SM_CYCAPTION*/ );
::Shell32 := ..raw.loadDll("Shell32")
var DragQueryFile = ::Shell32.api("DragQueryFile","INT(int hDrop, INT iFile,str& lpszFile,INT cch)");
var DragFinish = ::Shell32.api("DragFinish","INT(int hDrop)");
//接收拖放文件名
getDropFile = function(wparam){
var re = DragQueryFile(wparam,0xFFFFFFFF,0x104/*_MAX_PATH*/,0x104/*_MAX_PATH*/);
var file = {};
for(i=1;re)
re,file[i] = DragQueryFile(wparam,i-1,0x104/*_MAX_PATH*/,0x104/*_MAX_PATH*/);
DragFinish( wparam );
return file;
}
/**intellisense(win)
getDropFile(wparam) = 用于消息回调函数中获取拖放文件列表
end intellisense**/
try{
uxTheme = ..raw.loadDll("UxTheme.dll")
SetWindowTheme = uxTheme.api("SetWindowTheme","void(int hwnd,string pszSubAppName,string pszSubIdList)" )
//SetWindowTheme(控件句柄," "," ")
}
catch(e){
}
ui.NMHDR = class {
int hwndFrom;
INT idFrom;
INT code; // NM_ code
}
var NMHDR_L = ui.NMHDR;
/**intellisense()
!nmhdl.hwndFrom = 发送消息的控件句柄
!nmhdl.idFrom = 发送消息的控件ID
!nmhdl.code = 通知代码
?.ui.NMHDR = !nmhdl.
end intellisense**/
var io = ..io;
var raw = ..raw;
var hInstance = ::GetModuleHandle(null);
class form{
//form类构造函数
ctor( tparam ) begin
this.hInstance = hInstance;
var wndclass = ::WNDCLASSEX();
tparam.cls := "AAU_FORM"
tparam.cls = ..string.format("%s[TID:%d]",tparam.cls , ..thread.getId() )
if(not ::GetClassInfo(this.hInstance,tparam.cls,wndclass) ) {
//创建一个新的窗口类
wndclass = ::WNDCLASSEX();
wndclass.hInstance= hInstance ;
wndclass.lpszClassName=tparam.cls;
wndclass.hIcon = ::LoadIcon(this.hInstance, topointer(130) );
wndclass.hIconSm = ::LoadIcon(this.hInstance, topointer(130) );
wndclass.hCursor = ::LoadCursor(null, topointer(0x7F00/*_IDC_ARROW*/) );
wndclass.hbrBackground = topointer(0xF/*_COLOR_BTNFACE*/ + 1) //::GetStockObject(_HOLLOW_BRUSH);
wndclass.lpfnWndProc = ::DefWindowProc;
assert( RegisterClassEx( wndclass) , ..lasterr() )
}
//创建窗口之前,不允许tvalue修改t,l,r,b位置参数,以避免容器内控件错位
if(tparam.left===null)
tparam.left= -1;
if(tparam.top===null)
tparam.top= -1;
//自定义控件
if( tparam.tvalue ){
for(k,v in tparam.tvalue){
if(tparam[k]===null){ //不允许自定义控件重写的属性,请写在这段代码前面,例如cls
tparam[k] = v;
}
}
}
else {
tparam.id = 0;
}
tparam.exstyle := 0
tparam.style := 0
//生成窗口扩展样式
//---------------------------------
//初始化为组合扩展样式
select( tparam.exmode ) {
case "toolwindow" {
tparam.exstyle |= 0x80/*_WS_EX_TOOLWINDOW*/;
}
case "none" {
tparam.exstyle |= 0;
}
else {
tparam.exstyle |= 0x40000/*_WS_EX_APPWINDOW*/;
}
}
if(tparam.acceptfiles)
tparam.exstyle |= 0x10/*_WS_EX_ACCEPTFILES*/
if(tparam.frame)
tparam.exstyle |= 0x1/*_WS_EX_DLGMODALFRAME*/
if(tparam.cp)
tparam.exstyle |= 0x10000/*_WS_EX_CONTROLPARENT*/
if(tparam.topmost)
tparam.exstyle |= 0x8/*_WS_EX_TOPMOST*/
//生成窗口样式
//---------------------------------
//初始化为组合样式
select( tparam.mode ) {
case "child" {
tparam.style |= 0x40000000/*_WS_CHILD*/
}
case "popup" {
tparam.style |= 0x80000000/*_WS_POPUP*/ ;
}
else {
tparam.style |= 0x0/*_WS_OVERLAPPED*/;
}
}
//如果窗口标题为空,则自动禁用标题栏,系统菜单
if(! (#(tparam.text)) ){
tparam.title = false;
//tparam.sysmenu = false;
}
if(tparam.title === false ) //无标题栏时不能应用_WS_OVERLAPPED样式
tparam.style := 0x80000000/*_WS_POPUP*/
//边框样式
var cyborder = CY_BORDER
var cxborder = CX_BORDER
var cycaption = CY_CAPTION
//WS_CAPTION 实际上是 _WS_BORDER 与 _WS_DLGFRAME组合而成
var deltitle = ~0xC00000/*_WS_CAPTION*/;
select( tparam.border ) {
case "resizable" {
tparam.style |= 0x40000/*_WS_SIZEBOX*/;
}
case "thin" {
tparam.style |= 0x800000/*_WS_BORDER*/;
deltitle = ~0x400000/*_WS_DLGFRAME*/;
}
case "none" {
//无边框窗口
cyborder = 0;
cxborder = 0;
//取消默认的 0x0/*_WS_OVERLAPPED* 样式
tparam.style := 0x80000000/*_WS_POPUP*/
tparam.style &= ~ 0x800000/*_WS_BORDER*/;
tparam.title = false;
}
else {
tparam.style |= 0x400000/*_WS_DLGFRAME*/;
deltitle = ~0x800000/*_WS_BORDER*/;
}
}
if(tparam.title===false) {
tparam.style &= deltitle //避免去掉标题栏时覆盖了边框设置
cycaption = 0; //如果没有标题栏,则要去掉标题栏的高度
}
else{
tparam.style |= 0xC00000/*_WS_CAPTION*/
}
if(tparam.max!==false)
tparam.style |= 0x10000/*_WS_MAXIMIZEBOX*/
else
tparam.style &= ~0x10000/*_WS_MAXIMIZEBOX*/
if(tparam.min!==false)
tparam.style |= 0x20000/*_WS_MINIMIZEBOX*/
else
tparam.style &= ~0x20000/*_WS_MINIMIZEBOX*/
if(tparam.sysmenu!==false) {
tparam.style |= 0x80000/*_WS_SYSMENU*/
}
else {
tparam.style &= ~0x80000/*_WS_SYSMENU*/
}
if( tparam.maxmize ){
tparam.style |= 0x1000000/*_WS_MAXIMIZE*/;
}
if( tparam.minmize ){
tparam.style |= 0x20000000/*_WS_MINIMIZE*/
}
this@ = metaProperty
//如果用户设置了背景图片
this.image = tparam.image
if( ( type( tparam.parent) == type.table ) ){
this.parent = tparam.parent;
tparam.parent = tparam.parent.hwnd;
}
if( type( tparam.parent ) != type.number )
tparam.parent = 0;
//计算窗体宽、高
var cx = tparam.right - tparam.left + (cxborder*2) ;
var cy = tparam.bottom - tparam.top + (cyborder*2) + cycaption;
var x = tparam.left ;
//如果为负数,计算默认坐标
if(x==-1){
var sx = ::GetSystemMetrics(0x0/*_SM_CXSCREEN*/) ;
if(sx>cx)
x = (sx-cx)/2;
else
x = 0; //0x80000000/*_CW_USEDEFAULT*/
}
var y = tparam.top ;
//如果为负数,计算默认坐标
if(y==-1){
var sy = ::GetSystemMetrics(0x1/*_SM_CYSCREEN*/ ) ;
if(sy>cy)
y = (sy-cy)/2;
else
y = 0; //0x80000000/*_CW_USEDEFAULT*/
}
//创建主窗口
this.hwnd = ::CreateWindowEx(
tparam.exstyle,
tparam.cls,
tparam.text,
tparam.style , //窗口风格
x,//x
y,//y
cx,//w
cy,//h
tparam.parent,//parent
tparam.id,//menu
hInstance,
null//param
);
//记录窗口大小
this._defClientRect = ::RECT( 0, 0, tparam.right - tparam.left, tparam.bottom - tparam.top);
this.font = LOGFONT( );//设置字体
//不要清除设置图片时设定的默认背景色
if( tparam.bgcolor)
this[["bgcolor"]] = tparam.bgcolor;
this[["scroll"]] = tparam.scroll;
this._wndproc_c = raw.tostdcall( _wndproc, ..win.CALLBACK.WNDPROC,this/*设为owner对象*/)
::SetWindowPointer(this.hwnd,0xFFFFFFFC/*_GWL_WNDPROC*/, this._wndproc_c);
_forms[this.hwnd] = this;
..win.closed = null;//通知所有消息函数,窗体正在运行
end;
_ctrlId = {};//控件ID映射关系
_ctrlHwnd = {};//控件句柄映射关系
_menuProc = { freeId = 5000 };
add = function( tparam ) begin
var zorder = {}
for name,tvalue in tparam{
for(i=1;#zorder;1){
if( zorder[i][2].z > tvalue.z ) {
..table.insert( zorder,{name;tvalue} , i)
continue 2;
}
}
..table.push( zorder,{name;tvalue} );
}
var ctrl;
for(i=1;#zorder ){
var name = zorder[i][1];
var opt = zorder[i][2];
//创建控件
opt.parent = this;
if(!opt.id) //允许显示指定控件ID
opt.id = #this._ctrlId + 1;
opt.hInstance = this.hInstance;
ctrl = ctrl_factory.create(opt);
if(!ctrl)continue ;
this[name] = ctrl;
this._ctrlId[opt.id] = ctrl
ctrl[["id"]] = opt.id;
ctrl[["parent"]] = this;
//创建控件窗口
if( !ctrl.hwnd ){
//如果不是自定义控件
ctrl.hwnd = ::CreateWindowEx (opt.exstyle, opt.cls , opt.text , opt.style ,opt.left,opt.top,opt.right - opt.left , opt.bottom - opt.top,
this.hwnd , opt.id , opt.hInstance )
}
else{
..win.setPos(ctrl.hwnd,opt.left,opt.top,opt.right - opt.left , opt.bottom - opt.top);
}
//记录所有子控件的窗口句柄
this._ctrlHwnd[ctrl.hwnd] = ctrl
//初始化控件
ctrl_factory.onCreateComplete(ctrl);
}
end;
_tTimeProc = {};//定时回调函数
_tTimeTicks = {};//定时器时间间隔
addtimer = function(elapse,func){
var freeId = #this[["_tTimeProc"]] + 1;
..table.push( this[["_tTimeProc"]] ,func);
this[["_tTimeTicks"]][freeId] = elapse;
SetTimer(this.hwnd,freeId,elapse);
return freeId;
}
settimer = function(id,elapse,func){
if( this[["_tTimeProc"]][id] ){
SetTimer(this.hwnd,id,elapse )
this[["_tTimeTicks"]][id] = elapse;
if( func ){
this[["_tTimeProc"]][id] =func;
}
return true;
}
}
killtimer = function(id){
if( this[["_tTimeProc"]][id] ){
KillTimer(this.hwnd,id);
..table.remove( this[["_tTimeProc"]],id);
..table.remove( this[["_tTimeProc"]],id);
return true;
}
}
setTimeout = function(code,elapse=100,...){
if( type(code)==type.string ) {
code,err = loadcode(code)
if(!code)error(err,2)
}
var args = {...}
return this.addtimer ( elapse,
function(hwnd,msg,id){
this.killtimer(id)
code( ..table.unpack(args) );
}
)
}
reghotkey = function( func , mod,vk ){
if(! this[["_hotkeys"]] ) this[["_hotkeys"]] = {};
var id = ..table.push( this[["_hotkeys"]] ,func); //保存回调函数
RegisterHotKey(this.hwnd,id,mod,vk);
return id;
}
unreghotkey = function(idEvent){
UnregisterHotKey(this.hwnd,idEvent);
..table.remove( this[["_hotkeys"]],idEvent);
}
pretranslate = false; //避免触发元表
}
namespace form{
ctrl_factory = ..win.ui.ctrl.factory
/*intellisense(win.form)*/
RegisterHotKey = ::User32.api("RegisterHotKey","int(int hwnd,int id,int fsModifiers,int vk)")
UnregisterHotKey = ::User32.api("UnregisterHotKey","Long(int hwnd,int id)")
SetLayeredWindowAttributes = ::User32.api("SetLayeredWindowAttributes","int(int hwnd,int crKey,BYTE bAlpha,INT dwFlags)");
DefWindowProc = User32.api( "DefWindowProc", "int(int hWnd,INT msg,int wparam,int lParam) " )
RegisterClassEx = User32.api( "RegisterClassEx", " word(struct lpWndClass) " )
GetClassInfo = User32.api( "GetClassInfoA", "int(pointer hInstance,string lpClassName,struct &lpWndClass)" )
WNDCLASSEX = class{
INT cbSize = 48;
INT style = 0x2 | 0x1 | 0x8;//_CS_HREDRAW | _CS_VREDRAW | _CS_DBLCLKS;
pointer lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
pointer hInstance;
pointer hIcon;
pointer hCursor;
pointer hbrBackground;
string lpszMenuName;
string lpszClassName;
pointer hIconSm;
}
CY_BORDER = ::GetSystemMetrics( 0x6/*_SM_CYBORDER*/ );
CX_BORDER = ::GetSystemMetrics( 0x5/*_SM_CXBORDER*/ );
CY_CAPTION = ::GetSystemMetrics( 0x4/*_SM_CYCAPTION*/ );
/*end intellisense*/
//记录所有win.form对象,创建则添加此表,销毁则从表中移除
_forms = {}
getForm = function(hwnd){
var winform = _forms[hwnd];
while(!winform){
hwnd = ..win.getParent(hwnd);
if(!hwnd)
return null;
winform = _forms[hwnd];
}
return winform
}
/**intellisense(win.form)
getForm(__/*控件或窗口句柄*/) = 返回指向或包含句柄指向窗口的form对象
end intellisense**/
/*默认消息处理函数defaultProc{{*/
var defaultProc = {
[ 0x113/*_WM_TIMER*/ ] = function(this,hwnd, message, wparam, lparam){
var proc = this._tTimeProc[wparam];
if( proc ){
var ret = proc(hwnd,message,wparam,this._tTimeTicks[wparam] )
if( (ret !== null) && ( ret!== true ) ){
var tick = tonumber(ret)
if( !tick ){
this.killtimer(wparam)//移除此定时器
}
else {
this.settimer(wparam,tick)//重新设定时间间隔
}
}
}
}
[0x14/*_WM_ERASEBKGND*/] = function(this,hwnd, message, wparam, lparam){
var rc = this[["cachClientRect"]]; //获取新的窗口区域
if(! rc ){
rc = this.clientRect;
this[["cachClientRect"]] = rc;
}
var hdc = topointer(wparam);
var erase = 0;
if( type(this[["bgcolor"]] ) == type.number && (this[["bgcolor"]]!=-1) ){ //有可能为0 - 黑色,因为0为false,因此改用类型判断
var bgbrush = ::CreateSolidBrush( this[["bgcolor"]] );
var oldbrush = ::SelectObject(hdc,bgbrush );
::PatBlt(hdc,0,0,rc.right - rc.left ,rc.bottom - rc.top,0xF00021/*_PATCOPY*/);
::SelectObject(hdc,oldbrush);
::DeleteObject(bgbrush);
erase = 1;
}
// winform的元表对于不存在的对象会返回一个空的table
if( this[[ "hBkbitmap" ]] ){
var hdcMem = ::CreateCompatibleDC(hdc);
var hBitmapStartScanBAK = ::SelectObject(hdcMem,this.hBkbitmap );
::BitBlt(hdc,0,0,rc.right - rc.left ,rc.bottom - rc.top,hdcMem,0,0, 0xCC0020/*_SRCCOPY*/);
::SelectObject(hdcMem,hBitmapStartScanBAK);
::DeleteDC(hdcMem);
erase = 1;
}
if( erase )
return 1;
};
[0x5/*_WM_SIZE*/] = function(this,hwnd, message, wparam, lparam){
if( hwnd == this.hwnd){ //主窗口
if( ..win.isIconic(hwnd) )
return;
var defDlg = this._defClientRect;
var dlg = this.clientRect;
this.cachClientRect = dlg;
//计算变化的比例
var xRate = (dlg.right-dlg.left)/(defDlg.right-defDlg.left);
var yRate = (dlg.bottom-dlg.top)/(defDlg.bottom-defDlg.top);
var defCtrl;
var l,t,r,b,w,h; //控件左,上,右,下,宽高
for(id,ctrl in this._ctrlId ){
defCtrl = ctrl._defRect;
w = defCtrl.right-defCtrl.left ;
h = defCtrl.bottom -defCtrl.top ;
if( ctrl[["dl"]] )
l = defCtrl.left;
else
l = defCtrl.left * xRate ;
if( ctrl[["dt"]] )
t = defCtrl.top ;
else
t = defCtrl.top * yRate ;
if( ctrl[["dr"]] ) {
r = dlg.right - ( defDlg.right - defCtrl.right) ;
if( ctrl[["aw"]] == false ) && ( ctrl[["dl"]] == false )
l = r - w;
}
else {
if( ctrl[["aw"]] )
r = defCtrl.right * xRate ;
else
r = l+w;
}
if( ctrl[["db"]] ) {
y = dlg.bottom - ( defDlg.bottom - defCtrl.bottom ) ;
if( ( ctrl[["ah"]] == false ) && ( ctrl[["dt"]] == false ) )
t = y - h ;
}
else{
if( ctrl[["ah"]] )
y = defCtrl.bottom * yRate ;
else
y = t + h;
}
var adjust = ctrl[["adjust"]] ;
::MoveWindow( ctrl.hwnd ,l,t, r - l, y - t ,adjust?1:0)
if( type( adjust) == type.function ){
adjust( r - l, y - t); //容器控件
}
}
this.redraw();
if( type( this[["adjust"]] ) == type.function ){
this.adjust( dlg.right-dlg.left,dlg.bottom-dlg.top);
}
}
}
[0x111/*_WM_COMMAND*/] = function(this,hwnd, message, wparam, lparam){
var wmId = ::LOWORD(wparam);
var wmEvent = ::HIWORD(wparam);
if( !lparam ){
var proc = this._menuProc[wmId];
if(type(proc)==type.function)
proc(wmId,wmEvent);
}
else{
var ctrl = this._ctrlId[wmId];
if(ctrl) {
var oncommand = ctrl.oncommand;
if(oncommand)
oncommand(wmId,wmEvent);
}
}
}
[0x004E /*_WM_NOTIFY*/] = function(this,hwnd, message, wparam, lparam){
if(lparam){
wmId = wparam;
var ctrl = this._ctrlId[wmId];
if(ctrl && (ctrl._prenotify || ctrl.onnotify) ){
var nmdr = ..raw.convert(topointer(lparam),NMHDR_L());
if( ctrl._prenotify )
ctrl._prenotify(wmId,nmdr.code,topointer(lparam) )
if( ctrl.onnotify )
ctrl.onnotify(wmId,nmdr.code,topointer(lparam) )
}
}
}
[0x312/*_WM_HOTKEY*/] = function(this,hwnd, message, wparam, lparam){
var id = wparam; //这个是注册的时候设定的ID
if( this[["_hotkeys"]] && ( type( this[["_hotkeys"]][id] ) == type.function ) ){
this[["_hotkeys"]][id] (id,::LOWORD(lparam),::HIWORD(lparam) )
}
}
[0x2/*_WM_DESTROY*/] = function(this,hwnd, message, wparam, lparam){
//删除所有定时器
var tm = this[["_tTimeProc"]]
for(id=1;#tm){
KillTimer(this.hwnd,id);
this[["_tTimeProc"]][id] = null;
this[["_tTimeTicks"]][id] = null;
}
//遍历控件
for(hwnd,ctrl in this._ctrlHwnd){
if( type(ctrl[["brush"]])==type.number){ //删除GDI对象
::DeleteObject( ctrl[["brush"]] );
}
if( ctrl.ondestroy ){
ctrl.ondestroy();
}
}
if( this[["_ondestroy"]] ){
this[["_ondestroy"]] ();
}
if( this[["uniqueId"]] ){
this.atom();//释放实例占用原子
}
this[["continueModal _"]] =null;//退出模态循环
_forms[hwnd] = null;
for(k,v in _forms ){
//只要还有一个窗口存在,就不要退出当前线程
if(type(v)==type.table)
return ::DefWindowProc(hwnd,message,wparam,lparam);
}
..win.quitMessage();
}
[0x138/*_WM_CTLCOLORSTATIC*/ ] = function(this,hwnd, message, wparam, lparam){
var ctrl = this._ctrlHwnd[ lparam ];
var hdc = topointer(wparam)
if( ctrl ){ ;
if( type(ctrl.color)==type.number )
::SetTextColor(hdc,ctrl.color ) ;
if(ctrl.transparent) {
::SetBkMode(hdc,1);
return tonumber( ::GetStockObject(5) );//NULL_BRUSH
}
else if( ( type(ctrl[["bgcolor"]]) == type.number ) && (ctrl[["bgcolor"]]!=-1)) {
//::SetBkMode(hdc,0);
::SetBkColor(hdc,ctrl.bgcolor) ;
ctrl.brush := ::CreateSolidBrush( ctrl.bgcolor ) ;
return ctrl.brush ;//返回值必须与回调函数声明完全一致
}
}
}
}
var onCtlColor = defaultProc[0x138/*_WM_CTLCOLORSTATIC*/ ];
defaultProc[0x133/*_WM_CTLCOLOREDIT*/] = onCtlColor;
defaultProc[0x135/*_WM_CTLCOLORBTN*/] = onCtlColor;
defaultProc[0x134/*_WM_CTLCOLORLISTBOX*/] = onCtlColor;
/*}}*/
_wndproc = function( hwnd, message, wparam , lparam) {
if( owner[["wndproc__"]] ) {
var result = owner[["wndproc__"]]( hwnd, message, wparam , lparam );
if( (result !== null) && ( message!=0x2/*_WM_DESTROY*/) )//用非恒等式来排除0,false等逻辑假的值
return result;
}
var proc = defaultProc[message]
if( proc ){
var result = proc(owner,hwnd,message,wparam,lparam)
if( result !== null )
return result;
}
return ::DefWindowProc(hwnd,message,wparam,lparam);
}
var loopmessage_l = loopMessage
loadForm = function(code,parent){
loopMessage = function(){ }//禁用..win.loopMessage
var f = assert( loadcode(code) );
var ret,wb = f(parent);
loopMessage = loopmessage_l;//恢复..win.loopMessage
return ret,wb;
}
metaProperty = ..win.ui.ctrl.metaProperty(
loadForm = function(path){
return ..win.form.loadForm(path,owner /*指定父窗口*/ );
}
loadcode = function(path){
return owner.loadForm(path)
}
//覆盖父类 ..win.ui.ctrl.metaProperty.common的redraw成员
redraw = function(){
//重绘窗口
if(owner[["menu"]])owner[["menu"]].redraw();
var rc = ::RECT();
::GetClientRect(owner[["hwnd"]],rc);
::InvalidateRect(owner[["hwnd"]],rc,1);
::UpdateWindow(owner[["hwnd"]]);
}
doModal = function(hwndparent){
if(!hwndparent)
hwndparent = owner[["parent"]];
if(type(hwndparent)==type.table)
hwndparent = hwndparent.hwnd;//winform.hwnd
if(hwndparent){
..win.enable(hwndparent,0x0/*_FALSE*/);
}
//设置模态对话框样式
owner.modifyStyle(0,0x80/*_DS_MODALFRAME*/)
::SendMessageInt(owner[["hwnd"]],0x110/*_WM_INITDIALOG*/,0,0);
//模态标记,加上空格等使之成为非法标识符,以避免与控件名字冲突
owner[["continueModal _"]] = true;
//显示窗体
owner.show(true);
//SetForegroundWindow(owner.hwnd);
while(owner[["continueModal _"]])
..win.pumpMessage();
//还原开始被禁用的窗体
if(hwndparent) {//启用父窗体
..win.enable(hwndparent,1/*_TRUE*/);
..win.setForeground(hwndparent)
}
::DestroyWindow(owner[["hwnd"]]);
..win.pumpMessage(); //pump exit message
return owner[["result _"]];
}
endModal = function(result){
owner[["result _"]] = result;
owner[["continueModal _"]] =null;//退出模态循环
}
msgbox = function(str,title = "AAuto" ,style){
..win.msgbox(str,title,style,owner[["hwnd"]] )
}
msgboxTest = function(str,title){
return ..win.msgboxTest(str,title,owner[["hwnd"]] )
}
transparent = function(alpha=128,clr ){
owner.modifyStyleEx(0,0x80000/*_WS_EX_LAYERED*/)
SetLayeredWindowAttributes( owner[["hwnd"]],clr:0, alpha,clr!==null?1:2)
}
image = {
_get = function(){
return owner[["image__"]];
}
_set = function( v ){
if(type(v)==type.string ){
v = ..string.trim( v );
if(v!=""){
owner[["image__"]] = v;
if( owner[["hBkbitmap"]] )
::DeleteObject( owner[["hBkbitmap"]] )
if( ! owner[["bgcolor"]] )
owner[["bgcolor"]] = ::GetSysColor(0xF/*_COLOR_BTNFACE*/);
var pic = ..win.ole.image.load(v)
owner[["hBkbitmap"]] = topointer(pic.CopyHandle());
..com.Release(pic);
}
}
else if(v===null){
if(owner[["hBkbitmap"]])
::DeleteObject( tonumber( owner[["hBkbitmap"]] ) )
owner[["image__"]] = null;
}
}
};
//无边框窗体支持
hitCaption = function () {
::PostMessage( owner.hwnd, 0xA1/*_WM_NCLBUTTONDOWN*/ , 0x2/*_HTCAPTION*/, 0 );
};
hitTopleft = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF004/*_SC_SIZE | _WMSZ_TOPLEFT*/,0xD/*_HTTOPLEFT*/)
};
hitTop = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF003 ,0xC/*_HTTOP*/)
};
hitTopright = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF005,0xE/*_HTTOPRIGHT*/)
};
hitLeft = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF001,0xA/*_HTLEFT*/)
};
hitRight = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF002,0xB/*_HTRIGHT*/)
};
hitBottomleft = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF007,0x10/*_HTBOTTOMLEFT*/)
};
hitBottom = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF006,0xF/*_HTBOTTOM*/)
};
hitBottomright = function () {
::SendMessageInt( owner.hwnd, 0x112/*_WM_SYSCOMMAND*/, 0xF008,0x11/*_HTBOTTOMRIGHT*/)
};
hitmin = function () {
::PostMessage(owner.hwnd, 0x112/*_WM_SYSCOMMAND*/,0xF020/*_SC_MINIMIZE*/, 0);
};
hitmax = function(){
var zoomed = ..win.isZoomed(owner.hwnd);
if(zoomed)
::PostMessage(owner.hwnd, 0x112/*_WM_SYSCOMMAND*/,0xF120/*_SC_RESTORE*/, 0);
else
::PostMessage(owner.hwnd, 0x112/*_WM_SYSCOMMAND*/,0xF030/*_SC_MAXIMIZE*/,0);
return !zoomed;
}
)
}
//控件管理 win.ui.ctrl
import win.ole.image
import win.ui.ctrl.common;
import win.ui.ctrl.metaProperty;
import win.ui.ctrl.button;
namespace win.ui.ctrl;
//以下控件的库名与控件类名必须相同,发布时将从下面排除未使用的控件库
/*OPT_IMPORT{{*/
import win.ui.ctrl.static;
import win.ui.ctrl.picturebox;
import win.ui.ctrl.edit;
import win.ui.ctrl.richedit;
import win.ui.ctrl.combobox;
import win.ui.ctrl.listbox;
import win.ui.ctrl.tab;
import win.ui.ctrl.progress;
import win.ui.ctrl.datetimepick;
import win.ui.ctrl.hotkey;
import win.ui.ctrl.listview;
import win.ui.ctrl.checklist;
import win.ui.ctrl.trackbar;
import win.ui.ctrl.custom;
/*}}*/
//控件工厂
namespace factory{
create = function(tvalue){
//必须是子窗口
tvalue.exstyle := 0;
tvalue.style := 0x40000000/*_WS_CHILD*/
tvalue.style |= 0x40000000/*_WS_CHILD*/ ;
//获取通用的样式
if( tvalue.group ) tvalue.style |= 0x20000/*_WS_GROUP*/
if( tvalue.tabstop )tvalue.style |= 0x10000/*_WS_TABSTOP*/
if( !tvalue.hide )tvalue.style |= 0x10000000/*_WS_VISIBLE*/ ;
if( tvalue.disabled )tvalue.style |= 0x8000000/*_WS_DISABLED*/
if( tvalue.hscroll )tvalue.style |= 0x100000/*_WS_HSCROLL*/
if( tvalue.vscroll )tvalue.style |= 0x200000/*_WS_VSCROLL*/
if( tvalue.border )tvalue.style |= 0x800000/*_WS_BORDER*/
if(tvalue.frame)tvalue.exstyle |= 0x1/*_WS_EX_DLGMODALFRAME*/
if(tvalue.acceptfiles)tvalue.exstyle |= 0x10/*_WS_EX_ACCEPTFILES*/
if(tvalue.cp)tvalue.exstyle |= 0x10000/*_WS_EX_CONTROLPARENT*/
tvalue.cls = ..string.lower( tvalue.cls )
tvalue.cls_ = tvalue.cls;//记录友好类名
//创建控件,并在每个构造函数中对tvalue进行一些预处理,例如修改radiobutton类名为button,visible等属性更换为样式
var cls = ..win.ui.ctrl[tvalue.cls];
if(cls){
var obj = cls(tvalue.parent,tvalue);
obj.tparam = tvalue;
return obj;
}
}
onCreateComplete = function(obj){
var tvalue = obj.tparam;
obj.tparam = null;
//记录控件窗口原始大小(以计算自动调整的比例)
obj._defRect = ::RECT( tvalue.left,tvalue.top,tvalue.right,tvalue.bottom);
//去掉CreateWindowEx创建窗口时已经用到的属性
//tvalue.cls = null;
tvalue.style = null;
tvalue.left = null;
tvalue.right = null;
tvalue.top = null;
tvalue.bottom = null;
tvalue.hide = null;
tvalue.disabled = null;
tvalue.exstyle = null;
//首先设置字体
tvalue.font := LOGFONT( );
obj.font = tvalue.font;
tvalue.font = null;
//必须在设置其他属性以前调用初始化函数
var oncreate = obj[["oncreate"]];
if( oncreate ){ oncreate() }
//初始化窗口的其他属性
for(k,v in tvalue){
obj[k] = v;
}
tvalue.cls = tvalue.cls_ //恢复友好类名
}
}
/**intellisense()
_NM_FIRST=@0x0/*_NM_FIRST*/
_NM_LAST=@0xFFFFFF9D/*_NM_LAST*/
_NM_OUTOFMEMORY=@0xFFFFFFFF/*_NM_OUTOFMEMORY*/
_NM_CLICK=@0xFFFFFFFE/*_NM_CLICK*/
_NM_DBLCLK=@0xFFFFFFFD/*_NM_DBLCLK*/
_NM_RETURN=@0xFFFFFFFC/*_NM_RETURN*/
_NM_RCLICK=@0xFFFFFFFB/*_NM_RCLICK*/
_NM_RDBLCLK=@0xFFFFFFFA/*_NM_RDBLCLK*/
_NM_SETFOCUS=@0xFFFFFFF9/*_NM_SETFOCUS*/
_NM_KILLFOCUS=@0xFFFFFFF8/*_NM_KILLFOCUS*/
_NM_CUSTOMDRAW=@0xFFFFFFF4/*_NM_CUSTOMDRAW*/
_NM_HOVER=@0xFFFFFFF3/*_NM_HOVER*/
_NM_NCHITTEST=@0xFFFFFFF2/*_NM_NCHITTEST*/
_NM_KEYDOWN=@0xFFFFFFF1/*_NM_KEYDOWN*/
_NM_RELEASEDCAPTURE=@0xFFFFFFF0/*_NM_RELEASEDCAPTURE*/
_NM_SETCURSOR=@0xFFFFFFEF/*_NM_SETCURSOR*/
_NM_CHAR=@0xFFFFFFEE/*_NM_CHAR*/
_NM_TOOLTIPSCREATED=@0xFFFFFFED/*_NM_TOOLTIPSCREATED*/
_NM_LDOWN=@0xFFFFFFEC/*_NM_LDOWN*/
_NM_RDOWN=@0xFFFFFFEB/*_NM_RDOWN*/
_NM_THEMECHANGED=@0xFFFFFFEA/*_NM_THEMECHANGED*/
_NM_FONTCHANGED=@0xFFFFFFE9/*_NM_FONTCHANGED*/
_NM_CUSTOMTEXT=@0xFFFFFFE8/*_NM_CUSTOMTEXT*/
_NM_TVSTATEIMAGECHANGING=@0xFFFFFFE8/*_NM_TVSTATEIMAGECHANGING*/
end intellisense**/
import win.ui.ctrl.common;
import win.ui.ctrl.metaProperty;
import win.ui.ctrl.button;
namespace win.ui.ctrl;
//以下控件的库名与控件类名必须相同,发布时将从下面排除未使用的控件库
/*OPT_IMPORT{{*/
import win.ui.ctrl.static;
import win.ui.ctrl.picturebox;
import win.ui.ctrl.edit;
import win.ui.ctrl.richedit;
import win.ui.ctrl.combobox;
import win.ui.ctrl.listbox;
import win.ui.ctrl.tab;
import win.ui.ctrl.progress;
import win.ui.ctrl.datetimepick;
import win.ui.ctrl.hotkey;
import win.ui.ctrl.listview;
import win.ui.ctrl.checklist;
import win.ui.ctrl.trackbar;
import win.ui.ctrl.custom;
/*}}*/
//控件工厂
namespace factory{
create = function(tvalue){
//必须是子窗口
tvalue.exstyle := 0;
tvalue.style := 0x40000000/*_WS_CHILD*/
tvalue.style |= 0x40000000/*_WS_CHILD*/ ;
//获取通用的样式
if( tvalue.group ) tvalue.style |= 0x20000/*_WS_GROUP*/
if( tvalue.tabstop )tvalue.style |= 0x10000/*_WS_TABSTOP*/
if( !tvalue.hide )tvalue.style |= 0x10000000/*_WS_VISIBLE*/ ;
if( tvalue.disabled )tvalue.style |= 0x8000000/*_WS_DISABLED*/
if( tvalue.hscroll )tvalue.style |= 0x100000/*_WS_HSCROLL*/
if( tvalue.vscroll )tvalue.style |= 0x200000/*_WS_VSCROLL*/
if( tvalue.border )tvalue.style |= 0x800000/*_WS_BORDER*/
if(tvalue.frame)tvalue.exstyle |= 0x1/*_WS_EX_DLGMODALFRAME*/
if(tvalue.acceptfiles)tvalue.exstyle |= 0x10/*_WS_EX_ACCEPTFILES*/
if(tvalue.cp)tvalue.exstyle |= 0x10000/*_WS_EX_CONTROLPARENT*/
tvalue.cls = ..string.lower( tvalue.cls )
tvalue.cls_ = tvalue.cls;//记录友好类名
//创建控件,并在每个构造函数中对tvalue进行一些预处理,例如修改radiobutton类名为button,visible等属性更换为样式
var cls = ..win.ui.ctrl[tvalue.cls];
if(cls){
var obj = cls(tvalue.parent,tvalue);
obj.tparam = tvalue;
return obj;
}
}
onCreateComplete = function(obj){
var tvalue = obj.tparam;
obj.tparam = null;
//记录控件窗口原始大小(以计算自动调整的比例)
obj._defRect = ::RECT( tvalue.left,tvalue.top,tvalue.right,tvalue.bottom);
//去掉CreateWindowEx创建窗口时已经用到的属性
//tvalue.cls = null;
tvalue.style = null;
tvalue.left = null;
tvalue.right = null;
tvalue.top = null;
tvalue.bottom = null;
tvalue.hide = null;
tvalue.disabled = null;
tvalue.exstyle = null;
//首先设置字体
tvalue.font := LOGFONT( );
obj.font = tvalue.font;
tvalue.font = null;
//必须在设置其他属性以前调用初始化函数
var oncreate = obj[["oncreate"]];
if( oncreate ){ oncreate() }
//初始化窗口的其他属性
for(k,v in tvalue){
obj[k] = v;
}
tvalue.cls = tvalue.cls_ //恢复友好类名
}
}
/**intellisense()
_NM_FIRST=@0x0/*_NM_FIRST*/
_NM_LAST=@0xFFFFFF9D/*_NM_LAST*/
_NM_OUTOFMEMORY=@0xFFFFFFFF/*_NM_OUTOFMEMORY*/
_NM_CLICK=@0xFFFFFFFE/*_NM_CLICK*/
_NM_DBLCLK=@0xFFFFFFFD/*_NM_DBLCLK*/
_NM_RETURN=@0xFFFFFFFC/*_NM_RETURN*/
_NM_RCLICK=@0xFFFFFFFB/*_NM_RCLICK*/
_NM_RDBLCLK=@0xFFFFFFFA/*_NM_RDBLCLK*/
_NM_SETFOCUS=@0xFFFFFFF9/*_NM_SETFOCUS*/
_NM_KILLFOCUS=@0xFFFFFFF8/*_NM_KILLFOCUS*/
_NM_CUSTOMDRAW=@0xFFFFFFF4/*_NM_CUSTOMDRAW*/
_NM_HOVER=@0xFFFFFFF3/*_NM_HOVER*/
_NM_NCHITTEST=@0xFFFFFFF2/*_NM_NCHITTEST*/
_NM_KEYDOWN=@0xFFFFFFF1/*_NM_KEYDOWN*/
_NM_RELEASEDCAPTURE=@0xFFFFFFF0/*_NM_RELEASEDCAPTURE*/
_NM_SETCURSOR=@0xFFFFFFEF/*_NM_SETCURSOR*/
_NM_CHAR=@0xFFFFFFEE/*_NM_CHAR*/
_NM_TOOLTIPSCREATED=@0xFFFFFFED/*_NM_TOOLTIPSCREATED*/
_NM_LDOWN=@0xFFFFFFEC/*_NM_LDOWN*/
_NM_RDOWN=@0xFFFFFFEB/*_NM_RDOWN*/
_NM_THEMECHANGED=@0xFFFFFFEA/*_NM_THEMECHANGED*/
_NM_FONTCHANGED=@0xFFFFFFE9/*_NM_FONTCHANGED*/
_NM_CUSTOMTEXT=@0xFFFFFFE8/*_NM_CUSTOMTEXT*/
_NM_TVSTATEIMAGECHANGING=@0xFFFFFFE8/*_NM_TVSTATEIMAGECHANGING*/
end intellisense**/
//控件元属性 win.ui.ctrl.metaProperty
import util.metaProperty;
namespace win.ui.ctrl;
metaProperty = class {
ctor( meta ){
this = ..util.metaProperty(meta);
}
@metaPrototype //公用属性
}
namespace metaProperty {
commonProperty = {
redraw = function( flag = 0x105 /*_RDW_INVALIDATE | _RDW_UPDATENOW | _RDW_ERASE*/ ) {
::RedrawWindow(owner[["hwnd"]],{},null,flag);
};
invalidate = function(rc,erase=1){
rc := {}
var hwnd = rc.hwnd;
if(hwnd)
rc = ..win.getRect(hwnd);
::InvalidateRect(owner.hwnd,rc,erase?1:0);
}
update = function(){
::UpdateWindow(owner[["hwnd"]])
}
capture = {
_set = function( v ){
if(v)
SetCapture(owner[["hwnd"]])
else
ReleaseCapture();
}
};
text = {
_get = function(){
return ..win.getText( owner[["hwnd"]] );
}
_set = function(v){
..win.setText( owner[["hwnd"]],tostring(v) );
if(owner[["transparent"]]){
owner[["parent"]].invalidate(owner,1);
owner[["parent"]].update();
}
}
}
hide = {
_get = function(){
return ! ..win.getStyle(owner[["hwnd"]],0x10000000/*_WS_VISIBLE*/ )
}
_set = function(v){
owner.show(!v ? true:0x0/*_SW_HIDE*/)
}
};
close = function(){
::SendMessage(owner[["hwnd"]] ,0x10/*_WM_CLOSE*/ );
}
modifyStyle = function(remove=0,add=0,flags){
return ..win.modifyStyle(owner[["hwnd"]],remove,add,flags);
}
modifyStyleEx = function(remove=0,add=0,flags){
return ..win.modifyStyleEx(owner[["hwnd"]],remove,add,flags);
}
show = function(flag=true) {
..win.show(owner[["hwnd"]],flag);
}
disabled = {
_get = function(){
return ..win.getStyle(owner[["hwnd"]],0x8000000/*_WS_DISABLED*/ )
}
_set = function(v){
..win.enable(owner[["hwnd"]],!v?1:0);
}
};
wndproc = {
_set = function(v){
//Remove All
if( v === null){
owner[["wndproc__"]] = null;
return;
};
assert(type(v) == type.function,"消息回调函数必须是一个函数对象!")
var preProc = owner[["wndproc__"]];
if(preProc){
//Decorate the previous WndProc
owner[["wndproc__"]] = function(...){
var ret = v(...);
if(ret===null)
return preProc(...);
return ret;
}
return;
}
owner[["wndproc__"]] = v;
//真正的回调函数只能创建一次
if(owner[["_wndproc_c"]] )
return;
var _defwndpoc_c = 0;
var wndproc = function(hwnd, message, wParam , lParam){
var result;
var proc = owner[["wndproc__"]];
if(proc)
result = proc( hwnd, message, wParam , lParam);
if( result === null ){ //必须用恒等式才能判断是否有返回值(包括false,0等)
return ::CallWindowProc( _defwndpoc_c, hwnd,message, wParam , lParam );
}
return result;//用户函数中返回了自定义的值
}
owner[["_wndproc_c"]] = ..raw.tostdcall( wndproc , ..win.CALLBACK.WNDPROC,owner)
_defwndpoc_c= ::SetWindowPointer(owner[["hwnd"]],0xFFFFFFFC/*_GWL_WNDPROC*/, owner[["_wndproc_c"]] );
}
};
rect = {
_get = function(){
return ..win.getRect( owner.hwnd );
}
_set = function(v){
if( v[["left"]]===null )
error("参数必须是正确的:;RECT结构体",2)
..win.setRect(owner.hwnd,v)
}
};
clientRect = {
_get = function(){
return ..win.getClientRect(owner.hwnd)
}
};
left = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.left;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( v,rc.top);
}
};
right = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.right;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( , ,v - rc.left,rc.bottom-rc.top);
}
};
top = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.top;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( rc.left,v);
}
};
bottom = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.bottom;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( , ,rc.right - rc.left,v-rc.top);
}
};
getPos = function(){
return ..win.getPos(owner.hwnd)
}
setPos = function(...){
var defRc = owner[["_defCtrlRect"]];
if( defRc){
var rc = owner.rect;
xr = rc.left / defRc.left;
tr = rc.top / defRc.top;
rr = rc.right / defRc.right;
br = rc.bottom / defRc.bottom;
..win.setPos(owner.hwnd,...)
var rc2 = owner.rect;
defRc.left = rc2.left / xr;
defRc.top = rc2.top / tr;
defRc.right = rc2.right / rr;
defRc.bottom = rc2.bottom / br;
}
else
..win.setPos(owner.hwnd,...)
}
setFocus = function(){
..win.setFocus(owner.hwnd)
}
vScroll = function(pos = 0x7/*_SB_BOTTOM*/){
::SendMessageInt(owner[["hwnd"]],0x115/*_WM_VSCROLL*/ , pos, 0);
}
hScroll = function(pos = 0x7/*_SB_RIGHT*/ ){
::SendMessageInt(owner[["hwnd"]],0x114/*_WM_HSCROLL*/ , pos, 0);
}
font = {
_get = function(){
}
_set = function(v){
..win.gdi.setfont( owner[["hwnd"]],v );
}
};
theme = {
_get = function(){
}
_set = function(v){
if(..win.SetWindowTheme){
if(v === true )
v = "Explorer";
var subid = " ";
if(v)subid=null;
..win.SetWindowTheme(owner[["hwnd"]],v:" ",subid);
}
}
};
}
metaPrototype = { _get = commonProperty };
SetCapture = ::User32.api("SetCapture", "void(int hwnd)");
ReleaseCapture = User32.api("ReleaseCapture", "void()");
}
/**intellisense(win.ui.ctrl)
metaProperty = 属性元表
metaProperty(__) = @.metaProperty(\n\n 属性 = {\n _get = function(){ \n /*读取属性代码写在这里*/\n return null;\n }\n _set = function( v ){\n /*写入属性代码写在这里*/\n ..io.print( owner,v)\n } \n };\n)
end intellisense**/
namespace win.ui.ctrl;
metaProperty = class {
ctor( meta ){
this = ..util.metaProperty(meta);
}
@metaPrototype //公用属性
}
namespace metaProperty {
commonProperty = {
redraw = function( flag = 0x105 /*_RDW_INVALIDATE | _RDW_UPDATENOW | _RDW_ERASE*/ ) {
::RedrawWindow(owner[["hwnd"]],{},null,flag);
};
invalidate = function(rc,erase=1){
rc := {}
var hwnd = rc.hwnd;
if(hwnd)
rc = ..win.getRect(hwnd);
::InvalidateRect(owner.hwnd,rc,erase?1:0);
}
update = function(){
::UpdateWindow(owner[["hwnd"]])
}
capture = {
_set = function( v ){
if(v)
SetCapture(owner[["hwnd"]])
else
ReleaseCapture();
}
};
text = {
_get = function(){
return ..win.getText( owner[["hwnd"]] );
}
_set = function(v){
..win.setText( owner[["hwnd"]],tostring(v) );
if(owner[["transparent"]]){
owner[["parent"]].invalidate(owner,1);
owner[["parent"]].update();
}
}
}
hide = {
_get = function(){
return ! ..win.getStyle(owner[["hwnd"]],0x10000000/*_WS_VISIBLE*/ )
}
_set = function(v){
owner.show(!v ? true:0x0/*_SW_HIDE*/)
}
};
close = function(){
::SendMessage(owner[["hwnd"]] ,0x10/*_WM_CLOSE*/ );
}
modifyStyle = function(remove=0,add=0,flags){
return ..win.modifyStyle(owner[["hwnd"]],remove,add,flags);
}
modifyStyleEx = function(remove=0,add=0,flags){
return ..win.modifyStyleEx(owner[["hwnd"]],remove,add,flags);
}
show = function(flag=true) {
..win.show(owner[["hwnd"]],flag);
}
disabled = {
_get = function(){
return ..win.getStyle(owner[["hwnd"]],0x8000000/*_WS_DISABLED*/ )
}
_set = function(v){
..win.enable(owner[["hwnd"]],!v?1:0);
}
};
wndproc = {
_set = function(v){
//Remove All
if( v === null){
owner[["wndproc__"]] = null;
return;
};
assert(type(v) == type.function,"消息回调函数必须是一个函数对象!")
var preProc = owner[["wndproc__"]];
if(preProc){
//Decorate the previous WndProc
owner[["wndproc__"]] = function(...){
var ret = v(...);
if(ret===null)
return preProc(...);
return ret;
}
return;
}
owner[["wndproc__"]] = v;
//真正的回调函数只能创建一次
if(owner[["_wndproc_c"]] )
return;
var _defwndpoc_c = 0;
var wndproc = function(hwnd, message, wParam , lParam){
var result;
var proc = owner[["wndproc__"]];
if(proc)
result = proc( hwnd, message, wParam , lParam);
if( result === null ){ //必须用恒等式才能判断是否有返回值(包括false,0等)
return ::CallWindowProc( _defwndpoc_c, hwnd,message, wParam , lParam );
}
return result;//用户函数中返回了自定义的值
}
owner[["_wndproc_c"]] = ..raw.tostdcall( wndproc , ..win.CALLBACK.WNDPROC,owner)
_defwndpoc_c= ::SetWindowPointer(owner[["hwnd"]],0xFFFFFFFC/*_GWL_WNDPROC*/, owner[["_wndproc_c"]] );
}
};
rect = {
_get = function(){
return ..win.getRect( owner.hwnd );
}
_set = function(v){
if( v[["left"]]===null )
error("参数必须是正确的:;RECT结构体",2)
..win.setRect(owner.hwnd,v)
}
};
clientRect = {
_get = function(){
return ..win.getClientRect(owner.hwnd)
}
};
left = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.left;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( v,rc.top);
}
};
right = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.right;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( , ,v - rc.left,rc.bottom-rc.top);
}
};
top = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.top;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( rc.left,v);
}
};
bottom = {
_get = function(){
var rc = ..win.getRect( owner.hwnd )
return rc.bottom;
}
_set = function(v){
var rc = ..win.getRect( owner.hwnd )
owner.setPos( , ,rc.right - rc.left,v-rc.top);
}
};
getPos = function(){
return ..win.getPos(owner.hwnd)
}
setPos = function(...){
var defRc = owner[["_defCtrlRect"]];
if( defRc){
var rc = owner.rect;
xr = rc.left / defRc.left;
tr = rc.top / defRc.top;
rr = rc.right / defRc.right;
br = rc.bottom / defRc.bottom;
..win.setPos(owner.hwnd,...)
var rc2 = owner.rect;
defRc.left = rc2.left / xr;
defRc.top = rc2.top / tr;
defRc.right = rc2.right / rr;
defRc.bottom = rc2.bottom / br;
}
else
..win.setPos(owner.hwnd,...)
}
setFocus = function(){
..win.setFocus(owner.hwnd)
}
vScroll = function(pos = 0x7/*_SB_BOTTOM*/){
::SendMessageInt(owner[["hwnd"]],0x115/*_WM_VSCROLL*/ , pos, 0);
}
hScroll = function(pos = 0x7/*_SB_RIGHT*/ ){
::SendMessageInt(owner[["hwnd"]],0x114/*_WM_HSCROLL*/ , pos, 0);
}
font = {
_get = function(){
}
_set = function(v){
..win.gdi.setfont( owner[["hwnd"]],v );
}
};
theme = {
_get = function(){
}
_set = function(v){
if(..win.SetWindowTheme){
if(v === true )
v = "Explorer";
var subid = " ";
if(v)subid=null;
..win.SetWindowTheme(owner[["hwnd"]],v:" ",subid);
}
}
};
}
metaPrototype = { _get = commonProperty };
SetCapture = ::User32.api("SetCapture", "void(int hwnd)");
ReleaseCapture = User32.api("ReleaseCapture", "void()");
}
/**intellisense(win.ui.ctrl)
metaProperty = 属性元表
metaProperty(__) = @.metaProperty(\n\n 属性 = {\n _get = function(){ \n /*读取属性代码写在这里*/\n return null;\n }\n _set = function( v ){\n /*写入属性代码写在这里*/\n ..io.print( owner,v)\n } \n };\n)
end intellisense**/
浙公网安备 33010602011771号