Solved

Custom Slider Control

Posted on 2002-07-22
13
2,610 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
  • 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
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
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 350 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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
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.

831 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