Johan, I would find this functionality extremely useful. In the next couple of weeks I'll be attempting to implment multiple instances of the same window. I was thinking of using the NEM and closures to implement an OO like approach - although I've yet to get past the thinking stage:)
In my case, the application is likely to be long running and the user is likely to open and close multiple windows many times, which means I will have to "reuse" old windows, or I'll have a memory leak or worse on my hands. If this kind of functionality is included in the core, then the resources a window uses should be returned to the OS when it is closed/terminated. It may be worth talking to Aldo - I remember reading some comments from him suggesting that he was working on an improved model - which may (or may not) achieve what you are suggesting. Cheers, jez. ----- Original Message ----- From: "Johan Lindstrom" <[EMAIL PROTECTED]> To: "Win32-GUI" <perl-win32-gui-users@lists.sourceforge.net> Sent: Monday, January 05, 2004 2:07 AM Subject: [perl-win32-gui-users] RFC: Yet another event model, anyone? When I first looked at Win32::GUI for the first time many many years ago (4? ok, not so many) I found it kind of confusing how the objects and events worked. Coming from an OO background and with experience from a few other window toolkits (VB and Borland TurboVision among others) I would have expected to subclass the Window class, create an object, add controls to the object, and then I would defined methods in my subclass to be called when events fired. Kind of like this: package DemoWindow; #My DemoWindow is-a Window... use base qw(Win32::GUI::Window); #...but with event handlers for events that may fire sub btnOk_Click { my $self = shift; #the Window object #Change text of the clicked button $self->btnOk->Text( "Ok - " . int(rand(100)) ); return(1); } But that's not how it works. Instead, event handlers based on the -name of the windows and controls created. They are sub routines called in a procedural fashion which requires me as an application programmer to keep track of which window the event belongs to. This is not very convenient. I have not yet seen any "best practice" emerge for dealing with this. Either the window variable needs to be a global or a singleton (which in this case is the same thing, but without the stigma of globals, and people don't argue back when you bring up the havey artillery of design patterns), or it has to be connected to a global or singleton which is your "application" object or whaterver. It's nothing that can't be solved, but it's either inconvenient or not very maintainable. One other drawback with the event-handler-as-procedure approach is that there can only be one instance of the window, because if you create a new window with the exact same names the event handler sub has no way to determine which window fired the event. This can be coded around at great inconvenience (with Perl, few things are impossible). My point is: If only the Window object (or the window object of the control) firing off the event was passed as the first parameter to the event handler everything would be so much easier to live with. Finding the event handler sub in the correct package (OO style) would be a boon. Actually, the result of my holiday hacking today is a module that pretty much does this. Win32::GUI::Window::Object http://www.bahnhof.se/~johanl/perl/Win32GUI/Window/ The synopsis script (below) creates three distinct windows of the same class DemoWindow. The event handlers are methods on a subclass of Win32::GUI::Window, so the context ($self) for all events is the current Window::GUI::Window object. Consider this a proof-of-concept. A test of whether it could be done or not. I've had the idea for a long time, but never had the free time and motivation to actually do it. I have obviously not done anything real with this yet :) - Is this something that seems useful to proceed with? At least the concepts, if not the code? - Is this something that can easily be solved from within Win32::GUI XS code, passing the window object as the first variable ot the event handlers? Perhaps using Perl's OO mechanism so that the correct package is used? Doing it the real way is definitely more stable than my hack. - The subclassing isn't necessary, but could be useful. At the moment, with the objects as hash keys in the object, there is a high risk of clobbering them unintentionally, should people start subclassing Win32::GUI::Window en masse. Perhaps they could be moved to a "_controls" hash ref property of the window or something? Would that be difficult to use from XS code? So finally, an example program using Yet Another Event Model: http://www.bahnhof.se/~johanl/perl/Win32GUI/Window/synopsis.pl.txt #!/usr/local/bin/perl -w use strict; use Data::Dumper; use Win32::GUI; use lib ("../lib"); use Win32::GUI::Window::Object; for (1..3) { my $id = int(rand(100)); my $win = DemoWindow->winCreate($id); $win->Show(); } Win32::GUI::Dialog(); package DemoWindow; #Inherit from the new Window-as-object class use base qw(Win32::GUI::Window::Object); #A demo property to give it some identity use Class::MethodMaker get_set => [ "no" ]; #Class method to create/build a window of this class. It #could eventually be a window built by TGL. # #This could be in the new() method as well, calling the #SUPER::new() to create the object, then setting the no() #property. # sub winCreate { my $pkg = shift; my ($no) = @_; my $self = $pkg->new( -left => 100 + int(rand(400)), -top => 50 + int(rand(200)), -width => 300, -height => 100, -name => "winMain", -text => "Window $no", ); $self->no($no); #Set the demo property my $btnHelloWorld = $self->AddButton( -name => "btnHelloWorld", -text => "Hello world!", -left => 10, -top => 10, -height => 20, -width => 100, ); return($self); } #Event handlers are ordinary methods, with $self as #the first parameter as usual. This gives context to the #event, making it possible to have many instances of the #same window class. sub winMain_Terminate { my $self = shift; print "winMain_Terminate from DemoWindow with no (" . $self->no . ")\n"; return(-1); } sub btnHelloWorld_Click { my $self = shift; my $no = $self->no(); print "btnHelloWorld_Click in DemoWindow no == $no\n"; $self->Text("Window $no - " . int(rand(100)) ); return(1); } __END__ /J -------- ------ ---- --- -- -- -- - - - - - Johan Lindström Sourcerer @ Boss Casinos [EMAIL PROTECTED] Latest bookmark: "ACM Queue - Code Spelunking Exploring Cavernous..." <http://www.acmqueue.com/modules.php?name=Content&pa=showpage&pid=67&page=7> dmoz (1 of 4): /Arts/Music/Bands_and_Artists/T/ 20 ------------------------------------------------------- This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=ick _______________________________________________ Perl-Win32-GUI-Users mailing list Perl-Win32-GUI-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users