From: Veli-Pekka <vt...@ma...> - 2007-07-25 13:29:43
|
Hi list, I think I've found a bug or oddity in Win32::GUI::AcceleratorTable and have vague suggestions on how to improve the already very handy GridLayout control. I've discovered that if the accelerator object associated with a window goes out of scope, the accelerators appear to stop working for that window. This is quite odd in that I thought Perl's reference counting would ensure that the object won't get destroyed until all references to it have been. Surely a window with an accelerator has a reference to that accelerator, right? Maybe it only stores the handle of the actual Win32 accelerator table and not a Perl reference, this would explain a lot. Here's a barebones script to demonstrate the problem. FIrst the case where the accelerators are global: use strict; use warnings; use Win32::GUI; my $keys = Win32::GUI::AcceleratorTable->new(a => sub{ print "A" }); my $win = Win32::GUI::Window->new ( -size => [320, 200], -accel => $keys, -onTerminate => sub { -1 }, -onTimer => sub { print "." }, ); $win->AddTimer(clock => 1000); $win->Show(); Win32::GUI::Dialog(); This works as expected printing the dots when the timer gets triggered and printing a when-ever you hit the letter a and the window has the focus. Now, say we write a sub that returns the main window and associates it with an accelerator. The differences to the above are the third statement: my $win = mainWindow(); and later the almost identical code in the sub: sub mainWindow { my $keys = Win32::GUI::AcceleratorTable->new ( a => sub{ print "A" } ); return Win32::GUI::Window->new ( -size => [320, 200], -accel => $keys, -onTerminate => sub { -1 }, -onTimer => sub { print "." }, ); } # sub These changes result in the accelerators not working i.e. the functions don't get called. Secondly, I know this is much easier said than done, but would be great if the GridLayout control could be improved to be more like layout managers are in other UIs. I see two primary problems with it. As it is not really a Win32::GUI control in the traditional sense, you cannot nest grids inside each other for complex layouts. secondly, the grid is equally spaced as far as I've understood it. Would be nice if it adapted to the size of the control put in a particular location, so you could layout a grid without having to worry about the containing controls' sizes, Java's Swing has excellent layout managers that fill both gaps I mentioned but they are fairly complex. I've found that Gnome's take on things is relatively simple to use and gets most jobs done all right. Here's a brief and high-level explanation with in-line imagery: <http://www.gtk.org/tutorial1.2/gtk_tut-4.html> As GTK+ is open source, I wonder if you could actually borrow some of the code doing the hard parts and rewrite only Win32 specific bits. The grid control could then be XS code, too, like most of the Win32::GUI package appears to be -> at least I cannot find many pm files. This is minority stuff, but optionally having the grid start its indexing at $[ would be cool, too. While we're at this, could not you make a grid object that works like an array or ref to one but let's you call methods on it? Usage would be more intuitive then. I thought about this and tentatively concluded that Perl 5 cannot do that. Tied arrays lose their objectness and having the user directly access object internals as an array leads one to trouble, even if you'd store object data at the end or have per-object data as elements in a class array datum. OBjects that also look like arrays are trivial in, say, Ruby, though I mostly use Perl because of PPM and all the nifty modules like Win32::GUI, for example. For me this is an accessibility issue, my screen reader does not support most 3rd party UIs. Finally, my machine says: This is perl, v5.8.8 built for MSWin32-x86-multi-thread (with 50 registered patches, and also, Documentation for Win32::GUI v1.03 created 16 Mar 2006 Hope this can be of help. -- With kind regards Veli-Pekka Tätilä (vt...@ma...) Accessibility, game music, synthesizers and programming: http://www.student.oulu.fi/~vtatila |
From: Salvador O. <so...@ms...> - 2007-07-25 20:56:53
|
On Wed, 2007-07-25 at 16:29 +0300, Veli-Pekka Tätilä wrote: > Hi list, > I think I've found a bug or oddity in Win32::GUI::AcceleratorTable > ... Yes, right now only the internal handlers are stored in the associated window, a bug IMHO. BTW the same happens with a menu. As time permits I've be working in a proper fix, but as a quick workaround in my apps I store the perl objects in the window hash: sub CreateAll { my $menu = Win32::GUI::MakeMenu(...); my $accel = Win32::GUI::AcceleratorTable->new(...); my $rootWin = Win32::GUI::Window->new( ... -menu => $menu, -accel => $accel, ... ); # Workaround for window not storing the perl object. # I use the '_' prefix to avoid name clashes with child's named $rootWin->{_Menu} = $menu; $rootWin->{_Accel} = $accel; ... return $rootWin; } -- Salvador Ortiz García <so...@ms...> Matías Software Group |
From: Robert M. <rob...@us...> - 2007-07-26 20:03:17
|
On 25/07/07, Salvador Ortiz Garc=EDa <so...@ms...> wrote: > On Wed, 2007-07-25 at 16:29 +0300, Veli-Pekka T=E4til=E4 wrote: > > Hi list, > > I think I've found a bug or oddity in Win32::GUI::AcceleratorTable > > ... > > Yes, right now only the internal handlers are stored in the associated > window, a bug IMHO. Probably, but it's not a straightforward fix. > BTW the same happens with a menu. and fonts, and probably other non-window objects. > As time permits I've be working in a proper fix, That's great - I look forward to it. You might want to have a discussion with me about this, as I've looked into it briefly before, and if I remember correctly there are a number of edge cases to watch out for. > but as a quick > workaround in my apps I store the perl objects in the window hash: It's better practice to use the UserData() or ClassData() methods to store data with a window - that's the documented interface - and will remain supported. Poking directly into the representation of an Object is unhealthy. Regards, Rob. |
From: Robert M. <rob...@us...> - 2007-07-26 20:26:59
|
On 25/07/07, Veli-Pekka T=E4til=E4 <vt...@ma...> wrote: > Secondly, I know this is much easier said than done, but would be great > if the GridLayout control could be improved to be more like layout > managers are in other UIs. I'd like to see a family of layout modules, offering capabilities from the simplest grid layout through more complex schemes. I'm got a half-written layout manager that works somewhat like Tk's pack() command, but I'm not doing well on finding the tuits to complete it. > Java's Swing has excellent layout managers that fill both gaps I > mentioned but they are fairly complex. I've found that Gnome's take on > things is relatively simple to use and gets most jobs done all right. > Here's a brief and high-level explanation with in-line imagery: > > <http://www.gtk.org/tutorial1.2/gtk_tut-4.html> Thanks - I hadn't seen this one before. Having read it, I think that what I'm working on, along with an enhanced grid layout manager would probably do just about everything I can think of. > As GTK+ is open source, I wonder if you could actually borrow some of > the code doing the hard parts and rewrite only Win32 specific bits. The > grid control could then be XS code, too, like most of the Win32::GUI > package appears to be -> at least I cannot find many pm files. I'm not sure that it's a very hard problem - box layout is a well understood problem, it's just a bit tedious getting all the calculations correct and not having any 'off by one' errors. I'm actually of the opinion that we should be moving more of the code back into perl from XS. I don't think that speed is really much of an issue for most GUI apps - and if we do have performance problems we could keep the critical bits in XS. The biggest advantage of moving more of the code into perl would be that people who are not Win32 API gurus can see how things are done, and modify things that they need to. I've got a side project going on at the moment to look at this. > This is minority stuff, but optionally having the grid start its > indexing at $[ would be cool, too. While we're at this, could not you > make a grid object that works like an array or ref to one but let's you > call methods on it? Usage would be more intuitive then. I thought about > this and tentatively concluded that Perl 5 cannot do that. Tied arrays > lose their objectness and having the user directly access object > internals as an array leads one to trouble, even if you'd store object > data at the end or have per-object data as elements in a class array > datum. OBjects that also look like arrays are trivial in, say, Ruby, > though I mostly use Perl because of PPM and all the nifty modules like > Win32::GUI, for example. For me this is an accessibility issue, my > screen reader does not support most 3rd party UIs. overloading allows objects to look like arrays - its not something I've played with extensively, and I'm not sure that you can asign to the array, but try reading up on the overload.pm pragma. Regards, Rob. |
From: Veli-Pekka <vt...@ma...> - 2007-07-27 08:32:08
|
Robert May wrote: > > but as a quick > > workaround in my apps I store the perl objects in the window hash: > It's better practice to use the UserData() or ClassData() methods to > store data with a window - that's the documented interface - Yup I've noticed, it can be quite useful. Here's a real world example in my first major Win32::GUI project: in my little Perl drum machine I had 16 checkboxes without labels and had a unified -onClick event handler for all of them, which just tells the current track object to check the step number to which the box corresponds. I was faced withthe the problem of how to identify which box is which and storing its number as the user data 1 .. 16 solved this elegantly. I just ask the box whether it is checked and query the user data, which gives me enough info. -- With kind regards Veli-Pekka Tätilä (vt...@ma...) Accessibility, game music, synthesizers and programming: http://www.student.oulu.fi/~vtatila |
From: Veli-Pekka <vt...@ma...> - 2007-07-27 13:07:20
|
Hi Robert, First of all, good to hear you are working on a TK-like layout manager. I'm looking forward to its release. Although another great way to do GUis would be to design them with the Visual Studio tools and then load the resources in Win32::GUI. Is that supported, i.e. can I load plain Win32 dialogs or menus and have Perl do the event handling? I suppose not. Robert May wrote: > I'm actually of the opinion that we should be moving more of the code > back into perl from XS. <snip> > The biggest advantage of moving more of the code into perl would be > that people who are not Win32 API gurus can see how things are done, > and modify things that they need to. Well said I second that request. I've lately learned that if I don't get something in the API docs or want to learn how some processing is done, I can always check the source with ease. That's great. This reminds me of some misc questions I have about controls: Is the Win32::GUI::MakeMenu() function documented as used by the Notepad example in 1.03? I don't see it mentioned anywhere. What's the difference between track bar and slider? i used the slider and it works great. However, my screen reader and MSDN calls the control a track bar. Most people I know talk casualy about sliderse or faders if it is a mixer. Also I had two initial problems with the slider control. I failed to specify a size and was slightly disappointed that sliders cannot bundle a label with the control like check boxes can. Chek boxes don't even need their size specified. Would be nice if sliders had a default size, too, though maybe this is a mishap in the underlying Win32 APi. On a more general note, how do I specify the tab order in a dialog? It seems to me the tab order is analogous to the insertion order which is mostly OK but not always. Last but not least, how do I indicate that a group of radio buttons forms a radio control? Oh and before I forget: I have an unusual keybord interface where I'd like a push button to be pushed down while a key is hehld down and released on key up. How would I go about this, are there key up / down events for buttons and how do I programmatically push a button in stead of clicking it which means push and release? Can I ignore keyboard messages that are a result of Windows's key repeat when a key is held down? -- With kind regards Veli-Pekka Tätilä (vt...@ma...) Accessibility, game music, synthesizers and programming: http://www.student.oulu.fi/~vtatila |
From: Robert M. <rob...@us...> - 2007-07-27 19:45:16
|
On 27/07/07, Veli-Pekka T=E4til=E4 <vt...@ma...> wrote: > First of all, good to hear you are working on a TK-like layout manager. > I'm looking forward to its release. Don't hold you breath :-) Just because it's on my list doesn't mean that I'll get around to it. Of course, anyone else is free to write something and either release it themselves, or submit it for inclusion with Win32::GUI. > Although another great way to do > GUis would be to design them with the Visual Studio tools and then load > the resources in Win32::GUI. Is that supported, i.e. can I load plain > Win32 dialogs or menus and have Perl do the event handling? I suppose > not. It would be possible to make this work, but I believe that our target audience is primarily people who do not have access to the MS toolchain - so it's not something I'm likely to look at. > Is the Win32::GUI::MakeMenu() function documented as used by the Notepad > example in 1.03? I don't see it mentioned anywhere. I don't think so. Documentation patches are always welcome! > What's the difference between track bar and slider? i used the slider > and it works great. However, my screen reader and MSDN calls the control > a track bar. Most people I know talk casualy about sliderse or faders if > it is a mixer. MS call the control the TrackBar control in their documentation. Win32::GUI::Slider appears to be an alias for Win32::GUI::Trackbar - so I don't think there's a difference other than their name. > Also I had two initial problems with the slider control. I failed to > specify a size and was slightly disappointed that sliders cannot bundle > a label with the control like check boxes can. Chek boxes don't even > need their size specified. Would be nice if sliders had a default size, > too, though maybe this is a mishap in the underlying Win32 APi. What default size would you suggest for a slider? Like many of the controls there isn't really a natural default size, so Win32::GUI uses [0,0] if you don't provide one. Slider controls suooper a concept called 'buddy' windows - you can attach another window to the left/top or right/bottom (depending if the slider is horizonal or vertical). See the SetBuddy method. It works like this: #!perl -w use strict; use warnings; use Win32::GUI 1.05 qw(CW_USEDEFAULT); my $mw =3D Win32::GUI::Window->new( =09-title =3D> "Slider Demo", =09-size =3D> [400,300], ); my $slider =3D $mw->AddSlider( =09-pos =3D> [30,10], =09-size =3D> [100,30], =09-selrange =3D> 0, ); $slider->SetBuddy(1, $mw->AddLabel(-text =3D> 'Min')); $slider->SetBuddy(0, $mw->AddLabel(-text =3D> 'Max')); $mw->Show(); Win32::GUI::Dialog(); $mw->Hide(); __END__ > On a more general note, how do I specify the tab order in a dialog? Tab order is the same at the "z-order" of the child windows. Whenever a child window is created it is but at the end of the z-order list, and so by default the tab-order is the order of window creation. You can the z-order by using SetWindowPos() like this: $window_to_reorder->SetWindowPos($window_to_insert_after, 0 ,0 ,0 ,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIATE); > Last but not least, how do I indicate that a > group of radio buttons forms a radio control? Research the WS_GROUP window style, and use the -group option to set it. > Oh and before I forget: > I have an unusual keybord interface where I'd like a push button to be > pushed down while a key is hehld down and released on key up. How would > I go about this, are there key up / down events for buttons and how do I > programmatically push a button in stead of clicking it which means push > and release? Can I ignore keyboard messages that are a result of > Windows's key repeat when a key is held down? Generally unusual user-interface behaviour is a very bad idea. If you're sure that you want to proceed with this then from your description you're heading in the right direction. I don't immediately remember if Win32::GUI::Button's allow easy access to WM_KEYDOWN/WM_KEYUP messages, but you can always Hook() them. You want the $button->SetState(1) to programatically make the button look like it is pushed. Reagrds, Rob. |