I'm trying to create a class to manage the various game states for my engine (main menu, gamescreen, ect...) I think I'm on the right track here but I can't get anything to render to the screen.
Here is my manager class...
Code:
enum Purpose {
    SM_INIT = 0,
    SM_RESET,
    SM_PROCESS,
    SM_UPDATE,
    SM_RENDER,
    SM_LOST,
    SM_SHUTDOWN,
    SM_NO_PURPOSE
};
 
class CStateManager {
private:
    typedef void(*pFunction)(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr);
    std::vector<pFunction> States;
    std::vector<pFunction>::iterator StateIter;
public:
    CStateManager()  { }
    ~CStateManager() { PopAll(); }
    bool Push(void (*Function)(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr) );
    bool Pop();
    void PopAll() { States.clear(); }
    bool Process(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void* pData = NULL);
};
 
bool CStateManager::Push(void (*Function)(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void* pData) ) {
    // Don't push a NULL value
    if(Function != NULL) {
        // Push new function onto stack
        States.push_back(Function);
        return true;
    } else return false;
}
 
bool CStateManager::Pop() {
    // Remove the head of stack (if any)
    if(!States.empty() ) {
        States.pop_back();
    }
    // return TRUE if more states exist, FALSE otherwise
    if(States.empty() )
        return false;
    return true;
}
 
bool CStateManager::Process(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void* pData) {
    // return an error if no more states
    if(States.empty() )
        return false;
    // Process the top-most state
    StateIter = States.end() - 1;
    (*StateIter)(pDevice, pCaller, Purpose, pData);
    return true;
}
My game state function prototypes and definitions...
Code:
class CGameApp {
public:
    .....
    static void GameFrame(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr);
    static void GameStart(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr);
    ....
};
 
void CGameApp::GameStart(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr) {
    CGameApp *GameApp = (CGameApp*)pCaller;
    if (Purpose == SM_RENDER) {
        pDevice->SetTransform(D3DTS_VIEW, GameApp->m_camera.GetViewMatrix() );
        GameApp->m_fps = GameApp->m_pFramework->GetFPS() + " fps";
        pDevice->Clear(0, 
                       0, 
                       D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                       D3DCOLOR_XRGB(0, 0, 0), 
                       1.0f, 
                       0); 
        pDevice->BeginScene();
        GameApp->m_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE);
 
        GameApp->m_font.Print(g_instructions1.c_str(), 5, 20, D3DCOLOR_XRGB(200, 200, 200), GameApp->m_pTextSprite);
 
        GameApp->m_pTextSprite->End();
        pDevice->EndScene();
        pDevice->Present(0, 0, 0, 0);
    }
    if (Purpose == SM_PROCESS) {
        sUserInput Input = *( (psUserInput)DataPtr);
        if (Input.pPressedKeys[DIK_ESCAPE] ) { 
            GameApp->m_pFramework->LockKey(DIK_ESCAPE); 
            GameApp->m_StateManager.PopAll();
            PostQuitMessage(0); 
        }
        if (Input.pPressedKeys[DIK_SPACE]) {
            GameApp->m_pFramework->LockKey(DIK_SPACE);
            GameApp->m_StateManager.Push(GameApp->GameFrame);
        }
    }
    return;
}
 
void CGameApp::GameFrame(LPDIRECT3DDEVICE9 pDevice, void* pCaller, UINT Purpose, void *DataPtr) {
    CGameApp *GameApp = (CGameApp*)pCaller;
    if (Purpose == SM_RENDER) {
        pDevice->SetTransform(D3DTS_VIEW, GameApp->m_camera.GetViewMatrix() );
        GameApp->m_fps = GameApp->m_pFramework->GetFPS() + " fps";
        pDevice->Clear(0, 
                       0, 
                       D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                       D3DCOLOR_XRGB(0, 0, 0), 
                       1.0f, 
                       0); 
        pDevice->BeginScene();
        GameApp->m_pBall->Render(pDevice);
        GameApp->m_pWall->Render(pDevice);
 
        // Display framerate and instructions
        GameApp->m_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE);
 
        GameApp->m_font.Print(GameApp->m_fps.c_str(), 5, 5, D3DCOLOR_XRGB(255, 0, 0), GameApp->m_pTextSprite);
        GameApp->m_font.Print(g_instructions2.c_str(), 5, 20, D3DCOLOR_XRGB(200, 200, 200), GameApp->m_pTextSprite);
 
        GameApp->m_pTextSprite->End();
        pDevice->EndScene();
        pDevice->Present(0, 0, 0, 0);
    }
    if (Purpose == SM_PROCESS) {
        sUserInput Input = *( (psUserInput)DataPtr);
        if (Input.pPressedKeys[DIK_F1] ) {
            GameApp->m_pFramework->LockKey(DIK_F1);
            GameApp->m_pFramework->ToggleFullscreen();
        }
        if (Input.pPressedKeys[DIK_ESCAPE] ) { 
            GameApp->m_pFramework->LockKey(DIK_ESCAPE); 
            GameApp->m_StateManager.Pop();
        }
    }
    return;
}
And here is how it is being used...
Code:
void CGameApp::OnCreateDevice(LPDIRECT3DDEVICE9 pDevice) {
    m_StateManager.Push(GameStart);
    ....
}
 
void CGameApp::OnRenderFrame(LPDIRECT3DDEVICE9 pDevice, float ElapsedTime) {
    m_StateManager.Process(pDevice, this, SM_RENDER);
    return;
}
 
void CGameApp::ProcessInput(LPDIRECT3DDEVICE9 pDevice, 
                            long xDelta, 
                            long yDelta, 
                            long zDelta, 
                            bool* pMouseButtons, 
                            bool* pPressedKeys, 
                            float ElapsedTime) { 
    sUserInput Input = { xDelta, yDelta, zDelta, pMouseButtons, pPressedKeys };
    m_StateManager.Process(pDevice, this, SM_PROCESS, (void*)&Input);
    return;
}
I think I have all the relavent code listed, but if there is anything else you need please ask and I will post some more.

I'm not sure why this is not working, any ideas?