Could someone just take a look at this. I'm following Introduction to 3D Game Programming With Direct3D9 and I've whipped up this class to manage initialisation of Direct3D, but for some reason I'm getting D3DERR_NOTAVAILABLE returned from CreateDevice(). I've looked it up on MSDN but "This device does not support the queried technique." doesn't help much.

I've tried using D3DDEVTYPE_REF and D3DCREATE_SOFTWARE_VERTEXPROCESSING but nothing seems to make it work. What the hell am I doing wrong?

D3DManager.h
Code:
#pragma once

/* D3DManager
 */
#include <d3d9.h>
#include <iostream>

// TODO: Make this a singleton?
class D3DManager {
public:
    D3DManager();
    ~D3DManager();

    bool Initialise(HWND hWnd, D3DDEVTYPE deviceType, int bbWidth, int bbHeight, bool windowed);

private:
    IDirect3D9*         d3d9;
    IDirect3DDevice9*   d3dDevice;
    DWORD               vertProcessing;

};
D3DManager.cpp
Code:
#include ".\d3dmanager.h"

D3DManager::D3DManager()
{
    d3d9 = 0;
    d3dDevice = 0;
    vertProcessing = 0;
}

D3DManager::~D3DManager()
{
}

/* Initialise
 */
bool D3DManager::Initialise(HWND hWnd, D3DDEVTYPE deviceType, int bbWidth, int bbHeight, bool windowed)
{
    D3DCAPS9 caps;
    D3DPRESENT_PARAMETERS d3dpp;
    HRESULT hr = 0;

    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
    if (! d3d9) return false;

    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

    // Determine whether or not we can use hardware vertex processing (perferred)
    if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
        vertProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    else
        vertProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

    ZeroMemory(&caps, sizeof(D3DCAPS9));

    // Fill out the D3DPRESENT_PARAMETERS structure
    d3dpp.BackBufferCount = 1;                                  // Single backbuffer
    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;                   // 8bits for ARGB
    d3dpp.BackBufferHeight = bbHeight;                          // back buffer height
    d3dpp.BackBufferWidth = bbWidth;                            // back buffer width
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;                // No AA. TODO: Make this a parameter
    d3dpp.MultiSampleQuality = 0;                               // Zero quality
    d3dpp.Flags = 0;                                            // Zero flags
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; // Use current refresh rate
    d3dpp.hDeviceWindow = hWnd;                                 // Window handle
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Immediate back buffer presentation
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;                   // Discard previous back buffer contents
    d3dpp.Windowed = windowed;                                  // Run windowed (or not)

    // Create the device
    hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, deviceType, hWnd, vertProcessing, &d3dpp, &d3dDevice);
    //if (FAILED(hr)) {
    //    char msg[256] = {0};
    //    sprintf(msg, "D3DManager::Initialise: CreateDevice() Failed (%d)", GetLastError());
    //    ::MessageBox(0, msg, "Error", MB_OK | MB_ICONERROR | MB_TASKMODAL);
    //    return false;
    //}

    switch (hr) {
        case D3DERR_DEVICELOST:
            ::MessageBox(0, "Device lost?!?", "Error", 0);
            return false;
        case D3DERR_INVALIDCALL:
            ::MessageBox(0, "Invalid call", "Error", 0);
            return false;
        case D3DERR_NOTAVAILABLE:
            ::MessageBox(0, "Not available", "Error", 0);
            return false;
        case D3DERR_OUTOFVIDEOMEMORY:
            ::MessageBox(0, "Out of video mem", "Error", 0);
            return false;
        default:
            return false;
    }

    return true;
}
I've decided to really knuckle down with Direct3D now I've got ~15 weeks with nothing to do.