DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: qm13556
今日帖子: 26
在线用户: 11
导航: 论坛 -> 文档资料 斑竹:liumazi,ruralboy  
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2014/4/17 21:02:58
标题:
XE6+JQM+QuickBurro开发混合型手机App的一个实例 浏览:4223
加入我的收藏
楼主: 一、概述
    XE5\XE6\AppMethod做手机App程序的外壳、JQuery Mobie设计手机程序内容部分、后台QuickBurro+Delphi实现业务逻辑处理与提供内容服务,不失为一种开发周期短、平台适应性还好、维护简单的移动应用开发方案。
    这里给出一个实际的案例,来展示这一开发过程。


二、用XE6设计手机程序的外壳
    如下图所示,新建一个XE6 Mobile工程,依次做好顶部标题栏、主体多页面框架等,然后,在多页面TabControl的页面里放上WebBrowser控件,用来作为HTML/JQM的页面容器,再写上若干简单的控制代码,就完成了本APP外壳的设计:

unit main;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.WebBrowser,
  FMX.StdCtrls, FMX.Objects, FMX.TabControl, Data.Bind.Controls, FMX.Layouts,
  Fmx.Bind.Navigator;

type
  TForm1 = class(TForm)
    StyleBook1: TStyleBook;
    Panel1: TPanel;
    Line1: TLine;
    Button2: TButton;
    Button3: TButton;
    Panel2: TPanel;
    Panel3: TPanel;
    TabControl1: TTabControl;
    TabItem1: TTabItem;
    Browser1: TWebBrowser;
    TabItem2: TTabItem;
    Browser2: TWebBrowser;
    TabItem3: TTabItem;
    Browser3: TWebBrowser;
    TabItem4: TTabItem;
    Browser4: TWebBrowser;
    Label1: TLabel;
    Image1: TImage;
    Button4: TImage;
    Button5: TImage;
    Button6: TImage;
    RoundRect1: TRoundRect;
    Label2: TLabel;
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure TabControl1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Load1,Load2,Load3,Load4: boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

//
// 退出...
procedure TForm1.Button2Click(Sender: TObject);
begin
   halt;
end;

//
// 帮助...
procedure TForm1.Button3Click(Sender: TObject);
begin
   showmessage(#13#10+'『资金指标使用情况查询系统』'+#13#10#13#10+'版权所有(C) Jopher Software Studio.'+#13#10);
end;

//
// 前进...
procedure TForm1.Button4Click(Sender: TObject);
begin
   case TabControl1.ActiveTab.Index of
      0: if Browser1.CanGoForward then Browser1.GoForward;
      1: if Browser2.CanGoForward then Browser2.GoForward;
      2: if Browser3.CanGoForward then Browser3.GoForward;
      3: if Browser4.CanGoForward then Browser4.GoForward;
   end;
end;

//
// 返回...
procedure TForm1.Button5Click(Sender: TObject);
begin
   case TabControl1.ActiveTab.Index of
      0: if Browser1.CanGoBack then Browser1.GoBack;
      1: if Browser2.CanGoBack then Browser2.GoBack;
      2: if Browser3.CanGoBack then Browser3.GoBack;
      3: if Browser4.CanGoBack then Browser4.GoBack;
   end;
end;

//
// 首页...
procedure TForm1.Button6Click(Sender: TObject);
begin
   case TabControl1.ActiveTab.Index of
      0: Load1:=false;
      1: Load2:=false;
      2: Load3:=false;
      3: Load4:=false;
   end;
   TabControl1Change(nil);
end;

//
// 显示默认页面...
procedure TForm1.FormCreate(Sender: TObject);
begin
   Load1:=false;
   Load2:=false;
   Load3:=false;
   Load4:=false;
   TabControl1Change(nil);
end;

//
// 窗口自适应...
procedure TForm1.FormResize(Sender: TObject);
begin
   tabitem1.Width:=TabControl1.Width/4;
   tabitem2.Width:=TabControl1.Width/4;
   tabitem3.Width:=TabControl1.Width/4;
   tabitem4.Width:=TabControl1.Width/4;
end;

//
// 切换到不同页面时...
procedure TForm1.TabControl1Change(Sender: TObject);
begin
   case TabControl1.ActiveTab.Index of
      //
      // 总指标查询...
      0: begin
          Label1.Text:=formatdatetime('yyyy',now)+'年度指标总量';
          if not Load1 then
          begin
          Load1:=true;
          Browser1.Navigate('http://172.18.254.100/jquerymobileexample/list-split-buttons.html');
          end;
         end;
      //
      // 月计划查询...
      1: begin
          Label1.Text:=formatdatetime('yyyy',now)+'年'+formatdatetime('mm',now)+'月指标使用计划';
          if not Load2 then
          begin
          Load2:=true;
          Browser2.Navigate('http://172.18.254.100/webdemo/monthplan.asq?datafrom=zy_qegamsdatabase');
          end;
         end;
      //
      // 热点支出...
      2: begin
          Label1.Text:=formatdatetime('yyyy',now)+'年指标使用热点';
          if not Load3 then
          begin
          Load3:=true;
          Browser3.Navigate('http://172.18.254.100/jquerymobileexample/list-icons.html');
          end;
         end;
      //
      // 指标结余查询...
      3: begin
          Label1.Text:=formatdatetime('yyyy',now)+'年指标额度结余';
          if not Load4 then
          begin
          Load4:=true;
          Browser4.Navigate('http://172.18.254.100/jquerymobileexample/list-numbered.html');
          end;
         end;
   end;
end;

end.
此帖子包含附件:
PNG 图像
大小:88.0K
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2014/4/17 21:09:15
1楼: 三、接下来作设计服务端
    在QuickBurro中间件为服务端的系统下,只需要设计一个Web插件,就可以通过虚拟动态页面URL来调用它,得到结果了。
    先来设计一个页面模板,具体代码如下,并将它存放在中间件的模板文件夹下:

<!DOCTYPE html>
<html>

<head>

   <meta charset="gb2312">

      <title>月资金计划查询</title>

      <meta name="viewport" content="width=device-width, initial-scale=1">

      <link rel="stylesheet" href="/system/jquery.mobile-1.3.2.min.css" />

      <script type="text/javascript" src="/system/jquery-1.9.1.min.js"></script>

      <script type="text/javascript" src="/system/jquery.mobile-1.3.2.min.js"></script>
      <style>

          .tabbar .ui-btn .ui-btn-inner { font-size: 11px!important; padding-top: 24px!important; padding-bottom: 0px!important; }

          .tabbar .ui-btn .ui-icon { width: 30px!important; height: 20px!important; margin-left: -15px!important; box-shadow: none!important; -moz-box-shadow: none!important; -webkit-box-shadow: none!important; -webkit-border-radius: none !important; border-radius: none !important; }


          .segmented-control { text-align:center;}

          .segmented-control .ui-controlgroup { margin: 0.2em; }

          .ui-control-active, .ui-control-inactive { border-style: solid; border-color: gray; }

          .ui-control-active { background: #BBB; }

          .ui-control-inactive { background: #DDD; }

      </style>
</head>


<body>
   

<div data-role="page">

   <div data-role="content">

      <ul data-role="listview">

      `嵌入列表`
      
</ul>

   </div>
   
</div>


</body>


</html>


    再用Delphi按QuickBurro的插件模板格式写一个Web插件,具体代码如下:

//
// 主函数...
function MainFunction(RequestParcel: TQBParcel; ResponseParcel: TQBParcel): boolean;
var
   RawConn: _Connection;
   AdoConn: TAdoConnection;
   PoolId,ConnId,j: integer;
   //
   ParamParcel: TQBParcel;
   AdoDataset: TAdoDataset;
   ResponseBody,DatabaseId: AnsiString;
   //
   tmpFileName,tmpstr: ansistring;
begin
//
// 取模板...
   tmpFileName:=RequestParcel.GetAnsiStringGoods('Dll_Filename');
   j:=pos(ansistring('plugins\'),tmpFileName);
   tmpFileName:=copy(tmpFileName,1,j-1)+'templates\monthplan.tml';
   if not fileexists(string(tmpFileName)) then
      begin
         result:=false;
         exit;
      end;
   result:=File2Str(string(tmpFileName),ResponseBody);
   if not result then
      exit;
//
// 得到数据库Id...
   ParamParcel:=TQBParcel.Create;
   result:=RequestParcel.GetParcelGoods('Parameters',ParamParcel);
   if not result then
      exit;
   DatabaseId:=ParamParcel.GetAnsiStringGoods('DataFrom');
   FreeAndNil(ParamParcel);
//
// 通过API函数分配数据库连接对象...
   result:=GetAdoConnection(RequestParcel,DatabaseId,adoconn,RawConn,poolid,connid);
   if not result then
      exit;
//
// 创建访问数据库的Ado对象...
   AdoDataset:=TAdoDataset.Create(nil);
   AdoDataset.Connection:=AdoConn;
   AdoDataset.DisableControls;
//
// 打开通信录数据表...
   AdoDataset.CommandText:='SELECT * FROM CenterQuota order by FuncId';
   try
      AdoDataset.Active:=true;
      result:=true;
   except
      result:=false;
   end;
//
// 转换为HTML...
   if result then
      begin
         try
          tmpstr:='';
          AdoDataset.First;
          while not adodataset.Eof do
          begin
          tmpstr:=tmpstr+'<li>'#13#10;
          tmpstr:=tmpstr+'<a href="#">'#13#10;
          if trim(adodataset.FieldByName('BudgetType').AsString)='预算内' then
          tmpstr:=tmpstr+'<img src="/jquerymobileexample/images/in.png" />'#13#10
          else
          tmpstr:=tmpstr+'<img src="/jquerymobileexample/images/out.png" />'#13#10;
          tmpstr:=tmpstr+'<h3>'+AnsiString(trim(adodataset.FieldByName('FuncName').AsString))+'</h3>'#13#10;
          tmpstr:=tmpstr+'<p>本月计划:'+AnsiString(trim(adodataset.FieldByName('MonthPlan').AsString))+'</p>'#13#10;
          tmpstr:=tmpstr+'<p>累计发生:'+AnsiString(trim(adodataset.FieldByName('YearExpenses').AsString))+'</p>'#13#10;
          tmpstr:=tmpstr+'</a>'#13#10;
          tmpstr:=tmpstr+'</li>'#13#10;
          AdoDataset.Next;
          end;
          j:=pos(ansistring('`嵌入列表`'),ResponseBody);
          delete(ResponseBody,j,10);
          Insert(tmpstr,ResponseBody,j);
         except
          result:=false;
         end;
      end;
//
// 打开表成功才取数据...
   if result then
      begin
         ResponseParcel.PutAnsiStringGoods('ResponseBody',ResponseBody);
         ResponseParcel.PutAnsiStringGoods('Content-Type','text/html');
         ResponseParcel.PutBooleanGoods('DisableGZip',true);
      end;
//
// 完成,释放对象...
   FreeAndNil(AdoDataset);
   FreeAdoConnection(RequestParcel,AdoConn,RawConn,PoolId,ConnId);
end;

    完成后Build出一个DLL插件,复制到中间件目录下,然后,就可以用虚拟页面URL来访问了,比如,这里用“http://172.18.254.100/webdemo/monthplan.asq?datafrom=zy_qegamsdatabase”来访问,请参开上一帖中的代码。
    手机程序运行起来后,就能看到运行结果了:
此帖子包含附件:
JPEG 图像
大小:62.6K
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2014/4/17 21:12:23
2楼: 四、结论
1、手机外壳程序可以通过参数化来实现相对通用的外壳程序
2、页面风格改变了,只要改服务端插件,手机程序不用动,所以,很好维护
3、可以使用JQM等框架中的丰富表现力,设计出非常绚丽的界面
4、只需要懂简单的JQM以及Delphi程序设计,就能上手做应用
5、有钱赚
----------------------------------------------
樵夫的大马甲
作者:
男 zoujun3281 (无奈) ▲▲▲▲▲ -
普通会员
2014/4/18 8:21:11
3楼: 用JQM开发的在WebBrowser里能进行点击等等操作吗?
----------------------------------------------
delphi你妹
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2014/4/18 8:55:47
4楼: 当然能哦,这个怎么会不能
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2014/4/18 9:13:58
5楼: 画皮式App界面,再贴个效果图:
此帖子包含附件:
JPEG 图像
大小:63.2K
----------------------------------------------
樵夫的大马甲
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行171.875毫秒 RSS