CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Sep 2022
    Posts
    3

    How to create multiple trackbars each with its own custom bitmap thumb and channel?

    As abeginner in WIN32 programming in C language, in my example below I am trying to create two trackbars with their own bitmaps for the thumb and channel:

    Code:
    #include <Windows.h>
    #include <CommCtrl.h>
    
    HWND window = NULL;
    HWND trackBar = NULL;
    HWND trackBar1 = NULL;
    WNDPROC defWndProc = NULL;
    
    static HBITMAP hBitmapThumb;
    static HBITMAP hBitmapThumb1;
    static HBITMAP hBitmapChannel;
    static HBITMAP hBitmapChannel1;
    static BITMAP bm;
    static BITMAP bm1;
    
    LRESULT OnWindowClose(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
        PostQuitMessage(0);
        return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
    }
    
    // LRESULT OnTrackBarChanged(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    //  LRESULT value = SendMessage(trackBar, TBM_GETPOS, 0, 0);
    //  return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
    // }
    
    void DrawBitmapTransparent(HDC hDCDest, int nXDest, int nYDest, int nBitmapWidth, int nBitmapHeight, HBITMAP hBitmap, int nXSrc, int nYSrc, int nTransparentColor)
    {
        HDC hDCSrc;
        HBITMAP hBitmapOld;
        HDC hDCMask;
        HBITMAP hBitmapMask;
        HBITMAP hBitmapMaskOld;
        HDC hDCMem;
        HBITMAP hBitmapMem;
        HBITMAP hBitmapMemOld;
        int nBkColorOld;
        int nTextColorOld;
        BITMAP bm;
    
        GetObject( hBitmap, sizeof( BITMAP ), &bm );
    
        if (!nBitmapWidth) {
            nBitmapWidth = bm.bmWidth;
        }
    
        if (!nBitmapHeight) {
            nBitmapHeight = bm.bmHeight;
        }
    
        hDCSrc = CreateCompatibleDC( hDCDest );
        hBitmapOld = (HBITMAP)SelectObject( hDCSrc, hBitmap );
        hDCMask = CreateCompatibleDC( hDCDest );
        hBitmapMask = CreateBitmap( nBitmapWidth, nBitmapHeight, 1, 1, 0 );
        hBitmapMaskOld = (HBITMAP)SelectObject( hDCMask, hBitmapMask );
        hDCMem = CreateCompatibleDC( hDCDest );
        hBitmapMem = CreateCompatibleBitmap( hDCDest, nBitmapWidth, nBitmapHeight );
        hBitmapMemOld = (HBITMAP)SelectObject( hDCMem, hBitmapMem );
        nBkColorOld = SetBkColor( hDCSrc, nTransparentColor );
        BitBlt( hDCMask, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCCOPY );
        SetBkColor( hDCSrc, nBkColorOld );
        nBkColorOld = SetBkColor( hDCDest, RGB(255,255,255) );
        nTextColorOld = SetTextColor( hDCDest, RGB(0,0,0) );
        BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCDest, nXDest, nYDest, SRCCOPY );
        BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCINVERT );
        BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCMask, 0, 0, SRCAND );
        BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCINVERT );
        BitBlt( hDCDest, nXDest, nYDest, nBitmapWidth, nBitmapHeight, hDCMem, 0, 0, SRCCOPY );
        SetBkColor( hDCDest, nBkColorOld );
        SetTextColor( hDCDest, nTextColorOld );
        SelectObject( hDCMem, hBitmapMemOld );
        DeleteDC( hDCMem );
        DeleteObject( hBitmapMem );
        SelectObject( hDCMask, hBitmapMaskOld );
        DeleteDC( hDCMask );
        DeleteObject( hBitmapMask );
        SelectObject( hDCSrc, hBitmapOld );
        DeleteDC( hDCSrc );
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
        switch(message) {
            case WM_NOTIFY:
            {
                LPNMHDR lpNmhdr = (LPNMHDR)lParam;
                if (lpNmhdr->code == NM_CUSTOMDRAW)
                {
                    LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW)lParam;
    
                    if (lpNMCustomDraw->dwDrawStage == CDDS_PREPAINT) {
                        return CDRF_NOTIFYITEMDRAW;
                    }
    
                    else if (lpNMCustomDraw->dwDrawStage == CDDS_ITEMPREPAINT)
                    {
                        long nLeft = lpNMCustomDraw->rc.left;
                        long nTop = lpNMCustomDraw->rc.top;
                        long nRight = lpNMCustomDraw->rc.right;
                        long nBottom = lpNMCustomDraw->rc.bottom;
    
                        if (lpNMCustomDraw->dwItemSpec == TBCD_THUMB && hBitmapThumb)
                        {
                            long nWidth = nRight - nLeft;
                            long nHeight = nBottom - nTop;
    
                            if (nWidth - bm.bmWidth > 0)
                            {
                                nLeft += (nWidth - bm.bmWidth)/2;
                                nWidth = bm.bmWidth;
                            }
    
                            if (nHeight - bm.bmHeight > 0)
                            {
                                nTop += (nHeight - bm.bmHeight)/2;
                                nHeight = bm.bmHeight;
                            }
    
                            DrawBitmapTransparent(lpNMCustomDraw->hdc , nLeft, nTop, nWidth, nHeight, hBitmapThumb, 0, 0, RGB( 255, 0, 255 ));
    
                            return CDRF_SKIPDEFAULT;
                        }
                        if (lpNMCustomDraw->dwItemSpec == TBCD_CHANNEL && hBitmapChannel)
                        {
                            long nWidth = nRight - nLeft;
                            long nHeight = nBottom - nTop;
    
                            if (nWidth - bm.bmWidth > 0)
                            {
                                nLeft += (nWidth - bm.bmWidth)/2;
                                nWidth = bm.bmWidth;
                            }
    
                            if (nHeight - bm.bmHeight > 0)
                            {
                                nTop += (nHeight - bm.bmHeight)/2;
                                nHeight = bm.bmHeight;
                            }
    
                            DrawBitmapTransparent(lpNMCustomDraw->hdc , nLeft, nTop, nWidth, nHeight, hBitmapChannel, 0, 0, RGB( 255, 0, 255 ));
    
                            return CDRF_SKIPDEFAULT;
                        }
                        if (lpNMCustomDraw->dwItemSpec == TBCD_THUMB && hBitmapThumb1)
                        {
                            long nWidth = nRight - nLeft;
                            long nHeight = nBottom - nTop;
    
                            if (nWidth - bm1.bmWidth > 0)
                            {
                                nLeft += (nWidth - bm1.bmWidth)/2;
                                nWidth = bm1.bmWidth;
                            }
    
                            if (nHeight - bm1.bmHeight > 0)
                            {
                                nTop += (nHeight - bm1.bmHeight)/2;
                                nHeight = bm1.bmHeight;
                            }
    
                            DrawBitmapTransparent(lpNMCustomDraw->hdc , nLeft, nTop, nWidth, nHeight, hBitmapThumb1, 0, 0, RGB( 255, 0, 255 ));
    
                            return CDRF_SKIPDEFAULT;
                        }
                        if (lpNMCustomDraw->dwItemSpec == TBCD_CHANNEL && hBitmapChannel1)
                        {
                            long nWidth = nRight - nLeft;
                            long nHeight = nBottom - nTop;
    
                            if (nWidth - bm1.bmWidth > 0)
                            {
                                nLeft += (nWidth - bm1.bmWidth)/2;
                                nWidth = bm1.bmWidth;
                            }
    
                            if (nHeight - bm1.bmHeight > 0)
                            {
                                nTop += (nHeight - bm1.bmHeight)/2;
                                nHeight = bm1.bmHeight;
                            }
    
                            DrawBitmapTransparent(lpNMCustomDraw->hdc , nLeft, nTop, nWidth, nHeight, hBitmapChannel1, 0, 0, RGB( 255, 0, 255 ));
    
                            return CDRF_SKIPDEFAULT;
                        }
                    }
                }
            }
            break;
        }
        if (message == WM_CLOSE && hwnd == window) return OnWindowClose(hwnd, message, wParam, lParam);
        // if (message == WM_HSCROLL && hwnd == window && (HWND)lParam == trackBar) return OnTrackBarChanged(hwnd, message, wParam, lParam);
        return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
    }
    
    void customTrackbarThumb(void) {
        window = CreateWindowEx(0, WC_DIALOG, L"TrackBar example", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, NULL, NULL);
        trackBar = CreateWindowEx(0, TRACKBAR_CLASS, NULL, WS_CHILD | TBS_HORZ | TBS_BOTTOM | WS_VISIBLE, 1, 1, 250, 20, window, NULL, NULL, NULL);
        trackBar1 = CreateWindowEx(0, TRACKBAR_CLASS, NULL, WS_CHILD | TBS_HORZ | TBS_BOTTOM | WS_VISIBLE, 1, 30, 250, 20, window, NULL, NULL, NULL);
    
        defWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
    
        // hBitmapThumb = reinterpret_cast<HBITMAP>(LoadImage(NULL, reinterpret_cast<LPCWSTR>("pink.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
        hBitmapThumb = (HBITMAP)LoadImage(NULL, (LPCWSTR)L"c:\\Temp\\thumb.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        hBitmapChannel = (HBITMAP)LoadImage(NULL, (LPCWSTR)L"c:\\Temp\\channel.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        GetObject( hBitmapThumb, sizeof( BITMAP ), &bm );
        GetObject( hBitmapChannel, sizeof( BITMAP ), &bm );
    
        SendMessage(trackBar, TBM_SETRANGEMIN, 1, 0);
        SendMessage(trackBar, TBM_SETRANGEMAX, 1, 200);
        SendMessage(trackBar, TBM_SETTIPSIDE, bm.bmWidth/2, 100);
    
        hBitmapThumb1 = (HBITMAP)LoadImage(NULL, (LPCWSTR)L"c:\\Temp\\thumb1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        hBitmapChannel1 = (HBITMAP)LoadImage(NULL, (LPCWSTR)L"c:\\Temp\\channel1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        GetObject( hBitmapThumb1, sizeof( BITMAP ), &bm1 );
        GetObject( hBitmapChannel1, sizeof( BITMAP ), &bm1 );
    
        SendMessage(trackBar1, TBM_SETRANGEMIN, 1, 0);
        SendMessage(trackBar1, TBM_SETRANGEMAX, 1, 200);
        SendMessage(trackBar1, TBM_SETTIPSIDE, bm1.bmWidth/2, 100);
    
        ShowWindow(window, SW_SHOW);
    
        MSG message = { 0 };
        while (GetMessage(&message, NULL, 0, 0))
        DispatchMessage(&message);
    }
    
    int main() {
        customTrackbarThumb();
    }
    The trackbars are successfully created, but the problem is that the bitmaps for the thumbs and channels are the same for the two trackbars, i.e. the second trackbar does not load the images assigned to hBitmapThumb1 and hBitmapChannel1, but it loads from hBitmapThumb and hBitmapChannel. I know this might be a dumb question, but by searching on Google, reading the WIN32 api and a bunch of books on Windows programming, did not find anything that will serve me as an example to solve my problem. Your help would be appreciated on this matter.

    Thank you,
    Sormik

    P.S. Please do not post MFC examples or any other in C++, only in C.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to create multiple trackbars each with its own custom bitmap thumb and channe

    Quote Originally Posted by Sormik View Post
    ...

    P.S. Please do not post MFC examples or any other in C++, only in C.
    Please, check out this article explaining "How to Create a Trackbar" and compare it with your "own way"...
    Victor Nijegorodov

  3. #3
    Join Date
    Sep 2022
    Posts
    3

    Re: How to create multiple trackbars each with its own custom bitmap thumb and channe

    Hi Victor,

    Thank you for your answer, I have found the solution, the problem lied in comparing the lpNMCustomDraw->hdr.hwndFrom to each trackbar window instead to hBitmapThumb hBitmapChannel.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured