资源描述
个人收集整理 勿做商业用途
WINDOWS核心编程--—-窗口创建 1
一、创建窗口 1
二、窗口类附加数据缓冲区 2
三、窗口附加数据缓冲区 3
四、显示窗口 6
五、消息循环 6
六、Windows常用消息 7
windows核心编程----窗口创建
一、创建窗口
windows经典机制:回调、钩子;
回调(理解):自己定义的函数,自己不掉用,交给别人调用。
钩子:优先勾取消息的权限,木马程序等。
window经典窗口程序-—-—--创建窗口并加入消息循环
// WinCreate。cpp : Defines the entry point for the application.
//
#include ”stdafx。h”
HINSTANCE g_hinstance = 0;//接收winMain的参数
//消息处理函数
//windows 经典机制
LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
switch(nMsg)
{
case WM_DESTROY:
PostQuitMessage(0);//能够使GetMessage函数返回0
break;
}
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
//注册窗口类
BOOL Register (LPSTR lpClassName,WNDPROC wndProc)
{
WNDCLASSEX wce = {0};
wce。cbSize = sizeof(wce);
wce.cbClsExtra = 0;
wce。cbWndExtra = 0;
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce.hInstance = g_hinstance;
wce.lpfnWndProc = wndProc;
wce。lpszClassName = lpClassName;
wce.lpszMenuName = NULL;
wce。style = CS_HREDRAW | CS_VREDRAW;
ATOM nAtom = RegisterClassEx(&wce);
//返回0代表注册失败
if (nAtom == 0)
{
return false;
}
return true;
}
//创建主窗口
HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName)
{
HWND hWnd = CreateWindowEx(0,/*扩展风格*/
lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hinstance,NULL);
return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
}
//消息循环
void Message()
{
MSG nMsg = {0};
while(GetMessage(&nMsg,NULL,0,0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
hInstance = g_hinstance;
if( !Register(”Main",WndProc) )
{
MessageBox(NULL,"注册失败","Infor",MB_OK);
return 0;
}
HWND hWnd = CreateMain("Main”,"window”);
Display(hWnd);
Message();
return 0;
}
二、窗口类附加数据缓冲区
缓冲区
int a;//这句话开了一个4字节的缓冲区
a = 10;//这句话给缓冲区赋值
printf(“%d”,a);//从缓冲区读取数据
使用步骤:
1申请缓冲区
int cbClsExtra //一般是4的倍数。例如 200
2 向缓冲区中写入数据
SetClassLong ()//利用次函数向窗口附加缓冲区写入数据、
3 从缓冲区中读取数据
GetClassLong()//
SetClassLong和GetClassLong函数原型
DWORD SetClassLong(
HWND hWnd, // handle to window 窗口句柄
int nIndex, // index of value to change 字节索引号,指的是从哪个字节开始存数据
LONG dwNewLong // new value 存入的数据
);
DWORD GetClassLong(
HWND hWnd, // handle to window
int nIndex // offset of value to retrieve 字节索引号,从哪个字节开始读取数据
);//返回值获取读取到的数据
三、窗口附加数据缓冲区
使用步骤:
1 申请缓冲区
int cbWndExtra //一般是4的倍数
2 向缓冲区中写入数据
SetWindowLong
3 读取
GetWindowLong
SetWindowLong 和 GetWindowLong
LONG SetWindowLong(
HWND hWnd, // handle to window 窗口句柄
int nIndex, // offset of value to set 字节索引号
LONG dwNewLong // new value 存入的数据
);
LONG GetWindowLong(
HWND hWnd, // handle to window 窗口句柄
int nIndex // offset of value to retrieve 字节索引号
);//返回值获取 读取到的数据
区别:
窗口类附加数据缓冲区:基于同一个窗口类创建出来的所有窗口共享的缓冲区。
窗口附加缓冲区:窗口自己私有的缓冲去,即便是基于同一个窗口类创建的窗口,相互之间也不共享。
例子:
// WinCreate.cpp : Defines the entry point for the application.
//
#include ”stdafx.h"
HINSTANCE g_hinstance = 0;//接收winMain的参数
//消息处理函数
//windows 经典机制
LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
switch(nMsg)
{
case WM_DESTROY:
PostQuitMessage(0);//能够使GetMessage函数返回0
break;
}
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
//注册窗口类
BOOL Register (LPSTR lpClassName,WNDPROC wndProc)
{
WNDCLASSEX wce = {0};
wce.cbSize = sizeof(wce);
wce.cbClsExtra = 200;
wce.cbWndExtra = 200;
wce。hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce。hInstance = g_hinstance;
wce.lpfnWndProc = wndProc;
wce。lpszClassName = lpClassName;
wce。lpszMenuName = NULL;
wce。style = CS_HREDRAW | CS_VREDRAW;
ATOM nAtom = RegisterClassEx(&wce);
//返回0代表注册失败
if (nAtom == 0)
{
return false;
}
return true;
}
//创建主窗口
HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName)
{
HWND hWnd = CreateWindowEx(0,/*扩展风格*/
lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hinstance,NULL);
return hWnd;
}
//创建子窗口
HWND CreateChild(LPSTR lpClassName,LPSTR lpWndName,HWND hWndParent)
{
HWND hChild = CreateWindowEx(0,lpClassName,lpWndName,
WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,100,100,200,200,
hWndParent,NULL,g_hinstance,NULL);
return hChild;
}
//显示窗口
void Display(HWND hWnd)
{
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
}
//消息循环
void Message()
{
MSG nMsg = {0};
while(GetMessage(&nMsg,NULL,0,0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
//设置窗口类、窗口附加缓冲区示例
void SetExtra(HWND hWnd)
{
SetClassLong(hWnd,0,123456789);
SetWindowLong(hWnd,0,987654321);
}
//获取窗口类、窗口附加缓冲区示例
void GetExra(HWND hWnd)
{
LONG nClass = GetClassLong(hWnd,0);
LONG nWnd = GetWindowLong(hWnd,0);
CHAR szText[256] = {0};
sprintf(szText,"窗口类:%d,窗口:%d",nClass,nWnd);
MessageBox(NULL,szText,"Infor”,MB_OK);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
hInstance = g_hinstance;
if( !Register("Main”,WndProc) )
{
MessageBox(NULL,”注册失败”,"Infor",MB_OK);
return 0;
}
HWND hWnd = CreateMain("Main”,"window");
Register(”Child”,DefWindowProc);
HWND hWnd1 = CreateChild("child”,"ch1”,hWnd);
HWND hWnd2 = CreateChild("child”,"ch2”,hWnd);
//HWND hWnd2 = CreateChild("CHILD2","Child2",hWnd);
MoveWindow(hWnd1,300,100,200,200,TRUE);
MoveWindow(hWnd2,500,100,200,200,TRUE);
Display(hWnd);
SetExtra(hWnd1);
GetExra(hWnd2);
Message();
return 0;
}
四、显示窗口
ShowWindow(hWnd,SW_SHOW)
{
hWndà保存窗口数据的内存à按照读取到的数据将窗口绘制在显卡.
}
五、消息循环
1.过程驱动
程序的执行过程是按照预定好的顺序执行。注:多见于单片机
2.事件驱动
程序的执行是无序,用户可以根据需要随机出发相应的事件。
3.Win32窗口程序就是采用事件驱动方式执行,也就是消息机制.
4.当系统通知窗口工作时,就采用消息的方式派发给窗口。
派发者:DispatchMessage()函数,派发给窗口处理函数。
5.消息组成
窗口句柄: 标识消息是属于哪个窗口
消息ID: 标识消息的ID
消息的两个参数: 根据消息不同,参数也不同
消息产生的时间:
消息产生时的鼠标位置:
6.MSG结构体
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;
//把消息的6部分接收
7.窗口处理函数原型
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
u 每个窗口都必须具有窗口处理函数。
u 当系统通知窗口时,会调用窗口处理函数(由DispatchMessage()调用)。同时,将消息ID和消息参数传递给窗口处理函数。
DispatchMessage调用窗口处理函数过程伪代码:
DispatchMessage(&nMsg)
{
1。nMsg.hWnd—à保存窗口数据的内存à得到窗口类名称;
2.根据得到的窗口类名称,到操作系统中匹配窗口类名称;
3.根据匹配到的内存,找到窗口处理函数的地址;
4.调用窗口类中保存的函数;
…
WndProc(nMsg。hWnd,nMsg。message,nMsg.wParam,nMsg.lParam)
}
DispatchMessage函数原型
LRESULT DispatchMessage(
CONST MSG *lpmsg // message information
);
u 在窗口处理函数中,不处理的消息,使用缺省窗口处理函数,例如
DefWindowProc。
8.GetMessage –获取消息
函数作用、参数、返回值分析
BOOL GetMessage(
LPMSG lpMsg, // message information 存放获取到的消息buffer
HWND hWnd, // handle to window 窗口句柄
UINT wMsgFilterMin, // first message获取消息的最小ID 0
UINT wMsgFilterMax // last message 获取消息的最大ID 0
);
//返回值 只要是WM_QUIT,返回值得就是0,其他的都是非0。
//后三个参数限制得到的消息,hWnd限定是否本进程的hWnd窗口、wMsgFilterMin和wMsgFilterMax是对ID的限制
9.TranslateMessage
BOOL TranslateMessage(
CONST MSG *lpMsg // message information 要翻译的消息地址
); //只翻译键盘中可见字符
六、Windows常用消息
如何学习消息:
a) 什么时候产生消息
b) 这个消息用来干什么,可以做什么事
c) 消息的附带信息是什么
1.WM_DESTORY
窗口被销毁时的消息,无消息参数。常用于在窗口被销毁之前,做相应的善后处理,例如资源、内存等。
2.WM_SYSCOMMAND 系统命令消息
点击关闭按钮、最大化、最小化、标题栏等等出现的消息。常用在窗口关闭时,提示用户处理。
wParam — 具体点击的部位,例如关闭SC_CLOSE等。
lParam — 鼠标位置
LOWORD 鼠标低字,水平位置 int x = LOWORD(wParam);
HIWORD 鼠标高字,垂直位置 int y = HIWORD(lParam);
3.WM_CREATE —在窗口创建成功还未显示之前,收到这个消息。
常用于初始化窗口的参数、资源等等,包括创建子窗口等。
wParam不使用
lParam是CREATESTRUCT结构的指针,保存了CreateWindowEx的12个参数。
4.WM_SIZE -在窗口的大小发生变化后,会收到WM_SIZE.
常用于窗口大小变化后,调整窗口内各个部分的布局。
wParam —窗口大小变化的原因。最大的原因:从无到有。
lParam —变化窗口客户区的大小。
LOWORD 变化后的宽度
HIWORD 变化后的高度
展开阅读全文