Re: [win32gui] Re: [perl-win32-gui-hackers] DrapDrop support for Win32::GUI
Jeremy White wrote: Robert May wrote: NotifyIcon I certainly have on my list of candidates. I haven't thought much beyond that, but I am hopeful that a restructuring like this might reduce GUI.xs and GUI.pm to more manageable sizes. I also want to experiment with moving a lot of the per-control methods from XS back into perl. There are many methods implemented in XS that do a single call to SendMessage. By moving them back into perl I don't think we'll see much of a performance hit (there's still one 'thunk' between perl and XS, which I suspect to be the largest time overhead), and will be able to move all such methods to be AUTOLOADed, so we only take compile time and memory hits if we use them in our apps. I think we also have to bare in mind that a Win32-GUI app isn't deployed and run in the same way as a normal perl module/application. Most of the time a Win32-GUI app is run as an exe produced by PerlApp/Perl2exe/PAR. Even if the dll is reduced in size by moving out simple sendmessage calls, we just add bloat to the perl packages which would increase the size of the exe - even if those functions are never used. OK - if we split things out into separate packages they shouldn't be included in the exe - but I'm just wondering if we're making work for ourselves without any real tangible benefits i.e., if it's not broke why fix it? I think there are 2 main uses for Win32::GUI: (1) Very simple front ends for Windows platforms. For example, consider the recent request in the users list for implementing a dialog to enter a text string. When doing simple things like this we shouldn't have to pull in 3MB of dll plus all the perl code. (2) The example you give on an app packed with PAR/PerlApp/Perl2exe etc. Even in this case it would be nice to minimise the amount of stuff that we need to package up. I can' speak for PerlApp and Perl2exe, but it is my understanding that PAR has the ability to determine what methods are used, and only package up the autoload subs that are required. I am sympathetic to using these packaging tools, and certainly don't want to do anything that increases the difficulty of making such exes. Equally I don't want to see their size increase either. The perl vs. xs split is a difficult call to make, and one that I am not convinced I know the right answers to yet, but I do want to experiment with some ideas, and see how the size/performance trade-offs work. I'm a little sensitive when it comes to memory usage, as one of my Win32-GUI apps uses 50 meg before it's even done anything - a good chunk of that is due to Win32-GUI - I use a lot of controls, and think of all those SV's that are used for each one:) Getting rid of the tied hash would be a good start:) Getting rid of the tied hash mechanism is on my list of things to look at. I think that I do now understand all that it is doing for Win32::GUI, however, I'm nervous about touching it, as the potential for introducing memory leaks and destruction problems is very large (although as currently implemented there are already some problems). I will get around to looking at this, but it needs care. I don't think the perl vs. xs issue significantly affects the number of SV's that will be used per-say. Assuming you mean the typemap code when you talk about the thunk - the Win32-GUI typemap it's relatively efficient - more so than the classic way of doing a typemap conversion (when you check for the correct object) - so it'll probably be worth doing some performance testing to see what (if any) the impact would be. Not just the typemap. By the 'thunk' (and I think 'thunking' is a proper perl term) I mean all the stack and variable manipulation that is required to call into XS - conversion of SV's to C variables and back has overhead ... Where I'm going here is that we don't want to move functions/methods that call multiple windows apis from xs back into perl, as that would leave us with a function that does multiple perl-xs-perl transitions, rather than a single one. More work required, and it will happen in time. I hope that it can be a gradual evolution, during which we learn what works and what doesn't. Regards, Rob.
Re: [win32gui] Re: [perl-win32-gui-hackers] DrapDrop support for Win32::GUI
Reini Urban wrote: Robert May wrote: Here's what I am proposing: (1) All windows/controls will gain the -acceptfiles option that will be used to set/unset the WS_EX_ACCEPTFILES extended style on the window/control (For those of you familiar with it, this is all that the Win32 DrapAcceptFiles() API does). This is a minor change to GUI_Options.cpp, and improves on the original implementation that only supported dropping for Window/DialogBox. Great! OK. (2) All Windows/Controls will gain the AcceptFiles() method to get/set the WS_EX_ACCEPTFILES extended style. Additionally, as this information is available from the extended style, no additional storage is needed to track a window's dragdrop state. The only minor inconvenience is with the naming. DragDrop object -acceptfiles option DropFiles ( = WM_DROPFILES ) NEM or OEM eventname GetDroppedFiles() vs. DragQueryFile() methods I'd rather prefer -dropfiles over -acceptfiles, so that the supported event has the same name as the option which declares it. On the other side, WS_EX_ACCEPTFILES and DrapAcceptFiles() is also established on the API side. I'm not wedded to the API call names, particularly when we have methods that don't directly map to the API. As I think about it I propose the following public API: - flag to turn on/off WS_EX_ACCEPTFILES will be -acceptfiles - we have precedent for naming style options like this. - the callback will be -onDropFiles and window_name)_DropFiles, as that's what it is called today, and matches precedent for naming events (cf. WM_DROPFILES) - For consistency the module will be named Win32::GUI::DropFiles. This better reflects the actual functionality, and avoids a namespace clash with the existing Loft Win32::GUI::DragDop - There will an AccepFiles() method on the window objects for getting/setting the WS_EX_ACCEPTFILES style. This is consistent with current naming conventions (e.g. -dialogui/DialogUI()) Note that we can also use $win-Change(-acceptfiles = 0|1) for setting. (2) The DropFiles callback which is already supported for all windows/controls (handling WM_DROPFILES) will change it's callback parameter from the current HDROP integer to a Win32::GUI::DropFiles object. This is a minor change to GUI_MessageLoops.cpp This change will only be made if our new Win32::GUI::DropFiles module is loaded. If it is not, then the existing callback with a drophandle will be used - this gives us the backwards compatibility we are looking for. (3) The Win32::GUI::DropFiles object will expose the following methods: - GetDroppedFiles, which will return: in scalar context the number of files dropped in list context a list of dropped file names - GetDroppedFile, which will take a zero-based index for the dropped file, and will return the file name hmm. Why hmm? We need to provide some sort of iterator access so that the user can efficiently deal with large numbers of dropped files, rather than only being able to get a list of all the files. Perhaps a proper interator api would be better with a Reset() and GetNextFile[Name]() interface? - GetDropPos, which will return: in scalar context whether the drop was in the client or non-client area of the window Is this possible at all? Yes, it's the return value of DragQueryPos in list context the position of the mouse when the drop occurred in client co-ordinates It should be possible to write GetDroppedFiles() so that code written to use the GUI Loft's GetDroppedFiles() method will continue to work, without modification. That was my idea also. The only problem is with the naming, DragQueryFile() vs GetDroppedFile() This is no longer necessary, and deals with the naming conflict for DragQueryFile It's only the Loft which introduced the name GetDroppedFiles(). WINAPI declares DragQueryFile and DragQueryPoint. I would like to stay with the WINAPI names. I'm not wedded to the API calls, but the module will also provide the following (non-?)public APIs: Win32::GUI::DropFiles::DrapAcceptFiles(HWND,FLAG) - direct mapping of the win32 api. Included only for completeness. Win32::GUI::DropFiles::DragQueryFile(HDROP, [ITEM]) - mapping of the win32 api DragQueryFile api: if called with only the HDROP parameter, returns a count of the dropped files; if called with the HDROP and ITEMS parameter returns the filename for ITEM Win32::GUI::DropFiles::DragQueryPoint(HDROP) - returns a list of 3 scalars: X-pos, y-pos and (non-)client flag Win32::GUI::DropFiles::DragFinish(HDROP) - direct mapping of the win32 api GetDropPos: Doesn't DragQueryPoint report the position while being dragged also? So it's not only after being dropped. No. We only get the HDROP handle after the drop occurs (in the WM_DROPFILES message) You need to implement a full COM IDropTarget interface and use RegisterDragDrop() api to get this sort of functionality. You'd then get DragEnter, DragOver, DragLeave and Drop
Re: [win32gui] Re: [perl-win32-gui-hackers] DrapDrop support for Win32::GUI
100% agreed with all points. Thanks. 2006/3/18, Robert May [EMAIL PROTECTED]: Reini Urban wrote: Robert May wrote: Here's what I am proposing: (1) All windows/controls will gain the -acceptfiles option that will be used to set/unset the WS_EX_ACCEPTFILES extended style on the window/control (For those of you familiar with it, this is all that the Win32 DrapAcceptFiles() API does). This is a minor change to GUI_Options.cpp, and improves on the original implementation that only supported dropping for Window/DialogBox. Great! OK. (2) All Windows/Controls will gain the AcceptFiles() method to get/set the WS_EX_ACCEPTFILES extended style. Additionally, as this information is available from the extended style, no additional storage is needed to track a window's dragdrop state. The only minor inconvenience is with the naming. DragDrop object -acceptfiles option DropFiles ( = WM_DROPFILES ) NEM or OEM eventname GetDroppedFiles() vs. DragQueryFile() methods I'd rather prefer -dropfiles over -acceptfiles, so that the supported event has the same name as the option which declares it. On the other side, WS_EX_ACCEPTFILES and DrapAcceptFiles() is also established on the API side. I'm not wedded to the API call names, particularly when we have methods that don't directly map to the API. As I think about it I propose the following public API: - flag to turn on/off WS_EX_ACCEPTFILES will be -acceptfiles - we have precedent for naming style options like this. - the callback will be -onDropFiles and window_name)_DropFiles, as that's what it is called today, and matches precedent for naming events (cf. WM_DROPFILES) - For consistency the module will be named Win32::GUI::DropFiles. This better reflects the actual functionality, and avoids a namespace clash with the existing Loft Win32::GUI::DragDop - There will an AccepFiles() method on the window objects for getting/setting the WS_EX_ACCEPTFILES style. This is consistent with current naming conventions (e.g. -dialogui/DialogUI()) Note that we can also use $win-Change(-acceptfiles = 0|1) for setting. (2) The DropFiles callback which is already supported for all windows/controls (handling WM_DROPFILES) will change it's callback parameter from the current HDROP integer to a Win32::GUI::DropFiles object. This is a minor change to GUI_MessageLoops.cpp This change will only be made if our new Win32::GUI::DropFiles module is loaded. If it is not, then the existing callback with a drophandle will be used - this gives us the backwards compatibility we are looking for. (3) The Win32::GUI::DropFiles object will expose the following methods: - GetDroppedFiles, which will return: in scalar context the number of files dropped in list context a list of dropped file names - GetDroppedFile, which will take a zero-based index for the dropped file, and will return the file name hmm. Why hmm? We need to provide some sort of iterator access so that the user can efficiently deal with large numbers of dropped files, rather than only being able to get a list of all the files. Perhaps a proper interator api would be better with a Reset() and GetNextFile[Name]() interface? - GetDropPos, which will return: in scalar context whether the drop was in the client or non-client area of the window Is this possible at all? Yes, it's the return value of DragQueryPos in list context the position of the mouse when the drop occurred in client co-ordinates It should be possible to write GetDroppedFiles() so that code written to use the GUI Loft's GetDroppedFiles() method will continue to work, without modification. That was my idea also. The only problem is with the naming, DragQueryFile() vs GetDroppedFile() This is no longer necessary, and deals with the naming conflict for DragQueryFile It's only the Loft which introduced the name GetDroppedFiles(). WINAPI declares DragQueryFile and DragQueryPoint. I would like to stay with the WINAPI names. I'm not wedded to the API calls, but the module will also provide the following (non-?)public APIs: Win32::GUI::DropFiles::DrapAcceptFiles(HWND,FLAG) - direct mapping of the win32 api. Included only for completeness. Win32::GUI::DropFiles::DragQueryFile(HDROP, [ITEM]) - mapping of the win32 api DragQueryFile api: if called with only the HDROP parameter, returns a count of the dropped files; if called with the HDROP and ITEMS parameter returns the filename for ITEM Win32::GUI::DropFiles::DragQueryPoint(HDROP) - returns a list of 3 scalars: X-pos, y-pos and (non-)client flag Win32::GUI::DropFiles::DragFinish(HDROP) - direct mapping of the win32 api GetDropPos: Doesn't DragQueryPoint report the position while being dragged also? So it's not only after being dropped. No. We only get the HDROP handle after the drop occurs (in the WM_DROPFILES message) You need to implement a