From c83b15eb95e3655b6c8e8c1f1bba1e8cfb44e09c Mon Sep 17 00:00:00 2001 From: FellippeHeitor Date: Tue, 31 Jul 2018 00:23:36 -0300 Subject: [PATCH] Implements Drag/Drop of files onto a program's window (Windows-only). New statement: _ACCEPTFILEDROP [{ON|OFF}] Enables a program to accept files being dropped from a folder. New functions: _TOTALDROPPEDFILES Returns the number of files that have been received via drag/drop. _DROPPEDFILE$ Returns the list of files that have been dropped. The function sequentially returns the file list and decreases _TOTALDROPPEDFILES with every read. --- internal/c/libqb.cpp | 55 +++++++++++++++++++++++ internal/c/parts/core/src/freeglut_main.c | 5 +++ internal/c/qbx.cpp | 3 ++ source/subs_functions/subs_functions.bas | 26 +++++++++++ 4 files changed, 89 insertions(+) diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index de7034e7f..12d63ab29 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -235,6 +235,8 @@ void sub__delay(double seconds); void *generic_window_handle=NULL; #ifdef QB64_WINDOWS HWND window_handle=NULL; + HDROP hdrop=NULL; + int32 totalDroppedFiles=0; #endif //... @@ -327,6 +329,7 @@ extern "C" int qb64_custom_event(int event,int v1,int v2,int v3,int v4,int v5,in #define QB64_EVENT_CLOSE 1 #define QB64_EVENT_KEY 2 #define QB64_EVENT_RELATIVE_MOUSE_MOVEMENT 3 +#define QB64_EVENT_FILE_DROP 4 #define QB64_EVENT_KEY_PAUSE 1000 static int32 image_qbicon16_handle; @@ -26502,6 +26505,49 @@ void sub__echo(qbs *message){ }//echo +void sub__filedrop(int32 on_off=NULL) { + #ifdef QB64_WINDOWS + if ((on_off==NULL)||(on_off==1)) + DragAcceptFiles((HWND)func__handle(), TRUE); + if ((on_off==2)) + DragAcceptFiles((HWND)func__handle(), FALSE); + #endif +} + +int32 func__totaldroppedfiles() { + #ifdef QB64_WINDOWS + return totalDroppedFiles; + #endif + return 0; +} + +qbs *func__droppedfile() { + #ifdef QB64_WINDOWS + static int32 index=-1; + static char szNextFile[MAX_PATH]; + + if (totalDroppedFiles > 0) { + totalDroppedFiles--; + index++; + if ( DragQueryFile ( hdrop, index, szNextFile, MAX_PATH ) > 0 ) { + if (totalDroppedFiles==0) { + DragFinish(hdrop); + index=-1; + } + return qbs_new_txt(szNextFile); + } else { + goto reset; + } + } else { + reset: + DragFinish(hdrop); + totalDroppedFiles=0; + index=-1; + } + #endif + return qbs_new_txt(""); +} + // 0 1 2 0 1 2 void sub__resize(int32 on_off, int32 stretch_smooth){ @@ -29617,6 +29663,15 @@ extern "C" int qb64_custom_event(int event,int v1,int v2,int v3,int v4,int v5,in return NULL; }//QB64_EVENT_RELATIVE_MOUSE_MOVEMENT + if (event==QB64_EVENT_FILE_DROP){ + #ifdef QB64_WINDOWS + if (totalDroppedFiles > 0) DragFinish(hdrop); + + hdrop=(HDROP)p1; + totalDroppedFiles = DragQueryFile ( hdrop, -1, NULL, 0 ); + #endif + return NULL; + } return -1;//Unknown command (use for debugging purposes only) }//qb64_custom_event diff --git a/internal/c/parts/core/src/freeglut_main.c b/internal/c/parts/core/src/freeglut_main.c index e177eb1c4..e4f754de7 100644 --- a/internal/c/parts/core/src/freeglut_main.c +++ b/internal/c/parts/core/src/freeglut_main.c @@ -53,6 +53,7 @@ int qb64_custom_event(int event,int v1,int v2,int v3,int v4,int v5,int v6,int v7 #define QB64_EVENT_CLOSE 1 #define QB64_EVENT_KEY 2 #define QB64_EVENT_RELATIVE_MOUSE_MOVEMENT 3 +#define QB64_EVENT_FILE_DROP 4 #define QBK 200000 #define VK 100000 @@ -2235,6 +2236,10 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, break; + case WM_DROPFILES: + qb64_custom_event(QB64_EVENT_FILE_DROP,0,0,0,0,0,0,0,0,wParam,NULL); + break; + case WM_DESTROY: /* * The window already got destroyed, so don't bother with it. diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index 31567ee76..8a12670fb 100644 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -99,6 +99,9 @@ uint8**out_data,int32*out_x,int32 *out_y,int32*out_x_pre_increment,int32*out_x_p extern void sub__title(qbs *title); extern void sub__echo(qbs *message); +extern void sub__filedrop(int32 on_off=NULL); +extern int32 func__totaldroppedfiles(); +extern qbs *func__droppedfile(); extern void sub__glrender(int32 method); extern void sub__displayorder(int32 method1,int32 method2,int32 method3,int32 method4); diff --git a/source/subs_functions/subs_functions.bas b/source/subs_functions/subs_functions.bas index 1bf4dc86d..25d74777f 100644 --- a/source/subs_functions/subs_functions.bas +++ b/source/subs_functions/subs_functions.bas @@ -898,6 +898,32 @@ id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid +clearid +id.n = "_ACCEPTFILEDROP" +id.subfunc = 2 +id.callname = "sub__filedrop" +id.args = 1 +id.arg = MKL$(LONGTYPE - ISPOINTER) +id.specialformat = "[{ON|OFF}]" +id.NoCloud = 1 +regid + +clearid +id.n = "_TOTALDROPPEDFILES" +id.subfunc = 1 +id.callname = "func__totaldroppedfiles" +id.ret = LONGTYPE - ISPOINTER +regid + +clearid +id.n = "_DROPPEDFILE" +id.musthave = "$" +id.subfunc = 1 +id.callname = "func__droppedfile" +id.ret = STRINGTYPE - ISPOINTER +id.NoCloud = 1 +regid + clearid id.n = "CLEAR" id.subfunc = 2