- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to allow drag and drop files into an application I'm developing for ease of use. When the user drags and drops a file onto the application, the WM_DROPFILES message is to be activated. I can't get this to work unfortunately, I've allowed drag and drop files in the window properties and have used the DragAcceptFiles(ghwndMain,.TRUE.) subroutine upon dialog creation.
From searching around it seems that others have used the ChangeWindowMessageFilterEx function to allow the WM_DROPFILES and WM_COPYDATA messages to be activated, but there doesn't seem to be an definition for this in any of the *.f90 windows api interface files provided with Intel Fortran 2011. Am I doing something wrong or is there another way round this?
I'm using Windows 7, VS 2008, Intel Fortran 2011 XE SP1
Many thanks,
Bryce
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately, Microsoft adds API calls faster than we can add them to the modules.ChangeWindowMessageFilterEx is new in Windows 7 and we don't have a declaration for it. You can add your own in the meantime. If I get a chance tomorrow I'll write it up for you.
I'll let others comment on what you're trying to do - it's not a topic I am familiar with from a programming sense.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An easier way, which I have successfully used, is:
DRAG AND DROP: If a filename is dragged onto the application's icon
then the application should open as if called with that filename's
name on the command line.
At the start of your application, find out if an input file was given on the command line using a call to NARGS and then
get the filename using GETARGS.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your replies. Regardless of whether this is the most effective way forward, it would be very useful for me to learn how to reference external functions like windows api for future issues similiar to this. I've added something similiar to what Sergey has for handling the message but I haven't got any sign of the WM_DROPFILES message to appear. So if I was to declare an external reference (I've never done this before) to ChangeWindowMessageFilterEx so I can allow the WM_DROPFILES would it be something like the attached? - this gives an unresolved external symbol error.
!DEC$ IF .NOT. DEFINED (extrawin_ )
!DEC$ DEFINE xextrawin_
!DEC$ objcomment lib:"user32.lib"
MODULE extrawin
use ifwinty
interface !lib=user32.lib (+version.lib)
function ChangeWindowMessageFilterEx (hWnd, message, action, pChangeFilterStruct)
import
integer(BOOL) ChangeWindowMessageFilterEx
!DEC$ ATTRIBUTES DEFAULT :: ChangeWindowMessageFilterEx
!DEC$ ATTRIBUTES STDCALL,ALIAS : "_ChangeWindowMessageFilterEx" :: ChangeWindowMessageFilterEx
integer(HANDLE) hWnd
integer(UINT) message
integer(DWORD) action
integer(LPVOID) pChangeFilterStruct
end function ChangeWindowMessageFilterEx
end interface
!DEC$ IF .NOT. DEFINED(__extrawin_INCLUDE)
END MODULE extrawin
!DEC$ ENDIF
!DEC$ ENDIF ! /* extrawin_ */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...then make sure that when you create its window, you give the application the correct style to enable it to accept drag-and-drop-files....
(from MSDN help)
HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam );
Parameters dwExStyle
[in] Specifies the extended style of the window. This parameter can be one of the following values:
ValueDescription
WS_EX_ACCEPTFILES
Specifies that a window created with this style accepts drag-drop files.
...and so on for various other styles.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have written several windows programs and here is an example of defining a class and creating a window from it which generates the WM_DROPFILES messages, even though neither do I not use a call to DragAcceptFiles nor explicitly set the WM_EX_ACCEPTFILES style.
! Register the MAIN window class, if not already
! registered by a previous instance
if(hPrevInstance .eq. 0) then
wc%lpszClassName = LOC(lpszClassName)
wc%lpfnWndProc = LOC(MainWndProc)
wc%style = IOR(IOR(CS_VREDRAW , CS_HREDRAW),CS_OWNDC)
wc%hInstance = hInstance
wc%hIcon = LoadIcon( hInstance, LOC(lpszIconName))
wc%hCursor = LoadCursor( NULL, IDC_ARROW )
wc%hbrBackground = hclassbrush ! try a different background brush
wc%lpszMenuName = 0
wc%cbClsExtra = 0
wc%cbWndExtra = 0
i2 = RegisterClass(wc)
! write(i2char,'(i20)') i2
! ret=messagebox(0,'Registerclass return='//i2char//''c, &
! 'Register Main window class 'c, &
! MB_OK)
end if
!****************************CREATE AND SHOW MAIN WINDOW***************************************8
! create the main window,
hmenu = LoadMenu(hInstance, LOC(lpszMenuName))
haccel = LoadAccelerators(hInstance, LOC(lpszAcceltabname))
hWnd = CreateWindow( lpszClassName, &
lpszAppName, &
INT(WS_OVERLAPPEDWINDOW), &
50, &
0, &
550, &
550, &
NULL, &
hmenu, &
hInstance, &
NULL &
)
!
i = ShowWindow( hWnd, SW_SHOWNORMAL)
When I drag and drop a file onto its window, the following code in the MainWndProc detects the fact and tells me about the file dropped...(lpszMessage and lpszDropFileName are both 150 character buffers)
!****************************************************************
!* WM_DROPFILES: Drag and drop message *
!****************************************************************
case (WM_DROPFILES)
retlog=messagebox(hWnd,"WM_DROPFILES message detected"c,&
"MainWndProc messages"c, MB_OK)
hDrop=wParam
retint=DragQueryFile(hDrop, -1, 0, ncharDropFile)
write(lpszmessage,*) retint
lpszmessage=TRIM(ADJUSTL(lpszmessage))//" files dropped"c
retlog=messagebox(hWnd,lpszmessage,&
"Drag and drop data"c, MB_OK)
nchardropfile=150
! files are numbered from zero, so first file is '0', second file
! is '1', etc. in call to DragQueryFile
do i=1,retint
retnew=DragQueryFile(hDrop, i-1, lpszDropFileName, ncharDropFile)
write(lpszmessage,*) retnew
lpszmessage=TRIM(ADJUSTL(lpszmessage))//" characters in file"c
retlog=messagebox(hWnd,lpszmessage,&
"Drag and drop data"c, MB_OK)
write(lpszmessage,*) lpszDropFileName(1:retnew)
lpszmessage=TRIM(ADJUSTL(lpszmessage))//" = file name"c
retlog=messagebox(hWnd,lpszmessage,&
"Drag and drop data"c, MB_OK)
enddo
MainWndProc = 0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please can you give some details about your application, such as whether or not it is a true Windows application that uses RegisterClass to register a window class in the usual way and CreatWindow to create a window with a message loop whose messages are handled by your own MainWndProc?
I have created such applications in the past and WM_DROPFILEs messages appear quite normally and are handled when I drag and drop a file onto an open window, even though I may not have explicitly specified a WS_EX_ACCEPTFILES window style or called DragAcceptFiles with the window handle. So your inability to get the WM_DROPFILES messages is puzzling, unless your application is non-standard and you are trying to bolt a drag-and-drop style onto it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is an example:
! Register the MAIN window class, if not already
! registered by a previous instance
if(hPrevInstance .eq. 0) then
wc%lpszClassName = LOC(lpszClassName)
wc%lpfnWndProc = LOC(MainWndProc)
wc%style = IOR(IOR(CS_VREDRAW , CS_HREDRAW),CS_OWNDC)
wc%hInstance = hInstance
wc%hIcon = LoadIcon( hInstance, LOC(lpszIconName))
wc%hCursor = LoadCursor( NULL, IDC_ARROW )
wc%hbrBackground = hclassbrush ! try a different background brush
wc%lpszMenuName = 0
wc%cbClsExtra = 0
wc%cbWndExtra = 0
i2 = RegisterClass(wc)
write(i2char,'(i20)') i2
! ret=messagebox(0,'Registerclass return='//i2char//''c, &
! 'Register Main window class 'c, &
! MB_OK)
end if
!****************************CREATE AND SHOW MAIN WINDOW***************************************8
! create the main window,
hmenu = LoadMenu(hInstance, LOC(lpszMenuName))
haccel = LoadAccelerators(hInstance, LOC(lpszAcceltabname))
hWnd = CreateWindow( lpszClassName, &
lpszAppName, &
INT(WS_OVERLAPPEDWINDOW), &
50, &
0, &
550, &
550, &
NULL, &
hmenu, &
hInstance, &
NULL &
)
!
i = ShowWindow( hWnd, SW_SHOWNORMAL)
The WM_DROPFILES messages are handled thus in a MainWndProc:
!****************************************************************
!* WM_DROPFILES: Drag and drop message *
!****************************************************************
case (WM_DROPFILES)
retlog=messagebox(hWnd,"WM_DROPFILES message detected"c,&
"MainWndProc messages"c, MB_OK)
hDrop=wParam
retint=DragQueryFile(hDrop, -1, 0, ncharDropFile)
write(lpszmessage,*) retint
lpszmessage=TRIM(ADJUSTL(lpszmessage))//" files dropped"c
retlog=messagebox(hWnd,lpszmessage,&
"Drag and drop data"c, MB_OK)
nchardropfile=150
! files are numbered from zero, so first file is '0', second file
! is '1', etc. in call to DragQueryFile
do i=1,retint
retnew=DragQueryFile(hDrop, i-1, lpszDropFileName, ncharDropFile)
write(lpszmessage,*) retnew
lpszmessage=TRIM(ADJUSTL(lpszmessage))//" characters in file"c
retlog=messagebox(hWnd,lpszmessage,&
"Drag and drop data"c, MB_OK)
write(lpszmessage,*) lpszDropFileName(1:retnew)
lpszmessage=TRIM(ADJUSTL(lpszmessage))//" = file name"c
retlog=messagebox(hWnd,lpszmessage,&
"Drag and drop data"c, MB_OK)
enddo
MainWndProc = 0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Anthony That looks useful! For the record, as it just happens to be something I have been looking at today:
[fortran]!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_MyWndProc@16':: MyWndProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'MyWndProc' :: MyWndProc
!DEC$ ENDIF[/fortran]
can be replaced with:
[fortran]!DEC$ ATTRIBUTES STDCALL, DECORATE, ALIAS : 'MyWndProc':: MyWndProc[/fortran]
Which will work for x32 and x64. The x64 build ignores the decorate on stdcall it would appear.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's not that it ignore it, it supplies the appropriate decoration, which is none.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
<quote>It's not that it ignore it, it supplies the appropriate decoration, which is none. </quote>
Indeed! The help files says IA32 decorates and then makes no comment on x64. I will remember that quote next time the wife wants me to decorate the lounge. :-)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If it is a QUICKWIN application, you can get it to work by
a) getting the framewindow handle using
HWND=GETHWNDQQ(QWIN$FRAMEWINDOW)
b) calling DragAcceptFiles with the frame window handle using
call dragacceptfiles(HWND, .true.),
c) subclassing the frame window's message-handling procedure using SetWindowLong, for example
! get the handle HWNDPROC to the default Quickwin window procedure
HWNDPROC=GetWindowLong(HWND, GWL_WNDPROC)
!Replace the frame window's message-handling procedure with your window procedure, saving the handle to the default procedure
in HWNDPREV (HWNDPREV will be identical to HWNDPROC)
HWNDPREV=SetWindowLong(HWND, GWL_WNDPROC, LOC(MyWndProc))
and then
d) getting your sub-class procedure MyWndProc to handle the WM_DROPFILES messages that are then sent to the frame window when you drag-and-drop files onto it.
Your procedure should return 0 (MyWndProc=0) after you have processed the message. To prevent your Quickwin application from freezing, all other windows messages must be passed by default on to the original window procedure (handle HWNDPROC) using a function call to CallWindowProc, for example
integer function MyWndProc ( hWnd, mesg, wParam, lParam )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_MyWndProc@16':: MyWndProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'MyWndProc' :: MyWndProc
!DEC$ ENDIF
use dflib
use dfwin
implicit none
...
...
...
select case (mesg)
case (WM_DROPFILES)
message='WM_DROPFILES MESSAGE RECEIVED...'C
retint=messageboxqq(message,'QUICKWIN SUB-CLASSED WINDOW MESSAGE HANDLING PROCESSING'C,&
MB$OK.OR.MB$ICONEXCLAMATION)
! Insert code for handling your dropped files here...
MyWndProc=0
! DEFAULT PROCESSING
case default
! Let the default window proc handle all other messages
MyWndProc = CallWindowProc(HWNDPROC, mesg, wParam, lParam )
end select
The handle HWNDPROC needs to be made available to the MyWndProc code by defining it in a module that you can USE (or, if you are old-fashioned, put it into a labelled common block).
I have tested the above with one of my own QuickWin applications and it works fine.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page