Visual C++ 2012 Express也可以写WinForm程序

来源:互联网 发布:群体ai寻路算法 编辑:程序博客网 时间:2024/06/05 04:14

最近有几位朋友找我,VS 2012的Express版本,在C++/CLR项目中只能编写控制台应用程序,不支持WinForm啊,怎么办?

于是,有人就尝试在CLR的控制台应用程序中编写Windows Forms应用程序,理论上讲嘛,是可以的,不信?你看看下面的代码。

// C++#include "stdafx.h"using namespace System;[STAThreadAttribute]int main(array<System::String ^> ^args){System::Windows::Forms::Form^ mainForm = gcnew System::Windows::Forms::Form();// 窗体大小mainForm->Height=300;mainForm->Width =500;// 窗体标题mainForm -> Text = L"我的主窗口";// 窗口的初始位置mainForm -> StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;// 开始在窗口上的主消息循环并显示窗口System::Windows::Forms::Application::Run(mainForm);    return 0;}


可以说这段代码是没有问题的,运行一下就知道了。

 

程序是运行起来了,但让很多人不高兴,为啥?你认真瞧瞧,它总是会伴随着一个DOS窗口启动,这不太像WinForm,至少要不让那个DOS窗口跑出来。

是啊,这确实有点怪怪的,呵呵。

由于Express版本免费,而且具备了VS的核心功能,对于很多学生,个人或中小型项目来说是完全胜任的,我也一直在用这个版本。其实VS 2012 Express for Desktop在WinForm应用中支持VB和C#,但在C++的CLR项目模板中没有,而上面的方法又解决不了那个DOS窗口,咋办呢?

一时兴起,我在网上搜了一下相关论坛,确实不仅那几位朋友,看来想解决这问题的人还不少呢。

我是有方法解决,只是不知道算不算是最好的方法,反正只代表我个人想法,今天,我想在博客上分享一下,如果你想到更好的方法,你也不妨向大家分享一下。

 

虽然在C++的项目模板中看不到WinForm,但有一个应用模板你一定不陌生——Win 32 应用程序,对吧,我就是拿它来开刀的。

为什么会显示窗口呢?因为入口点是main,大家应该记得,Windows窗体应用程序的入口点是WinMain,是的,这样一说,你可以已经猜到我的解决方法了。

 

原理:在Win 32应用程序中编写托管代码,不管怎么说,其实WinForm就是对Win32的一种封装罢了。

 

好了,我就不多扯了,不然有人说是废话,接下来我们开始吧。

 

启动Visual Studio 2012 Express for Desktop,新建项目,在项目模板中找到Visual C++/Win32 / Win32 项目。

 

输入项目名字,确定。

随后会弹出一个向导,点击下一步。

 

在应用程序类型中选择“Windows应用程序”,在附加选项中勾选“空项目”,然后点击完成。

 

好了,这时候,一个空的Win32 项目已经建好了,不过,不要急着写代码,因为,我们要做一些设置才能编写托管代码。

(1)鼠标右击项目节点,从弹出的快捷菜单中选择【属性】。

 

(2)在项目属性窗口中,依次找到“配置属性- 常观”,在右边的属性设置网格中找到“公共语言运行时支持”,选择“公共语言运行时支持(/clr)”。

记得为debug和release模式也设置一遍。

 

(3)展开“通用属性 - 框架和引用”,添加可能会用到的程序集的引用。

 

单击“确定”按钮,关闭属性窗口。这样,就配置好了,下面就可以编写托管代码了。

 

在解决方案资源管理器中,右击项目节点,从弹出的菜单中选择【添加】-【新建项】,在弹出的窗口中,找到UI节点,在右边窗格中选择“Windows窗体”。

输入名字后单击确定,这时候,我们看到灰常熟悉的窗口设计器,我们可在上面扔控件。

 

双击按钮,编写它的Click事件处理代码。

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) { System::Windows::Forms::MessageBox::Show( L"你选择的日期是:" + this->dateTimePicker1->Value.ToString(L"yyyy年MM月dd日"), L"提示信息", System::Windows::Forms::MessageBoxButtons::OK, System::Windows::Forms::MessageBoxIcon::Information); }


到了现在,窗口做好了,不过啊,还不能运行,我们还有关键的一步,对,入口点。

右击项目节点,从弹出来的菜单中选择【添加】-【新建项】,在 代码 节点下选择C++文件 *.cpp,随便给个名字,确定,我们在这里面写入口点函数。

注意了,我们要的是Windows应用程序,不是DOS控制台,所以我们写的是WinMain函数。首先,要包含Windows.h头文件。

看看,入口点函数如下:

#include <Windows.h>int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd){// ..........return 0;}


这里为什么我用wWinMain而不是WinMain呢?我们来看看WinBase.h中的定义吧。

我们的程序是中文的,应属于Unicode的,所以,最好使用wWinMain函数,它是一个宏,无论如何定义,它最终都是指向WinMain函数。

刚才我们做了一个MainFom窗体,我们要把它所在的头文件包含进来。

#include <Windows.h>#include "MainForm.h"


接着我们在入口点中显示主窗体。完整的代码如下:

#include <Windows.h>#include "MainForm.h"using namespace System::Windows::Forms;int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd){Application::Run(gcnew MyWindowsFormApp::MainForm());return 0;}


注意,创建新实例的时候,在托管C++中要用gcnew。

现在,运行一下,是不是没有了DOS窗口了。

 

好了,看不到DOS窗口了,这样就解决问题了。

 

一些建议:

我们不应该为了用某种语言而用某种语言,WinForm其实也是封装了Win32控件的,所以,有时候应考虑用VB.NET或C#,至少可以提高开发效率,而UI布局也方便了很多,C++可以用于编写一些类库之类的。

在.NET 4之后,许多类库被重写,性能有了本质提升,你看看.NET 4.0 连Logo都换了,这是走向成熟的标志。所以,我建议大家,学到的知识要灵活去应用,不必要为了使用而使用某个语言,最重要的是高效快捷地解决问题就行了,有了技术还得加上技巧的配合才能发挥作用。