Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Drag and drop trigger (not of files)
#1
Hello again,

Is there a way to drag an item from one window to another, and have the receiving window capture the information of the item? 

For example, say the user drags the address from browser bar of chrome and drops it onto notepad, then have the address populate into notepad.

Thanks in advance.
Cuitino
#2
This is what I have been playing with so far. I set the the trigger to left mouse click (uncheck the "when release" check box)
 
Code:
Copy      Help
int  hwnd=id(15 "Notepad")
str s
s.getsel

rep
   ifk-((1))
      if ifa(hwnd)
         key {s} 
      ret


Two problems with this code: 1) it must have notepad the active window as apposed to the window under the mouse position at drop. 2) it spits out the letter "s" as apposed to the selected text on drag action.

Any suggestions are welcome
Cuitino
#3
I would not use a mouse trigger. Could easily make the left mouse button useless for all.

better idea would be to create a drop dialog and attach it to the notepad window  and drop the text there.

I adapted this from a couple other forum posts

creates a semi transparent dialog on  notepad that will except drag and drop text and transfer it to notepad.

macro runs in the background and when a notepad window appears will create the dialog. no triggers are needed. macro just needs to be running.

Macro AttachDropDialogToWindow
Code:
Copy      Help
type TB5016752 hdlg howner
ARRAY(TB5016752) a

int hhFore=SetWinEventHook(EVENT_SYSTEM_FOREGROUND EVENT_SYSTEM_FOREGROUND 0 &sub.HookProcFore 0 0 WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNTHREAD)
if(!hhFore) end F"{ERR_FAILED}. {_s.dllerror}"
int hhLoc=SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE EVENT_OBJECT_LOCATIONCHANGE 0 &sub.HookProcLoc 0 0 WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNTHREAD)
if(!hhLoc) end F"{ERR_FAILED}. {_s.dllerror}"
int idTimer=SetTimer(0 1 500 0)

MSG m
rep
,if(GetMessage(&m 0 0 0)<1) break
,sel m.message
,,case WM_TIMER
,,if(m.wParam=idTimer) sub.Timer1
,,continue
,,
,,case WM_APP
,,if IsWindow(m.wParam)
,,,int h=sub.Dialog(m.wParam)
,,,if h
,,,,TB5016752& r=a[]; r.howner=m.wParam; r.hdlg=h
,,,,sub.Attach(a.len-1)
,,continue
,
,TranslateMessage &m; DispatchMessage &m

UnhookWinEvent hhFore
UnhookWinEvent hhLoc
int i
for(i a.len-1 -1 -1) clo a[i].hdlg


#sub HookProcFore v
function hHook event hwnd idObject idChild dwEventThread dwmsEventTime

if(!hwnd or idObject or idChild) ret
str sc.getwinclass(hwnd); err ret
sel sc 1
,case "Notepad"
,int i
,for(i 0 a.len) if(hwnd=a[i].howner) ret
,PostMessage 0 WM_APP hwnd 0


#sub HookProcLoc v
function hHook event hwnd idObject idChild dwEventThread dwmsEventTime

;This code runs whenever a window
;or mouse pointer, caret, control, etc
;has locationchange.

;outw hwnd
if(!hwnd) ret ;;probably mouse
;out idObject
if(idObject!=OBJID_WINDOW) ret ;;eg caret
;out idChild
if(idChild) ret
int style=GetWinStyle(hwnd); if(style&WS_CHILD) ret

int i
for(i 0 a.len) if(hwnd=a[i].howner) sub.Attach(i); break


#sub Attach v
function i

;out "App Window has moved"
TB5016752& r=a[i]
int x y cx cy
GetWinXY(r.howner x y cx cy)
mov+ x+205 y+5 cx-355 45 r.hdlg


#sub Timer1 v
int i
for i 0 a.len
,if !IsWindow(a[i].howner)
,,clo a[i].hdlg; err


#sub Dialog v
function# hwndOwner

str dd=
;BEGIN DIALOG
;0 "" 0x80000848 0x8000080 0 0 227 150 "TextDrop"
;END DIALOG
;DIALOG EDITOR: "" 0x2040802 "*" "" "" ""

int h=ShowDialog(dd &sub.DlgProc 0 hwndOwner 1 0 0 hwndOwner 0 0 0)
act hwndOwner; err
ret h


#sub DlgProc v
function# hDlg message wParam lParam

int hwndControl=DT_GetParam(hDlg)
sel message
,case WM_INITDIALOG
,Transparent hDlg 105
,SetWindowPos hDlg 0 0 0 0 0 SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
,QmRegisterDropTarget(hDlg hDlg 0)
,case WM_QM_DRAGDROP
,QMDRAGDROPINFO& di=+lParam
,sel wParam
,,case 3 ;;drop
,,str s
,,if(!di.GetText(s)) ret
,,s.setsel(0 id(15 hwndControl))
,,;s.setwintext(id(15 hwndControl))
,,ret DT_Ret(hDlg 1)    
,case WM_DESTROY
,int i
,for(i a.len-1 -1 -1) if(hDlg=a[i].hdlg) a.remove(i); break
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL
ret 1

also need this 


Member function QMDRAGDROPINFO.GetText
Code:
Copy      Help
function! str&s [flags] ;;flags: 1 drag source must not delete text

;Extracts dropped text.
;Returns 1 if successful, 0 if failed.


s.fix(0)

int k=GetMod
sel(k) case [0,2] case else this.effect=DROPEFFECT_NONE; ret
if(flags&1) k=2

int i
for(i 0 this.formats.len) if(this.formats[i].cfFormat=CF_UNICODETEXT) break
if(i=this.formats.len) ret

#opt nowarnings 1
STGMEDIUM sm
this.dataObj.GetData(&this.formats[i] &sm); err ret

int gs=GlobalSize(sm.hGlobal)-2; if(gs<=0) ret
s.all(gs 2)
byte* m=GlobalLock(sm.hGlobal); if(!m) ret
memcpy s m s.len
GlobalUnlock sm.hGlobal
ReleaseStgMedium(&sm)
s.ansi

sel k
,case 0 this.effect&DROPEFFECT_MOVE
,case 2 this.effect&DROPEFFECT_COPY

ret 1
#4
Thanks for your response Kevin.
I get an error. It says that the variable 'di' does not have a member named GetText
#5
sorry forgot that function was part of the archives.

posted the member function above
also posted  the macro and the member function as a qml file below


.qml   AttachDropDialogToWindow.qml (Size: 21 KB / Downloads: 206)
#6
Thank you! works like a charm


Forum Jump:


Users browsing this thread: 1 Guest(s)