虚表 —— 拖入拖出文件

光庆 2024-4-3 1735

升级虚表库到最新版

拖放到虚表:

从虚表拖放到外部窗口:

import win.ui;
import godking.vlistEx;
/*DSG{{*/
mainForm = win.form(text="vlistEx - table adapter";right=455;bottom=247)
mainForm.add(
listview={cls="vlistEx";left=16;top=24;right=440;bottom=240;border=1;z=1}
)
/*}}*/
var t = {
    {"[@rowindex]",""} 
    {"[@rowindex]",""} 
    {"[@rowindex]",""} 
    {"[@rowindex]",""} 
    {"[@rowindex]",""}
}
mainForm.listview.setTable(t,"序号,文件",{50,-1},1);

//从外部拖放文件到虚表
mainForm.listview.onDropFiles = function(row/*行*/,col/*列*/,files/*文件数组*/){
    if row and col==2 owner.setCellText(row,col,files[1])
}

//从虚表拖放文件到外部窗口
mainForm.listview.onDragRow = true;
import winex;
import mouse;
mainForm.listview.onDragRowEnd = function(draglist/*要拖动的行号数组*/,dragtorow/*拖到的目标行号*/){
	var x,y = ..mouse.getPos();
	if mainForm.getRect(true).contains(x,y) return false; //鼠标在主窗口范围内则返回
	var hwnd = ..winex.fromPoint(x,y); //获取目标窗口句柄
	var files = mainForm.listview.getColText( 2/*列号*/,draglist/*行号或数组或null*/); //获取第二列选中的文件列表
	mainForm.listview.dragFileTo(hwnd/*目标窗口句柄*/,files/*文件或数组*/,true/*拖到目标顶层父窗口*/); //拖放操作
    return false;
}

mainForm.show();
win.loopMessage();
最新回复 (13)
  • aardio 12月前
    0 引用 2
    一下子发这么多好,学不过来
  • kio 11月前
    0 引用 3

    对于管理员权限运行导致拖拽事件失效的,因UAC的影响,可以使用相应的函数允许消息传递。 

    ::User32.ChangeWindowMessageFilterEx(mainForm.listview.hwnd, 0x233/*_WM_DROPFILES*/, 1, null); 

    ::User32.ChangeWindowMessageFilterEx(mainForm.listview.hwnd, 0x0049, 1, null);

  • 光庆 11月前
    0 引用 4
    kio 对于管理员权限运行导致拖拽事件失效的,因UAC的影响,可以使用相应的函数允许消息传递。 ::User32.ChangeWindowMessageFilterEx(mainForm.l ...
    已加入虚表库,以备使用。谢谢提供。
  • zhhyit 20天前
    0 引用 5
    光大,如果从虚标拖出文件呢,请教一下方法🥹,我这想法是不是很奇怪
  • 光庆 18天前
    0 引用 6
    zhhyit 光大,如果从虚标拖出文件呢,请教一下方法🥹,我这想法是不是很奇怪
    一般用不到这种功能吧。以前我有过这个想法,理论上应该可以通过伪造拖放消息实现,但一直没具体写这些代码。
  • 光庆 17天前
    0 引用 7
    zhhyit 光大,如果从虚标拖出文件呢,请教一下方法🥹,我这想法是不是很奇怪
    升级了,可以支持这个功能了。
  • 近我者赤 17天前
    0 引用 8

  • zhhyit 17天前
    0 引用 9
    光大,我回头找找,有个开源项目,就是做的这个类似功能
  • zhhyit 17天前
    0 引用 10
    https://github.com/GameGodS3/DropPoint 类似于这个开源的项目的功能
  • zhhyit 17天前
    0 引用 11

    很久之前找了一个dragout-v0.2的库文件,现在不知道原网址了,不知道咋用,给的案例也报错

     //dragout 文件拖放-拖出
    
    import win;
    import win.cur;
    import fsys;
    
    namespace win.util;
    
    //鼠标按下状态
    class dragout{
    	ctor(){
    		this.running = false;
    		
    		var newWndproc = function(hwnd, message, wParam, lParam){
    			select(message) {
    				case 0x20/*_WM_SETCURSOR*/ {
    					//win.cur.setCur(GetDropTarget(this.allowParent) ? cur_yes : cur_no);
    					return 0;
    				}
    				case 0x200/*_WM_MOUSEMOVE*/ {
    					setCur(getDropTarget(this.allowParent) ? this.cur_yes : this.cur_no);
    					return 0;
    				}
    				case 0x202/*_WM_LBUTTONUP*/ {
    					var drop = dropFiles(getDropTarget(this.allowParent), this.files);
    					releaseCapture();
    					this.stop();
    					if(drop && this.callback){
    						this.callback(hwnd);
    					}
    					return 0;
    				}
    				else {
    					return this.originWndproc(hwnd, message, wParam, lParam);
    				}
    			}
    		}
    	};
    	start = function(winform, files, callback, allowParent = true, cur_yes, cur_no){
    		this.stop();
    		if(!winform[["hwnd"]]) error("参数@1:应为窗口!", 2);
    		if(type(files) != type.table) error("参数@1:应为字符串数组!", 2);
    		
    		this.winform = winform;
    		this.originWndproc = null;
    		
    		//如果原来没有回调函数,则先添加一个回调函数,最后在取消掉
    		var originWndproc = winform.wndproc;
    		if(!originWndproc){
    			this.haveOriginWndproc = false;
    			winform.wndproc = function(){};
    			originWndproc = winform.wndproc;
    			if(!originWndproc) error("扩展库错误:窗口回调函数错误!", 2);
    		} else {
    			this.haveOriginWndproc = true;
    		}
    		this.originWndproc = originWndproc;
    		
    		this.files = files;
    		for(i=1;#files;1){
    			this.files[i] = ..string.toUnicode(files[i]);
    		}
    		this.callback = callback;
    		this.allowParent = allowParent;
    		
    		this.cur_yes = cur_yes : self.cur_yes;
    		this.cur_no  = cur_no  : self.cur_no;
    		
    		winform.wndproc = null;
    		winform.wndproc = newWndproc;
    		
    		setCapture(winform.hwnd);
    		setCur(getDropTarget(this.allowParent) ? this.cur_yes : this.cur_no);
    		
    		this.running = true;
    	}
    	stop = function(){
    		if(!this.running) return;
    		if(this.originWndproc){
    			this.winform.wndproc = null;
    			if(this.haveOriginWndproc){
    				this.winform.wndproc = this.originWndproc;
    				this.originWndproc = null;
    			}
    		}
    		this.running = false;
    	}
    }
    
    /*curdata{{*/
    var curdata = '\x00\x00\x02\x00\x01\x00\x20\x20\x00\x00\x00\x00\x00\x000\x01\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x20\x00
    \x00\x00@\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
    \x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\xF0\x00\x00\x1F\xF0
    \x00\x00\x1E\xF0\x00\x00\x1E\xF0\x00\x00\x180\x00\x0A\x9E\xF0\x00\x15^\xF0\x00\x08\x1F\xF0\x00\x10\x1F\xF0\x00\x08\x00\x00
    \x00\x10\x01\x00\x00\x08\x02\x00\x00\x11\x95\x00\x00\x09\xAA\x00\x00\x03\x00\x00\x00C\x00\x00\x00f\x00\x00\x00~\x00\x00\x00
    ~\x00\x00\x00\x7F\xC0\x00\x00\x7F\x80\x00\x00\x7F\x00\x00\x00~\x00\x00\x00|\x00\x00\x00x\x00\x00\x00p\x00\x00\x00\x60\x00
    \x00\x00@\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\x07\xFF\xFF\xC0\x07\xFF\xFF\xC0\x07\xFF\xFF
    \xC0\x07\xFF\xFF\xC0\x07\xFF\xFF\xC0\x07\xFF\xE0\x00\x07\xFF\xE0\x00\x07\xFF\xE7\xC0\x07\xFF\xE7\xC0\x07\xFF\xE7\xC0\x07
    \xFF\xE7\xFC\xFF\xFF\xE6<\xFF\xFF\xE4\x00\xFF\xFF\x60\x00\xFF\xFF8\x7F\xFF\xFF\x18\x7F\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF
    \xFF\x00\x0F\xFF\xFF\x00\x1F\xFF\xFF\x00?\xFF\xFF\x00\x7F\xFF\xFF\x00\xFF\xFF\xFF\x01\xFF\xFF\xFF\x03\xFF\xFF\xFF\x07\xFF
    \xFF\xFF\x0F\xFF\xFF\xFF\x1F\xFF\xFF\xFF?\xFF\xFF\xFF';
    /*}}*/
    
    namespace dragout{
    	var win = ..win;
    	var string = ..string;
    	
    	setCur = win.cur.setCur;
    	setCapture = win.setCapture;
    	releaseCapture = win.releaseCapture;
    	
    	cur_no = win.cur.load(0x7F88/*_IDC_NO*/)
    	var tname = string.fromto((..io.tmpname("aardio_dragout_cur_")), 0, 65001);
    	string.save(tname, curdata);
    	
    	cur_yes = win.cur.loadfile(tname);
    	..fsys.delete(tname);
    	tname = null;
    	
    	var GetCursorPos = User32.api("GetCursorPos","INT( struct &lpPoint)" ) ;
    	getCursorPos = function(){
    		var p = ::POINT();
    		GetCursorPos(p);
    		return p.x, p.y;
    	}
    	
    	var WindowFromPoint = ::User32.WindowFromPoint;
    	var getStyleEx = ..win.getStyleEx;
    	var getParentOwner = ..win.getParentOwner;
    	getDropTarget = function(allowParent = true){
    		var hwnd = WindowFromPoint(getCursorPos());
    		if(allowParent) while(hwnd){
    			if(getStyleEx(hwnd, 0x10/*_WS_EX_ACCEPTFILES*/))
    				break;
    			hwnd = getParentOwner(hwnd);
    		} else {
    			if(!getStyleEx(hwnd, 0x10/*_WS_EX_ACCEPTFILES*/)){
    				return;
    			}
    		}
    		return hwnd;
    	}
    	
    	class DROPFILES{
    		ctor(x, y){
    			this.x = x;
    			this.y = y;
    		}
    		INT pFiles = 20;		// offset of file list
    		int x;					// drop point (client coords)
    		int y;					// drop point (client coords)
    		INT fNC = 1;			// is it on NonClient area and pt is in screen coords
    		INT fWide = 1;			// WIDE character switch
    	}
    	var rtostring = ..raw.tostring;
    	dropFiles = function(hwnd, files){
    		if(!hwnd) return false;
    
    		var str = rtostring(DROPFILES(getCursorPos()));
    		for(i=1;#files;1) str += files[i] + '\0\0'; str += '\0\0';
    
    		var p = ::GlobalAlloc(0x40/*_GPTR*/, #str);
    		::CopyMemory(p, str, #str);
    		
    		// The handler for WM_DROPFILES deallocates the "drop" structure for us
    		::PostMessage(hwnd, 0x233/*_WM_DROPFILES*/, tonumber(p), 0);
    		return true; 
    	}
    }
    
    /**intellisense()
    win.util.dragout = 文件拖放-拖出扩展库
    win.util.dragout() = 创建 文件拖放-拖出 对象\n\nstart之后,stop之前不要修改窗口回调函数\n不支持往桌面拖动\n!dragout.
    !dragout.start(.(winform, files, callback, allowParent, cur_yes, cur_no) = 启动:在鼠标左键按下的情况下调用该函数!\n\n参数@1:[必]窗口或控件,不是句柄!\n参数@2:[必]文件路径数组\n参数@3:[选]回调函数:参数为目标窗口句柄(0为失败)\n参数@4:[选]是否允许探测父窗口【true】\n参数@5:[选]允许拖放文件时的光标\n参数@6:[选]拒绝拖放文件时的光标
    !dragout.stop() = 停止\n\n不需要手动调用
    end intellisense**/


    给的实列,有报错

     import win.ui;
    /*DSG{{*/
    var winform = win.form(text="aardio form";right=448;bottom=311;acceptfiles=1)
    winform.add(
    button={cls="button";text="button";left=143;top=96;right=269;bottom=184;z=1}
    )
    /*}}*/
    
    import console;
    console.open();
    
    import win.util.dragout;
    drag = win.util.dragout();
    
    filetab = {"D:\test.aardio"; "D:\test2.aardio"};
    
    winform.button.wndproc = function(hwnd,message,wParam,lParam){
    	select( message ) { 
    		case 0x201/*_WM_LBUTTONDOWN*/{
    			drag.start(winform.button, filetab, function(hwnd){
    				console.log(hwnd);
    			}, true);
    		}
    		case 0x233/*_WM_DROPFILES*/{
    			console.dump(win.getDropFile(wParam));
    		} 
    	}
    	//无返回值则继续调用默认回调函数
    }
    winform.wndproc = function(hwnd,message,wParam,lParam){
    	select( message ) { 
    		case 0x201/*_WM_LBUTTONDOWN*/{
    			drag.start(winform, filetab, function(hwnd){
    				console.log(hwnd);
    			},false);
    		}
    		case 0x233/*_WM_DROPFILES*/{
    			console.dump(win.getDropFile(wParam));
    		} 
    	}
    	//无返回值则继续调用默认回调函数
    }
    
    winform.show();
    win.loopMessage();
    
    console.pause(true);


    上传的附件:
  • zhhyit 17天前
    0 引用 12

    例如把已有的素材用godking.vlistEx加载好,可以拖拽到聊天框或者其他应用程序中

  • 光庆 17天前
    0 引用 13
    zhhyit 例如把已有的素材用godking.vlistEx加载好,可以拖拽到聊天框或者其他应用程序中
    这个功能我在截屏库中有封装。
  • zhhyit 17天前
    0 引用 14
    光庆 这个功能我在截屏库中有封装。
    好滴好滴,下载最新的vlistEx我看下,多谢光大
返回