一.窗口的创建过程
1.设计窗口类
2.注册窗口类
3.创建窗口
4.显示窗口
#include <windows.h>
//回调函数声明
LRESULT CALLBACK MyProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
//主函数
int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow ) // show state
{
const char clsName[] = "mycls"; //窗口类名称
HWND hFirstWnd; //创建的窗口的句柄
WNDCLASS cls; //wndclass结构体
MSG msg; //消息结构体
//填充wndclass结构体
cls.cbClsExtra= 0;
cls.cbWndExtra= 0;
cls.hbrBackground= HBRUSH( GetStockObject( WHITE_BRUSH ) );
cls.hCursor = LoadCursor( NULL, IDC_ARROW );
cls.hIcon = LoadIcon( NULL, IDI_WARNING );
cls.hInstance = hInstance;
cls.lpfnWndProc= MyProc;
cls.lpszClassName= "mycls";
cls.lpszMenuName= NULL;
cls.style = CS_VREDRAW | CS_HREDRAW;
//注册窗口类
if( !RegisterClass(&cls) )
{
return 0;
}
//创建窗口
hFirstWnd = CreateWindow( clsName, //窗口类名称,必须与注册的窗口类名称一致及与lpszClassName一致
"hello world", //窗口的标题
WS_OVERLAPPEDWINDOW,//窗口的style,是否有最大最小等按钮
CW_USEDEFAULT , //窗口左上角x坐标
CW_USEDEFAULT, //窗口左上角y坐标
CW_USEDEFAULT, //窗口的宽
CW_USEDEFAULT, //窗口的高
NULL, //父窗口
NULL, //菜单menu
hInstance, //实例,与main中一致
NULL); //传递的参数,在窗口创建WM_CREATE的时候传递给msg的lparam
//创建完成后显示窗口
ShowWindow( hFirstWnd, nCmdShow );
//UpdateWindow更新窗口,此时会使客户区域无效,发送WM_PAINT消息,WM_PAINT使区域有效
UpdateWindow(hFirstWnd);
//消息循环
//GetMessage在接收到WM_QUIT消息时,返回0,消息循环结束
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );//转化键盘按键等消息
DispatchMessage( &msg );//分发给相应窗口来处理
}
return msg.wParam;
}
//回调函数的实现
LRESULT CALLBACK MyProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
char *szTmp = "hello world ! !";
switch( uMsg )
{
case WM_PAINT:
hdc = BeginPaint( hwnd, &ps );
GetClientRect( hwnd, &rect );
DrawText( hdc, szTmp, -1,
&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
EndPaint( hwnd, &ps);
return 0;
case WM_CLOSE:
DestroyWindow(hwnd); //destroywindow发送一个WM_DESTROY消息
return 0;
case WM_DESTROY:
PostQuitMessage( 0 ); //postquitmessage发送一个WM_QUIT消息
return 0;
default:
return DefWindowProc( hwnd, uMsg, wParam, lParam );
}
}
二、程序中各类及函数的介绍
1.WNDCLASS介绍
typedef struct {UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS, *pWNDCLASS;
成员:
style:
(1)CS_BYTEALIGNCLIENT:在X轴方向上以某边界值对齐窗口的用户区域,该属性影响窗口的宽度和显示位置的水平坐标。
(2)CS_BYTEALIGNWINDOW:在X轴方向上以某个边界值对齐窗口,该属性影响窗口的宽度和显示位置的水平坐标。
(3)CS_CLASSDC:为窗口分配一个该类的所有窗口都共享的设备描述表。由于窗口类是进程指定的,一个应用中的多个线
程就可能创建属于同一个窗口了的窗口,这些线程也就可以尝试同时使用设备描述表,但此时,系统只
允许一个线程成功完成其图形输出。
(4)CS_DBLCLKS:用户在属于该窗口类的窗口中双击鼠标时将鼠标双击消息发送到窗口处理函数。打开该函数才支持鼠标
双击功能。
(5)CS_DROPSHADOW:Windows XP 中允许窗口的拖拉阴影效果。通过SPI_SETDROPSHADOW打开或关闭该功能。
(6)CS_GLOBALCLASS:将窗口类指定为一个应用全局类,所谓的应用全局类就是在exe或dll中定义的窗口类,加载该exe
或dll的进程都可以创建属于该窗口类的窗口。
(7)CS_HREDRAW:当窗口的水平位置或窗口的宽度值发生变化时,是窗口能够重新绘制其用户区域的内容
(8)CS_NOCLOSE:不能使用窗口菜单中的“关闭”功能
(9)CS_OWNDC:为该类的每个窗口分配独立的设备描述表。
(10)CS_PARENTDC:允许子窗体使用父窗体的设备描述表。
(11)CS_SAVEBITS:当窗口中部分内容被遮挡时,自动保存图像,当被遮挡的区域恢复时,使用自动保存的图形来进行自动恢复。
(12)CS_VREDRAW:当窗口水平方向的宽度变化时重绘整个窗口
lpfnWndProc:
指向窗口过程的指针。必须使用CallWindowProc函数调用窗口过程。
cbClsExtra:
表示窗口类结构之后分配的额外的字节数。系统将该值初始化为0.
cbWndExtra:
表示窗口实例之后分配的额外的字节数。系统将该值初始化为0.如果使用资源文件里的CLASS指令创建对话框,
并用WNDCLASS注册该对话框时,cbWndExtra必须设置成DLGWNDOWEXTRA。
hInstance:
包含该类实例的句柄,该实例包含了窗口过程。
hIcon
类图标的句柄。该成员必须为一个图标资源的句柄。如果hIcon为NULL,系统将提供默认图标。
hCursor
鼠标指针的句柄。改成员必须为一个指针资源的句柄。如果hCursor为NULL,应用程序必须在指针移入应用程序窗口时显式设
置指针类型。
hbrBackground:
背景画刷的句柄。该成员或者是用于绘制背景的物理画刷的句柄,或者是一个颜色值。颜色值必须为如下标准系统颜色值
(值1必须加到选定颜色中)。如果颜色值给定后,必须将该值转换成如下HBRUSH类型。
(1)COLOR_ACTIVEBORDER
(2)COLOR_ACTIVECAPTION
(3)COLOR_APPWORKSPACE
(4)COLOR_BACKGROUND
(5)COLOR_BTNFACE
(6)COLOR_BTNSHADOW
(7)COLOR_BTNTEXT
(8)COLOR_CAPTIONTEXT
(9)COLOR_GRAYTEXT
(10)COLOR_HIGHLIGHT
(11)COLOR_HIGHLIGHTTEXT
(12)COLOR_INACTIVEBORDER
(13)COLOR_INACTIVECAPTION
(14)COLOR_MENU
(15)COLOR_MENUTEXT
(16)COLOR_SCROLLBAR
(17)COLOR_WINDOW
(18)COLOR_WINDOWFRAME
(19)COLOR_WINDOWTEXT
当调用UnregisterClass时,系统自动删除背景画刷。应用程序不应删除这些画刷。
当hbrBackground为NULL时,应用程序必须在绘制客户区域时绘制它自己的背景。为了确定背景是否一定要绘制,应用程
序或者可以处理WM_ERASEBKGND消息,或者测试PAINTSTRUCT的fErase成员。PAINTSTRUCT是由BeginPaint函数填
充的。
lpszMenuName:
指向NULL结束的字符串,该字符串描述菜单的资源名,如同在资源文件里显示的名字一样。若使用一个整数标识菜单,可以
使用MAKEINTRESOURCE宏。如果lpszMenuName为NULL,那么该窗口类的窗口将没有默认菜单。
lpszClassName:
指向NULL结束的字符串,或者是一个原型(atom)。若该参数是一个原型,它必须是一个有先前调用RegisterClass或
者RegisterClassEx函数产生的类原型。类原型必须作为lpszClassName的低字,高字必须为0.若lpszClassName是一个
字符串,它描述了窗口类名。这个类名可以是由RegisterClass或者RegisterClassEx注册的名字,或者是任何预定义的控件
类名。
结构信息
Header在winuser.h声明,包含windows.h
2.消息处理