在 IIS 7.0 中,您可以创建网站、Web 应用程序和虚拟目录,以便与 Internet、Intranet 或 Extranet 上的用户共享信息。网站、Web 应用程序和虚拟目录以一种分层结构的关系协同进行工作,用作寄存联机内容的基础构建块。

简而言之,网站包含一个或多个 Web 应用程序,Web 应用程序包含一个或多个虚拟目录,虚拟目录则映射到 Web 服务器或远程计算机上的物理目录。下面的小节将分别详细介绍这三个概念。

什么是网站?
网站是 Web 应用程序的容器,您可以通过一个或多个唯一绑定来访问网站。网站绑定由 IP 地址、端口和可选的主机头组合而成,HTTP.sys 在此侦听对网站的请求。

什么是 Web 应用程序?
Web 应用程序是一种在应用程序池中运行并通过 HTTP 协议向用户提供 Web 内容(通常以 HTML 格式)的软件程序。创建 Web 应用程序时,Web 应用程序的名称将成为网站 URL 的一部分,用户可以通过 Web 浏览器请求该 URL。

在 IIS 7.0 中,每个网站必须拥有一个必需的 Web 应用程序,它被称为根 Web 应用程序或默认 Web 应用程序。但网站可以包含多个 Web 应用程序。例如,您可能有一个在线商务网站,该网站包含若干 Web 应用程序,例如购物车应用程序和登录应用程序,前者允许用户在购物过程中收集商品,后者允许用户在购买时回溯已保存的支付信息。

什么是虚拟目录?
虚拟目录是您在 IIS 中指定并映射到本地或远程服务器上的物理目录的目录名称。然后,目录名称将成为 Web 应用程序 URL 的一部分,用户可以通过 Web 浏览器请求该 URL 以访问物理目录的内容,例如网页或其他目录和文件的列表。如果为虚拟目录指定了不同于物理目录的名称,将增加用户在服务器上查找实际物理文件结构的难度,因为 URL 无法直接映射到网站的根。

在 IIS 7.0 中,每个 Web 应用程序都必须拥有一个命名为根虚拟目录的虚拟目录,该虚拟目录可以将 Web 应用程序映射到包含 Web 应用程序内容的物理目录。但 Web 应用程序可以拥有多个虚拟目录。例如,如果您希望 Web 应用程序包含文件系统的其他位置上的图像,但又不希望将这些图像文件移动到映射至 Web 应用程序根虚拟目录的物理目录中,则可以使用虚拟目录。
转载请注明出自高地网 - 笔记本技术区 http://enbbs.gaodi.net/,本贴地址:http://enbbs.gaodi.net/viewthread.php?tid=1616

 

 

posted @ 2010-05-19 22:07 landylee 阅读(446) 评论(0) 编辑
之前写过一个关于symbian常用程序架构的帖子,不过当时是在简单的看了看书本的条件下写的,仅仅是当时做的一个笔记而已,并没有多少自己的感想体会在里面。当然现在也不能就对传统的symbian os架构很了解了,因为毕竟没有做太多深入的研究试验,仅仅是根据自己的想法做了几个小程序而已。
 
从四个小程序上来分析:
 
一、在屏幕上显示两个Label
这是最最基本的了。
关键的就是创建一个容器Container(实际上就是一个拥有窗口的复合控件而已)和一个UI其中Container继承自控件基类CCoeControl,而UI继承自CAknAppUi,这都是必须的。另外,如果Container里的控件,比如编辑框想接收用户事件的话,那么Container同时还要继承?????????因为我的容器里面只有两个Label,所以也就不需要继承这个类了。
(1)先看容器类Container的内容:
因为容器Container里包含两个Label,一定要注意,将两个Label 的指针设为Container类的私有成员变量即:
private:
     CEikLabel* iLabel;
     CEikLabel* iToDoLabel;
当然这是在Container类的头文件里声明的。
然后就是看Container的四个方法,这四个都需要我们重写,否则容器中的两个Label控件不会显示。它们分别是:
void Draw(const TRect& aRect) const;
virtual CCoeControl* ComponentControl(TInt aIndex) const;
virtual TInt CountComponentControls() const;
void SizeChanged();
 
在本例中,我是这样重写这四个方法的:
CCoeControl* CHelloWorldBasicAppView::ComponentControl(TInt aIndex) const
{
     switch(aIndex)
     {
     case 0:
         return iLabel;
     case 1:
         return iToDoLabel;
     default:
         return NULL;
     }
}
获取容器中每个控件的指针。
 
void CHelloWorldBasicAppView::SizeChanged()
{
     //设置标签的位置
     iLabel->SetExtent( TPoint(10,10), iLabel->MinimumSize() );
    iToDoLabel->SetExtent( TPoint(10,100), iToDoLabel->MinimumSize() );
    
}
SetExtent()方法设置Label的位置。
开始时,我认为,Label的大小不会改变,所以不需要重写该方法,但事实证明,即使容器中的控件大小不会改变,我们也必须重写这两个方法。如果不,那么这两个Label就不会显示。
 
TInt CHelloWorldBasicAppView::CountComponentControls() const
{
     return 2;
}
返回容器中控件的数目,在这里有两个Label,所以返回2。
 
void CHelloWorldBasicAppView::Draw(const TRect& aRect) const
{
    // Get the standard graphics context
    CWindowGc& gc = SystemGc();
    // Gets the control's extent
    TRect rect = Rect();
    // Clears the screen
    gc.Clear(rect);
     //设置笔刷
gc.SetPenStyle( CGraphicsContext::ENullPen );
    gc.SetBrushColor( KRgbRed ); //红色
    gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
    gc.DrawRect( aRect );
 }
将整个窗口的aRect范围,涂成红色。通过一个TRect对象可以设置Draw的区域即:gc.DrawRect( aRect );也就是说,并不一定要绘制整个窗口。
 
下面看Container的ConstructL方法:
void CHelloWorldBasicAppView::ConstructL(const TRect& aRect)
    {
     // Create a window for this application view
     CreateWindowL();//复合控件创建窗口
 
     iLabel=new(ELeave) CEikLabel;
     iLabel->SetContainerWindowL(*this);//将不拥有窗口的控件和窗口关联
     iLabel->SetTextL(_L("iLabel"));
     iLabel->SetUnderlining(ETrue);
 
     iToDoLabel=new(ELeave) CEikLabel;
     iToDoLabel->SetContainerWindowL(*this);
     iToDoLabel->SetTextL(_L("iToDoLabel"));
 
    // Set the windows size
    SetRect(aRect);
 
    // Activate the window, which makes it ready to be drawn
    ActivateL();
}
首先,我们给这个容器创建一个窗口,然后分别创建两个Label的实例iLabel和iToDoLabel,这其中用到一个方法SetContainerWindowL(*this);,表示将这两个控件显示在那个窗口上,而参数表示的是容器Container,而不是一个Rwindow,这实际上是调用的是CcoeControl中的方法:
virtual void SetContainerWindowL(const CCoeControl& aContainer);
通过看这个函数原型就知道了没有必要非要传递一个Rwindow实例,我们也可以传递一个拥有窗口的容器,而在这里容器Container就是一个拥有窗口的CCoeControl实例,因为我们调用了方法CreateWindowL();
当然也可以给该方法传递一个RWindow实例,即调用CCoeControl的重载方法:
void SetContainerWindowL(RWindow& aWindow);
 
然后设置我们创建的窗口的显示范围SetRect(aRect);,一般是全屏,当然我们也可以设置一个TRect实例,比如:TRect(TPoint(0,0),TSize(100,100)),但是这种情况下,就会看到,我们程序的窗口没有占满整个屏幕,也就是说,仅有TRect(TPoint(0,0),TSize(100,100))的区域来显示我们的程序,而屏幕上剩余的范围还会显示原来的,这样子就比较奇怪,比较难看了。
 
最后激活窗口ActivateL();也就是说调用容器的Draw()、SizeChanged()等函数,从而开始绘制窗口。
 
最后就是容器Container类的析构函数:
CHelloWorldBasicAppView::~CHelloWorldBasicAppView()
{
     if(iLabel)
     {
         delete iLabel;
          iLabel=NULL;
     }
     if(iToDoLabel)
     {
         delete iToDoLabel;
          iToDoLabel=NULL;
     }
}
这个析构函数的主要作用是销毁我们容器中创建的两个Label实例iLabel和iToDoLabel。
 
(2)看UI的内容
其实主要就是UI的ConstructL()方法和析构函数,之所以有析构函数,因为实际上UI也是一个C类。
void CHelloWorldBasicAppUi::ConstructL()
{
    BaseConstructL();
    iAppView = CHelloWorldBasicAppView::NewL(ClientRect());
iAppView->SetMopParent( this );
    AddToStackL(iAppView);
}
首先创建UI的框架即调用方法BaseConstructL();,然后创建容器Container实例,实际上就是这里的iAppView。
接下来的的SetMopParent( this );和AddToStackL(iAppView);在本例中并不是必须的:
SetMopParent( this );是为了设置父控件用的。据网友pan讲:通过这个方法可以设置控件之间的父子关系,然后在子控件中就可以访问父控件或其他子控件,父控件中也可以访问子控件。需要注意的就是要讲这个方法和SetContainerWindowL()区分开。
AddToStackL(iAppView);将容器放到栈顶,从而可以接收用户的事件,如果想让其他容器接收事件的话,就可以通过另一个方法,RemoveFromStatck(iAppView)将当前容器从栈顶移出,然后在将其他容器移入该栈顶即:AddToStackL(iAppView2);
 
CHelloWorldBasicAppUi::~CHelloWorldBasicAppUi()
{
    if (iAppView)
        {
        iEikonEnv->RemoveFromStack(iAppView);
        delete iAppView;//调用容器Container的析构函数,销毁容器对象即iAppView
        iAppView = NULL;//注意,一定要将指针置空,否则就会称为悬空指针,也就是野指针。
        }
}
在析构函数中销毁创建的容器实例。
 
需要注意:容器实例iAppView必须是UI类的私有成员,即:
private:
       CHelloWorldBasicAppView* iAppView;
 
小结:这里面出现几个概念,比如屏幕、窗口、容器、复合控件等,比较容易让人混淆。我的理解是这样子的:屏幕就只有一个,也就是手机的显示屏,是一个物理概念;而窗口是逻辑上的概念,一个程序里我们可以创建多个窗口,下面的一个例子我就来说明这个问题;容器和复合控件都是继承自控件基类CCoeControl,并且它们的类定义中都有子控件成员,不同之处就是容器拥有自己的窗口,而复合控件没有,我们可以把复合控件加到其他的复合控件或容器上,我也会在下面的例子里加以实现。
 
二、屏幕上面切换显示两个窗口
每个窗口都有两个Label。
最开始,我是想这样来实现:让第一个iAppView创建一个窗口,而第二个iAppView2(实际上就是一个复合控件)不再创建新的,而是共用iAppView创建的窗口。试验的时候,在UI的ConstructL()方法里,先创建iAppView,在将拥有窗口的容器iAppView作为参数传递到iAppView2的构造函数中,但却发现并不能实现。
因此,我只能也给iAppView2也创建一个窗口,看这两个容器类的构造函数如下:
void CHelloWorldBasicAppView::ConstructL(const TRect& aRect)
    {
    // Create a window for this application view
    CreateWindowL();//复合控件创建窗口
 
     iLabel=new(ELeave) CEikLabel;
     iLabel->SetContainerWindowL(*this);//将不拥有窗口的控件和窗口关联
     iLabel->SetTextL(_L("iLabel"));
     iLabel->SetUnderlining(ETrue);
 
     iToDoLabel=new(ELeave) CEikLabel;
     iToDoLabel->SetContainerWindowL(*this);
     iToDoLabel->SetTextL(_L("iToDoLabel"));
 
    // Set the windows size
    SetRect(aRect);
 
    // Activate the window, which makes it ready to be drawn
    ActivateL();
}
 
void CHelloWorldBasicAppView2::ConstructL(const TRect& aRect,CHelloWorldBasicAppView* iAppView)
    {
    // Create a window for this application view
    CreateWindowL();//复合控件创建窗口
 
     iLabel2=new(ELeave) CEikLabel;
     iLabel2->SetContainerWindowL(*iAppView);//将不拥有窗口的控件和窗口关联
     iLabel2->SetTextL(_L("iLabel2"));
     iLabel2->SetUnderlining(ETrue);
 
     iToDoLabel2=new(ELeave) CEikLabel;
     iToDoLabel2->SetContainerWindowL(*iAppView);
     iToDoLabel2->SetTextL(_L("iToDoLabel2"));
 
    // Set the windows size
    SetRect(aRect);
 
    // Activate the window, which makes it ready to be drawn
    ActivateL();
}
通过对照发现,两个构造函数中都创建了窗口,并进行了激活。注意就是它们的窗口范围都是整个屏幕。
现在的问题是:如何轮换显示两个窗口呢?
可以通过方法:iAppView->MakeVisible( EFalse );或iAppView->MakeVisible( ETrue );来实现窗口的是否显示,来在一个屏幕上切换显示两个范围都是占满个屏幕的窗口。
即看UI的构造函数:
void CHelloWorldBasicAppUi::ConstructL()
    {
    BaseConstructL();
    iAppView = CHelloWorldBasicAppView::NewL(ClientRect());
iAppView->MakeVisible( EFalse );//暂时不显示容器iAppView
iAppView2 = CHelloWorldBasicAppView2::NewL(ClientRect());
    }
三、在一个屏幕上同时显示两个窗口
在设定窗口的范围上,iAppView占屏幕的上半部分,而iAppView2占屏幕的下半部分。其他的和上面一样,当然也就不需要MakeVisible()这个方法了,呵呵。
主要的区别就是UI的构造函数:
void CHelloWorldBasicAppUi::ConstructL()
    {
    BaseConstructL();
TRect rect = ClientRect();
    iAppView = CHelloWorldBasicAppView::NewL(TRect(rect.iTl.iX,
                                                           rect.iTl.iY,
                                                           rect.Width(),
                                                           rect.Height()/2+rect.iTl.iY));
 
     iAppView2 = CHelloWorldBasicAppView2::NewL(TRect(rect.iTl.iX,
                                                              rect.Height()/2+rect.iTl.iY,
                                                              rect.Width(),
                                                              rect.iBr.iY));
}
 
这两个容器的窗口分别占屏幕的上下各一半。
 
四、让iAppView2仅作为一个复合控件,并称为容器iAppView的一个子控件,和iAppView在一个窗口上显示。
这个地方要比上面复杂一些,我在这里贴出iAppView2的ConstructL()代码:
void CHelloWorldBasicAppView2::ConstructL(const TRect& aRect)
    {
     iLabel2=new(ELeave) CEikLabel;
     iLabel2->SetContainerWindowL(*this);//将不拥有窗口的控件和窗口关联
     iLabel2->SetTextL(_L("iLabel2"));
     iLabel2->SetUnderlining(ETrue);
 
     iToDoLabel2=new(ELeave) CEikLabel;
     iToDoLabel2->SetContainerWindowL(*this);
     iToDoLabel2->SetTextL(_L("iToDoLabel2"));
}
 
可以看到,仅仅是创建了两个Label控件而已,而没有之前的创建窗口CreateWindowL()和激活窗口ActiveWindowL()方法了,因为这里的iAppView2仅仅是作为一个复合控件而已,所以就不需要创建窗口了。其它的方法即SizeChanged()、Draw()、CountComponentControls()和ComponentControl()都是不变的。
上面的iLabel2->SetContainerWindowL(*this);,参数传递的是当前复合控件对象,虽然复合控件并不拥有窗口,但是通过复合控件iAppView2的SetContainerWindowL()方法中的参数是拥有窗口的iAppView,也就是通过层层上传,最后,这两个Label控件也和要显示在上面的窗口联系起来了。而不是把iAppView直接传递给这两个Label的SetContainerWindowL()方法,这里必须注意。
 
因为要将复合控件iAppView2作为容器iAppView的一个子控件,所以iAppView2要作为iAppView的容器类的一个成员变量即:
private:
     CEikLabel* iLabel;
     CEikLabel* iToDoLabel;
     CHelloWorldBasicAppView2* iAppView2;//多了复合控件iAppView2这个私有成员变量。
因为iAppView的容器类多了一个新的子控件,即iAppView2,所以这个类的ConstructL()、SizeChanged()、CountComponentControls()、ComponentControl()以及析构函数~ChelloWorldBasicAppView都需要修改,如下:
 
void CHelloWorldBasicAppView::ConstructL(const TRect& aRect)
    {
    // Create a window for this application view
     CreateWindowL();//复合控件创建窗口
 
     iLabel=new(ELeave) CEikLabel;
     iLabel->SetContainerWindowL(*this);//将不拥有窗口的控件和窗口关联
     iLabel->SetTextL(_L("iLabel"));
     iLabel->SetUnderlining(ETrue);
 
     iToDoLabel=new(ELeave) CEikLabel;
     iToDoLabel->SetContainerWindowL(*this);
     iToDoLabel->SetTextL(_L("iToDoLabel"));
     //多了下面两行代码
     iAppView2=CHelloWorldBasicAppView2::NewL(TRect(TPoint(0,100),TSize(200,200)));
     iAppView2->SetContainerWindowL(*this);
    
    // Set the windows size
    SetRect(aRect);
 
    // Activate the window, which makes it ready to be drawn
    ActivateL();
}
 
――――――――――――――――――――――――――――――――――――
void CHelloWorldBasicAppView::SizeChanged()
{
     //设置控件的位置
iLabel->SetExtent( TPoint(10,10), iLabel->MinimumSize() );
iToDoLabel->SetExtent( TPoint(10,30), iToDoLabel->MinimumSize() );
//多了下面一行代码,TPoint(10,60)相对于窗口左上角
iAppView2->SetExtent( TPoint(10,60), iToDoLabel->MinimumSize() );
    
}
 
―――――――――――――――――――――――――――――――――――――――――――
TInt CHelloWorldBasicAppView::CountComponentControls() const
{
     return 3;
}
返回是3,不是4(虽然复合控件有两个子控件)。
――――――――――――――――――――――――――――――――――――――――――
CCoeControl* CHelloWorldBasicAppView::ComponentControl(TInt aIndex) const
{
     switch(aIndex)
     {
     case 0:
         return iLabel;
     case 1:
         return iToDoLabel;
     //多了下面两行
     case 2:
         return iAppView2;
     default:
         return NULL;
     }
}
 
――――――――――――――――――――――――――――――――――――
CHelloWorldBasicAppView::~CHelloWorldBasicAppView()
{
     if(iLabel)
     {
         delete iLabel;
          iLabel=NULL;
     }
 
     if(iToDoLabel)
     {
         delete iToDoLabel;
          iToDoLabel=NULL;
     }
     //多了下面几行
     if(iAppView2)
     {
         delete iAppView2;
          iAppView2=NULL;
     }
}
 
 
问题:
1、 draw()方法,不需要做任何改变。我开始想,可能需要加一个iAppView2.DrawNow()之类的代码,启动绘制复合控件iAppView2的代码,实际是多此一举的。系统会自动运行复合控件的draw()等四个方法。
2、  复合控件以及复合控件中的两个Label子控件显示的坐标问题,一定记住,它们都是相对于窗口左上角的坐标位置,我曾经将两个子控件的坐标设为相对于它们所属的复合控件了,结果因为超出屏幕范围,没有显示出来。另外屏幕的范围大约在(0,0)--(120,150)之间,如果设置坐标时超出这个范围,就显示不出来了。
 
当然这只是一些最基本的架构问题,也没有显示一些比较复杂的控件,在这里只是起个熟悉传统程序架构的作用,不正之处,还请各位网友指正。
posted @ 2010-05-19 22:05 landylee 阅读(216) 评论(0) 编辑