win32程序窗口的创建
尽管Windows应用程序千变万化,令人眼花缭乱,但,消息机制和窗口过程却始终它们的基础,掌握了这两项技术,也就相当于把握住了问题的关键。
如果你以前是C程序员或是MFC的忠实用户,只要你学习过C语言的语法,自己亲手编过一些简短的C程序,理解以下的Win32编程基础也不是一件困难的事。
一个最简单的Win32程序
在以前的C语言编程中,一个最简单的程序可以只有两行。
而要实现同样功能的Windows程序却最少也要写几十行,这并不是说明Windows应用程序效率低下,难于掌握,只是说明程序在Windows环境下有更丰富的内涵。Windows程序的效率其实不低,在所有的Windows应用程序中,都有一个程序初始化的过程,这得用上几十条语句,这段初始化的代码对于任何Windows应用程序而言,都是大同小异的。下面以一个实现最简单功能的程序EasyWin为例,说明Windows程序的基本框架。
打开Visual C++ 6.0。
选择File菜单的New,在出现的对话框中,选择Projects栏目(新建工程),并点取其下的Win32 Application项,表示使用Win32环境创建应用程序。先在Locatin(路径)中填入“c:”,然后在Project Name(项目名称)中填入“EasyWin”,其它按照缺省设置)。单击OK按钮。
再次选择File菜单的New,在出现的对话框中,选择Files栏目(新建文件),并点取其下的C++ Source File项,表示新建一个C++源文件。在右边的File栏中输入“EasyWin”,最后确定让Add to project检查框打上勾 )。单击OK按钮。
在EasyWin.cpp文件中输入以下源程序代码。
程序输入完毕,即可编译执行。在窗口中击鼠标键或按ESC键时,会弹出一个对话框以表示你的操作。
其实,这个程序可以看成是所有Win32应用程序的框架,在以后所有的程序中,你会发现它们都是在这个程序的基础之上再添加代码。
WinMain()函数
WinMain()函数是应用程序开始执行时的入口点,通常也是应用程序结束任务退出时的出口点。它与DOS程序的main()函数起同样的作用,有一点不同的是,WinMain()函数必须带有四个参数,它们是系统传递给它的。WinMain()函数的原型如下:
第一个参数hInstance,是标识该应用程序当前的实例的句柄。它是HINSTANCE类型,HINSTANCE是Handle of Instance的缩写,表示实例的句柄。hInstance是一个很关键的数据,它唯一的代表该应用程序,在后面初始化程序主窗口的过程中需要用到这个参数。
这里有两个概念,一个是实例,一个是句柄。实例代表的是应用程序执行的整个过程和方法,一个应用程序如果没有被执行,只是存在于磁盘上,那么就说它是没有被实例化的;只要一执行,则说该程序的一个实例在运行。句柄,顾名思义,指的是一个对象的把柄。在Windows中,有各种各样的句柄,它们都是32位的指针变量,用来指向该对象所占据的内存区。句柄的使用,可以极大的方便Windows管理其内存中的各种对象。
第二个参数是hPrevInstance,它是用来标识该应用程序的前一个实例句柄。对于基于Win32的应用程序来说,这个参数总是NULL。这是因为在Win95操作系统中,应用程序的每个实例都有各自独立的地址空间,即使同一个应用程序被执行了两次,在内存中也会为它们的每一个实例分配新的内存空间,所以一个应用程序被执行后,不会有前一个实例存在的可能。也就是说,hPrevInstance这个参数是完全没有必要的,只是为了提供与16位Windows的应用程序形式上的兼容性,才保留了这个参数。在以前的16位Windows环境下(如Windows3.2),hPrevInstance用来标识与hInstance相关的应用程序的前一个句柄。
第三个参数是lpCmdLine,是指向应用程序命令行参数字符串的指针。如在Win95的“开始”菜单中单击“运行”,输入“easywin hello”,则此参数指向的字符串为“hello”。
最后一个参数是nCmdShow,是一个用来指定窗口显示方式的整数。这个整数值可以是SW_SHOW、SW_HIDE、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED等,关于这些值的含义,将在下一节说明。
注册窗口类
一个应用程序可以有许多窗口,但只有一个是主窗口,它是与该应用程序的实例句柄唯一关联的。上面的例程中,创建主窗口的函数是InitWindow()。
通常要对填充一个窗口类结构WNDCLASS,然后调用RegisterClass()对该窗口类进行注册。每个窗口都有一些基本的属性,如窗口边框、窗口标题栏文字、窗口大小和位置、鼠标、背景色、处理窗口消息函数的名称等等。注册的过程也就是将这些属性告诉系统,然后再调用CreateWindow()函数创建出窗口。这也就象你去裁缝店订做一件衣服,先要告诉店老板你的身材尺寸、布料颜色、以及你想要的款式,然后他才能为你做出一件让你满意的衣服。
在VC的帮助中,可以看到WNDCLASS结构是这样定义的:
在Win95和WinNT的具有新界面特性的系统中,为了支持新的窗口界面特性,还有一种扩展的窗口类型WNDCLASSEX,它的定义如下:
如果你以前是C程序员或是MFC的忠实用户,只要你学习过C语言的语法,自己亲手编过一些简短的C程序,理解以下的Win32编程基础也不是一件困难的事。
一个最简单的Win32程序
在以前的C语言编程中,一个最简单的程序可以只有两行。
void main(void) { printf "Hello World!"; } |
而要实现同样功能的Windows程序却最少也要写几十行,这并不是说明Windows应用程序效率低下,难于掌握,只是说明程序在Windows环境下有更丰富的内涵。Windows程序的效率其实不低,在所有的Windows应用程序中,都有一个程序初始化的过程,这得用上几十条语句,这段初始化的代码对于任何Windows应用程序而言,都是大同小异的。下面以一个实现最简单功能的程序EasyWin为例,说明Windows程序的基本框架。
打开Visual C++ 6.0。
选择File菜单的New,在出现的对话框中,选择Projects栏目(新建工程),并点取其下的Win32 Application项,表示使用Win32环境创建应用程序。先在Locatin(路径)中填入“c:”,然后在Project Name(项目名称)中填入“EasyWin”,其它按照缺省设置)。单击OK按钮。
再次选择File菜单的New,在出现的对话框中,选择Files栏目(新建文件),并点取其下的C++ Source File项,表示新建一个C++源文件。在右边的File栏中输入“EasyWin”,最后确定让Add to project检查框打上勾 )。单击OK按钮。
在EasyWin.cpp文件中输入以下源程序代码。
//******************************************************************* // 工程:easywin // 文件:easywin.cpp // 内容:一个基本的Win32程序 //******************************************************************* #include <windows.h> #include <windowsx.h> //函数声明 BOOL InitWindow( HINSTANCE hInstance, int nCmdShow ); LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); //******************************************************************* //函数:WinMain() //功能:Win32应用程序入口函数。创建主窗口,处理消息循环 //******************************************************************* int PASCAL WinMain( HINSTANCE hInstance, //当前实例句柄 HINSTANCE hPrevInstance, //前一个实例句柄 LPSTR lpCmdLine, //命令行字符 int nCmdShow) //窗口显示方式 { MSG msg; //创建主窗口 if ( !InitWindow( hInstance, nCmdShow ) ) return FALSE; //进入消息循环: //从该应用程序的消息队列中检取消息,送到消息处理过程, //当检取到WM_QUIT消息时,退出消息循环。 while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } //程序结束 return msg.wParam; } //****************************************************************** //函数:InitWindow() //功能:创建窗口。 //****************************************************************** static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow ) { HWND hwnd; //窗口句柄 WNDCLASS wc; //窗口类结构 //填充窗口类结构 wc.style = CS_VREDRAW | CS_HREDRAW; wc.lpfnWndProc = (WNDPROC)WinProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "EasyWin"; //注册窗口类 RegisterClass( &wc ); //创建主窗口 hwnd = CreateWindow( "EasyWin", //窗口类名称 "一个基本的Win32程序", //窗口标题 WS_OVERLAPPEDWINDOW, //窗口风格,定义为普通型 100, //窗口位置的x坐标 100, //窗口位置的y坐标 400, //窗口的宽度 300, //窗口的高度 NULL, //父窗口句柄 NULL, //菜单句柄 hInstance, //应用程序实例句柄 NULL ); //窗口创建数据指针 if( !hwnd ) return FALSE; //显示并更新窗口 ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); return TRUE; } //****************************************************************** //函数:WinProc() //功能:处理主窗口消息 //****************************************************************** LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { case WM_KEYDOWN://击键消息 switch( wParam ) { case VK_ESCAPE: MessageBox(hWnd,"ESC键按下了!","Keyboard",MB_OK); break; } break; case WM_RBUTTONDOWN://鼠标消息 { MessageBox(hWnd,"鼠标右键按下了!","Mouse",MB_OK); break; } case WM_PAINT://窗口重画消息 { char hello[]="你好,我是EasyWin !"; HDC hdc; PAINTSTRUCT ps; hdc=BeginPaint( hWnd,&ps ); //取得设备环境句柄 SetTextColor(hdc, RGB(0,0,255)); //设置文字颜色 TextOut( hdc, 20, 10, hello, strlen(hello) );//输出文字 EndPaint( hWnd, &ps ); //释放资源 break; } case WM_DESTROY://退出消息 PostQuitMessage( 0 );//调用退出函数 break; } //调用缺省消息处理过程 return DefWindowProc(hWnd, message, wParam, lParam); } |
程序输入完毕,即可编译执行。在窗口中击鼠标键或按ESC键时,会弹出一个对话框以表示你的操作。
其实,这个程序可以看成是所有Win32应用程序的框架,在以后所有的程序中,你会发现它们都是在这个程序的基础之上再添加代码。
WinMain()函数
WinMain()函数是应用程序开始执行时的入口点,通常也是应用程序结束任务退出时的出口点。它与DOS程序的main()函数起同样的作用,有一点不同的是,WinMain()函数必须带有四个参数,它们是系统传递给它的。WinMain()函数的原型如下:
int PASCAL WinMain( HINSTANCE hInstance, //当前实例句柄 HINSTANCE hPrevInstance, //前一个实例句柄 LPSTR lpCmdLine, //命令行字符 int nCmdShow) //窗口显示方式 |
第一个参数hInstance,是标识该应用程序当前的实例的句柄。它是HINSTANCE类型,HINSTANCE是Handle of Instance的缩写,表示实例的句柄。hInstance是一个很关键的数据,它唯一的代表该应用程序,在后面初始化程序主窗口的过程中需要用到这个参数。
这里有两个概念,一个是实例,一个是句柄。实例代表的是应用程序执行的整个过程和方法,一个应用程序如果没有被执行,只是存在于磁盘上,那么就说它是没有被实例化的;只要一执行,则说该程序的一个实例在运行。句柄,顾名思义,指的是一个对象的把柄。在Windows中,有各种各样的句柄,它们都是32位的指针变量,用来指向该对象所占据的内存区。句柄的使用,可以极大的方便Windows管理其内存中的各种对象。
第二个参数是hPrevInstance,它是用来标识该应用程序的前一个实例句柄。对于基于Win32的应用程序来说,这个参数总是NULL。这是因为在Win95操作系统中,应用程序的每个实例都有各自独立的地址空间,即使同一个应用程序被执行了两次,在内存中也会为它们的每一个实例分配新的内存空间,所以一个应用程序被执行后,不会有前一个实例存在的可能。也就是说,hPrevInstance这个参数是完全没有必要的,只是为了提供与16位Windows的应用程序形式上的兼容性,才保留了这个参数。在以前的16位Windows环境下(如Windows3.2),hPrevInstance用来标识与hInstance相关的应用程序的前一个句柄。
第三个参数是lpCmdLine,是指向应用程序命令行参数字符串的指针。如在Win95的“开始”菜单中单击“运行”,输入“easywin hello”,则此参数指向的字符串为“hello”。
最后一个参数是nCmdShow,是一个用来指定窗口显示方式的整数。这个整数值可以是SW_SHOW、SW_HIDE、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED等,关于这些值的含义,将在下一节说明。
注册窗口类
一个应用程序可以有许多窗口,但只有一个是主窗口,它是与该应用程序的实例句柄唯一关联的。上面的例程中,创建主窗口的函数是InitWindow()。
通常要对填充一个窗口类结构WNDCLASS,然后调用RegisterClass()对该窗口类进行注册。每个窗口都有一些基本的属性,如窗口边框、窗口标题栏文字、窗口大小和位置、鼠标、背景色、处理窗口消息函数的名称等等。注册的过程也就是将这些属性告诉系统,然后再调用CreateWindow()函数创建出窗口。这也就象你去裁缝店订做一件衣服,先要告诉店老板你的身材尺寸、布料颜色、以及你想要的款式,然后他才能为你做出一件让你满意的衣服。
在VC的帮助中,可以看到WNDCLASS结构是这样定义的:
typedef struct _WNDCLASS { UINT style; //窗口的风格* WNDPROC lpfnWndProc; //指定窗口的消息处理函数的远指针* int cbClsExtra; //指定分配给窗口类结构之后的额外字节数* int cbWndExtra; //指定分配给窗口实例之后的额外字节数 HANDLE hInstance; //指定窗口过程所对应的实例句柄* HICON hIcon; //指定窗口的图标 HCURSOR hCursor; //指定窗口的鼠标 HBRUSH hbrBackground; //指定窗口的背景画刷 LPCTSTR lpszMenuName; //窗口的菜单资源名称 LPCTSTR lpszClassName; //该窗口类的名称* } WNDCLASS; |
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: 客户端从服务端下载文件的流程分析
- 下一篇: solr.xml文件解析