进度条控件的绘制

       在许多自绘控件中进度条的绘制是相对要非常容易得多的一件事情,因为进度条只作为进度信息的显示并不需要做其它的鼠标键盘事件处理,设置一下最小进度和最大进度基本上就可以用了。

 

      我就说说我自绘进度条的方法,首先要绘制它就必须先获得进度相关的一些参数信息,列如最小进度最大进度和当前进度值,这些值获得的方法也很简单通常的办法就是向进度条控件发消息,例如PBM_GETPOS得到当前进度值,这个方法虽然简单但是效率并不高。还有个方法就是获得存储进度信息的数据结构体,当然这个结构体怎样获得微软并没有公开给用户,在这里我就透露下tagPRODATA这样一个构体,下面来看下这个结构体的申明:

 

 <textarea cols="85" rows="10" name="code" class="cpp">typedef struct tagPRODATA { HWND hwnd; //进度条窗口句柄 DWORD dwStyle; //进度条窗口样式 int iLow, iHigh; //最小最大进度 int iPos; //当前进度值 int iStep; //进度步长 HFONT hfont; //文本字体 COLORREF _clrBk; //背景颜色 COLORREF _clrBar; //进度条颜色 } PRODATA, NEAR *PPRODATA; // ppd</textarea>

 

那如何获得这个结构体呢?其实非常简单这个结构就存储在窗口属性表里可以用以下函数去获得它:

<textarea cols="86" rows="1" name="code" class="cpp">PPRODATA ppd = (PPRODATA)(LONG_PTR)GetWindowLongPtr(m_hWnd, 0);</textarea>

 

好了有了以上这个结构体以后我们就可以着手处理绘制工作了,处理进度条的绘制需要处理WM_PAINT,WM_ERASEBKGND这两个消息,先看看WM_PAINT消息的代码处理:

<textarea cols="89" rows="23" name="code" class="cpp">void CXXXProgressCtrl::OnPaint() { CPaintDC dc(this); //创建DC PPRODATA ppd = (PPRODATA)(LONG_PTR)GetWindowLongPtr(m_hWnd, 0); CRect rcClient; //客户区矩形 CRect rcProgress; //进度区相对客户区的 int px; //垂直或平水进度的位置相对客户区的 GetClientRect(&amp;rcClient); //判断是垂直进度条还是不平水度条 if( ppd-&gt;dwStyle &amp; PBS_VERTICAL )//垂直 { //计算位置 px = MulDiv(rcClient.Height(), ppd-&gt;iHigh - ppd-&gt;iPos, ppd-&gt;iHigh - ppd-&gt;iLow); //设置矩形区域 rcProgress.SetRect(rcClient.left, px, rcClient.right, rcClient.bottom); } else //水平 { px = MulDiv(rcClient.Width(), ppd-&gt;iPos - ppd-&gt;iLow, ppd-&gt;iHigh - ppd-&gt;iLow); rcProgress.SetRect(rcClient.left, rcClient.top, px, rcClient.bottom); } //开始绘制,这里我只作一个简单的填充工作,至于你想达到一个什么样的效果你可以自已去贴图 dc.FillSolidRect(&amp;rcProgress, RGB(255,255,255)); }</textarea>

接下来就是WM_ERASEBKGND消息的代码处理:

<textarea cols="89" rows="9" name="code" class="cpp">BOOL CXXXProgressCtrl::OnEraseBkgnd(CDC* pDC) { CRect rcClient; //客户区矩形 GetClientRect(&amp;rcClient); //在这里我也仅填充下背景,作个简单的示例。 pDC-&gt;FillSolidRect(&amp;rcClient, RGB(0,0,0)); return TRUE; }</textarea>

 

      上面的代码基本上完成了一个粗造的进度条自绘工作,要注意的是Windows还对进度条的非客户区进行了处理,是用于画进度条边框的,如果你不喜他为你绘制的边框那么你可以处理这个消息或者干脆处理WM_NCCALCSIZE消息将非客户尺寸调整为0把边框放在WM_PAINT或WM_ERASEBKGND消息中去画这样更简洁。

你可能感兴趣的:(进度条控件的绘制)