day03

type
DC - 设备上下文
CS - class Style
一、窗口类风格 (sTyle)
CS_GLOBALCLASS 应用程序全局窗口类
CS_BYTEALIGNCLIENT 窗口客户区水平位置按照8像素对齐
CS_BYTEALIGNWINDOW 窗口水平位置按照8像素对齐
CS_HREDRAW 窗口水平变化时重绘窗口内容
CS_VREDRAW 窗口垂直变化时重绘窗口内容
CS_CLASSDC 同类窗口共享一个设备上下文
CS_PARENTDC 子窗口使用父窗口的设备上下文
CS_OWNDC 使用自己设备上下文(默认这种方式)
CS_SAVEBITS 以位图的形式保存窗口的客户区(提高效率,但是费内存)
CS_DBLCLKS 接受窗口接受鼠标双击消息
CS_NOCLOSE 没有关闭按钮

SetWindowLong
设置
GetWindowLong
获取
Window每次显示窗口都需要重绘


使用自己的窗口过程函数截获消息(对于系统定义的函数)
g_OldBtnProc = SetWindowLong (hWnd, GWL_WNDPROC, (LONG)MyBtnProc);
可以让你修改窗口数据区,第二个参数就是改变的哪个部分,第三个参数你想改成什么。
当你用第三个参数进行替换的时候,这个函数会把替换部分原来的值返回出来。
CallWindowProc (g_OldBtnProc, hWnd, wParam,lParam);
在系统调用的窗口中,自己定义的过程函数替换了系统自己的获证函数,但是我只想是改变一些消息的处理方式,其他的方式不想改变,就使用这个函数,他可以帮助你处理。
窗口子类化








二、注册窗口类与创建窗口
typedef struct
{
....
HINSTANCE hInstance; //应用程序实例句柄
....
LPCTSTR  lpszClassName; //类名
}WNDCLASSEX,*PWNDCLASS;
------------------------------
WNDCLASSEX wcex = {0};
wcex.hInstance = hInstance;
wcex.lpszClassName = "MainWnd";
...
RegisterClassEx (&wcex);
-------------------------------
局部窗口类列表(没有CS_GLOBALCLASS)
局部窗口类1 -> 局部窗口类2 -> ....
hInstance 
lpszClassName
全局窗口类列表(定义了CS_GLOBALCLASS)
全局窗口类1 -> 全局窗口类2 -> ....
lpszClassName
系统窗口类列表
系统窗口类1 -> 系统窗口类2 -> ....
"BUTTON" "EDIT"
-------------------------------------
HWND  hWnd = CreateWindow ("MainWnd", ...., hInstance, ....);
-------------------------------------
HWND CreateWindow (LPCTSTR lpClassName, ...., HINSTANCE hInstance, ....)
{
if (局部窗口类列表中存在lpszClassName和hInstance成员与lpclassName和hInstance参数相匹配的元素) 
{
根据该元素去创建一个窗口并返回其句柄.
}
else 
if (全局列表中存在lpszClassName和lpClassName参数相匹配额元素)
{
根据该元素去创建一个窗口并返回其句柄
}
else 
if (系统列表中存在lpszClassName和lpClassName参数相匹配额元素) 
{
根据该元素去创建一个窗口并返回其句柄
}
else
return NULL;
}




创建自己的Icon的步骤:
在工程中添加资源脚本 - 在脚本中添加位图 - 保存
LoadIcon (hInstance, MAKEINTRESOURCE (IDI_WINREG_BIG));
为什么会出现MAKEINTRESOURCE呢?
这个是LoadIcon中参数的问题,他要的是一个实例句柄和字符串指针
但是IDI_WINREG_BIG是一个宏所以他不能成为LoadIcon的参数


WS_EX_CLIENTEDGE
多了一个3D效果的边框
在CreateWindowEx 中使用的。而且是第一个参数






三、创建窗口API
CreateWindow
CreateWindowEx相对于CreateWindow,增加了一个参数 - dwExStyle - 扩展风格
WS_EX_CLIENTEDGE - 3D效果的边框
WS_EX_MDICHILD - MDI子窗口


四、常用窗口风格
WS_BURDER - 边框
WS_CAPTION - 标题
WS_CHILD - 子窗口
WS_CHILDWINDOW - 同WS_CHILD
WS_CLIPCHILDREN - 恢复父窗口先前被子窗口覆盖时部分时,不绘制被子窗口覆盖的部分。应用于父窗口。
(绘制父窗口时不绘制被子窗口覆盖的部分)
WS_CLIPSIBLINGS - 绘制子窗口的同时也绘制其兄弟窗口。应用于子窗口。 
WS_DISABLE - 禁用
WS_DLGFRAME - 对话框边框(大小固定,不能缩放)
WS_GROUP - 控件组的首控件
WS_HSCROLL - 水平滚动条
WS_VSCROLL - 垂直滚动条


WS_ICONIC - 初始最小化
WS_MAXIMIZE - 初始最大化
WS_MAXIMIZEBOX - 最大化按钮
WS_OVERLAPPED - 交叠 带有标题栏和边框
WS_OVERLAPPEDWINDOW - 交叠、系统菜单、带尺寸框、最小最大化按钮
WS_POPUP - 弹出式
WS_POPUPWINDOW - 弹出式、边框(改变大小)、系统菜单
WS_SIZEBOX - 尺寸框
WS_SYSMENU - 系统菜单
WS_TABSTOP - 可用Tab切换
WS_THICKFRAME - 同WS_SIZEBOX
WS_TILED - 同WS_OVERAPPLED
WS_TILEDWINDOW - 同WS_OVERAPPLEDWINDOW
WS_VISIBLE - 初始可见


窗口风格 只管着一个风格
窗口类风格 管着一类风格


case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint (hWnd, &ps);
RECT rcClient;
GetClientRect (hWnd, &rcClient);
Ellipse (hDC, rcClient.left, rcClient.top,
rcClient.right, rcClient.bottom);
EndPaint (hWnd, &ps);
return 0;
}


五、子窗口的创建
1.WS_CHILD | WS_VISIBLE
2.有父窗口
3.与子窗口有关的风格


SetWindowPos
设置窗口位置
GetSystemMetrics
获取某些东西的信息
六、窗口类附加数据和窗口附加数据
WNDCLASSEX wcex;
...
wcex.cbClsExtra = 4;
wcex.cbWndExtra = 4;
/*这个表示使用4个字节存储数据*/






SetClassLong/GetClassLong
SetWindowLong/GetWindowLong




DWORD SetClassLong(
  HWND hWnd,       // handle of window
  int nIndex,      // index of value to change
/*这个就是一个索引号,例如你定义了8个字节,如果你给0,就使用前4个字节,如果你给1,就使用后4个字节,类似一个数组下标*/
 
  LONG dwNewLong   // new value
/* Set value it you need*/
);


在setclasslong中的规定宏都是小于0的。
 


窗口附加数据独立的存在,每一个窗口都有一个窗口附加数据
窗口类附加数据不是独立的,他是整个窗口含有一个,他就像一个父类一样,有很多的基类
但是窗口附加数据就相当于子类。
七、显示/刷新窗口
BOOL ShowWindow (HWND hWnd, int nCmdShow) 
{
根据hWnd窗口位置大小颜色等信息。
根据所获得的窗口外观信息和nCmdShow参数在屏幕上绘制窗口;

}
BOOL UpdateWindow (hWnd) {
if (hWnd参数所标识的窗口存在无效区域)
以WM_PAINT消息为参数调用相应窗口过程函数
}
无效区域就是 两个文件的遮盖部分


InvalidateRect ()
重画函数


八、消息队列/消息循环/消息处理
1.程序的执行机制
1)过程驱动: 程序按照预定的顺序执行。
2)事件驱动: 根据用户触发的事件来执行相应的动作
3)Win32窗口程序采用事件驱动方式执行, 消息机制
2.消息
typedef struct tagMSG {
HWND hWnd; //窗口句柄
UINT message; //消息标示
WPARAM wParam;
LPARAM lParam; //消息参数
DWORD time; //消息产生的时间
POINT pt; //消息产生时鼠标的位置
} MSG;
消息结构前四个成员与窗口过程函数的参数一致
3.消息队列
GetMessage () <-WM_CREATE WM_SIZE WM_PAINT ... -< 消息源
每一个线程有一个消息队列.
4.消息循环
MSG msg = {0};
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
1) GetMessage 函数负责从消息队列中获取消息,并将其内容填入Msg结构体。
BOOL GetMessage (
LPMSG lpMsg, //消息结构
HWND hWnd, //窗口句柄,若非NULL则,只获取特定窗口的消息。
UINT uMsgFilterMin, //消息过滤器的下限
UINT uMsgFilterMax, //消息过滤器的上限
);
收到WM_QUIT消息返回FALSE,收到其他消息返回TRUE
case WM_DESTROY:
PostQuitMessage (0);
return 0;


PostQuitMessage 函数在消息队列中放入一个WM_QUIT消息


2)TranslateMessage 函数负责对部分消息(与可见字符相关、键盘消息,进行翻译);
BOOL TranslateMessage (
const MSG* lpMsg //消息结构
);
如果消息被翻译了,返回TRUE,否则返回FALSE
根据CapsLock键的状态判断大小写。
3)DispatchMessage 派发消息
LONG DispatchMessage (const MSG* lpmsg)
{
根据 lpmsg->hWnd获取相应的窗口类
从窗口类的lpfnWndProc成员确定窗口过程函数的地址;
窗口过程函数 (lpmsg->hWnd, lpMsg->message, lpmsg->wParam, lpmsg->lParam);

}
4)一旦GetMessage函数从消息队列中取到WM_QUIT消息,即返回FALSE,消息循环结束,线程终止。
如果线程为进程的主线程,进而线程终止。




------------------------------------------------------------
三、消息处理







































































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章