Johan,
That is an interesting idea, and of course, makes things more OO-like.
OO-likeness, in my opinion, doesn't necessarily make something better,
but in this case there are a couple benefits that you point out: the
ability to have multiple instances of a Window or widget without name
conflicts, and confusion between the window object variable and its
name. The latter can be "worked around" with naming conventions, of
course, but the former requires either code duplication, or, well,
something like your new module, which is quite a bit of work.
What I can't tell by glancing at your module is whether you can deal
with existing windows using your module. One thing that works today
with Win32::GUI is that you can "take over" an existing Window, and
perform operations on it using the Win32::GUI methods. Does this still
work with your class? I don't know why it wouldn't, but then again, I
didn't try to prove that it would. Your comments on that topic would be
welcome.
Another orthogonal issue is the New Event Model. If it were finished
and working. NEM allows the event subs to be nameless. Of course,
there is still the problem of trying to support multiple instances of a
Window or widget. It is not clear, though, how your approach would
integrate into the NEM. Maybe that doesn't matter, except perhaps to
people that use it. I tried the NEM, but found too many bugs and
missing features. But it appears some people are using it.
None of my current Win32::GUI applications would currently benefit from
being able to have multiple instances of the same sort window, but I can
certainly envision some applications that I might want to write that
could benefit. So that is why I find it an interesting idea.
I imagine that it would be quite simple to add an additional parameter
to the event calls, which would be the window object, as the XS code
does have pointers to sufficient information. Whether that would have a
significant impact on performance, I do not know, but probably there
would be less impact than the approach you have taken in your pure Perl
proof of concept. Certainly it would be less code generated for an
application if done in XS, but also harder to maintain code, probably.
Not sure it would be much harder, though, but XS is more complex than Perl.
Well, there's some initial comments for you to ponder. Not clear that
I'll have the time or need to play with this at the moment, but maybe
someone will.
On approximately 1/4/2004 6:07 PM, came the following characters from
the keyboard of Johan Lindstrom:
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=click
_______________________________________________
Perl-Win32-GUI-Users mailing list
Perl-Win32-GUI-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users
--
Glenn -- http://nevcal.com/
===========================
The best part about procrastination is that you are never bored,
because you have all kinds of things that you should be doing.