minigui[基础篇][12]—— 光标

问题:1.什么是光标,光标和鼠标是怎样的关系? --- 光标是含有热点会移动的位图  光标是鼠标的显式输出,会把鼠标消息发送到含光标的窗口
    2.光标是怎样创建、操作和销毁的? ---- 光标是图片,就需要加载资源  
    3.光标有哪几种 --- 系统、缺省、类、控件、对象
    4.光标含有两种特性: 图片(加载资源 光标形状) + 热点(接收鼠标消息 重新设置位置)

1.什么是光标

1.光标是一个小的位图,它在屏幕上的位置由鼠标等定点设备控制,用来指示定点的位置
2.用户移动鼠标时,光标在屏幕上作相应的移动
3.如果光标移动到了窗口的不同区域或不同的窗口内时,系统很可能会改变光标的外形
4.光标内一个称为热点的像素标志光标的准确屏幕位置,系统用这个点来跟踪和识别光标的位置
5.光标的热点通常就是光标的焦点。如果有一个鼠标输入事件发生,系统将把包含热点坐标的鼠标消息发送给光标热点所在的窗口或捕获到鼠标的窗口
    
注:光标就是鼠标事件的显示输出
光标 = 大小 + 位置 + 颜色位数 + 位图印象 光标其实更像不断移动的图像

2.光标的载入和创建

方式1:从光标文件加载光标

//从光标文件里加载光标 光标文件中读入光标的大小、热点位置、颜色位数和位图映像数据等信息
HCURSOR GUIAPI LoadCursorFromFile (const char* filename);
@filename:光标文件
@return HCURSOR:光标文件句柄

方式2:从内存加载光标

//从指定的内存区域中载入一个光标
HCURSOR GUIAPI LoadCursorFromMem (const void* area);
@area:area 所指的光标内存区域和 Windows 光标文件的布局应该是一样的
@return HCURSOR:光标文件句柄

方式3:从内存创建光标

//应用程序运行时动态运行时创建的光标
HCURSOR GUIAPI CreateCursor (int xhotspot, int yhotspot, int w, int h,const BYTE* pANDBits, const BYTE* pXORBits, int colornum);
@xhotspot, yhotspot 光标热点的水平和垂直坐标
@w, h 光标的宽和高  而 MiniGUI 中只能使用 32x32 像素的光标
@pAndBits AND 位屏蔽光标位图映像指针 一个包含光标的 AND 位屏蔽位图映像数据的字节数组,AND位屏蔽位图是一个单色位图
@pXorBits XOR 位屏蔽光标位图映像指针 指向一个包含光标的 XOR 位屏蔽位图映像数据的字节数组,XOR 位屏蔽位图
可以是单色位图,也可以是彩色位图。MiniGUI 目前支持单色的和 16 色的两种光标
@colornum XOR 位屏蔽光标位图映像的颜色位数 对于单色光标,它应该为 1,对于 16 色光标,它应该为 4

方式4:从系统加载光标

//MiniGUI 源代码中定义的系统所使用光标的最大数目为 (MAX_SYSCURSORINDEX + 1)。MAX_SYSCURSORINDEX 为最大的系统光标索引值,定义为 22,因此系统预定义的光标最大数目为 23
MINIGUI.cfg文件
[cursorinfo]
# Edit following line to specify cursor files path
cursorpath=/usr/local/lib/minigui/res/cursor/
cursornumber=23
cursor0=d_arrow.cur
cursor1=d_beam.cur
cursor2=d_pencil.cur
cursor3=d_cross.cur
cursor4=d_move.cur
cursor5=d_sizenesw.cur
cursor6=d_sizens.cur
cursor7=d_sizenwse.cur
cursor8=d_sizewe.cur
cursor9=d_uparrow.cur
cursor10=d_none.cur
cursor11=d_help.cur
cursor12=d_busy.cur
cursor13=d_wait.cur
cursor14=g_rarrow.cur
cursor15=g_col.cur
cursor16=g_row.cur
cursor17=g_drag.cur
cursor18=g_nodrop.cur
cursor19=h_point.cur
cursor20=h_select.cur
cursor21=ho_split.cur
cursor22=ve_split.cur

HCURSOR GUIAPI GetSystemCursor (int csrid);
IDC_ARROW 系统缺省的箭头光标
IDC_IBEAM ‘I’ 形光标,指示输入区域
IDC_PENCIL 笔形光标
IDC_CROSS 十字光标
IDC_MOVE 移动光标
IDC_SIZENWSE 西北-东南方向的调整大小光标
IDC_SIZENESW 东北-西南方向的调整大小光标
IDC_SIZEWE 东西方向的调整大小光标
IDC_SIZENS 南北方向的调整大小光标
IDC_UPARROW 向上箭头光标
IDC_NONE 空光标
IDC_HELP 带问号光标
IDC_BUSY 忙光标
IDC_WAIT 等待光标
IDC_RARROW 右箭头光标
IDC_COLOMN 列光标
IDC_ROW 行光标
IDC_DRAG 拖动光标,用于拖放操作
IDC_NODROP 不可放下光标,用于拖放操作
IDC_HAND_POINT 手形指点光标
IDC_HAND_SELECT 手形选择光标
IDC_SPLIT_HORZ 水平分割光标
IDC_SPLIT_VERT 垂直分割光标

3.光标的操作

如果系统包含鼠标,系统将自动地显示光标,并根据鼠标移动指定的位置更新它在屏幕上的位置,重新绘制光标

3.1显示和隐藏光标

//显示光标和隐藏光标
int GUIAPI ShowCursor (BOOL fShow);
@fShow:FALSE :隐藏光标
        TRUE :显示光标

3.2设置或获取光标的位置

//GetCursorPos函数来获取光标的当前屏幕位置
void GUIAPI GetCursorPos (POINT* ppt);
@ppt: 传出参数 光标的屏幕位置

//SetCursorPos函数来把光标移动到屏幕上的指定位置
void GUIAPI SetCursorPos (int x, int y);
@x:x 屏幕坐标
@y: y 屏幕坐标

3.3限定光标的活动范围

// ClipCursor 函数把光标限定在屏幕的某个矩形区域内
// ClipCursor 函数在把光标限定在屏幕的某个矩形区域内的同时,将把光标移动到该矩形区域的中心点处
void GUIAPI ClipCursor (const RECT* prc);
@prc:指向给定的限定矩形 ; prc == NULL ClipCursor 函数将取消光标限制
    
//获取当前的光标限定矩形   
void GUIAPI GetClipCursor (RECT* prc);
@prc:原来的光标的限定

3.4获取或设置新的光标 (可以设置光标形状)

1.缺省光标 -- 移动到桌面上的光标
2.类光标 ---- 注册类的光标 为所有该类创建出来的对象所共享
3.主窗口光标 ---- 创建主窗口的光标
4.控件光标 ----- 创建控件实体的光标

//获取当前光标句柄
HCURSOR GUIAPI GetCurrentCursor (void);

//设置当前光标
HCURSOR GUIAPI SetCursorEx (HCURSOR hcsr, BOOL set_def);
@hcsr:hcsr 指定的光标设置为当前光标
@set_def: set_def 为 TRUE,SetCursorEx 还将把该光标设置为缺省光标,缺省光标为移动到桌面之上时显示的光标
@HCURSOR:返回老的光标句柄
    
// 设置当前光标,不改变缺省光标
#define SetCursor(hcsr) SetCursorEx (hcsr, FALSE);
// SetDefaultCursor 把给定光标设置为当前光标和缺省光标
#define SetDefaultCursor(hcsr) SetCursorEx (hcsr, TRUE);
  
//获取给定窗口的当前光标
HCURSOR GUIAPI GetWindowCursor (HWND hWnd);
@hWnd:窗口
@HCURSOR:当前窗口的光标

// 来设置新的窗口光标
HCURSOR GUIAPI SetWindowCursor (HWND hWnd, HCURSOR hNewCursor);
@hWnd:窗口
@hNewCursor:新光标
@HCURSOR:旧光标  

4.一个光标的demo

/*程序运行时,当用户在主窗口内点击鼠标左键时,光标的移动范围将被限制在主窗口之内,而且被隐藏掉。用户可以通过点
击设备右键来重新显示光标。当光标被移动到 trap 窗口上时,光标将被“抓住”在这个黑色的窗口范围之内*/

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#define IDC_TRAP 100

static HWND hTrapWin, hMainWnd;
static RECT rcMain, rc;

/* “trap”控件类的窗口过程 */
static int TrapwindowProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    static BOOL bTrapped = FALSE;
    switch (message) {
        case MSG_MOUSEMOVE: //因为是光标所在窗口 所以是客户区坐标
            /* 当鼠标进入该控件范围时,进一步限制在控件范围内 */
            if (!bTrapped) {
                GetWindowRect(hWnd, &rc);
                ClientToScreen(hMainWnd, &rc.left, &rc.top); //客户区转屏幕坐标
                ClientToScreen(hMainWnd, &rc.right, &rc.bottom);
                ClipCursor(&rc); //但是限定光标的函数又是屏幕坐标
                bTrapped = TRUE;
            }
            break;
        case MSG_DESTROY:
            return 0;
}
	return DefaultControlProc(hWnd, message, wParam, lParam);
}

/* 注册“trap”控件类 */
BOOL RegisterTrapwindow (void)
{
    WNDCLASS WndClass;
    WndClass.spClassName = "trap";
    WndClass.dwStyle = 0;
    WndClass.dwExStyle = 0;
    WndClass.hCursor = GetSystemCursor(IDC_HAND_POINT); //类光标 当创建的实体没有设置光标时 用这个光标 控件里面显示的光标
    WndClass.iBkColor = PIXEL_black;
    WndClass.WinProc = TrapwindowProc;
    return RegisterWindowClass (&WndClass);
}

static int CursordemoWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
    case MSG_CREATE:
        RegisterTrapwindow();
        hTrapWin = CreateWindow("trap", "", WS_VISIBLE | WS_CHILD, IDC_TRAP,10, 10, 100, 		 100, hWnd, 0);
        break;
    case MSG_LBUTTONDOWN:
        GetWindowRect(hWnd, &rcMain); //得到该窗口的矩形区域
        ClipCursor(&rcMain);//将光标限定在该窗口区域内
        ShowCursor(FALSE);//影藏光标
        break;
    case MSG_RBUTTONDOWN:
        ShowCursor(TRUE); //鼠标右键显示光标
        break;
    case MSG_SETCURSOR: //鼠标移动时会产生这个消息 这是在父窗口的光标形状
        SetCursor (GetSystemCursor (IDC_IBEAM)); //设置光标形状
        return 0;
    case MSG_CLOSE:
        DestroyAllControls (hWnd);
        DestroyMainWindow (hWnd);
        PostQuitMessage (hWnd);
        return 0;
}
    return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/* 以下创建主窗口的代码从略 */

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6cXjctEl-1665327187735)(C:\Users\cjy\AppData\Roaming\Typora\typora-user-images\image-20221009222506955.png)]

5.光标API和消息

函数说明
LoadCursorFromFile从光标文件加载光标到内存
LoadCursorFromMem从内存加载光标
CreateCursor在内存创建光标
GetSystemCursor从系统加载光标
ShowCursor显示或隐藏光标
GetCursorPos得到光标位置 屏幕坐标
SetCursorPos设置光标位置 屏幕坐标
ClipCursor限定光标范围 在一个矩形区域内
GetClipCursor得到限定光标的范围
GetCurrentCursor得到当前光标
SetCursorEx设置光标
SetCursor设置光标 不对缺省光标有效
SetDefaultCursor设置光标 对缺省光标有效
GetWindowCursor得到窗口光标 包括控件,控件也是窗口的一种
SetWindowCursor设置窗口光标
DestroyCursor销毁光标
消息说明消息的产生消息的接收
MSG_SETCURSOR可以在处理该消息时改变当前的光标当用户移动鼠标时光标下面的窗口
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值