之前用wxlua写过脚本界面,今天尝试了一下wxWidget的win32版本。
没有界面设计工具怎么行,什么年代了肯定不能纯手工打造界面。
于是找得code:Blocks,开源的,才22M,一用,很牛B,基本上编译器功能全了,基于插件的设计和ECLIPCE一样强大。
但是如果用vs自带的cl编译的话,还要配置很多,设置断点还得用cdb,太麻烦了,我不就是想找一个界面设计的工具么,你给我连编译器都准备好了,过了。window下还是习惯Vs,没办法,房子都是别人建的,在别人房子里还是得守别人的规则。
不过有一点,如果是跨平台的话,用code:Blocks+GCC+wxWidget绝对是强大,而且还能在mac中一样用啊,强大啊强大,汗奔。不过鉴于本人太懒,不想编译gcc版本的wxWidget了,还是先放下这个诱人的工具。
最后尝试开源的,也没什么好选择的,就WxFormBuilder这个东东了。
设计与编码分离,也算是比较不错的选择了,以后做界面就用他了。MFC,win32的东西实在是不想碰,实在是不利于水平的提高,界面也丑死了。
不过wx,几M的dll,也是很蛋疼的。快速开发界面的有木有,有木有,一定要我用脚本来界面么。
设计好界面,做一个继承类,直接加入工程中,以后就界面就交给基类了,改动的话,直接复制过来就好了,我们的部分逻辑在派生的类中进行。
用widget2.9+wXForm3.2做界面时,调试时会报错:
无法解析Sizer::Remove(wxWindow*) ,跟踪进去看发现如下定义
1#if WXWIN_COMPATIBILITY_2_6
2 // Deprecated in 2.6 since historically it does not delete the window,
3 // use Detach instead.
4 wxDEPRECATED( virtual bool Remove( wxWindow *window ) );
5#endif // WXWIN_COMPATIBILITY_2_6 原来这个东东已经过时了,是为了兼容2.6所保留了,由于我用的是2.9,只兼容2.8,由于在生成wx库的时候,没有定义2.6的宏,所以肯定没这没个函数的定义啦。
但是由于wx/setup
#define WXWIN_COMPATIBILITY_2_6 1 里,有如下定义,这样生成库时不兼容2.6,头文件里却定义为1.
改回来:
#define WXWIN_COMPATIBILITY_2_6 0
wxFrom自动生成四个文件
BaseForm.h BaseForm.cpp
AppForm.h AppForm.cpp
全部复制到工程里
然后:
.h
1#pragma once
2#include <wx/wx.h>
3
4class TestWxFrame : public wxApp
5{
6public:
7 TestWxFrame();
8 virtual ~TestWxFrame();
9 virtual bool OnInit();
10
11};
12
13DE CLARE_APP(TestWxFrame) .cpp
1IMPLEMENT_APP(TestWxFrame)
2bool TestWxFrame::OnInit()
3{
4 AppForm*TF = new AppForm((wxWindow*)NULL);
5 TF->Show(true);
6 return true;
7}
8
9 DECLARE_APP()这个不用说了,和MFC一样的,动态声明全局函数wxGetApp()
1#define wxDECLARE_APP(appname) \
2 extern appname& wxGetApp() IMPLEMENT_APP()没什么新意,界面消息等机制就那么一回事,包括XNA,OGRE等的回调机制都是利用多虚性。这个基类A定义好虚函数,在派生类B中重载虚函数如上面的OnInit(),然后再在循环中调用A * = GetApp()得到B类的指针,这样不管B怎么变,只要是A的派生类,重载了一些固有的行为,整个框架都不需要任何改变。(- -!,这也是刚学习MFC时,会被搞晕了的原因,因为所有的细节都被隐藏起来了,更不用说他的消息回调机制了,太过方便了就让人变得蠢,所以不太喜欢微软的东东,越学越成为一个CODE FARMER,不用费脑筋的。不过DX除外)
下面是隐藏的东东,一目了然,把它脱光光一看,就没有之前的欲望啦,原来也是main,原来也是地球人写的代码。
1#define wxIMPLEMENT_APP(appname) \
2 wxIMPLEMENT_WX_THEME_SUPPORT \
3 wxIMPLEMENT_APP_NO_THEMES(appname)
4
5#define wxIMPLEMENT_APP_NO_THEMES(appname) \
6 wxIMPLEMENT_WXWIN_MAIN \
7 wxIMPLEMENT_APP_NO_MAIN(appname)
8
9//:)熟悉的WinMain来了
10#define wxIMPLEMENT_WXWIN_MAIN \
11 extern "C" int WINAPI WinMain(HINSTANCE hInstance, \
12 HINSTANCE hPrevInstance, \
13 wxCmdLineArgType WXUNUSED(lpCmdLine), \
14 int nCmdShow) \
15 { \
16 wxDISABLE_DEBUG_SUPPORT(); \
17 \
18 /**//* NB: We pass NULL in place of lpCmdLine to behave the same as */ \
19 /**//* Borland-specific wWinMain() above. If it becomes needed */ \
20 /**//* to pass lpCmdLine to wxEntry() here, you'll have to fix */ \
21 /**//* wWinMain() above too. */ \
22 return wxEntry(hInstance, hPrevInstance, NULL, nCmdShow); \
23 } \
24 wxIMPLEMENT_WXWIN_MAIN_BORLAND_NONSTANDARD
25
26//<动态定义GetApp()之类的来了
27#define wxIMPLEMENT_APP_NO_MAIN(appname) \
28 wxAppConsole *wxCreateApp() \
29 { \
30 wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, \
31 "your program"); \
32 return new appname; \
33 } \
34 wxAppInitializer \
35 wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp); \
36 appname& wxGetApp() { return *static_cast<appname*>(wxApp::GetInstance()); } \
37 wxDECLARE_APP(appname) 生成图:(比较丑)
不要忘记wx也是有操作系统底层函数的哦,基本上不用用到win32的API,一个wx就可以解决所有问题了。最重要的,他是跨平台的!所以尽量不要用win API.