[Perl]Win32::GUI官方教程翻译 Part1-窗口配置

来源:互联网 发布:js map 值是否存在 编辑:程序博客网 时间:2024/04/29 06:47

[Perl]Win32::GUI官方教程翻译 Part1-窗口配置

编辑 IF_EXIST / PakTC
mail: 523066680@163.com

所编辑的内容均从该文档中翻译提取,并加上自己的描述:
http://search.cpan.org/~robertmay/Win32-GUI-1.06/docs/GUI/Tutorial/Part1.pod
如果已经安装Win32::GUI模块,

也可以在 C:\Perl\site\lib\Win32\GUI\Tutorial下找到该文档。Notes:

 

\---[Perl]Win32::GUI官方教程翻译Part1-配置窗口
    |   主要内容  
    |     1.使窗口大小适合于label文本
    |     2.使窗口、label的居中
    |     3.设置窗口最小限制
    |   
    |   (说实话,我觉得这里的设置窗体大小的过程挺绕路的……针对第一部分。
    |     后面东西还多着呢,忍忍就过去了)
    |   
    |
    +---1.使窗口大小适合于label文本
    |       $main 继承窗口对象,与窗口大小相关的函数:
    |       属性查询函数:
    |         Width(); 窗口宽度   Height(); 窗口高度
    |         ScaleWidth();  ScaleHeight(); 窗口除了外框,剩下部分的宽度和高度
    |       操作函数:
    |         Resize($宽,$高); 重设当前窗口的宽和高。
    |       
    |       AddLabel(); 同样可以将label对象继承到到变量中:
    |         $label=$main->AddLabel(-text=>"text of label");
    |       通过该对象的 Width(); 和Height(); 函数查询当前label的宽高
    |       
    |       为了让窗口大小刚好适于label文本,首先获取外框尺寸,
    |       然后加上label尺寸,重设窗体大小即可。
    |       
    |           #外框占用空间
    |           $ncw = $main->Width() - $main->ScaleWidth();
    |           $nch = $main->Height() - $main->ScaleHeight();
    |       
    |           #label占用空间+外框空间
    |           $w = $label->Width() + $ncw;
    |           $h = $label->Height() + $nch;
    |       
    |           #重设窗口
    |           $main->Resize($w,$h);
    |       
    |       这段操作应置于创建窗口以及设置label之后,显示窗口之前。
    |         $main=Win32::GUI::Window->new(...);
    |         $label=$main->AddLabel(...);
    |            中间
    |         $main->Show();
    |       
    |       原文代码示例:
    |           use Win32::GUI();
    |       
    |           $text = defined($ARGV[0]) ? $ARGV[0] : "Hello, world";
    |       
    |           $main = Win32::GUI::Window->new(-name => 'Main', -text => 'Perl');
    |           $label = $main->AddLabel(-text => $text);
    |       
    |           $ncw = $main->Width()  - $main->ScaleWidth();
    |           $nch = $main->Height() - $main->ScaleHeight();
    |           $w = $label->Width()  + $ncw;
    |           $h = $label->Height() + $nch;
    |       
    |           $main->Resize($w, $h);
    |           $main->Show();
    |           Win32::GUI::Dialog();
    |       
    |           sub Main_Terminate {
    |               -1;
    |           }
    |       
    |       不过当label占用非常小的时候,由于窗口还需要显示一定的图标,
    |       无法达到一样小。
    |       
    |       分析:这里由于窗口需要重设大小,所以没有必要在 Window->new( 中设置
    |         尺寸。
    |       
    |    
    +---2.使窗口、label的居中
    |       居中窗口
    |       (原文中说GetDesktopWindow返回一个handle,不过我觉得翻译为对象也OK)
    |       
    |       首先可以通过 Win32::GUI::GetDesktopWindow(); 获取桌面窗口对象,
    |       有一点要说的是,这不同于 Win32::GUI::Window ,
    |       不能通过->Width(); ->Height();这样的方式获取桌面分辨率。
    |       而通过类如 Win32::GUI::Width(对象) 的形式 获取桌面的宽。
    |       
    |       窗口对象的 Move();函数可以修改当前窗口位置,以下是一段实例:
    |       
    |           # Assume we have the main window size in ($w, $h) as before
    |           $desk = Win32::GUI::GetDesktopWindow();
    |           $dw = Win32::GUI::Width($desk);
    |           $dh = Win32::GUI::Height($desk);
    |           $x = ($dw - $w) / 2;
    |           $y = ($dh - $h) / 2;
    |           $main->Move($x, $y);
    |       
    |       label的居中
    |       OK,现在还要使label文本始终居中在窗口中间,考虑到用户可能手动改变窗体
    |       大小,所以这里设置一个事件处理函数,原文实例+注释:
    |       
    |           sub Main_Resize {                       # Main窗口的 Resize事件
    |               my $mw = $main->ScaleWidth();       # 有效区域宽 Scale可以译为画布
    |               my $mh = $main->ScaleHeight();      # 有效区域高
    |               my $lw = $label->Width();           #
    |               my $lh = $label->Height();          
    |               if ($lw > $mw) {                    #如果 label所需空间 > 可用空间
    |                   $main->Width($lw + $ncw);       #  使$main窗口的宽=label宽+外框宽 [大小刚刚好]
    |               }                                   #  注: $ncw 是外部定义的边框占用宽度
    |               else {                              #其他情况:
    |                   $label->Left(($mw - $lw) / 2);  #  通过设定label左上角位置使其居中
    |               }                                   
    |               if ($lh > $mh) {                    #跟Width一样,做类似的处理
    |                   $main->Height($lh + $nch);      # Remember the non-client height!
    |               }                                   # ok , 原来nch是 non-client height 的缩写
    |               else {                              # 这里指的是非有效区域,标题栏或者外框占用高度
    |                   $label->Top(($mh - $lh) / 2);   #
    |               }                                   #
    |           }                                       #
    |       
    |       接着的效果是如果你拉宽或者拉高窗口,label文本始终居中,
    |       如果拉小了,比文本还小,则会反弹为刚好足够存放文本的大小。
    |       
    |               另外这段代码告诉我们,$main->Width();这样的操作函数,
    |               在参数为空的时候可以用于查询当前宽度,如果有参数,
    |               则设置当前宽度。 Label对象也是如此 ,另外还出现了
    |               label->Left(值); #设置左端位置  这个位置是相对于$main窗口之内的。
    |               label->Top(值);  #设置上端位置
    |       
    |               同样也有 $main->Left(); $main->Top();
    |               稍微总结一下,Win32::GUI::Window->new(); 其中可以包含参数:
    |               -name 标识名称
    |               -text 文本标题
    |               -left 左端位置
    |               -top  上端位置
    |               -width 宽度
    |               -height 高度
    |       
    |          像这些普通的选项都有对应的操作函数:
    |          $main->Text();
    |          $main->Left(); ....等等,可用于查询,也可用于设置
    |          ->Name就不要了…… 危险
    |       
    |       
    |       YY多了,要是错了就成罪人了,回到正题。
    |       
    |    
    \---3.设置窗口最小限制
            假设我们要保证窗口不小于100x100 分辨率单位,我们可以将重置代码写入
            Resize事件处理函数,但是这样比较费事,一个更好的办法是通过 -minsize 选项
                $main = Win32::GUI::Window->new(
                    -name => 'Main',
                    -text => 'Perl',
                    -minsize => [100, 100],
                );
            
            为了使minsize的大小适合于文本,这一项应该在AddLabel之后设置,
            我们可以通过窗口对象的 Change 函数修改 -minsize 的属性,
                $main->Change(-minsize => [$w, $h]);
            
            完整代码:
                use Win32::GUI();
            
                $text = defined($ARGV[0]) ? $ARGV[0] : "Hello, world";
            
                $main = Win32::GUI::Window->new(
                    -name => 'Main',
                    -text => 'Perl',
                );
                $font = Win32::GUI::Font->new(
                    -name => "Comic Sans MS",
                    -size => 24,
                );
                $label = $main->AddLabel(
                    -text => $text,
                    -font => $font,
                    -foreground => [255, 0, 0],
                );
            
                $ncw = $main->Width() -  $main->ScaleWidth();
                $nch = $main->Height() - $main->ScaleHeight();
                $w = $label->Width()  + $ncw;
                $h = $label->Height() + $nch;
            
                $desk = Win32::GUI::GetDesktopWindow();
                $dw = Win32::GUI::Width($desk);
                $dh = Win32::GUI::Height($desk);
                $x = ($dw - $w) / 2;
                $y = ($dh - $h) / 2;
            
                $main->Change(-minsize => [$w, $h]);
                $main->Resize($w, $h);
                $main->Move($x, $y);
                $main->Show();
            
                Win32::GUI::Dialog();
            
                sub Main_Terminate {
                -1;
                }
            
                sub Main_Resize {
                    my $mw = $main->ScaleWidth();
                    my $mh = $main->ScaleHeight();
                    my $lw = $label->Width();
                    my $lh = $label->Height();
            
                $label->Left(int(($mw - $lw) / 2));
                $label->Top(int(($mh - $lh) / 2));
                }
原创粉丝点击