htmlcontrol-for-symbian 源码解析

Symbian泡泡龙游戏源码深度剖析 Symbian平台曾经是智能手机市场的主要操作系统之一,在21世纪初期由诺基亚主导开发。作为早期移动游戏开发的主要平台,它支持多种硬件设备和丰富的游戏类型。由于其系统架构与资源管理的特点,Symbian为开发者提供了独特的游戏开发挑战和机遇。本文将探讨Symbian平台的游戏开发实践,特别是针对操作系统的特点进行深入分析,为读者提供实用的开发技巧。 阅读详情

from:http://www.haogongju.net/art/571010


作者:浪端之渡鸟 | 出处:博客园 | 2011/10/24 15:30:48 | 阅读4次
正文:
        ytom哥的HtmlControl是一个开源的轻量级的HTML/CSS解析和渲染的控件,可以轻松支持复杂的界面效果,也可以用来显示Web内容。大家可以从http://code.google.com/p/htmlcontrol-for-symbian/获得,首先感谢ytom哥给大家提供了这么好的一个选择。
        本文主要从源代码的角度来分析HtmlControl, 有需要从应用的角度多了解的朋友们可以到前面那个网址看ytom哥的例子。








HtmlControl使用方法:
        代码中最先与大家接触的就是CHtmlControl啦,它就是我们与此控件交互的接口,使用很简单,就像标准控件一样创建:
iControl = CHtmlControl::NewL(NULL);
iControl->SetMopParent(this);
iControl->SetRect(ClientRect());
iControl->SetEventObserver(this);
iControl->ActivateL();
AddToStackL(iControl);
        然后将包含html字符的描述符加入控件并刷新就行了:
                        _LIT(KHtml, "<body style='overflow:auto'><p align='center'>"
                        "<font size='large' color='#FF0000'>Hello World!</font><br>"
                        "<font size='20'><b><i>Hello World!</i></b></font><br>"
                        "<text res='"MAKESTR(R_COMMAND1_TEXT)"'><br>"
                        "<div style='line-height:+30'>Hello World!</div><br>"
                        "<a href="http://www.abc.com/" target="_blank" rel="nofflow">                        "<a href="http://archive.cnblogs.com/a/2222716/#abc" target="_blank" rel="nofflow">                        "</p>"
                        );
                        iControl->AppendContentL(KHtml);
                        iControl->RefreshAndDraw();
        这样就得到了本文第一张图片那样的界面。


CHtmlControl的介绍
        CHtmlControl最重要的两个函数就是上面的AppendContentL和RefreshAndDraw,其他的有InsertContentL,在指定位置插入html代码。而Element和ElementByTag则通过元素ID和元素标签两种方法得到元素实例的指针供下一步操作。FocusedElement直接得到处于焦点状态的元素。SetEventObserver通过Symbian Observer模式指定得到htmlcontrol里事件的实例,比如得到EOnClick事件后可以通过aEvent.iElement->GetProperty(KHStrHref,buf)得到用户点的超链接。


解析Html的流程
        CHtmlControl里面包含了CHtmlControlImpl实例的一个指针,实际上几乎所有操作都是通过此指针间接的调用CHtmlControlImpl来操作的,由于使用这种设计隐藏了实现的细节,因此使用此控件的时候会觉得很简单,用作者的话来讲就是“发布的头文件可以干净很多”。
        CHtmlControlImpl最重要的三个函数就是InsertContentL、 ParseL、Refresh,前两个与解析html有关,第三个是解析完成后显示阶段使用。按照程序流程,现在先介绍前两个,CHtmlControl里的AppendContentL、InsertContentL实际上是间接的调用这里的InsertContentL,然后在函数内部又调用了ParseL,在ParseL里又继续调用CHtmlParser里的ParseL,在CHtmlParser的ParseL又调用HcUtils里面EnumTag将Html文档解析为一个个的标签,形如:<a …></a>、<br />,然后在CHtmlParser里调用AppendElementL将完整的标签加入到一个链表里,这个链表完整的串联了所有的从CHtmlElementImpl继承而来的实例,表示各个html元素。现在可以支持的html标签有body、img、a、div、form、input、select、textarea等等,对应的从CHtmlElementImpl继承而来的类是CHtmlElementBody、CHtmlElementImg、CHtmlElementA、CHtmlElementDiv、CHtmlElementForm、CHtmlElementInput、CHtmlElementSelect、CHtmlElementTextArea,而实际上CHtmlElementImpl也是从CHtmlElement继承而来,CHtmlElement保存了一个html元素基本的信息,比如它的Id,标签名等等。
        下面有个简单的序列图可以参考:


        AppendElementL继续调用HtmlParser里的ParseTag,在ParseTag将循环调用HcUtils里的EnumAttribute,将一个完整的标签分解为一个个的属性,比如:
        "<a href="http://www.abc.com/" target="_blank" rel="nofflow">        每个元素都有SetProperty和GetProperty,负责把自己支持的属性保存起来,不支持的忽略,比如CHtmlElementA:
TBool CHtmlElementA::SetProperty(const TDesC& aName, const TDesC& aValue)
{//先调用基类的,用以处理所有元素的共有属性,比如id、tag、name等等。
        if(CHtmlElementImpl::SetProperty(aName, aValue))
                return ETrue;
        //以下处理不同的元素的不同属性
        if(aName.CompareF(KHStrHref)==0) 
        {//href
                delete iHref;
                ihref="http://archive.cnblogs.com/a/2222716/aValue.AllocL();        }
        else if(aName.CompareF(KHStrTarget)==0) 
        {//target
                delete iTarget;
                iTarget = aValue.AllocL();
        }
        else if(aName.CompareF(KHStrInnerText)==0)
        {
                ClearContent();
                
                if(aValue.Length()>0)
                {
                        CHtmlElementText* sub = new (ELeave)CHtmlElementText(iOwner);
                        sub->iParent = iParent;
                        CleanupStack::PushL(sub);
                        sub->PrepareL();
                        sub->SetTextL(aValue);
                        iOwner->Impl()->InsertContent(sub, sub, this, EAfterBegin);
                        CleanupStack::Pop();//sub
                }
                …………………………
        }
        else
                return EFalse;        //对于暂时不支持的属性则忽略
        return ETrue;
}


整个循环结束后,html字符解析就基本结束,下面就是要刷新显示了。


HtmlControl的刷新和显示
        使用的时候很简单,只要调用CHtmlControl的RefreshAndDraw就行了,
void CHtmlControl::RefreshAndDraw()
{
        Refresh();
        Window().Invalidate(Rect());
}
        其中,最重要的就是Refresh,它通过自己保存的CHtmlControlImpl实例指针间接的调用了CHtmlControlImpl的Refresh,这个实现可不简单,遍历先前创建的元素队列,对每个元素进行了3个操作,Measure、Layout、Refresh,Measure主要根据解析的结果对元素的风格、大小、位置进行了设置,Layout主要是对div类型的元素进行设置,其他的采用基类的通用的方法设置本元素的坐标位置,部分元素使用Refresh重新计算内部文字的位置等信息。
        前期准备工作做完后,就可以画出来了,最主要的就是CHtmlControlImpl的Draw,然后通过DrawOffscreen遍历元素列表,调用每个元素的Draw依次画在新创建的CFbsBitGc上,最后再一次性的把CFbsBitGc上的内容画到SystemGc上,核心代码如下:
void CHtmlControlImpl::DrawOffscreen()
{
        iOffScreenBitmap->Gc().CancelClippingRect();
        CHtmlElementImpl* current = iBody;
        do
        {
                if(!current->iState.IsSet(EElementStateHidden))
                        current->Draw(iOffScreenBitmap->Gc());
                current = current->iNext;
        }
        while(current && current!=iBody);
        iState.Clear(EHCSNeedRedraw);
}


按键事件处理
        同系统标准控件一样,按键控件的入口是CHtmlControl的OfferKeyEventL,间接的调用了CHtmlControlImpl的OfferKeyEventL,主要核心处理代码又放在了OfferKeyEventL2中,
TKeyResponse CHtmlControlImpl::OfferKeyEventL2 (CHtmlElementDiv* aContainer, const TKeyEvent &aKeyEvent, TEventCode aType) 
{        
        if(aContainer->iFocusedElement
                && aContainer->iFocusedElement->CanFocus() 
                && !aContainer->iFocusedElement->iState.IsSet(EElementStateHidden))
        {
                if(aContainer->iFocusedElement->TypeId()==EElementTypeDiv
                                && ((CHtmlElementDiv*)aContainer->iFocusedElement)->IsContainer())
                {//如果是容器,将此消息再次发给容器处理
                        if(OfferKeyEventL2((CHtmlElementDiv*)aContainer->iFocusedElement, aKeyEvent, aType)==EKeyWasConsumed)
                                return EKeyWasConsumed;
                }
                 
                if((VisibilityTest(aContainer->iFocusedElement, aContainer->iDisplayRect)
                        )如果控件可见,将按键消息发给控件处理
                        && aContainer->iFocusedElement->OfferKeyEventL(aKeyEvent, aType)==EKeyWasConsumed)
                        return EKeyWasConsumed;
        }
        if(aContainer->iList && !aContainer->iList->IsEmpty())
                return aContainer->iList->OfferKeyEventL(aKeyEvent, aType);


        if(aType!=EEventKey || aContainer->iNext==aContainer->iEnd)
                return EKeyWasNotConsumed;
//如果控件未处理该消息
        aContainer->iState.Clear(EElementStateFocusChanged);
        TInt keyCode = HcUtils::TranslateKey(aKeyEvent.iCode);
        switch(keyCode)
        {//如果是上下左右方向键,则进行元素焦点的转移和显示内容往上或者往下移动
                case EKeyLeftArrow:
                        iState.Set(EHCSNavKeyPrev);
                        HandleKeyLeft(aContainer);
                        break;
                        
                case EKeyRightArrow:
                        iState.Set(EHCSNavKeyNext);
                        HandleKeyRight(aContainer);
                        break;
                        
                case EKeyUpArrow:
                        iState.Set(EHCSNavKeyPrev);
                        HandleKeyUp(aContainer);
                        break;
                        
                case EKeyDownArrow:
                        iState.Set(EHCSNavKeyNext);
                        HandleKeyDown(aContainer); 
                        break;
        }
        ………………………………
}
列举个按了右方向键的处理:
void CHtmlControlImpl::HandleKeyRight(CHtmlElementDiv* aContainer, TBool aScrolled)
{
        CHtmlElementImpl* found = NULL;//找到右边或者下一行第一个可视又可获得焦点的元素
        UpdateVFEs(aContainer);//首先获得可视可获得焦点的元素集合
        if(iVFEs.Count()==0) //如果没有符合要求的元素
        {
                if(!aScrolled && aContainer->iScrollbar->AddStepPos()) //向下滚动视图
                {
                        UpdateVFEs(aContainer);//重新检查是否有可视可获得焦点的元素
                        if(iVFEs.Count()>0) //如果有那么第一个元素就是目标元素,否则不作处理
                                found = iVFEs[0];
                }
        }
        else
        {//如果有符合要求的元素
                TInt index = iVFEs.Find(aContainer->iFocusedElement);
                if(index==KErrNotFound) //如果当前没有焦点元素,那么设置第一个就是焦点元素
                        found = iVFEs[0];
                else if(index<iVFEs.Count()-1) //如果现有的焦点元素不是最后一个,那么它的下一个元素就成为即将设置焦点的元素
                        found = iVFEs[index+1];
                else if(!aScrolled && aContainer->iScrollbar->AddStepPos()) //如果现有元素是可视元素集合中的最后一个,那么下面滚动视图重新处理该消息
                        HandleKeyRight(aContainer, ETrue); 
        }
        if(found)
        {//如果找到了符合要求的元素
                TInt adjustY = aContainer->iScrollbar->RealPos() - aContainer->iScrollbar->Pos();
                TInt offset = found->iPosition.iY + adjustY + found->iSize.iHeight  - aContainer->iDisplayRect.iBr.iY + 2;
                if(offset>0 && offset<aContainer->iDisplayRect.Height())  //可能需要滚动视图
                        aContainer->iScrollbar->AddPos(offset);
                aContainer->FocusChangingTo(found);//设置新焦点元素
        }
}


至此,本文简单介绍了HtmlControl的大体流程,只需要知道怎么用的朋友只要看第一点就够了,如果现有HtmlControl有不符合使用要求或者需要支持的更多的html标签的情况,则大家可以全部看完,在了解了整个流程后,对自己需要修改的方面再详细阅读源代码,多了解细节方面则可以自己修改HtmlControl以适应自己的需求。


HtmlControl值的我们学习和借鉴的是:
        1)将WSD(可写静态数据)放在控件环境CHtmlCtlEnv中,这种方法很巧妙
        2)作者创建了图片池,利用CImageDecoder对各种类型的图片进行解析。
        3)经典的观察者模式的使用
        4)富有层次结构的类设计,如CHtmlControl、CHtmlControlImpl,CHtmlElement <= CHtmlElementImpl <= CHtmlElementA等等
        5)公用属性、代码与各自独有属性、代码的分层设计,比如SetProperty、GetProperty
        6)对不同版本SDK宏的大量运用,一套代码适应不同的SDK


最后再次感谢作者ytom哥给大家带来如此好的开源作品。
symbian 源码 symbian 诺基亚 论坛源程序 编辑环境carbidec++ 立即下载

相关推荐

symbian 源代码

这文件是应用sip协议开发的一个比较基础的工程,对于初学symbian sip 开发的人是一个比较好的借鉴

symbian源码分析-位置

D:\e\symbian_code\symbian_src\src_oss_os 的目录 src_oss_os_boardsupport.zip                    src_oss_os_bt.zip

andych008的专栏 944

symbian源代码

活动对象应用的例子,可以锻炼大家的对活动对象的理解

塞班(Symbian)开源了(包括Symbian 3和S60等)

今天早些时候,塞班基金会正式宣布,其智能手机操作系统Symbian OS的内核及中间件和大部分软件都将以不同的license开放源代码,用户可以下载和修改它们,这次开放的源代码超过4000万行。这次开源行动无疑会吸引更多的开发者到Symbian的marketplace中来,这让近来一直收到iphone和android打压的Symbian OS又找回了些许空间。 全球现在约有3.3亿Symbian...

weixin_34310127的博客 7218

Symbian OS 软件开发教程合集

资源包含以下内容: 中文版: Symbian OS C++程序员编码诀窍 Series 60 Developer Platform 1.0/2.0: 使用C++进行游戏编程 Symbian编程VC开发环境设置.doc 英文版: Developing Software for Symbian OS vol2 Example Code Developer Platform 2.0: Known Issues S60 2nd Edition Feature Pack 1: What’s New – Lead Features and APIs Series 60 Developer Platform 1.0/2.0: Basics Programming for the Series 60 Platform and Symbian OS Symbian OS Explained

html-control

html-control html-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-controlhtml-control

symbian OS:应用程序的架构——单视图和多视图的对比学习及程序实例

Symbian的程序框架   Symbian常用的程序框架是单视图框架和多视图框架两种:单视图框架就是一HelloWord为代表的程序,他是比较简单的程序框架(也是塞班的传统框架),多视图框架也就是我们前面经常有用到的那种双视图程序。 我们还是来回顾一下塞班程序是如何运行起来的。前面已经有提到,塞班运行是从文件app—document—appui--[view]—container按顺序被执

计算机技术博客 1272

Symbian OS C++ 编程诀窍 随书源代码

Symbian出版社《Quick Recipes on Symbian OS...》中文《Symbian OS C++ 编程诀窍》源代码

symbian 源码站点

http://developer.symbian.org/oss 包含部分源代码。

将总结养成一种习惯 605

VECTOR硬件VN1600系列对比:VN1610、VN1611、VN1630A、VN1640A、VN1630log、VN1670

VN16系列说不清道不明的区别和关系

AmorRun的博客 2万+

STM32F103C8T6 Bootloader开发实战:串口IAP固件升级与Keil工程配置详解

本文详细介绍了STM32F103C8T6 Bootloader开发实战,重点讲解串口IAP固件升级的实现方法与Keil uVision5工程配置。通过Flash分区管理、USART1通信协议设计及应用程序跳转机制等核心技术,帮助开发者掌握嵌入式系统固件升级方案,提升设备维护效率。

weixin_29165725的博客 437

手机浏览器开发初步调研

  现在需要在symbian/wm上实现一个简单的功能,点击rtsp://链接,触发我的流媒体播放器来播放。能调用系统播放器最好,俺本不想趟浏览器这摊混水。 但总结网上的资料,得出以下结论:  1.  symbian:    1)  CBrCtlInterface: 调用系统浏览器接口,可嵌入在程序里。虽然bug很多但还是有很多人用。 但是,它只支持file://,http://和

移动视频探索者 3183

细说VLAN之untag和tag

一、拓扑图 先给出上面拓扑图的结论,后面再详细讲解: 结论:只有PC1与PC4之间能相互通信,除此之外,所有PC之间均不能通信,比如PC1与PC3不能建立通信。 针对Ping命令的一个知识: 要想ping通某台主机,必须满足两个条件: 1,源主机的ICMP请求包必须能达到目的主机。 2,目的主机的ICMP应答包必须能回到源主机。 二、理论基础 端口的出...

NoobMaster的博客 3万+

Symbian源码分析(转)

Symbian源码分析:拷贝8位描述符到16位的方法 如果直接用Copy函数的话,16位描述符的长度会被设为8位的长度,如果是ASCII码的话没有问题,中文的话就会乱码,看看Copy函数的源代码: EXPORT_C void TDes16::Copy(const TDesC8 &aDes) { TInt len=aDes.L...

dengxu4495的博客 763

从零开始:使用CMake构建GreenHills RH850项目的完整工作流(2018.1.5版)

本文详细介绍了如何从零开始使用CMake构建GreenHills RH850嵌入式项目的完整工作流。通过编写工具链文件、定义CMakeLists.txt,实现自动化、可维护的跨平台构建,有效解决了传统IDE在多模块、持续集成场景下的局限性,显著提升团队协作效率和项目可维护性。

weixin_28839699的博客 130

【eNSP 华为模拟器】小型校园网模拟环境的设计与配置(附eNSP源文件)

【eNSP 华为模拟器】小型校园网模拟环境的设计与配置 一、实验概述 二、交换机的配置 2.1 二层交换机的配置 2.2 三层交换机的配置 三、路由器的配置 四、实验结果 五、实验总结 一、实验概述 按照以下的拓扑连接,自行设计VLAN和IP地址等网络参数,实现PC1到PC2的IP通信。其中,R1,R2为路由器;LSW1,LSW4为3层交换机;LSW2,LSW3 ,LSW6, LSW7为2层交换机;CLIENT1-CLIENT12为PC机。 拓扑图 课程设计要求:(1)IP地址自行规划设计,应该清晰地

qq_43757282的博客 4万+

跟着Code走,详解Symbian UI程序框架(1)——UI程序结构

在Symbian下开发程序这么久,但是一直不清楚UI程序框架的具体实现是怎样的。虽然有一些参考书籍讲解了大体的结构,但是没有具体看到实现的Code,还是没有那么具体的理解。开源使得我有机会自己去看看,UI程序框架到底是怎样的。这篇文章是一个系列的如下文章,这是第一篇。(1)UI程序结构(2)程序结构进阶,窗口管理及事件分发【UI程序基本结构及用到的核心库】了解Symbian UI程序框架的人,都会很熟悉下图。从下图,我们大概可以看出,初始化过程中会首先创建CAknApplication,再通过CAknApp

胜蓝工作室的专栏 1562

把 ABAP ALV 做成可点、可改、可保存:Interactive Editable ALV Grid 的一套落地打法

文章摘要(148字): SAP ALV报表开发中,交互式可编辑网格的实用方案需解决三个核心问题:数据展示、交互下钻与编辑保存。本文以SCARR航空公司和SFLIGHT航班数据为例,演示如何实现双击主列表下钻明细、动态切换编辑模式、精确保存修改的技术路线。关键点包括:通过PF-STATUS添加业务按钮、使用CHECK_CHANGED_DATA同步前端修改、保护关键字段避免误操作,以及变更数据的审计跟踪方法。该方案适用于SAP GUI环境下的快速业务调整需求,相比Fiori开发具有更高的实施效率。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 231

Symbian学习笔记(2):基本概念

第一次打开SymbianC++的程序源代码,第一感觉就是“这是C/C++吗?咋这么眼生啊”。看代码看书,才算是稍稍明白了一点,其实无非就是typedef罢了,symbian可比brew定义了更多的东西。这是以后干活的基础,所以做个笔记,省得忘了。一、基本数据类型这个比较简单,都在e32def.h中写着呢。也就是以下这几个类型要注意一下,以后照着写罢了,含义也很明了,不用多说。typedef

SHARE & TOP 3514

PMP--工件

合同是指对双方都有约束力的协议,强制卖方提供规定的产品、服务或结果,以及强制买方支付相应的费用。它还可能包括处于中间状态的特性,例如已设计但尚未构建的特性、质量保证中的特性或测试中的特性。RACI 矩阵是一种常见的方法,用于显示执行、担责、咨询或知情,且与项目活动、决策和可交付物有关的干系人。计划是提议的实现某种目标的方式。在项目开始前或开始时创建的文件,涉及与项目有关的战略、商业或高层级的信息。或 © 它们是用特定方法创建的结果,例如,虽然成本估算结果是一个重要工件,它们是用不同估算方法得出的结果。

stqer的博客 1666

从零玩转Vitis裸机开发:手把手教你创建、移植与实战优化

✅ Vitis裸机开发全流程✅ 中断系统配置技巧✅ 跨平台移植方法论✅ 性能优化实战经验研究FreeRTOS移植探索AMP(非对称多处理)架构学习使用Vitis Analyzer进行性能分析技术雷达:关注Xilinx最新推出的Vitis Unified IDE,其集成了更强大的调试和分析工具。立即动手实践吧!

QQ_778132974的博客 584

Symbian源代码还原之一——TRect CCoeControl::Rect(void) const

重要声明:由于Symbian的源代码不是任何人都能得到的,所以这大大限制了我们对Symbian的理解。现在我在业余时间对Symbian框架的模拟器版本代码进行了相应的逆向还原。注意,仅供参考,由于本代码造成的任何问题,均与本人无关! TRect CCoeControl::Rect(void) const { TPoint point; TSize sz; if ( OwnsWindow(

sapair的技术专栏 1184

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Symbian C++的3D游戏引擎的分析(附源码下载)

 3D Types部分仅仅由一个头文件组成。里面包含了一些需要的数据结构的类,并且定义了fixed point的位数。在Symbian C++里面,浮点数都是由int来实现的,通过固定小数点的方法来模拟浮点数,虽然精度有限,但是足够用了。3D Types里面主要有以下几个类:TMatrix一个矩阵类,不过是4x3的。应该是专门用来做旋转的。因为这个引擎并没有用到其次坐标系,应该是出于效

jasonfqw的专栏 1233

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Symbian源代码还原之一,二,三,四,五(转)

Symbian源代码还原之一——TRect CCoeControl::Rect(void) const收藏重要声明:由于Symbian的源代码不是任何人都能得到的,所以这大大限制了我们对Symbian的理解。现在我在业余时间对Symbian框架的模拟器版本代码进行了相应的逆向还原。注意,仅供参考,由于本代码造成的任何问题,均与本人无关!TRect CCoeControl::Rec...

dengxu4495的博客 172

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Symbian专区源代码

Symbian专区源代码

mobilechannel的专栏 2051
上一篇: s60各版本
下一篇: 移动白名单
andych008
博客等级 码龄19年 23粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值