4.4. Hello Internet
(配套光盘中提供本节教程的动画版)
本节我们将使用wxWidgets库的网络功能,访问www.d2school.com 提供的网络资源。过程是:在窗口的编辑框内输入姓名,点击既定按钮,程序通过wxWidgets提供的组件,访问“第二学堂”预设的网络链接,获得一句来自互联网的问候语。
请将您的电脑连上因特网。做一个小测试:打开浏览器,在地址栏输入以下内容:
http://www.d2school.com/hello.php?name=丁小明
回车后,正确的情况是,您将在浏览器看到:
“Hello 丁小明! welcome to d2school……”。
4.4.1. 创建项目
首先需要创建一个wxWidgets的框架,和4.1小节的例程相似,除了项目名称改为“HelloInternet”之外,最大的不同在于“wxWidgets projects”项目向导中最后一步,我们需要选中三个附加库模块:
图 84 Hello Internet 需要wxNet模块
4.4.2. 界面设计
完成向导后,Code::Blocks同样会打开默认生成的对话框设计页面。文件名为:“HelloInternetdialog.wxs”。我们将对默认的界面进行改造。
最终改造结果为:
图 85 Hello Internet 最终设计效果
请读者根据前面两小节的内容,自行设计出该界面。以下是几点提示。
第一、 “关于”和“退出”按钮,同样分别来自“About”和“Quit”按钮;
第二、 “Welcome to wxWidgets”标签的“Proportion”为1,而其左边和右边的两个“BoxSizer” “Proportion”均为0。
第三、 “Welcome to wxWidgets”标签的字体(Font)属性被修改了(“宋体”、字符集为“CHINESE_GB2312”、大小为“四号”)。控件的长和宽,都故意被拉大一些。
第四、 对话框的“Title”属性为“Hello Internet”。
4.4.3. 编写代码
双 击设计界面上的“问候”按钮,Code::Blocks将自动为该按钮产生其“OnClick”的事件函数;并且自动切换到代码位 置:HelloInternetMain.cpp文件的底部,不过,请先将位置移到该文件的顶部,我们首先加入本次编写代码需要用到的头文件。
- 包含头文件
#include "HelloInternetMain.h"
#include <wx/msgdlg.h>
013 #include <wx/protocol/http.h>
014 #include <wx/mstream.h>
//(*InternalHeaders(HelloInternetDialog)
<wx/protocol/http.h> 用于引入wxHTTP控件,该文件可以方便地访问一个http协议的网络资源。wxWidgets提供更为简单的wxURL控件,但和wxHTTP相比,它不支持对url中的汉字自动进行必要的编码处理。
〖小提示〗:URL对汉字的转码
打开浏览器,重复做一次本节开始提到的小测试。这一次,在输入url并回车之后,看一眼浏览器的地址栏,它的内容是:
http://www.d2school.com/hello.php?name=%B6%A1%D0%A1%C3%F7
后面的一串%字符,就是对汉字“丁小明”的一种转码。
为了更好的理解本节内容,建议读者学习http协议的基础知识。
从 第二学堂上述url所得到的回复,同样含有汉字,并且采用的是非UNICODE编码的“gb2312”字符集,必须将其转换成UNICODE编码,才有可 能显示在“UNICODE版本的”wxWidgets的图形界面之上,在转换过程中,我们需要用到“wxMemoryOutputStream”,它来自 头文件:<wx/mstream.h> 。
-
- 函数:FromGB2312
请在刚才双击“问候”按钮所产生的“OnButton3Click”函数之前,加入一个用于将gb2312转换到UNICODE。
#117 wxString FromGB2312(wxStreamBuffer const * buf)
{
return wxString ((char const *)buf->GetBufferStart()
, wxCSConv(wxT("gb2312"))
, buf->GetBufferSize());
}
通过wxWidgets,可以非常方便地转换gb2312字符集的字符串至UNICODE编码。代码的具体含义,本章从略。
〖小提示〗:wxWidgets对汉字的支持
表面上看,wxString仅支持对“gb2312”的汉字(上述代码,若将"gb2312"成"gbk",运行时将出现异常),但事实上本例程可以支持一些”gb2312”所不包含的偏僻汉字,比如“镕、旻”等。
-
- 函数:OnButton3Click
最后我们完成OnButton3Click的函数:
#124 void HelloInternetDialog::OnButton3Click(wxCommandEvent& event)
{
wxHTTP http;
//尝试连接网站:
if (!http.Connect(_T("www.d2school.com")))
{
wxMessageBox(_T("连接不上第二学堂!"));
return;
}
//拼装出URL:/hello.php?name=丁小明
wxString url = _T("/hello.php?name=");
url += this->TextCtrl1->GetValue();
//一个HTTP的“输入流”,是指它的从网站返回的内容。
wxInputStream* in = http.GetInputStream(url);
if (!in)
{
wxMessageBox(_T("无法获得指定网址的输入流!"));
return;
}
//将该HTTP返回的内容读入到一个“内存流”中
wxMemoryOutputStream mem;
in->Read(mem);
//读完以后,输入流就可以释放了
delete in;
//将内存流中的内容,转换为UNICODE编码
wxString result = FromGB2312(mem.GetOutputStreamBuffer());
//显示
StaticText1->SetLabel(result);
}
请保存项目。然后编译、运行程序,以下是运行结果:
图 86 Hello Internet 运行结果
由于本项目仍然采用“静态库”,因此,如果您有兴趣,同样可以编译一个Release版,然后“发布”到你的朋友的机器上跑跑看。
白话C++