计算机二级C++辅导:自绘调色板
来源:优易学  2010-1-14 18:45:20   【优易学:中国教育考试门户网】   资料下载   IT书店
  几个函数,告别MFC自带调色板
  BOOL CWnd::SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
  void CRect::SetRect(int x1,int y1,int x2,int y2) throw( );
  void CDC::FillSolidRect(LPCRECT lpRect,COLORREF clr );
  绘制每个色条都不是什么麻烦的事情,麻烦的是怎么让色彩过渡更平滑,美观。
  这个调色板有很多人性化的设计,很直观。
  上半部分,每个色带里面可选的颜色值都是256个值,而颜色的范围则是由另外2个原色当前选定值决定的。
  下半部分,从上到下,是一个灰度阶梯,从左到右,则是三原色的真值变化(当然你把它看作是256进制的数),具体变化如下:
  R:255 -》255 -》0 -》0 -》0 -》255 -》255
  G:0 -》255 -》255 -》255 -》0 -》0 -》0
  B:0 -》0 -》0 -》255 -》255 -》255 -》0
  注意:这个真值表,每次只有一项真值发生了变化。
  然后整体从左上角到右下角时,遵循的规律是:(J是从左到右发生变化的某个真值递增值)
  255-》255 0-》0 255《-》0
  前H/2: 255 255递减到0 255递减到J
  后H/2 255递减到0 0 J递减到0
  在OnInitDialog()重新设定元素的位置。
  色条的边框是用静态文本的Client Edge效果出来的。
  当然要归功于SetWindowPos的切割。
  GetDlgItem(IDC_STATIC_RC)->GetWindowRect(&rcStaticR);
  ScreenToClient(&rcStaticR);
  GetDlgItem(IDC_STATIC_RC)->SetWindowPos(NULL,rcStaticR.left,rcStaticR.top,157,\
  rcStaticR.bottom-rcStaticR.top-2,SWP_NOMOVE|SWP_NOZORDER);
  设置CSliderCtrl的范围,我的颜色条是153个像素的。
  m_cSliderR.SetRange(1,153,false);
  颜色条的绘制区高度,是要去掉边框的,自绘的话,边框值好设定和得到。我这里没有重绘,6是我试出来的,左右边框。
  m_uiStaticRHigh=rcStaticR.bottom-rcStaticR.top-6;
  在OnPaint里绘制色条
  得到拖拉条现在的位置:
  int nRpos=m_cSliderR.GetPos();
  获得DialogItem的DC,一定要用子元素自己的DC绘制;
  CDC *pDcR=GetDlgItem(IDC_STATIC_RC)->GetDC();
  禁止DialogItem自绘,一个小技巧。
  GetDlgItem(IDC_STATIC_RC)->Invalidate(false);
  GetDlgItem(IDC_STATIC_RC)->UpdateWindow();
  绘制:
  for(;i <153;i++ ){
  rectangle.SetRect(i,0,i+1, m_uiStaticRHigh);
  pDcR->FillSolidRect(&rectangle, RGB(i/3*5,nGpos/3*5,nBpos/3*5));
  }
  绘制下面的条子,灰度我从上到下共绘制26个像素,这是6段里面的第一段,其他的如法炮制:
  i=0;
  CRect rc;
  for(int j=0;j<=36;j++){
  for(int k=0;k<=25;k++){
  rc.SetRect(i,k,i+1,k+1);
  if(k<=12)
  pDcAll->FillSolidRect(&rc,RGB(255,255-(255-j*7)*k/13,255-255*k/13));
  else
  pDcAll->FillSolidRect(&rc,RGB(255-255*(k-12)/13,j*7-j*7*(k-12)/13,0));
  }
  i++;
  }
  接下来就是处理消息循环,处理CEdit的ON_EN_CHANGE,CSliderCtrl的NM_RELEASEDCAPTURE和 ON_WM_HSCROLL,处理下面条子的ON_WM_LBUTTONDOWN,ON_WM_MOUSEMOVE,ON_WM_LBUTTONUP。来源:考
  为什么不在HSCROLL中处理鼠标的拖拽和方向键拖拉呢,这样导致的结果是频繁的重绘。另外,每次要重新绘制的时候并不是调用Invalidate,而是另外添加个函数,只会上面的部分,下部分没必要重绘。
  另外要处理方向键拖动拖拉条。
  BOOL CPalletteDlg::PreTranslateMessage(MSG* pMsg)
  {
  // TODO: 在此添加专用代码和/或调用基类
  if(pMsg->message==WM_KEYUP){
  if(pMsg->wParam==37||pMsg->wParam==38||pMsg->wParam==39||pMsg->wParam==40){
  OnPaintEX();//只绘上半部分
  }
  }
  return CDialog::PreTranslateMessage(pMsg);
  }

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训