在Visual Studio上构建C++的GUI框架wxWidgets的开发环境
作者:双子座 发布时间:2023-04-12 01:02:06
本文使用的Unicode+DLL+Debug的方式,因为不想最后生成的exe文件太大。
环境搭建步骤如下:
1、下载wxWidgets包:
登录wxWidgets的下载页面:http://www.wxwidgets.org/downloads
下载最新的Stable Release稳定版,我这里用旧的2.8.12版作演示。
2、将wxMSW-2.8.12.zip解压到D盘根目录下。
转到D:\wxMSW-2.8.12\build\msw目录,用VS2005打开wx.dsw,会有提示转换项目:
选择“全是”。
3、进入到VS2005的界面,在下图所示区域选择DLL Unicode Debug:
4、按F7生成解决方案,这个操作会在D:\wxMSW-2.8.12\lib下生成一个“vc_dll”文件夹,里面是我们需要的dll和lib。
不过第一次执行会提示有一些失败的。因为有一些生成项依赖于其他的生成项。此时继续按F7,直到提示有1个失败。此时,再按F7也是没用的,看看错误提示:
1>LINK : fatal error LNK1104: 无法打开文件“..\..\lib\vc_dll\wxbase28ud_odbc.lib”
这个wxbase28ud_odbc.lib在D:\wxMSW-2.8.12\lib\vc_dll下并不存在。此时可以在上图中选择Unicode Debug,之后在左边选择odbc,右击,选择生成,会在D:\wxMSW-2.8.12\lib\vc_lib目录下生成wxbase28ud_odbc.lib,将这个文件拷到D:\wxMSW-2.8.12\lib\vc_dll目录下,在上图中将选项选回DLL Unicode Debug,再按F7,这样所有的文件都生成了。
这样,在生成了14个dll文件和18个lib文件。
5、在菜单栏依次选择 工具——选项,在打开的窗口依次选择 项目和解决方案——VC++目录。
5.1 在“包含文件”中添加:
D:\wxMSW-2.8.12\include
D:\wxMSW-2.8.12\include\msvc
5.2 在“库文件”中添加:
D:\wxMSW-2.8.12\lib\vc_dll
D:\wxMSW-2.8.12\lib\vc_dll\mswud
如下图:
6、关闭原来的工程,新建一个空的Win32项目,名称为wxTest。注意,要是空的项目。
为这个项目添加一个C++文件Test.cpp,内容为D:\wxMSW-2.8.12\samples\minimal\minimal.cpp的内容。
7、配置项目:
选中这个项目,在菜单栏依次选择 项目——wxTest属性,在打开的窗口配置属性:
7.1 在“配置属性 —— C/C++ —— 预处理器”中的“预处理器定义”添加:
_UNICODE;WXUSINGDLL
7.2 在“配置属性 —— C/C++ —— 运行时库”中的“运行时库”选择:
多线程调试 DLL (/MDd)
7.3 在“配置属性 —— 链接器 —— 输入”中的“附加依赖库”添加:
wxbase28ud.lib
wxbase28ud_net.lib
wxbase28ud_odbc.lib
wxbase28ud_xml.lib
wxexpatd.lib
wxjpegd.lib
wxmsw28ud_adv.lib
wxmsw28ud_aui.lib
wxmsw28ud_core.lib
wxmsw28ud_html.lib
wxmsw28ud_media.lib
wxmsw28ud_qa.lib
wxmsw28ud_richtext.lib
wxmsw28ud_xrc.lib
wxpngd.lib
wxregexud.lib
wxtiffd.lib
wxzlibd.lib
这里是一股脑全加上了。
8、生成解决方案,是成功的。按F5运行这个程序,会提示计算机中丢失wxmsw28ud_core_vc_custom.dll,从D:\wxMSW-2.8.12\lib\vc_dll中把这个文件拷到生成的exe文件所在的目录下。再次运行,会提示丢失wxbase28ud_vc_custom.dll,再把这个文件拷到生成的exe文件所在的目录下。此时再运行就可以正确执行了:
关于wxWidgets控件出现乱码问题的解决
这两天在用wxWidgets做一个小程序,突然遇到了一个控件显示出现乱码的问题。
首先声明:我用的编译器是Visual Studio 2005,wxWidgets版本是2.8.12,下面的解决方法不一定对所有的平台都有效。
我们知道,wxWidgets中控件显示字符串一般都是用wxString,例如下面的一小段代码创建并显示一个按钮:
// 创建一个按钮,显示名称就是“按钮”
wxButton* oneButton = new wxButton( itemFrame1, ID_BUTTON, wxT("按钮"), wxDefaultPosition, wxDefaultSize, 0);
// 把这个按钮放在一个BoxSizer中
itemBoxSizer->Add(oneButton, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
上面的代码没有错误,显示截图如下:
但是,很多情况下,我们想要显示的控件的标签是先放在char *中的,我们当然要先转换成wxString,转换的方法有很多,比如用wxString::FromUTF8(),或者可以定义一个wxString对象,调用Printf方法。然而,两种方法都不行。
如下代码:
char *label = "按钮";
wxString wxLabel;
wxLabel.Printf(wxT("%s"), label);
wxButton* oneButton = new wxButton( itemFrame1, ID_BUTTON, wxLabel, wxDefaultPosition, wxDefaultSize, 0);
itemBoxSizer->Add(oneButton, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
得到的结果是
而如果使用wxString::FromUTF8(),则控件中根本没有显示的标签。
谷歌了很久都没找到解决办法,后来突然想到,以前做一个GTK项目的时候遇到过中文出现乱码的问题,当时峰哥给我发了一个将字符串转换编码的函数,当然,GTK有自带的函数可以进行转换,是g_locale_to_utf8。而wxWidgets貌似没有这样的函数。峰哥给我的函数正好派上用场。
峰哥给我的函数是ANSI与UTF8相互转换,为什么有用,是因为VS默认的编码是ANSI。我今天在谷歌的时候,见到有人说将源代码的编码格式改成UTF8,在VS的 文件——高级保存选项中,我试过了,没用。但是用了峰哥给我的函数,效果就不一样了。
峰哥的代码是:
BOOL ansi_to_utf8(char * lpcszStr, char** lpwszStr)
{
WCHAR* strA;
int i= MultiByteToWideChar(CP_ACP, 0, (char*)lpcszStr, -1, NULL, 0);
strA = (WCHAR *)malloc(sizeof(WCHAR) * i);
MultiByteToWideChar(CP_ACP, 0, (char* )lpcszStr, -1, strA, i*2);
i= WideCharToMultiByte(CP_UTF8, 0, strA, -1, NULL, 0, NULL, NULL);
*lpwszStr = (char *)malloc(i);
WideCharToMultiByte(CP_UTF8, 0, strA, -1, *lpwszStr, i, NULL, NULL);
return TRUE;
}
可以把这段代码放在程序的某个头文件中,作为一个成员函数。别忘了包含windows.h头文件。
再修改上面的第二段代码如下:
char *label = "按钮2";
char *label_utf8;
this->ansi_to_utf8(label, &label_utf8);
wxButton* oneButton = new wxButton( itemFrame1, ID_BUTTON, wxString::FromUTF8(label_utf8), wxDefaultPosition, wxDefaultSize, 0);
free(label_utf8);
itemBoxSizer->Add(oneButton, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
这样就可以正常显示了:
猜你喜欢
- 最近在公司用到外设,需要判断接入的外设的VendorId和ProductId,然后给大家说一下自己的学习成果把 ,首先我门可以通过andro
- 在前面的《基于任务的异步编程模式(TAP)》文章中讲述了.net 4.5框架下的异步操作自我实现方式,实际上,在.net 4.5中部分类已实
- 目录简单介绍具体实现首先,咱们先配置一下相关的jar包(pom.xml)创建一个Pet接口,存放方法say()创建一个Person类创建一个
- 前言上一篇讲了普通轮询、加权轮询的两种实现方式,重点讲了平滑加权轮询算法,并在文末留下了悬念:节点出现分配失败时降低有效权重值;成功时提高有
- 女朋友他们项目用了 spring-boot,以 spring-boot-parent 作为 parent:<parent> &l
- java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类 。在java的世界里,提供了匿名内部类语法,用于帮助大家简化代码,本文
- Android中实现定时器的四种方式第一种方式利用Timer和TimerTask1、继承关系java.util.Timer基本方法sched
- 相对于Swing来说,JavaFX在UI上改善了很多,不仅可以通过FXML来排版布局界面,同时也可以通过CSS样式表来美化UI。其实在开发J
- 我们在开发Java项目的时候,经常需要对参数进行一些必填项、格式、长度等进行校验,如果手写代码对参数校验,每个接口会需要很多低级的代码,这样
- 从Map、JSONObject取不存在键值对时异常1.在Map中取不存在的键值对时不会报异常只会返回null@Test  
- LeetCode -- Path Sum III分析及实现方法题目描述:You are given a binary tree in whi
- 前言 因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没
- IDEA创建一个传统JAVA WEB项目(不使用maven构建)方法一File --> NEW --> Project --&g
- 本来项目是用的viewpager实现的轮播滚动,但是客户觉得轮播的效果太大众化了,于是就要我们改成渐变切换的效果。听到这需求,我最先想到是给
- 前言在使用Mybatis-Plus新增的时候,我们往往想要id随着数据库自增,但是如果不是我们指定id为auto(自增)的话,会通过算法算出
- java 读取本地文件实例详解用javax.xml、w3c解析实例代码:package cn.com.xinli.monitor.utils
- 本文实例讲述了Java中方法名称和泛型相同的用法。分享给大家供大家参考,具体如下:一 点睛Java中,方法的名称可以用泛型替代。二 实战1
- 一.显示、隐藏 jQuery 中显示方法为:.show(),隐藏方法为:.hide()。在无参数的时候,只是硬性的显示内容和隐藏内
- 官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-a
- Task的应用Task的MSDN的描述如下:【Task类的表示单个操作不会返回一个值,通常以异步方式执行。Task对象是一种的中心思想基于任