Thread: Windows Double Buffer

  1. #1
    Unregistered
    Guest

    Windows Double Buffer

    Alright I got my Winamp vis to show up but I can't get the double buffer working it says

    C:\Program Files\Winamp\Plugins\finalwinampvismod\lolipopthun der.cpp(89) : error C2440: '=' : cannot convert from 'void *' to 'struct HBITMAP__ *'
    Conversion from 'void*' to pointer to non-'void' requires an explicit cast

    when I have
    memDC = CreateCompatibleDC(NULL);
    memBM = CreateCompatibleBitmap(memDC,cxClient,cyClient);
    oldBM = SelectObject(memDC, memBM);

    but if I go
    memDC = CreateCompatibleDC(NULL);
    memBM = CreateCompatibleBitmap(memDC,cxClient,cyClient);
    SelectObject(memDC, memBM);

    I don't get an error any help?

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    You have to cast the return value of SelectObject to the kind of object that you are replacing in the dc, eg:

    Code:
    oldBM = (HBITMAP)SelectObject(memDC, memBM);
    Last edited by Ken Fitlike; 01-27-2002 at 10:26 PM.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I'm away from my compiler, but basically, you can write a function like this:

    HDC NewDC(HDC hdc)
    {
    int x, y;
    x = GetSystemMetrics(SM_CXSCREEN);
    y = GetSystemMetrics(SM_CYSCREEN);

    HDC new_ = CreateCompatibleDC(hdc);
    HBITMAP b = CreateCompatibleBitmap(hdc, x, y);
    HBRUSH r = GetStockObject(WHITE_BRUSH);
    SelectObject( new_, r);
    SelectObject( new_, b);
    PatBlt(new_, 0, 0, x, y, PATCOPY);

    return new_;
    }



    That might just work. Anyhow, in WM_CREATE, it would look like this:

    hdc = GetDC(hwnd);
    mdc = NewDC(hdc);

    In WM_PAINT, use a function similar to this:

    void Paint( HDC hdc, HDC mdc, HWND hwnd)
    {
    int x, y;
    x = GetSystemMetrics(SM_CXSCREEN);
    y = GetSystemMetrics(SM_CYSCREEN);

    PAINTSTRUCT pnt;

    hdc = BeginPaint(hwnd, &pnt);
    BitBlt(hdc, 0, 0, x, y, mdc.........); //<--TODO, fill in...
    EndPaint(hwnd, &pnt); //<-correct params??
    }

    ...play with it...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    I think problem is with the declaration of OldBM (not having seen the declaration).

    It would appear you have declared it as a pointer not an instance. No type cast is needed.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    No type cast is needed.
    It most certainly is:
    error C2440: '=' : cannot convert from 'void *' to 'struct HBITMAP__ *'
    Conversion from 'void*' to pointer to non-'void' requires an explicit cast
    and msdn says:Compiler Error C2440
    'conversion' : cannot convert from 'type1' to 'type2'
    The compiler was unable to cast from ‘type1’ to ‘type2.’

    Which seems fairly explicit and clear on the point.

    eg try:
    Code:
    case WM_PAINT:
        {
        PAINTSTRUCT ps;
        BeginPaint(hwnd,&ps);
            HBITMAP farty=SelectObject(ps.hdc,0);
        EndPaint(hwnd,&ps);
        return 0;
        }
    and compilation fails with error C2440 as originally reported. Replace it with:
    Code:
    case WM_PAINT:
        {
        PAINTSTRUCT ps;
        BeginPaint(hwnd,&ps);
            HBITMAP farty=(HBITMAP)SelectObject(ps.hdc,0);
        EndPaint(hwnd,&ps);
        return 0;
        }
    and no more errors, clean compile.

    Novocaine: What version of msvc are you using? I recall not having to cast these things with msvc5. Or perhaps you are using a different compiler? Or is there a project setting i've missed? I don't mean to be a hassle, i'm just curious in case i've missed something...

  6. #6
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Currently I am trying not to go back to MSVC v5 from MSVC v6 because I HATE what they have done to the help.

    Look in the MSDN help under SelectObject(). Do they use a type cast?

    I use SelectObject() 118 times in my latest app, nearly 650 times in my previous app, both written in v5, recomplied in v6. None with casts.

    EDIT:

    Could it be that one of the params for size is zero and so the new BMP is NULL and that is causing the error? (the new BMP not considered a BMP if failed to be created)
    EDIT 2
    Now that ws a silly idea, would only happen at run not on compile.
    Last edited by novacain; 01-29-2002 at 10:21 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Novacain: You do not have STRICT type checking enabled, either because you are porting msvc5 projects to msvc6 and IT is failing to set default STRICT type checking OR you have #define NO_STRICT prior to #include <windows.h> I know that msvc5 does NOT define STRICT type checking by default.

    Fair's fair: I tried your suggestion and ensured that a valid bmp was being selected into the dc (I used debugger to step through the code to ensure the created bmp handle was non-NULL):
    Code:
    case WM_PAINT:
        {
        PAINTSTRUCT ps;
        BeginPaint(hwnd,&ps);
        HBITMAP hTmp=CreateCompatibleBitmap(ps.hdc,100,100);
        HBITMAP hOldBmp=(HBITMAP)SelectObject(ps.hdc,hTmp);
        SelectObject(ps.hdc,hOldBmp);
        DeleteObject(hTmp);
        EndPaint(hwnd,&ps);
        return 0;
        }
    The ONLY circumstances that I could get this to compile without the (HBITMAP) cast (Win98SE/Win2k - UNICODE) was if I removed msvc6 default STRICT type checking by using #define NO_STRICT prior to #include <windows.h>

    For good measure I tested it with MinGW - it's error was along the lines of ansi c++ forbids implicit casting.... Borland's bcc5.5, understandably, reported an error remarkably similar in content to the 'error C2440' reported by the original questioner.

    On the basis of this and what msdn (msvc6) has to say about STRICT type checking I have to recommend that the original questioner cast the return values from SelectObject to the correct GDI object handle type, rather than the alternative of #defining NO_STRICT.

    Also, from psdkAug2001 msdn:
    When STRICT is defined, data type definitions change as follows:

    Specific handle types are defined to be mutually exclusive; for example, you won't be able to pass an HWND where an HDC type argument is required. Without STRICT, all handles are defined as integers, so the compiler doesn't prevent you from using one type of handle where another type is expected.
    If only microsoft had made this as explicitly clear in earlier versions...

  8. #8
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    From MSDN help, a search on 'SelectObject' and looking at 'GDI Objects' gives a good code example. (remember I am using .c source not .cpp so declarations are different)

    More important is 'did the Unreg fix the problem?'.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    remember I am using .c source not .cpp so declarations are different
    Since this is the first time you have mentioned this, how could I possibly remember?

    From the original question:
    C:\Program Files\Winamp\Plugins\finalwinampvismod\lolipopthun
    der.cpp
    Surely you must have noticed this? I only ask because i've spent some time working through this in the mistaken belief that I was doing something wrong.

    'did the Unreg fix the problem?'.
    What 'unreg'? Is this something else that I am also supposed to have 'remembered'?

    The problem - as explicitly stated in the original question - was error C2440.

    The correct solution to this specific problem is clealry and incontrovertibly - cast the return from SelectObject to required gdi object type

    OR

    #define NO_STRICT prior to #include <windows.h>

    Why? Because if he was using msvc5 where STRICT is not defined by default then he would not have received that error, unless he had #defined STRICT himself. If he is using msvc6, then STRICT is defined by default and that error will always occur under the stated circumstances.

  10. #10
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Sorry I had mentioned it (.c not .cpp) but I obviously deleted it.
    Unreg(istered) who asked the question, who I was just interested in helping, not having an argument with you.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  11. #11
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Who's arguing?

    I have simply presented a methodical and logical analysis to clear up any misunderstanding that 'unreg' (whom I am equally keen to assist) may have had with regard to the reported problem and, more importantly, its proper solution.

    In the course of this process I have learned a thing or two myself, which is always a bonus.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ to C Conversion
    By dicon in forum C Programming
    Replies: 7
    Last Post: 06-11-2007, 08:38 PM
  2. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  3. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  4. Tetris Questions
    By KneeGrow in forum Game Programming
    Replies: 19
    Last Post: 10-28-2003, 11:12 PM
  5. Console Screen Buffer
    By GaPe in forum Windows Programming
    Replies: 0
    Last Post: 02-06-2003, 05:15 AM