您的位置:程序门 -> vc/mfc -> 界面



listbox的中onmeasureitem计算文本的高度出现问题,setfont  还是 gettextmetrics


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


listbox的中onmeasureitem计算文本的高度出现问题,setfont 还是 gettextmetrics[已结贴,结贴人:bborn]
发表于:2007-07-18 17:55:48 楼主
自绘一个listbox   使其支持多行显示

开始setfont   一个字体
然后在   onmeasureitem   中   计算文本的高度
但在这里   gettextmetrics   得到的文字高度和设置的字体不一致
通过
drawtext(   ......,dt_wordbreak   ¦   dt_calcrect   );
得到的大小也是默认字体的合适大小
就是说   不用   setfont   就能正常显示  
用   setfont   设置一个大号的字体后
就显示不全了

如何让drawtext   通过不同的font计算不同的大小
发表于:2007-07-18 18:51:501楼 得分:20
在setonsetfont中
lresult   res   =     default();

crect   rc;
getwindowrect(   &rc   );

windowpos   wp;
wp.hwnd   =   m_hwnd;
wp.cx   =   rc.width();
wp.cy   =   rc.height();
wp.flags   =   swp_noactivate   ¦   swp_nomove   ¦   swp_noownerzorder   ¦   swp_nozorder;
sendmessage(   wm_windowposchanged,   0,   (lparam)&wp   );

return   res;
在measureitem中,
logfont   lf;
getfont()-> getlogfont(   &lf   );

if(   lf.lfheight   <   0   )
lpmeasureitemstruct-> itemheight   =   -lf.lfheight;
else
lpmeasureitemstruct-> itemheight   =   lf.lfheight;
好的,别忘给分!
发表于:2007-07-18 21:08:332楼 得分:0
依然不行     能否解释一下代码

我的问题是
1   setfont   字体
2   在   onmeasureitem   中   计算文本的输出区域   得到的值还是未使用setfont前的值
    drawtext(   ......,dt_wordbreak   ¦   dt_calcrect   );
3   在   ondrawitem   中   drawtext   显示的是   setfont   的字体

现在就是在2中,     如何计算到setfont后   字体的显示大小
发表于:2007-07-19 11:00:253楼 得分:0
当你改变你的字体时,控件并不会自己改变行高来适应你的字体,既没有   wm_measureitem被发送,造成字体改变了,但是控件的行高不能用了.主要是如何产生   wm_measureitem消息.
该方法的主要思想是,当调用cwnd::setfont()方法时,会发送wm_setfont   ,在处理消息wm_setfont   中,我们发送wm_windowposchanged来欺骗windows,让他认为窗口大小改变,产生wm_measureitem消息.因为这个消息是子窗口发给父窗口的,所以我们用消息反射,这个用类向导没发添加我们想要的,只有手工消息映射中添加on_wm_measureitem_reflect().
        这主要是改变控件的行高来适应字体变化.注意,如果onsetfont   没有和wm_font联系,也要在消息处理中添加   on_message(wm_setfont,   onsetfont).
      上面的方法不中的话再试试void   measureitem(lpmeasureitemstruct   lpmeasureitemstruct)
{
        textmetric   tm;
        hdc   hdc   =   ::getdc(null);
        cfont*   pfont   =   getfont();
        hfont   hfontold   =   (hfont)selectobject(hdc,   pfont-> getsafehandle());
        gettextmetrics(hdc,   &tm);
        lpmeasureitemstruct-> itemheight   =   tm.tmheight   +   tm.tmexternalleading   +   1;
        selectobject(hdc,   hfontold);
        ::releasedc(null,   hdc);
}来调整逻辑值和实际的物理值的差别.
drawtext实际上并不绘制文本,而是计算出文本需要多少空间。drawtext改变传入矩形的大小以便适应文本的宽度和高度。调用drawtext之后,crect将返回文本的宽度和高度.看看你调用drawtext前是不是又恢复成原来的字体了.
发表于:2007-07-19 12:05:544楼 得分:0
我明白你的意思了   但是得到的字体大小还是老的
我用了一个比较笨的方法
在第一次drawitem中记录文本大小   之后清空listbox
再插入   通过第一次记录的高度来设置   这样没问题了
好在是数据小   只有几十条     看不出差异


问题的核心是wm_measureitem这个消息吗?
这个listbox   是基于wtl的
按你说的我试了试
两次得到的文字大小不一样
问题是在哪里去响应wm_windowposchanged
结贴了   希望还能和你讨论这个问题


快速检索

最新资讯
热门点击