Link to home
Start Free TrialLog in
Avatar of Andyb
Andyb

asked on

Direct Draw image in a window (MFC)

I am trying to use DDRAW to display an image in a dialog box. I have set the cooperative level to DDSCL_NORMAL and passed the handle from the dialog box (m_hWnd). This is used by the CreateSurface and CreateClipper functions, I am not receiving an error when I execute ethier of these. I check for DD_OK after each function call. The problem is that no image appears in the window when I load a bitmap. I have tried 98 and NT 4.0 but the result is the same. Have I missed something obvious?


Thanks
Avatar of olgat
olgat

Do you Flip() your back surface ?
>>The problem is that no image appears >>in the window when I load a bitmap

How can it appear if you only load the bitmap?
YOu must  blt it by whatever means.
Avatar of Andyb

ASKER

I Blit the surface with the Bitmap directly into the Primary surface. At the moment I was just concentrating on getting the image on the screen. Do I need to use flipping at this stage?
Avatar of Andyb

ASKER

Sorry, I did not clarify the process. I am bliting the surface with the bitmap directly into the primary surface providing a src and dst rectangle
Can you post your blitting code here ?
Avatar of Andyb

ASKER

I will try and include the important bits.

THIS WILL SETUP THE DDRAW OBJECT AND SURFACE.

// 1st we create the direct draw object
      // Create the DirectDraw object.
      hResult = DirectDrawCreate(NULL, &m_lpDD, NULL);

    if ( hResult != DD_OK)
      {
            ReportError("Couldn't create DirectDraw object\n");
        return false;
    }

      // Set normal cooperative level. use DDSCL_NORMAL for windowed mode .
      hResult = m_lpDD->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
    if (hResult != DD_OK)
      {
            ReportError("Couldn't set cooperative level.\n");
        return false;
    }

    // Create the primary surface.
      // Setup the parameters
    ddsd.dwSize = sizeof( ddsd );
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

      hResult = m_lpDD->CreateSurface(&ddsd, &m_lpDDSPrimary, NULL );
    if (hResult != DD_OK)
      {
            ReportError("Couldn't create primary surface.\n");
        return false;
    }
      
      // We need a clipper so that our window does not over write other windows
      //
      // Create a clipper and attach it to the primary surface.
      hResult = m_lpDD->CreateClipper( 0, &m_lpDDClipper, NULL );
    if (hResult != DD_OK)
      {
        ReportError("Failed to create Clipper Surface.\n");
        return false;
    }

    // Associate our clipper with our hwnd so it will be updated
    // by Windows.
      hResult = m_lpDDClipper->SetHWnd( 0, hwnd );
    if (hResult != DD_OK)
      {
        ReportError("Failed to Associate Clipper with hWnd.\n");
        return false;
    }

    // Associate our clipper with the primary surface, so Blt
    // will use it. If this step is skipped by defining NOCLIPPER, you
    // can observe the effects of rendering without clipping. Other
    // windows partially obscuring Inawin's will be overwritten.
    hResult = m_lpDDSPrimary->SetClipper( m_lpDDClipper );
    if (hResult != DD_OK )
      {
            ReportError("Failed to Associate Clipper Surface with Primary Surface.\n");
        return false;
    }
       
    m_lpDDClipper->Release();

THIS WILL SETUP THE BITMAP SURFACE

// Load the bitmap from File
      hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
      if(hbm == NULL)
      {
            ReportError("Failed to load bitmap into Handle");
            return NULL;
      }

    //
    // get size of the bitmap
    //
    GetObject(hbm, sizeof(bm), &bm);      // get size of bitmap

    //
    // create a DirectDrawSurface for this bitmap
    //
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd.dwWidth = bm.bmWidth;
    ddsd.dwHeight = bm.bmHeight;

    if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
      {
            ReportError("Failed to Create Surface: \n In CreateAndLoadBitmap\n ");
            return NULL;
      }

//
    // make sure this surface is restored.
    //
      if(pdds->IsLost())
      {
            pdds->Restore();
      }
      
    //
    //  select bitmap into a memoryDC so we can use it.
    //
    hdcImage = CreateCompatibleDC(NULL);
    if (!hdcImage)
      {
            TRACE("createcompatible dc failed\n");
      }
      //Load our bitmap into the DC we have just created
    SelectObject(hdcImage, hbm);

      //
    // get size of the bitmap
    //
    GetObject(hbm, sizeof(bm), &bm);    // get size of bitmap
    dx = dx == 0 ? bm.bmWidth  : dx;    // use the passed size, unless zero
    dy = dy == 0 ? bm.bmHeight : dy;

    //
    // get size of surface.
    //
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    pdds->GetSurfaceDesc(&ddsd);

    if ((hr = pdds->GetDC(&hdc)) == DD_OK)
    {
            StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
            pdds->ReleaseDC(hdc);
    }

    DeleteDC(hdcImage);

NOW DO THE BLITTING
      HRESULT hResult;

      hResult = lpPrimary->Blt(&rectDest, lpSource, &rectSrc, DDBLT_WAIT, NULL);
      if(hResult != DD_OK)
      {
            ReportError("Failed to Copy Bitmap to Surface\n In CreateAndLoadBitmap\n");
            return hResult;
      }
      
      return hResult;

I have followed the Inside DirectX book which is a couple of years old. The window example it has works fine but they use WIN32 code and not MFC.

Thanks for your assistance.
seems right?
Honestly,Andyb,I dont think this code useful for us to help solve your problem because it's error-free and in plain c++,not MFC.
Regards
Wyn
ASKER CERTIFIED SOLUTION
Avatar of Wyn
Wyn

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
or post the code in your MFC.
Avatar of Andyb

ASKER

The code is within a class inside an MFC Dialog project. The MFC part has changed little over the basic project.A button is added which when pressed, passes the m_hWnd parameter to the direct class and initialises the DDRAW stuff. I presume I am missing something important when combining the two. I thought that by passing the correct HWND parameter the DDRAW functions would be able to cope dialog window. Do I need to add MFC or DirectX functionality in order to display the image. As you say the DirectX code I use gives me no errors. I will look at the example you pointed me to.

Many thanks
Andyb , not enough clue for me to provide more info but I'm sure you can find what you need under:
http://www.codeguru.com/directx

Best Regards
W.Yinan
Avatar of Andyb

ASKER

I shall continue looking at it. I really can't see why it should not work, thanks for you help.