接触SOUI有段时间了,一直觉得SOUI中xml配置界面很方面,比如要根据图片大小来居中一个按钮,在xml中只需要写<imgbtn pos="|0,|0" offset="-0.5,-0.5" skin="skin_customer_pic"> 其中skin_customer_pic就是自己想显示的那张图片。
这次我用上面这个方法配置xml时却失效了,首先我定义了一个SDXFImage继承自SWindow ,代码大致如下:
class SDXFImage : public SWindow { SOUI_CLASS_NAME(SDXFImage, L"dxfimage") }
然后将新创建的窗口注册到了soui系统中,代码如下:
theApp->RegisterWindowClass<SDXFImage>();
然后在xml中定义了一个以下的标签:
<window name="page_download" visible="0" pos="0,0,-0,-0" colorBkgnd="#ffffff" > <dxfimage pos="|0,|0" offset="-0.5,-0.5" skin="skin_avatar" > </dxfimage> </window>
然后运行程序,但是图片没有显示在窗口中间,居中显示的xml配置我已经用了很久,不可能出问题,查看了一下soui代码,发现窗口大小都为0,查看了一下soui代码,发现在计算子窗口位置的时候调用了如下方法。
CSize SwndLayoutBuilder::CalcSize(SWindow *pWnd,const CRect & rcContainer,const SwndLayout * pSwndLayout) { if((pSwndLayout->IsFitContent(PD_ALL) ) && pSwndLayout->nCount!=4) { CSize szDesire=pWnd->GetDesiredSize(rcContainer); if(pSwndLayout->IsFitContent(PD_X)) sz.cx=szDesire.cx; if(pSwndLayout->IsFitContent(PD_Y)) sz.cy=szDesire.cy; } return sz; }
soui中会在这里调用一个Swindow中的GetDesiredSize(rcContainer)方法,这是一个虚方法,在SWindow中里面对文本进行了计算,使得能够自动适应大小,但是图片的话却没有处理。所以导致获取的窗口区域为0,那么可想而知按钮能够自动适应图片大小应该是重写了这个GetDesiredSize()方法。
Size SButton::GetDesiredSize( LPCRECT pRcContainer ) { SASSERT(m_pBgSkin); CSize szRet=m_pBgSkin->GetSkinSize(); if(szRet.cx==0 || szRet.cy==0) szRet=__super::GetDesiredSize(pRcContainer); return szRet; }
这里面正确的返回了图片的大小,使得按钮大小能够自动适应图片的尺寸。所以自己派生的SDXFImage要想实现类似的效果,也只需要覆盖该方法即可。