MINIGUI(1)-在新的页面建立控件、显示控件、触发控件

一个界面进来首先要先进入初始化函数
例:

int ui_password_init(HWND hParent)
{
    sg_PasswordDlg.controls = sg_ctrlsg_PasswordDlg;
    sg_PasswordDlg.controlnr = TABLESIZE(sg_ctrlsg_PasswordDlg);
    DialogBoxIndirectParam (&sg_PasswordDlg, hParent, uiPasswordProc, 0L);

return LL_INDOOR_SUCCESS;
}

可以看出,进入初始化函数之前需要给定参数HWND hParent,这个为父窗口的句柄。

再去分析初始化函数内所需的变量,以上面代码为例,需要对话框结构体sg_PasswordDlg页面内所使用的控件sg_ctrlsg_PasswordDlg页面回调函数uiPasswordProc,一个个分析。

在进入初始化函数之前首先要定义对话框结构体(例如例子中的sg_PasswordDlg)。

接下来看一下这个sg_PasswordDlg的结构

static DLGTEMPLATE sg_PasswordDlg=
{
    WS_VISIBLE ,
    WS_EX_NONE/* | WS_EX_AUTOSECONDARYDC*/,
    0,0,272,480,
    "",
    0, 0,
    0, NULL,
    0
};

可以看出,这里定义了对话框的属性、起始坐标与宽高(一般照搬之后改一下宽高就行)。

再回到初始化函数,通过**sg_PasswordDlg.controls = sg_ctrlsg_PasswordDlg;**对对话框使用的控件进行了指定;

接下来看一下这个sg_ctrlsg_PasswordDlg这里面定义了什么。

static CTRLDATA sg_ctrlsg_PasswordDlg[] =
{
    //密码
    {
    CTRL_STATIC,
    WS_CHILD | WS_VISIBLE | SS_LEFT,
    13,77,180,48,
    ID_STATIC_PRIVATE_PASSWORD_CLICKED_PICTURE,
    "",
    0,
    WS_EX_TRANSPARENT
       },
    //密码按钮
    {
    CTRL_BUTTON,
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    13,60,220,48,
    ID_PUSHBUTTON_PRIVATE_PASSWORD,
    "",
    0,
    WS_EX_TRANSPARENT
    },
    /*余下控件省略*/
}

可以看出,这里面定义了一系列的控件,以第一个为例介绍

//密码
{
    CTRL_STATIC,
    WS_CHILD | WS_VISIBLE | SS_LEFT,
    13,77,180,48,
    ID_STATIC_PRIVATE_PASSWORD_CLICKED_PICTURE,
    "",
    0,
    WS_EX_TRANSPARENT
},

简单来说这里定义了控件的属性、坐标与宽高,同时还指定了控件的ID:ID_STATIC_PRIVATE_PASSWORD_CLICKED_PICTURE
其余细节可参考官方的windows.h中定义的结构

/** Class name of the control */
const char* class_name;             
/** Control style */
DWORD       dwStyle;                
/** Control position in dialog */
int         x, y, w, h;             
/** Control identifier
* \note The type changed from int to LINT since v3.2.
*/
LINT         id;                     
/** Control caption */
const char* caption;                
/** Additional data */
DWORD       dwAddData;              
/** Control extended style */
DWORD       dwExStyle;              

/** window element renderer name */
const char* werdr_name;

/** table of we_attrs */
const WINDOW_ELEMENT_ATTR* we_attrs;

这里的这个ID要着重说明一下,我们需要在该UI文件中定义一个枚举类型,专门用来收纳各个控件,同时也可满足对空间ID的定义,例如以下:

typedef enum {
    ID_STATIC_COMMON_PASSWORD                 ,   /*通用密码 文字*/
    ID_PUSHBUTTON_COMMON_PASSWORD              ,   /*通用密码 选框*/
    /*其余省略*/
}SYSSETING_PWD_DEFINE;

这样再回到最开始的初始化函数就可以发现控件的相关定义就已经完成了,就下来就剩一个控件回调函数uiPasswordProc了。

static int uiPasswordProc (HWND hDlg, int nMessage, WPARAM wParam, LPARAM lParam)
{
    int i;
    g_bUIRun = TRUE;//防止UI界面死掉
    switch (nMessage)
    {
    case MSG_CREATE:
    {
        sg_hPasswordDialog = hDlg;
        break;
    }
    case MSG_PAINT:
    {
        HDC hdc = BeginPaint(hDlg);
        RECT rect;
        HWND hWnd;
        //获取无效区域
        GetUpdateRect(hDlg, &rect);
        HDC Hdc = CreateCompatibleDC(hdc);
        
        /*绘制文字*/
        hWnd = GetDlgItem(hDlg, ID_STATIC_PRIVATE_PASSWORD_CLICKED_PICTURE);
        if (hWnd)
        {
            SelectFont (hdc, default_font[MAIN_FONT_SIZE_17]);
            GetWindowRect(hWnd, &rc);
            DrawText(hdc, "一户一密码", -1, &rc, DT_LEFT| DT_VCENTER );
        }
        
        /*绘制图片*/
        FillBoxWithBitmap(hdc,200,72,
                          bmp_setting[xxx].bmWidth, bmp_setting[xxx].bmHeight,
                          &bmp_setting[xxx]);
        
        /*绘制纯色矩形*/
        SetBrushColor(hdc, RGB2Pixel (HDC_SCREEN, 0xCE, 0xC9, 0xC9));
        FillBox(hdc,0,59,272,1);
        
        BitBlt(Hdc,rect.left,rect.top,RECTW(rect),RECTH(rect),hdc,rect.left,rect.top,0);
        DeleteCompatibleDC(Hdc);
        EndPaint(hDlg,hdc);
        break;
    }
    case MSG_ERASEBKGND:
    {
        return 0;
    }
    case MSG_INITDIALOG:
    {
        /*省略*/
    }
    case MSG_SOFEKEY_SLEDIT_SAVE:
    {
        PostMessage(hDlg,MSG_COMMAND,ID_PUSHBUTTON_OK_PASSWORD,NULL);
        break;
    }
    case MSG_COMMAND://按键触发
    {
        int nCmdId = LOWORD (wParam);
        int nNc = HIWORD (wParam);
        HWND hWnd = GetDlgItem(hDlg, nCmdId);
        if (BN_CLICKED != nNc)
        {
            break;
        }
        //按下按钮后会一直处于hilit状态,需要清除一下
        PostMessage(hWnd, BM_SETSTATE, 0, 0);
        keySound();
        switch (nCmdId)
        {
        case ID_PUSHBUTTON_COMMON_PASSWORD :/*密码*/
        {
            /*省略业务逻辑*/
        }
        /*省略其余控件*/
        default:
        {
            break;
        }
        }
        break;
    }
    case MSG_LBUTTONDOWN:
    {
        static int pre_x, pre_y;
        pre_x = LOWORD (lParam);
        pre_y = HIWORD (lParam);
        break;
    }
    case MSG_DESTROY:
    {
        sg_hPasswordDialog = 0;
        SetIMEStatus(IME_STATUS_ENABLED, FALSE);
        SetIMEStatus(IME_STATUS_AUTOTRACK, FALSE);
        break;
    }
    case MSG_CLOSE:
    {
        EndDialog(hDlg, 0);
        break;
    }
    }
    return DefaultDialogProc (hDlg, nMessage, wParam, lParam);
}

这个回调函数很长,但可以分成几个部分来看

首先是在页面生成的时候会按顺序执行MSG_CREATEMSG_INITDIALOGMSG_PAINT内语句,MSG_INITDIALOG一般进行业务逻辑的初始化,MSG_PAINT内进行页面内控件的绘制;

以绘制文字、绘制图片、绘制纯色矩形为例介绍,代码如下

        /*绘制文字*/
        hWnd = GetDlgItem(hDlg, ID_STATIC_PRIVATE_PASSWORD_CLICKED_PICTURE);
        if (hWnd)
        {
            SelectFont (hdc, default_font[MAIN_FONT_SIZE_17]);
            GetWindowRect(hWnd, &rc);
            DrawText(hdc, "一户一密码", -1, &rc, DT_LEFT| DT_VCENTER );
        }
        
        /*绘制图片*/
        FillBoxWithBitmap(hdc,200,72,
                          bmp_setting[xxx].bmWidth, bmp_setting[xxx].bmHeight,
                          &bmp_setting[xxx]);
        
        /*绘制纯色矩形*/
        SetBrushColor(hdc, RGB2Pixel (HDC_SCREEN, 0xCE, 0xC9, 0xC9));
        FillBox(hdc,0,59,272,1);

再回到回调函数uiPasswordProc,然后根据不同控件nCmdId的触发,调用switch函数选择性的执行MSG_COMMAND内的指令,在执行命令后会再次调用MSG_PAINT对界面进行刷新重绘

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值