windows编程(窗口与消息)
来源:互联网 发布:网络购物合同纠纷案例 编辑:程序博客网 时间:2024/06/13 18:17
窗口是屏幕上的矩形区域,消息窗口功能有限,因为我们不能添加四个以上的按钮以及菜单等,而且添加的按钮必须是windows提供的按钮,不能自定义。所以我们有必要自己创建一个多功能可自定义的窗口。
自己的窗口
创建窗口最重要的函数是CreateWindow,它可以创建重叠式窗口,弹出式窗口,子窗口等。而且可以自定义各种功能。
HWND CreateWindow(
LPCTSTR lpClassName, //窗口类
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
从函数原型可以看出创建窗口的各种属性,一种窗口含有显示程序名称的标题列、菜单甚至可能还有工具列和滚动条,另一种窗口是对话框,在上面可以放置各种控件。而这些控件也是窗口,称为子窗口。
窗口消息处理程序
窗口处理函数是理解消息机制的关键,windows处理将消息循环中取得的各种消息放入这个函数中进行处理,该函数会比对各个匹配项直到找到对应的处理项,如果没有找到就传给一个默认的窗口函数,是程序正常结束。该函数可以在程序中也可以在dll中。使用窗口类使多个窗口能够属于同一个窗口类,并使用同一个窗口消息处理函数。
HELLOWIN程序
//===========================
// (c)狗尾草 2008.1.19
//===========================
#include<windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
static TCHAR szAppName[]="HelloWin";
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WndProc;
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,"This program requires windows nt!",szAppName,MB_ICONERROR);
return 0;
}
hWnd=CreateWindow(szAppName,
"The Hello Program!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd,iCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch(message)
{
case WM_CREATE:
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
GetClientRect(hWnd,&rect);
DrawText(hdc,"Hello,WindowsXP!",
-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hWnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
调用的函数和功能如下,绝大多数在winuser.h:
LoadIcon
加载图标供程序使用
LoadCursor
加载鼠标光标供程序使用
GetStockObject
取得一个图形对象
RegisterClass
为程序窗口注册窗口类别
MessageBox
显示消息框
CreateWindow
根据窗口类别建立一个窗口
ShowWindow
在屏幕上显示窗口
UpdateWindow
指示窗口自我更新
GetMessage
从消息队列中取得消息
TranslateMessage
转译某些键盘消息
DispatchMessage
将消息发送给窗口消息处理程序
PlaySound
播放一个声音文件
BeginPaint
开始绘制窗口
GetClientRect
取得窗口显示区域的大小
DrawText
显示字符串
EndPaint
结束绘制窗口
PostQuitMessage
在消息队列中插入一个「退出程序」消息
DefWindowProc
执行内定的消息处理
关于一些常量定义的约定如下:
前缀
类别
CS
窗口类别样式
CW
建立窗口
DT
绘制文字
IDI
图示ID
IDC
游标ID
MB
消息框
SND
声音
WM
窗口消息
WS
窗口样式
常数值是没有必要记忆的,记住常量的一些大写标识符就可以了。
各种句柄
标识符
含义
HINSTANCE
执行实体(程序自身)句柄
HWND
窗口句柄
HDC
设备内容句柄
句柄通常是调用函数取得的,起到一个标识身份的目的。其实实质是一个32位整数。
数据结构注解
窗口类结构
typedef struct {
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;
窗口是根据窗口类建立的,窗口类相当于一个模板。他定义了各种属性,定义后打造出来的窗口就是他定义的那个样子了。如果窗口类没有定义完全,注册的时候就会失败,我在写的过程中漏写了几个属性导致这样的错误
该消息是在注册的时候发生的。
Msg数据结构
ttypedef struct tagMSG { HWND hwnd ; UINT message ; WPARAM wParam ; LPARAM lParam ; DWORD time ; POINT pt ; } MSG, * PMSG ;
从消息队列中取得的消息来填充各个属性。
Point数据结构
typedef struct tagPOINT { LONG x ; LONG y ; } POINT, * PPOINT
存放该消息时的鼠标坐标。
建立窗口
HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
其中的大部分参数都可以猜出意思,最后一个参数有必要解释一下,是用来传递额外的数据的,这里并没有用到就设为NULL了。该函数返回一个窗口句柄,用来唯一表示一个窗口的。这样其他函数才知道作用在哪个窗口上。
建立窗口后调用ShowWindow (hwnd, iCmdShow)来显示窗口,第二个参数是初始的显示方式。UpdateWindow (hwnd)是用来重画窗口的。
消息循环
while(GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ; }
消息循环功能是将事件转换为消息并给处理函数处理。TranslateMessage用来解释消息,DispatchMessage用来投递给消息处理函数,非常神奇的一个函数。
WM_PAINT消息
显示区域无效时才产生WM_PAINT消息,遮盖后重新要求显示,此时为无效。当然改变窗口大小也为无效。
关于程序的结束
当WM_DESTROY消息收到后执行PostQuiteMessage产生WM_QUITE消息,这样该消息GetMessage()时返回的是0,导致消息循环结束。WinMain函数继续执行,这个例子中是返回并结束程序。从这里我可以想象到,windows程序主要是消息循环和消息处理函数的交互。除此之外的都是一些设置和初始化等事务性的例程。
- windows编程(窗口与消息)
- Windows核心编程笔记(二十) 窗口与消息
- windows窗口与消息
- Windows 窗口与消息
- windows编程——窗口与消息1
- windows编程——窗口与消息2
- windows编程学习笔记(1)创建窗口与消息循环
- Windows核心编程笔记(二十) 窗口与消息2
- windows程序设计--窗口与消息
- programming windows-----窗口与消息
- Windows程序设计--窗口与消息
- 2013.8.3 学习笔记《windows核心编程》(七) 窗口类,窗口显示更新与消息
- Windows消息:如何自定义窗口消息与线程消息
- Windows消息:如何自定义窗口消息与线程消息
- 《Windows程序设计》读书笔记之窗口与消息
- 窗口破坏过程与Windows消息循环
- 窗口破坏过程与Windows消息循环
- 窗口破坏过程与Windows消息循环
- 各个编程语言经典书籍(转)
- SVN 全局忽略设置
- 数字图像处理--空间变换
- ubuntu apt-get apt-cache 报错 error
- --灵活的java泛型应用
- windows编程(窗口与消息)
- UITableView的移动、删除操作
- 交流文档的重要性
- 匹配网页编码格式的正则表达式
- iphone程序启动互相调用
- 交叉编译工具安装——s3c6410
- Oracle 数据库导出
- Android新手入门的十個問題!
- 【笔试面试知识点查缺补漏深入理解之C与C++篇】C/C++语言中的sizeof 深入理解