本系列文章由 莫问 出品,转载请注明出处。
文章链接:http://blog.csdn.net/mni2005/article/details/27228111
作者:莫问(mni2005) 邮箱:mni2005@163.com
本片博文属于Window编程的相关知识,对Windows开发很熟悉的读者可直接无视。
1 创建空项目
1、打开你的vs开发工具,版本你可以随便选择,我这里选择的是MicrosoftVisual studio 2008版本。
2、从菜单栏中依次选择【文件】—【新建】—【项目】菜单项,打开新建项目对话框;在项目类型列表中选择Win32,模板类型选择Win32控制台应用程序,然后输项目名称。如下图所示:
3、点击确定后,会弹出一个向导,继续单击【下一步】,弹出应用程序设置向导,应用程序类型选择Windows应用程序,附加选项选择空项目,如下图所示。
4、单击完成,这样一个空项目便创建成功了。
2 添加入口函数
上面我们创建好了空项目,接下来就需要我们自己添加代码了。按照以下几步就可轻松完成:
1、打开【解决方案资源管理器】,在“源文件”文件夹上右击,从菜单中找到【添加】—【新建项】,打开添加新项对话框,类别选择visual c++,模板选择c++文件,然后输入文件名称,如下图所示:
2、添加完成后,在解决方案的源文件目录下面会出现一个空的TestMain.cpp文件,首先在源文件中包含Windows.h头文件,这个是最基本的。
//包含Windows.h头文件.
#include <windows.h>
接下来在原文件中增加应用程序的入口函数WinMain,学过标准C++的朋友,应该都知道每个应用程序运行时都会先进入入口点函数main,而当从main函数跳出时程序就结束了,在Windows编程里面,也是一样的,只是我们的入口点函数不叫main,而叫WinMain,它的声明形式也是固定死的,不能随便改的,如果忘记了,可以在MSDN中查找一下即可。
//入口函数
int CALLBACKWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
return 0;
}
3、编写完成后,我们编译一下工程,如果能编译通过,则说明我们的项目创建以及代码编写没有问题。
3 创建窗口
用Windows API创建应用程序窗口的过程是固定死的,主要包括下面五个步骤:
(1) 注册窗口
(2) 创建窗口
(3) 处理消息
(4) 显示窗口
(5) 启动消息循环
既然步骤是固定的,那么我们就按照步骤一步步来创建窗口,首先在源文件中增加下面两个全局变量和两个空函数:
HINSTANCE g_windows_instance= 0;
HWND g_windows_hwnd = 0;
LRESULT CALLBACK window_proc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
LRESULT ret=0;
return ret;
}
bool init(unsigned width, unsigned height)
{
return true;
}
我们在init函数中实现注册窗口和创建窗口,这个函数代码有点多,不过很简单,大家可以慢慢看,这里我增加了比较详细的注释,最终完成的函数代码如下:
bool init(unsigned width, unsigned height)
{
WNDCLASS wc;
// 1. 设计i窗口
wc.lpszClassName =TEXT("AGGAppClass"); //注册窗口类名
wc.lpfnWndProc =window_proc; //窗口过程
wc.style =CS_VREDRAW |CS_HREDRAW; //窗口风格
wc.hInstance =g_windows_instance; //应用程序实例
wc.hIcon =LoadIcon(0,IDI_APPLICATION); //应用程序图标
wc.hCursor =LoadCursor(0,IDC_ARROW); //应用程序光标
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//窗口背景
wc.lpszMenuName =NULL; //窗口菜单名
wc.cbClsExtra = 0; //默认
wc.cbWndExtra = 0; //默认
// 1. 注册窗口
if(!RegisterClass(&wc))
{
return 0;
}
// 2. 创建窗口
HWND hwnd= CreateWindow(
TEXT("AGGAppClass"), //类名,要和刚才注册的一致
L"我的应用程序", //窗口标题文字
WS_OVERLAPPEDWINDOW, //窗口外观样式
38, //窗口相对于父级的X坐标
20, //窗口相对于父级的Y坐标
width, //窗口的宽度
height, //窗口的高度
NULL, //没有父窗口,为NULL
NULL, //没有菜单,为NULL
g_windows_instance, //当前应用程序的实例句柄
NULL); //没有附加数据,为NULL
//检查窗口是否创建成功
if(!hwnd)
{
return 0;
}
return true;
}
接下来我实现窗口消息处理的函数,由于我们的窗口什么事情也不需要干,所以这里我们只处理窗口退出的消息,其他消息暂时不管,最终完成的函数代码如下:
// 3. 消息处理
LRESULT CALLBACK window_proc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
LRESULT ret=0;
switch(msg)
{
case WM_CREATE:
{
g_windows_hwnd=hWnd;//保存窗口句柄
}
break;
case WM_PAINT:
{
}
break;
case WM_DESTROY:
{
::PostQuitMessage(0); //窗口退出消息
}
break;
default:
ret = ::DefWindowProc(hWnd,msg,wParam,lParam);
break;
}
return ret;
}
创建窗口的五个步骤,我们已经实现了三步,下来我们再增加一个run函数,完成最后两步。最后完整的run的函数代码如下:
int run()
{
MSG msg;
//4. 显示窗口
ShowWindow(g_windows_hwnd,SW_SHOW|SW_NORMAL);
//5. 消息循环
while(GetMessage(&msg,NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
最后修改一下WinMain函数,去调用我们封装的init和run两个函数,实现最终的窗口创建,修改之后的WinMain函数如下:
//入口函数
int CALLBACKWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_windows_instance =hInstance;
init(400, 400);
run();
return 0;
}
4 创建空项目
最后编译运行下,我们期待已久的窗口就出来,运行截图如下。