miniGUI学习笔记二

五.控件基础编程
1.控件的概念:所有的子窗口都是控件
特点:与主窗口一致,但是其行为限制在主窗口内

2.利用预定义类创建控件实例
创建一个控件
HWND GUIAPI CreateWindowEx2 (const char* spClassName,const char* spCaption, DWORD dwStyle, DWORD dwExStyle,int id, int x, int y, int w, int h, HWND hParentWnd,const char* werdr_name, const WINDOW_ELEMENT_ATTR* we_attrs,DWORD dwAddData);
static inline HWND GUIAPI CreateWindowEx (const char* spClassName,const char* spCaption, DWORD dwStyle, DWORD dwExStyle,int id, int x, int y, int w, int h, HWND hParentWnd,DWORD dwAddData)
{
    return CreateWindowEx2 (spClassName, spCaption, dwStyle, dwExStyle,id, x, y, w, h, hParentWnd, NULL, NULL, dwAddData);
}
参数 add_data用来向控件传递其特有数据的指针,该指针所指向的数据结构随控件类的不同而不同

#define CreateWindow(class_name, caption, style, id, x, y, w, h, parent, add_data) CreateWindowEx(class_name, caption, style, 0, id, x, y, w, h, parent, add_data)
销毁一个控件
BOOL GUIAPI DestroyWindow (HWND hWnd);

3.控件编程涉及的内容
3.1 相关的函数 ShowWindow、 MoveWindow、 EnableWindow、 SetWindowFont
3.2 控件内部发生某种事件时,会通过通知消息通知其父窗口
注:如果在创建过程中有相应的回调函数,则给回调函数处理,否则由父窗口处理
3.3 MSG_COMMAND消息
   wParam 参数由子窗口标识符(低16位)和通知码组成(高16位)
   lParam 参数含有发出通知消息的控件句柄。
   例:若在编辑框发生改变,则向父窗口发出MSG_COMMAND消息,标识符为该编辑框在父窗口的id,通知码为EN_CHANGE
   
  SetNotificationCallback 
  static void my_notif_proc (HWND hwnd, int id, int nc, DWORD add_data);//控件过程回调函数
  SetNotificationCallback (GetDlgItem (hDlg, IDC_SIZE_MM), my_notif_proc);
  SetWindowAdditionalData (hDlg, lParam);
  double* length = (double*) GetWindowAdditionalData (hDlg);
  
3.4控件专用的操作函数
GetNotificationCallback 获取控件的通知消息回调函数
SetNotificationCallback 设置控件的通知消息回调函数
NotifyParentEx 发送控件通知消息


六.控件的高级编程
1.自定义控件
 RegisterWindowClass
 UnregisterWindowClass 
2.控件的子类化
    • 一种是对已经建立的控件实例进行子类化,子类化的结果只会影响这一个控件实例。
    • 一种是对某个控件类进行子类化,将影响其后创建的所有该控件类的控件实例。
    • 最后一种是在某个控件类的基础上新注册一个子类化的控件类,不会影响原有控件类。 在 Windows 中,这种技术
    又称为超类化。
方法:在主窗口内,用自定义的窗口过程替换编辑框的窗口过程,并保存老的窗口过程(可以是编辑框默认的窗口过程,也可以是用户封装过的窗口过程)
old_edit_proc = SetWindowCallbackProc (hWnd1, RestrictedEditBox);
SetWindowCallbackProc (hWnd2, RestrictedEditBox);

问题:那么控件的过程处理是什么,而我需要自定义一个控件到底该怎么做

 
十九.静态框
1.什么是静态框
    1.1 用于在窗口特定位置显示文字、数字或者图片
    1.2 静态框不能对用户的输入进行动态的响应
    1.3 控件名称: CTRL_STATIC  或者 "static"

2.标准型
SS_SIMPLE、 SS_LEFT、 SS_CENTER、 SS_RIGHT,以及 SS_LEFTNOWORDWRAP
SS_SIMPLE:单行文本,不会自动换行显示,左对齐
SS_LEFT、 SS_CENTER 或 SS_RIGHT:多行文本 左对齐、中对齐和右对齐显示
SS_LEFTNOWORDWRAP: 静态框会扩展文本中的 TAB 符,但不做自动换行处理。
创建一个标准型静态框
CreateWindow (CTRL_STATIC,"This is a simple static control.",WS_CHILD | SS_NOTIFY | SS_SIMPLE | WS_VISIBLE | WS_BORDER,IDC_STATIC1,10, 10, 180, 20, hWnd, 0);

3.位图型 ---- SS_BITMAP  SS_ICON
 dwAddData 参数设定要显示的位图对象指针或者图标对象句柄。
 默认情况下,位图和图标要经过适当的缩放充满整个静态框
 SS_REALSIZEIMAGE 风格将取消缩放操作,并显示在静态框的左上方
 SS_REALSIZEIMAGE | SS_CENTERIMAGE 会在控件中部显示位图或图标。
 
 创建一个位图型控件
 CreateWindow (CTRL_STATIC,"",WS_CHILD | SS_BITMAP | WS_VISIBLE,IDC_STATIC,280, 80, 50, 50, hWnd, (DWORD)GetSystemBitmap (SYSBMP_CHECKMARK));
 创建一个图标型控件
 CreateWindow (CTRL_STATIC,"",WS_CHILD | SS_ICON | WS_VISIBLE,IDC_STATIC,280, 20, 50, 50, hWnd, (DWORD)GetLargeSystemIcon (IDI_INFORMATION));
 
4.分组框 ------ SS_GROUPBOX
创建一个分组框对话框
CreateWindow (CTRL_STATIC,"A Group Box",WS_CHILD | SS_GROUPBOX | WS_VISIBLE,IDC_STATIC,350, 10, 200, 100, hWnd, 0);

5.其它类型风格对话框
• SS_WHITERECT:以白色填充静态框矩形。
• SS_GRAYRECT:以灰色填充静态框矩形。
• SS_BLACKRECT:以黑色填充静态框矩形。
• SS_GRAYFRAME:灰色边框。
• SS_WHITEFRAME:白色边框。
• SS_BLACKFRAME:黑色边框。 

6.静态框消息
获得或者修改静态框的位图:
STM_GETIMAGE 获得静态框消息
STM_SETIMAGE 通过 wParam 参数重新设置位图指针或者图标句柄,并且返回原来的指针
意思是发消息的时候,想要修改静态框的图标,在wParam参数那里,传入图标的句柄

7.静态框消息通知码
当风格含有:SS_NOTIFY
STN_DBLCLK:表示用户在静态框内双击了鼠标左键
STN_CLICKED:表示用户在静态框内单击了鼠标左键

二十.按钮
1.普通按钮 ---- BS_PUSHBUTTON 和 BS_DEFPUSHBUTTON
    1.1对话框: BS_DEFPUSHBUTTON 默认接收 ENTER 键输入的按钮
    1.2普通主窗口:BS_DEFPUSHBUTTON 边框要粗
    1.3按钮文本会以单行的形式在垂直和水平方向居中显示,不会自动换行。
        自动换行: BS_MULTILINE 垂直向上对齐
    1.4BS_BITMAP 或者 BS_ICON 默认情况下位图或图标会缩放显示以充满整个按钮窗口范围
    创建一个带位图的按钮
    hwnd = CreateWindow (CTRL_BUTTON,"Close",WS_CHILD | BS_PUSHBUTTON | BS_BITMAP |BS_REALSIZEIMAGE | BS_NOTIFY | WS_VISIBLE,IDC_BUTTON + 4,10, 300, 60, 30, hWnd, (DWORD) GetSystemBitmap (IDI_APPLICATION));

2.复选框
    BS_CHECKBOX 和 BS_AUTOCHECKBOX
    BS_CHECKBOX : 应用程序需要自己向该控件发送消息来设定选中标记
    BS_AUTOCHECKBOX : 控件会自动在选中和非选中状态之间切换
    BS_3STATE 和 BS_AUTO3STATE 第三种状态是灰色的
    BS_LEFTTEXT 使复选框靠右对齐
    BS_LEFT、 BS_CENTER、 BS_RIGHT、 BS_TOP、 BS_VCENTER、 BS_BOTTOM
    BS_PUSHLIKE 风格将使复选框以普通按钮的形式显示:选中时显示为按下状态,未选中时显示为正常状态

3.单选钮 ------  BS_RADIOBUTTON 或 BS_AUTORADIOBUTTON
    每一个按钮都对应一个频道,而且一次只能有一个按钮被按下;相互排斥;当第二次按单选按钮时,它的状态会保持不变
    注:这句话没有理解: BS_PUSHLIKE 风格将使单选按钮以普通按钮的形式显示:选中时显示为按下状态,未选中时显示为正常状态
    3.1 创建一个单选钮
    CreateWindow (CTRL_BUTTON,"Auto Radio Button 2",WS_CHILD | BS_AUTORADIOBUTTON | WS_VISIBLE,IDC_RADIOBUTTON + 1,20, 160, 130, 30, hWnd, 0);

4.按钮消息
    查询/设置复选框或者单选钮的选中状态: BM_GETCHECK、 BM_SETCHECK
    查询/设置普通按钮或者复选框的按下或释放状态: BM_GETSTATE、 BM_SETSTATE
    获取/设置位图按钮上的位图或者图标: BM_GETIMAGE、 BM_SETIMAGE
    发送 BM_CLICK 模拟用户鼠标的单击操作

设置按钮选中状态
    SendMessage (hwndButton, BM_SETCHECK, BST_CHECKED, 0);
    wParam:BST_UNCHECKED(0) 未选中
            BST_CHECKED(1) 已选中
            BST_INDETERMINATE(2) 不可用状态
    得到状态,可以选用BM_GETCHECK
    
设置按钮按下和释放状态
    模拟按钮来回闪动: SendMessage (hwndButton, BM_SETSTATE, BST_PUSHED, 0) ;
                      SendMessage (hwndButton, BM_SETSTATE, 0, 0) ;
                      
获取位图和图标信息
    int ret_val = SendMessage (hwndButton, BM_GETIMAGE, (WPARAM)&image_type, 0) ;
设置位图和图标信息
    int ret_val = SendMessage (hwndButton, BM_SETIMAGE, BM_IMAGE_BITMAP, btn_bmp) ;
    SendMessage (hwndButton, BM_SETIMAGE, BM_IMAGE_ICON, btn_icon) ;
    PBITMAP btn_bmp
    HICON btn_icon;
    
5.消息通知码
    BS_NOTIFY
    BN_CLICKED:表明用户单击此按钮。
    如果是在父窗口传递过来的:只需判断 MSG_COMMAND 消息的 wParam 参数是否等于按钮的标识符即可
    BN_PUSHED:表明用户将此按钮按下
    BN_UNPUSHED:表明用户将此按钮释放
    BN_DBLCLK:表明用户在此按钮上进行了鼠标左键的双击操作。
    BN_SETFOCUS:表明按钮获得了输入焦点。
    BN_KILLFOCUS:表明按钮失去了输入焦点。

三十章.滚动型控件 ------ ScrollView
1.滚动型控件概念 
   滚动型控件中滚动显示的是列表项而不是控件
   滚动型的主要用途: 是显示和处理列表
   滚动型中的列表高度是可以由用户指定的,不同的列表项显示不同的高度
   
2.控件风格
    在控件风格中 SVS_AUTOSORT scrollview style
    则可以如下写:
    SVM_SETITEMCMP myItemCmp;
    SendMessage (hScrWnd, SVM_SETITEMCMP, 0, (LPARAM)myItemCmp);
    SVM_SETITEMCMP的原型如下
    typedef int (*SVITEM_CMP) (HSVITEM hsvi1, HSVITEM hsvi2);
对不具有 SVS_AUTOSORT
    SVM_SETITEMCMP myItemCmp;
    SendMessage (hScrWnd, SVM_SORTITEMS, 0, (LPARAM)myItemCmp);

3.滚动型控件消息
    滚动型控件的相关消息主要用于列表项的添加、删除和访问等方面
    3.1 列表项控件显示
        SVITEM_DRAWFUNC myDrawItem;
        SendMessage (hScrWnd, SVM_SETITEMDRAW, 0, (LPARAM)myDrawItem);
        typedef void (*SVITEM_DRAWFUNC) (HWND hWnd, HSVITEM hsvi, HDC hdc, RECT *rcDraw);
                    滚动型窗口句柄  列表项句柄  图形设备上下文 列表项绘制的矩形区域
  
    3.2 列表项操作函数的设置
        SVITEMOPS myops;
        SendMessage (hScrWnd, SVM_SETITEMOPS, 0, (LPARAM)&myops);
        typedef struct _svitem_operations
        {
            SVITEM_INITFUNC initItem; 
            SVITEM_DESTROYFUNC destroyItem;
            SVITEM_DRAWFUNC drawItem;
        }SVITEMOPS;
        创建列表项的初始化函数的句柄:typedef int (*SVITEM_INITFUNC) (HWND hWnd, HSVITEM hsvi);
        销毁列表项的初始化函数的句柄:typedef void (*SVITEM_DESTROYFUNC) (HWND hWnd, HSVITEM hsvi);
        
    3.3 列表项的操作
        增加一个列表项
        SVM_ADDITEM 和 SVM_DELITEM 消息分别用来添加和删除一个列表项
        int idx;
        HSVITEM hsvi; //滚动型控件列表项
        SVITEMINFO svii; //每一项滚动型控件列表项信息
        Idx = SendMessage (hScrWnd, SVM_ADDITEM, (WPARAM)&hsvi, (LPARAM)&svii);
        
        typedef struct _SCROLLVIEWITEMINFO
        {
            int nItem; //item的标识符
            int nItemHeight;//item的高
            DWORD addData; //item的额外数据
        }SVITEMINFO;
        nItem 项为列表项的添加位置,如果 nItem 为负值,列表项将被添加到末尾
        SVM_ADDITEM 消息返回所添加列表项的实际索引值
        
        删除一个列表项
        int idx;
        HSVITEM hsvi;
        SendMessage (hScrWnd, SVM_DELITEM, idx, hsvi);
        hsvi 指定所要删除的列表项的句柄。如果 hsvi为0,idx 指定所要删除的列表项的索引值。
        
        刷新一个列表项
        int idx;
        HSVITEM hsvi;
        SendMessage (hScrWnd, SVM_REFRESHITEM, idx, hsvi);
        
        获取列表项的附加数据
        SendMessage (hScrWnd, SVM_GETITEMADDDATA, idx, hsvi);
        
        设置列表项的附加数据
        int idx;
        DWORD addData;
        SendMessage (hScrWnd, SVM_SETITEMADDDATA, idx, addData);
        
        获取当前列表项的数量
        int count = SendMessage (hScrWnd, SVM_GETITEMCOUNT, 0, 0);
        
        SVM_RESETCONTENT 消息用来删除掉控件中所有的列表项
        SendMessage (hScrWnd, SVM_RESETCONTENT, 0, 0);
    
    3.4获取和设置当前高亮项
        滚动型控件具有一个高亮列表项属性,列表项中仅有(如果有的话)一个列表项是当前高亮的列表项
        设置控件的高亮列表项
        SendMessage (hScrWnd, SVM_SETCURSEL, idx, bVisible);
        获取控件的当前高亮列表项
        int hilighted_idx = SendMessage (hScrWnd, SVM_GETCURSEL, 0, 0);
        
    3.5列表项的选择和显示
        高亮是唯一的,选中不是唯一的
        列表项的选择
        SendMessage (hScrWnd, SVM_SELECTITEM, idx, bSel);
        idx 指定所要设置的列表项的索引值。 bSel 如果为 TRUE,该列表项将被设置为选中;反之为非选中。
        
        列表项的显示
        SendMessage (hScrWnd, SVM_SHOWITEM, idx, hsvi);
        
        列表项的选择和显示
        SendMessage (hScrWnd, SVM_CHOOSEITEM, idx, hsvi);
        SVM_CHOOSEITEM 消息是 SVM_SELECTITEM 和 SVM_SHOWITEM 的组合
        
        显示的优化 ---- MSG_FREEZE 的 wParam 参数为TURE则是冻结,反之是解冻
        用于的场合:在使用 SVM_ADDITEM 消息或者 SVM_DELITEM 消息一次性增加或者删除很多列表项时,可以使用 MSG_FREEZE 消息进行一定的优化。用法是在操作之前冻结控件,操作之后解冻。

    3.6设置可见区域范围
      滚动型控件由内到外 可视区域  ---->  边缘区域  ------>  内容区域
      SVM_SETMARGINS 消息可以对滚动型控件的边缘范围进行设置
      
      设置边缘区域
      RECT rcMargin;
      SendMessage (hScrWnd, SVM_SETMARGINS, 0, (LPARAM)&rcMargin);
      获取边缘区域的值
      RECT rcMargin;
      SendMessage (hScrWnd, SVM_GETMARGINS, 0, (LPARAM)&rcMargin);
      SVM_GETLEFTMARGIN、SVM_GETTOPMARGIN、SVM_GETRIGHTMARGIN 和 SVM_GETBOTTOMMARGIN 消息分别用来获取左、上、右和下边缘值。
      
4.控件通知码
      SVN_SELCHANGED:当前高亮列表项发生改变 ----- 被点击或当前的列表项
      SVN_CLICKED:用户点击列表项
      SVN_SELCHANGING:当前高亮列表项正发生改变  ----- 先前的高亮列表项句柄

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值