minigui学习笔记三

本文详细讲解了Windows编程中滚动条的使用、启用禁用、范围设置、鼠标事件处理,以及键盘和鼠标的基本输入流程、消息机制,包括鼠标捕获和事件钩子。涵盖了滚动条消息、字符消息和击键消息,是开发者必备的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

八.滚动条
1.概念
    1.1滚动条既有垂直方向的(供上下移动),也有水平方向的(供左右移动)
    1.2程序实际上是将文件相对于显示窗口向上移动 ---- 向上滚动意味着朝文件的开头移动,向下滚动意味着朝文件尾部移动
    1.3关键字
      在CreateWindow的第三个参数中包括窗口风格标识号WS_VSCROLL(垂直滚动)和(或)WS_HSCROLL(水平滚动)
      这些滚动条默认在窗口的右部和底部
      垂直滚动条显示在窗口的左侧: WS_EX_LEAFTSCROLLBAR
      
2.使能、禁止滚动条
   EnableScrollBar (hWnd, SB_HORZ, TRUE);
   EnableScrollBar (hWnd, SB_VERT, FALSE);


3.滚动条的范围和位置
   滚动条的属性 ------ 范围 : 最小值 和 最大值
                       位置 :滚动滑块在次范围内的位置

   结构体:SCROLLINFO si;
          si.nMax = 100;
          si.nMin = 0;
          si.nPage = 10;
          si.nPos = 0;
          SetScrollInfo (hWnd, Bar, &si, bRedraw);
          窗口根据新范围重画滚动条,则设置 bRedraw 为 TRUE
          SetScrollRange 调用了影响滚动条位置的其他函数  bRedraw 设定为 FALSE
    
    处理滚动条鼠标事件
    1.使用者  ----》 拖动滚动滑块  ---》 移动滚动滑块
    2.为包含滚动条的窗口处理程序  ----》 发送滚动条消息
    
    程序编写者
    1.初始化滚动条的位置和范围
    2.处理窗口处理程序的滚动条消息
    3.更新滚动条内滚动滑块的位置
    4.显示区的区域的内容  ------- 滚动条的更改
    
4.滚动条消息
   产生的事件:鼠标单击滚动条 拖动滚动滑块
   消息: MSG_VSCROLL(供上下移动) MSG_HSCROLL(供左右移动)
   wParam消息参数 ----》 通知码
   SB_LINEUP SB_LINEDOWN  SB_PAGEUP  SB_PAGEDOWN
   SB_LINELEFT SB_LINERIGHT SB_PAGELEFT SB_PAGERIGHT
   SB_THUMBTRACK  SB_THUMBPOSITION
   在滑动过程中
   wParam : SB_THUMBTRACK -------- lParam : 是使用者在拖动滑块时的目前位置
   在滑动完成后
   在SB_THUMBTRACK或SB_THUMBPOSITION中,如果不调用SetScrollPos函数,滑块就会回到原来的位置
   如果在滑动中如果要移动显示的区域,有些程序数据量大,重绘效率低很难跟的上消息
   这时可以只处理SB_THUMBPOSITION
   
5.相关函数
EnableScrollBar (hWnd, SB_HORZ, FALSE);
SetScrollRange (hWnd, SB_VERT, 0, 20);
ShowScrollBar (hWnd, SB_HORZ, FALSE);
在MSG_HSCROLL中 ---》向右滚:ScrollWindow (hWnd, -GetSysCharWidth (), 0, NULL, NULL);  
每次滚一个系统字符宽度
SB_LINEDOWN向上滚每次滚一个 20 个象素高:ScrollWindow (hWnd, 0, -20, NULL, NULL);
相当于外面的滑动框是静止不动的,要看到下面的区域,显示区域需要向上移动(向上移动对应y轴)


九.键盘和鼠标
1.键盘
1.1输入流程
键盘 -----(原始输入数据)-----> 键盘设备驱动 -------> 底层事件处理 ----(击键消息)----->消息队列----->窗口过程
设备驱动程序: 键盘(接收原始的输入事件或数据) ---->  MiniGUI抽象的键盘和输入

1.2MiniGUI抽象的键盘和输入
 特点: 1.支持255个键
       2.每个不同的键对应独一无二的"扫描码"
       3.129以下的对应PC键盘
       
1.3击键消息
按下: MSG_KEYDOWN 或者 MSG_SYSKEYDOWN 
释放: MSG_KEYUP 或者 MSG_SYSKEYUP
长按不放 ----> 会产生一系列的MSG_KEYDOWN 自动重复特性
作用:系统击键消息:控制菜单的激活 非系统击键消息:应用程序
产生系统按键消息:ALT按下击键  非系统按键消息:普通击键
击键消息的wParam --- 扫描码   IParam --- SHIFT、ALT、CTRL特殊键标志

1.4字符消息 --- MSG_CHAR MSG_SYSCHAR
TranslateMessage(&Msg);
根据击键消息的MSG_KEYDOWN和MSG_SYSKEYDOWN的扫描码和特殊符号的组合--->字符编码(ascii码)
wParam:按下字符键的ASCII码 lParam:特殊按键

注:用途
    MSG_KEYDOWN:读取游标键、功能键、Delete、Insert、Shift、Ctrl以及Alt
    MSG_CHAR: 读取输入到窗口的键盘字符

1.5键状态
处理组合键 ----- lparam与相关的宏位与
特殊换档键: Shift Ctrl Alt
开关键: Caps Lock、Num Lock 和 Scroll Lock
KS_CAPSLOCK     CapsLock 键被锁住
KS_NUMLOCK         NumLock 键被锁住
KS_SCROLLLOCK     ScrollLock 键被锁住

KS_LEFTCTRL     左 Ctrl 键被按下
KS_RIGHTCTRL     右 Ctrl 键被按下
KS_CTRL         任何一个 Ctrl 键被按下

KS_LEFTSHIFT     左 Shift 键被按下
KS_RIGHTSHIFT     右 Shift 键被按下
KS_SHIFT         任何一个 Shift 键被按下

KS_IMEPOST         鼠标消息由 IME 窗口投递
KS_LEFTBUTTON     鼠标左键被按下
KS_RIGHTBUTTON     鼠标右键被按下
KS_MIDDLBUTTON     鼠标中键被按下
KS_CAPTURED     鼠标被窗口捕获(只能用于鼠标消息)

这些键均能用于击键消息和鼠标消息

得到这些消息和状态: 1.在消息过程处理函数的lparam消息与状态位与
                    2.DWORD GUIAPI GetShiftKeyStatus (void);
                        例:GetShiftKeyStatus() & KS_CTRL 来确定左或右 Ctrl 键是否被按下
                    3.BOOL GUIAPI GetKeyStatus (UINT uKey);
                        查询的是该键的扫描码,如果该键被按下,GetKeyStatus返回TRUE,否则返回FALSE

1.6 输入焦点
具有输入焦点的键盘可以接收键盘输入
活动窗口、活动窗口的子窗口、活动窗口的子窗口的子窗口
子窗口一般通过一个闪烁的插入符 ------- 代表这个窗口有输入焦点
输入焦点是窗口的一个属性 ---- 移动输入焦点让显示在屏幕上的所有窗口共享键盘
系统-----(MSG_KILLFOCUS)-----失去焦点的窗口
系统-----(MSG_SETFOCUS)------得到焦点的窗口

应用程序  GetFocusChild  获得某个窗口中具有输入焦点的子窗口的句柄
    #define GetFocus GetFocusChild 
    HWND GUIAPI GetFocusChild (HWND hWnd);            

父窗口 -----(设置输入焦点) ----- 子窗口
    #define SetFocus SetFocusChild
    HWND GUIAPI SetFocusChild (HWND hWnd);

消息把击键消息发送到具有输入焦点的窗口    

2.鼠标
2.1相关概念
鼠标设备---(原始输入数据)---->鼠标设备驱动------->底层事件处理----(鼠标消息)---->消息队列---->窗口过程

屏幕:鼠标光标的小位图
鼠标光标的小位图里面有一个像素点 ----- 热点
热点 ----- 跟踪和识别光标的位置
系统把鼠标消息发送到具有热点的窗口

2.2鼠标消息
事件的产生:用户移动鼠标、按下或者释放鼠标按钮
鼠标消息:客户区消息和非客户区消息(通常处理客户区消息而忽略非客户区消息)

客户区消息:
MSG_MOUSEMOVE  移动鼠标
MSG_LBUTTONDOWN 鼠标左按钮被按下
MSG_LBUTTONUP 鼠标左按钮被释放
MSG_RBUTTONDOWN 鼠标右按钮被按下
MSG_RBUTTONUP 鼠标右按钮被释放
MSG_LBUTTONDBLCLK 鼠标左按钮被双击
MSG_RBUTTONDBLCLK 鼠标右按钮被双击

wParam参数:键状态值 例:lParam & KS_SHIFT) 为 TRUE
lParam参数:光标热点的位置 低位字(x) 高位字(y) ------> 客户区坐标
           当窗口捕获鼠标时,上述消息的位置坐标 -----> 屏幕坐标
           
非客户区消息:标题栏、菜单和窗口滚动条
MSG_NCLBUTTONDOWN 鼠标左按钮被按下
MSG_NCLBUTTONUP 鼠标左按钮被释放
MSG_NCRBUTTONDOWN 鼠标右按钮被按下
MSG_NCRBUTTONUP 鼠标右按钮被释放
MSG_NCLBUTTONDBLCLK 鼠标左按钮被双击
MSG_NCRBUTTONDBLCLK 鼠标右按钮被双击
wParam参数: 指明移动或单击鼠标按钮时的非客户区位置
lParam参数: 低位字(x) 高位字(y) -------> 窗口坐标
wParam参数值: 击中检测码
#define HT_UNKNOWN 0x00
#define HT_OUT 0x01
#define HT_MENUBAR 0x02
#define HT_TRANSPARENT 0x03
#define HT_BORDER_TOP 0x04
#define HT_BORDER_BOTTOM 0x05
#define HT_BORDER_LEFT 0x06
#define HT_BORDER_RIGHT 0x07
#define HT_CORNER_TL 0x08
#define HT_CORNER_TR 0x09
#define HT_CORNER_BL 0x0A
#define HT_CORNER_BR 0x0B
#define HT_CLIENT 0x0C
#define HT_NEEDCAPTURE 0x10
#define HT_BORDER 0x11
#define HT_NCLIENT 0x12
#define HT_CAPTION 0x13
#define HT_ICON 0x14
#define HT_CLOSEBUTTON 0x15
#define HT_MAXBUTTON 0x16
#define HT_MINBUTTON 0x17
#define HT_HSCROLL 0x18
#define HT_VSCROLL 0x19

哪些窗口会收到鼠标消息----->含有热点的窗口或者捕捉鼠标的窗口
MSG_HITTEST(MSG_NCHITTEST)
wParam: 光标热点的 x 坐标
lParam: 光标热点的 y 坐标
缺省的鼠标消息处理程序:对MSG_HITTEST处理 返回值:击中检测码
如果光标热点在客户区 -----> 返回HT_CLIENT 光标热点屏幕坐标转为客户区坐标 ---> 向相应的窗口过程发送客户区鼠标消息
如果光标热点在窗口的非客户区 -----> 击中检测码返回 ----> 击中检测码(wParam),光标坐标(lParam)--> 向相应的窗口发送非客户区鼠标消息

2.3 鼠标捕获
在某一时刻只能有一个窗口捕获鼠标
HWND GUIAPI SetCapture(HWND hWnd);//使某个窗口捕获鼠标
void GUIAPI ReleaseCapture(void);//
HWND GUIAPI GetCapture(void);//来确定当前是哪个窗口捕获了鼠标

3.事件钩子
3.1正常的途径
(键盘事件和鼠标事件) -----> 底层设备 ------> 最终的应用程序窗口过程

机制
底层设备 ------(消息)---------(钩子函数)-------> 返回值 ---->(继续传递) -----> 窗口
底层设备 ------(消息)---------(钩子函数)-------> 返回值 ---->不再传递

钩子函数的原型
MiniGUI-Threads 和 MiniGUI-Standalone 
typedef int (* MSGHOOK)(void* context, HWND dst_wnd, int msg, WPARAM wparam, LPARAM lparam);
context:注册钩子时传入的一个上下文信息
dst_wnd:该消息的目标主窗口
msg: 消息的标识符
wparam和lparam是消息的两个参数
返回值: HOOK_GOON 继续传递事件
        HOOK_STOP 停止事件的继续传递
        
注册键盘和鼠标事件的钩子函数
MSGHOOK GUIAPI RegisterKeyMsgHook (void* context, MSGHOOK hook);
MSGHOOK GUIAPI RegisterMouseMsgHook (void* context, MSGHOOK hook);
context:上下文信息
hook:回调函数的指针
返回值:会返回先前注册的钩子函数的指针

注销先前的钩子函数
MSGHOOK GUIAPI RegisterKeyMsgHook (void* context, MSGHOOK hook);
MSGHOOK GUIAPI RegisterMouseMsgHook (void* context, MSGHOOK hook);
hook = NULL

钩子回调函数是由 MiniGUI 桌面线程调用的,也就是说,钩子回调函数是在桌面线程中执行的,因此,不能在钩子
回调函数中向其他线程通过 SendMessage 的方式发送消息,这样会导致可能的死锁发生。

MiniGUI-Processes模式
HWND GUIAPI RegisterKeyHookWindow (HWND hwnd, DWORD flag);
HWND GUIAPI RegisterMouseHookWindow (HWND hwnd, DWORD flag);
hwnd:客户端窗口句柄
flag: 控制是否停止处理钩子消息
HOOK_GOON 用来继续, HOOK_STOP 用来停止

服务器进程
typedef int (* SRVEVTHOOK) (PMSG pMsg);
SRVEVTHOOK GUIAPI SetServerEventHook (SRVEVTHOOK SrvEvtHook);
pMsg 是要传递的消息结构指针。服务器可以随意修改该指针指向的消息结构中的值
返回值: HOOK_GOON 正常处理
        HOOK_STOP 取消处理
作用:使用钩子函数,我们可以监测系统的空闲时间,并在系统空闲时间到达设定值时启动屏幕保护程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值