From: Stephen P. <Ste...@uc...> - 2003-12-16 11:14:59
|
Hi, The problem is simply that the implementation of relative co-ordinates = is not done properly.=20 If you make a parent window and give it a child window that is a = DialogBox, then position the main window at screen co-ordinates 100x100, = then call $CHILD->Top(0); to position child window at the very top of the screen, the child window = will move to the top of the screen but WILL ALSO MOVE 100px TO THE LEFT = because Win32::GUI is treating the relative X co-ordinate it gets using = ScreenToClient() as an absolute co-ordinate when it passes it to = SetWindowPos(). The Y co-ordinate given as the argument (0) is not = converted by ScreenToClient() since it's not part of (and not put into) = the myRect struct, and therefore is passed directly to SetWindowPos = resulting in correct, absolute positioning for the Y co-ordinate. The = same goes for the Left() function, but the co-ordinate affected by the = bug is then the Y co-ordinate instead of the X co-ordinate. This is the bug I'm on about, and this is the bug that I believe I have = fixed. The child window must be a DialogBox. The correct behaviour perhaps, for dialogboxes, is for Top(0) to = position them at the Y co-ordinate of their parent, however this is not = what I would expect Top(0) to do. To be honest I'm not sure why = Win32::GUI makes the distinction between a Window and a DialogBox = anyway, internally both are the same thing with slightly different = styles. I can't see any real justification for just using = Win32::GUI::Window at all (other than the fact that it does not suffer = from this bug :) ). The code here demonstrates the problem: use Win32::GUI; my $PARENT =3D new Win32::GUI::DialogBox( -name =3D> "ParentWin", -left =3D> 100, -top =3D> 100, -width =3D> 100, -height =3D> 100, -text =3D> "Parent" ); $PARENT->Show; my $CHILD =3D new Win32::GUI::DialogBox( -name =3D> "ChildWin", -left =3D> 400, -top =3D> 200, -width =3D> 100, -height =3D> 100, -text =3D> "Child", -parent =3D> $PARENT ); $PARENT->AddButton( -name =3D> "movechild", -left =3D> 10, -top =3D> 10, -right =3D> 10, -width =3D> 70, -height =3D> 25, -text =3D> "Move child" ); $CHILD->Show; Win32::GUI::Dialog; sub ::movechild_Click { print "Child X co-ordinate: ".$CHILD->Left()."\n"; $CHILD->Top(0); print "Child X co-ordinate after Top(0): ".$CHILD->Left()."\n"; return 0; }; If that's the behaviour YOU expect then I strongly disagree with you. = Setting Top() should certainly NOT affect Left(). Steve -----Original Message----- From: per...@li... [mailto:per...@li...]On Behalf Of Laurent ROCHER Sent: 15 December 2003 23:03 To: Steve Pick Cc: Win32 GUI Hackers Subject: Re: [perl-win32-gui-hackers] bugfixed some cvs Hi, > Just fixed a bug with windows that had the -parent option given, and = were > then positioned with the Left() and Top() methods. These methods were > detecting that the window had a parent and were translating X (in the = case > of Top() ) and Y (in the case of Left() ) into the current X or Y > co-ordinate minus the parent X or Y co-ordinate, causing child windows that > were sent multiple Top(somenumber) or Left(somenumber) calls to "walk" > horizontally or vertically across the desktop in steps dependent on = the > position of their parent window. Nasty. I'm not understand your problem and bug fix. For me, coordinate of a child windows is relative to parent window and = not screen relative. Only main window are screen coordinate. I have test sample below with your change, and button move when sizing = or main window move. Button should alway be at 5,5 in main window, with AddButton or with new GUI::Button + parent option. use Win32::GUI; $W =3D new Win32::GUI::Window( -title =3D> "test", -left =3D> 100, -top =3D> 100, -width =3D> 280, -height =3D> 280, -name =3D> "Window", ); # $button =3D $W->AddButton( # This keep button = as 5,5 $button =3D new Win32::GUI::Button( -parent =3D> $W, # This move button -name =3D> "Simple1", -left =3D> 5, -top =3D> 5, -width =3D> 122, -height =3D> 400, -text =3D> "Just button", ); $W->Show; Win32::GUI::Dialog(); sub Window_Terminate { return -1; } sub Window_Resize { $button->Left(5); $button->Top(5); print "Resize !!!\n"; } > > You might be confused as to why I fixed this in quite the way I did (setting > a flag in userdata if the user specifies -parent). > > I did this because I wanted to preserve the ability to explicitly call > SetParent on a window to insert it into another window's client area. = This > is an especially handy trick for making hidable/moveable panes without > moving all the widgets one by one. If I simply detected if the thing = that > was having Top/Left set was a window or not, it would not translate = the > co-ordinates when it should do. If you want move or hide a group of widget, it's better to create all = widget directly to a parent/container window. And move or hide this container window. Some thing like that : use Win32::GUI; $W =3D new Win32::GUI::Window( -title =3D> "test", -pos =3D> [100, 100], -size =3D> [280, 280], -name =3D> "Window", ); $Grp1 =3D $W->AddGroupbox( -name =3D> "Groupe", -text =3D> "Groupe", -pos =3D> [5, 5], -size =3D> [122, 200], ); new Win32::GUI::Button ( -parent =3D> $Grp1, -name =3D> "Test", -text =3D> "Test!!!", -pos =3D> [20, 20] ); $W->AddButton ( -name =3D> "Hide", -text =3D> "Hide it", -pos =3D> [200, 5], ); $W->AddButton ( -name =3D> "Show", -text =3D> "Show it", -pos =3D> [ 200, 40], ); $W->AddButton ( -name =3D> "Move", -text =3D> "Move it", -pos =3D> [200, 75], ); $W->Show; Win32::GUI::Dialog(); sub Window_Terminate { return -1; } sub Test_Click { print "test !!!\n"; } sub Hide_Click { $Grp1->Hide(); } sub Show_Click { $Grp1->Show(); } sub Move_Click { $Grp1->Top($Grp1->Top + 2); } You can look on my TabFrame package, i have a Frame.pm class with act as window container. Frame heritate from Win32::GUI::Window so you can use standard = Add<Control> method. If you really need use SetParent for runtime change, i think it's = probably better to add set functionnality to AbsLeft and AbsTop. And use those functions rather Left and Top. Laurent. ------------------------------------------------------- This SF.net email is sponsored by: SF.net Giveback Program. Does SourceForge.net help you be more productive? Does it help you create better code? SHARE THE LOVE, and help us help YOU! Click Here: http://sourceforge.net/donate/ _______________________________________________ Perl-Win32-GUI-Hackers mailing list Per...@li... https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-hackers |