3.13 滑块
<p>滑块由CSkinSlider类来代表,继承于CSkinView,支持CSkinView的所有属性和方法。</p>
<p>通过给滑块设置不同的图片资源,可以得到各种形态的进度条。</p>
<h2>1 属性和相关方法</h2>
<h4>1.1 设置滑块的移动范围</h4>
<ul>
<li>通过XML属性控制如下:
<pre><code class="language-xml">Range=&quot;100&quot;</code></pre></li>
<li>通过C++程序代码调用方法控制如下:
<pre><code class="language-c">void SetRange(LONG nRange);</code></pre></li>
</ul>
<h4>1.2 设置滑块的当前位置</h4>
<ul>
<li>通过XML属性控制如下:
<pre><code class="language-xml">Pos=&quot;1&quot;</code></pre></li>
<li>通过C++程序代码调用方法控制如下:
<pre><code class="language-c">void SetPos(LONG nPos);</code></pre></li>
</ul>
<h4>1.3 设置滑块的图像</h4>
<ul>
<li>通过XML属性控制如下:
<pre><code class="language-xml">ThumbImage=&quot;SliderThumb.png&quot;</code></pre></li>
<li>通过C++程序代码调用方法控制如下:
<pre><code class="language-c">void SetThumbImage(uint64 nPos);</code></pre></li>
</ul>
<h2>2 消息处理</h2>
<h4>2.1 WM_SLIDER_POS_CHANGE消息</h4>
<p>滑块位置发生变化时,会给所在窗口发送自定义消息WM_SLIDER_POS_CHANGE。</p>
<p>参考下面的示例代码:</p>
<pre><code class="language-cpp">void CSkinSliderThumb::HandleMouseMove(CPoint point, UINT nFlags)
{
if(GetState() == VS_PRESS_DOWN)
{
CSkinSlider* pScrollSlider = static_cast&lt;CSkinSlider*&gt;(GetParent());
if(pScrollSlider)
{
CRect rcRange = pScrollSlider-&gt;GetRect();
LONG nWidth = GetRect().Width();
LONG nLeft = point.x - m_nLeftOffset;
LONG nRight = nLeft + nWidth;
if(nLeft &lt; rcRange.left)
{
nLeft = rcRange.left;
}
else if(nRight &gt; rcRange.right)
{
nLeft = rcRange.right - nWidth;
}
CSize szThumb = SkinUI::GetImageSize(GetImage());
LONG nRange = pScrollSlider-&gt;GetRange();
LONG nPos = (nLeft - rcRange.left) * nRange / (rcRange.Width() - szThumb.cx);
if(nPos != pScrollSlider-&gt;GetPos())
{
pScrollSlider-&gt;SetPos(nPos);
pScrollSlider-&gt;SetRect(rcRange);
pScrollSlider-&gt;RedrawView();
CSkinSlider* pScrollSlider = static_cast&lt;CSkinSlider*&gt;(GetParent());
if(pScrollSlider)
{
GetOwner()-&gt;PostMessage(WM_SLIDER_POS_CHANGE, pScrollSlider-&gt;GetId(), reinterpret_cast&lt;LPARAM&gt;(pScrollSlider));
}
}
}
}
}</code></pre>
<h2>请看下面的示例</h2>
<h4>效果图</h4>
<p><img src="http://www.skinui.cn/doc/img/3/13/1.png" alt="滑块" /></p>
<h4>布局文件</h4>
<pre><code class="language-xml">&lt;SkinDialog DefaultWidth=&quot;400&quot; DefaultHeight=&quot;300&quot; SysButton=&quot;CLOSE&quot; Icon=&quot;128&quot; Caption=&quot;IDS_CONTROL_SHOW13&quot; Animation=&quot;SizeChange&quot;&gt;
&lt;SkinSlider Id=&quot;101&quot; LayoutHeight=&quot;21&quot; AlignParentLeft=&quot;15&quot; AlignParentRight=&quot;15&quot; AlignParentVerticalCenter=&quot;-20&quot; Range=&quot;100&quot; Pos=&quot;0&quot; Image=&quot;SliderBkg.png&quot; ThumbImage=&quot;SliderThumb.png&quot;/&gt;
&lt;SkinButton Id=&quot;201&quot; LayoutWidth=&quot;WrapContent&quot; LayoutHeight=&quot;30&quot; ChildText1=&quot;增加进度, Step=10&quot; Image=&quot;Button.png&quot; Layout=&quot;Button.xml&quot; AlignParentHorizontalCenter=&quot;0&quot; AlignParentVerticalCenter=&quot;20&quot; PressDownOffset=&quot;1&quot;/&gt;
&lt;/SkinDialog&gt;</code></pre>
<h4>h文件</h4>
<pre><code class="language-cpp">#pragma once
class CSliderDialog : public CSkinDialog
{
public:
enum
{
IDC_SLIDER1 = 101,
IDC_BUTTON1 = 201,
};
public:
CSliderDialog(const tstring&amp; strXml);
public:
virtual void OnInitDialog();
protected:
void OnBtnClickedAddPos(UINT uNotifyCode, int nID, CSkinView* pView);
LRESULT OnSliderPosChange(WPARAM wParam, LPARAM lParam);
SKINUI_DECLARE_MESSAGE_MAP()
private:
CSkinSlider* m_pSlider1;
};</code></pre>
<h4>cpp文件</h4>
<pre><code class="language-cpp">#include &quot;stdafx.h&quot;
#include &quot;SliderDialog.h&quot;
SKINUI_BEGIN_MESSAGE_MAP(CSliderDialog, CSkinDialog)
ON_SKINUI_COMMAND(IDC_BUTTON1, OnBtnClickedAddPos)
ON_SKINUI_MESSAGE(WM_SLIDER_POS_CHANGE, OnSliderPosChange)
SKINUI_END_MESSAGE_MAP()
CSliderDialog::CSliderDialog(const tstring&amp; strXml)
: CSkinDialog(strXml)
, m_pSlider1(NULL)
{
}
void CSliderDialog::OnInitDialog()
{
CSkinDialog::OnInitDialog();
m_pSlider1 = static_cast&lt;CSkinSlider*&gt;(GetChildById(IDC_SLIDER1));
}
void CSliderDialog::OnBtnClickedAddPos(UINT uNotifyCode, int nID, CSkinView* pView)
{
if(m_pSlider1)
{
m_pSlider1-&gt;SetPos(min(m_pSlider1-&gt;GetPos() + 10, m_pSlider1-&gt;GetRange()));
m_pSlider1-&gt;SetRect(m_pSlider1-&gt;GetRect());
m_pSlider1-&gt;RedrawView();
}
}
LRESULT CSliderDialog::OnSliderPosChange(WPARAM wParam, LPARAM lParam)
{
CSkinSlider* pSlider = reinterpret_cast&lt;CSkinSlider*&gt;(lParam);
if(pSlider)
{
MsgBoxModeless(SkinUI::StringFormat(_T(&quot;OnSliderPosChange,Id=%d,CurPos=%d!&quot;), wParam, pSlider-&gt;GetPos()));
}
return 1L;
}</code></pre>