Powerbuilder之5年经验谈(一之2)--PB的关键字Create

    返回目录                                          返回  下页

若需制成电子文档并用于非商业用途方式的传播,请保留以下版权信息,并与笔者联系邮寄副本一份。

作者:张楠

网名:SummerHeart

Email:Costware@163.com

Bloghttp://summerheart.cnblogs.com/

      http://blog.csdn.net/summerheart

时间:2008.5.30          Copyright: 2008

1.2PB的对象和类

熟悉面向对象的朋友,最先认识的应该是类(Class),但在PB中从头到尾似乎只有对象(Object)而没有类(Class)。类是从对象中抽象出来的概念,它并不能被直接使用,类只有在实例化后才能使用它,实例化的类我们称之为对象(Object)。

Menu lm_menu

lm_menu = Create Menu

严格来讲所有类的创建都该如上的代码一样使用Create关键字(有关Create请参阅相关章节)。然而有种情况例外:如果你自己定义过一个NoVusialObject,你会发现在定义的过程中NoVusialObject的属性页上有个AutoInstantiate的选项。NoVusialObject加上了这个属性,在你使用的时候就不用Create进行创建而像Structure一样定义后就可直接使用。

在PB中文档至始至终的出现Object这个词,例如介绍菜单时使用的名称是Menu Object 而不是 Menu Class。得承认PB的这种做法在概念上有误导程序员的可能,至少开始时我就是这样的以为对象就是类。但对于我们程序员来计,应该有Class与Object是有分别的这么个概念。为了概念上不至于混淆,笔者将在本系列文章中一贯的遵循这种概念上的叫法。

1.3 值得注意的几个关键字

1.3.1 Create的适合场合

Create是用来创建对象用的,可以说几乎所有的类都需要创建。它有两种使用形式:

 

      listview lv_view

1 .lv_view  =   Create  listview

2 . lv_view  =   Create  using "listview" 

 

所有的类(参见PB对象与类)在使用前都应该使用Create进行创建,然而有几种场合下不需要这么做,比如:

1.      你定义了一个窗口,在代码中,你不需要使用Create,而是直接Open()就可以显示该窗口了;

2.      对于窗口中的控件,你可以直接使用控件而不需要手动Create;

3.      SQLCA对象可以直接使用,其实它是一个transaction的全局对象。

情况1、2,用Create然后再open、或show是不会显示窗口的,但可以对窗窗口的属性或窗口上的控件可以引用了。说明对象已经被创建,但为什么没显示,答案看来只有Sybase才能回答了。但我在这想说的是open他包括了对窗口及窗口中的控件的创建过程,所以在我们写代码时近量不要总是只用open来打开窗口,特别是经常会多次打开同一窗口时,因为创建会消耗系统时间,而应该这么写:
If   not  IsValid (w_mywin)   then
    
Open (w_mywin)
End   if  
 

不妨作个测试,测试1代码如下:

int  i,t1 ,t2
t1 
=  cpu()
for  i  = 1   to   10000
    
open (  w2 )
next
t2 
=  cpu() –t1
messagebox("",t2)

以上代码写在application对象的open事件里,w2是个只带一个buttonmain!窗口,最终编译成exe运行几次后,t2显示的时间650-700毫秒左右。让我们再作个测试,测试2代码如下:

int  i,t1 ,t2
t1 
=  cpu()
for  i  = 1   to   10000
if   not  invalid(w2)  then
        
open (  w2 )
end   if
next
t2 
=  cpu() –t1
messagebox("",t2)
 

同样最终编译成exe运行几次后,t2显示的时间30--50毫秒之间。由以上两个例子可以看出,Open是很花时间的,因为它在每次执行时都要创建窗口。

当然,光这样还说明不了系统在Create花费的时间,我们不妨把上述的例子作个修改:

Window lw_win       //开头加上此定义

测试1的循环里改为(测试1-)

lw_win =Create w2

测试2的循环里改为(测试2-1):

If not invalid(lw_win) then

   lw_win =Create w2

end if

同样的分别编译后再运行,测试1-1的时间在250-300之间,而测试2-1的时间始终为0毫秒

由此可以看出PBCreate上花费的时间是很多的。不仅如此,创建出来的对象,在用不着的时候,PB不得不再调用垃圾回收器进行回收,这又将时一笔额外的时间开销。而使用isValid则可大大的减少这两方面不必要的花费。就这一点而言,NoVusialObject对象更应该注意这一点,一则防止上述的时间花费问题,二则防止出现对象未创建就直接使用的情况发生。

至此,既然前面我们已经探讨了window对象创建的时间问题,不妨我们再进一步探讨下window的创建都要做哪些事情。细心的朋友可能已经发现上述的测试1和测试11分别是对窗口用了OpenCreate的工作,而二者之间消耗的时间前者是后者的两倍,为什么?这需要我们来了解下window程序的窗口创建过程。

写过WIN32程序的朋友对这点自然可以明白,在用WIN32编程中要创建一个窗口需要做几步工作:1.注册窗口类;2.创建窗口;3.显示窗口;4.在屏幕上绘制窗口;5.进行窗口消息循环。以下是显示一个最简单的WIN32窗口的例子。
Code
HELLOWIN.C        
/**//*------------------------------------------------------------------------      
HELLOWIN.C -- Displays "Hello, Windows 98!" in client area        
(c) Charles Petzold, 1998        
-----------------------------------------------------------------------
*/
        
#include 
<windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,        
                    PSTR szCmdLine, 
int iCmdShow)        
{        
    
static TCHAR szAppName[] = TEXT ("HelloWin") ;        
    HWND   hwnd ;        
    MSG    msg ;        
    WNDCLASS   wndclass ;                    
//定义窗口类
    wndclass.style        = CS_HREDRAW | CS_VREDRAW ;        
    wndclass.lpfnWndProc  
= WndProc ;        
    wndclass.cbClsExtra   
= 0 ;        
    wndclass.cbWndExtra   
= 0 ;        
    wndclass.hInstance    
= hInstance ;        
    wndclass.hIcon        
= LoadIcon (NULL, IDI_APPLICATION) ;        
    wndclass.hCursor      
= LoadCursor (NULL, IDC_ARROW) ;        
    wndclass.hbrBackground
= (HBRUSH) GetStockObject (WHITE_BRUSH) ;        
    wndclass.lpszMenuName  
= NULL ;        
    wndclass.lpszClassName
= szAppName ;       
    
if (!RegisterClass (&wndclass))        //1.注册窗口类
    {        
        MessageBox (  NULL, TEXT (
"This program requires Windows NT!"),szAppName, MB_ICONERROR) ;        
        
return 0 ;        
    }
        
    
//2.创建窗口
    hwnd = CreateWindow( szAppName,      // window class name        
        TEXT ("The Hello Program"),   // window caption        
        WS_OVERLAPPEDWINDOW,  // window style        
        CW_USEDEFAULT,// initial x position        
        CW_USEDEFAULT,// initial y position        
        CW_USEDEFAULT,// initial x size        
        CW_USEDEFAULT,// initial y size        
        NULL,                 // parent window handle        
        NULL,            // window menu handle        
        hInstance,   // program instance handle        
        NULL) ;      // creation parameters   

    ShowWindow (hwnd, iCmdShow) ; 
//3.显示窗口
    UpdateWindow (hwnd) ;            //4.绘制窗口
    while (GetMessage (&msg, NULL, 00)) //5.获取消息,并进入消息循环
    {
        TranslateMessage (
&msg) ;
        DispatchMessage (
&msg) ;
    }

    
return msg.wParam ;
}


//消息处理函数
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    HDC         hdc ;
    PAINTSTRUCT    ps ;
    RECT        rect ;
    
switch (message)
    
{
    
case WM_CREATE:
        PlaySound (TEXT (
"hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
        
return 0 ;
    
case   WM_PAINT:
        hdc 
= BeginPaint (hwnd, &ps) ;
        GetClientRect (hwnd, 
&rect) ;
        DrawText (hdc, TEXT (
"Hello, Windows 98!"), -1&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
        EndPaint (hwnd, 
&ps) ;
        
return 0 ;
    
case   WM_DESTROY:
        PostQuitMessage (
0) ;
        
return 0 ;
    }

    
return DefWindowProc (hwnd, message, wParam, lParam) ; //将消息交由系统处理
}

 

窗口产生的大致流程图如下,标在①②③④的为消息循环的顺序,这个循环一直会循环反复,直到中接收到WM_QUIT这个消息才退出循环结束程序运行。


 

由此可以看到,窗口的创建时间消耗大部分时间是在消息循环中。在做前面的4个测试时你可能会发现,用Create的例子执行后并没有窗口显示。而用open的会显示窗口。原因很简单,PB在执行Create时仅仅是创建了窗口及窗口中的控件,而并没有“显示窗口”,更没有让窗口进行“消息循环”。怎么样说明这一点呢,很简单,只要在窗口中的某个控件的constructor事件中写条messagebox语句就知道了。执行Create后并不会弹出messagebox来,但你可以以mywin.mycontrl.property的形式对控件的属性进行操作,说明1.窗口创建时,连同窗口里的控件也被创建;2.窗口创建后,PB没有让窗口接受任何的事件,至于Windows产出的WM_CREATE事件也许产生了也许并未产生,只有Sybase知道了。然而用Open打开的窗口,不用说是执行了完整的窗口产生过程,并开始了消息循环的。而且控件的constructor事件会被先执行,即显示窗口之前会弹出messagebox对话框。

情况3,是因为SQLCAapplication的附加属性里被字义为全局对象变量。

对于Create using 其实PB中不只Create可以带using,像Connect 等也可以带using,这种作为使用程序变的更加灵活。通过一个字符串进行对象创建,这种技术是需要一种叫RTTI(运行时类型识别)技术才能做到的。也就是若你有类的继承关系如下:

Windowàmywin1àmywin2

那么你可以使用

Window lw_win

lw_win = create using "mywin2"

就能创建窗口mywin2,这里的lw_win其实相当于指向一个mywin2对象的指针。Using将在后面的章节以实例作应用性讲解。
  返回目录                                          返回  下页

转载于:https://www.cnblogs.com/SummerHeart/archive/2008/06/01/1211749.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值