硕鼠的博客站

范路的博客主站,时而会发些东西。

下面让我们来分析以下VCL for PHP的基本结构,李维在作 Demo的时候最喜欢拿出来炫的就是Google Map VCL,你们能够想像得出来这个组件一共有多少行代码吗?

不到100行,是不是吓到了?你有可能编写很少的代码,就可以开发一共非常漂亮的组件,并且开始你自己的软件创业之路。

下面让我们来看一下这个组件的源代码:

<?php

        //Includes

        require_once("vcl/vcl.inc.php");

 

        use_unit("controls.inc.php");

 

        //Class definition

        class GoogleMap extends Control

        {

            function __construct($aowner = null)

            {

                parent::__construct($aowner);

            }

 

            private $_mapskey="ABQIAAAAQlQ8ZvigZnDc1z7MTEuUQxTJO8fVsnY3pyCJC531oZiosu_8phSnTlxi08R1_58Gfdyd9NUJdyES5w";

 

            function getMapsKey() { return $this->_mapskey; }

            function setMapsKey($value) { $this->_mapskey=$value; }

            function defaultMapsKey() { return "ABQIAAAAQlQ8ZvigZnDc1z7MTEuUQxTJO8fVsnY3pyCJC531oZiosu_8phSnTlxi08R1_58Gfdyd9NUJdyES5w"; }

 

            private $_address="Scotts Valley, CA";

 

            function getAddress() { return $this->_address; }

            function setAddress($value) { $this->_address=$value; }

            function defaultAddress() { return "Scotts Valley, CA"; }

 

 

 

            function dumpHeaderCode()

            {

?>

    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key= <?php echo $this->MapsKey; ?>"

      type="text/javascript"></script>

    <script type="text/javascript">

    //<![CDATA[

    function <?php echo $this->Name; ?>load()

    {

      if (GBrowserIsCompatible())

      {

        var map = new GMap2(document.getElementById("<?php echo $this->Name; ?>_div"));

        map.addControl(new GLargeMapControl());

        map.addControl(new GScaleControl());

        map.addControl(new GMapTypeControl());

 

        var geocoder = new GClientGeocoder();

 

        var address="<?php echo $this->Address; ?>";

 

        geocoder.getLatLng (address,

 

        function(point)

        {

                if (!point)

                {

                        alert(address + " not found");

                }

                else

                {

                        map.setCenter(point, 13);

                        var marker = new GMarker(point);

                        map.addOverlay(marker);

                        marker.openInfoWindowHtml(address);

                }

        }

        );

      }

   }

    //]]>

    </script>

<?php

            }

 

            function dumpContents()

            {

                echo "<div id="".$this->Name."_div" style="width: ".$this->Width."px; height: ".$this->Height."px"></div>";

?>

    <script type="text/javascript">

    <?php echo $this->Name; ?>load();

    </script>

<?php

            }

        }

 

?>

 

连空行都算上一共84行。我就不讲解这段代码了,我想不管你是什么语言的程序员, DelphiPHPJava C++C#JavaScript等等等等,你应该都能够读懂上面的几十行代码。

看看,这是多么容易的一件事啊,你也能的。

 

如果你希望能够进入这个行业,那么我给大家指几个方向,供大家参考。在早期,这个领域还是一片空白的时候,大家可以试着从这些方向下手。

第一、    使用现有组件进行一些扩展,完成一些更加具体的功能:

下面这个例子是LabeledEdit组件,将一个 Label和一个Edit组合起来,完成一个完整的功能。

class SubLabel extends Persistent

{

        protected $_caption = "";

 

        function assignTo($dest)

        {

                $dest->_caption=$this->_caption;

        }

 

        /**

         * Specifies the caption used in the label

         *

         * @return string

         */

        protected function readCaption()           { return $this->_caption; }

        protected function writeCaption($value)    { $this->_caption=$value; }

        function defaultCaption()                  { return ""; }

 

        // publish properties

        function getCaption()           { return $this->readCaption(); }

        function setCaption($value)     { $this->writeCaption($value); }

}

 

class CustomLabeledEdit extends CustomTextField

{

        protected $_lblname = "";

 

        protected $_edtlabel=null;

        protected $_lblspacing = 3;

        protected $_lblposition = lpAbove;

        protected $_text = "";

 

        protected function CalculateEditorRect()

        {

                switch ($this->_lblposition)

                {

                  case lpBelow:

                        $y = 0;

                        break;

                  default: // lpAbove:

                        $y = 14 + $this->_lblspacing;

                        break;

                }

                return array(0, $y, $this->Width, $this->Height – 14 – $this->_lblspacing);

        }

 

        protected function dumpExtraControlCode()

        {

                $eh = $this->Height – 14 – $this->_lblspacing;

                switch ($this->_lblposition)

                {

                  case lpBelow:

                        $y = $eh;

                        break;

                  default: // lpAbove:

                        $y = 0;

                        break;

                }

 

                $this->_lblname = $this->Name . "_Lbl";

 

                echo "  var $this->_lblname = new qx.ui.basic.Atom("" . $this->_edtlabel->Caption . "");n"

                   . "  $this->_lblname.setLeft(0);n"

                   . "  $this->_lblname.setTop($y);n"

                   . "  $this->_lblname.setWidth($this->Width);n"

                   . "  $this->_lblname.setHorizontalChildrenAlign("left");n";

 

                if (($this->Visible) || (($this->ControlState & csDesigning)==csDesigning))

                      { $visible="true"; }

                else  { $visible="false"; };

                echo "  $this->_lblname.setVisibility($visible);n"

                   . "  inline_div.add($this->_lblname);n";

        }

 

        function __construct($aowner = null)

        {

                //Calls inherited constructor

                parent::__construct($aowner);

 

                $this->_edtlabel = new SubLabel();

                $this->Width = 121;

                $this->Height = 34;

        }

 

        function setName($value)

        {

                $oldname=$this->_name;

                parent::setName($value);

 

                //Sets the caption if not already changed

                if ($this->_edtlabel->Caption == $oldname)

                {

                        $this->_edtlabel->Caption = $this->Name;

                }

        }

 

        /**

         * Use EditLabel to work with the label that is associated with this

         * labeled edit control. Use this label�s properties to specify the

         * caption that appears on the label.

         */

        protected function readEditLabel()              { return $this->_edtlabel; }

        protected function writeEditLabel($value)       { if (is_object($value)) $this->_edtlabel=$value; }

        /**

         * Specifies the position of the label relative to the edit control.

         *

         * @return enum (lpAbove, lpBelow)

         */

        protected function readLabelPosition()          { return $this->_lblposition; }

        protected function writeLabelPosition($value)   { $this->_lblposition=$value; }

        function defaultLabelPosition()     { return lpAbove; }

        /**

         * Specifies the distance, in pixels, between the label and the edit region.

         *

         * @return integer

         */

        protected function readLabelSpacing()           { return $this->_lblspacing; }

        protected function writeLabelSpacing($value)    { $this->_lblspacing=$value; }

        function defaultLabelSpacing()      { return 3; }

}

 

class LabeledEdit extends CustomLabeledEdit

{

        //Publish common properties

        function getAlign()             { return $this->readAlign(); }

        function setAlign($value)       { $this->writeAlign($value); }

 

        //function getFont()              { return $this->readFont(); }

        //function setFont($value)        { $this->writeFont($value); }

 

        function getColor()             { return $this->readColor(); }

        function setColor($value)       { $this->writeColor($value); }

 

        function getEnabled()           { return $this->readEnabled(); }

        function setEnabled($value)     { $this->writeEnabled($value); }

 

        function getParentColor()       { return $this->readParentColor(); }

        function setParentColor($value) { $this->writeParentColor($value); }

 

        function getParentFont()        { return $this->readParentFont(); }

        function setParentFont($value)  { $this->writeParentFont($value); }

 

        function getParentShowHint()    { return $this->readParentShowHint(); }

        function setParentShowHint($value) { $this->writeParentShowHint($value); }

 

        function getPopupMenu()         { return $this->readPopupMenu(); }

        function setPopupMenu($value)   { $this->writePopupMenu($value); }

 

        function getShowHint()          { return $this->readShowHint(); }

        function setShowHint($value)    { $this->writeShowHint($value); }

 

        function getVisible()           { return $this->readVisible(); }

        function setVisible($value)     { $this->writeVisible($value); }

 

        //Publish Edit control properties

        function getBorderStyle()       { return $this->readBorderStyle();  }

        function setBorderStyle($value) { $this->writeBorderStyle($value);  }

 

        function getCharCase()          { return $this->readCharCase(); }

        function setCharCase($value)    { $this->writeCharCase($value); }

 

        function getDataField()         { return $this->readDataField(); }

        function setDataField($value)   { $this->writeDataField($value); }

 

        function getDataSource()        { return $this->readDataSource(); }

        function setDataSource($value)  { $this->writeDataSource($value); }

 

        function getIsPassword()        { return $this->readIsPassword(); }

        function setIsPassword($value)  { $this->writeIsPassword($value); }

 

        function getMaxLength()         { return $this->readMaxLength(); }

        function setMaxLength($value)   { $this->writeMaxLength($value); }

 

        function getReadOnly()          { return $this->readReadOnly(); }

        function setReadOnly($value)    { $this->writeReadOnly($value); }

 

        function getText()              { return $this->readText(); }

        function setText($value)        { $this->writeText($value); }

 

        // publish Common Events

        function getjsOnActivate()      { return $this->readjsOnActivate(); }

        function setjsOnActivate($value){ $this->writejsOnActivate($value); }

 

        function getjsOnDeActivate()    { return $this->readjsOnDeActivate(); }

        function setjsOnDeActivate($value) { $this->writejsOnDeActivate($value); }

 

        function getjsOnChange()        { return $this->readjsOnChange(); }

        function setjsOnChange($value)  { $this->writejsOnChange($value); }

 

        function getjsOnBlur()          { return $this->readjsOnBlur(); }

        function setjsOnBlur($value)    { $this->writejsOnBlur($value); }

 

        function getjsOnClick()         { return $this->readjsOnClick(); }

        function setjsOnClick($value)   { $this->writejsOnClick($value); }

 

        function getjsOnContextMenu()   { return $this->readjsOnContextMenu(); }

        function setjsOnContextMenu($value) { $this->writejsOnContextMenu($value); }

 

        function getjsOnDblClick()      { return $this->readjsOnDblClick(); }

        function setjsOnDblClick($value){ $this->writejsOnDblClick($value); }

 

        function getjsOnFocus()         { return $this->readjsOnFocus(); }

        function setjsOnFocus($value)   { $this->writejsOnFocus($value); }

 

        function getjsOnKeyDown()       { return $this->readjsOnKeyDown(); }

        function setjsOnKeyDown($value) { $this->writejsOnKeyDown($value); }

 

        function getjsOnKeyPress()      { return $this->readjsOnKeyPress(); }

        function setjsOnKeyPress($value){ $this->writejsOnKeyPress($value); }

 

        function getjsOnKeyUp()         { return $this->readjsOnKeyUp(); }

        function setjsOnKeyUp($value)   { $this->writejsOnKeyUp($value); }

 

        function getjsOnMouseDown()      { return $this->readjsOnMouseDown(); }

        function setjsOnMouseDown($value){ $this->writejsOnMouseDown($value); }

 

        function getjsOnMouseUp()       { return $this->readjsOnMouseUp(); }

        function setjsOnMouseUp($value) { $this->writejsOnMouseUp($value); }

 

        function getjsOnMouseMove()     { return $this->readjsOnMouseMove(); }

        function setjsOnMouseMove($value) { $this->writejsOnMouseMove($value); }

 

        function getjsOnMouseOut()      { return $this->readjsOnMouseOut(); }

        function setjsOnMouseOut($value) { $this->writejsOnMouseOut($value); }

 

        function getjsOnMouseOver()     { return $this->readjsOnMouseOver(); }

        function setjsOnMouseOver($value) { $this->writejsOnMouseOver($value); }

 

        // publish new properties

        function getEditLabel()             { return $this->readEditLabel(); }

        function setEditLabel($value)       { $this->writeEditLabel($value); }

 

        function getLabelPosition()         { return $this->readLabelPosition(); }

        function setLabelPosition($value)   { $this->writeLabelPosition($value); }

 

        function getLabelSpacing()         { return $this->readLabelSpacing(); }

        function setLabelSpacing($value)   { $this->writeLabelSpacing($value); }

        // publish events

        function getOnClick()           { return $this->readOnClick(); }

        function setOnClick($value)     { $this->writeOnClick($value); }

}

第二、    结合JavaScript来做一些页面特效,这需要JavaScript 比较熟悉的人来完成。我向很多JavaScript程序员手里应该已经积攒了不少非常棒的代码,比如各种按钮、菜单等等。

第三、    结合一些提供特定服务的网站,例如Google Map,或者是图片交流方面的或者是提供一些特定信息的 WebServices网站,例如股票、金融、餐饮服务、新闻、天气、出行信息等内容,作一些能够提供特定信息的组件。这些组件可以从网站得到一些收入。

第四、    将现在比较流行的完整的开源代码拆开,封装成组件包。

第五、    GridReport Chart这三类组件在Delphi VCL里面是种类最丰富的,所以如果能够在这方面及早下手,肯定效果不错。

第六、    调用PHP基础函数,封装一些基础功能也是一个不错的选择,比如 phpinfo()就完全可以进行些方面的封装,FTP和各种文件操作封装的余地也很大。

第七、    编写一些特定的数据库连接和操作的组件应该有不错的应用前景。

第八、    结合Delphi或者是C++ 来编写一些PHP扩展,然后将去封装到VCL中,可以完成一些更强劲的的功能,也更容易让客户认同这些组件的价值。

第九、    编写完整的网站决绝方案,比如门户网站、BBS、商务网站等等。

 

我在这里只是启一个头儿,相信大家能够想出更多更有创意的点子来。

 

 

 

 

 

让我们一起来迎接新控件时代的到来吧!

 

 

Both comments and pings are currently closed.

Comments are closed.

Close Bitnami banner
Bitnami