Thread: DirectX screenshot via C (app crashes)

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    4

    Question DirectX screenshot via C (app crashes)

    Hey,

    I'm trying to make a simple addon for an existing application which would take screenshot from inside a directx game by a keystroke.

    First of all, I made one using the simple old method via bitblt, GetDC and it worked, but only for XP and below, in Vista it gets black screens therefore I'm trying to make one via directx with no luck.

    The application is old, and written in pure C and most of the samples available are for C++ and I couldnt find nor make work of anything relevant.

    (directx header version: dx9-nov2007)

    Here is the relevant part of my code for my try
    Code:
    /*
     * File : Snap.c
     * Usage: Snapshots.
    */
    
    #include <windows.h>
    
    //DX9
    #include "dx9/d3d9.h"
    #include "dx9/d3dx9.h"
    
    //headers
    #include "Include/Snap.h"
    
    // include the Direct3D Library files
    #pragma comment (lib, "d3d9.lib")
    #pragma comment (lib, "d3dx9.lib")
    
    //Vista API (dwm)
    //#include "Include/dwmapi.h"
    
    dword     g_dwScreenWidth = 640;
    dword     g_dwScreenHeight = 480;
    
    static IDirect3DDevice9 *init_d3d9(void)
    {
        static HMODULE d3d9_handle = 0;
    
        IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
        IDirect3D9 *d3d9_ptr = 0;
        IDirect3DDevice9 *device_ptr = 0;
        D3DPRESENT_PARAMETERS present_parameters;
        HRESULT hr;
     
        d3d9_handle = LoadLibraryA("d3d9.dll");
        if (!d3d9_handle)
        {
            LOG("Could not load d3d9.dll, critical.\n");
        }
    
        d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
        if (!d3d9_create) 
            LOG("Failed to get address of Direct3DCreate9");
        
        d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
        if (!d3d9_ptr) 
            LOG("Failed to create IDirect3D9 object");
    
        ZeroMemory(&present_parameters, sizeof(present_parameters));
        present_parameters.Windowed = FALSE;
        present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
        present_parameters.BackBufferWidth = 640;
        present_parameters.BackBufferHeight = 480;
        present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
    
        //hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
        //if(!hr)
        //    LOG("Direct3D_CreateDevice returned:");
    
        return device_ptr;
    }
    
    void Snap()
    {
        HRESULT hr;
    
        static HMODULE d3d9_handle = 0;
        IDirect3DDevice9 *device_ptr;
        D3DPRESENT_PARAMETERS present_parameters;
    
        device_ptr = init_d3d9();
        if (!device_ptr) 
            LOG("NO DEVICE %u", device_ptr);
    
        hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device_ptr, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &present_parameters, NULL);
    }
    Few issues I see with the code:

    • device_ptr in Snap() is NULL for some reason and it LOG's "NO DEVICE" in my log. (not sure what it should return)
    • When it gets to the last "hr" it crashes the application with an access violation 0xC0000005.

    I've searched all over for the past 7 days now with no luck, hope anyone came across this in a traditional C.

    edit: my compiler is VC6 (again, old project)

    Best Regards,
    Oleg.
    Last edited by Delusionz; 01-10-2009 at 04:27 PM.

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    I may have missed something, but init_d3d9() seems to always return a null pointer as its local variable device_ptr is initialized to 0 and never updated later...
    Besides I'm a bit surprised you allow your functions to resume even when a error situation is encountered (each time you have a LOG, you should terminate the function as everything following will be wrong (mostly null pointer usage))

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    4
    I'm not sure how to make it correctly and where to direct the pointer to instead of NULL.
    All the tutorials I found doing the same.

    Therefore I'm trying to figure what have I done wrong.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    IDirect3D9_CreateDevice should create the device and fill device_ptr with a valid address.
    Why do you think you can use a NULL pointer? A pointer is not a storage - it stores memory addresses, which must point to a valid memory location that can be read/write in order to use them.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    4
    Basicly, I've never used directx before.
    I'm basic my code on this one I found online: http://www.codeproject.com/....

    As for the IDirect3D9_CreateDevice.

    I've removed the comment out from the "hr" in the init and return it. it gets me a something which looks as a fine memory address.

    Code:
        device_ptr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
        if(!device_ptr)
            LOG("Direct3D_CreateDevice returned:");
    
    	//debug address
    	LOG("IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", device_ptr);
    
        return device_ptr;

    but the snap function still fails with access violation

    Code:
    void Snap()
    {
        HRESULT hr;
    
        static HMODULE d3d9_handle = 0;
        IDirect3DDevice9 *device_ptr;
    	IDirect3DSurface9 *present_parameters = 0;
    
        device_ptr = init_d3d9();
        if (!device_ptr) 
            LOG("NO DEVICE %u", device_ptr);
    
    	// GOOD TILL HERE
    
    	// ----> FAILS HERE <----
            hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device_ptr, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &present_parameters, NULL);
    
    	if (!hr) 
    		LOG("IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr);
    }

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Does it fail with some specific error?
    Crash? Some bad HRESULT returned?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    4
    regular windows "close" and report to microsoft.

    In debugger it gets me an access violation 0xC0000005

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Take screenshot with directX?
    By Dampy in forum Game Programming
    Replies: 20
    Last Post: 05-30-2008, 04:28 PM
  2. Windows Form App as parent, Directx as child??
    By yetti82 in forum C++ Programming
    Replies: 3
    Last Post: 05-29-2006, 03:04 AM
  3. Adding custom GUI to a DirectX 9 App
    By X PaYnE X in forum Game Programming
    Replies: 0
    Last Post: 09-01-2005, 05:34 AM
  4. Replies: 3
    Last Post: 08-14-2003, 01:37 PM
  5. DirectX app won't compile on release mode
    By confuted in forum Game Programming
    Replies: 3
    Last Post: 08-02-2003, 11:23 AM

Tags for this Thread