Windows
操作系统的特征
Windows
操作系统是多任务、图形界面的操作系统。
Windows
拥有一个图形用户界面(
GUI
)。用户可以用键盘和鼠标与显示器上的图形实现直接交互。
Windows
支持多任务操作,可以在同一时刻运行多个程序,并可以在程序间锦绣信息交互。每个程序只能在称为“窗口”的屏幕矩形中实现输出。
Windows
的图形设备接口(
GDI
),实现了程序与设备的无关性,即为
Windows
编写的应用程序可以运行于任何具有
Windows
设备驱动程序的硬件环境中,方便了使用。
API
函数
为使程序员在编写应用程序时实现这些特征
,Windows
提供了一个应用程序编程接口
,
称为
Windows API(Application Progtamming Interface),
这是
Windows
支持的函数定义
,
参数定义和消息格式的集合
,
可供应用程序调用
.
这上千个
API
函数包含了各种窗口类和系统资源
(
内存管理
,
文件
,
线程等等
).
利用这些函数就可以编出具有
Windows
风格的程序
. Windows API
也是
Windows
操作系统自带的在
Windows
环境下运行的软件开发包
(SDK).
程序员总是直接或见解应用
API
进行应用程序的开发
,
所以
Windows
应用程序就有大致相同的用户界面
.
标准
Win32 API
函数分类
:
->
系统服务
->
通用控件库
->
图形设备借口
->
网络服务
->
用户接口
->
系统
Shell
->Windows
系统消息
例如
:
一个对话框的简单
Windows
程序
:
#include <windows.h>
int APIENTRY WinMain ( HINSTANCE hInstance ,
HINSTANCE hPrevInstance ,
LPSTR lpCmdLine ,
Int nCmdShow )
{
MessageBox( NULL , “This is a MessageBox windows Example”,” Title name”, MB_OK );
Return 0;
}
说明
:
<1> windows.h
是
windows
程序最基本的头文件
,
它包含了其他几个
windows
头文件
,
他们定义了
windows
的所以数据类型
,
数据结构
,
符号常量和
API
函数原型声明
.
<2>MessageBox
是一个
API
函数
,
显示一个消息框
.
其中
:
第一个参数指明此消息框的父窗口句柄
,
为
NULL
则说明没有父窗口
;
第二
,
三个参数类型均为字符型指针
,
分别指向消息框中要显示的字符串和消息框标题栏显示的字符串
;
第四个参数是一个无符号整数
,
表明消息框中消息的按钮和风格
.
<3> WinMain
函数是
windows
程序的入口函数
,
包含
4
个参数
:
hInstance
是唯一标识本程序的实例句柄
,
系统和其他应用程序通过该句柄与本程序通讯
.
HPrevInstance
是本程序的前一个实例句柄
,
由于
32
位
windows
采用进程
—
线程模式
,
每个线程拥有自己的句柄
,
因此该参数始终为空
.
LpCmdLine
是一个字符串指针
,
指向命令行参数字符串
,
没有命令行参数时为空
.
NCmdShow
指明程序最初运行时窗口打开方式
,
如正常方式
,
最大化或最小化运行
.
WinMain
返回一个整数侄
,
作为推出代码
.APIENTRY
表示函数调用约定
,
函数调用时参数按从左到右的顺序压入栈
,
又被调用者将参数弹出栈
.
事件与消息
事件
----
在
Windows
环境下
,
应用程序启动后
,
系统等待用户在图形用户界面内的输入选择
,
如鼠标按键
,
键盘按键
,
窗口被创建
,
关闭
,
改变大小
,
移动等
,
对系统来说
.
这都是事件
.
只要有事件发生
,
系统即产生特定的消息
.
消息描述事件的类别
,
包含了相关信息
, Windows
应用程序利用消息与系统及其它应用程序进行信息交换
.
由于
Windows
事件的发生的是随机的
,
程序的执行先后顺序也无法预测
,
系统采用消息队列来存放事件发生的消息
,
然后从消息队列中依次取出消息进行相应的处理
.
消息结构的定义如下
:
typedef struct tagMSG {
HWND hWnd; //
指定消息发向的窗口句柄
UINT message; //
标识消息的消息值
WPARAM wParam; //
消息参数
LPARAM lParam; //
消息参数
DWORD time; //
消息进入队列的时间
POINT pt; //
消息进如对列时鼠标指针的屏幕坐标
}MSG , *PMSG , NEAR *NPMSG , FAR *LPMSG;
message----
是标识消息的消息值或消息名
.
每个消息都有唯一一个数值标识
,
常用不同前缀的符号变量以示区别
.
例如
WM_
表示窗口消息
.
Windows
常用的窗口消息和消息值定义与
winuser.h
中
#define WM_CREATE 0X0001 //
创建窗口产生的消息
#define WM_DESTORY 0X0002 //
撤消窗口产生的消息
#define WM_PAINT 0X000F //
重画窗口产生的消息
#define WM_CLOSE 0X0010 //
关闭窗口产生的消息
#define WM_CHAR 0X0102 //
按下非系统键产生的字符消息
#define WM_USER 0X0400 //
用户自定义消息
wParam,lParam---
消息参数
,
均为
32
位
,
其数据类型在
windef.h
中定义如下
:
typedef UINT WPARAM;
typedef LONG LPARAM;
pt----
表示消息进入消息队列时鼠标指针个屏幕坐标
,
数据类型
POINT
是定义在
windef.h
中的结构体
,
表示屏幕上一点
,
定义如下
:
typedef struct tagPOINT {
LONG x; //
表示点的屏幕横坐标
LONG y; //
表示点的屏幕纵坐标
}POINT T , *PPOINT , NEAR *NPPOINT , FAR *LPPOINT;
常用
windows
数据类型
:
BYTE 8
位无符号字符
PSTR 32
位字符指针
COLORREF 32
位整数
,
表示一个颜色
WORD 16
位无符号整数
LONG 32
位有符号整数
DWORD 32
位无符号整数
UINT 32
位无符号整数
BOOL
布尔值
,
值为
TRUE
或
FALSE
HANDLE
句柄
LPSTR 32
位指针
,
指向字符
LPCSTR 32
位指针
,
指向字符串常量
LPTSTR 32
位指针
,
指向字符串
,
此字符串可移植到
UNICODE
和
DBCS
双字符集
LPCTSTR 32
位指针
,
指向字符串常量
,
此串可移植到
UNICODE
和
DBCS
双字符集
LPVOID 32
位指针
,
可指向任何类型数据
LPRESULT 32
位数值
,
作为窗口函数或
CALLBACK
函数的返回类型
WNDPROC 32
位指针
,
指向一个窗口函数
LPARAM 32
位数值
,
作为窗口函数和
CALLBACK
函数的参数
WPARAM
作为窗口函数和
CALLBACK
函数的参数
,
在
win16
中是
16
位
,
在
win32
中是
32
位
典型的
Windows
程序结构
入口函数中有一个由
while
语句组成的消息循环
,
其中调用了诸如获取消息
,
键盘消息转换
,
派送消息和窗口处理函数等
API
函数
,
循环直到取得退出消息
(WIN_QUIT)
结束
.
在应用程序中还有由操作系统的
API
函数回调
(CALLBACK)
的窗口处理函数
(
简称窗口函数
),
根据消息值转向相应的消息处理
,
这是由
switch
语句组成的多向选择
.
如果不能处理则转缺省的窗口函数
.
例
:
显示一个窗口的
Windows
应用程序
#include <windows.h>
LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM); //
窗口函数声明
Int APIENTRY WinMain( HINSTANCE hInsance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
WNDCLASS wndclass; //
定义窗口类结构变量
HWND hwnd; //
定义窗口句柄
MSG msg; //
定义消息结构变量
/*
定义窗口类的各个属性
*/
wndclass.style = CS_HREDRAW | CS_VREDRAW; //
改变窗口大小则重画
wndclass.lpfnWndProc = WndProc; //
窗口函数为
WndProc
wndclass.cbClsExtra = 0; //
窗口类无扩展
wndclass.cbWndExtra = 0; //
窗口实例无扩展
wndclass.hInstance = hUnstance; //
注册窗口类实例句柄
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATIOB); //
用默认光标
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
//
用箭头光标
wdclass.hbrBackground =
(HBRUSH)GetStockObject(WHITE_BRUSH);
//
背景为白色
wndclass.lpszMenuName = NULL;
//
窗口缺省无菜单
wndclass.lpszClassName = "Ex2_2";
//
窗口类名为
Ex2_2
/*注册窗口类*/
if(! RegisterClass(&wndclass)) return FALSE;
/
*
创建窗口*/
hwnd = CreateWindow("Ex2_2", //
窗口类名
Ex2_2
"Ex2_2", //
窗口名
EX2_2
WS_OVERLAPPEDWINDOW,//
重叠式窗口
CW_USEDEFAULT, CW_USEDEFAULT, //
左上角屏幕坐标
CW_USEDEFAULT, CW_USEDEFAULT, //
宽度和高度
NULL, //
此窗口无父窗口
NULL, //
此窗口无主菜单
hInstance, //
创建此窗口的实例句柄
NULL); //
此窗口无创建参数
/*
显示并更新窗口
*/
ShowWindow(hwnd,nCmdShow); //
显示窗口
UpdateWindow (hwnd); //
更新窗口的客户区
/*
消息循环
*/
//
获取消息,遇
WM_QUIT
退出循环
while(GetMessage (&msg,NULL,0,0)) {
TranslateMessage (&msg); //
键盘消息转换
DispatchMessage (&msg); //
派送消息给窗口函数
}
return msg.wParam; //
返回退出值
}
/*
窗口函数
*/
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam){
//
根据消息值转相应的消息处理
switch (message){
case WM_PAINT: //
重画窗口客户区消息处理
HDC hdc; //
定义设备描述表句柄
PAINTSTRUCT ps; //
定义绘图信息结构变量
hdc = BeginPaint (hwnd,&ps); //
获取要重画的窗口的设备描述表句柄
TextOut (hdc,0,0,"This is my Windows application”, 26); //
输出文本
EndPaint (hwnd,&ps); //
结束要重画的窗口
return 0;
case WM_DESTROY: //
撤消窗口消息处理
PostQuitMessage (0); //
产生退出程序消息
WM_QUIT
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam); //
其它转缺省窗口函数
}
窗口结构类型:
typedef struct tagWNDCLASS {
UINT style; //
窗口风格
WNDPROC lpfnWndProc; //
指向窗口处理函数的函数指针
int cbClsExtra; //
窗口结构中的预留字节数
int cbWndExtra; //
为其它创建窗口预留字节数
HINSTANCE hInstance; //
注册该窗口类的实例句柄
HICON hIcon; //
代表该窗口类的图标句柄
HCURSOR hCursor; //
该窗口客户区鼠标光标句柄
HBRUSH hbrBackGround; //
该窗口背景颜色句柄
LPCSTR lpszMenuName; //
指向窗口菜单名的字符指针
LPCSTR lpszClassName; //
指向窗口名的字符指针
} WNDCLASS, *PWNDCLASS,NEAR *NPWNDCLASS,
FAR *LPWNDCLASS;
绘图信息数据结构定义:
typedef struct tagPAINTSTRUCT{
HDC hdc; //
设备描述表句柄
BOOL fErase; //
布尔值,若背景要重画,则为非
0
,否则为
0
RECT rcPaint; //
指定窗口客户区无效区域
BOOL fRestore; //
保留
BOOL fIncUpdate; //
保留
BYTE rgbReserved[32]; //
保留
}
PAINTSTRUCT
,
* PPAINTSTRUCT,* NPPAINTSTRUCT, *lPPAINTSTRUCT;
DispatchMessage函数
根据消息所包含的信息,将消息派送到相应的窗口函数.