Thread: One last time...

  1. #1
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195

    One last time...

    I've still got problems with this source code. It would be much relief if I could fine out what is wrong with it?

    I'm going to go to the library on Saturday, and I'll get a book, which ones would you guys recommend? Ideally, I want something to do with graphics programming using the windows api.

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I hate to be a nag... But what is the problem as far as you have identified? I don't like reading an entire source code file when it is missing its headers without having a clue where to start.

  3. #3
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    Quote Originally Posted by master5001 View Post
    I hate to be a nag... But what is the problem as far as you have identified? I don't like reading an entire source code file when it is missing its headers without having a clue where to start.
    Sorry, my bad. The problem is the drawing of the bitmaps. I can't seem to get the painting stuff to work in the WM_CASE of the callback. It use to draw, but I had to change it so that it could redraw the bitmaps when the WM_PAINT message was called, but now it doesn't draw at all.

    Any recommendations on the books to look for?

  4. #4
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Thanks. That is more like it:

    Example:
    Code:
               case WM_PAINT:
                    HDC hdcMemory;
                    HDC hdc;
                    BITMAP bm;
                    PAINTSTRUCT ps;
                    hdcMemory = CreateCompatibleDC(hdc);
                    hdc = BeginPaint(hwnd, &ps);
                    int i;
                    int x_coord, y_coord;
        
                    for(i=0; i<(TILE_NUM*TILE_NUM); i++)
                    {
                             if( GameLogic.game_board[i] == 1 )
                             {
                                 ShowWindow(ButtonHandles.hButton[i], SW_HIDE);
                                 x_coord == TILE_SIZE*(i&#37;TILE_NUM);
                                 y_coord == (int)(i/TILE_NUM);
                                 SelectObject(hdcMemory, hbmCross);
                                 BitBlt(hdc, x_coord, y_coord, TILE_SIZE, TILE_SIZE, hdcMemory, 0, 0, SRCCOPY);
                                 }
                             else if( GameLogic.game_board[i] == -1 )
                             {
                                  ShowWindow(ButtonHandles.hButton[i], SW_HIDE);
                                  x_coord == TILE_SIZE*(i%TILE_NUM);
                                  y_coord == (int)(i/TILE_NUM);
                                  SelectObject(hdcMemory, hbmNaught);
                                  BitBlt(hdc, x_coord, y_coord, TILE_SIZE, TILE_SIZE, hdcMemory, 0, 0, SRCCOPY);
                             }
                    }
                    EndPaint(hwnd, &ps);
                    DeleteDC(hdcMemory);
                    //DeleteDC(hdc); This is a no no.
    Ok, now that fixes some of the problem. But when are you actually drawing anything to the hdcMemory buffer? By the way, you should only make the hdcMemory buffer whenever the window is resizes, in my opinion. But just leave it alone for now. It is just an issue of slowing down drawing. But since your drawing still doesn't technically work, optimizing it is a moot point.

  5. #5
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    Does this function not draw to the HDC buffer?
    Code:
    SelectObject(hdcMemory, hbmCross);
    How do I draw into the buffer?

  6. #6
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    No. That selects an object to a device context. I just noticed what you were doing here. And you are doing it correctly. The BitBlt() call is what does the drawing. That step is just copying a memory object onto a drawable canvas, so to speak. It will probably flicker like crazy though when it repaints.

  7. #7
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Books:
    Petzold's 'Programming Windows'

    Also you should return the HDC to it's original state before trying to DeleteDC() it.

    Code:
    hOrigBMP=(HBITMAP*)SelectObject(hdcMem,bmpCross);
    //use
    
    SelectObject(hdcMem,hOrigBMP);
    DeleteDC(hdcMem);
    "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

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    214
    I believe you aren't getting any drawing because your hdcMemory is empty.

    You select the bitmap into that dc with SelectObject(...) but then the next line is :

    BitBlt(hdc, x_coord, y_coord, TILE_SIZE, TILE_SIZE, hdcMemory, 0, 0, SRCCOPY);

    This just copies hdcMemory to hdc, but hdcMemory hasn't been drawn to yet.

  9. #9
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    How do you draw a bitmap to hdcMemory?

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    214
    Quote Originally Posted by Swarvy View Post
    How do you draw a bitmap to hdcMemory?
    I goofed. I just looked at the rest of the code to see where you are loading a bitmap.

  11. #11
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I did the same thing too DeveH, I am so used to how I write my code that his kind of threw me off due to its similarities.

  12. #12
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> hdcMemory = CreateCompatibleDC(hdc);
    >> hdc = BeginPaint(hwnd, &ps);

    These two lines need to be reversed.
    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;
    }

  13. #13
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    I still have problems with the display of my naughts and crosses game. In the source code, I have a statement in the main game code like this:
    Code:
    sprintf(GameLogic.buffer, "Ret = %d", ret);
    MessageBox(hwnd, GameLogic.buffer, "Return Value", MB_OK);
    This is used for testing the return value for the AI (It was put in there during the development of the AI part of the game). Although, when I comment it out, because it's no longer executed, the WM_PAINT message doesn't get called at this point in the program, and so the bitmaps don't draw, when they should. Could I not just use SendMessage(hwnd, WM_PAINT, ...); at this point to solve that problem? If I did do that, what should I put for the last two arguments? I also have the problem of the bitmaps not drawing when the window is deselected and then reselected. I still have no idea how to solve that.

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Now you see why GDI is crap for making any kind of game.

    How I would do it is to set it up like any other game.

    Setup()
    Update()
    Render()

    Your Render() is going to probably just be an Invalidate() call to force a refresh on the entire window. Make sure you have the default double buffer turned OFF or you will get odd flickering. Also make sure you are drawing to an off screen DC and then blitting the entire thing at the end of your paint function.

    Setup() will setup the DC 's for use. Make sure you listen carefully to what novacain said or you will have a serious GDI resource leak and GDI will eventually hate you for it. It will take a long time to occur on modern systems but GDI resource leaks can cause your program to do very strange things. Also it has been my experience that GDI leaks can also cause system instability to the point of requiring a reboot.

    Update() will do just what it says. It will update the positions and states of the game objects and nothing more. In most cases Update() is also where you will accept real-time user input. However this does not exactly fit into the Windows style of event handling so it may flesh out differently in your instance.


    Remember that every time you interact with your window a message is sent to it. Selecting a window would send a focus message to that window and a losing focus message to the window that has the focus. If you are getting strange behavior then you are not accounting for this message in your message loop.
    Last edited by VirtualAce; 09-20-2008 at 08:19 AM.

  15. #15
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    To add to Bubba's advice.....

    You also need a CleanUp().
    CleanUp() returns any GDI objects to their default state and delete/releases them, it is called on close of the app.
    CleanUp() will also be called in response to a size change (followed by a setup).

    The idea is to have your game board drawn into a memory DC (a DC you created off screen).
    When something requires a redraw (user input, resize or external event) you call the Render() method. Render() clears the DC, draws the board, draws the N/Crosses and calls for a paint with;

    InvalidateRect()//send paint msg
    UpdateWindow()//bypass OS queue and send directly to app queue.

    WM_PAINT uses the memory DC, DC and rect from within the PAINTSTRUCT and a single BitBlt() to draw to the screen.

    This will solve all your issues mentioned.
    I have posted code previously to do this.
    "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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to get current time
    By tsubasa in forum C Programming
    Replies: 3
    Last Post: 05-01-2009, 02:03 AM
  2. Replies: 11
    Last Post: 03-29-2009, 12:27 PM
  3. Help with assignment!
    By RVDFan85 in forum C++ Programming
    Replies: 12
    Last Post: 12-03-2006, 12:46 AM
  4. calculating user time and time elapsed
    By Neildadon in forum C++ Programming
    Replies: 0
    Last Post: 02-10-2003, 06:00 PM
  5. time class
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 12-11-2001, 10:12 PM