如何象commanddialog选择一个文件一样选择一个目录

crazypeople 2005-08-28 01:45:17
谢谢!!!!
...全文
92 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
kenny 2005-08-29
  • 打赏
  • 举报
回复

我的样例,供楼主参考:


使用 API 制作选择目录位置的对话框


'声明 API 选择目录时使用

Private Type BROWSEINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type

Private Const BIF_RETURNONLYFSDIRS = &H1

Private Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long


'选择存放目录
Private Sub SelFolder_Click()

Dim bi As BROWSEINFO
Dim r As Long
Dim pidl As Long
Dim path As String
Dim pos As Integer

bi.hOwner = Me.hWnd '句柄
bi.pidlRoot = 0& '展开根目录
bi.lpszTitle = "输出条形码位置 : " '列表框标题
bi.ulFlags = BIF_RETURNONLYFSDIRS '规定只能选择文件夹,其他无效
pidl = SHBrowseForFolder(bi) '调用API函数显示列表框
path = Space$(512) '利用API函数获取返回的路径
r = SHGetPathFromIDList(ByVal pidl&, ByVal path)

If r Then
pos = InStr(path, Chr$(0))
Folder_L.Caption = Left(path, pos - 1) '返回选择的目录位置
Else
Folder_L.Caption = ""
End If

End Sub





fishmans 2005-08-28
  • 打赏
  • 举报
回复
dirlistbox不就是这么个东西吗?
crazypeople 2005-08-28
  • 打赏
  • 举报
回复
就是让用户选择路径 可以手动输入 也可以通过一个点击选择 象commanddialog选择文件一样 选择
pweixing 2005-08-28
  • 打赏
  • 举报
回复
目的是什么??
百度首页 | 百度空间 | 登录 广告停放提高网站流量,centos学习 主页博客相册|个人档案 查看文章
.htaccess怎么用2007-05-16 14:04(文章来源)http://www.dnpark.com.cn/news/mm/www/1179329504375ZKlMSgYr.html

Apache服务器的.htaccess是一个非常强大的分布式配置文件,学会使用.htaccess,对虚拟主机用户来说,可以实现众多的功能。这里有一篇很容易让人理解的.htaccess介绍,作为入门文章非常的适合。文章最初来自freewebmasterhelp.com,QiRan作了简单的中文翻译,我将加以完善。

Part 1 – Introduction介绍
Part 2 - .htaccess Commande命令
Part 3 - Password protection密码保护
Part 1 – Introduction介绍

Introduction 介绍

In this tutorial you will find out about the .htaccess file and the power it has to improve your website. Although .htaccess is only a file, it can change settings on the servers and allow you to do many different things, the most popular being able to have your own custom 404 error pages. .htaccess isn't difficult to use and is really just made up of a few simple instructions in a text file.
从本指南中,你将可以学习到有关.htaccess文件及其功能的知识,并用以优化你的网站。尽管.htaccess只是一个文件,但它可以更改服务器的设置,允许你做许多不同的事情,最流行的功能是您可以创建自定义的“404 error”页面。.htaccess 并不难于使用,归根结底,它只是在一个text文档中添加几条简单的指令而已。

Will My Host Support It? 我的主机支持它吗?

This is probably the hardest question to give a simple answer to. Many hosts support .htaccess but don't actually publicise it and many other hosts have the capability but do not allow their users to have a .htaccess file. As a general rule, if your server runs Unix or Linux, or any version of the Apache web server it will support .htaccess, although your host may not allow you to use it.
这可能很难用简单的答案来回答。许多主机支持.htaccess,但实际上并不会特别声明,许多其他类型的主机有能力但并不允许他们的用户使用.htaccess。一般来说,如果你的主机使用Unix或Linux系统,或任何版本的Apache网络服务器,从理论上都是支持.htaccess的,尽管你的主机服务商可能不允许你使用它。

A good sign of whether your host allows .htaccess files is if they support password protection of folders. To do this they will need to offer .htaccess (although in a few cases they will offer password protection but not let you use .htaccess). The best thing to do if you are unsure is to either upload your own .htaccess file and see if it works or e-mail your web host and ask them.
判断你的主机是否允许.htaccess,一个标志很好的是它是否支持文件夹密码保护。为达到此功能,主机服务商需要使用.htaccess(当然,少数情况下他们虽提供密码保护功能,但却并不允许你使用.htaccess)。如果你不确定自己的主机是否支持.htaccess,最好的办法是上传你自己的.htaccess文件看看是否有用,或者直接发送e-mail向你的主机服务商咨询。

What Can I Do? 我该怎么做?

You may be wondering what .htaccess can do, or you may have read about some of its uses but don't realise how many things you can actually do with it.
你可能疑惑.htaccess到底能做些什么,或者你可能曾知道它的一些功能但并不真正了解你实际到底可以用它来做多少事情。

There is a huge range of things .htaccess can do including: password protecting folders, redirecting users automatically, custom error pages, changing your file extensions, banning users with certian IP addresses, only allowing users with certain IP addresses, stopping directory listings and using a different file as the index file.
.htaccess可以做大量的事情,包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件

Creating A .htaccess File 创建一个.htaccess文档

Creating a .htaccess file may cause you a few problems. Writing the file is easy, you just need enter the appropriate code into a text editor (like notepad). You may run into problems with saving the file. Because .htaccess is a strange file name (the file actually has no name but a 8 letter file extension) it may not be accepted on certain systems (e.g. Windows 3.1). With most operating systems, though, all you need to do is to save the file by entering the name as:
创建.htaccess文件也许会给你带来一些困难。写文件很容易,你只需要在文字编缉器(例如:写字板)里写下适当的代码。真正困难的可能是文件的保存,因为.htaccess是一个古怪的文件名(它事实上没有文件名,只有一个由8个字母组成的扩展名),而在一些系统(如windows 3.1)中无法接受这样的文件名。在大多数的操作系统中,你需要做的是将文档保存成名为:

".htaccess"
(including the quotes). If this doesn't work, you will need to name it something else (e.g. htaccess.txt) and then upload it to the server. Once you have uploaded the file you can then rename it using an FTP program.
(包括引号)。如果这也不行,你需要将其先命名为其它名字(例如htaccess.txt),再将其上传到服务器上,之后直接使用FTP软件来重命名。

Warning 警告

Before beginning using .htaccess, I should give you one warning. Although using .htaccess on your server is extremely unlikely to cause you any problems (if something is wrong it simply won't work), you should be wary if you are using the Microsoft FrontPage Extensions. The FrontPage extensions use the .htaccess file so you should not really edit it to add your own information. If you do want to (this is not recommended, but possible) you should download the .htaccess file from your server first (if it exists) and then add your code to the beginning.
在使用.htaccess之前,我必须给你一些警告。虽然在服务器上使用.htaccess绝对不太可能给你带来任何麻烦(如果有些东西错了,它只是没效用罢了),但如果你使用Microsoft FrontPage Extensions,就必须特别小心。因为FrontPage Extensions本身使用了.htaccess,因此你不能编辑它并加入你自己的信息。如果确实有这方面的需要(并不推荐,但是可能),你应该先从服务器上下载.htaccess文档(如果存在),之后在前面加上你的代码。

Custom Error Pages 自定义错误页

The first use of the .htaccess file which I will cover is custom error pages. These will allow you to have your own, personal error pages (for example when a file is not found) instead of using your host's error pages or having no page. This will make your site seem much more professional in the unlikely event of an error. It will also allow you to create scripts to notify you if there is an error (for example I use a PHP script on Free Webmaster Help to automatically e-mail me when a page is not found).
我要介绍的.htaccess的第一个应用是自定义错误页面,这将使你可以拥有自己的、个性化的错误页面(例如找不到文件时),而不是你的服务商提供的错误页或没有任何页面。这会让你的网站在出错的时候看上去更专业。你还可以利用脚本程序在发生错误的时候通知你(例如我使用Free Webmaster Help的PHP脚本程序,当找不到页面的时候自动e-mail给我)。

You can use custom error pages for any error as long as you know its number (like 404 for page not found) by adding the following to your .htaccess file:
你所知道的任何页面错误代码(像404找不到页面),都可以通过在.htaccess文件里加入下面的文字将其变成自定义页面:

rrorDocument errornumber /file.html
For example if I had the file notfound.html in the root direct
ory of my site and I wanted to use it for a 404 error I would use:
举例来说,如果我的根目录下有一个nofound.html文件,我想使用它作为404 error的页面:

ErrorDocument 404 /notfound.html
If the file is not in the root directory of your site, you just need to put the path to it:
如果文件不在网站的根目录下,你只需要把路径设置为:

ErrorDocument 500 /errorpages/500.html
These are some of the most common errors:
以下是一些最常用的错误:

401 - Authorization Required 需要验证
400 - Bad request 错误请求
403 - Forbidden 禁止
500 - Internal Server Error 内部服务器错误
404 - Wrong page 找不到页面
Then, all you need to do is to create a file to display when the error happens and upload it and the .htaccess file.
接下来,你要做的只是创建一个错误发生时显示的文件,然后把它们和.htaccess一起上传。


Part 2 - .htaccess 命令

Introduction 介绍

In the last part I introduced you to .htaccess and some of its useful features. In this part I will show you how to use the .htaccess file to implement some of these.
在上一部分,我已经简单介绍了.htaccess以及它的一些有用功能,在这一部分,我将向你演示如何使用.htaccess文档去实现这些功能。

Stop A Directory Index From Being Shown 停示显示目录列表

Sometimes, for one reason or another, you will have no index file in your directory. This will, of course, mean that if someone types the directory name into their browser, a full listing of all the files in that directory will be shown. This could be a security risk for your site.
有些时候,由于某种原因,你的目录里没有index文件,这意味着当有人在浏览器地址栏键入了该目录的路径,该目录下所有的文件都会显示出来,这会给你的网站留下安全隐患。

To prevent against this (without creating lots of new 'index' files, you can enter a command into your .htaccess file to stop the directory list from being shown:
为避免这种情况(而不必创建一堆的新index文件),你可以在你的.htaccess文档中键入以下命令,用以阻止目录列表的显示:

Options -Indexes
Deny/Allow Certian IP Addresses 阻止/允许特定的IP地址

In some situations, you may want to only allow people with specific IP addresses to access your site (for example, only allowing people using a particular ISP to get into a certian directory) or you may want to ban certian IP addresses (for example, keeping disruptive memembers out of your message boards). Of course, this will only work if you know the IP addresses you want to ban and, as most people on the internet now have a dynamic IP address, so this is not always the best way to limit usage.
某些情况下,你可能只想允许某些特定IP的用户可以访问你的网站(例如:只允许使用特定ISP的用户进入某个目录),或者想封禁某些特定的IP地址(例如:将低级用户隔离于你的信息版面外)。当然,这只在你知道你想拦截的IP地址时才有用,然而现在网上的大多数用户都使用动态IP地址,所以这并不是限制使用的常用方法。

You can block an IP address by using:
你可以使用以下命令封禁一个IP地址:

deny from 000.000.000.000
where 000.000.000.000 is the IP address. If you only specify 1 or 2 of the groups of numbers, you will block a whole range.
这里的000.000.000.000是被封禁的IP地址,如果你只指明了其中的几个,则可以封禁整个网段的地址。如你输入210.10.56.,则将封禁210.10.56.0~210.10.56.255的所有IP地址。

You can allow an IP address by using:
你可以使用以下命令允许一个IP地址访问网站:

allow from 000.000.000.000
where 000.000.000.000 is the IP address. If you only specify 1 or 2 of the groups of numbers, you will allow a whole range.
被允许的IP地址则为000.000.000.000,你可以封禁IP地址一样封禁整个网段。

If you want to deny everyone from accessing a directory, you can use:
如果你想阻止所有人访问该目录,则可以使用:

deny from all
but this will still allow scripts to use the files in the directory.
不过这并不影响脚本程序使用这个目录下的文档。

Alternative Index Files 替换index文件

You may not always want to use index.htm or index.html as your index file for a directory, for example if you are using PHP files in your site, you may want index.php to be the index file for a directory. You are not limited to 'index' files though. Using .htaccess you can set foofoo.blah to be your index file if you want to!
也许你不想一直使用index.htm或index.html作为目录的索引文件。举例来说,如果你的站点使用PHP文件,你可能会想使用index.php来作为该目录的索引文档。当然也不必局限于“index”文档,如果你愿意,使用.htaccess你甚至能够设置foofoo.balh来作为你的索引文档!

Alternate index files are entered in a list. The server will work from left to right, checking to see if each file exists, if none of them exisit it will display a directory listing (unless, of course, you have turned this off).
这些互为替换的索引文件可以排成一个列表,服务器会从左至右进行寻找,检查哪个文档在真实的目录中存在。如果一个也找不到,它将会把目录列表显示出来(除非你已经关闭了显示目录文件列表)。

DirectoryIndex index.php index.php3 messagebrd.pl index.html index.htm
Redirection 重定向

One of the most useful functions of the .htaccess file is to redirect requests to different files, either on the same server, or on a completely different web site. It can be extremely useful if you change the name of one of your files but allow users to still find it. Another use (which I find very useful) is to redirect to a longer URL, for example in my newsletters I can use a very short URL for my affiliate links. The following can be done to redirect a specific file:
.htaccess最有用的功能之一就是将请求重定向到同站内或站外的不同文档。这在你改变了一个文件名称,但仍然想让用户用旧地址访问到它时,变的极为有用。另一个应用(我发现的很有用的)是重定向到一个长URL,例如在我的时事通讯中,我可以使用一个很简短的URL来指向我的会员链接。以下是一个重定向文件的例子:

Redirect /location/from/root/file.ext
http://www.othersite.com/new/file/location.xyz
In this above example, a file in the root directory called oldfile.html would be entered as:
上述例子中,访问在root目录下的名为oldfile.html可以键入:

/oldfile.html
and a file in the old subdirectory would be entered as:
访问一个旧次级目录中的文件可以键入:

/old/oldfile.html
You can also redirect whole directoires of your site using the .htaccess file, for example if you had a directory called olddirectory on your site and you had set up the same files on a new site at: http://www.newsite.com/newdirectory/ you could redirect all the files in that directory without having to specify each one:
你也可以使用.htaccess重定向整个网站的目录。假如你的网站上有一个名为olddirectory的目录,并且你已经在一个新网站 http://www.newsite.com/newdirectory/上建立了与上相同的文档,你可以将旧目录下所有的文件做一次重定向而不必一一声明:

Redirect /olddirectory http://www.newsite.com/newdirectory
Then, any request to your site below /olddirectory will bee redirected to the new site, with the
extra information in the URL added on, for example if someone typed in:
这样,任何指向到站点中/olddirectory目录的请求都将被重新指向新的站点,包括附加的额外URL信息。例如有人键入:

http://www.youroldsite.com/olddirecotry/oldfiles/images/image.gif
They would be redirected to:
请求将被重定向到:

http://www.newsite.com/newdirectory/oldfiles/images/image.gif
This can prove to be extremely powerful if used correctly.
如果正确使用,此功能将极其强大。

Part 3 – 密码保护

Introduction 介绍

Although there are many uses of the .htaccess file, by far the most popular, and probably most useful, is being able to relaibly password protect directories on websites. Although JavaScript etc. can also be used to do this, only .htaccess has total security (as someone must know the password to get into the directory, there are no 'back doors')
尽管有各种各样的.htaccess用法,但至今最流行的也可能是最有用的做法是将其用于网站目录可靠的密码保护。尽管JavaScrip等也能做到,但只有.htaccess具有完美的安全性(即访问者必须知晓密码才可以访问目录,并且绝无“后门”可走)。

The .htaccess File 密码保护的.htaccess文件

Adding password protection to a directory using .htaccess takes two stages. The first part is to add the appropriate lines to your .htaccess file in the directory you would like to protect. Everything below this directory will be password protected:
利用.htaccess将一个目录加上密码保护分两个步骤。第一步是在你的.htaccess文档里加上适当的几行代码,再将.htaccess文档放进你要保护的目录下:

AuthName "Section Name"
AuthType Basic
AuthUserFile /full/path/to/.htpasswd
Require valid-user
There are a few parts of this which you will need to change for your site. You should replace "Section Name" with the name of the part of the site you are protecting e.g. "Members Area".
你可能需要根据你的网站情况修改一下上述内容中的一些部分,如用被保护部分的名字"Members Area",替换掉“Section Name”。

The /full/parth/to/.htpasswd should be changed to reflect the full server path to the .htpasswd file (more on this later). If you do not know what the full path to your webspace is, contact your system administrator for details.
/full/parth/to/.htpasswd则应该替换为指向.htpasswd文件(后面详述该文档)的完整服务器路径。如果你不知道你网站空间的完整路径,请询问一下你的系统管理员。

The .htpasswd File 密码保护的.htpasswd文件

Password protecting a directory takes a little more work than any of the other .htaccess functions because you must also create a file to contain the usernames and passwords which are allowed to access the site. These should be placed in a file which (by default) should be called .htpasswd. Like the .htaccess file, this is a file with no name and an 8 letter extension. This can be placed anywhere within you website (as the passwords are encrypted) but it is advisable to store it outside the web root so that it is impossible to access it from the web.
目录的密码保护比.htaccess的其他功能要麻烦些,因为你必须同时创建一个包含用户名和密码的文档,用于访问你的网站,相关信息(默认)位于一个名为.htpasswd的文档里。像.htaccess一样,.htpasswd也是一个没有文件名且具有8位扩展名的文档,可以放置在你网站里的任何地方(此时密码应加密),但建议你将其保存在网站Web根目录外,这样通过网络就无法访问到它了。

Entering Usernames And Passwords 输入用户名和密码

Once you have created your .htpasswd file (you can do this in a standard text editor) you must enter the usernames and passwords to access the site. They should be entered as follows:
创建好.htpasswd文档后(可以通过文字编辑器创建),下一步是输入用于访问网站的用户名和密码,应为:

username:password
where the password is the encrypted format of the password. To encrypt the password you will either need to use one of the premade scripts available on the web or write your own. There is a good username/password service at the KxS site which will allow you to enter the user name and password and will output it in the correct format.
“password”的位置应该是加密过的密码。你可以通过几种方法来得到加密过的密码:一是使用一个网上提供的permade脚本或自己写一个;另一个很不错的username/password加密服务是通过KxS网站,这里允许你输入用户名及密码,然后生成正确格式的密码。

For multiple users, just add extra lines to your .htpasswd file in the same format as the first. There are even scripts available for free which will manage the .htpasswd file and will allow automatic adding/removing of users etc.
对于多用户,你只需要在.htpasswd文档中新增同样格式的一行即可。另外还有一些免费的脚本程序可以方便地管理.htpasswd文档,可以自动新增/移除用户等。

Accessing The Site 访问网站

When you try to access a site which has been protected by .htaccess your browser will pop up a standard username/password dialog box. If you don't like this, there are certain scripts available which allow you to embed a username/password box in a website to do the authentication. You can also send the username and password (unencrypted) in the URL as follows:
当你试图访问被.htaccess密码保护的目录时,你的浏览器会弹出标准的username/password对话窗口。如果你不喜欢这种方式,有些脚本程序可以允许你在页面内嵌入username/password输入框来进行认证,你也可以在浏览器的URL框内以以下方式输入用户名和密码(未加密的):

http://username:password@www.website.com/directory/
Summary 小结

.htaccess is one of the most useful files a webmaster can use. There are a wide variety of different uses for it which can save time and increase security on your website.
.htaccess是一个站点管理员可以应用的强大工具,有更多的变化以适应不同的用途,可以节约时间及提高网站的安全性。

相关阅读:


KxS Password Encrypter
Apache .htaccess Documentation
More .htaccess Sites
Related Reading

.htaccess的特别说明


启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用
如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:

AccessFileName .config
一般情况下,不应该使用.htaccess文件,除非你对主配置文件没有访问权限。有一种很常见的误解,认为用户认证只能通过.htaccess文件实现,其实并不是这样,把用户认证写在主配置文件中是完全可行的,而且是一种很好的方法。.htaccess文件应该被用在内容提供者需要针对特定目录改变服务器的配置而又没有root权限的情况下。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是ISP在同一个机器上运行了多个用户站点,而又希望用户可以自己改变配置的情况下。虽然如此,一般都应该尽可能地避免使用.htaccess文件。任何希望放在.htaccess文件中的配置,都可以放在主配置文件段中,而且更高效。避免使用.htaccess文件有两个主要原因,即性能和安全。


类别:php+mysql+apache+zend | 添加到搜藏 | 浏览(40) 网友评论: 发表评论:姓 名: 注册 | 登录 *姓名最长为50字节

网址或邮箱: (选填)

内 容:

验证码: 请输入下图中的四位验证码,字母不区分大小写。
看不清?




©2007 Baidu
NEAT 开 发 指南 文档 适用于 PT80 系列 移动数据终端 版本记录 版本号 版本描述 发布日期 V 1.0 初始版本。 2012-04-12 V1.1 修改前三章内容 2012-09-25 目录 第一章 关于本手册........................................................................................................................................ 1 简介 ........................................................................................................................................................ 1 相关文档 ................................................................................................................................................. 1 章节介绍 ................................................................................................................................................. 1 版权和许可条款 ...................................................................................................................................... 1 第二章 PT80 开发入门 .................................................................................................................................. 2 开发环境搭建 ......................................................................................................................................... 2 使用 NEAT 工程向导建立应用程序 ........................................................................................................ 5 编译及运行程序(模拟器下) ................................................................................................................ 7 编译及运行程序(PT80) .................................................................................................................... 11 下载 PT80 应用程序 ............................................................................................................................. 12 第三章 PT80 NEAT 编程基础 ..................................................................................................................... 17 事件驱动和消息响应机制 ..................................................................................................................... 17 建立一个应用程序 ................................................................................................................................ 17 应用程序的关闭 .................................................................................................................................... 19 框架窗口 ............................................................................................................................................... 19 完整的例子 ........................................................................................................................................... 20 NEAT 程序一般执行过程 ..................................................................................................................... 20 第四章 窗口 ................................................................................................................................................ 21 窗口的概念 ........................................................................................................................................... 21 窗口的创建和删除 ................................................................................................................................ 22 窗口类型 ............................................................................................................................................... 23 窗口事件 ............................................................................................................................................... 24 窗口类概览 ........................................................................................................................................... 24 基础窗口类 ........................................................................................................................................... 26 窗口类 CNeatWnd ................................................................................................................................ 26 窗口类 CNeatView 视图类 ................................................................................................................... 26 CNeatControl 类 ................................................................................................................................... 26 CNeatFrame 类 .................................................................................................................................... 26 第五章 消息与消息处理 .............................................................................................................................. 27 消息驱动的编程模型 ............................................................................................................................ 27 消息及消息处理过程 ............................................................................................................................ 27 第六章 在窗口中绘画 .................................................................................................................................. 30 设备上下文 ........................................................................................................................................... 30 绘画工具 ............................................................................................................................................... 32 绘制基本图形 ....................................................................................................................................... 34 绘制文本 ............................................................................................................................................... 34 第七章 处理用户输入 .................................................................................................................................. 36 PT80 的按键所对应的键值 .................................................................................................................. 36 输入事件相应 ....................................................................................................................................... 36 第八章 对话框编程基础 .............................................................................................................................. 37 模态和非模态对话框编程 ..................................................................................................................... 37 通用对话框 ........................................................................................................................................... 38 对话框示例 ........................................................................................................................................... 38 对话框资源 ........................................................................................................................................... 40 第九章 NEAT 控件 ...................................................................................................................................... 41 控件综述 ............................................................................................................................................... 41 静态框 .................................................................................................................................................. 41 编程示例 ............................................................................................................................................... 42 按钮 ...................................................................................................................................................... 43 列表框 .................................................................................................................................................. 45 组合框 .................................................................................................................................................. 46 编辑框 .................................................................................................................................................. 48 进度条 .................................................................................................................................................. 50 滑块 ...................................................................................................................................................... 51 旋钮 ...................................................................................................................................................... 52 第十章 资源及资源模板 .............................................................................................................................. 53 概述 ...................................................................................................................................................... 53 图标 ...................................................................................................................................................... 53 对话框 .................................................................................................................................................. 54 菜单 ...................................................................................................................................................... 54 第十一章 编写国际化程序 ........................................................................................................................... 57 国际化简介 ........................................................................................................................................... 57 如何实现国际化 .................................................................................................................................... 57 使用 NEAT 平台开发国际化应用程序 .................................................................................................. 59 小结 ...................................................................................................................................................... 61 第十二章 编写多线程程序 ........................................................................................................................... 62 多线程简介 ........................................................................................................................................... 62 如何使用 wxThread 线程类 .................................................................................................................. 62 线程同步对 ....................................................................................................................................... 64 编程实例 ............................................................................................................................................... 69 小结 ...................................................................................................................................................... 69 第十三章 网络编程...................................................................................................................................... 70 使用 wxSocket 编程 ............................................................................................................................. 70 Socket 类和功能概览 ........................................................................................................................... 70 Socket 及其基本处理介绍 .................................................................................................................... 70 Socket 标记 .......................................................................................................................................... 75 使用 Socket 流 ..................................................................................................................................... 78 第十四章 数据库编程 .................................................................................................................................. 81 wxSqlite3 简介 ..................................................................................................................................... 81 如何使用 wxSqlite3 .............................................................................................................................. 81 编程实例 ............................................................................................................................................... 92 小结 ...................................................................................................................................................... 92 第十五章 设备编程...................................................................................................................................... 93 PT80 设备操作类 ................................................................................................................................. 93 PT88WIFI 操作类 ................................................................................................................................. 93 PT88BT 操作类 .................................................................................................................................... 93 PT88 配置信息操作类 .......................................................................................................................... 93 第十六章 wxBase 编程接口 ........................................................................................................................ 94 概述 ...................................................................................................................................................... 94 时间日期 ............................................................................................................................................... 94 动态库 .................................................................................................................................................. 94 字符串 .................................................................................................................................................. 94 文件文件夹、流 ................................................................................................................................ 95 附录 1 系统调用 .......................................................................................................................................... 97 1 第一章 关于本手册 简介 NEAT 是 Newland Embedded Application Toolkit 的缩写,由福建新大陆电脑股份有限公司开发,其目标是为开发者提供一套可 靠、高效、易用的跨平台应用开发支撑系统。PT80 使用 NEAT 这个软件做为 PT80 应用程序的开发工具,开发人员通过 NEAT 可 以快速开发出在 PT80 上运行的应用程序。 本手册详细讲述了利用 NEAT 的基础知识、技术资料和开发技巧,以及 NEAT 当前。 相关文档 章节介绍 版权和许可条款 2 第二章 PT80 开发 入门 开发环境搭建 运行环境 NEAT 做为 Microsoft 开发工具 Visual Studio 2005 的插件存在, 开发人员首先要安装 Microsoft Visual Studio 2005, 当前版本 NEAT 只 v0.2.0 只支持 Visual Studio 2005。开发人员需要使用 Visual Studio 中的 Visual C++ 进行 NEAT 应用程序的开发。 NEAT 简介 NEAT 系统大概包含以下几部分内容:  各种库及头文件  交叉编译工具及各种辅助工具  Windows 端的模拟器  帮助文档及示例代码 NEAT 安装步骤 运行安装包,弹出如下界面: 3 \image html chapter2_setup1.jpg 点击―下一步‖,进入安装准备状态: \image html chapter2_setup2.jpg 点击安装,即进入安装过程,安装程序将在 D:\NEAT(默认安装路径,可修改)下安装所有内容。 \image html chapter2_setup3.jpg 安装完成后,有以下界面: 4 \image html chapter2_setup4.jpg 点击完成即可。安装程序将生成 NEAT 开发向导,NEAT 开发手册,NEAT 模拟器的快捷方式。 5 使用 NEAT 工程向导建立应用程序 使用 NEAT ―工程向导‖(NeatProjectWiz)来快速建立 NEAT 应用程序。启动方法:点击“开始”、“程序”;选择“Neat 嵌 入式应用开发套件”中的“工程向导”(如下图)。 NEAT 工程向导使用步骤: 1. 设置开发环境,目前只支持 VS2005 2. 设置平台,目前只支持 PT80 3. 设置程序类型,分为两大类:  应用程序:即当前 PT80 系统菜单里头的应用程序,应用程序是做为系统菜单的插件而运行。  系统程序:类似 PT80 的整体程序(当前 NEAT 版本不支持,保留功能,新建工程时请勿选择此模式)。 注:每类又包含两种模式,及对话框模式和非对话框模式。  非对话框模式:开发人员需要用代码确定图形控件的放置位置和大小。 6  对话框模式:开发人员可以将图形控件从 Visual Studio 中‖Control Toolbar‖中拖放到 PT80 可视化对话框界面,不 需要使用代码确定图形界面的放置位置和大小,推荐开发人员新建应用程序时使用此模式。 \image html chapter2_projWiz1.jpg 4. 填写工程名称及工程所在的路径。 \image html chapter2_projWiz2.jpg 7 5. 点击确定,NEAT 工程向导会开始创建 VC 工程。 6. 工程创建后会提示是否要打开新建工程,点击确定打开(如下图) 注意:1. 如果点击‘ 是’ 后打不开工程 , 请设置在 在 Windows 操作系统中设置 VS2005 的环境变量 ,即将 VS2005 的启动路径添 加到系统的”Path” 环境变量中 。 2. 如果在工程目录下已经存在工程名和新生成的工程名相同的工程时,会被新的工程覆盖。 编译及运行程序(模拟器下) 使用 NEAT “ 工程向导” (NeatProjectWiz )来快速建 编译和运行 应用程序 创建完成 PT80 应用程序工程后,可以参考下列编译和运行应用程序: Step1: 使用 VC 打开已建立好的 NEAT VC 工程。 Step2: 打开当前工程的配置管理器(如下图) 8 9 针对当前项目,―配置‖选择―WIN32‖,―平台‖选择―Win32‖。如果你想脱离主控系统程序,独立运行应用程序,请在―配置‖中 选择―WIN32-Alone‖。 \image html chapter2_appProjCfg.jpg “配置管理器的配置” 检查工程属性的―调试‖项,在―命令‖栏中填写―d:\neat\pt880system.exe‖(默认安装路径)。 \image html chapter2_appProjDebugCfg.jpg “调试的配置” 编译并运行程序。PT80 模拟器将自动被打开,脱离主控系统程序运行的应用程序,接下来请直接看 Step4。 Step4: (1)在模拟器上,选择―系统菜单‖的―系统设置‖项,进入―系统设置‖界面,选择"1.设定程序"项; 10 选择"系统设置"项进入 选择"设定程序"项进入 (2)进入"设定程序"项后,在插件栏按"OK"键显示可选插件后,选择要运行的程序。然后在"开机运行"项设置为"是"; 选择好需要运行的程序后 将"开机自动运行"设为"是" (3)选择设定后会自动回到"系统设置"界面。按"ESC"退出到"系统菜单"界面后选择"1 运行程序"项即可; 选择"运行程序"项后即运行已设定的程序 (4)下一次编辑运行时即自动进入程序。 11 应用程序成功启动。你可以点击模拟器上的按钮进行操作,你也可以在程序中添加断点等工具,进行调试。 \image html chapter2_appProjDebuging.jpg “调试应用程序” 编译程序(PT80 ) 在模拟器上编译运行PT80应用程序正常后, 需要使用NEAT编译工具编译在PT80应用程序。 点击NEAT工具栏上的―Compile‖ 按钮,如果没找到 NEAT 工具栏,请右键当前工具栏空白区域,选择―NEAT‖。成功编译后,可以看到―输出‖窗口中关于.so 文件或 可执行文件的信息。 \image html chapter2_NEATtoolbar.jpg “NEAT 工具栏” 12 \image html chapter2_NEAToutput.jpg “成功编译后输出窗口的内容” 下载 PT80 应用程序 在编译完成 PT80 应用程序后,有两种方法将编译完成的 PT80 应用程序下载到 PT80 上:“USB 模式下载”和“NEAT 插件 下载”。 USB 模式下载应用程序 Step1: 在 PT80 上将 USB 数据通讯方式设置为“U 盘”(具体设置方式可参考《PT80 用户手册》)。 Step2: 将 PT80 和 PC 用 USB 线缆连接 Step3: 将编译完成的 *.so 文件复制到 U 盘下的“app”目录中(如下图): 13 Step4: 在 PT80 的系统菜单里选择刚下载的应用程序运行(运行以下载应用程序的方法可参考《PT80 用户手册》)。 使用 NEAT 插件工具下载应用程序 Step1: 在 PT80 上将 USB 数据通讯方式设置为“串口下载模式”(具体设置方式可参考《PT80 用户手册》)。 Step2: 将 PT80 和 PC 用 USB 线缆连接 Step3: 在 PC 端安装“USB 转串口”驱动(PT80 USB 转串口驱动请访问新大陆自动识别网站 www.nlscan.com 上下载) Step4: 驱动安装完成后,在 PC 上会新增一个虚拟串口,在 PC 上的“设备管理器”中可以查看虚拟串口号(如下图),记录 下这虚拟串口号。 14 Step5: 点击“下载”按键(如下图) 在下载对话框中(入下图)按照以下步骤下载 PT80 应用程序到 PT80  选择正确的虚拟串口  选择需要下载 PT80 应用程序,应用程序在 VC 工程目录下的“NEAT_OBJ”目录,应用程序是以“.so”为后缀名 的文件  点击“下载”按键 15 下载成功后,在下载对话框上会提示下载成功(如下图): 16 Step6: 至此下载 PT80 应用程序完成, 可以在 PT80 上开始运行应用程序 (具体运行应用程序的方法可参考 《PT80 用户手册》 ) 。 17 第三章 PT80 NEAT 编程基础 事件驱动和消息响应机制 NEAT 程序设计是一种事件驱动的程序设计模式,在程序提供给用户的界面中有许多可操作的可视对。用户可以从所有可 能的操作中任意选择,被选择的操作会产生某些特定的事件,这些事件发生后的结果是向程序中的某些对发出消息,然后这些对 调用相应的消息处理函数来完成特定的操作。NEAT 应用程序最大的特点就是程序没有固定的流程,而只是针对某个事件处理有 特定的子流程,NEAT 应用程序是由许多这样的子流程构成的。 NEAT 应用程序是面向对的。程序提供给用户界面的可视对在程序的内部一般也被看成一个,用户对可视对的操 作通过事件驱动模型触发相应的消息处理函数。 程序的运行过程就是用户的外部操作不断产生事件, 这些事件又不断被处理的过程。 NEAT 这种事件驱动模型源于消息响应机制。在 NEAT 系统中,事件产生消息,消息对应事件,所谓事件响应,其实就是对 各种消息的响应。NEAT 系统会不断的捕捉各种消息,并把捕捉到的消息发送到应用程序,应用程序将消息再传递给相关的消息处 理函数做相应的处理。这种等待消息、响应消息的操作方式就是 NEAT 的消息处理机制,类似于 Windows 的消息处理机制。 下面是 NEAT 应用程序的工作原理示意图。 \image html neat-message.jpg "NEAT 消息处理机制" 建立 一个应用程序 每一个 NEAT 程序都需要定义一个 \ref CNeatApp 类的派生类,并需要且只能构造一个这个类的实例,这个实例控制着整个 程序的执行。你的这个继承自 \ref CNeatApp 的子类至少需要定义一个 OnInit 函数,当 NEAT 准备好运行你写的代码的时候,它 将会调用这个函数(和一个典型的 Win32 程序中的 main 函数或者 WinMain 函数类似)。 你定义这个子类的代码可能和下面的代码类似: \code class MyApp : public CNeatApp { public: virtual bool OnInit(int args, const char* arg[]); 18 virtual int OnExit(); }; \endcode 在这个 OnInit 函数中,你通常应该创建至少一个窗口,对传入的命令行参数进行解析,为应用程序进行数据设置和其它的一 些初始化的操作。然后 NEAT 将开始消息循环,用来处理用户输入并且在必要的情况下处理这些输入。如果 OnInit 函数返回假, NEAT 将会释放它内部已经分配的资源,然后结束整个程序的运行。 接下来我们看一个最简单的 OnInit 函数的实现: \code CMyFrame m_FrameWnd; // 应用程序初始化函数 bool CMyApp::OnInit(int args, const char* arg[]) { \code CMyFrame m_FrameWnd; // Initialization function of the application program bool CMyApp::OnInit(int args, const char* arg[]) { // 调用 Create 函数来创建主框架窗口 m_FrameWnd.Create(_("Minimal"), WS_THINFRAME|WS_CAPTION ); // Call the Create function to create the frame window m_FrameWnd.Create(_("Minimal"), WS_THINFRAME|WS_CAPTION ); // 显示主窗口 m_FrameWnd.ShowWindow(SW_SHOW); return true; } // Show the window m_FrameWnd.ShowWindow(SW_SHOW); return true; } \endcode \endcode 你可能还会注意到上面例子中的_()这个宏,在接下来的例子中,这个宏还会被频繁用到。它的作用是用来告诉 NEAT 将其 中的字符串翻译成其它语言的版本,参见―编写国际化程序‖。 那么创建 MyApp 实例的代码在哪里呢?实际上, 这是在 NEAT 内部实现的, 不过你仍然需要告诉 NEAT 需要创建哪一个 App 类的实例,所以你还需要增加下面的一个宏: \code IMPLEMENT_APP(MyApp) \endcode 如果没有实现这个类,NEAT 就不知道怎样创建一个新的应用程序对。这个宏除了上述的功能以外,还会检查编译应用程 序使用的库文件是否和当前的库文件的版本相匹配,如果没有这种检查,由此而产生的一些运行期的错误可能很难被查出原因。 19 应用程序的关闭 当框架窗口关闭后,应用程序也跟着关闭了,在应用程序关闭前,它会调用 \ref CNeatApp::OnExit 函数,可以在这里增加 应用程序退出前的操作。 举个例子: \code class MyApp : public CNeatApp { public: CNeatWnd *m_helpCtrl; ... }; bool MyApp::OnInit(int argc,const char* argv[]) { ... m_helpCtrl = new CNeatWnd; ... return true; } int MyApp::OnExit() { delete m_helpCtrl; return 0; } \endcode 框架窗口 我们来看一看自定义的派生至 CNeatFrameWnd 窗口类的 MyFrame。一个 \ref CNeatFrameWnd 窗口是一个可以容纳别的 窗口的顶级窗口,通常拥有一个标题栏和一个状态栏和一个客户视图。下面是我们的例子中这个类的定义,可以将其放在 MyApp 的定义之前: \code // 从 CNeatFrameWnd 派生一个框架窗口类,做为该应用程序的框架窗口 class CMyFrame : public CNeatFrameWnd { public: // 窗口刷新事件的处理函数 virtual int OnPaint(); }; \endcode \code // Derive a frame window class from CNeatFrameWnd and use it as the frame window for the application program class CMyFrame : public CNeatFrameWnd { 20 public: // handler function for the window refreshing events virtual int OnPaint(); }; \endcode 这个窗口类的中只定义了一个用来把窗口刷新事件的处理函数。 完整的例子 现在把所有的代码放在一起了,通常,我们应该把头文件和实现文件分开,但是对于这样小的一个程序,就没有这个必要了。 \include minimal\minimal.cpp \image html demo-minimal.jpg "NEAT 最小应用程序" NEAT 程序一般执行过程 下面大概描述一下整个程序的执行过程: 1. 程序执行时,main 函数被调用,NEAT 初始化它自己的数据结构并且创建一个 MyApp 的实例。 2. NEAT 调用 MyApp::OnInit 函数, 这个函数会创建一个 MyFrame 的实例,MyFrame 通过调用 Create 来创建一个窗口, MyApp::OnInit 函数显示主窗口并且返回真。 3. NEAT 开始进入消息循环,等待事件发生并且将事件分发给相应的处理过程。 4. 应用程序会在以下情况下退出:主窗口被关闭,用户选择退出菜单或者系统按钮和系统菜单中的关闭选项(这些系统菜 单和系统按钮在不同的系统中就往往千差万别了)。 21 第四章 窗口 你当然大略的知道一个窗口指的是什么,但是为了更好的理解 NEAT 窗口相关的 API,你应该更精通 NEAT 所使用的窗口模 型的细节。它可能和你在某个特定平台上的窗口概念有些许的不同。下图演示了一个窗口中的各个基本元素: \image html neat-window.jpg "NEAT 窗口" 窗口的概念 一个窗口指的是屏幕上的任何一个拥有以下特征的规则区域:它可以被改变大小,可以自我刷新,可以被显示和隐藏等等。 它可以包含别的窗口(比如 frame 窗口就可以包含菜单条窗口,工具条窗口以及状态条窗口),也可以子窗口(比如一个静态的文本或 者一副静态图片)。通常你在使用 NEAT 编写的程序运行的屏幕上看到的窗口,都和一个 \ref CNeatWnd 类或者它的派生类对应。 客户区和非客户区 当我们谈到窗口的大小,我们通常指的是它整个的大小,包括一些用于修饰的边框和标题栏等。而当我们谈到一个窗口的客 22 户区大小,通常都只意味着窗口里面那些能被绘制或者它的子窗口能被放置的位置的大小。例如一个 frame 窗口的客户区大小就不 包括那些菜单栏,状态栏和工具栏所占用的地方。 滚动条 大多数窗口都有显示滚动条的能力,这些滚动条通常是窗口自己增加的而不是由应用程序手动增加的。在这种情况下,客户 区的大小还应该减去滚动条所占用的空间。 为了优化性能, 只有那些拥有 WS_HSCROLL 和 WS_VSCROLL 类型的窗口才会自动生 成它们自己的滚动条。 座标体系 窗口的座标体系通常是左上角为原点(0,0),单位是素。 窗口绘制 当一个窗口需要重绘的时候,它将收到两个事件,MSG_ERASEBKGND 事件用于通知应用程序重新绘制背景,对应的消息处 理函数为OnEraseBkgnd, MSG_PAINT则用于通知重新绘制前景, 对应的消息处理函数为OnPaint。 那些常用控件比如CNeatButton(按 钮)已经处理这两个事件,但是如果你是要创建自己的窗口控件,你就需要自己处理这两个事件。通过获取窗口的变动区域你可以 优化你的绘制代码。 颜色和字体 每一个窗口都有一个前景色和一个背景色。默认的背景擦除函数会使用背景色来清除窗口背景,如果没有设置背景色,则会 使用系统默认的背景颜色进行背景的清除。前景色为文本输出的字体颜色。每一个窗口也拥有一个字体设置,是否用到这个字体设 置要取决于这个窗口本身的类型。 改变大小 当一个窗口的大小,无论是来自用户还是应用程序本身的原因,发生变化时,它将收到一个 MSG_SIZE 事件,对应的消息处理 函数为 OnSize。 输入 只有当前处于活动状态的窗口才可以接收键盘事件。应用程序自己可以设置自己为活动状态,NEAT 也会在用户点击某个窗 口的时候将其设置为活动状态。正变成活动状态的窗口会收到 MSG_SETFOCUS 事件,对应的消息处理函数为 OnSetFocus,而正 失去焦点的窗口会收到 MSG_KILLFOCUS 事件,对应的消息处理函数为 OnKillFocus。 窗口的创建和删除 大多数的窗口类都可以需要两步来创建,首先定义一个窗口类对,然后调用 Create 函数来创建窗口。下面演示一个创建窗 口的代码片段: \code CNeatWnd *mywnd = new CNeatWnd; 23 mywnd->Create( ―mywindow‖, WS_CHILD, 10, 10, 100, 100,parent); \endcode 你可以传递一个字符串的名字,一个类型 (接下来会提到),位置和大小参数给这个窗口。除非是 frame 或者 dialog 窗口,对 于别的窗口, 都必须在 Create 函数中传入一个非空的父窗口, 这会把这个新窗口作为这个父窗口的子窗口, 当父窗口被释放的时候, 它的所有的子窗口也将被释放。 窗口在你调用 Create 函数的时候会收到 MSG_CREATE 事件,对应的消息函数为 OnCreate,你可以对这个事件进行进一步的 处理。 当你创建一个窗口类,或者其它任何非顶层窗口的派生类的时候,如果它的父窗口是可见的,那么它也总是可见的,你可以 通过 ShowWindow(SW_HIDE)来使它不可见或使用 ShowWindow(SW_SHOW)来使它可见。 你可以通过向窗口发送 MSG_CLOSE 消息(对应的消息处理函数为 OnClose)来关闭窗口。通过调用 DestroyWindow 函数来释 放窗口的资源,MSG_DESTROY 事件(对应的消息函数为 OnDestroy)会在窗口刚刚要被释放之前被调用。 窗口拥有一个类型和一个扩展类型。窗口类型是设置窗口创建时的行为和外观的一种简洁的方法。这些类型的值被设置成可 以使用类似比特位的方法操作,例如下面的例子: WS_CAPTION | WS_THICKFRAME|WS_VISIBLE CNeatWnd 类有一组基本的类型值,例如边框的类型等,每一个派生类可以增加它们自己的类型。需要特别指出的是,扩展类 型的值是不可以拿来给类型用的。 窗口类型 每一个窗口类都可以使用定义在下表中的这些的窗口类型。这些类型中不是所有的类些都被所有的控件所支持。需要注意的 是以 WS_开头的类型用于 dwStyle 的设置,以 WS_EX_开头的类型用于 dwExStyle 的设置,两个不能互用。 通用窗口类型: 风格标识 含义 备注 WS_VISIBLE 创建初始可见的窗口 WS_DISABLED 创建初始被禁止的窗口 WS_CAPTION 创建含标题栏的主窗口 仅用于主窗口 WS_SYSMENU 创建含系统菜单的主窗口 仅用于主窗口 WS_BORDER 在窗口周围显示一个边框 WS_THICKFRAME 创建具有厚边框的窗口 WS_THINFRAME 创建具有薄边框的窗口 WS_VSCROLL 创建带垂直滚动条的窗口 WS_HSCROLL 创建带水平滚动条的窗口 24 WS_MINIMIZEBOX 标题栏上带最小化按钮 仅用于主窗口 WS_MAXIMIZEBOX 标题栏上带最大化按钮 仅用于主窗口 WS_EX_TRANSPARENT 透明窗口风格 仅用于部分控件,如编辑框和滚动 窗口控件等 WS_EX_NOCLOSEBOX 主窗口标题栏上不带关闭按钮 窗口事件 窗口类和它的派生类可以产生下面的事件,在窗口里有对应的事件处理函数,所有的事件处理函数的返回类型为 int,如果返 回值为 0 表示该事件处理函数返回后,继续执行 NEAT 对该事件的默认处理,如果返回值为非 0,表示不再执行系统的默认处理。 通用窗口事件及消息处理函数: 窗口事件 消息处理函数 备注 MSG_CREATE \ref CNeatWnd::OnCreate 窗口创建事件 MSG_CLOSE \ref CNeatWnd::OnClose 窗口关闭事件 MSG_DESTROY \ref CNeatWnd::OnDestroy 窗口销毁事件 MSG_ERASEBKGND \ref CNeatWnd::OnEraseBkgnd 窗口背景擦除事件 MSG_PAINT \ref CNeatWnd::OnPaint 窗口客户区刷新 MSG_KEYDOWN \ref CNeatWnd::OnKeyDown 按键按下事件 MSG_KEYUP \ref CNeatWnd::OnKeyUp 按键释放事件 MSG_CHAR \ref CNeatWnd::OnChar 字符事件 MSG_TIMER \ref CNeatWnd::OnTimer 定时器事件 MSG_COMMAND \ref CNeatWnd::OnCommand 命令事件 MSG_SETFOCUS \ref CNeatWnd::OnSetFocus 窗口获得焦点事件 MSG_KILLFOCUS \ref CNeatWnd::OnKillFocus 窗口失去焦点事件 MSG_SIZE \ref CNeatWnd::OnSize 窗口大小调整事件 MSG_SHOWWINDOW \ref CNeatWnd::OnShowWindow 窗口显示(不显示)事件 MSG_HSCROLL \ref CNeatWnd::OnHScroll 水平滚动事件 MSG_VSCROLL \ref CNeatWnd::OnVScroll 垂直滚动事件 MSG_ENABLE \ref CNeatWnd::OnEnable 窗口允许事件 MSG_IDLE \ref CNeatWnd::OnIdle 窗口进入 IDEL 事件 窗口类概览 在接下来的章节中,我们会介绍最常用的那些窗口类以便你可以在你的应用程序中使用它们。 25 基本窗口类 下面的这些基本的窗口类实现了一些最基本的功能,这些类主要是用来作为别的类型的基类以生成更实用的派生类。 窗口类 描述 \ref CNeatWnd 这是所有窗口类的基类。 \ref CNeatControl 所有控件(比如 CNeatButton)的基类。 顶层窗口类 顶层窗口类通常指那些独立的位于桌面上的类。 窗口类 描述 \ref CNeatFrame 一个可以包含其他窗口,并且大小可变的窗口类。 \ref CNeatDialog 是一种可变大小的用于给用户提供选项的对话框窗口类。 视图类 窗口类 描述 \ref CNeatView 这是所有视图类的基类。 \ref CNeatMenuView 一个实现菜单选择功能的视图,支持文本和图标模式。 \ref CNeatTreeView 一个实现树型功能的视图。 \ref CNeatListView 一个实现列表功能的视图。 控件窗口类 这些控件是用户可以操作或者编辑的。 窗口类 描述 \ref CNeatStatic 静态框 \ref CNeatButton 按钮 \ref CNeatEdit 编辑框 \ref CNeatProgressCtrl 进度条 \ref CNeatListBox 列表框 \ref CNeatComboBox 组合框 \ref CNeatScrollBar 滚动条 \ref CNeatMonthCalendar 日历 \ref CNeatSliderCtrl 滑块 \ref CNeatSpinButtonCtrl 旋钮 26 基础窗口类 虽然你不一定有机会直接使用基础窗口类(CNeatWnd),但是由于这个类是很多窗口控件的基类,它实现的很多方法在它的子 类型中都可以直接拿来使用,所以有必要介绍一下这个基础窗口类。 窗口类 CNeatWnd \ref CNeatWnd 窗口类既是一个重要的基类, 也是一个你可以直接在代码中使用的类。 当然, 前者使用的频度要比后者大很多。 CNeatWnd 类的成员函数。 因为 CNeatWnd 类是其它所有窗口类的基类,它拥有很多的成员函数。我们不在这里作一一的说明,只能拣其中最重要的一 些作简要的说明。具体的内容参见\ref CNeatWnd 的接口说明,以便能够彻底了解 CNeatWnd 类提供的所有功能,以及要使用这个 功能你需要提供的参数等。 TODO:增加部分成员函数的使用介绍。 窗口类 CNeatView 视图类 CNeatControl 类 \ref CNeatControl 继承自\ref CNeatWnd 类, 用来作为控件的基类,所谓控件指的是那些可以显示数据项并且通常需要响应鼠 标或者键盘事件的那些窗口类。 CNeatFrame 类 顶层窗口直接被放置在桌面上而不是包含在其它窗口之内。如果应用程序允许,他们可以被移动或者重新改变大小。有两种 基础的顶层窗口类型。 CNeatFrameWnd 和 CNeatDialog 都是从 CNeatWnd 继承来的。一个对话框既可以是模态的也可以是非模态 的,而 frame 通常都是非模态的。模态对话框的意思是说当这个对话框弹出时,应用程序除了等待用户关闭这个对话框以外不再作 别的事情。对于那些要等待用户响应以后才能继续的操作来说,这是比较合适的。 顶层窗口通常都拥有一个标题栏,这个标题栏上有一些按钮或者菜单或者别的修饰用来关闭,或者最小化,或者恢复这个窗 口。而 frame 窗口则通常还会拥有菜单条,工具条和状态条。但是通常对话框则没有这些。 27 第五章 消息与消息处理 消息驱动的编程模型 所有的 GUI 程序都是事件驱动的。换句话说,应用程序一直停留在一个循环中,等待着来自用户或者其他地方(比如窗口刷 新或网络连接)的事件,一旦收到某种事件,应用程序就将其扔给处理这个事件的函数。虽然看上去不同的窗口是同时被刷新的, 但实际上,绝大多数的 GUI 程序都是单线程的,因此窗口的刷新是依次按顺序进行的。如果由于某种意外你的设备变得很慢导致 窗口刷新的过程变的很明显,你就会注意到这一点。 不同的 GUI 编程架构用不同的方法将它内部的事件处理机制展现给程序开发者。对于 NEAT 来说,消息函数重载是最主要的 方法。在下一小节我们会对此进行进一步的解释。 NEAT 应用程序通过接收消息来和外界交互。消息由系统或应用程序产生,系统对输入事件产生消息,系统对应用程序的响 应也会产生消息,应用程序可以通过产生消息来完成某个任务,或者与其它应用程序的窗口进行通讯。总而言之,NEAT 是消息驱 动的系统,一切运作都围绕着消息进行。 系统把消息发送给应用程序窗口过程,窗口过程有四个参数:窗口句柄、消息标识以及两个 32 位的消息参数。窗口句柄决定 消息所发送的目标窗口,NEAT 可以用它来确定向哪一个窗口过程发送消息。消息标识是一个整数常量,由它来标明消息的类型。 如果窗口过程接收到一条消息,它就通过消息标识来确定消息的类型以及如何处理。消息的参数对消息的内容作进一步的说明,它 的意义通常取决于消息本身,可以是一个整数、位标志或数据结构指针等。对其他不同的消息类型来讲,wParam 和 lParam 也具有 明确的定义。应用程序一般都需要检查消息参数以确定如何处理消息。 消息及消息处理过程 NEAT 事件处理系统采用通常的虚方法机制来实现。每一个 CNeatWnd 的派生类,例如 frame,按钮,对话框等,都会在其内 部重载消息处理函数,用来告诉 NEAT 事件和事件处理过程的对应关系。 要重载一个消息处理函数,你需要下面两个步骤: 1. 在派生类里声明重载的消息函数,类型要和基类中定义的一样。 2. 实现该消息处理函数。 让我们来扩展一下前一章中的例子,来增加一个按键事件的处理。下面是扩展以后的 MyFrame 的定义: \code class CMyFrame : public CNeatFrameWnd { public: // 窗口刷新事件的处理函数 virtual int OnPaint(); // 按键事件的处理函数 virtual int OnKeyDown(UINT nKeyCode, UINT nRepCnt, UINT nFlags); 28 }; \endcode 增加处理的实现部分: \code // 按键按下事件的消息处理函数 int CMyFrame::OnKeyDown(UINT nKeyCode, UINT nRepCnt, UINT nFlags) { wxString str = _("OnKeyDown: "); // nKeyCode 按键的扫描码 switch (nKeyCode) { case KEY_0: str += "0"; break; case KEY_1: str += "1"; break; case KEY_2: str += "2"; break; case KEY_3: str += "3"; break; case KEY_4: str += "4"; break; case KEY_5: str += "5"; break; case KEY_6: str += "6"; break; case KEY_7: str += "7"; break; case KEY_8: str += "8"; break; case KEY_9: str += "9"; break; case KEY_UP: str += "UP"; break; case KEY_FUNC: str += "FN"; break; default: str += wxString::Format("0xX",nKeyCode); } CNeatPaintDC dc(this); str += " "; dc.TextOut(0,0,str); // 如果不要基类来处理一些默认的实现,可以在这里直接返回 // return 1; // 交给基类来完成一些默认处理 return CNeatFrameWnd::OnKeyDown(nKeyCode,nRepCnt,nFlags); } \endcode 消息循环 在每个主窗口及对话框后面都存在一个消息循环,消息循环就是一个循环体,在这个循环体中,程序利用 GetMessage 函数不 停地从消息队列中获得消息,然后利用 DispatchMessage 函数将消息发送到指定的窗口,也就是调用指定窗口的窗口过程,并传递 消息及其参数。典型的消息循环如下所示: \code MSG Msg; while ( GetMessage(&Msg, m_hWnd) ) { 29 TranslateMessage (&Msg); DispatchMessage (&Msg); } \endcode 如上所示,应用程序在创建了主窗口之后开始消息循环。 GetMessage 函数从\a m_hWnd 窗口所属的消息队列当中获得消息,然后调用 TranslateMessage 函数将击键消息 MSG_KEYDOWN 和 MSG_KEYUP 翻译成字符消息 MSG_CHAR ,最后调用 DispatchMessage 函数将消息发送到指定的窗口。 GetMessage 函数直到在消息队列中取到消息才返回,一般情况下返回非 0 值;如果取出的消息为 MSG_QUIT,GetMessage 函数 将返回 0,从而使消息循环结束。结束消息循环是关闭应用程序的第一步,应用程序一般在主窗口的窗口过程中通过调用 PostQuitMessage 来退出消息循环。 消息事件相应函数 NEAT 在 NEAT 消息处理机制之上进行了进一步的封装,它把消息循环封装在\ref CNeatApp 和\ref CNeatWnd 等基类里,从 应用程序的角度来看,它是看不到消息循环及消息派发的过程。NEAT 把每个消息的处理过程定义成消息事件响应函数,这些响应 函数大部分定义在\ref CNeatWnd 中,和控件通知消息相关的响应函数定义在\ref CNeatDialog 类里面。 30 第六章 在窗口中绘画 设备上下文 理解设备上下文 在 NEAT 中,所有的绘画相关的动作,都是由设备上下文完成的。每一个设备上下文都是\ref CNeatDC 的一个派生类。每次 在窗口上绘画,都要先创建一个窗口绘画设备上下文,然后在这个上下文上绘画。 可用的设备上下文 在 NEAT 中,所有的绘画相关的动作,都是由设备上下文完成的。每一个设备上下文都是\ref CNeatDC 的一个派生类。每次 在窗口上绘画,都要先创建一个窗口绘画设备上下文,然后在这个上下文上绘画。 下面列出了你可以使用的设备上下文: \ref CNeatDC 设备上下文的基类,其他各种设备上下文都是派生自这个类. \ref CNeatClientDC 用来在一个窗口的客户区绘画。 \ref CNeatPaintDC 仅用在重绘事件的处理函数中,用来在窗口的客户区绘画。 当使用\ref CNeatDC 中的输出函数在屏幕上画图时,输出的某些特性并没有在函数调用过程中规定,它是通过设备上下文的 属性获得。 例如, 在调用 CNeatDC::DrawText 时, 要指定待输出的字符串和显示该字符串的矩形区域, 但没有指定文本颜色和字体, 因为颜色和字体是设备上下文的属性。 下面列出了一些设备上下文中最常用的属性和访问这些属性的 CNeatDC 函数。 Attribute Default Operation functions 文本颜色 Text Color Black(黑色) \ref CNeatDC::SetTextColor \ref CNeatDC::GetTextColor 背景颜色 Background Color White(黑色) \ref CNeatDC::SetBkColor \ref CNeatDC::GetBkColor 背景模式 Background Mode OPAQUE(覆盖) \ref CNeatDC::SetBkMode \ref CNeatDC::GetBkMode 当前位置 Current Position (0,0) \ref CNeatDC::MoveTo \ref CNeatDC::GetCurrentPosition 31 Attribute Default Operation functions 当前画笔 Current Pen (黑色) (Black) \ref CNeatDC::SelectObject \ref CNeatDC::GetCurrentPen 当前画刷 Current Brush (黑色) (Black) \ref CNeatDC::SelectObject \ref CNeatDC::GetCurrentBrush 当前字体 Current Font (黑色) (Black) \ref CNeatDC::SelectObject \ref CNeatDC::GetCurrentFont 下面我们描述一下怎样创建和使用这些设备上下文。 使用 CNeatClientDC 在窗口客户区进行绘画。 \ref CNeatClientDC 用来在非重绘事件处理函数中对窗口的客户区进行绘制。下面的例子演示了按键时在窗口中随机画线: \code int MyWindow::OnKeyDown(UINT nKeyCode, UINT nRepCnt, UINT nFlags) { int x, y; CNeatRect rect; // 创建一设备上下文 CNeatClientDC dc(this); // 创建一画笔,使用默认属性(宽度为 1,颜色为黑色,实线) CNeatPen pen; // 将画笔选进设备上下文,选进成功后,设备上下文后续的画线将使用这个画笔 dc.SelectObject(&pen); // 获得当前窗口的客户区尺寸,在客户区内随机定位一个点,然后画线 GetClientRect( &rect ); x = rand()%rect.Width(); y = rand()%rect.Height(); dc.LineTo(x,y); } \endcode 使用 CNeatPaintDC 在窗口上绘画 如果你定义了一个窗口重绘事件处理函数,则必须在这个处理函数中产生一个 CNeatPaintDC 设备上下文,并且使用它来进行 你需要的绘画动作。 产生这个对将告诉 NEAT 的窗口体系这个窗口的需要重画的区域已经被重画了, 这样窗口系统就不会重复的 发送重画消息给这个窗口了。重画事件是由于用户和窗口系统的交互造成的,但是它也可以通过调用 CNeatWnd::InvalidateRect 函 数手动产生。 下面的代码演示了如何在窗口正中位置画一个黑边红色的矩形区域,并且会判断这个区域是否位于需要更新的区域范围内以 32 便决定是否需要重画。 \code int MyWindow::OnPaint() { // 创建一设备上下文 CNeatPaintDC dc(this); // 获取窗口大小 CNeatRect rect; GetClientRect( &rect ); // 绘制一矩形框 dc.Rectangle(&rect); } \endcode 绘画工具 画笔 NEAT 使用\ref CNeatPen 来实现画笔的功能,一个画笔对包含三个属性:画笔的类型,颜色和线宽,默认为:实线,黑色, 1 个像素线宽。如果要使用自定义的画笔,首先要定义一个 CNeatPen 的对,并设置相关属性;使用时,先要调用\ref CNeatDC::SelectObject 将画笔对选进设备上下文中,如下面代码所示: \code CNeatPen pen(PT_SOLID,1,COLOR_black); dc.SelectObject(&pen); \endcode 下面给出一个画笔及常用画线(画框)函数的示例代码: \include gdi\pen\src\gdi-pen.cpp \image html gdi-pen-normal.jpg ―画笔 - 普通‖ \image html gdi-pen-width.jpg ―画笔 - 不同线宽‖ \image html gdi-pen-color.jpg ―画笔 - 不同颜色‖ \image html gdi-pen-dbdash.jpg ―画笔 - 双虚线‖ \image html gdi-pen-dash.jpg ―画笔 - 可定制虚线‖ 画刷 NEAT 使用\ref CNeatBrush 来实现画刷的功能,一个画刷对包含两个属性:画刷的类型和颜色,默认为:纯色(黑色)填 充。 如果要使用自定义的画刷, 首先要定义一个 CNeatBrush 的对, 并设置相关属性; 使用时, 先要调用\ref CNeatDC::SelectObject 将画笔对选进设备上下文中,如下面代码所示: \code CNeatBrush brush(COLOR_black); dc.SelectObject(&brush); \endcode 下面给出一个画刷及填充的示例代码: 33 \include gdi\brush\src\gdi-brush.cpp \image html gdi-brush-color.jpg ―画刷 - 纯色填充‖ \image html gdi-brush-CROSS.jpg ―画刷 - 预设类型填充‖ \image html gdi-brush-DIAGCROSS.jpg ―画刷 - 预设类型填充‖ \image html gdi-brush-bmp1.jpg ―画刷 - 位图填充‖ \image html gdi-brush-bmp2.jpg ―画刷 - 位图填充‖ 字体 NEAT 使用\ref CNeatFont 来实现字体的功能,一个字体对包含属性: 字符集及编码:多字节编码字符集:简体中文(gb2312,gbk),单字节编码字符集:ascii,iso8859-1,ISO8859-15 字体样式:中文默认为宋体,英文默认为(Arial) 字体大小:中文默认为宋体,英文默认为(Arial) 其他属性:下划线,穿透线,粗体,斜体等等 下面给出一个字体使用的示例代码: \include gdi\font\src\gdi-font.cpp 不同大小字体(12,16,24) \image html gdi-font-12.jpg \image html gdi-font-16.jpg \image html gdi-font-24.jpg 不同粗细 \image html gdi-font-bold.jpg \image html gdi-font-demibold.jpg \image html gdi-font-book.jpg \image html gdi-font-subpiexl.jpg 下划线及穿透线斜体 \image html gdi-font-underline.jpg \image html gdi-font-structout.jpg \image html gdi-font-slant.jpg 图标 NEAT 使用\ref CNeatIcon 来实现图标的功能。 位图 NEAT 使用\ref CNeatBitmap 来实现位图的功能。 34 绘制基本图形 下面列出 NEAT 支持的常见的图标图形操作: 函数 功能 备注 \ref CNeatDC::LineTo 画线 当前画笔 \ref CNeatDC::Rectangle 画矩形框 当前画笔 \ref CNeatDC::Circle 画圆 当前画笔 \ref CNeatDC::CircleEx 画圆(支持线类型及线宽) 当前画笔 \ref CNeatDC::Ellipse 画椭圆 当前画笔 \ref CNeatDC::EllipseEx 画椭圆(支持线类型及线宽) 当前画笔 \ref CNeatDC::CircleArc 画弧线 当前画笔 CNeatDC::SetPixel 设置像素点颜色 调用参数指定 \ref CNeatDC::FillSolidRect 区域填充 调用参数指定 \ref CNeatDC::FillRect 区域填充,使用当前画刷 当前画刷 \ref CNeatDC::FillCircle 圆填充,使用当前画刷,只支持纯色模式 当前画刷 \ref CNeatDC::FillCircleEx 圆填充,使用当前画刷,支持画刷的各个类型 当前画刷 \ref CNeatDC::FillEllipse 椭圆填充,使用当前画刷,只支持纯色模式 当前画刷 \ref CNeatDC::FillEllipseEx 椭圆填充,使用当前画刷,支持画刷的各个类型 当前画刷 \ref CNeatDC::FillArcEx 弧型填充,使用当前画刷,支持画刷的各个类型 当前画刷 绘制文本 下面列出 NEAT 支持的绘制文本操作: 函数 功能 备注 \ref CNeatDC::TextOut 文本输出 当前画笔 \ref CNeatDC::DrawText 文本格式化输出 当前画笔 \ref CNeatDC::TabbedTextOut 文本输出,支持 TAB 当前画笔 35 文本格式: 格式 备注 格式 备注 DT_TOP 顶部对齐 DT_LEFT 左对齐 DT_CENTER 中间对齐(设置 DT_SINGLELINE 时有效) DT_RIGHT 右对齐 DT_VCENTER 上下居中 DT_BOTTOM 底部对齐 DT_WORDBREAK 自动卷行时,判断单词边界 DT_SINGLELINE 单行 DT_EXPANDTABS TAB 扩展,默认为个空格 DT_TABSTOP 格式参数的高 8 位用来指定 TAB 键宽度 DT_NOCLIP 不进行边界切割 DT_CHARBREAK 当文本输出超过矩形区时按字 符换行输出 DT_CALCRECT 不作实际输出,只计算实际的输 出矩形大小 36 第七章 处理用户输入 PT80 的按键所对应的键值 输入事件相应 事件 消息处理函数 备注 MSG_KEYDOWN \ref CNeatWnd::OnKeyDown 按键按下事件 MSG_KEYUP \ref CNeatWnd::OnKeyUp 按键释放事件 标识 键值 标识 键值 标识 键值 KEY_0 11 KEY_8 9 KEY_OK 59 KEY_1 2 KEY_9 10 KEY_CANCEL 1 KEY_2 3 KEY_UP 103 KEY_POWER 68 KEY_3 4 KEY_DOWN 108 KEY_FUNC 60 KEY_4 5 KEY_LEFT 105 KEY_BACKSPACE 14 KEY_5 6 KEY_RIGHT 106 KEY_TAB 15 KEY_6 7 KEY_ENTER 28 KEY_ALPHA 66 KEY_7 8 KEY_DOT 52 37 第八章 对话框编程基础 使用资源编辑器编辑对话框 几乎每一个 NEAT 程序都会使用对话框与用户进行交互,对话框可能是一个简单的 OK 按钮,也可以是一个复杂的数据输入 表单。NEAT 目前只支持模态对话框方式,\ref CNeatDialog 是对话框的基类,使用模态对话框,在对话框关闭之前,用户不能在 同一应用程序的其他地方工作。 对话框和普通窗口的主要区别在于,对话框几乎始终与资源相关联,这些资源标识对话框元素,并指定它的布局。在 VC 开 发环境下,可以利用 VC 的对话框编辑器(资源编辑器之一)来创建和编辑对话框资源,所以,我们可以快速并且高效地以可视化 的方式生成对话框。 对话框包含许多名为控件的元素,对话框控件包括编辑控件、按钮、列表框、组合框、静态文本(标签)、进度条、滑块等。 控件发送通知消息到它的对话框,以响应键入文本或单击按钮之类的用户活动。 NEAT 已经对这些事件做了很好的封装,使用时,只要重载你关心的事件处理函数就可以了。在对话框创建的时候,要建立 对话框数据成员和这些控件的关联,然后就可以利用这些数据成员进行控件的数据操作了。 模态和非模态对话框编程 模态对话框是最常用的对话框。用户的操作打开一个对话框,用户在对话框中输入数据,然后关闭对话框。下面在当前工程 中增加一个模态对话框的步骤(在 VC 集成开发环境下): 1. 使用对话框编辑器来创建包含不同控件的对话框资源。对话框编辑器更新工程的资源 脚本(RC)文件,以包含新的对话框资源,并且,它使用对应的#define 变量来更新该工程的 resource.h 文件。 2. 创建一个\ref CNeatDialog 的派生类。 3. 在创建的派生类中,添加要进行数据操作的控件数据成员。 4. 在创建的派生类中,添加要处理的控件事件处理函数。 5. 在创建的派生类中,重载\ref CNeatDialog::OnInitDialog 函数,并在此函数里实现控件数据成员和相应控件的关联。 6. 在合适的位置编写代码来激活对话框。这个代码包括对对话框构造函数的调用,接着是对\ref CNeatDialog::DoModal 对 话框类成员函数的调用。只有当用户退出这个对话框窗口时,\ref CNeatDialog::DoModal 函数才返回。 38 通用对话框 对话框 示例 现在,我们将开始一个示例程序。 对话框资源编辑(有关 VC 资源编辑器的使用,已经超出了本帮助文档的范围,但有关 VC 资源编辑器使用介绍的文档 、书籍 很多,请用户去参考相关的使用介绍)。 \image html dialog1-rc.jpg "对话框资源" 创建一个\ref CNeatDialog 的派生类。 \code // CMyDialog // 资源头文件 #include "resource.h" // NEAT 对话框及控件实现相关的头文件 #include // 定义一个对话框 // 创建一个\ref CNeatDialog 的派生类。 class CMyDialog : public CNeatDialog { public: // 构造函数 CMyDialog(UINT dlgid, CNeatWnd* parent); // 对话框创建初始化函数,用于控件的关联和控件数据的初始化。 virtual int OnInitDialog(); // 列表框选择发生改变的事件响应处理函数 virtual int OnLbnSelchange(UINT nID,HWND hwnd); // 确认退出前的事件响应处理函数 virtual int OnOK(); public: wxString m_str; protected: // 列表框控件对 CNeatListCtrl m_listctrl; }; \endcode 在 OnInitDialog 中实现控件数据成员和相应控件的关联。 \code int CMyDialog::OnInitDialog() { CNeatDialog::OnInitDialog(); 39 // 实现列表控件和列表框对的关联,IDC_LIST1 为列表框对应的资源 ID m_listctrl.Attach(GetDlgItem(IDC_LIST1)); // 利用列表框对进行相关的数据操作,这里添加一些字符串 m_listctrl.AddString( _("list string1") ); m_listctrl.AddString( _("list string2") ); m_listctrl.SetCurSel(0); return 0; } \endcode 重写你关心的一些事件处理函数 \code // 列表边框选择发生改变的事件处理函数 int CMyDialog::OnLbnSelchange(UINT nID,HWND hwnd) { if (hwnd==m_listctrl.GetSafeHwnd()) { int sel = m_listctrl.GetCurSel(); } } // 对话确认退出前的事件响应函数 void CMyDialog::OnOK() { int sel = m_listctrl.GetCurSel(); m_str = m_listctrl.GetText(sel); } \endcode 调用这个对话框,看看运行的效果。 \code // 按键事件处理函数 int CMyFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // 调用对话框 CMyDialog dlg(IDD_DIALOG1,this); if (dlg.DoModal()==IDOK) { NeatMessage( dlg.m_str ); } return 0; } \endcode \image html dialog1-emu.jpg "模拟器下运行效果" 40 对话框资源 在 VC 开发环境下的 NEAT, 可以利用 VC 的资源编辑工具进行资源的编辑, 但没有直接使用它的 rc 文件, 需要使用 neatrg 工 具进行资源的转换,转换后的资源称为资源模板,默认存在 res.cpp 文件中。 资源模板文件 在资源模板文件中,常包含有以下几种资源: 1. 对话框(Dialog)资源,资源数据利用数据结构\ref DLGTEMPLATE 来实现。 2. 位图(Bitmap)资源,资源数据为一个资源 ID 及对应的位图文件。 3. 图标(Icon)资源,资源数据为一个资源 ID 及对应图标文件。 4. 菜单(Menu)资源。 5. 版本信息(Version)资源。 用到了几个将资源数据和资源 ID 建立关联的数据结构: \ref DLGID_TEMPL 用于对话框资源和资源 ID 的关联。 \ref STRID_TEMPL 用于字符串(Bitmap,Icon,cursor 等)资源和资源 ID 的关联。 \ref MENU_TEMPL 用于菜单资源和资源 ID 的关联。 \ref MENUITEM_TEMPL 用于菜单项的关联。 41 第九章 NEAT 控件 控件综述 许多人对控件(或者部件)的概念已经相当熟悉了,控件可以理解为主窗口中的子窗口,这些子窗口的行为和主窗口一样, 既能够接收键盘和鼠标等外部输入,也可以在自己的区域内进行输出,只是它们的所有活动被限制在主窗口中。NEAT 也支持子窗 口,并且可以在子窗口中嵌套建立子窗口。我们将 NEAT 中的所有子窗口均称为控件。 静态框 静态框用来在窗口的特定位置显示文字、数字等信息,还可以用来显示一些静态的图片信息,比如公司徽标、产品商标等等。 就像其名称暗示的那样,静态框的行为不能对用户的输入进行动态的响应,它的存在基本上就是为了展示一些信息,而不会接收任 何键盘或鼠标输入。 静态框风格 静态框的风格由静态框种类和一些标志位组成。我们可将静态框控件按功能划分为标准型(只显示文本)、位图型(显示图 标或图片),以及特殊类型分组框。下面我们将分别介绍上述不同类型的静态框。 标准型 SS_SIMPLE 创建的控件只用来显示单行文本 SS_LEFT 风格创建的静态框可用来显示多行文本并左对齐 SS_CENTER 风格创建的静态框可用来显示多行文本并中对齐 SS_RIGHT 风格创建的静态框可用来显示多行文本并右对齐 SS_LEFTNOWORDWRAP 创建的静态框会扩展文本中的 TAB 符,但不做自动换行处理。 位图型 SS_BITMAP 显示一幅位图 SS_ICON 显示一幅图标 SS_REALSIZEIMAGE 取消缩放操作,并显示在静态框的左上方 SS_CENTERIMAGE 在控件中部显示位图或图标 分组框 SS_GROUPBOX 用来包含其他的控件 42 其他静态框类型 SS_WHITERECT 以白色填充静态框矩形 SS_GRAYRECT 以灰色填充静态框矩形 SS_BLACKRECT 以黑色填充静态框矩形 SS_GRAYFRAME 灰色边框 SS_WHITEFRAME 白色边框 SS_BLACKFRAME 黑色边框 编程示例 1. 手动创建: 直接在视图上创建\ref CNeatStatic 的对,并调用 Create 方法。 2. 利用资源创建: 创建\ref CNeatStatic 的对并调用 LoadTemplate(CNeatWnd * parent, PCTRLDATA templdata, const wxString & res = NEATAPPNAME) 函数 3. 对话框创建: 首先将 Picture Control 控件拖到模板上 \image html 9.2-static1.JPG 添加图标:设置 Type 熟悉对话框为 Icon,设置 Image 为所选图标的 ID。 添加位图:Type 为 Bitmap。 \image html 9.2-static2.JPG 添加静态框只需将控件拖到模板上即可 \image html 9.2-static3.JPG 部分示例代码: \include demo-static.cpp 显示效果截图: \image html demo-static-1.jpg "静态框示例 按键 1" \image html demo-static-2.jpg "静态框示例 按键 2" \image html demo-static-3.jpg "静态框示例 按键 3" \image html demo-static-4.jpg "静态框示例 按键 4" 43 按钮 按钮是除静态框之外使用最为频繁的一种控件。按钮通常用来为用户提供开关选择。NEAT 的按钮可划分为普通按钮、复选 框和单选钮等几种类型。用户可以通过键盘或者鼠标来选择或者切换按钮的状态。用户的输入将使按钮产生通知消息,应用程序也 可以向按钮发送消息以改变按钮的状态。 按钮风格 普通按钮 BS_PUSHBUTTON 普通按钮 BS_DEFPUSHBUTTON 默认选中普通按钮 复选框 复选框风格: BS_CHECKBOX 在选中和非选中状态之间切换 BS_AUTOCHECKBOX 控件会自动在选中和非选中状态之间切换 BS_3STATE 能显示第三种状态——复选框内是灰色的,应用程序来操作其状态 BS_AUTO3STATE 能显示第三种状态——复选框内是灰色的,由控件负责状态的自动切换 BS_PUSHLIKE 复选框以普通按钮的形式显示 文本对齐的风格: BS_LEFT 文本左对齐 BS_CENTER 文本水平居中 BS_RIGHT 文本右对齐 BS_TOP 文本上对齐 BS_VCENTER 文本垂直居中 BS_BOTTOM 文本下对齐 单选钮 显示用户的选择情况 BS_RADIOBUTTON 显示用户的选择情况 BS_AUTORADIOBUTTON 自动显示用户的选择情况 BS_PUSHLIKE 单选按钮以普通按钮的形式显示 44 文本对齐的风格: BS_LEFT 文本左对齐 BS_CENTER 文本水平居中 BS_RIGHT 文本右对齐 BS_TOP 文本上对齐 BS_VCENTER 文本垂直居中 BS_BOTTOM 文本下对齐 按钮事件响应 按钮事件 消息处理函数 备注 BN_CLICKED CNeatWnd::OnBnClicked 按钮单击事件的响应函数 BN_PUSHED CNeatWnd::OnBnPushed 按钮按下事件的响应函数 BN_UNPUSH
CISCO 技术大集合 {适合你们的技术} 二、命令状态 1. router> 路由器处于用户命令状态,这时用户可以看路由器的连接状态,访问其它网络和主机,但不能看到和更改路由器的设置内容。 2. router# 在router>提示符下键入enable,路由器进入特权命令状态router#,这时不但可以执行所有的用户命令,还可以看到和更改路由器的设置内容。 3. router(config)# 在router#提示符下键入configure terminal,出现提示符router(config)#,此时路由器处于全局设置状态,这时可以设置路由器的全局参数。 4. router(config-if)#; router(config-line)#; router(config-router)#;… 路由器处于局部设置状态,这时可以设置路由器某个局部的参数。 5. > 路由器处于RXBOOT状态,在开机后60秒内按ctrl-break可进入此状态,这时路由器不能完成正常的功能,只能进行软件升级和手工引导。 6. 设置对话状态 这是一台新路由器开机时自动进入的状态,在特权命令状态使用SETUP命令也可进入此状态,这时可通过对话方式对路由器进行设置。   返回目录 三、设置对话过程 1. 显示提示信息 2. 全局参数的设置 3. 接口参数的设置 4. 显示结果 利用设置对话过程可以避免手工输入命令的烦琐,但它还不能完全代替手工设置,一些特殊的设置还必须通过手工输入的方式完成。 进入设置对话过程后,路由器首先会显示一些提示信息: --- System Configuration Dialog --- At any point you may enter a question mark '?' for help. Use ctrl-c to abort configuration dialog at any prompt. Default settings are in square brackets '[]'. 这是告诉你在设置对话过程中的任何地方都可以键入“?”得到系统的帮助,按ctrl-c可以退出设置过程,缺省设置将显示在‘[]’中。然后路由器会问是否进入设置对话: Would you like to enter the initial configuration dialog? [yes]: 如果按y或回车,路由器就会进入设置对话过程。首先你可以看到各端口当前的状况: First, would you like to see the current interface summary? [yes]: Any interface listed with OK? value "NO" does not have a valid configuration Interface IP-Address OK? Method Status Protocol Ethernet0 unassigned NO unset up up Serial0 unassigned NO unset up up ……… ……… … …… … … 然后,路由器就开始全局参数的设置: Configuring global parameters: 1.设置路由器名: Enter host name [Router]: 2.设置进入特权状态的密文(secret),此密文在设置以后不会以明文方式显示: The enable secret is a one-way cryptographic secret used instead of the enable password when it exists. Enter enable secret: cisco 3.设置进入特权状态的密码(password),此密码只在没有密文时起作用,并且在设置以后会以明文方式显示: The enable password is used when there is no enable secret and when using older software and some boot images. Enter enable password: pass 4.设置虚拟终端访问时的密码: Enter virtual terminal password: cisco 5.询问是否要设置路由器支持的各种网络协议: Configure SNMP Network Management? [yes]: Configure DECnet? [no]: Configure AppleTalk? [no]: Configure IPX? [no]: Configure IP? [yes]: Configure IGRP routing? [yes]: Configure RIP routing? [no]: ……… 6.如果配置的是拨号访问服务器,系统还会设置异步口的参数: Configure Async lines? [yes]: 1) 设置线路的最高速度: Async line speed [9600]: 2) 是否使用硬件流控: Configure for HW flow control? [yes]: 3) 是否设置modem: Configure for modems? [yes/no]: yes 4) 是否使用默认的modem命令: Configure for default chat script? [yes]: 5) 是否设置异步口的PPP参数: Configure for Dial-in IP SLIP/PPP access? [no]: yes 6) 是否使用动态IP地址: Configure for Dynamic IP addresses? [yes]: 7) 是否使用缺省IP地址: Configure Default IP addresses? [no]: yes 8) 是否使用TCP头压缩: Configure for TCP Header Compression? [yes]: 9) 是否在异步口上使用路由表更新: Configure for routing updates on async links? [no]: y 10) 是否设置异步口上的其它协议。 接下来,系统会对每个接口进行参数的设置。 1.Configuring interface Ethernet0: 1) 是否使用此接口: Is this interface in use? [yes]: 2) 是否设置此接口的IP参数: Configure IP on this interface? [yes]: 3) 设置接口的IP地址: IP address for this interface: 192.168.162.2 4) 设置接口的IP子网掩码: Number of bits in subnet field [0]: Class C network is 192.168.162.0, 0 subnet bits; mask is /24 在设置完所有接口的参数后,系统会把整个设置对话过程的结果显示出来: The following configuration command script was created: hostname Router enable secret 5 $1$W5Oh$p6J7tIgRMBOIKVXVG53Uh1 enable password pass ………… 请注意在enable secret后面显示的是乱码,而enable password后面显示的是设置的内容。 显示结束后,系统会问是否使用这个设置: Use this configuration? [yes/no]: yes 如果回答yes,系统就会把设置的结果存入路由器的NVRAM中,然后结束设置对话过程,使路由器开始正常的工作。 返回目录   四、常用命令 1. 帮助 在IOS操作中,无论任何状态和位置,都可以键入“?”得到系统的帮助。 2. 改变命令状态 任务 命令 进入特权命令状态 enable 退出特权命令状态 disable 进入设置对话状态 setup 进入全局设置状态 config terminal 退出全局设置状态 end 进入端口设置状态 interface type slot/number 进入子端口设置状态 interface type number.subinterface [point-to-point | multipoint] 进入线路设置状态 line type slot/number 进入路由设置状态 router protocol 退出局部设置状态 exit 3. 显示命令 任务 命令 查看版本及引导信息 show version 查看运行设置 show running-config 查看开机设置 show startup-config 显示端口信息 show interface type slot/number 显示路由信息 show ip router 4. 拷贝命令 用于IOS及CONFIG的备份和升级 5. 网络命令 任务 命令 登录远程主机 telnet hostname|IP address 网络侦测 ping hostname|IP address 路由跟踪 trace hostname|IP address   6. 基本设置命令 任务 命令 全局设置 config terminal 设置访问用户及密码 username username password password 设置特权密码 enable secret password 设置路由器名 hostname name 设置静态路由 ip route destination subnet-mask next-hop 启动IP路由 ip routing 启动IPX路由 ipx routing 端口设置 interface type slot/number 设置IP地址 ip address address subnet-mask 设置IPX网络 ipx network network 激活端口 no shutdown 物理线路设置 line type number 启动登录进程 login [local|tacacs server] 设置登录密码 password password   五、配置IP寻址   1. IP地址分类 IP地址分为网络地址和主机地址二个部分,A类地址前8位为网络地址,后24位为主机地址,B类地址16位为网络地址,后16位为主机地址,C类地址前24位为网络地址,后8位为主机地址,网络地址范围如下表所示: 种类 网络地址范围 A  1.0.0.0 到126.0.0.0有效 0.0.0.0 和127.0.0.0保留 B 128.1.0.0到191.254.0.0有效 128.0.0.0和191.255.0.0保留 C 192.0.1.0 到223.255.254.0有效 192.0.0.0和223.255.255.0保留 D 224.0.0.0到239.255.255.255用于多点广播 E 240.0.0.0到255.255.255.254保留 255.255.255.255用于广播 2. 分配接口IP地址 任务 命令 接口设置 interface type slot/number 为接口设置IP地址 ip address ip-address mask 掩玛(mask)用于识别IP地址中的网络地址位数,IP地址(ip-address)和掩码(mask)相与即得到网络地址。 3. 使用可变长的子网掩码 通过使用可变长的子网掩码可以让位于不同接口的同一网络编号的网络使用不同的掩码,这样可以节省IP地址,充分利用有效的IP地址空间。 如下图所示: Router1和Router2的E0端口均使用了C类地址192.1.0.0作为网络地址,Router1的E0的网络地址为192.1.0.128,掩码为255.255.255.192, Router2的E0的网络地址为192.1.0.64,掩码为255.255.255.192,这样就将一个C类网络地址分配给了二个网,既划分了二个子网,起到了节约地址的作用。 4. 使用网络地址翻译(NAT) NAT(Network Address Translation)起到将内部私有地址翻译成外部合法的全局地址的功能,它使得不具有合法IP地址的用户可以通过NAT访问到外部Internet. 当建立内部网的时候,建议使用以下地址组用于主机,这些地址是由Network Working Group(RFC 1918)保留用于私有网络地址分配的. l Class A:10.1.1.1 to 10.254.254.254 l Class B:172.16.1.1 to 172.31.254.254 l Class C:192.168.1.1 to 192.168.254.254 命令描述如下: 任务 命令 定义一个标准访问列表 access-list access-list-number permit source [source-wildcard] 定义一个全局地址池 ip nat pool name start-ip end-ip {netmask netmask | prefix-length prefix-length} [type rotary] 建立动态地址翻译 ip nat inside source {list {access-list-number | name} pool name [overload] | static local-ip global-ip} 指定内部和外部端口 ip nat {inside | outside} 如下图所示, 路由器的Ethernet 0端口为inside端口,即此端口连接内部网络,并且此端口所连接的网络应该被翻译,Serial 0端口为outside端口,其拥有合法IP地址(由NIC或服务提供商所分配的合法的IP地址),来自网络10.1.1.0/24的主机将从IP地址池c2501中选择一个地址作为自己的合法地址,经由Serial 0口访问Internet。命令ip nat inside source list 2 pool c2501 overload中的参数overload,将允许多个内部地址使用相同的全局地址(一个合法IP地址,它是由NIC或服务提供商所分配的地址)。命令ip nat pool c2501 202.96.38.1 202.96.38.62 netmask 255.255.255.192定义了全局地址的范围。 设置如下: ip nat pool c2501 202.96.38.1 202.96.38.62 netmask 255.255.255.192 interface Ethernet 0 ip address 10.1.1.1 255.255.255.0 ip nat inside ! interface Serial 0 ip address 202.200.10.5 255.255.255.252 ip nat outside ! ip route 0.0.0.0 0.0.0.0 Serial 0 access-list 2 permit 10.0.0.0 0.0.0.255 ! Dynamic NAT ! ip nat inside source list 2 pool c2501 overload line console 0 exec-timeout 0 0 ! line vty 0 4 end   六、配置静态路由 通过配置静态路由,用户可以人为地指定对某一网络访问时所要经过的路径,在网络结构比较简单,且一般到达某一网络所经过的路径唯一的情况下采用静态路由。 任务 命令 建立静态路由 ip route prefix mask {address | interface} [distance] [tag tag] [permanent] Prefix :所要到达的目的网络 mask :子网掩码 address :下一个跳的IP地址,即相邻路由器的端口地址。 interface :本地网络接口 distance :管理距离(可选) tag tag :tag值(可选) permanent :指定此路由即使该端口关掉也不被移掉。 以下在Router1上设置了访问192.1.0.64/26这个网下一跳地址为192.200.10.6,即当有目的地址属于192.1.0.64/26的网络范围的数据报,应将其路由到地址为192.200.10.6的相邻路由器。在Router3上设置了访问192.1.0.128/26及192.200.10.4/30这二个网下一跳地址为192.1.0.65。由于在Router1上端口Serial 0地址为192.200.10.5,192.200.10.4/30这个网属于直连的网,已经存在访问192.200.10.4/30的路径,所以不需要在Router1上添加静态路由。 Router1: ip route 192.1.0.64 255.255.255.192 192.200.10.6 Router3: ip route 192.1.0.128 255.255.255.192 192.1.0.65 ip route 192.200.10.4 255.255.255.252 192.1.0.65 同时由于路由器Router3除了与路由器Router2相连外,不再与其他路由器相连,所以也可以为它赋予一条默认路由以代替以上的二条静态路由, ip route 0.0.0.0 0.0.0.0 192.1.0.65 即只要没有在路由表里找到去特定目的地址的路径,则数据均被路由到地址为192.1.0.65的相邻路由器。 返回目录   一、HDLC   HDLC是CISCO路由器使用的缺省协议,一台新路由器在未指定封装协议时默认使用HDLC封装。 1. 有关命令 端口设置 任务 命令 设置HDLC封装 encapsulation hdlc 设置DCE端线路速度 clockrate speed 复位一个硬件接口 clear interface serial unit 显示接口状态 show interfaces serial [unit] 1 注:1.以下给出一个显示Cisco同步串口状态的例子. Router#show interface serial 0 Serial 0 is up, line protocol is up Hardware is MCI Serial Internet address is 150.136.190.203, subnet mask is 255.255.255.0 MTU 1500 bytes, BW 1544 Kbit, DLY 20000 usec, rely 255/255, load 1/255 Encapsulation HDLC, loopback not set, keepalive set (10 sec) Last input 0:00:07, output 0:00:00, output hang never Output queue 0/40, 0 drops; input queue 0/75, 0 drops Five minute input rate 0 bits/sec, 0 packets/sec Five minute output rate 0 bits/sec, 0 packets/sec 16263 packets input, 1347238 bytes, 0 no buffer Received 13983 broadcasts, 0 runts, 0 giants 2 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 2 abort 22146 packets output, 2383680 bytes, 0 underruns 0 output errors, 0 collisions, 2 interface resets, 0 restarts 1 carrier transitions 2. 举例     设置如下: Router1: interface Serial0 ip address 192.200.10.1 255.255.255.0 clockrate 1000000 Router2: interface Serial0 ip address 192.200.10.2 255.255.255.0 ! 3. 举例使用E1线路实现多个64K专线连接. 相关命令: 任务 命令 进入controller配置模式 controller {t1 | e1} number 选择帧类型 framing {crc4 | no-crc4} 选择line-code类型 linecode {ami | b8zs | hdb3} 建立逻辑通道组与时隙的映射 channel-group number timeslots range1 显示controllers接口状态 show controllers e1 [slot/port]2 注: 1. 当链路为T1时,channel-group编号为0-23, Timeslot范围1-24; 当链路为E1时, channel-group编号为0-30, Timeslot范围1-31. 2.使用show controllers e1观察controller状态,以下为帧类型为crc4时controllers正常的状态. Router# show controllers e1 e1 0/0 is up. Applique type is Channelized E1 - unbalanced Framing is CRC4, Line Code is HDB3 No alarms detected. Data in current interval (725 seconds elapsed): 0 Line Code Violations, 0 Path Code Violations 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs Total Data (last 24 hours) 0 Line Code Violations, 0 Path Code Violations, 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins, 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs 以下例子为E1连接3条64K专线, 帧类型为NO-CRC4,非平衡链路,路由器具体设置如下: shanxi#wri t Building configuration... Current configuration: ! version 11.2 no service udp-small-servers no service tcp-small-servers ! hostname shanxi ! enable secret 5 $1$XN08$Ttr8nfLoP9.2RgZhcBzkk/ enable password shanxi ! ! ip subnet-zero ! controller E1 0 framing NO-CRC4 channel-group 0 timeslots 1 channel-group 1 timeslots 2 channel-group 2 timeslots 3 ! interface Ethernet0 ip address 133.118.40.1 255.255.0.0 media-type 10BaseT ! interface Ethernet1 no ip address shutdown ! interface Serial0:0 ip address 202.119.96.1 255.255.255.252 no ip mroute-cache ! interface Serial0:1 ip address 202.119.96.5 255.255.255.252 no ip mroute-cache ! interface Serial0:2 ip address 202.119.96.9 255.255.255.252 no ip mroute-cache ! no ip classless ip route 133.210.40.0 255.255.255.0 Serial0:0 ip route 133.210.41.0 255.255.255.0 Serial0:1 ip route 133.210.42.0 255.255.255.0 Serial0:2 ! line con 0 line aux 0 line vty 0 4 password shanxi login ! end 广域网设置:   一、HDLC   HDLC是CISCO路由器使用的缺省协议,一台新路由器在未指定封装协议时默认使用HDLC封装。 1. 有关命令 端口设置 任务 命令 设置HDLC封装 encapsulation hdlc 设置DCE端线路速度 clockrate speed 复位一个硬件接口 clear interface serial unit 显示接口状态 show interfaces serial [unit] 1 注:1.以下给出一个显示Cisco同步串口状态的例子. Router#show interface serial 0 Serial 0 is up, line protocol is up Hardware is MCI Serial Internet address is 150.136.190.203, subnet mask is 255.255.255.0 MTU 1500 bytes, BW 1544 Kbit, DLY 20000 usec, rely 255/255, load 1/255 Encapsulation HDLC, loopback not set, keepalive set (10 sec) Last input 0:00:07, output 0:00:00, output hang never Output queue 0/40, 0 drops; input queue 0/75, 0 drops Five minute input rate 0 bits/sec, 0 packets/sec Five minute output rate 0 bits/sec, 0 packets/sec 16263 packets input, 1347238 bytes, 0 no buffer Received 13983 broadcasts, 0 runts, 0 giants 2 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 2 abort 22146 packets output, 2383680 bytes, 0 underruns 0 output errors, 0 collisions, 2 interface resets, 0 restarts 1 carrier transitions 2. 举例     设置如下: Router1: interface Serial0 ip address 192.200.10.1 255.255.255.0 clockrate 1000000 Router2: interface Serial0 ip address 192.200.10.2 255.255.255.0 ! 3. 举例使用E1线路实现多个64K专线连接. 相关命令: 任务 命令 进入controller配置模式 controller {t1 | e1} number 选择帧类型 framing {crc4 | no-crc4} 选择line-code类型 linecode {ami | b8zs | hdb3} 建立逻辑通道组与时隙的映射 channel-group number timeslots range1 显示controllers接口状态 show controllers e1 [slot/port]2 注: 1. 当链路为T1时,channel-group编号为0-23, Timeslot范围1-24; 当链路为E1时, channel-group编号为0-30, Timeslot范围1-31. 2.使用show controllers e1观察controller状态,以下为帧类型为crc4时controllers正常的状态. Router# show controllers e1 e1 0/0 is up. Applique type is Channelized E1 - unbalanced Framing is CRC4, Line Code is HDB3 No alarms detected. Data in current interval (725 seconds elapsed): 0 Line Code Violations, 0 Path Code Violations 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs Total Data (last 24 hours) 0 Line Code Violations, 0 Path Code Violations, 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins, 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs 以下例子为E1连接3条64K专线, 帧类型为NO-CRC4,非平衡链路,路由器具体设置如下: shanxi#wri t Building configuration... Current configuration: ! version 11.2 no service udp-small-servers no service tcp-small-servers ! hostname shanxi ! enable secret 5 $1$XN08$Ttr8nfLoP9.2RgZhcBzkk/ enable password shanxi ! ! ip subnet-zero ! controller E1 0 framing NO-CRC4 channel-group 0 timeslots 1 channel-group 1 timeslots 2 channel-group 2 timeslots 3 ! interface Ethernet0 ip address 133.118.40.1 255.255.0.0 media-type 10BaseT ! interface Ethernet1 no ip address shutdown ! interface Serial0:0 ip address 202.119.96.1 255.255.255.252 no ip mroute-cache ! interface Serial0:1 ip address 202.119.96.5 255.255.255.252 no ip mroute-cache ! interface Serial0:2 ip address 202.119.96.9 255.255.255.252 no ip mroute-cache ! no ip classless ip route 133.210.40.0 255.255.255.0 Serial0:0 ip route 133.210.41.0 255.255.255.0 Serial0:1 ip route 133.210.42.0 255.255.255.0 Serial0:2 ! line con 0 line aux 0 line vty 0 4 password shanxi login ! end 返回目录   二、PPP   PPP(Point-to-Point Protocol)是SLIP(Serial Line IP protocol)的继承者,它提供了跨过同步和异步电路实现路由器到路由器(router-to-router)和主机到网络(host-to-network)的连接。 CHAP(Challenge Handshake Authentication Protocol)和PAP(Password Authentication Protocol) (PAP)通常被用于在PPP封装的串行线路上提供安全性认证。使用CHAP和PAP认证,每个路由器通过名字来识别,可以防止未经授权的访问。 CHAP和PAP在RFC 1334上有详细的说明。 1. 有关命令 端口设置 任务 命令 设置PPP封装 encapsulation ppp1 设置认证方法 ppp authentication {chap | chap pap | pap chap | pap} [if-needed][list-name | default] [callin] 指定口令 username name password secret 设置DCE端线路速度 clockrate speed 注:1、要使用CHAP/PAP必须使用PPP封装。在与非Cisco路由器连接时,一般采用PPP封装,其它厂家路由器一般不支持Cisco的HDLC封装协议。 2. 举例 路由器Router1和Router2的S0口均封装PPP协议,采用CHAP做认证,在Router1中应建立一个用户,以对端路由器主机名作为用户名,即用户名应为router2。同时在Router2中应建立一个用户,以对端路由器主机名作为用户名,即用户名应为router1。所建的这两用户的password必须相同。 设置如下: Router1: hostname router1 username router2 password xxx interface Serial0 ip address 192.200.10.1 255.255.255.0 clockrate 1000000 ppp authentication chap ! Router2: hostname router2 username router1 password xxx interface Serial0 ip address 192.200.10.2 255.255.255.0 ppp authentication chap !   返回目录   三、x.25 1. X25技术 X.25规范对应OSI三层,X.25的第三层描述了分组的格式及分组交换的过程。X.25的第二层由LAPB(Link Access Procedure, Balanced)实现,它定义了用于DTE/DCE连接的帧格式。X.25的第一层定义了电气和物理端口特性。 X.25网络设备分为数据终端设备(DTE)、数据电路终端设备(DCE)及分组交换设备(PSE)。DTE是X.25的末端系统,如终端、计算机或网络主机,一般位于用户端,Cisco路由器就是DTE设备。DCE设备是专用通信设备,如调制解调器和分组交换机。PSE是公共网络的主干交换机。 X.25定义了数据通讯的电话网络,每个分配给用户的x.25 端口都具有一个x.121地址,当用户申请到的是SVC(交换虚电路)时,x.25一端的用户在访问另一端的用户时,首先将呼叫对方x.121地址,然后接收到呼叫的一端可以接受或拒绝,如果接受请求,于是连接建立实现数据传输,当没有数据传输时挂断连接,整个呼叫过程就类似我们拨打普通电话一样,其不同的是x.25可以实现一点对多点的连接。其中x.121地址、htc均必须与x.25服务提供商分配的参数相同。X.25 PVC(永久虚电路),没有呼叫的过程,类似DDN专线。 2. 有关命令: 任务 命令 设置X.25封装 encapsulation x25 [dce] 设置X.121地址 x25 address x.121-address 设置远方站点的地址映射 x25 map protocol address [protocol2 address2[...[protocol9 address9]]] x121-address [option] 设置最大的双向虚电路数 x25 htc citcuit-number1 设置一次连接可同时建立的虚电路数 x25 nvc count2 设置x25在清除空闲虚电路前的等待周期 x25 idle minutes 重新启动x25,或清一个svc,启动一个pvc相关参数 clear x25 {serial number | cmns-interface mac-address} [vc-number] 3 清x25虚电路 clear x25-vc 显示接口及x25相关信息 show interfaces serial show x25 interface show x25 map show x25 vc 注:1、虚电路号从1到4095,Cisco路由器默认为1024,国内一般分配为16。 2、虚电路计数从1到8,缺省为1。 3、在改变了x.25各层的相关参数后,应重新启动x25(使用clear x25 {serial number | cmns-interface mac-address} [vc-number]或clear x25-vc命令),否则新设置的参数可能不能生效。同时应对照服务提供商对于x.25交换机端口的设置来配置路由器的相关参数,若出现参数不匹配则可能会导致连接失败或其它意外情况。 3. 实例: 3.1. 在以下实例中每二个路由器间均通过svc实现连接。 路由器设置如下: Router1: interface Serial0 encapsulation x25 ip address 192.200.10.1 255.255.255.0 x25 address 110101 x25 htc 16 x25 nvc 2 x25 map ip 192.200.10.2 110102 broadcast x25 map ip 192.200.10.3 110103 broadcast ! Router2: interface Serial0 encapsulation x25 ip address 192.200.10.2 255.255.255.0 x25 address 110102 x25 htc 16 x25 nvc 2 x25 map ip 192.200.10.1 110101 broadcast x25 map ip 192.200.10.3 110103 broadcast ! Router: interface Serial0 encapsulation x25 ip address 192.200.10.3 255.255.255.0 x25 address 110103 x25 htc 16 x25 nvc 2 x25 map ip 192.200.10.1 110101 broadcast x25 map ip 192.200.10.2 110102 broadcast ! 相关调试命令: clear x25-vc show interfaces serial show x25 map show x25 route show x25 vc 3.2. 在以下实例中路由器router1和router2均通过svc与router连接,但router1和router2不通过svc直接连接,此三个路由器的串口运行RIP路由协议,使用了子接口的概念。由于使用子接口,router1和router2均学习到了访问对方局域网的路径,若不使用子接口,router1和router2将学不到到对方局域网的路由。 子接口(Subinterface)是一个物理接口上的多个虚接口,可以用于在同一个物理接口上连接多个网。我们知道为了避免路由循环,路由器支持split horizon法则,它只允许路由更新被分配到路由器的其它接口,而不会再分配路由更新回到此路由被接收的接口。 无论如何,在广域网环境使用基于连接的接口( X.25和Frame Relay),同一接口通过虚电路(vc)连接多台远端路由器时,从同一接口来的路由更新信息不可以再被发回到相同的接口,除非强制使用分开的物理接口连接不同的路由器。Cisco提供子接口(subinterface)作为分开的接口对待。你可以将路由器逻辑地连接到相同物理接口的不同子接口, 这样来自不同子接口的路由更新就可以被分配到其他子接口,同时又满足split horizon法则。 Router1: interface Serial0 encapsulation x25 ip address 192.200.10.1 255.255.255.0 x25 address 110101 x25 htc 16 x25 nvc 2 x25 map ip 192.200.10.3 110103 broadcast ! router rip network 192.200.10.0 ! Router2: interface Serial0 encapsulation x25 ip address 192.200.11.2 255.255.255.0 x25 address 110102 x25 htc 16 x25 nvc 2 x25 map ip 192.200.11.3 110103 broadcast ! router rip network 192.200.11.0 ! Router: interface Serial0 encapsulation x25 x25 address 110103 x25 htc 16 x25 nvc 2 ! interface Serial0.1 point-to-point ip address 192.200.10.3 255.255.255.0 x25 map ip 192.200.10.1 110101 broadcast ! interface Serial0.2 point-to-point ip address 192.200.11.3 255.255.255.0 x25 map ip 192.200.11.2 110102 broadcast ! router rip network 192.200.10.0 network 192.200.11.0 ! 返回目录   帧中继是一种高性能的WAN协议,它运行在OSI参考模型的物理层和数据链路层。它是一种数据包交换技术,是X.25的简化版本。它省略了X.25的一些强健功能,如提供窗口技术和数据重发技术,而是依靠高层协议提供纠错功能,这是因为帧中继工作在更好的WAN设备上,这些设备较之X.25的WAN设备具有更可靠的连接服务和更高的可靠性,它严格地对应于OSI参考模型的最低二层,而X.25还提供第三层的服务,所以,帧中继比X.25具有更高的性能和更有效的传输效率。 帧中继广域网的设备分为数据终端设备(DTE)和数据电路终端设备(DCE),Cisco路由器作为 DTE设备。 帧中继技术提供面向连接的数据链路层的通信,在每对设备之间都存在一条定义好的通信链路,且该链路有一个链路识别码。这种服务通过帧中继虚电路实现,每个帧中继虚电路都以数据链路识别码(DLCI)标识自己。DLCI的值一般由帧中继服务提供商指定。帧中继即支持PVC也支持SVC。 帧中继本地管理接口(LMI)是对基本的帧中继标准的扩展。它是路由器和帧中继交换机之间信令标准,提供帧中继管理机制。它提供了许多管理复杂互联网络的特性,其中包括全局寻址、虚电路状态消息和多目发送等功能。 2. 有关命令: 端口设置 任务 命令 设置Frame Relay封装 encapsulation frame-relay[ietf] 1 设置Frame Relay LMI类型 frame-relay lmi-type {ansi | cisco | q933a}2 设置子接口 interface interface-type interface-number.subinterface-number [multipoint|point-to-point] 映射协议地址与DLCI frame-relay map protocol protocol-address dlci [broadcast]3 设置FR DLCI编号 frame-relay interface-dlci dlci [broadcast] 注:1.若使Cisco路由器与其它厂家路由设备相连,则使用Internet工程任务组(IETF)规定的帧中继封装格式。 2.从Cisco IOS版本11.2开始,软件支持本地管理接口(LMI)“自动感觉”, “自动感觉”使接口能确定交换机支持的LMI类型,用户可以不明确配置LMI接口类型。 3.broadcast选项允许在帧中继网络上传输路由广播信息。 3. 帧中继point to point配置实例: Router1: interface serial 0 encapsulation frame-relay ! interface serial 0.1 point-to-point ip address 172.16.1.1 255.255.255.0 frame-reply interface-dlci 105 ! interface serial 0.2 point-to-point ip address 172.16.2.1 255.255.255.0 frame-reply interface-dlci 102 ! interface serial 0.3 point-to-point ip address 172.16.4.1 255.255.255.0 frame-reply interface-dlci 104 ! Router2: interface serial 0 encapsulation frame-relay ! interface serial 0.1 point-to-point ip address 172.16.2.2 255.255.255.0 frame-reply interface-dlci 201 ! interface serial 0.2 point-to-point ip address 172.16.3.1 255.255.255.0 frame-reply interface-dlci 203 ! 相关调试命令: show frame-relay lmi show frame-relay map show frame-relay pvc show frame-relay route show interfaces serial go top 4. 帧中继 Multipoint 配置实例: Router1: interface serial 0 encapsulation frame-reply ! interface serial 0.1 multipoint ip address 172.16.1.2 255.255.255.0 frame-reply map ip 172.16.1.1 201 broadcast frame-reply map ip 172.16.1.3 301 broadcast frame-reply map ip 172.16.1.4 401 broadcast ! Router2: interface serial 0 encapsulation frame-reply ! interface serial 0.1 multipoint ip address 172.16.1.1 255.255.255.0 frame-reply map ip 172.16.1.2 102 broadcast frame-reply map ip 172.16.1.3 102 broadcast frame-reply map ip 172.16.1.4 102 broadcast ! 五、ISDN   1. 综合数字业务网(ISDN) 综合数字业务网(ISDN)由数字电话和数据传输服务两部分组成,一般由电话局提供这种服务。ISDN的基本速率接口(BRI)服务提供2个B信道和1个D信道(2B+D)。BRI的B信道速率为64Kbps,用于传输用户数据。D信道的速率为16Kbps,主要传输控制信号。在北美和日本,ISDN的主速率接口(PRI)提供23个B信道和1个D信道,总速率可达1.544Mbps,其中D信道速率为64Kbps。而在欧洲、澳大利亚等国家,ISDN的PRI提供30个B信道和1个64Kbps D信道,总速率可达2.048Mbps。我国电话局所提供ISDN PRI为30B+D。 2. 基本命令 任务 命令 设置ISDN交换类型 isdn switch-type switch-type1 接口设置 interface bri 0 设置PPP封装 encapsulation ppp 设置协议地址与电话号码的映射 dialer map protocol next-hop-address [name hostname] [broadcast] [dial-string] 启动PPP多连接 ppp multilink 设置启动另一个B通道的阈值 dialer load-threshold load 显示ISDN有关信息 show isdn {active | history | memory | services | status [dsl | interface-type number] | timers} 注:1.交换机类型如下表,国内交换机一般为basic-net3。 按区域分关键字 交换机类型 Australia basic-ts013 Australian TS013 switches Europe basic-1tr6 German 1TR6 ISDN switches basic-nwnet3 Norway NET3 switches (phase 1) basic-net3 NET3 ISDN switches (UK, Denmark, and other nations); covers the Euro-ISDN E-DSS1 signalling system primary-net5 NET5 switches (UK and Europe) vn2 French VN2 ISDN switches vn3 French VN3 ISDN switches Japan ntt Japanese NTT ISDN switches primary-ntt Japanese ISDN PRI switches North America basic-5ess AT&T basic rate switches basic-dms100 NT DMS-100 basic rate switches basic-ni1 National ISDN-1 switches primary-4ess AT&T 4ESS switch type for the U.S. (ISDN PRI only) primary-5ess AT&T 5ESS switch type for the U.S. (ISDN PRI only) primary-dms100 NT DMS-100 switch type for the U.S. (ISDN PRI only) New Zealand basic-nznet3 New Zealand Net3 switches 3. ISDN实现DDR(dial-on-demand routing)实例: 设置如下: Router1: hostname router1 user router2 password cisco ! isdn switch-type basic-net3 ! interface bri 0 ip address 192.200.10.1 255.255.255.0 encapsulation ppp dialer map ip 192.200.10.2 name router2 572 dialer load-threshold 80 ppp multilink dialer-group 1 ppp authentication chap ! dialer-list 1 protocol ip permit ! Router2: hostname router2 user router1 password cisco ! isdn switch-type basic-net3 ! interface bri 0 ip address 192.200.10.2 255.255.255.0 encapsulation ppp dialer map ip 192.200.10.1 name router1 571 dialer load-threshold 80 ppp multilink dialer-group 1 ppp authentication chap ! dialer-list 1 protocol ip permit ! Cisco路由器同时支持回拨功能,我们将路由器Router1作为Callback Server,Router2作为Callback Client。 与回拨相关命令: 任务 命令 映射协议地址和电话号码,并在接口上使用在全局模式下定义的PPP回拨的映射类别。 dialer map protocol address name hostname class classname dial-string 设置接口支持PPP回拨 ppp callback accept 在全局模式下为PPP回拨设置映射类别 map-class dialer classname 通过查找注册在dialer map里的主机名来决定回拨. dialer callback-server [username] 设置接口要求PPP回拨 ppp callback request 设置如下: Router1: hostname router1 user router2 password cisco ! isdn switch-type basic-net3 ! interface bri 0 ip address 192.200.10.1 255.255.255.0 encapsulation ppp dialer map ip 192.200.10.2 name router2 class s3 572 dialer load-threshold 80 ppp callback accept ppp multilink dialer-group 1 ppp authentication chap ! map-class dialer s3 dialer callback-server username dialer-list 1 protocol ip permit ! Router2: hostname router2 user router1 password cisco ! isdn switch-type basic-net3 ! interface bri 0 ip address 192.200.10.2 255.255.255.0 encapsulation ppp dialer map ip 192.200.10.1 name router1 571 dialer load-threshold 80 ppp callback request ppp multilink dialer-group 1 ppp authentication chap ! dialer-list 1 protocol ip permit ! 相关调试命令: debug dialer debug isdn event debug isdn q921 debug isdn q931 debug ppp authentication debug ppp error debug ppp negotiation debug ppp packet show dialer show isdn status 举例:执行debug dialer命令观察router2呼叫router1,router1回拨router2的过程. router1#debug dialer router2#ping 192.200.10.1 router1# 00:03:50: %LINK-3-UPDOWN: Interface BRI0:1, changed state to up 00:03:50: BRI0:1:PPP callback Callback server starting to router2 572 00:03:50: BRI0:1: disconnecting call 00:03:50: %LINK-3-UPDOWN: Interface BRI0:1, changed state to down 00:03:50: BRI0:1: disconnecting call 00:03:50: BRI0:1: disconnecting call 00:03:51: %LINK-3-UPDOWN: Interface BRI0:2, changed state to up 00:03:52: callback to router2 already started 00:03:52: BRI0:2: disconnecting call 00:03:52: %LINK-3-UPDOWN: Interface BRI0:2, changed state to down 00:03:52: BRI0:2: disconnecting call 00:03:52: BRI0:2: disconnecting call 00:04:05: : Callback timer expired 00:04:05: BRI0:beginning callback to router2 572 00:04:05: BRI0: Attempting to dial 572 00:04:05: Freeing callback to router2 572 00:04:05: %LINK-3-UPDOWN: Interface BRI0:1, changed state to up 00:04:05: BRI0:1: No callback negotiated 00:04:05: %LINK-3-UPDOWN: Interface Virtual-Access1, changed state to up 00:04:05: dialer Protocol up for Vi1 00:04:06: %LINEPROTO-5-UPDOWN: Line protocol on Interface BRI0:1, changed state to up 00:04:06: %LINEPROTO-5-UPDOWN: Line protocol on Interface Virtual-Access1, chang ed state to up 00:04:11: %ISDN-6-CONNECT: Interface BRI0:1 is now connected to 572 #router1 4. ISDN访问首都在线263网实例: 本地局部网地址为10.0.0.0/24,属于保留地址,通过NAT地址翻译功能,局域网用户可以通过ISDN上263网访问Internet。263的ISDN电话号码为2633,用户为263,口令为263,所涉及的命令如下表: 任务 命令 指定接口通过PPP/IPCP地址协商获得IP地址 ip address negotiated 指定内部和外部端口 ip nat {inside | outside} 使用ppp/pap作认证 ppp authentication pap callin 指定接口属于拨号组1 dialer-group 1 定义拨号组1允许所有IP协议 dialer-list 1 protocol ip permit 设定拨号,号码为2633 dialer string 2633 设定登录263的用户名和口令 ppp pap sent-username 263 password 263 设定默认路由 ip route 0.0.0.0 0.0.0.0 bri 0 设定符合访问列表2的所有源地址被翻译为bri 0所拥有的地址 ip nat inside source list 2 interface bri 0 overload 设定访问列表2,允许所有协议 access-list 2 permit any 具体配置如下: hostname Cisco2503 ! isdn switch-type basic-net3 ! ip subnet-zero no ip domain-lookup ip routing ! interface Ethernet 0 ip address 10.0.0.1 255.255.255.0 ip nat inside no shutdown ! interface Serial 0 shutdown no description no ip address ! interface Serial 1 shutdown no description no ip address ! interface bri 0 ip address negotiated ip nat outside encapsulation ppp ppp authentication pap callin ppp multilink dialer-group 1 dialer hold-queue 10 dialer string 2633 dialer idle-timeout 120 ppp pap sent-username 263 password 263 no cdp enable no ip split-horizon no shutdown ! ip classless ! ! Static Routes ! ip route 0.0.0.0 0.0.0.0 bri 0 ! ! Access Control List 2 ! access-list 2 permit any ! dialer-list 1 protocol ip permit ! ! Dynamic NAT ! ip nat inside source list 2 interface bri 0 overload snmp-server community public ro ! line console 0 exec-timeout 0 0 ! line vty 0 4 ! end 5. Cisco765M通过ISDN拨号上263 由于Cisco765的设置命令与我们常用的Cisco路由器的命令不同,所以以下列举了通过Cisco765上263访问Internet的具体命令行设置步骤。 >set system c765 c765> set multidestination on c765> set switch net3 c765> set ppp multilink on c765> cd lan c765:LAN> set ip routing on c765:LAN> set ip address 10.0.0.1 c765:LAN> set ip netmask 255.0.0.0 c765:LAN> set briding off c765:LAN>cd c765> set user remotenet New user remotenet being created c765:remotenet> set ip routing on c765:remotenet> set bridging off c765:remotenet> set ip framing none c765:remotenet> set ppp clientname 263 c765:remotenet> set ppp password client Enter new Password: 263 Re-Type new Password: 263 c765:remotenet> set ppp authentication out none c765:remotenet> set ip address 0.0.0.0 c765:remotenet> set ip netmask 0.0.0.0 c765:remotenet> set ppp address negotiation local on c765:remotenet> set ip pat on c765:remotenet> set ip route destination 0.0.0.0/0 gateway 0.0.0.0 c765:remotenet> set number 2633 c765:remotenet> set active 命令描述如下: 任务 命令 设置路由器系统名称 set system c765 允许路由器呼叫多个目的地 set multidestination on 设置ISDN交换机类型为NET3 set switch net3 允许点到点间多条通道连接实现负载均衡 set ppp multilink on 关掉桥接 set briding off 建立用户预制文件用于设置拨号连接参数- 可以设置多个用户预制文件用于相同的物理端口对应于不同的连接。 set user remotenet 使用PPP/IPCP set ip framing none 设置上网用户帐号 set ppp clientname 263 设置上网口令 set ppp password client Enter new Password: 263 Re-Type new Password: 263 不用PPP/CHAP或PAP做认证 set ppp authentication out none 允许地址磋商 set ppp address negotiation local on 设置地址翻译 set ip pat on 设置默认路由 set ip route destination 0.0.0.0/0 gateway 0.0.0.0 设置ISP的电话号码 set number 2633 激活用户预制文件 set active   返回目录   六、PSTN   电话网络(PSTN)是目前普及程度最高、成本最低的公用通讯网络,它在网络互连中也有广泛的应用。电话网络的应用一般可分为两种类型,一种是同等级别机构之间以按需拨号(DDR)的方式实现互连,一种是ISP为拨号上网为用户提供的远程访问服务的功能。 1. 远程访问 1.1.Access Server基本设置: 选用Cisco2511作为访问服务器,采用IP地址池动态分配地址.远程工作站使用WIN95拨号网络实现连接。 全局设置: 任务 命令 设置用户名和密码 username username password password 设置用户的IP地址池 ip local pool {default | pool-name low-ip-address [high-ip-address]} 指定地址池的工作方式 ip address-pool [dhcp-proxy-client | local] 基本接口设置命令: 任务 命令 设置封装形式为PPP encapsulation ppp 启动异步口的路由功能 async default routing 设置异步口的PPP工作方式 async mode {dedicated | interactive} 设置用户的IP地址 peer default ip address {ip-address | dhcp | pool [pool-name]} 设置IP地址与Ethernet0相同 ip unnumbered ethernet0 line拨号线设置: 任务 命令 设置modem的工作方式 modem {inout|dialin} 自动配置modem类型 modem autoconfig discovery 设置拨号线的通讯速率 speed speed 设置通讯线路的流控方式 flowcontrol {none | software [lock] [in | out] | hardware [in | out]} 连通后自动执行命令 autocommand command 访问服务器设置如下: Router: hostname Router enable secret 5 $1$EFqU$tYLJLrynNUKzE4bx6fmH// ! interface Ethernet0 ip address 10.111.4.20 255.255.255.0 ! interface Async1 ip unnumbered Ethernet0 encapsulation ppp keepalive 10 async mode interactive peer default ip address pool Cisco2511-Group-142 ! ip local pool Cisco2511-Group-142 10.111.4.21 10.111.4.36 ! line con 0 exec-timeout 0 0 password cisco ! line 1 16 modem InOut modem autoconfigure discovery flowcontrol hardware ! line aux 0 transport input all line vty 0 4 password cisco ! end 相关调试命令: show interface show line 1.2. Access Server通过Tacacs服务器实现安全认证: 使用一台WINDOWS NT服务器作为Tacacs服务器,地址为10.111.4.2,运行Cisco2511随机带的Easy ACS 1.0软件实现用户认证功能. 相关设置: 任务 命令 激活AAA访问控制 aaa new-model 用户登录时默认起用Tacacs+做AAA认证 aaa authentication login default tacacs+ 列表名为no_tacacs使用ENABLE口令做认证 aaa authentication login no_tacacs enable 在运行PPP的串行线上采用Tacacs+做认证 aaa authentication ppp default tacacs+ 由TACACS+服务器授权运行EXEC aaa authorization exec tacacs+ 由TACACS+服务器授权与网络相关的服务请求。 aaa authorization network tacacs+ 为EXEC会话运行记帐.进程开始和结束时发通告给TACACS+服务器。 aaa accounting exec start-stop tacacs+ 为与网络相关的服务需求运行记帐包括SLIP,PPP,PPP NCPs,ARAP等.在进程开始和结束时发通告给TACACS+服务器。 aaa accounting network start-stop tacacs+ 指定Tacacs服务器地址 tacacs-server host 10.111.4.2 在Tacacs+服务器和访问服务器设定共享的关键字,访问服务器和Tacacs+服务器使用这个关键字去加密口令和响应信息。这里使用tac作为关键字。 tacacs-server key tac 访问服务器设置如下: hostname router ! aaa new-model aaa authentication login default tacacs+ aaa authentication login no_tacacs enable aaa authentication ppp default tacacs+ aaa authorization exec tacacs+ aaa authorization network tacacs+ aaa accounting exec start-stop tacacs+ aaa accounting network start-stop tacacs+ enable secret 5 $1$kN4g$CvS4d2.rJzWntCnn/0hvE0 ! interface Ethernet0 ip address 10.111.4.20 255.255.255.0 ! interface Serial0 no ip address shutdown interface Serial1 no ip address shutdown ! interface Group-Async1 ip unnumbered Ethernet0 encapsulation ppp async mode interactive peer default ip address pool Cisco2511-Group-142 no cdp enable group-range 1 16 ! ip local pool Cisco2511-Group-142 10.111.4.21 10.111.4.36 tacacs-server host 10.111.4.2 tacacs-server key tac ! line con 0 exec-timeout 0 0 password cisco login authentication no_tacacs line 1 16 login authentication tacacs modem InOut modem autoconfigure type usr_courier autocommand ppp transport input all stopbits 1 rxspeed 115200 txspeed 115200 flowcontrol hardware line aux 0 transport input all line vty 0 4 password cisco ! end 2. DDR(dial-on-demand routing)实例 此例通过Cisco 2500系列路由器的aux端口实现异步拨号DDR连接。Router1拨号连接到Router2。其中采用PPP/CHAP做安全认证,在Router1中应建立一个用户,以对端路由器主机名作为用户名,即用户名应为Router2。同时在Router2中应建立一个用户,以对端路由器主机名作为用户名,即用户名应为Router1。所建的这两用户的password必须相同。 相关命令如下: 任务 命令 设置路由器与modem的接口指令 chat-script script-name EXPECT SEND EXPECT SEND (etc.) 设置端口在挂断前的等待时间 dialer idle-timeout seconds 设置协议地址与电话号码的映射 dialer map protocol next-hop-address [name hostname] [broadcast] [modem-script modem-regexp] [system-script system-regexp] [dial-string] 设置电话号码 dialer string dial-string 指定在特定线路下路由器默认 使用的chat-script script {dialer|reset} script-name Router1: hostname Router1 ! enable secret 5 $1$QKI7$wXjpFqC74vDAyKBUMallw/ ! username Router2 password cisco chat-script cisco-default "" "AT" TIMEOUT 30 OK "ATDT \T" TIMEOUT 30 CONNECT \c ! interface Ethernet0 ip address 10.0.0.1 255.255.255.0 ! interface Async1 ip address 192.200.10.1 255.255.255.0 encapsulation ppp async default routing async mode dedicated dialer in-band dialer idle-timeout 60 dialer map ip 192.200.10.2 name Router2 modem-script cisco-default 573 dialer-group 1 ppp authentication chap ! ip route 10.0.1.0 255.255.255.0 192.200.10.2 dialer-list 1 protocol ip permit ! line con 0 line aux 0 modem InOut modem autoconfigure discovery flowcontrol hardware Router2: hostname Router2 ! enable secret 5 $1$F6EV$5U8puzNt2/o9g.t56PXHo. ! username Router1 password cisco ! interface Ethernet0 ip address 10.0.1.1 255.255.255.0 ! interface Async1 ip address 192.200.10.2 255.255.255.0 encapsulation ppp async default routing async mode dedicated dialer in-band dialer idle-timeout 60 dialer map ip 192.200.10.1 name Router1 dialer-group 1 ppp authentication chap ! ip route 10.0.0.0 255.255.255.0 192.200.10.1 dialer-list 1 protocol ip permit ! line con 0 line aux 0 modem InOut modem autoconfigure discovery flowcontrol hardware ! 相关调试命令: debug dialer debug ppp authentication debug ppp error debug ppp negotiation debug ppp packet show dialer 3. 异步拨号备份DDN专线: 此例主连接采用DDN专线,备份线路为电话拨号。当DDN专线连接正常时,主端口S0状态为up,line protocol亦为up,则备份线路状态为standby,line protocol为down,此时所有通信均通过主接口进行。当主接口连接发生故障时,端口状态为down,则激活备份接口,完成数据通信。此方法不适合为X.25做备份。因为,配置封装为X.25的接口只要和X.25交换机之间的连接正常其接口及line protocol的状态亦为 up,它并不考虑其它地方需与之通信的路由器的状态如何,所以若本地路由器状态正常,而对方路由器连接即使发生故障,本地也不会激活备份线路。例4将会描述如何为X.25做拨号备份。 以下是相关命令: 任务 命令 指定主线路改变后,次线路状态发生改变的延迟时间 backup delay {enable-delay | never} {disable-delay | never} 指定一个接口作为备份接口 backup interface type number hostname c2522rb ! enable secret 5 $1$J5vn$ceYDe2FwPhrZi6qsIIz6g0 enable password cisco ! username c4700 password 0 cisco ip subnet-zero chat-script cisco-default "" "AT" TIMEOUT 30 OK "ATDT \T" TIMEOUT 30 CONNECT \c chat-script reset atz ! interface Ethernet0 ip address 16.122.51.254 255.255.255.0 no ip mroute-cache ! interface Serial0 backup delay 10 10 backup interface Serial2 ip address 16.250.123.18 255.255.255.252 no ip mroute-cache no fair-queue ! interface Serial1 no ip address no ip mroute-cache shutdown ! interface Serial2 physical-layer async ip address 16.249.123.18 255.255.255.252 encapsulation ppp async mode dedicated dialer in-band dialer idle-timeout 60 dialer map ip 16.249.123.17 name c4700 6825179 dialer-group 1 ppp authentication chap ! interface Serial3 no ip address shutdown no cdp enable ! interface Serial4 no ip address shutdown no cdp enable ! interface Serial5 no ip address no ip mroute-cache shutdown ! interface Serial6 no ip address no ip mroute-cache shutdown ! interface Serial7 no ip address no ip mroute-cache shutdown ! interface Serial8 no ip address no ip mroute-cache shutdown ! interface Serial9 no ip address no ip mroute-cache shutdown ! interface BRI0 no ip address no ip mroute-cache shutdown ! router eigrp 200 network 16.0.0.0 ! ip classless ! dialer-list 1 protocol ip permit ! line con 0 line 2 script dialer cisco-default script reset reset modem InOut modem autoconfigure discovery rxspeed 38400 txspeed 38400 flowcontrol hardware line aux 0 line vty 0 4 password cisco login ! end c2522rb# 4. 异步拨号备份X.25: 设置X.25的拨号备份,首先X.25连接的端口必须运行动态路由协议,异步拨号口必须使用静态路由.本例选择EIGRP作为路由选择协议,将静态路由的Metric的值设置为200,由于EIGRP的默认Metric为90,所以当同时有两条路径通往同一网段时,其中Metric值小的路径生效,而当X.25连接出现问题时,路由器无法通过路由协议学习到路由表,则此时静态路由生效,访问通过拨号端口实现。当X.25连接恢复正常时,路由器又可以学习到路由表,则由于 Metric值的不同,静态路由自动被动态路由所代替,这样就实现了备份的功能。 路由器Router1配置如下: hostname router1 ! enable secret 5 $1$UTvD$99YiY2XsRMxHudcYeHn.Y. enable password cisco ! username router2 password cisco ip subnet-zero chat-script cisco-default "" "AT" TIMEOUT 30 OK "ATDT \T" TIMEOUT 30 CONNECT \c chat-script reset atz interface Ethernet0 ip address 202.96.38.100 255.255.255.0 ! interface Serial0 ip address 202.96.0.1 255.255.255.0 encapsulation x25 x25 address 10112227 x25 htc 16 x25 map ip 202.96.0.2 10112225 broadcast ! interface Serial1 no ip address shutdown ! ! interface Async 1 ip address 202.96.1.1 255.255.255.252 encapsulation ppp dialer in-band dialer idle-timeout 60 dialer map ip 202.96.1.2 name router2 modem-script cisco-default 2113470 dialer-group 1 ppp authentication chap ! router eigrp 200 redistribute connected network 202.96.0.0 ! ip route 202.96.37.0 255.255.255.0 202.96.1.2 200 dialer-list 1 protocol ip permit line con 0 line aux 0 script dialer cisco-default script reset reset modem InOut modem autoconfigure discovery transport input all rxspeed 38400 txspeed 38400 flowcontrol hardware line vty 0 4 password cisco login ! end 路由器Router2配置如下: hostname router2 ! enable secret 5 $1$T4IU$2cIqak8f/E4Ug6dLT0k.J0 enable password cisco ! username router1 password cisco ip subnet-zero chat-script cisco-default "" "AT" TIMEOUT 30 OK "ATDT \T" TIMEOUT 30 CONNECT \c chat-script reset atz ! interface Ethernet0 ip address 202.96.37.100 255.255.255.0 ! interface Serial0 ip address 202.96.0.2 255.255.255.0 no ip mroute-cache encapsulation x25 x25 address 10112225 x25 htc 16 x25 map ip 202.96.0.1 10112227 broadcast ! interface Serial1 no ip address shutdown ! interface Async1 ip address 202.96.1.2 255.255.255.252 encapsulation ppp keepalive 30 async default routing async mode dedicated dialer in-band dialer idle-timeout 60 dialer wait-for-carrier-time 120 dialer map ip 202.96.1.1 name router1 modem-script cisco-default 2113469 dialer-group 1 ppp authentication chap ! router eigrp 200 redistribute static network 202.96.0.0 ! no ip classless ip route 202.96.38.0 255.255.255.0 202.96.1.1 200 dialer-list 1 protocol ip permit ! line con 0 exec-timeout 0 0 line aux 0 script reset reset modem InOut modem autoconfigure discovery transport input all rxspeed 38400 txspeed 38400 flowcontrol hardware line vty 0 4 password cisco login ! end   路由协议: 一、RIP协议   RIP(Routing information Protocol)是应用较早、使用较普遍的内部网关协议(Interior Gateway Protocol,简称IGP),适用于小型同类网络,是典型的距离向量(distance-vector)协议。文档见RFC1058、RFC1723。 RIP通过广播UDP报文来交换路由信息,每30秒发送一次路由信息更新。RIP提供跳跃计数(hop count)作为尺度来衡量路由距离,跳跃计数是一个包到达目标所必须经过的路由器的数目。如果到相同目标有二个不等速或不同带宽的路由器,但跳跃计数相同,则RIP认为两个路由是等距离的。RIP最多支持的跳数为15,即在源和目的网间所要经过的最多路由器的数目为15,跳数16表示不可达。 1. 有关命令 任务 命令 指定使用RIP协议 router rip 指定RIP版本 version {1|2}1 指定与该路由器相连的网络 network network 注:1.Cisco的RIP版本2支持验证、密钥管理、路由汇总、无类域间路由(CIDR)和变长子网掩码(VLSMs) 2. 举例 Router1: router rip version 2 network 192.200.10.0 network 192.20.10.0 ! 相关调试命令: show ip protocol show ip route   返回目录   二、IGRP协议   IGRP (Interior Gateway Routing Protocol)是一种动态距离向量路由协议,它由Cisco公司八十年代中期设计。使用组合用户配置尺度,包括延迟、带宽、可靠性和负载。 缺省情况下,IGRP每90秒发送一次路由更新广播,在3个更新周期内(即270秒),没有从路由中的第一个路由器接收到更新,则宣布路由不可访问。在7个更新周期即630秒后,Cisco IOS 软件从路由表中清除路由。 1. 有关命令 任务 命令 指定使用RIP协议 router igrp autonomous-system1 指定与该路由器相连的网络 network network 指定与该路由器相邻的节点地址 neighbor ip-address 注:1、autonomous-system可以随意建立,并非实际意义上的autonomous-system,但运行IGRP的路由器要想交换路由更新信息其autonomous-system需相同。 2.举例 Router1: router igrp 200 network 192.200.10.0 network 192.20.10.0 ! 三、OSPF协议   OSPF(Open Shortest Path First)是一个内部网关协议(Interior Gateway Protocol,简称IGP),用于在单一自治系统(autonomous system,AS)内决策路由。与RIP相对,OSPF是链路状态路有协议,而RIP是距离向量路由协议。 链路是路由器接口的另一种说法,因此OSPF也称为接口状态路由协议。OSPF通过路由器之间通告网络接口的状态来建立链路状态数据库,生成最短路径树,每个OSPF路由器使用这些最短路径构造路由表。 文档见RFC2178。 1.有关命令 全局设置 任务 命令 指定使用OSPF协议 router ospf process-id1 指定与该路由器相连的网络 network address wildcard-mask area area-id2 指定与该路由器相邻的节点地址 neighbor ip-address 注:1、OSPF路由进程process-id必须指定范围在1-65535,多个OSPF进程可以在同一个路由器上配置,但最好不这样做。多个OSPF进程需要多个OSPF数据库的副本,必须运行多个最短路径算法的副本。process-id只在路由器内部起作用,不同路由器的process-id可以不同。 2、wildcard-mask 是子网掩码的反码, 网络区域ID area-id在0-4294967295内的十进制数,也可以是带有IP地址格式的x.x.x.x。当网络区域ID为0或0.0.0.0时为主干域。不同网络区域的路由器通过主干域学习路由信息。 2.基本配置举例: Router1: interface ethernet 0 ip address 192.1.0.129 255.255.255.192 ! interface serial 0 ip address 192.200.10.5 255.255.255.252 ! router ospf 100 network 192.200.10.4 0.0.0.3 area 0 network 192.1.0.128 0.0.0.63 area 1 ! Router2: interface ethernet 0 ip address 192.1.0.65 255.255.255.192 ! interface serial 0 ip address 192.200.10.6 255.255.255.252 ! router ospf 200 network 192.200.10.4 0.0.0.3 area 0 network 192.1.0.64 0.0.0.63 area 2 ! Router3: interface ethernet 0 ip address 192.1.0.130 255.255.255.192 ! router ospf 300 network 192.1.0.128 0.0.0.63 area 1 ! Router4: interface ethernet 0 ip address 192.1.0.66 255.255.255.192 ! router ospf 400 network 192.1.0.64 0.0.0.63 area 1 ! 相关调试命令: debug ip ospf events debug ip ospf packet show ip ospf show ip ospf database show ip ospf interface show ip ospf neighbor show ip route 3. 使用身份验证 为了安全的原因,我们可以在相同OSPF区域的路由器上启用身份验证的功能,只有经过身份验证的同一区域的路由器才能互相通告路由信息。 在默认情况下OSPF不使用区域验证。通过两种方法可启用身份验证功能,纯文本身份验证和消息摘要(md5)身份验证。纯文本身份验证传送的身份验证口令为纯文本,它会被网络探测器确定,所以不安全,不建议使用。而消息摘要(md5)身份验证在传输身份验证口令前,要对口令进行加密,所以一般建议使用此种方法进行身份验证。 使用身份验证时,区域内所有的路由器接口必须使用相同的身份验证方法。为起用身份验证,必须在路由器接口配置模式下,为区域的每个路由器接口配置口令。 任务 命令 指定身份验证 area area-id authentication [message-digest] 使用纯文本身份验证 ip ospf authentication-key password 使用消息摘要(md5)身份验证 ip ospf message-digest-key keyid md5 key 以下列举两种验证设置的示例,示例的网络分布及地址分配环境与以上基本配置举例相同,只是在Router1和Router2的区域0上使用了身份验证的功能。: 例1.使用纯文本身份验证 Router1: interface ethernet 0 ip address 192.1.0.129 255.255.255.192 ! interface serial 0 ip address 192.200.10.5 255.255.255.252 ip ospf authentication-key cisco ! router ospf 100 network 192.200.10.4 0.0.0.3 area 0 network 192.1.0.128 0.0.0.63 area 1 area 0 authentication ! Router2: interface ethernet 0 ip address 192.1.0.65 255.255.255.192 ! interface serial 0 ip address 192.200.10.6 255.255.255.252 ip ospf authentication-key cisco ! router ospf 200 network 192.200.10.4 0.0.0.3 area 0 network 192.1.0.64 0.0.0.63 area 2 area 0 authentication ! 例2.消息摘要(md5)身份验证: Router1: interface ethernet 0 ip address 192.1.0.129 255.255.255.192 ! interface serial 0 ip address 192.200.10.5 255.255.255.252 ip ospf message-digest-key 1 md5 cisco ! router ospf 100 network 192.200.10.4 0.0.0.3 area 0 network 192.1.0.128 0.0.0.63 area 1 area 0 authentication message-digest ! Router2: interface ethernet 0 ip address 192.1.0.65 255.255.255.192 ! interface serial 0 ip address 192.200.10.6 255.255.255.252 ip ospf message-digest-key 1 md5 cisco ! router ospf 200 network 192.200.10.4 0.0.0.3 area 0 network 192.1.0.64 0.0.0.63 area 2 area 0 authentication message-digest ! 相关调试命令: debug ip ospf adj debug ip ospf events   返回目录   四、重新分配路由   在实际工作中,我们会遇到使用多个IP路由协议的网络。为了使整个网络正常地工作,必须在多个路由协议之间进行成功的路由再分配。 以下列举了OSPF与RIP之间重新分配路由的设置范例: Router1的Serial 0端口和Router2的Serial 0端口运行OSPF,在Router1的Ethernet 0端口运行RIP 2,Router3运行RIP2,Router2有指向Router4的192.168.2.0/24网的静态路由,Router4使用默认静态路由。需要在Router1和Router3之间重新分配OSPF和RIP路由,在Router2上重新分配静态路由和直连的路由。 范例所涉及的命令 任务 命令 重新分配直连的路由 redistribute connected 重新分配静态路由 redistribute static 重新分配ospf路由 redistribute ospf process-id metric metric-value 重新分配rip路由 redistribute rip metric metric-value Router1: interface ethernet 0 ip address 192.168.1.1 255.255.255.0 ! interface serial 0 ip address 192.200.10.5 255.255.255.252 ! router ospf 100 redistribute rip metric 10 network 192.200.10.4 0.0.0.3 area 0 ! router rip version 2 redistribute ospf 100 metric 1 network 192.168.1.0 ! Router2: interface loopback 1 ip address 192.168.3.2 255.255.255.0 ! interface ethernet 0 ip address 192.168.0.2 255.255.255.0 ! interface serial 0 ip address 192.200.10.6 255.255.255.252 ! router ospf 200 redistribute connected subnet redistribute static subnet network 192.200.10.4 0.0.0.3 area 0 ! ip route 192.168.2.0 255.255.255.0 192.168.0.1 ! Router3: interface ethernet 0 ip address 192.168.1.2 255.255.255.0 ! router rip version 2 network 192.168.1.0 ! Router4: interface ethernet 0 ip address 192.168.0.1 255.255.255.0 ! interface ethernet 1 ip address 192.168.2.1 255.255.255.0 ! ip route 0.0.0.0 0.0.0.0 192.168.0.2 !   五、IPX协议设置   IPX协议与IP协议是两种不同的网络层协议,它们的路由协议也不一样,IPX的路由协议不IP的路由协议那样丰富,所以设置起来比较简单。但IPX协议在以太网上运行时必须指定封装形式。 1. 有关命令 启动IPX路由 ipx routing 设置IPX网络及以太网封装形式 ipx network network [encapsulation encapsulation-type]1 指定路由协议,默认为RIP ipx router {eigrp autonomous-system-number | nlsp [tag] | rip} 注:1.network 范围是1 到FFFFFFFD. IPX封装类型列表 接口类型 封装类型 IPX帧类型 Ethernet novell-ether (默认) arpa sap snap Ethernet_802.3 Ethernet_II Ethernet_802.2 Ethernet_Snap Token Ring sap (默认) snap Token-Ring Token-Ring_Snap FDDI snap (默认) sap novell-fddi Fddi_Snap Fddi_802.2 Fddi_Raw 举例: 在此例中,WAN的IPX网络为3a00,Router1所连接的局域网IPX网络号为2a00,在此局域网有一台Novell服务器,IPX网络号也是2a00, 路由器接口的IPX网络号必须与在同一网络的Novell服务器上设置的IPX网络号相同。路由器通过监听SAP来建立已知的服务及自己的网络地址表,并每60秒发送一次自己的SAP表。 Router1: ipx routing interface ethernet 0 ipx network 2a00 encapsulation sap ! interface serial 0 ipx network 3a00 ! ipx router eigrp 10 network 3a00 network 2a00 ! Router2: ipx routing interface ethernet 0 ipx network 2b00 encapsulation sap ! interface serial 0 ipx network 3a00 ! ipx router eigrp 10 network 2b00 network 3a00 ! 相关调试命令: debug ipx packet debug ipx routing debug ipx sap debug ipx spoof debug ipx spx show ipx eigrp interfaces show ipx eigrp neighbors show ipx eigrp topology show ipx interface show ipx route show ipx servers show ipx spx-spoof   五、IPX协议设置   IPX协议与IP协议是两种不同的网络层协议,它们的路由协议也不一样,IPX的路由协议不IP的路由协议那样丰富,所以设置起来比较简单。但IPX协议在以太网上运行时必须指定封装形式。 1. 有关命令 启动IPX路由 ipx routing 设置IPX网络及以太网封装形式 ipx network network [encapsulation encapsulation-type]1 指定路由协议,默认为RIP ipx router {eigrp autonomous-system-number | nlsp [tag] | rip} 注:1.network 范围是1 到FFFFFFFD. IPX封装类型列表 接口类型 封装类型 IPX帧类型 Ethernet novell-ether (默认) arpa sap snap Ethernet_802.3 Ethernet_II Ethernet_802.2 Ethernet_Snap Token Ring sap (默认) snap Token-Ring Token-Ring_Snap FDDI snap (默认) sap novell-fddi Fddi_Snap Fddi_802.2 Fddi_Raw 举例: 在此例中,WAN的IPX网络为3a00,Router1所连接的局域网IPX网络号为2a00,在此局域网有一台Novell服务器,IPX网络号也是2a00, 路由器接口的IPX网络号必须与在同一网络的Novell服务器上设置的IPX网络号相同。路由器通过监听SAP来建立已知的服务及自己的网络地址表,并每60秒发送一次自己的SAP表。 Router1: ipx routing interface ethernet 0 ipx network 2a00 encapsulation sap ! interface serial 0 ipx network 3a00 ! ipx router eigrp 10 network 3a00 network 2a00 ! Router2: ipx routing interface ethernet 0 ipx network 2b00 encapsulation sap ! interface ser

7,785

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧