分享
 
 
 

如何创建原生的窗口程序

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

如何创建原生的窗口程序

如何创建原生的窗口程序现在用的已经不多了,因为现在的RAD工具普遍都是,用不着费尽心思去考虑那些窗口创建的细节,的确,一般不会有人会首先想到会用比较原始的方法来构建一般的窗口,可当你知道了那些原始的方法对你却是大大有好处的,我就深有体会,比如:用RAD开发工具创建的窗口往往是非常标准的,你如果想要创建一些特殊的窗口,那么就得更改你已创建的窗口,这时仍然要求你对如何创建原生窗口有所了解,何况当你知道了如何创建原生的窗口程序后,你会感觉到窗口原来还可以这样构建,同时你也会学到如何通过控制窗口的样式来更改窗口的风格等等。好了,下面我就来介绍一下如何创建原生的窗口程序,我使用的工具是Borland C++ Builder,也许和你们一样,也属于快速开发工具.

1、启动C++Builder(不在乎你的版本)新建一控制台程序,

2、在弹出的对话框中请确信只有C++ Radio Button被选中,如图:

3、单击OK按钮你将看到如下代码

#include <vcl.h>

#include <windows.h>

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

return 0;

}

其中WinMain函数是窗口程序的入口函数,就想C或C++中的main函数一样,唯一不同的是C或C++的main函数的参数是可选的,而WinMain函数的参数是固定的,这也是你的程序和操作系统交换信息的地方。这几个参数表示如下:

第一个参数hInstance 表示你写的应用程序的句柄即标志

第二个参数hPrevInstance表示的是你程序的前一个实例句柄,条件是要有你程序的前一个实例在运行,如果没有的话,你可以忽略该参数。

第三个参数lpCmdLine是一个字符串,它主要的用途是相应命令行的命令,如你可能会用命令行的方式来编译程序

第四个参数nCmdShow控制你程序创建的窗口的显示

以上只是介绍了WinMain函数的参数而已,这才是创建原生窗口程序的开始,下面还有一些几乎固定的步骤来完成创建原生窗口程序的创建,步骤如下:

1、注册你要创建窗口的窗口类

2、根据注册的窗口类来创建并显示显示窗口

3、处理消息循环

注册你要创建窗口的窗口类

Win32提供了WNDCLASS 和 WNDCLASSEX类(其实都是结构体)可供我们使用,你只要用其中的一个就可以了,它们的定义如下:

typedef struct _WNDCLASS {

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HINSTANCE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCTSTR lpszMenuName;

LPCTSTR lpszClassName;

} WNDCLASS, *PW

typedef struct _WNDCLASSEX {

UINT cbSize;

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HINSTANCE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCTSTR lpszMenuName;

LPCTSTR lpszClassName;

HICON hIconSm;

} WNDCLASSEX, *PWNDCLASSEX;

在注册窗口类之前应该先初始化窗口类的实例,这时我们的任务就是如何来完成WNDCLASSEX 实例的初始化,如果完成了这一步,后面的事情就变得简单了。好了,下面我们就根据WNDCLASSEX的结构来一一构建窗口类

代码如下:

WNDCLASSEX WndClsEx;

WndClsEx.cbSize = sizeof(WNDCLASSEX);

WndClsEx.style = CS_HREDRAW | CS_VREDRAW;

WndClsEx.lpfnWndProc = WndProcedure;

WndClsEx.cbClsExtra = 0;

WndClsEx.cbWndExtra = 0;

WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);

WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);

WndClsEx.hbrBackground = GetStockObject(WHITE_BRUSH);

WndClsEx.lpszMenuName = NULL;

WndClsEx.lpszClassName = ClsName;//窗口类名的常量

WndClsEx.hInstance = hInstance;

WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

这段代码中大部分的参数你可以参照MSDN来设置,我要说明一下的是以下几个方面

WndProcedure 为窗口的回调函数,主要用来处理窗口消息:

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)

{

switch(Msg)

{

case WM_DESTROY:

PostQuitMessage(WM_QUIT);

break;

default:

//将不处理的消息交由系统来处理

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

return 0;

}

除了WndProcedure回调函数以外,还调用了LoadIcon(),LoadCursor(),GetStockObject()等API函数来完成窗口图标,小图标,鼠标,背景颜色的设置,关于函数你可以参考MSDN来调用,同时还自定义了一些常数如:ClsName等

完成了以上步骤后现在的程序代码如下:

#include <vcl.h>

#include <windows.h>

#pragma hdrstop

//定义两个产量用来表示窗口类名和窗口名称

const char *ClsName = "窗口类名";

const char *WndName = "窗口名称";

//窗口的回调函数,用来处理窗口消息

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)

{

switch(Msg)

{

case WM_DESTROY:

PostQuitMessage(WM_QUIT);

break;

default:

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

return 0;

}

//---------------------------------------------------------------------------

#pragma argsused

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

WNDCLASSEX WndClsEx;

WndClsEx.cbSize = sizeof(WNDCLASSEX);

WndClsEx.style = CS_HREDRAW | CS_VREDRAW;

WndClsEx.lpfnWndProc = WndProcedure;

WndClsEx.cbClsExtra = 0;

WndClsEx.cbWndExtra = 0;

WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);

WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);

WndClsEx.hbrBackground = GetStockObject(WHITE_BRUSH);

WndClsEx.lpszMenuName = NULL;

WndClsEx.lpszClassName = "窗口窗名称";

WndClsEx.hInstance = hInstance;

WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

return 0;

}

注册程序窗口

这测程序窗口很简单,只是简单的调用RegisterClassEx(&WndClsEx)函数即可完成,RegisterClassEx函数的参数即为上面定义的窗口类,代码如下:

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

WNDCLASSEX WndClsEx;

。。。。。。

RegisterClassEx(&WndClsEx);

return 0;

}

创建并显示窗口

创建窗口也很简单,只是调用CreateWindow函数就可搞定,只是如果你还想在你的程序中使用你创建的窗口的话,你应该设置一个用来保存窗口的窗口句柄,代码如下:

WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

{

HWND hWnd;

WNDCLASSEX WndClsEx;

. . .

RegisterClassEx(&WndClsEx);

hWnd = CreateWindow(

ClsName,

WndName,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL);

if( !hWnd )return 0; //如果窗口创建失败的话则退出程序

//显示所创建的窗口

ShowWindow(hWnd, SW_SHOWNORMAL);

UpdateWindow(hWnd);

}

这样就完成了窗口的创建和显示了,可是当我们去运行程序时却发现我们创建的窗口一闪而过,程序马上就结束了,这不是我们需要的,如何解决这个问题呢,其实,上面我也已经说了,还有一个步骤没有完成嘛,那就时消息循环,只有建立了消息循环以后,程序窗口才不会消失,原因很简单,因为程序一直处于循环之中,它就始终没有结束,所以我们创建的窗口也就不会显示了。

处理消息循环:

消息循环的处理主要是用到了GetMessage,TranslateMessage 和DispatchMessage这三个API函数,GetMessage的作用是取得程序的消息队列中取得窗口消息,TranslateMessage函数的作用是处理GetMessage函数取得的消息的格式以致于能够被应用程序识别,DispatchMessage函数的作用是将处理后的消息分派给应用程序,他们的函数原型可以参考MSDN,那儿由详细的介绍。

//处理消息循环

while( GetMessage(&Msg, NULL, 0, 0) )

{

TranslateMessage(&Msg);

DispatchMessage(&Msg);

}

只有这样,我们的窗口才不会消失,窗口程序才不会结束,可是问题又来了,你说程序不会结束,当我只要一点击关闭按钮程序马上就结束了,这不是与你说的又矛盾吗,其实,并没有矛盾,当你点击窗口的关闭按钮时程序将受到WM_DESTROY消息,而我们又在窗口的回调函数WndProcedure中对它进行了处理,即调用PostQuitMessage(WM_QUIT)函数来结束程序,这个过程之所以会发生就在于每次当程序的窗口受到窗口消息时都会调用它的回调函数来进行处理,只是这儿的处理方式是当受到WM_DESTROY消息时结束程序而已。你可以将处理WM_DESTROY消息的代码注释掉,你看看程序还会不会结束!我的测试结果时它只是关闭了窗口,程序并没有结束,你还可以在任务管理其中看到它!

上面的言语只是简单的表达了如何创建一个原生的窗口程序而已,其实那里面还又很多东西要学,如在说处理消息循环时的消息队列,Window 是如何来处理这些消息的等等,这要求读者在以后的学习中慢慢体会,学习!如果你对本程序感兴趣的话可以到http://www.zccfamily.com/zqget/ 网站下载该程序来测试一笑效果.!如果有什么问题的话还可以和我联系,我的Email:zqget123@sina.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有