From 218082436291f16b3922a48eca08cbcfbb855090 Mon Sep 17 00:00:00 2001 From: JianjunLiu Date: Tue, 26 Sep 2023 17:41:20 +0800 Subject: [PATCH] =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gtk实现文件拖拽打开 --- designer/utslcodeeditor.tsf | 20 +-- funcext/tvclib/ugtkinterface.tsf | 181 ++++++++++++++++++++++++++- funcext/tvclib/uwindowsinterface.tsf | 21 +++- 3 files changed, 199 insertions(+), 23 deletions(-) diff --git a/designer/utslcodeeditor.tsf b/designer/utslcodeeditor.tsf index 663e0eb..ceb1ed4 100644 --- a/designer/utslcodeeditor.tsf +++ b/designer/utslcodeeditor.tsf @@ -2777,27 +2777,9 @@ type TEditer=class(TCustomcontrol) // inherited; P.ExStyle := P.ExStyle .| WS_EX_ACCEPTFILES; end - {$ifdef linux} - function DragQueryFileA(); - {$else} - function DragQueryFileA(hDrop:pointer;iFile:integer;lpszFile:string;cch:integer):integer;stdcall;external "Shell32.dll" name "DragQueryFileA"; - {$endif} function WMDROPFILES(o,e):WM_DROPFILES; begin - dn := ""; - opends := array(); - for i := 1 to DragQueryFileA(e.wparam,0xFFFFFFFF,"",0) do - begin - len := DragQueryFileA(e.wparam,i-1,nil,0); - if len>0 then - begin - setlength(dn,len+10); - if DragQueryFileA(e.wparam,i-1,dn,len+1)>0 then - begin - opends[length(opends)]:= dn[1:len]; - end - end - end + opends := _wapi.get_drage_file_names(e.wparam); for i,v in opends do begin arr := FileList("",v); diff --git a/funcext/tvclib/ugtkinterface.tsf b/funcext/tvclib/ugtkinterface.tsf index d23ee45..6d2f71c 100644 --- a/funcext/tvclib/ugtkinterface.tsf +++ b/funcext/tvclib/ugtkinterface.tsf @@ -4080,8 +4080,119 @@ type tgtkapis = class() //gtk _f_ := static function(w:pointer):pointer;cdecl;external getfuncptrbyname(0,functionname()); return ##_f_(w); end - /////////////////////////////////////////////////////////////// - + ////////////////////ÍÏ×§ÎļþÏà¹Ø/////////////////////////////////////////// + function gtk_drag_get_data(w:pointer;c:pointer;ls:pointer;tm:integer); + begin + _f_ := static procedure(w:pointer;c:pointer;ls:pointer;tm:integer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(w,c,ls,tm); + + end + function gdk_drag_status(c:pointer;ac:integer;tm:integer); + begin + _f_ := static procedure(c:pointer;ac:integer;tm:integer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(c,ac,tm); + + end + function gtk_drag_dest_set(w:pointer;flgs:integer;targets:pointer;ntg:integer;actions:integer):integer; + begin + _f_ := static procedure(w:pointer;flgs:integer;targets:pointer;ntg:integer;actions:integer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(w,flgs,targets,ntg,actions); + end + + function gdk_drag_context_list_targets(c:pointerr); + begin + _f_ := static procedure(c:pointer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(c); + + end + function gtk_selection_data_get_text(d:pointer); + begin + _f_ := static function(d:pointer):string;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(d); + end + function gtk_selection_data_get_data_type(d:pointer); + begin + _f_ := static function(d:pointer):pointer;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(d); + end + + function gdk_atom_name(a:pointer); + begin + _f_ := static function(d:pointer):string;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(d); + end + function gtk_drag_dest_find_target(w:pointer;ctx:pointer;tglist:pointer); + begin + + _f_ := static function(w:pointer;ctx:pointer;tglist:pointer):pointer;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(w,ctx,tglist); + end + function gtk_target_list_new(ntg):pointer; + begin + _f_ := static function(tg:pointer;ntg:integer):pointer;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(0,0); + end + function gdk_window_get_pointer(w:pointer;var x:integer;var y:integer;var mask:pointer); + begin + _f_ := static function(d:pointer):pointer;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(d); + end + function gtk_selection_data_get_length(ntg):integer; + begin + _f_ := static function(ntg:pointer;):integer;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(ntg); + end + function get_drage_file_names(w); + begin + global g_drage_file_file_names; + r := g_drage_file_file_names; + g_drage_file_file_names := array(); + if not ifarray(r) then r := array(); + return r; + end + function gtk_selection_data_get_uris(d); + begin + _f_ := static function(d:pointer):pointer;cdecl;external getfuncptrbyname(0,functionname()); + r := ##_f_(d); + rr := r; + ret := array(); + _tool := static new aefclassobj_(); + while true do + begin + p1 := _tool.readptr(r); + if not p1 then break; + fi := _tool.readstr(p1); + if not fi then continue; + if pos("file://",fi) then + begin + ret[idx++] := fi[8:]; + end + r+=8; + end + g_strfreev(rr); + return ret; + end + function gtk_target_entry_new(target,flags,info); + begin + _f_ := static function(target:string;flags:integer;info:integer):pointer;cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(target,flags,info); + end + function gtk_target_entry_free(tg:pointer); + begin + _f_ := static procedure(tg:pointer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(tg); + end + function gtk_drag_finish(ctx,suc,del,tm); + begin + //return ; + _f_ := static procedure(ctx:pointer;suc:integer;del:integer;tm:integer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(ctx,suc,del,tm); + end + function g_strfreev(uris); + begin + _f_ := static procedure(uris:pointer);cdecl;external getfuncptrbyname(0,functionname()); + return ##_f_(uris); + end /////////////////////////////////widget//////////////////////////////////// function gtk_widget_get_realized(w:pointer):integer; begin @@ -7938,9 +8049,33 @@ type tgtk_ctl_scroll_window = class(tgtk_ctl_object) v2 := new tscrollobject(FHscrollbar,Fhadjustment,fhsi); FScroller[_const.SB_HORZ] := v2; FScroller[_const.SB_VERT] := v1; - + if (dwExStyle .& _const.WS_EX_ACCEPTFILES)>0 then + begin + ftarget := _wapi.gtk_target_entry_new("text/uri-list",4,1); + wg := _wapi.GTK_WIDGET(h); + _wapi.gtk_drag_dest_set(wg,GTK_DEST_DEFAULT_DROP,ftarget,1,GDK_ACTION_COPY); + _wapi.g_signal_connect_data(wg,"drag-motion",get_instance_i(thisfunction(do_motion)),0,0); + _wapi.g_signal_connect_data(wg,"drag-data-received",get_instance_i(thisfunction(do_received)),0,0); + _wapi.g_signal_connect_data(wg,"drag-drop",get_instance_i(thisfunction(do_drop)),0,0); + end return inherited; end + procedure do_drop(w:pointer;ctx:pointer;x:integer;y:integer;tm:integer);cdecl; + begin + return true; + end + procedure do_received(w:pointer;ctx:pointer;x:integer;y:integer;d:pointer;info:integer;tm:integer);cdecl; + begin + global g_drage_file_file_names; + g_drage_file_file_names := _wapi.gtk_selection_data_get_uris(d); + _wapi.gtk_drag_finish(ctx,true,true,tm); + AddMessageToGtkMessageQueue(w,_const.WM_DROPFILES,d,tm); + end + function do_motion(w:pointer;c:pointer;x:integer;y:integer;tm:integer;d:pointer):bool;cdecl; + begin + _wapi.gdk_drag_status(c,GDK_ACTION_COPY,tm); + return true; + end function widgetsizechanged(h_,w_);override; //´óС¸Ä±ä begin h := h_; @@ -8252,6 +8387,7 @@ type tgtk_ctl_scroll_window = class(tgtk_ctl_object) return inherited; end } private + ftarget ; fscrollinfos; ftimerobj; Fscrolltimedo; @@ -8345,6 +8481,9 @@ type tgtk_ctl_scroll_window = class(tgtk_ctl_object) function Destroy();override; begin inherited; + get_instance_u(thisfunction(do_motion)); + get_instance_u(thisfunction(do_received)); + get_instance_u(thisfunction(do_drop)); FHadjustment := nil; Fvadjustment := nil; FHscrollbar := nil; @@ -8353,6 +8492,11 @@ type tgtk_ctl_scroll_window = class(tgtk_ctl_object) Fvscrollbarobj := nil; Fhscrollbarobj := nil; FClientWideget := nil; + if ftarget then + begin + _wapi.gtk_target_entry_free(ftarget); + ftarget := nil; + end end protected function initadjustSingal(); @@ -9087,6 +9231,23 @@ type _gtkeventtype=class static const GTK_RESPONSE_ACCEPT=-3; static const GTK_RESPONSE_REJECT=-2; static const GTK_RESPONSE_NONE=-1; + + static const GTK_TARGET_SAME_APP =1; + static const GTK_TARGET_SAME_WIDGET =2; + static const GTK_TARGET_OTHER_APP =4; + static const GTK_TARGET_OTHER_WIDGET =8; + + static const GDK_ACTION_DEFAULT =1; + static const GDK_ACTION_COPY =2; + static const GDK_ACTION_MOVE =4; + static const GDK_ACTION_LINK =8; + static const GDK_ACTION_PRIVATE =16; + static const GDK_ACTION_ASK =32; + + static const GTK_DEST_DEFAULT_MOTION =1; + static const GTK_DEST_DEFAULT_HIGHLIGHT =2; + static const GTK_DEST_DEFAULT_DROP =4; + static const GTK_DEST_DEFAULT_ALL =7; end { //cairo ³£Á¿ CAIRO_OPERATOR_CLEAR:=0; @@ -9161,6 +9322,20 @@ begin "tsl_gtk_idle": return mgnr.get(thisfunction(tsl_gtk_idle)); end ; end +function get_instance_i(fn); +begin + global g_gtk_call_handler_manager; + if not g_gtk_call_handler_manager then return 0; + mgnr := g_gtk_call_handler_manager; + return mgnr.get(fn); +end +function get_instance_u(fn); +begin + global g_gtk_call_handler_manager; + if not g_gtk_call_handler_manager then return 0; + mgnr := g_gtk_call_handler_manager; + return mgnr.del(fn); +end function tsl_gtk_idle(dlg:pointer):integer; begin return _gtkidledo_(dlg); diff --git a/funcext/tvclib/uwindowsinterface.tsf b/funcext/tvclib/uwindowsinterface.tsf index 5388d4f..bed239c 100644 --- a/funcext/tvclib/uwindowsinterface.tsf +++ b/funcext/tvclib/uwindowsinterface.tsf @@ -97,7 +97,26 @@ type twindowsapi = class() if oldmp then SelectObject(thdc,oldmp); return r; end - + function get_drage_file_names(w); + begin + dn := ""; + opends := array(); + for i := 1 to DragQueryFileA(w,0xFFFFFFFF,"",0) do + begin + len := DragQueryFileA(w,i-1,nil,0); + if len>0 then + begin + setlength(dn,len+10); + if DragQueryFileA(w,i-1,dn,len+1)>0 then + begin + opends[length(opends)]:= dn[1:len]; + end + end + end + return opends; + end + ///////////////////////////////////////// + function DragQueryFileA(hDrop:pointer;iFile:integer;lpszFile:string;cch:integer):integer;stdcall;external "Shell32.dll" name "DragQueryFileA"; ////////////////////////clipboar////////////////////// function OpenClipboard(hwd :pointer):integer;stdcall;external "User32.dll" name "OpenClipboard"; function EmptyClipboard():integer;stdcall;external "User32.dll" name "EmptyClipboard";