Custom Slider Control

I would like to create a slider control that has a transparent background and a bitmap for the thumb slider instead of the boring old Windows colored rectangle. I have searched and searched but have not been able to find anything that works. I searched both codeguru and codeproject as well as others. Please let me know if anyone has a way to do this or knows where I could find some examples.

PS. I am able to make the background transparent, it is just using the bitmap for the thumb slider that I am not able to do.
Please help, I am going crazy.

Thanks in advance,
John
LVL 3
jsaxon2Asked:
Who is Participating?
 
mblatConnect With a Mentor Commented:
And that would the code for CSliderExt NM_CUSTOMDRAW handler, that derived from CSliderCtrl


void CSliderExt::OnCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{
  NMCUSTOMDRAW* lpcd = (NMCUSTOMDRAW*)pNMHDR;

  LRESULT lr = CDRF_DODEFAULT;

  switch( lpcd->dwDrawStage )
  {
  case CDDS_PREPAINT:
      TRACE(_T("Slider custom draw stage: CDDS_PREPAINT\n") );
      lr = CDRF_NOTIFYITEMDRAW;
      break;

  case CDDS_ITEMPREPAINT:
      TRACE(_T("Slider custom draw stage: CDDS_ITEMPREPAINT\n") );
      if ( lpcd->dwItemSpec == TBCD_THUMB )
      {
       TRACE(_T("Slider item TBCD_THUMB prepaint\n") );
       CDC dc;
       dc.Attach(lpcd->hdc);
//        ... do some painting

      //create a memory dc
      CBitmap maskBitmap;
      BITMAP bmBitmap;
      CDC maskDC;
      //fill in the memory dc for the mask
      maskDC.CreateCompatibleDC(NULL);
      //create a monochrome bitmap
      maskBitmap.LoadBitmap(IDB_BITMAP3);
      //select the mask bitmap into the dc
      maskBitmap.GetBitmap(&bmBitmap);
      int iWidth = bmBitmap.bmWidth;
      int iHeight = bmBitmap.bmHeight;
      CBitmap* OldmaskBitmap = maskDC.SelectObject(&maskBitmap);
      // Blit the image using the mask
      dc.BitBlt( lpcd->rc.left, lpcd->rc.top, iWidth, iHeight, &maskDC, 0, 0, SRCCOPY);
      //restore and clean up
      DeleteObject(maskDC.SelectObject(OldmaskBitmap));
      DeleteDC(maskDC);

       dc.Detach();
       lr = CDRF_SKIPDEFAULT;
      }
      break;
  };

  *pResult = lr;
}
0
 
jkrCommented:
Is this one close to what you want? http://www.codeguru.com/controls/MacSlider.shtml
0
 
jsaxon2Author Commented:
Good resource but not quite what I need. I need to make the thumb a bitmap, not just change the color.

Thanks for your time.
0
Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

 
jkrCommented:
Uh, the red slider pretty much looks like a bitmap to me...
0
 
jsaxon2Author Commented:
It's not a bitmap, it's using a COLOR_3DHILIGHT.

I want the slider to look like one you would find on a audio mixing board. I have the bitmap image, I just need to know how to load it on the thumb.
0
 
mblatCommented:
May be making control owner-drawn.

Or you can handle WM_HSCROLL message in parent window of the control use GetBoundingRect() to find out position of the thumb and BitBlt your own bitmap on the top of it.
0
 
mblatCommented:
sorry I meant GetThumbRect()
0
 
jsaxon2Author Commented:
I'm trying to use mblat's suggestion, but I can't quite get it. It is displaying the bitmap, but the default thumb is showing on top off it. Any suggestions?

Code:

          if (lpcd->dwItemSpec == TBCD_THUMB)
          {
               CRect crect;
               GetThumbRect(crect);
               //create a memory dc
               CBitmap maskBitmap;
               BITMAP bmBitmap;
               CDC maskDC;
               //fill in the memory dc for the mask
               maskDC.CreateCompatibleDC(NULL);
               //create a monochrome bitmap
               maskBitmap.LoadBitmap(IDB_BITMAP1);
               //select the mask bitmap into the dc
               maskBitmap.GetBitmap(&bmBitmap);
               int iWidth = bmBitmap.bmWidth;
               int iHeight = bmBitmap.bmHeight;
               CBitmap* OldmaskBitmap = maskDC.SelectObject(&maskBitmap);
               // Blit the image using the mask
               BitBlt(lpcd->hdc, crect.left, crect.top, iWidth, iHeight, maskDC, 0, 0, SRCCOPY);
               //restore and clean up
               DeleteObject(maskDC.SelectObject(OldmaskBitmap));
               DeleteDC(maskDC);
               *pResult = 0;
               break;
          }

Thanks
0
 
jsaxon2Author Commented:
I am increasing the points to 300.
0
 
mblatCommented:
void CMyDlg::OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult)
{
   
  NMCUSTOMDRAW* lpcd = (NMCUSTOMDRAW*)pNMHDR;

  LRESULT lr = CDRF_DODEFAULT;

  switch( lpcd->dwDrawStage )
  {
  case CDDS_PREPAINT:
      TRACE(_T("Slider custom draw stage: CDDS_PREPAINT\n") );
      lr = CDRF_NOTIFYITEMDRAW;
      break;

  case CDDS_ITEMPREPAINT:
      TRACE(_T("Slider custom draw stage: CDDS_ITEMPREPAINT\n") );
      if ( lpcd->dwItemSpec == TBCD_THUMB )
      {
       TRACE(_T("Slider item TBCD_THUMB prepaint\n") );
       CDC dc;
       dc.Attach(lpcd->hdc);
//        ... do some painting

       CRect crect;
      ((CSliderCtrl*)GetDlgItem(IDC_SLIDER1))->GetThumbRect(crect);
      //create a memory dc
      CBitmap maskBitmap;
      BITMAP bmBitmap;
      CDC maskDC;
      //fill in the memory dc for the mask
      maskDC.CreateCompatibleDC(NULL);
      //create a monochrome bitmap
      maskBitmap.LoadBitmap(IDB_BITMAP3);
      //select the mask bitmap into the dc
      maskBitmap.GetBitmap(&bmBitmap);
      int iWidth = bmBitmap.bmWidth;
      int iHeight = bmBitmap.bmHeight;
      CBitmap* OldmaskBitmap = maskDC.SelectObject(&maskBitmap);
      // Blit the image using the mask
      dc.BitBlt( crect.left, crect.top, iWidth, iHeight, &maskDC, 0, 0, SRCCOPY);
      //restore and clean up
      DeleteObject(maskDC.SelectObject(OldmaskBitmap));
      DeleteDC(maskDC);

 // now clean up
       dc.Detach();

// NO DEFAULT PROCESSING!
       lr = CDRF_SKIPDEFAULT;
      }
      break;
  };

  *pResult = lr;
}

Really you this should be done in control itseft, but example is in dlg. for simplicity.  Note:  You shouldn't be returning 0 form OnCustomDraw - that probably what your problem is....
0
 
jsaxon2Author Commented:
Sorry I didn't get back to you yesterday. It works fine. I now have a bitmap as the thumb on the slider. The only problem is that to move the thumb, I can only click on the Upper left corner which is where the original thumb is hidden. How can I change it so that I can click anywhere on the bitmap to slide the thumb?

If this should be another question, let me know and I will award mblat the points and start a new thread. If you have the answer mblat, let me know and I will increase the points and award them to you.

Thanks for all your help.
John
0
 
mblatCommented:
So I guess you have bitmap much bigger than "original" thumb?

My first try here would be to try to handle OnMouseDown and OnMouseMove and OnMouseUp messages for the control.  
Inside OnMouseDown I would try to find out if click was on bitmap ( you know size and position of the bitmap, right? ) and then implement custom dragging.

If click within "original" thumb ( via GetThumbRect() ) then let default processing take place.


Hope it helps...

0
 
jsaxon2Author Commented:
I haven't had time to get the last problem solved and probably won't have time for a week or so. I will post another question if I can't get it working. Thanks for all you help.

John
0
All Courses

From novice to tech pro — start learning today.