?
Solved

Custom Slider Control

Posted on 2002-07-22
13
Medium Priority
?
2,642 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:jsaxon2
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 2
13 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 7169742
Is this one close to what you want? http://www.codeguru.com/controls/MacSlider.shtml
0
 
LVL 3

Author Comment

by:jsaxon2
ID: 7169870
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
 
LVL 86

Expert Comment

by:jkr
ID: 7169912
Uh, the red slider pretty much looks like a bitmap to me...
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Author Comment

by:jsaxon2
ID: 7169934
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
 
LVL 4

Expert Comment

by:mblat
ID: 7170388
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
 
LVL 4

Expert Comment

by:mblat
ID: 7170398
sorry I meant GetThumbRect()
0
 
LVL 3

Author Comment

by:jsaxon2
ID: 7170654
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
 
LVL 3

Author Comment

by:jsaxon2
ID: 7170655
I am increasing the points to 300.
0
 
LVL 4

Expert Comment

by:mblat
ID: 7170714
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
 
LVL 4

Accepted Solution

by:
mblat earned 1400 total points
ID: 7170755
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
 
LVL 3

Author Comment

by:jsaxon2
ID: 7171590
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
 
LVL 4

Expert Comment

by:mblat
ID: 7172107
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
 
LVL 3

Author Comment

by:jsaxon2
ID: 7176303
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

Featured Post

Survive A High-Traffic Event with Percona

Your application or website rely on your database to deliver information about products and services to your customers. You can’t afford to have your database lose performance, lose availability or become unresponsive – even for just a few minutes.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question