windows基础[..ing]
[2011.01.19_19:44] p410 系统 向子窗口发送WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_PAINT等.
子窗口 向父窗口发送WM_COMMAND+LOWORD(wParam)内装ID.
[2011.01.20_08:28] P416 子窗口 向自己和父窗口均发送消息. scroll发WM_SCROLL, button发WM_COMMAND.
1. GetWindowLong GetClassLong
2. hwnd+message
1. 坐标变换
(1)坐标原点设置
设备坐标: 始终左上角为(0, 0)
逻辑坐标:
转换:
(1) SetViewportOrgEx(hdc, x, y, NULL);
将逻辑原点移动到设备点(x, y).
(2) SetWindowOrgEx(hdc, x, y, NULL);
理解1:将逻辑原点设置为逻辑点(x, y).
理解2:旧逻辑x以里的开始显示, 旧逻辑Y以里的开始显示, 其他都移出屏幕.
用户使用: GDI等函数绘图都基于当前逻辑坐标原点.
(2)MM_ISOTROPIC模式. 坐标范围设置.
http://topic.csdn.net/u/20080110/07/7c41efa9-87c4-4d04-9d64-dbd20c198e84.html
现在有3个尺寸: 客户区尺寸, Viewport尺寸, Window尺寸.
1 SetWindowExtEx(hdc, x, y, NULL) : 逻辑窗口大小
2 SetViewportExtEx(hdc, x, y, NULL) : 设备窗口大小
3 cxClient, cyClient : 客户区大小
SetViewportOrgEx(hdc, x, y, NULL) : 相对客户区左上角的坐标.
SetWindowOrgEx(hdc, x, y, NULL) : 相对设备窗口左上角的坐标
已解决:
1.
SetMapMode(hdc, MM_ISOTROPIC);
SetWindowExtEx(hdc, 300, 300, NULL);
SetViewportExtEx(hdc, 600, -cyClient, NULL);
SetWindowOrgEx(hdc, 0, 300, NULL);
TextOut(hdc, 0, 0+cyChar, TEXT("A"), 1) ;
错误时: 认为“A”应该输出在最左下角. 刚好输出.
正确解: “A”偏上很多输出, 因为cyChar是普通模式获得的字体高度17, 而用在此处17逻辑单位对应
cyClient/300 * 17 > cyClient/cyClient *17, 所以会高。
关键点: 逻辑单位与设备单位比.
2. 坐标模式
1. 右正, 下正
MM_TEST : 图像不伸缩,可能图像溢出Client。 完全受限
2. 右正, 下负
MM_LOMETRIC
MM_HIMETRIC
MM_LOENGLISH
MM_HIENGLISH
MM_TWIPS
3. 自定义
"an application must call the SetWindowExtEx function before it calls SetViewportExtEx"
MM_ISOTROPIC 图像伸缩, 可设计保证图像不溢出Client自动适应。 半受限
MM_ANISOTROPIC
3. 窗口重绘
1. WM_PAINT
各种窗口变化,发送WM_PAINT
InvalidateRect(hdc, RECT*, TRUE), 发送WM_PAINT, RECT重绘区域
UpdateWindows(); 直接处理" sends the WM_PAINT message for the specified window directly to the window procedure."
4. 消息发送目标
发送给焦点窗口:
WM_MOUSEWHEEL 鼠轮滚动
VK_XX 键盘事件
发送给鼠标下窗口:
WM_MOUSEMOVE
WM_MOUSECLICK
WM_xx 鼠标系列 除MOUSEWHEEL
特殊:
SetCapture(HWND) 将消息发送给指定窗口, 这样可以迫使鼠标消息发送给非鼠标下窗口。
5. 获取信息
SystemParametersInfo() 获取系统很多属性的信息, 包括屏幕背景, 滚轮滚动长短等
GetTextMetrics(hdc, &tm) 获取系统字体信息, 包括字体,字体占高等
GetSystemMetrics(Char *paraname) 获取系统显示信息, 包括屏幕分辨率等.
P290
GetDialogBaseUnits 获取字符默认字体宽度和高度 GetTextMetrics像.
6. wParam, lParam
wParam: 消息码, 通知码
lParam: 坐标, 大小
WM_VSCROLL P309
LOWORD(wParam) : SB_LINEUP, SB_LINEDOWN, SB_PAGEDOWN... 按键
HIWORD(wParam) : POS 位置
lParam : scroll_id= GetWindowLong((HWND)lParam, GWL_ID); id
WM_KEYDOWN P187
wParam : VK_HOME, VK_UP, VK_DOWN, VK_TAB... 按键
WM_CHAR P191
wParam : ‘a’, 'b' 字符
WM_SIZE P317
LOWORD(lParam) : X
HIWORD(lParam) : Y
WM_COMMOND p317
LOWORD(wParam) : 按钮ID
HIWORD(wParam) : 操作通知码, BN_CLICKED...
lParam : 控件句柄
Menu WM_COMMOND P345
LOWORD(wParam) : 按钮ID
lParam : 0
7. 修改已经注册好的类信息
SetClassLong : 窗口相关的尺寸, 背景刷子, 光标的句柄, 图标的句柄, 菜单名字, 窗口过程. http://baike.baidu.com/view/1080269.htm
SetWindowsLong: 窗口过程, 新实例句柄, 窗口风格, 窗口标识符, http://baike.baidu.com/view/1080272
8. 一个基本的问题, 消息是自己发还是系统发, 一个动作系统要发哪些消息, 这直接影响到处理顺序和使哪个消息处理.
鼠标移动: WM_MOUSEMOVE, WM_NCHITTEST, WM_SETCURSOR
9. 焦点的设置
scroll控件
1. CreateWindow(...WS_TABSTOP...)
2. case WM_SIZE: SetFocus(hwnd)
3. case WM_SETFOCUS: SetFocus(childhwnd[i]);
一次即可. 之后的焦点设置均由子窗口设置.
10. 窗口层叠关系
1. static在最下. scroll在其上. P309程序
11. 动画
"如果你对动画感兴趣, 可以深入研究一些其他光栅操作的代码(如: SRCINVERT), 这些代码可以在源和目标图片之间进行异或运算。 其他的动画技术与Windows调色板(以及AnimatePalette函数)和CreateDIBSection函数有关。 如果想要做更复杂的动画, 可能需要放弃GDI而研究一下DirectX接口"。
1. 抠图 P555
12. 绘图
P554
1. 黑或: 绘图.
白或: 刷白.
黑与: 刷黑.
白与: 不变
2. 或: 黑绘图,白刷白
与: 黑刷黑,白不变
3. 改变图片形状. 图1黑框框白色, 图2黑框框原图
0x220326, 做图1
SRCPAINT, 做图2
13. Hook钩子
可以截获自己进程,甚至其他进程的消息。 可以在窗口处理函数前1处理,2不处理,3结束消息。
14. 多进程, 多线程窗口, 互控制.
通过全局的GetWindows, GetThread, 无条件获取任何一个窗口进行SetFocus, ShowWindows, SendMessage等操作. 进行方便的打通.
#QUESTION
20101101
1. P308 控件背景颜色设置
WM_CTLCOLOR
2. P308焦点现在有问题, 一上来焦点不对。
见9焦点设置
3. 如果不用static遮住一半, 无法再WM_SIZE, WM_PAINT时, 只把右边重绘. 现在全重绘.
Invalidate(Rect)
20101201
1. P303 WM_DRAWITEM响应慢. 点的快
if (lpdis->itemState & ODS_SELECTED)
InvertRect(lpdis->hDC, &lpdis->rcItem);
2. P562的截屏程序. 如何做的像Snagit 9.0一样, (1)背景的窗口不接收任何消息, (2)寻找进程控制MainFrame隐藏后的行为。
思路1: hook截获所有消息, 不响应, 主窗口hdc更新, 要开锁解锁
思路2: 弄个全屏大窗口, 进行操作. 如何创建只有绘制区的窗口?
20110111
1. P388程序, Dialog中frame资源和text资源背景刷新区别:
frame Invalidate不刷新背景.
test Invalidate正常.
20110119
1. 子窗口退出, 父窗口也退出了.
子窗口发送的PostMessageQueit(0),被父窗口处理.
20110120
1. 如何获取 窗口句柄, GetItemDlg必须有父窗口, p416的hDlg没有指定父窗口.
有父窗口, 只是获取时还没创建完, 所以没获取到.
#重要设置
1. 焦点 P309
’ WM_SIZE: SetFocus(hwnd)
''case WM_SETFOCUS: SetFocus(hwndScroll[idFocus]);
保证:焦点一直控件上.
避免:焦点混乱, 上来焦点在一点上闪烁, WM_SIZE后焦点位置不跟随一起变化,闪烁.
#PRACTICE
1. bitmap : widthbyte = whithpix * pixbit / 8 否则建图失败
2. hdcMem : (1) 必须选入HBITMAP, 才能绘图 (2) 绘制内容会保存在HBITMAP中, Delete(hdcMem)后, HBITMAP依然存在.
3. hBitmap : hBitmap= CreateBitmap((R+xmove)*2, (R+ymove)*2, 1, 4, NULL); 只能为1?
现象: 画出图像都是点
原因: hBitmap与原图设备不匹配,造成抖动.
修改: CreateCompatibleBitmap(hdc, (R+xmove)*2, (R+ymove)*2);
#Method
MAKELONG(x, y) x高16位, y低16位, 拼成32位 lParam或wParam
max(0, min(MAX, x)) 上越界取MAX, 下越界取0. GetCursorPos时, 鼠标可能在屏幕外, 所以需要限制.
SetWindowLong(hwnd, 0, 1^GetWindowLong(hwnd, 0));
SETROP2(hdc, R2_NOT); Rectangle(hdc, x, y, x, y),Rectangle(hdc, x, y, x, y). 连续的两个, 前者被擦除,再画后者. 重画使用.
p288
SetBkMode(hdc, TRANSPARENT); 为text, pen, brush设置绘画模式. 有透明模式.
获取实例 p290
GetWindowLong(hwnd, GWL_HINSTANCE)
(LPCREATESTRUCT)lParam->hInstance 只有在WM_CREATE消息中
全局hIns.
获取ID P292
id= GetWindowLong(hwndChild, GWL_ID)
id= GetDlgCtrlID(hwndChild)
P292
MoveWindow(x, y, weith, hight)