Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4775187
  • 博文数量: 206
  • 博客积分: 5240
  • 博客等级: 大校
  • 技术积分: 3224
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-12 21:40
文章分类

全部博文(206)

文章存档

2013年(13)

2012年(8)

2011年(33)

2010年(152)

我的朋友

分类:

2011-04-30 02:53:25

//外部进程窗口操作
namespace winex;
import win; //winex基于win库扩展,重用普通窗口操作模块
 
//AllowSetForegroundWindow := ::User32.api( "AllowSetForegroundWindow", "int(INT dwProcessId)" ) 

AttachThreadInput := ::User32.api( 
"AttachThreadInput""int(INT idAttach,INT idAttachTo,int fAttach)" )  
EnumWindows := User32.api( 
"EnumWindows""int(POINTER lpEnumFunc ,int lParam )" )
EnumChildWindows := User32.api( 
"EnumChildWindows""int(int hWndParent,POINTER lpEnumFunc ,int lParam )" ) 
isUnicode := User32.api( 
"IsWindowUnicode""int(int hwnd)" )

/**intellisense(winex)
isUnicode(__/*窗口句柄*/) = 判断窗口是否Unicode窗口
end intellisense**/



var getWindow = win.GetWindow;
match = 
function(hwnd,text,cls,id){ 

    
if( cls  ){ 
        
ifnot ..string.find( win.getClass(hwnd), cls ) ) {
            
return false;  
        }
    }

    
if( text ) {  
        
ifnot  ..string.find( win.getText(hwnd,30/*不要取太长的标题*/),text ) ){ 
            
return false;
        } 
    }
    
    
if( id ) { 
        
if( win.getId(hwnd) != id) { 
            
return false;  
        }
    }
    
    
return true;
}

//枚举所有子窗口 - 深度递归遍历
var enumWindows
enumWindows=
function( onfind, parent, cls ,text, id,depth  ){   
    
//取到第一个子窗口
    var next = getWindow( parent ,0x5/*_GW_CHILD*/ ) ;
    
if(!next)
        
return;
    
    
    
do{
        
sleep(0);   
        
        
if( enumWindows( onfind, next, cls ,text, id ,depth+1 ) === false )
            
return;
         
        
do{
        
            
if( ! match(next,text,cls,id ) )
                
break;
            
            
if( onfind( next,depth ) === false )
                
return false;
        
        }
while(0) 
        
         
        next = getWindow( next ,0x2
/*_GW_HWNDNEXT*/ )
        
    }
while( next  )
}

enum = 
function( onfind, parent, cls ,text, id  ){
    parent := ..win.getDesktop(); 
    enumWindows(onfind, parent, cls ,text, id,2)
}
 
function enumTop( onfind ) {  
    
// 须是一个字符串
    assert( where===null || type(where) == type.string ,"查询条件必须是字符串")
 
    
var EnumwndProc = function( hwnd,lparam ){ 
                    
        
if( onfind( hwnd ) === false)
            
return 0;
        
else
            
return 1 ;  
    } 
    
    pEnumwndProc = ..raw.tostdcall(EnumwndProc,
"int(int hwnd,int lparam )"/* ,{ tag='crane' }  */ ); 
    EnumWindows(pEnumwndProc ,0); 
//回调函数声明了_topointer无方法,因此可以自动转换为pointer指针
    pEnumwndProc = null;//确认不会再用到的回调函数,可以显示声明为null进行释放 
    
}


/**intellisense(winex)
enum(onfind,parent)=@.enum( \n  function(hwnd,depth){\n     ..io.print( depth/*深度*/,hwnd/*窗口*/,win.getText(hwnd)/*标题*/ )\n        /*return false*/\n  } \n    ,__/*输入父窗口*/\n ,要查找的类名\n ,要查找的标题\n ,要查找的控件ID\n)
enum(onfind)=@.enum( \n function(hwnd,depth){\n     ..io.print( depth/*深度*/,hwnd/*窗口*/,win.getText(hwnd)/*标题*/ )\n        /*return false*/\n  } \n)
enumTop=@.enumTop(\n    function(hwnd){\n       ..io.print(hwnd)\n  }\n)\n//枚举桌面顶层窗口;
end intellisense**/



//迭代指定父窗口的子级窗口 - 广度迭代遍历
function each( mcls,mtitle,parent ) {
    parent := ..win.getDesktop(); 
    
    
return function(hwnd) { //接收for循环传递的参数得到迭代器控制变量  
        var title;
        
        
do{
            hwnd = getWindow( hwnd  ,0x2
/*_GW_HWNDNEXT*/ );
            
if(!hwnd)
                
return null;
            
            
if( ! match(hwnd,mtitle,mcls ) )
                
continue
            
            
if(!title)
                title = ..win.getText(hwnd); 
                
            
return hwnd,title,  ..win.getThreadProcessId(hwnd); 
        
            
        }
while(1) 
       
    } , , getWindow( parent ,0x5
/*_GW_CHILD*/ ) ;



/**intellisense(winex) 
each("类名","查找标题") =  @for hwnd,title,theadId,processId in winex.each( "", ".*__/*请输入标题包含字符串\n可使用模式匹配语法*/" ) { \n//遍历所有进窗口\n \n}
each() =  @for hwnd,title,theadId,processId in winex.each( __/*无参数则返回桌面所有顶层窗口\n可在此输入标题包含字符串\n可使用模式匹配语法*/ ) { \n//遍历所有进窗口\n    \n}
each("类名","查找标题",父窗口) =  @for hwnd,title,theadId,processId in winex.each("",__/*请输入父窗口句柄*/) { \n//遍历所有进窗口\n \n}
end intellisense**/

 
//模糊匹配查找顶层窗口,可选参数(类名,标题,进程ID,线程ID)
find = function(cls,title,pid,tid){
    
for hwnd,title,theadId,processId in  each( cls,title ) { 
        
if( pid ){
            
if( pid != processId )
                
continue;
        }
        
if( tid ){
            
if( tid != theadId )
                
continue;
        } 
        
return hwnd,theadId,processId
    } 
}

findEx = 
function(parent,count,cls ,text, id  ){
    
var count2=0;
    
var result;
    
    enum( 
        
function( hwndfind,depth ){
            result = hwndfind; 
            
if( count ){
                count2++;
                
if( count2 < count ) 
                    
return true//接着找 
            }
            
return false;//停止查找
            
        } 
        ,parent
        ,cls
        ,text
        ,id
    )
    
    
return result;
}
 
findExists = 
function(title,text,cls,ctrlcls,ctrlid){ 
    
    
if( text || ctrlcls || ctrlid ) {
        
var ctrl;
        
for parent,title,theadId,processId in  each( cls,title ) { 
            ctrl = findEx( parent,
null,ctrlcls ,text, ctrlid ) 
            
if( ctrl )
                
return parent,ctrl,theadId,processId
        } 
    }
    
else {
        parent,theadId,processId = find(cls,title);
        
return parent, ,theadId,processId;
    }
    


findActivate = 
function(title,text,cls,ctrlcls,ctrlid){
    parent,ctrl,theadId,processId = findExists(title,text,cls,ctrlcls,ctrlid);
    
if(parent){  
        ..win.setForeground(parent)
        
sleep(1)
    }
    
return parent,ctrl,theadId,processId;
}

waitTimeout = 
null;
waitDelay = 100;
wait = 
function( title,text,cls,ctrlcls,ctrlid){
    
var tk = ..time.tick();
    
var parent,ctrl,theadId,processId ;
    
var fctrl = text || ctrlcls || ctrlid;
    
    
while(!parent){
         
         
if(fctrl)
            parent,ctrl,theadId,processId = findExists(title,text,cls,ctrlcls,ctrlid)
         
else
            parent,theadId,processId = find(cls,title)
         
         
if( waitTimeout ){
            
if( ..time.tick() - tk > waitTimeout ){
                
return parent,ctrl,theadId,processId
            }
         }
         
sleep(0)
         ..win.delay(waitDelay)
    }
    
return parent,ctrl,theadId,processId;
}

waitClose = 
function( title,text,cls,ctrlcls,ctrlid){
    
var tk = ..time.tick(); 
    
var waitfunc = type(title)==type.number? ..win.isWindow : findExists
    
while( waitfunc(title,text,cls,ctrlcls,ctrlid) ){ 
    
         
if( waitTimeout ){
            
if( ..time.tick() - tk > waitTimeout ){
                
return false
            }
         }
         
sleep(0)
         ..win.delay(waitDelay)
    }
    
return true;
}


waitActive = 
function( title,text,cls,ctrlcls,ctrlid){
    
var tk = ..time.tick(); 
    
var hwnd = type(title)==type.number ? title;
    
var f;
    
while( 1 ){
        f = ..win.getForeground();
        
if( hwnd ){
            
if(hwnd == f )
                
return f;
        }
        
else {
            
if( match(f,title,cls ) ){
                
var ctrl = findEx(f,null,ctrlcls ,text, ctrlid  )
                
if(  ctrl )
                    
return f,ctrl,..win.getThreadProcessId(f);
            }
        }
        
        
if( waitTimeout ){
            
if( ..time.tick() - tk > waitTimeout ){
                
return;
            }
         }
         
sleep(0)
         ..win.delay(waitDelay)
    }
      
}

//MenuItemFromPoint = ::User32.api("MenuItemFromPoint","int(int hWnd,int hMenu,int x,int y)")

//叶级子窗口
fromPoint= User32.api("WindowFromPoint""int(int x, int y)");
 
//叶级子窗口,并穿透groupbox 
fromPointReal = function(x,y){
    
var hwnd = fromPoint(x,y);
    
if(hwnd){
        
var parent = ..win.getParent(hwnd);
        
if(parent)
            hwnd= fromClientPointReal(parent,
                ..win.toClient(parent,x,y) );
    }
    
return hwnd;
}

//子窗口,而非叶级窗口
var childWindowFromPointEx = User32.api("ChildWindowFromPointEx","int(int hwnd,int x,int y,INT flags)")
fromClientPoint = 
function(hwnd,x,y,un=0x0001/*_CWP_SKIPINVISIBLE*/){ 
    
return childWindowFromPointEx(hwnd,x,y,un);


//子窗口,而非叶级窗口,穿透groupbox
fromClientPointReal = User32.api("RealChildWindowFromPoint","int(int hwnd,int x,int y )")


attachThread = 
function(tid,att = true){
    
var cid = ..thread.getId(); 
    
if(tid==cid)
        
return att;
        
    
return AttachThreadInput(tid, cid, att?1:0)
}

attach = 
function(hwnd,att = true){
    
if(!hwnd)
        
error("无效的窗口句柄",2)
    
var tid,pid = ..win.getThreadProcessId(hwnd); // 当前窗口的线程ID  
    return attachThread(tid,att);
}

getFocus = 
function(hwnd){
    hwnd := win.getForeground();
    
if(type(hwnd)!=type.number)
        
error("错误的句柄",2)
    
var tid,pid = ..win.getThreadProcessId(hwnd); // 当前窗口的线程ID  
    var cid = ..thread.getId();
    
    
var hwndChildAfter = ..win.findEx(hwnd,0);
    
if(hwndChildAfter){ 
        
if(tid == cid ) 
            
return ..win.getFocus(),cid,pid; 
        
else if(  AttachThreadInput(tid, cid, 1)) {
            
var hCtrl = ..win.getFocus();
            AttachThreadInput(tid, cid, 0);
            
return hCtrl,tid,pid;
        } 
    }
    
else
        
return hwnd,tid,pid;
    

 

/**intellisense(winex) 
match(.(句柄,文本,类名,ID) = 指定一个窗口句柄,检测是否符合给定参数\n所有参数可选,类名与文本支持模式表达式
find(.(类名模式串,标题模式串,进程ID,线程ID)=查找顶层窗口,所有参数都是可选参数\n返回值为:句柄,线程ID,进程ID
findEx(.(父窗口句柄,返回第几个匹配句柄,类名模式串 ,标题模式串, 控件ID )=查找子窗口,除父窗口句柄外所有参数可选\n返回值为句柄
findExists(.(父窗口标题,控件文本,父窗口类名,控件类名,控件ID) = 查找包含指定控件窗口的父窗口,所有参数可选\n返回值为:窗口句柄,控件句柄,线程ID,进程ID
findActivate(.(父窗口标题,控件文本,父窗口类名,控件类名,控件ID) = 调用winex.findExists查找并激活包含指定控件窗口的父窗口,所有参数可选\n返回值为:窗口句柄,控件句柄,线程ID,进程ID
wait(.(父窗口标题,控件文本,父窗口类名,控件类名,控件ID) = 等待指定窗口创建,所有参数可选\n成功返回窗口句柄,控件句柄,线程ID,进程ID,超时返回空值
waitClose(.(父窗口标题,控件文本,父窗口类名,控件类名,控件ID) = 等待指定窗口关闭,所有参数可选\n成功返回true,超时返回false
waitClose(窗口句柄) = 等待指定窗口关闭,所有参数可选\n成功返回true,超时返回false
waitActive(.(父窗口标题,控件文本,父窗口类名,控件类名,控件ID) = 等待指定窗口激话,所有参数可选\n成功返回窗口句柄,控件句柄,线程ID,进程ID,超时返回false
waitActive(窗口句柄) = 等待指定窗口激话,所有参数可选\n成功返回窗口句柄,超时返回false
waitTimeout = 指定winex库所有wait前缀的等待函数的默认超时值\n以毫秒为单位,默认为null表示永不超时.
waitDelay = 指定winex库所有wait前缀的等待函数的的检测时间间隔;\n以毫秒为单位,默认为100毫秒

fromPoint(.(x坐标,y坐标)=从指定的屏幕坐标查找窗口\n获取叶级子窗口。
fromPointReal(.(x坐标,y坐标)=从指定的屏幕坐标查找窗口\n获取叶级子窗口,穿透groupbox。
fromClientPoint(.(窗口句柄,x坐标,y坐标) = 从指定的窗口坐标查找子窗口\n仅子窗口,非叶级窗口
fromClientPoint(.(窗口句柄,x坐标,y坐标,_CWP_ALL) = 从指定的窗口坐标查找子窗口\n_CWP_ALL指定包含隐藏、禁用控件
fromClientPointReal(.(窗口句柄,x坐标,y坐标) = 从指定的窗口坐标查找子窗口\n仅子窗口,非叶级窗口,穿透groupbox。 
attach(__/*窗口句柄*/) = 附加到输入线程\n返回值为是否成功附加
attach(__/*窗口句柄*/,false) = 解除附加\n返回值为是否成功解除
attachThread(__/*线程ID*/) = 附加到输入线程\n返回值为是否成功附加
attachThread(__/*线程ID*/,false) = 解除附加\n返回值为是否成功解除
getFocus(__/*输入父窗口句柄*/)=获取输指定窗口输入焦点所在的控件句柄
getFocus()=获取前台窗口、输入焦点所在的控件句柄
end intellisense**/

 
say2  = 
function(str,hwnd){ 
    
//注入对方进程,并发送文本
    hwnd = getFocus(hwnd); 
    
    
for(i=1;#str ) {  
        
//双字节字符
        if(str[i]>0x80){
            ::PostMessage(hwnd, 0x102
/*_WM_CHAR*/,  (  ( ( str[i+1] << 8) | str[i]  ) ) , 1); 
            i++
        }
        
else 
            ::PostMessage(hwnd, 0x102
/*_WM_CHAR*/,  str[i] , 1); 
    } 
    ..win.delay(1) 
}

sayIme = 
function(str,hwnd){
    hwnd = getFocus(hwnd); 
    
for(i=1;#str ) {  
        
//双字节字符
        if(str[i]>0x80){
            ::PostMessage(hwnd, 0x286
/*_WM_IME_CHAR*/,  (  ( ( str[i] << 8) | str[i+1]  ) ) , 1); 
            i++
        }
        
else 
            ::PostMessage(hwnd, 0x286
/*_WM_IME_CHAR*/,  str[i] , 1); 
    }  
    ..win.delay(1) 
}


say = 
function(str,hwnd){
    
//自动发送文本
    hwnd = getFocus(hwnd); 
    
if(  ..win.isWindow(hwnd) ){   
        
for(i=1;#str) { 
            
//这里如果用SendMessage,就发不出字体 
            ::PostMessage(hwnd, 0x102/*_WM_CHAR*/, str[i] & 0xFF, 0x0001); 
        }  
    }
    ..win.delay(1) 
}

sendString = 
function(str,hwnd){
    
//自动发送文本
    hwnd = getFocus(hwnd);

    
if(  ..win.isWindow(hwnd) ) {
        ::SendMessage(hwnd,0xC2
/*_EM_REPLACESEL*/,null,str);  
    }
}

click = 
function( hwnd,cmdid ){
   
if( ! cmdid )  
        ::PostMessage(hwnd, 0xf5
/*_BM_CLICK*/, 0, 0) 
   
else  
        ::PostMessage(hwnd, 0x111
/*_WM_COMMAND*/,cmdid ,0);
}

quit = 
function(hwnd){
    ::PostThreadMessage(win.getThreadProcessId(hwnd),0x12
/*_WM_QUIT*/ ,0,0);
}

close = 
function(hwnd){ 
    ::PostMessage(hwnd,0x10
/*_WM_CLOSE*/,0,0);


setText = 
function(hwnd,str){
    ::SendMessage(hwnd,0xC
/*_WM_SETTEXT*/,,str);
}

//菜单函数 
GetMenu = ::User32.api("GetMenu","int(int hwnd)")
GetSubMenu = User32.api(
"GetSubMenu","int(int hMenu,int nPos)");
GetMenuItemID = User32.api(
"GetMenuItemID","INT(int hMenu,int nPos)"); 
GetMenuItemCount = User32.api(
"GetMenuItemCount","int(int hMenu)");
GetMenuString = User32.api(
"GetMenuStringA","int(int hMenu,int wIDItem,string& lpString,int nMaxCount,int wFlag)")

MENU_ITEM_IS_SUBMENU = 0xFFFFFFFF
findMenu = 
function(target_window,...) { 
    lables = {...}
    
    
var hMenu = GetMenu(target_window); 
    
if (!hMenu)  
        
return 0;

    
ifnot #lables )
        
return hMenu;


    
var menuId = MENU_ITEM_IS_SUBMENU;
    
var itmeCount = GetMenuItemCount(hMenu); 
    
if (itmeCount < 1)  
        
return;  
 
    
var hMenuFind;
    onFindSubMenu = 
function( menu_pos ){ 
        
        menuId = GetMenuItemID(hMenu, menu_pos); 
     
        
if (menuId == MENU_ITEM_IS_SUBMENU) {
            hMenu = GetSubMenu(hMenu, menu_pos);
            itmeCount = GetMenuItemCount(hMenu); 
            hMenuFind = hMenu;
        }
        
else { 
            itmeCount = 0; 
            hMenu = 
null
        }
    }
 
    
for(i=1;#lables ) {
        
if (!hMenu)  
            
return;   
    
        
iftype(lables[i])==type.number ){ 
            
if ( (lables[i] <= -1) || ( lables[i] >= itmeCount) )  
                
return;  
            
            onFindSubMenu(lables[i])

        }
        
else if(type(lables[i])==type.string) {
            
for(pos=0;itmeCount-1){
                
var len, target= GetMenuString(hMenu, pos, 1024, 1024-1, 0x400/*_MF_BYPOSITION*/);
                
                
ifnot  ..string.find( lables[i],"\&" ) )
                    target = ..string.replace(target,
"\&","");
                
                
if( ..string.find( target,lables[i] ) ){
                    onFindSubMenu(pos)
                    
break;
                }
                
                
            }  
            
        }  
        
else
            
return ;
    }  

    
if (menuId == MENU_ITEM_IS_SUBMENU) 
        
return hMenuFind;   
    
else
        
return hMenuFind,menuId 
 

}

/**intellisense(winex)
findMenu(.(窗口句柄,"子菜单标题",或子菜单序号,.....) = 例如:\nhmenu,menuid = winex.findMenu(hwnd ,"文件","另存为"  )
click(.(窗口句柄,命令ID) = 模拟点击命令
click(.(按钮窗口句柄) = 模拟点击按钮
sendString("") = 向前台窗口的文本框发送文本
sendString("",__/*输入窗口句柄*/) = 向指定窗口上的文本框发送文本
say("") = 向前台窗口的文本框发送文本
say("",__/*输入窗口句柄*/) = 向指定窗口上的文本框发送文本
say2("") = 向前台窗口的文本框发送文本
say2("",__/*输入窗口句柄*/) = 向指定窗口上的文本框发送文本
sayIme("") = 向前台窗口的文本框发送文本\n使用_WM_IME_CHAR消息
sayIme("",__/*输入窗口句柄*/) = 向指定窗口上的文本框发送文本\n使用_WM_IME_CHAR消息
quit(__/*输入窗口句柄*/) = 退出程序(WM_QUIT)
close(__/*输入窗口句柄*/) = 关闭窗口(WM_CLOSE)
setText(.(窗口句柄,文本) = 修改外部程序窗口标题或文本
end intellisense**/


  
阅读(2927) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~