win32第三天

1.花了半小时复习昨天的课程。郁闷
就用程序全局窗口类的注册,需要在窗口类的风格中增加CS_GLOBALCLASS,如果不添加这个风格,则注册的窗口为局部窗口类。
WNDCLASSEX wce;
wce.style=|CS_GLOBALCLASS;
应用程序所有的窗口风格style
CS_GLOBALCLASS  应用程序全局窗口类


CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8倍数对齐(属于一种对齐方式,如果你给的位置不是8的倍数,则选择后系统会徽调使其为8的位数,不过效果不大)


CS_BYTEALIGNWINDOW - 窗口的水平位置8倍数对齐


CS_HREDRAW - 当窗口水平变化时,窗口重新绘制
CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制 
CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备 
CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备
CS_OWNDC - 该类型的窗口,每个窗口都使用自己的绘图(DC)设备
CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源
CS_DBLCLKS - 允许窗口接收鼠标双击
CS_NOCLOSE - 窗口没有关闭按钮


把一个现有的项目添加到当前的工作区。
void AppReg(){
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)DefWindowProc;
wce.lpszClassName="Main";  //注意
wce.lpszMenuName=NULL;
wce.style=CS_HREDRAW|CS_VREDRAW;
ATOM nAtom=RegisterClassEx(&wce);
if(nAtom==0)
{MessageBox(NULL,"注册失败","Error",MB_OK);}
}
HWND hWnd=CreateWindow("Main","Infor",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,g_hInstance,NULL);
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg;
while(GetMessage(&nMsg,NULL,0,0)){
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}




窗口类的查找过程CreateWindow
1 系统根据传入的窗口类名称,在应用程序局部窗口类中查找,如果找到执行2,如果未找到执行3。
2 比较局部窗口类与创建窗口时传入的HINSTANCE变量。如果发现相等,创建和注册的窗口类在同一模块,创建窗口返回。如果不相等,继续执行3。
3 在应用程序全局窗口类,如果找到,执行4,如果未找到执行5。
4 使用找到的窗口类的信息,创建窗口返回。
5 在系统窗口类中查找,如果找到创建窗口返回,否则创建窗口失败。
GetClassInfo获取窗口类信息
Unregisterclass卸载


CreateWindow/CreateWindowEx
HWND CreateWindowEx(
DWORD dwExStyle, //窗口的扩展风格
LPCTSTR lpClassName,  //已经注册的窗口类名称
LPCTSTR lpWindowName, //窗口标题栏的名字
DWORD dwStyle, //窗口的基本风格
int x, //窗口左上角水平坐标位置
int y, //窗口左上角垂直坐标位置
int nWidth, //窗口的宽度
int nHeight,//窗口的高度
HWND hWndParent,//窗口的父窗口句柄
HMENU hMenu,//窗口菜单句柄
HINSTANCE hInstance, //应用程序实例句柄
LPVOID lpParam //窗口创建时附加参数   
); 创建成功返回窗口句柄




wincreate.c
以前都是点击关闭按钮后,没办法结束进程。于是加一段消息处理代码以退出消息循环:
switch(uMsg){
case WM_DESTROY:
PostQuitMessage(0);break;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
可以得出结论:
PostQuitMessage(0)可以使GetMessage()返回0.
子窗口的创建
创建时要设置父窗口句柄
创建风格要增加WS_CHILE,WS_VISIBLE
MoveWindow


#include "windows.h"


HINSTANCE g_hInstance;
//消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch(uMsg){
case WM_DESTROY:
PostQuitMessage(0);break;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);


}
//注册窗口
BOOL Register(LPSTR lpClassName,WNDPROC wndproc){
WNDCLASSEX wce;
ATOM nAtom;
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.lpszMenuName=NULL;
wce.lpszClassName=lpClassName;
wce.style=CS_HREDRAW|CS_VREDRAW;
nAtom=RegisterClassEx(&wce);
if(nAtom==0)
return FALSE;
return TRUE;
}
//创建主窗口
HWND Create(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 hWnd){
HWND hWndChild=CreateWindowEx(0,lpClassName,lpWndName,WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,100,100,200,200,hWnd,NULL,g_hInstance,NULL);
return hWndChild;
}
//显示窗口
void Display(HWND hWnd){
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
}
//消息循环
void Message(){
MSG nMsg;
while(GetMessage(&nMsg,NULL,0,0)){
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}


int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow){
HWND hWnd;
HWND hWndChild1;
HWND hWndChild2;
g_hInstance=hInstance;
if(!Register("Main",WndProc)){
MessageBox(NULL,"注册失败","Error",MB_OK);
}
hWnd=Create("Main","主窗口");
//注册子窗口
Register("child",DefWindowProc);
//创建子窗口
hWndChild1=CreateChild("child","子窗口1",hWnd);
hWndChild2=CreateChild("child","子窗口2",hWnd);
MoveWindow(hWndChild2,200,200,100,100,TRUE);
Display(hWnd);
Message();
return 0;
}
注册窗口类的两个成员
cbClsExtra,cbWndExtra
可以设置这两个数据内存空间的大小,是数据BUFFER大小,可以提供窗口类和窗口存放自己的数据。
1.定义数据空间的大小
int cbClsExtra,一般定义为4字节倍数
2.存入数据
DWORD SetClassLong(
HWND hWnd,
int nIntex,//字节索引号
LONG dwNewLong//存入数据
);返回旧数据
3.读取数据
DWORD GetClassLong(
HWND hWnd;
int nIndex//字节索引号
);返回索引值。
 窗口附加数据
1 定义数据空间的大小
     int cbWndExtra;
2 存入数据
    LONG SetWindowLong(
HWND hWnd,       // handle to window
int nIndex,      // offset of value to set
LONG dwNewLong   // new value
);
3 读取数据
  LONG GetWindowLong(
HWND hWnd,  // handle to window
int nIndex  // offset of value to retrieve
);
窗口类的附加数据提供BUFF,是所有该类窗口共享的BUFF。
窗口附加数据提供BUFF,只属于该窗口所有,是窗口私有的BUFF。
BUFF中只要可多存指针变量,那么附加数据是什么都可以了。


消息和消息机制
程序执行机制;;;;
过程驱动:程序的执行过程是按照预定好的顺序执行。
事件驱动:程序的执行是无序,用户可以根据需要随机触发相应的事件。
Win32窗口程序就是采用事件驱动方式执行,也就是消息机制。
当系统通知窗口工作时,就采用消息的方式派发给窗口(窗口处理函数)。DispatchMessage(&nMsg);
MSG消息组成:
窗口句柄
消息ID
消息的两个参数
消息产生的时间
消息产生时的鼠标位置
 
每个窗口都必须具有窗口处理函数。
LRESULT CALLBACK WindowProc(
    HWND hwnd, //窗口句柄
    UINT uMsg, //消息ID
    WPARAM wParam, //消息参数
    LPARAM lParam  //消息参数
);
当系统通知窗口时,会调用窗口处理函数同时,将消息ID和消息参数传递给窗口处理函数。
在窗口处理函数中,不处理的消息,使用缺省窗口处理函数,例如DefWindowProc
DispatchMessage是如何派发消息的?
{《猜》
1.获取消息是属于本进程哪个窗口(&nMsg)->hWnd
2.根据窗口句柄获取内存中的信息"Main"
3.拿着"Main"到操作系统中去匹配窗口类名
4.如果匹配到了,调用被匹配到的那个窗口类中存的函数地址。
}


程序员自己定义的函数,但是交给操作系统调用叫作回调机制。
两大机制:构子机制(木马),回调机制。





























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值