minigui/ncs控件集中的Spinbox
控件存在一个问题,如下图,即使设置了字体,在运行时也不会应用指定的字体。
通过查看libmgncs-1.2.0的源码,找到了原因,Spinbox
控件中用于显示数字的子控件是SLEdit
,
以下是mSpinBox.c代码片段,createBody
用于创建子控件,可以看到editor
为一个SLEdit
对象
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_SETFOCUS
,MSG_KILLFOCUS
消息,就把控制权交给了父类(mSpinner
)的消息处理函数。
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
消息的处理:
// 判断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 editor_font = CreateLogFontIndirect(GetWindowFont(self->hwnd)); // 设置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
中
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 modifystatic void Spinbox1_onFontChanged (mWidget* self, UINT message) { PLOGFONT editor_font =CreateLogFontIndirect(GetWindowFont(self->hwnd)); 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 modifystatic NCS_EVENT_HANDLER Spinbox1_handlers [] = { {MSG_FONTCHANGED,Spinbox1_onFontChanged}, //$user -- TODO add your handlers here {-1,NULL} };
执行结果:
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦