前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >minigui/mgncs:解决Spinbox字体设置无效问题

minigui/mgncs:解决Spinbox字体设置无效问题

作者头像
10km
发布2019-05-25 21:48:13
5700
发布2019-05-25 21:48:13
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433552

minigui/ncs控件集中的Spinbox控件存在一个问题,如下图,即使设置了字体,在运行时也不会应用指定的字体。

通过查看libmgncs-1.2.0的源码,找到了原因,Spinbox控件中用于显示数字的子控件是SLEdit

以下是mspinbox.c代码片段,createBody用于创建子控件,可以看到editor为一个SLEdit对象

代码语言:javascript
复制
static mObject* mSpinBox_createBody(mSpinBox *self)
{
    mObject *body;
    DWORD dwStyle = GetWindowStyle(self->hwnd);
    NCS_EVENT_HANDLER editor_handlers[] = {
        {MSG_CHAR, editor_onChar},
        {MSG_SETPIECE_PROPERTY, editor_onSetPieceProperty},
        {NCS_NOTIFY_CODE(NCSN_EDIT_CHANGE), editor_onChanged},
        {0, NULL}
    };
    //create a editor
    mWidget * editor = ncsCreateWindow(NCSCTRL_SLEDIT, "",
        spinbox_style_to_editor_style(dwStyle),
        WS_EX_NONE,
        100,
        0, 0, 0, 0,
        self->hwnd,
        NULL,
        NULL, //rdr_info
        editor_handlers, //handlers,
        (DWORD)self);

    body = create_pieces(self, editor, dwStyle);

    return body;
}

SLEdit本身是可以正常响应MSG_FONTCHANGED消息的,但是Spinbox作为容器控件并没有处理MSG_FONTCHANGED消息。所以SLEdit作为子控件根本收不到MSG_FONTCHANGED消息的,也就无法改变字体,只能使用默认的系统字体。

以下是mSpinBox.c的消息处理函数,可以看出,mSpinBox只处理了MSG_SETFOCUSMSG_KILLFOCUS消息,就把控制权交给了父类(mSpinner)的消息处理函数。

代码语言:javascript
复制
static LRESULT mSpinBox_wndProc (mSpinBox* self, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message) {
        case MSG_SETFOCUS:
        {
            if ((GetWindowStyle(self->hwnd) & NCSS_SPNBOX_AUTOFOCUS))
                SetFocusChild (GetDlgItem(self->hwnd, 100));
            break;
        }
        case MSG_KILLFOCUS:
        {
            SendDlgItemMessage (self->hwnd, 100, MSG_KILLFOCUS, 0, 0);
            break;
        }
        default:
        break;
    }
    return Class(mSpinner).wndProc((mSpinner*)self, message, wParam, lParam);
}

知道原因就有了解决办法

解决方案1

修改libmgncs-1.2.0的源码,修改上面的mSpinBox_wndProc函数,增加对MSG_FONTCHANGED消息的处理:

代码语言:javascript
复制
// 判断logfont是否为系统字体
static inline BOOL is_system_font(PLOGFONT logfont)
{
    if(logfont){
        for(int font_id = 0; font_id < NR_SYSLOGFONTS; ++font_id)
        {
            if(logfont == g_SysLogFont[font_id])
            {
                return TRUE;
            }

        }
    }
    return FALSE;
}

static LRESULT mSpinBox_wndProc (mSpinBox* self, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message) {
        case MSG_SETFOCUS:
        {
            if ((GetWindowStyle(self->hwnd) & NCSS_SPNBOX_AUTOFOCUS))
                SetFocusChild (GetDlgItem(self->hwnd, 100));
            break;
        }
        case MSG_KILLFOCUS:
        {
            SendDlgItemMessage (self->hwnd, 100, MSG_KILLFOCUS, 0, 0);
            break;
        }
        case MSG_FONTCHANGED:
        {
            // 为SLEdit控件创建字体
            PLOGFONT self_font = GetWindowFont(self->hwnd);
            // 如果是系统字体直接使用否则要创建一个副本
            PLOGFONT editor_font = is_system_font(self_font)
                ? self_font
                : CreateLogFontIndirect(self_font);
            // 设置SLEdit字体,100为SLEdit控件的ID
            PLOGFONT of = SetWindowFont (GetDlgItem(self->hwnd, 100), editor_font);
            // 如果原字体不是系统字体,则销毁原字体,不能销毁系统字体
            if(!is_system_font(of)){
                DestroyLogFont(of);
            }
            return FALSE;
        }
        default:
        break;
    }
    return Class(mSpinner).wndProc((mSpinner*)self, message, wParam, lParam);
}

解决方案2

修改自己的UI界面代码,在mSpinBox收到MSG_FONTCHANGED消息时设置SLEdit控件字体

代码与方案1相同,只是放在了了应用程序的onFontChanged

代码语言:javascript
复制
static inline BOOL is_system_font(PLOGFONT logfont)
{
    if(logfont){
        for(int font_id = 0; font_id < NR_SYSLOGFONTS; ++font_id)
        {
            if(logfont == g_SysLogFont[font_id])
            {
                return TRUE;
            }

        }
    }
    return FALSE;
}
//$func @2628714496 onFontChanged -- Need by merge, don't modify
static void Spinbox1_onFontChanged (mWidget* self, UINT message) 
{
    PLOGFONT self_font = GetWindowFont(self->hwnd);
    // 如果是系统字体直接使用否则要创建一个副本
    PLOGFONT editor_font = is_system_font(self_font)
            ? self_font
            : CreateLogFontIndirect(self_font);
    mWidget* editor = ncsGetChildObj(self->hwnd,100);
    PLOGFONT of = SetWindowFont(editor->hwnd,editor_font);
//          PLOGFONT of = SetWindowFont (GetDlgItem(self->hwnd, 100), editor_font);
    if(!is_system_font(of)){
        DestroyLogFont(of);
    }
}

//$handle @2628714496 -- Need by merge, don't modify
static NCS_EVENT_HANDLER Spinbox1_handlers [] = {
    {MSG_FONTCHANGED,Spinbox1_onFontChanged},
    //$user -- TODO add your handlers here
    {-1,NULL}
};

执行结果:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年07月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解决方案1
  • 解决方案2
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档