软件工程

本类阅读TOP10

·PHP4 + MYSQL + APACHE 在 WIN 系统下的安装、配置
·Linux 入门常用命令(1)
·Linux 入门常用命令(2)
·使用 DCPROMO/FORCEREMOVAL 命令强制将 Active Directory 域控制器降级
·DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析
·基于ICE方式SIP信令穿透Symmetric NAT技术研究
·Windows 2003网络负载均衡的实现
·一网打尽Win十四种系统故障解决方法
·数百种 Windows 软件的免费替代品列表
·收藏---行百里半九十

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
choice.com 应用推广三部曲

作者:未知 来源:月光软件站 加入时间:2005-6-5 月光软件站

===========================
choice.com 应用推广三部曲
Will Sort - 2005/04/18
Updated:2005/05/14
===========================

序言
==============================================================================

  在 choice.com 出现之前,用户控制批处理运行过程的途径通常被限制在命令行参
数和环境变量上,虽然有个别的编程者会使用debug 的汇编脚本或者 date 、time等一
些可以接受键盘输入的特殊命令来实现运行中接受用户输入的参数,但是它们不是使用
方法很复杂,就是适用的场合很有限,或者还有其他一些诸如此类的问题。

  但是,自从 choice.com 出现后,菜单选择立即成为批处理程序交互的重要手段。
程序中开始大量出现由 echo/choice/if errorlevel goto 所组成的结构范式。然而,
随着 choice.com 不断深入的应用,大家在享受它所带来的便利时,也渐渐无法忍受它
所带来的不便。

  这不便中最主要的,就是 choice.com 仅支持字母和数字等可以指定候选字符的按
键,而对经常会在菜单中用到的回车、空格、Esc 、光标移动、翻页等特殊按键却无法
用字母进行指定,也就无法在菜单中使用它们。

  然而,事实真的如此吗?不妨看看下文会给我们带来哪些收获。
==============================================================================

===========================
三部曲之一:自欺欺人
Will Sort - 2005/04/18
Updated:2005/04/23
===========================

==============================================================================

  首先,让我们进入命令行,当出现命令提示符后,尝试敲入并执行下面的语句:

  choice /n/s/c:Q  Press [PageDown] to quit:

  当按下回车后,我们看到了提示,然后根据提示按下 PageDown 键,然后我们发现
了什么?程序运行结束了!并且在提示语的后面出现了一个大写的字母 Q。


  哦,太神奇了,我发现了新大陆!

  不,这只是新大陆的一个小岛而已。事实上,大部分的特殊按键在 choice.com 中
都对应着一个字母、数字或者其他可以显示出来的字符。

  以下是一些常用的特殊按键对应字符的简明列表:
  ------------------------------------------------------------------------
  ; [F1]   < [F2]     = [F3]    > [F4]    ? [F5]
  @ [F6]   A [F7]     B [F8]    C [F9]    D [F10]

  R [Insert]          G [Home]            I [Page Up]
  S [Delete]          O [End]             Q [Page Down]

                      H [UP Arrow]
  K [Left Arrow]      P [Down Arrow]      M [Right Arrow]

  27 [Esc]            8 [Back Space]
  ------------------------------------------------------------------------

  我们可以再根据上表中提供的字符做新的尝试:

  choice /n/s/c:; Press [F1] to quit:

  哈,又成功了!再试:

  choice /n/s/c:< Press [F2] to quit:

  啊,出错了!找不到文件,怎么回事?
  嗯,你用的小于号是系统定义的文件重定向符号,它把 Press当成文件重定向了。
  那怎么办?
  简单,在小于号两边加上双引号,系统不认识小于号就行了,就像这样:

  choice /n/s/c:"<" Press [F2] to quit:

  哈,真是这样呢!
  那么,你可以再多试一些练习一下。
  好,我试,我试,我试试试。

  choice /n/s/c:= Press [F3] to quit: ---〉成功!
  choice /n/s/c:> Press [F4] to quit: ---〉失败!
  哦,不对,改:
  choice /n/s/c:">" Press [F4] to quit: ---〉成功!
  choice /n/s/c:? Press [F5] to quit: ---〉成功!

  好了,我会用了,但是,这到底是怎么回事呢?

  原因嘛,深究起来比较复杂;简单的说,是因为这些特殊的按键会产生一种系统可
以识别的扩展编码,一般是由0 或者224 和另一数字编码组成。而 choice.com 接受这
些按键时,会将编码中认为无效的0 或者224 过滤掉,而剩下后面的数字编码,而这部
分数字又恰好会被误认为是某个可显示字符的 ASCII编码。以开始提到的 PageDown 来
说,它的扩展编码就是“0;81”,而与此相对应的,字母 Q的 ASCII编码也是81,于是
choice.com就将这 PageDown 和 Q这两个键混淆了。其它“F1”和分号、“F2”和小于
号等等都是类似的原因。这也是本节篇名“自欺欺人”的由来。
  等等,你说什么“扩展编码”,那是什么东东?
  “扩展编码”实际上是 MS-DOS 从键盘读取按键时,经由键盘扫描码略加修改转换
后的一种按键的内部编码,通过这种转换后的编码形式,它可以兼容地处理 ASCII字符
键和非 ASCII字符键(就是在 ASCII码表中找不到对应编码的按键)。
  呵,似懂非懂啊,还是算了吧。

  等一下,表里面最后一个 Esc ,前面怎么是个二位数?

  哦,你观察的倒真仔细。是这样的, Esc还有 BackSpace,它们与 PageDown 有所
不同。那就是 Esc和 BackSpace它们都是 ASCII字符键,也就是说它们在 ASCII码表中
可以找到对应的编码,正是表中所列的 27 和 8。而这个数字同时也是它们的扩展编码
只有一串数字,没有0 或者 224打头,这就意味着,它们在独立地在 ASCII码表中占用
两个位置,也就没有可能冒充其他的字符。
  同时,因为他们在命令行和各种编辑器中都被赋予了特殊的含义(命令行中 Esc用
来重写命令, BackSpace用来向前删除字符),所以就无法通过按键直接输入字符来指
定候选键。但是,实际上 choice.com 是可以接受 27 和 8这样的编码的,所以我们只
要想办法将这两个键变成字符输进命令行就可以完成任务了。

  唔,那么怎么把它们输进去呢?
  这就要请出我们命令行工具的不老悍将—— edit 了。
  edit,就是那个DOS 下面打字的软件吗?

  对,准确的说, edit 是一个文本编辑器;它有个很实用的功能,就是用 Ctrl+P
输入特殊字符。比如,我们要把 Esc当作字符输进去,就可以先按下Ctrl+P,放开后再
按Esc ,这时一个向左的小箭头就会出现了,它就是Esc 在 ASCII码表中对应的字符;
同样,按下 Ctrl+P 、 BackSpace后就会出现一个带圆孔的长方块,那就是 BackSpace
对应的字符了。

  输进去以后怎么办呢?
  这样,我们可以把上面的 choice.com 语句写进批处理程序中,然后将 /c 后面的
候选字符换成我们刚刚学会输入的那两个字符,就像下面这样:

  @choice /n/s/c: Press [Esc] or [BackSpace] to quit:

  将上面这个句子保存为批处理程序,比如“Esc-BkSp.bat”。然后,在命令行中执
行它。然后按 Esc 和 BackSpace 试试看。

  唉,终于成功了!好累啊,不过也蛮有成功感的。

  嗯,到这里,我们的第一部曲也该就此结束了。现在,我们应该可以解决一些以前
用 choice.com 时无法解决的问题。但是,仍然还有一些问题,比如我们一直没讲到回
车键怎么在 choice.com 中使用,它无论在命令行还是在批处理中都被当作了语句结束
的标志,因而始终无法作为候选字符使用,还有很多其它的一些类似的特殊按键(例如
Tab )因为同样的原因而无法使用。
  而这些,都将留在第二部曲“瞒天过海”中探讨和解决。

  最后,作为本节内容的附赠品,一篇详细标明更多特殊按键扩展编码以及替代字符
的列表以附件形式列于其后,附件中还包括 EscBksp.bat和 PgDw.bat 用以测试是否支
持 [Esc]/[BackSpace]/[PageDown] 等特殊的按键。在 EscBksp.bat中使用了自动获取
 [Esc]/[BackSpace]这两个特殊按键对应字符的方法。
------------------------------------------------------------------------------

编后语:

  其实,就我自己而言,很不习惯也很不喜欢写这样风格的文字,短短的一篇技术短
文硬是被拖拽成了又长又臭的搞笑散文 :< 没办法,为了照顾大多数初学者,只好牺牲
一下我的个人品味了 :) 不过,在后两节文字中,随着技术含量的增加,同时也是为了
照顾我的个人情绪,我将会适当的提高文章的理解水平底线,低于此线的朋友们,在此
先说声抱歉了。
==============================================================================

===========================
三部曲之二:瞒天过海
Will Sort - 2005/04/24
Updated:2005/04/30
===========================

==============================================================================

  在上节中我们留下一个题目,那就是如何让 choice.com 接受并正确处理回车键以
及其他一些系统保留的特殊键。我的答案是键盘重定义,就是将键盘上的特殊键重定义
为我们可以利用的常规键,比如字母或者数字。

  这需要使用从 MS-DOS 时代起便出现的一个设备驱动程序 ANSI.SYS 。它是为了支
持美国国家标准学会(ANSI)所制订的一套关于键盘和屏幕控制的标准而设计的,具有
相当丰富的键盘和屏幕控制功能,详细内容可以参阅附件中的文档 ANSI_SYS.TXT 。利
用它所提供的重定义键(实际上是重定义键的扩展编码)的功能,可以将回车重定义为
字母‘y’,从而实现我们的初衷。但是要使用这个功能,我们需要预先做一些准备。

在 MS-DOS 和 Win98 中准备使用 ANSI.SYS
--------------------------------------

  在 MS-DOS 和 Win98的命令行环境中,我们使用 ANSI.SYS 需要通过一个启动配置
文件来加载它,那就是 config.sys ,它是一个纯文本文件,通常位于系统所在盘的根
目录,可以用“记事本”或者上节提到的“edit”来编辑它。我们可以在这个文件的最
后添加一行如下的文字:

  device=c:\Windows\Command\ANSI.SYS /x

  其中的 C:\Windows\Command 可能需要替换成 ANSI.SYS 文件实际所在的目录。比
如你是 MS-DOS 的用户,那么 ANSI.SYS 很可能在 C:\DOS 下。

  编辑完成后,重新启动计算机就可以在 MS-DOS 或者 Win 98 的命令行环境下使用
 ANSI.SYS 所提供的各种功能特性了。

在 Win2K 和 WinXP 中准备使用 ANSI.SYS
-------------------------------------

  在 Win2K和 WinXP的命令行环境中,已不再使用 config.sys ,但是可以在系统路
径下的 System32 目录中找到一个替代品,那就是 config.nt,它用于配置 MS-DOS 模
拟环境(command.com)。它也是纯文本文件,所以也可以用记事本打开并编辑它。我
们需要给它加上与 MS-DOS 和 Win9x 系统相类似的文字:

  device=%SystemRoot%\system32\ANSI.SYS /x

  其中的 %SystemRoot% 是个全局的环境变量,我们可以直接使用它引用系统路径,
而不需要人为地修改它。

  与 MS-DOS 和 Win9x 的命令行环境不同的是,我们还需要修改 config.nt 文件中
的一个细节,那就是将“REM DOSONLY”一行中的“REM”去除。这样做的原因是,ANSI
是一个基于 MS-DOS 的终止并驻留(TSR)内存的程序,它需要一个纯粹的运行 MS-DOS
程序的环境,否则就会无法正常的使用。而 DOSONLY正是创建这个环境的必要开关,所
以我们去掉它前面的注释命令,以使它在 config.sys 中生效。

  所有的设置修改完成后,就可以立即在运行中输入 “command”(不是 CMD),此
时有 ANSI 支持的命令行环境就被启动了。

开始体验 ANSI.SYS
-----------------

  准备了这么久,我们终于可以使用 ANSI.SYS 带给我们的特性了,请将下面的代码
拷贝并保存到批处理文件中。

  @echo off
  echo [13;'y'p-------- Start -------------
  choice Press Enter or Y to quit: /c:y /n
  echo --------- End --------------
  pause

  然后在我们刚才启动的有 ANSI 支持的命令行环境下,执行这个批处理,看到提示
后我们按回车键:此时,程序运行结束,并在提示语后出现一个大写字母 'Y'。

  我们分析一下程序,第一行是将命令回显关闭,第二行就用了 ANSI 的重定义键功
能, echo 后面的向左箭头就是上节中提到的 Esc 键的 ASCII 字符,它和'[' 联合使
用,标志着随后的序列开始使用 ANSI 的功能,它们不会被 echo ,而会被 ANSI 发现
并转变其含义,因此这个序列被称为转义序列,Esc 也被称为转义字符。第三行是供我
们测试的 choice 语句,其中仅仅定义了一个候选字符‘y’;第四行是恢复回车原来
的定义;第五行实现暂停。

  而转义序列“13;'y'p”的意思,我们应该可以猜得出来,那就是将回车重定义为
字母‘y',回车的表示正是上节中提到的扩展编码,而字母‘y'被单引号括了起来,表
示它是一个 ASCII 字符,而非字符的编码;至于紧跟其后的字母‘p’正是重定义键的
功能标志。而后面的 -Start- 并不是转义序列的一部分,将会原样输出。

  我们也可以实现更多地重定义按键,比如制表符键、光标键、删除键、回删键等,
详细的代码请参阅附件中的 Remap2.bat ,我们可以在命令行中执行它,然后测试一
下我们的按键和输出结果是否一一匹配。

如何在我需要时才使用 ANSI.SYS
-----------------------------

  以上对 config.sys 和 config.nt 的修改将会使以后运行所有的 MS-DOS 程序都
可以享用 ANSI.SYS 所带来的特性,但同时也会始终占用命令行环境下约 4K 的内存空
间。我们可能并不想这样,因为我们并不经常需要 ANSI.SYS 的支持,当我们不需要它
时,总是不希望它浪费我们宝贵的内存空间。

  要解决这个问题,我们可以在系统启动以后再加载它。在 MS-DOS 环境中,当需要
使用 ANSI.SYS 的时候,一般使用 device.exe 或者其他有相似功能的第三方程序在命
令行加载 ANSI.SYS ,不需要的时候也同样可以卸载它。

  在 Win9x的命令行环境中,我们多了一种选择,那就是为需要使用 ANSI.SYS 的程
序编辑自己专属的启动配置文件:在程序的右键“属性”菜单中,选择“程序->高级->
MS-DOS方式->指定新的 MS-DOS 配置”,然后在 config.sys 的对话框中添加 device
语句即可。但是这个方法的缺点是启动和退出这个程序时,都会重新启动系统以进入新
的命令行环境。而在WinXP 中,没有了 Win9x的缺点,我们可以为需要使用 ANSI.SYS
的程序创建一个指向 MS-DOS 程序的快捷方式(.PIF文件):在程序所在文件夹的空白
处点击右键,选择“新建->快捷方式”,在文本框中填入 command,然后一路回车,在
出现“MS-DOS方式”之后,在右键“属性”菜单中,修改程序名为 Remap2.bat ,修改
启动配置文件为我们自己制作的启动配置文件,比如附件中的 Remap_XP.PIF 使用的便
是 %SystemRoot%\System32 下的 ANSI_SYS.NT(对应CONFIG.NT)和 ANSI_BAT.NT(对
应AUTOEXEC.BAT),它们可以在附件中 ANSI_XP 文件夹中找到。

  这一节我们讲述了如何通过 ANSI 的重定义键功能来实现 CHOICE 接受任意按键,
除了极个别的按键之外(如 Ctrl+Break 或者 Ctrl+Alt+Del ),我们已经可以处理各
种常用的特殊键。下一节,我们将涉及 choice 的另一个应用需求,那就是默认按键的
优化。
------------------------------------------------------------------------------

编后语:

  可能对于很多人来说,本节是比较枯燥的一节,因为它的文字量远远大于代码量,
以至于让很多兄弟少了很多实践锻炼的素材,也许将 Remap2 贴上是个办法,但我并不
愿意如此做。下一节,这种情况就会完全反过来了,请大家也有所准备。

  另外,本节的内容很久前就筹划好了,大概是在回复了“联合 DOS论坛”的一位站
友关于 choice.com 接受回车键的问题帖之后。只是后来觉得这种方法有很多的缺陷,
我们必须预先配置命令行环境,然后才能在这个环境中运行相应的程序;而对于 XP 等
NT类环境来说,这种配置无法全局有效,对 config.nt的修改只能影响 command.com,
而无法影响直接点击运行的批处理程序,因为它们默认是启用 cmd作为命令解释器的。
直到不久前发现 XP 中也可以借助 .PIF 文件进行启动配置,我才下定决心将此节继续
完成并公布于众。

  因为花了很多时间编写并测试一些代码实例,以及其他一些无关的工作,所以本节
出得稍微晚了一些。如果没有意外,第三节可能会快一些,因为我将不会做太多的文字
说明。
==============================================================================

===========================
三部曲之三:借花献佛
Will Sort - 2005/05/03
Updated:2005/05/15
===========================

==============================================================================

  在上一节中,我们基本完成了 choice 接受任意按键的任务,现在我们将目标定位
在 choice 的其他功能扩展上。而探讨的焦点就在 choice 的缺省按键功能上。

  当我们用 /t 开关指定了缺省按键后,经常会有一个问题,那就是一旦按下了某个
候选字符未指定的按键,就会终止缺省按键的倒计时。这是程序固有的细节,我们很难
通过外部的办法来改变它,于是,我们所能使用的最佳方法就是从内部修改它。

  修改一个可执行程序,并不是一件十分神秘高深的事情,虽然它有可能是一件枯燥
乏味的事情:)但是只要选对合适的工具,这项工作也将会进行的顺利和简单。可执行程
序是一个二进制文件,在 Windows下有很多人选择 UltraEdit或者 WinHex 来修改它,
但是,在这个案例中,为了兼顾 MS-DOS 的使用者,同时也考虑到修改过程的自动化,
我决定使用 DOS平台下的程序调试器—— DEBUG.EXE。

  作为 DOS下的调试工具, DEBUG.EXE有着相当广泛的用途。一方面它是一个二进制
文件编辑器,另一方面它又是一个汇编与反汇编器,同时也担当着用户与底层硬件的交
互平台,特别是在早期的逆向工程领域中,它扮演着举足轻重的角色,因此有着“屠龙
宝刀”的诨号,我们在这里使用它来扩展 choice 的使用功能,只能说是牛刀小试。关
于它子命令的用法说明,可以在网络上找到许多相当优秀的教程文章。

  修改程序之前,我们首先需要熟悉程序的流程,尤其是修改处的细节流程。我们运
用 debug的 d/u/g/t/p/ 等命令可以了解到 choice.com 的流程大致如下:

------------------------------------------------------------------------------
   CS:0100  跳至0211程序区 jump 0211 program area
   CS:0103  数据区 date area
   CS:0211  检查系统版本号 Verify MS-DOS version is 4.0 or later
   CS:0236  获取大写字母表 Get Upper Case Table address/bias
   CS:0262  分析命令行 Parse command line
   CS:03C7  转换小写字母 convert choices and default to Upper Case
   CS:03E9  检查缺省选择 verify specified default is in Choices
   CS:0401  显示选择提示 Display prompt
   CS:0442  等待按键或倒计时结束 wait for timeout or keypress
   CS:0476  接受按键 get key
   CS:04A4  显示按键并设置错误码后退出 got key, set errorlevel, quit
------------------------------------------------------------------------------
 
  进而分析我们关心的倒计时终止部分:
------------------------------------------------------------------------------
   CS:0442  计时秒数若为0 则跳至0476等待按键,否则取当前秒数后继续
   CS:0451  如果有案件则跳至0476,否则继续
   CS:045D  如当前秒数变化,则计时秒数减一后继续,否则跳至0451循环
   CS:046B  若计时秒数为0 则模拟按下缺省键并跳至0485,否则跳至0451循环
   CS:0476  接收按键
   CS:0485  搜索按键是否候选,如果是跳至04A4,如果否跳至049C
   CS:049C  响铃后跳至0476(* 注意此处 *)
   CS:04A4  显示并设置按键后退出
------------------------------------------------------------------------------

  从上面的分析可以看出,问题的关键在于 049C--04A4 之间的错误按键处理段。在
此处,程序响铃(即输出字符 07 )后,跳到了 0476 继续接收按键,从此不再计时。
解决的办法很简单,只需要将这个跳转地址改为 0451/045D的任意一处即可。通过 u命
令反汇编,确定这个跳转命令的地址 04A2 ,这样我们只要通过 a 4a2将汇编代码 jmp
476 替换为 jmp 451即可。

  此外,我们还可以考虑其它的一些功能上的扩展。比如无效按键不能终止倒计时,
在用户需要谨慎选择的时候,就需要一个特有按键(比如 ESC)停止倒计时;又比如,
按下一个常用键(比如回车或者空格),可以直接选择任意设定的缺省按键。

  这些功能的实现都不是很复杂,但前提是操作者要有一定的汇编编程和程序调试经
验。当然,谁也不可能要求所有的 DOS用户都能熟悉甚至了解 DEBUG子命令和 8086 代
码集。所以对于大多数人,本文提供了更为简洁的操作方式——批处理。这个程序可以
在附件的 X3 文件夹下见到,名为 ModChc.bat ,点击它即可以自动地根据可以找到的
choice.com生成一个新的 choicex.com。这个新的程序也可以在附件中的同样位置直接
找到,它业已实现了我在上面所提到的三项扩展。

  关于 xchoice.com更详细准确的描述如下:
------------------------------------------------------------------------------
  1.如果指定缺省选择键,键入无效选择键不会终止取缺省选择时的倒计时
  2.如果指定缺省选择键,可通过键入回车或空格键终止计时并立即返回缺省选择键
  3.如果指定缺省选择键,可通过键入跳出键终止计时并等待至键入有效选择键
  4.指定缺省选择键时,设置等待时间为 0,可实现仅在按回车或空格时取缺省选择
   键而不会限时。如:choice /c:qwert /t:w,0
  5.当指定跳出、回车或者空格键为选择键时,其终止计时的功能将相应失效
------------------------------------------------------------------------------

  如果程序附件的链接失效,或者你无法得到附件,那么可以根据下文提供的修改脚
本自己用 debug修改 choice.com ,命令格式如下:

  debug choice.com < choicex.asd > nul

  注意:在修改前请自己备份原程序
------------------------------------------------------------------------------
:: ChoiceX.asd - Choice 扩展 DEBUG 汇编脚本
:: Will Sort - 14:48 2005-5-15 - Debug
:: Modifition:
::   1.Not terminates timeout when press invalid choice key
::   2.press ESC to terminate timeout
::   3.press CR or SPACE to choose default choice key
a 047D
JNZ     0482        ; Call 0A80 when press control key
CALL    0A80        ; get second byte of scancode of control key
CALL    0A85        ; process event of press ESC, CR, SPACE

a 04A2
JMP     0451        ; Not terminate timeout when press invalid choice key       

a 0A80
MOV     AH,08       ; get char again
INT     21
RET
CMP     AL,1B       ; if press ESC
JZ      0A94        ; YES, terminate timeout
CMP     AL,0D       ; if press CR
JZ      0A91        ; Yes, goto set default choice
CMP     AL,20       ; if press SPACE
JNZ     0A99        ; No, goto return
MOV     AL,[018A]   ; set default choice
MOV     BYTE PTR [0189],00    ; set timeout is zero
RET

n ChoiceX.com
w
q
:: Please reserved this line.
------------------------------------------------------------------------------

编后语:

  第三部曲的准备,其实很早前就开始了,只是中途不耐于繁琐的文档整理而罢手,
直到这次执笔编写应用扩展三部曲,才又将它从故纸堆里翻了出来,花了几天时间重新
整理文档,又删除了一些复杂而不实用的修改(比如用十六进制的 ASCII编码指定候选
按键),简化了许多代码,终于成了现在的模样。

  至此,《 choice.com 应用扩展三部曲》已全部结束。回顾近一个月的编写历程,
仍不免留有一些遗憾,但已基本达成我的初衷,应该可以给自己有所交待了。希望它能
够对大家有所启发和帮助,也希望大家能对它提出自己宝贵的意见和建议,联系地址可
通过帖子上方的邮件功能找到。

  最后,在此真诚地祝愿所有的读者健康、快乐!
==============================================================================




相关文章

相关软件




月光软件源码下载编程文档电脑教程网站优化网址导航网络文学游戏天地生活休闲写作范文安妮宝贝站内搜索
电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

月光软件站·版权所有