|

做了几天将近完成的时候,发现一个让我不得不放弃的问题,就是在编辑输入内容的时候(WM_KEYDOWN事件),无法自绘内置的滚动条,趁着有空把自绘原理说一下。
第一步:
.版本 2
SetProp (hwnd, “Gsk.窗口过程”, GetWindowLong (hwnd, #GWL_WNDPROC))SetWindowLong (hwnd, -4, 到整数 (&编辑框_消息处理))
因为是用HOOK方式处理所有编辑框自绘,所以直接将窗口过程保存在该句柄的属性列表中,
第二次:消息处理
.版本 2
.子程序 编辑框_消息处理, 整数型.参数 hWnd, 整数型.参数 Msg, 整数型.参数 wParam, 整数型.参数 lParam, 整数型.局部变量 a, 整数型
.判断开始 (Msg = #WM_NCPAINT)‘框架必须绘制时发出该消息, 通用绘图.画边框 (hWnd) 编辑框_WM_NCPAINT (hWnd) 返回 (0)
’画边框比较简单,直接使用API函数:FrameRect描一下就行了,它会围绕边框根据你提供的颜色描一下。但是如果编辑框带有内置的滚动条,它同样会描上去,因为内置滚动条也是属于非客户区。所以呢如果你要自绘滚动条,这个消息也要处理一下。返回(0)表示告诉程序该事件已经处理,或者说什么事也没发生。(边框自绘END!)
.判断 (Msg = #WM_NCMOUSEMOVE) 编辑框_NCMOUSEMOVE (hWnd, wParam, lParam)
‘以下内容都是关于滚动条自绘事件,WM_NCMOUSEMOVE 这个消息发生时,表示鼠标在滚动条经过,如果是在左箭头上面,那么我们要画左箭头的点燃图片,就像图形按钮一样有默认,按下,点燃,禁止。如果是在滑块钮上同样也要画上点燃图片。另外要判断用户是不是正在托动滑块钮,如果是的画就保持图片是按下效果。
相关API:
GetWindowDC’得到窗口场景,我们要在该场景上面画上点燃图片,不过在画之前我们先要创建一个内存场景,并将图片加载到内存场景中。
StretchBlt‘将图片画到窗口场景中,
TransparentBlt ’这个函数最后一个参数允许你指定图片透明色。
.判断 (Msg = #WM_NCMOUSELEAVE) 编辑框_NCMOUSELEAVE (hWnd, wParam, lParam)
’没有该消息,需要在WM_NCMOUSEMOVE消息发生时加上追踪器,探测一下它到底有没有离开非客户区(滚动条和边框都不属于非客户区),我把这个追踪器集中在以下子程序中。如果发生鼠标离开事件就是要将滚动条图片换成默认状态。
‘----------------------
.版本 2
.子程序 开启鼠标移入移出, , 公开.参数 hWnd, 整数型.参数 是否客户区, 逻辑型, 可空.局部变量 tme, TRACKMOUSEEVENT
tme.cbSize = 16tme.dwFlags = 1 ' TME_HOVERtme.hwndTrack = hWndTrackMouseEvent (tme).判断开始 (是否为空 (是否客户区) 或 是否客户区 = 真) tme.dwFlags = 2 ' TME_LEAVE.默认 tme.dwFlags = #TME_NONCLIENT .判断结束
TrackMouseEvent (tme)
‘----------------------
.判断 (Msg = #WM_NCLBUTTONDOWN) ' 左键按下, 编辑框_OnNcLButtonDown (hWnd, wParam, lParam) 返回 (0)
这里要判断一下按下的位置是左右上下调节钮还是滑动钮,如果不是滑动钮就要开启时钟事件,然后发送消息到编辑框
SendMessage (hWnd, 局_消息值, 局_时钟事件, hWnd)如果是横向滚动条局_消息值就是WM_HSCROLL,如果是纵向滚动条局_消息值就是WM_VSCROLL,而局_时钟事件是告诉编辑框,滚动条要滚到哪边去,向左滚还是向右滚,或者是用户点击了滚动条背景,要一页一页的滚等等。这个消息值大家可以查一下,有SB_LINELEFT,SB_PAGEUP,SB_PAGEDOWN,SB_LINERIGHT。
.判断 (Msg = #WM_NCLBUTTONUP) 编辑框_OnNCLBUTTONUP (hWnd, wParam, lParam)
这个消息要处理的事情有,停止时钟,设置滑动钮托动为假,更换滚动条图片。另外如果处理了WM_NCLBUTTONDOWN消息不返回0的话,是不会有左键弹起消息。大家注意一下。
.判断 (Msg = #WM_NCLBUTTONDBLCLK) 编辑框_OnNcLButtonDown (hWnd, wParam, lParam) 返回 (0)
.判断 (Msg = #WM_NCDESTROY) 编辑框_OnNcDestroy (hWnd, wParam, lParam)
‘这里的作用就是释放内存。
.默认
.判断结束返回 (CallWinProc (hWnd, Msg, wParam, lParam))
唉!以后直接发源码算了,太难写了。
早上尝试把有滚动的地方挖空,但是挖空之后滚动条画不上去,因为要画的地方变成是主窗口了。如果画在主窗口上,主窗口背景要擦除时,编辑框是捕获不到这些消息,所以画了等于没画。怪不得大家都说滚动条最难画。 |
|