wxWidgets文件操作(三)wxFileDialog与wxTextCtrl

本人目前的wx环境是Win7下Code::Blocks nightlybuild 7040+MinGW4.5.1+wx2.9.2 SVN 2011-03-12,编译wx的各选项如下:

mingw32-make -f makefile.gcc BUILD=release SHARED=0 MONOLITHIC=1 UNICODE=1 2>errlog.txt

如未经说明,所有有关wx的随笔都是在些环境下。

突然提到这个是因为在本人过去的经历中,也就是在C::B nightly 7040之前,用wxSmith制作界面(如下讨论)后,在wxTextCtrl与wxFileDialog互操作时,很郁闷的发现:

1.界面菜单里的中文以及状态栏里的中文

2.读入到wxTextCtrl里的中文

3.把wxTextCtrl内容写回到文本文件里的中文

三者总有一个或两个出现乱码,不管我如何地刻苦努力,也无济于事。为此曾着实郁闷了一阵子,学习wx的兴趣也因之剧减。但因对wx的“此情不渝”,wx每有一个新的nightly build放出,我都要编译下来试一下。终于,这一个环境下,该问题不再出现。因此,在未发现有新的问题出现之前,本人会在相当长的时间内,一直使用这个环境,不再尝试跟着新的版本跑了。

好了,言归正题。下面的例子主要解决以下几个问题:

1.利用wxSmith生成中文菜单及要注意的问题

2.wxFileDialog的使用

3.在wxTextCtrl与wxFileDialog之间进行读写文件操作,该文件一定要中英文混合,本例中所用到的文件正是本例程源码之一,即wxSmith生成的xxxMain.cpp。

在C::B里wx项目向导下,为工程起名为testcnread,名字很不好,原因是易懂的名字都被我在前些版本下测试上述问题时用完了,创建这个工程时也没指望这个版本下上述问题会消失,所以很随意地起了这样一个名(TestCnRead),将就着点吧~

工程生成后,项目下总共有如下几个文件

testcnreadApp.h

testcnreadMain.h

testcnreadApp.cpp

testcnreadMain.cpp

resource.rc

testcnreadframe.wxs

其中testcnreadframe.wxs是wxSimth界面文件,而testcnreadMain.cpp会在程序运行时被用来测试。

下图是程序运行时的主菜单打开后,鼠标点在"(&X)退出"菜单上时的截图,注意状态栏提示信息。

下面是点击"(&O)打开",然后在弹出的打开文件对话框下选择了上述的testcnreadMain.cpp文件后,wxTextCtrl将该文件内容读入后所显示的截图。

而下图则是点击"(&S)保存"后,将文本框里的内容保存至文件dummy.cpp里:

而下图则是打开保存的文件dummy.cpp看看数据显示是否正确无乱码:

下面一一来说明。

一.wxSmith生成中文界面

利用wxSimth设计器制作中文界面当然很简单,只需记着两点就够了:

1.所有有中文的地方,都需在源代码中(如,本例为testcnreadMain.cpp)将默认的_("blabla")改为wxT("中文的东东"),不然程序编译时会导致断言失败,运行后的界面会乱码;

2.wxSimth界面设计器每更新一次,默认生成的代码部分都会重置,如上面的例子,虽然你已将_("blabla")改为wxT("中文的东东")了。假设后来你又想起什么,或是新添加了一个子菜单或是一个新的按钮等等,保存后wxSmith又会将你已改好的wxT("中文的东东")改为_("中文的东东"),从而又一次导致前面所讲的问题。所以结论是:

1).一开始你只需测试一个中文菜单或按钮项什么的,只要确定是OK,建议用英文菜单就行了;

2).如果你和我一样固执,以为给中国人写的程序就一定得是中文菜单,那么,好好构思你的界面吧,一次完成;

3).如果你是上述2)里的人,同时也和我一样经常改来改去,那么,就不要嫌烦,哪里被wxSmith改回去了,你就再把它改回来。弄多几次自然就知道怎么弄了。

二.wxTextCtrl类的两个重要方法LoadFile和SaveFile

wxTextCtrl::LoadFile是从文件中获取内容:

bool wxTextCtrl::LoadFile ( const wxString & filename, int fileType = wxTEXT_TYPE_ANY ) 
如果文件filename存在,则将文件内容加载到wxTextCtrl里。
参数:
filename 要加载的文件名.
fileType 要加载文件的文件类型,目前该参数被wxTextCtrl所忽略. 
返回值: 操作成功返回true ,失败返回 false. 

也就是说,要将testcnreadMain.cpp里的内容一字不漏地读入到变量名为text1 (wxTextCtrl* text1)的wxTextCtrl里,你只需要下面一行代码:

text1->LoadFile(wxT("testcnreadMain.cpp"));

而SaveFile则是把wxTextCtrl里的内容写入到一文件里:

bool wxTextCtrl::SaveFile ( const wxString & filename = wxEmptyString, int fileType = wxTEXT_TYPE_ANY )   
把wxTextCtrl里的内容保存到文件filename里
参数:
filename 要保存到的文件名.
fileType 要保存文件的文件类型,目前该参数被wxTextCtrl所忽略. 
返回值: 操作成功返回true ,失败返回 false. 

同样的,要将text1里的内容保存到名为dummy.cpp的文件里,你唯一需要的代码就是

text1->SaveFile(wxT("dummy.cpp"));

三.wxFileDialog

使用wxFileDialog类时首先要包含头文件<wx/filedlg.h>

wxFileDialog::wxFileDialog ( wxWindow * parent, 
                                     const wxString & message = wxFileSelectorPromptStr, 
                                     const wxString & defaultDir = wxEmptyString, 
                                     const wxString & defaultFile = wxEmptyString, 
                                     const wxString & wildcard = wxFileSelectorDefaultWildcardStr, 
                                     long style = wxFD_DEFAULT_STYLE, 
                                     const wxPoint & pos = wxDefaultPosition, 
                                     const wxSize & size = wxDefaultSize, 
                                     const wxString & name = wxFileDialogNameStr ) 
构选函数。
用ShowModal() 显示对话框
参数: 
parent 父窗口
message 要显示的提示信息
defaultDir 默认要打开的目录,或为空字符串
defaultFile 要打开的默认文件名,或为空字符串
wildcard 文件扩展名通配符,比如 "*.*" 或 "BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif" 
style 对话框式样. 比如wxFD_OPEN为打开文件对话框,wxFD_FILE_MUST_EXIST则为打开文件对话框时文件必须存在
wxFD_SAVE为保存文件对话框,wxFD_OVERWRITE_PROMPT则为保存文件时如给定的文件已存在,则提示是否要覆盖已存在文件 
pos 对话框位置,未实现 
size 对话框大小,未实现 
name 对话框名称,未实现 

wxFileDialog::ShowModal() 用户点击了OK按钮则返回wxID_OK,不然的话则返回wxID_CANCEL

wxFileDialog::GetPath()、GetPaths()、wxFileDialog::GetFilename()、GetFilenames()其义自明。

下面是本例中通过打开文件对话框,选择源文件(testcnreadMain.cpp)并读入到wxTextCtrl (text1)里的全部代码:

1 #include <wx/filedlg.h>
2
3  void testcnreadFrame::OnOpenFileClick(wxCommandEvent& event)
4 {
5 wxFileDialog dlg(this,wxT("打开C++源程序"),wxT(""),wxT(""),
6 wxT("C++源程序(*.cpp)|*.cpp"),
7 wxFD_OPEN|wxFD_FILE_MUST_EXIST);
8 if(dlg.ShowModal()==wxID_CANCEL)
9 return;
10 text1->LoadFile(dlg.GetPath());
11
12 }

而下面则是打开保存文件对话框,选择要保存的文件名(dummy.cpp),然后将wxTextCtrl里的内容保存到该文件里的全部代码:

1 void testcnreadFrame::OnSaveFileClick(wxCommandEvent& event)
2 {
3 wxFileDialog* dlg=new wxFileDialog(this,wxT("保存C++源文件"),wxT(""),wxT(""),
4 wxT("C++源程序(*.cpp)|*.cpp|文本文件(*.txt)|*.txt"),
5 wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
6 if(dlg->ShowModal()==wxID_CANCEL)
7 return;
8 text1->SaveFile(dlg->GetPath());
9 dlg->Destroy();
10
11 }

注意两次分别演示了在堆上和栈上实例化wxFileDialog的方法。

全部源代码: http://cid-cc918acb2883534f.office.live.com/self.aspx/.Public/testcnread.7z

posted @ 2011-03-18 15:57  高斯山  阅读(6687)  评论(2编辑  收藏  举报