Page 1 of 1

Working D3D9 Hook With CEGUI as Base for Rendering.

Posted: Tue Aug 13, 2013 08:51
by xifoxex
Finally managed to put it all together and have a working Hook using CEGUI with (minimal) Example , playing around would be easy from this point.

I will post my Code but keep in mind i'm not a C++ programmer , i just do it for fun. My initial Goal was to create Different hooks ( d3d9, d3d10 , d3d11 , opengl etc.. ) , but for the time beeing I will keep learning just CEGUI and create some kind of generic overlay ( Browser , Option Panel etc..).

Anwyays , back to this sample:

Used VC++ 2010 Express without problems , VC++ 2005 causes lots of problems so i dont recommend it.

The first thing you will need is a Test Application , you can use this one that works fine:

Code: Select all


#include <windows.h>
#include <d3dx9.h>
#include <dinput.h>
#include "ods.h"


LPDIRECTINPUT8 directInput;
LPDIRECTINPUTDEVICE8 keyboardDevice;
void doDirectInputEvents();

#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } }
#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }



LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

bool Init(HINSTANCE hThisInstance);
bool InitWindow(HINSTANCE hThisInstance);
bool InitD3D();
bool initialiseDirectInput(HWND window);

void Load();
void Unload();
void Draw();
void Update();
void SetProjection();

char     *ClassName ;
IDirect3DDevice9  *Device ; 
D3DXMATRIX    World ;   
IDirect3DVertexBuffer9* Triangle ; 
HWND hwnd;       
MSG messages;     


struct ColorVertex
{
 float _x, _y, _z;
 D3DCOLOR _color;
 ColorVertex(float x, float y, float z, D3DCOLOR color)
 {
  _x=x;_y=y;_z=z;_color=color;
 }
 static const DWORD FVF;
};

const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
int WINAPI WinMain (HINSTANCE hThisInstance,
 HINSTANCE hPrevInstance,
 LPSTR lpszArgument,
 int nFunsterStil)
{
 MSG Msg;
 ZeroMemory(&Msg, sizeof(MSG));
 if (Init( hThisInstance) ){
  ShowWindow (hwnd, nFunsterStil);
  Load();
  SetProjection();
  Device->SetRenderState(D3DRS_LIGHTING, false);
  while(Msg.message != WM_QUIT) {
   if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
   } else {
    Update();
    Draw();
   }
  }
  Unload();
 }
}



LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)                 
 {
 case WM_DESTROY:
  PostQuitMessage (0);     
  break;
 default:                   
  return DefWindowProc (hwnd, message, wParam, lParam);
 }
 return 0;
}


bool InitWindow(HINSTANCE hThisInstance){
 WNDCLASSEX wincl;       
 wincl.hInstance = hThisInstance;
 wincl.lpszClassName = ClassName;
 wincl.lpfnWndProc = WindowProcedure;     
 wincl.style = CS_DBLCLKS;               
 wincl.cbSize = sizeof (WNDCLASSEX);
 wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
 wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
 wincl.hCursor = LoadCursor (NULL, IDC_NO);
 wincl.lpszMenuName = NULL;               
 wincl.cbClsExtra = 0;                     
 wincl.cbWndExtra = 0;                 
 wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 if (!RegisterClassEx (&wincl))
  return false;
 RECT wr = {0, 0, 400, 300};   
 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
 
 hwnd = CreateWindowEx (
  0,                 
  ClassName,     
  "Test_1",       
  WS_OVERLAPPEDWINDOW,
  200,     
  200,       
  wr.right - wr.left,               
  wr.bottom - wr.top,               
  HWND_DESKTOP,       
  NULL,               
  hThisInstance,       
  NULL               
  );
 return true;
}

bool InitD3D(){
 HRESULT hr = 0;
 IDirect3D9* d3d9 = 0;
 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
 if( !d3d9 )
 {
  MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
  return false;
 }
 
 D3DCAPS9 caps;
 d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);

 int vp = 0;
 if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
  vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
 else
  vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
 
 D3DPRESENT_PARAMETERS d3dpp;
 d3dpp.BackBufferWidth            = 400;
 d3dpp.BackBufferHeight           = 300;
 d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
 d3dpp.BackBufferCount            = 1;
 d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
 d3dpp.MultiSampleQuality         = 0;
 d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;
 d3dpp.hDeviceWindow              = hwnd;
 d3dpp.Windowed                   = true;
 d3dpp.EnableAutoDepthStencil     = true;
 d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
 d3dpp.Flags                      = 0;
 d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
 d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_ONE;

 hr = d3d9->CreateDevice(
  D3DADAPTER_DEFAULT,
  D3DDEVTYPE_HAL,         
  hwnd,               
  vp,               
  &d3dpp,             
  &Device);           

 if( FAILED(hr) )
 {
 
  d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

  hr = d3d9->CreateDevice(
   D3DADAPTER_DEFAULT,
   D3DDEVTYPE_HAL,
   hwnd,
   vp,
   &d3dpp,
   &Device);


  if( FAILED(hr) )
  {
   d3d9->Release();
   MessageBox(0, "CreateDevice() - FAILED", 0, 0);
   return false;
  }
 }

 d3d9->Release();

 return true;
}

bool Init(HINSTANCE hThisInstance){

 ClassName = "Test_1" ;
 Device  = 0 ;
 Triangle = 0 ;

 InitWindow(hThisInstance);

 InitD3D();
 //initialiseDirectInput(hwnd);


 Device->CreateVertexBuffer(
  3 * sizeof(ColorVertex),
  D3DUSAGE_WRITEONLY,
  ColorVertex::FVF,
  D3DPOOL_MANAGED,
  &Triangle,
  0);

 return true ;
}

void Load(){


 ColorVertex* v;
 Triangle->Lock(0, 0, (void**)&v, 0);

 v[0] = ColorVertex(-1.0f, 0.0f, 2.0f, D3DCOLOR_XRGB(0, 255,0));
 v[1] = ColorVertex( 0.0f, 1.0f, 2.0f, D3DCOLOR_XRGB( 0, 255,0));
 v[2] = ColorVertex( 1.0f, 0.0f, 2.0f, D3DCOLOR_XRGB( 0, 255,0));

 Triangle->Unlock();

}

void SetProjection(){


 D3DXMATRIX proj;

 D3DXMatrixPerspectiveFovLH(
  &proj,
  D3DX_PI * 0.5f,
  (float)800 / (float)600,
  1.0f,
  1000.0f);
 Device->SetTransform(D3DTS_PROJECTION, &proj);

}

void Draw(){
 Device->Clear(0, 0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,0xffffffff, 1.0f, 0);
 Device->BeginScene();
 Device->SetStreamSource(0, Triangle, 0, sizeof(ColorVertex));
 Device->SetFVF(ColorVertex::FVF);
 Device->SetCursorPosition(0,0,D3DCURSOR_IMMEDIATE_UPDATE);
 Device->ShowCursor(false);
 D3DXMatrixTranslation(&World, 0.0f, 0.0f, 0.0f);
 Device->SetTransform(D3DTS_WORLD, &World);
 Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
 Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
 Device->EndScene();
 Device->Present(0, 0, 0, 0);
}

void Update(){


}

void Unload(){

 SAFE_RELEASE(Device);
 SAFE_RELEASE(Triangle);
}


Removed all the comments because of Language ("spanish") , anyways we won't need to modify this code , so just create a new project and Paste it as windowdx.cpp or whatever you want.

Don't forget to point to DX9 libs and includes.

About "ods.h" , its borrowed from Mumble that helped me with the errors:

Code: Select all

/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2011-2011, Stefan Hacker <dd0t@users.sourceforge.net>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdio.h>
#include <ctype.h>
#include <windows.h>
#include "ods.h"

void __cdecl _ods_out(const char *format, va_list *args) {
   char buf[4096], *p = buf + 2;

   buf[0] = 'M'; // Add a prefix
   buf[1] = ':';

   // Format but be aware of space taken by prefix
   int len = _vsnprintf_s(p, sizeof(buf) - 3, _TRUNCATE, format, *args);


   if (len <= 0)
      return;

   p += len;

   // Truncate trailing spaces
   while (p > (buf + 2) && isspace(p[-1]))
      *--p = '\0';

   // Add custom termination
   if (p > (buf + sizeof(buf) - 3)) { // Make sure there's space
      p = buf + sizeof(buf) - 3;
   }
   *p++ = '\r';
   *p++ = '\n';
   *p   = '\0';

   OutputDebugStringA(buf);
}

void __cdecl fods(const char *format, ...) {
   va_list args;

   va_start(args, format);
   _ods_out(format, &args);
   va_end(args);
}


ods.h:

Code: Select all

/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2011-2011, Stefan Hacker <dd0t@users.sourceforge.net>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ODS_H
#define ODS_H

#include <stdarg.h>

void __cdecl _ods_out(const char *format, va_list *args);
void __cdecl fods(const char *format, ...);

#endif // ODS_H



Ok , now we have a test application that use D3D9, now lets create another project , this project will be a Dynamic Library (.dll) using a Module Definition file called Ovr_dll.def.


Ovr_dll.def:

Code: Select all

EXPORTS
SetWHook
RemoveWHook



Ok , now lets start with the actual hook and CEGUI Code:

lib.cpp:

Code: Select all

#include "lib.h"
#include "ods.h"
#include "misc.h"
#include "vhook.h"
#include "CEGUIInjections.h"


HHOOK hkD3D = NULL;
HHOOK hkMsg = NULL;
HMODULE hSelf = NULL;
vHook * d3Dhook ;
CEGUIInjections * CeguiInjections;

static LRESULT CALLBACK MouseMsgProc(UINT nCode, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK KeyBoardMsgProc( int nCode, WPARAM wParam, LPARAM lParam);

extern "C" BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
{
   char procname[1024+64];
   GetModuleFileNameA(NULL, procname, 1024);
   char * pMyAppName = CleanPath(&procname[strlen(procname)]);
   switch (fdwReason)
   {
      case DLL_PROCESS_ATTACH:
      {
                        //TO-DO : CleanPath for XP or Win7
         if ( strcmp(pMyAppName,"\\windowdx.exe") == 0)
         {
            fods("Lib: Found %s\n",pMyAppName);
            d3Dhook = new vHook();
            CeguiInjections = new CEGUIInjections();
            
            d3Dhook->startMyThread();
            hkMsg = SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC)MouseMsgProc,
               hModule, GetCurrentThreadId());
            if ( hkMsg == NULL )
            {
               fods("Lib: Failed to Hook Messages...\n");
               return FALSE;
            }
         }
         break;
      }

      case DLL_PROCESS_DETACH:
      {
         fods("Lib: DLL Detach\n");
         break;
      }

      default:
      {
         break;
      }
   }
   return TRUE;
}



static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
   return CallNextHookEx(hkD3D, nCode, wParam, lParam);
}


extern "C" _declspec(dllexport) void __stdcall SetWHook()
{
   GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) &SetWHook, &hSelf);
   if (hSelf == NULL)
      fods("Lib: Failed to find myself");
   hkD3D = SetWindowsHookEx(WH_CBT, CallWndProc, hSelf, 0);
   if (hkD3D == NULL)
      fods("Lib: Failed to insert WNDProc hook");
}

static LRESULT CALLBACK MouseMsgProc(UINT nCode, WPARAM wParam, LPARAM lParam)
{
   if(nCode < 0)
   {
      CallNextHookEx(hkMsg, nCode, wParam, lParam);
      return 0;
   }
   
   if (CeguiInjections)
      CeguiInjections->InjectToCEGUI((LPMSG)lParam,wParam,lParam);
   
   return CallNextHookEx(hkMsg, nCode, wParam, lParam);
}




extern "C" _declspec(dllexport) void __stdcall RemoveWHook()
{
   if(hkD3D !=NULL)
      UnhookWindowsHookEx(hkD3D);
   hkD3D = NULL;
   if(hkMsg)
      UnhookWindowsHookEx(hkMsg);
   hkMsg = NULL;
}



I use strcmp(pMyAppName,"\\windowdx.exe") to identify the application I would like to hook , so change it with the Test application name you used b4. If you r using XP , \\ is required but not with Win7.


lib.h:

Code: Select all

#ifndef __LIB_H
#define __LIB_H

#include <stdio.h>
#include <windows.h>



static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) ;
extern "C" _declspec(dllexport) void __stdcall SetWHook();
extern "C" _declspec(dllexport) void __stdcall RemoveWHook();

#endif


misc.cpp

Code: Select all

#include <windows.h>
#include "misc.h"


bool __stdcall StrToBool( TCHAR * myChar )
{
   if ( myChar[0] == 89 || myChar[0] == 121 )
      return TRUE;
   return FALSE;
}

char * __stdcall CleanPath( char * pMyChar)
{
   while( pMyChar[0] != 92 )
      pMyChar--;
   return pMyChar++;
}


misc.h

Code: Select all

#ifndef __MISC_H
#define __MISC_H


bool __stdcall StrToBool( TCHAR * myChar  );
char * __stdcall CleanPath(char * pMyPath);
#endif



ods.h and ods.cpp r the same I used for Test Application , so copy .cpp and .h to this Project Folder.


vhook.cpp

Code: Select all

#include <Windows.h>
#include "vhook.h"
#include "ods.h"
#include "d3d.h"

oReset pReset;
oEndScene pEndScene;

vHook::vHook()
{
}


vHook::~vHook()
{
}


DWORD vHook::D3D9VTable_1()
{

  DWORD dwObjBase = (DWORD)LoadLibraryA("d3d9.dll");
      while ( dwObjBase++ < dwObjBase + 0x127850 )
       {
         if ( (*(WORD*)(dwObjBase + 0x00)) == 0x06C7 &&
            (*(WORD*)(dwObjBase + 0x06)) == 0x8689 &&
            (*(WORD*)(dwObjBase + 0x0C)) == 0x8689 )
      
         {
            dwObjBase += 2;
            break;
         }
      }
      return ( dwObjBase );
}      

 

VOID * vHook::DetourCreate(BYTE *src, const BYTE *dst, const int len)
{
    BYTE *jmp = (BYTE*)malloc(len+5);
   DWORD dwBack;
   VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwBack);
   memcpy(jmp, src, len);   
   jmp += len;
   jmp[0] = 0xE9;
   *(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
   src[0] = 0xE9;
   *(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
   DWORD oProt;
   VirtualProtect(jmp,1,PAGE_EXECUTE_READWRITE,&oProt);
   for (int i=5; i<len; i++)  src[i]=0x90;
   VirtualProtect(src, len+1, dwBack, &dwBack);
   return (jmp-len);
}



VOID WINAPI  vHook::ThreadStart()
{
   PDWORD D3DVTable_1;
   do
   {
      *(DWORD*)&D3DVTable_1 = *(DWORD*)D3D9VTable_1();
   }
   while ( !D3DVTable_1 );
   
   pReset      =   (oReset)   this->DetourCreate((PBYTE)D3DVTable_1[16],(PBYTE)myReset,5);
   pEndScene   =   (oEndScene)   this->DetourCreate((PBYTE)D3DVTable_1[42],(PBYTE)myEndScene,5);
   
}


VOID  vHook::StopAll()
{
   PDWORD D3DVTable_1;
   do
   {
      *(DWORD*)&D3DVTable_1 = *(DWORD*)D3D9VTable_1();
   }
   while ( !D3DVTable_1 );
   /* TO-DO : Detour Destroy ..
   this->DetourCreate((PBYTE)D3DVTable_1[16],(PBYTE)pReset,5);
   this->DetourCreate((PBYTE)D3DVTable_1[42],(PBYTE)pEndScene,5);*/
}



vhooh.h:

Code: Select all

#ifndef __V_HOOK
#define __V_HOOK

class vHook
{
   public:
      vHook();
      ~vHook();
      VOID   *DetourCreate( BYTE *src, const BYTE *dst, const int len );
      VOID   StopAll();
      DWORD D3D9VTable_1();
         
      static VOID WINAPI StaticThreadStart(void* Param)
      {
           vHook* This = (vHook*) Param;
         return This->ThreadStart();
      }

      VOID WINAPI ThreadStart();

      void startMyThread()
      {
         MyThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) StaticThreadStart, (void*) this, 0, &ThreadID);
      }

      void StopMyThread()
      {
         this->StopAll();
         TerminateThread(MyThread, 0);
      }

   private:
      DWORD ThreadID;
      HANDLE MyThread;
};


#endif


d3d.cpp

Code: Select all

#include "ods.h"
#include "d3d.h"
#include "CEGUIBase.h"
#include "CEGUIMainMenu.h"


#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

LPD3DXFONT      g_pFont = NULL; //D3D Font
LPD3DXLINE      g_pLine = NULL; //D3D Line
D3DVIEWPORT9    g_ViewPort; //ViewPort
LPDIRECT3DDEVICE9 npDevice;

bool InitCEGUI = false;
bool MenuSet = false;

CEGUIBase * CEGuiBase;
CEGUIMainMenu * CEGuiMainMenu;

HRESULT WINAPI myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
   _asm pushad;
    if( g_pFont )
        g_pFont->OnLostDevice();
 
    if( g_pLine )
        g_pLine->OnLostDevice();
 
    HRESULT iReturnValue = pReset(pDevice, pPresentationParameters);
 
    if(iReturnValue == D3D_OK) {
 
        if( g_pFont )
            g_pFont->OnResetDevice();
 
        if( g_pLine )
            g_pLine->OnResetDevice();
    }
   _asm popad;
    return iReturnValue;
 
}

HRESULT WINAPI myEndScene( LPDIRECT3DDEVICE9  pDevice )
{
   _asm pushad;
   
   if ( ! InitCEGUI )
   {
      
      CEGuiBase = new CEGUIBase(pDevice);
      CEGuiMainMenu = new CEGUIMainMenu();
      InitCEGUI = true;
      
   }
   
   SHORT PRESSED = GetAsyncKeyState(VK_INSERT);
   if ((PRESSED&1) && (MenuSet == FALSE) )
   {
      CEGuiMainMenu->ShowMenu();   
   } else if  ((PRESSED&1) && (MenuSet == TRUE) )
      CEGuiMainMenu->ShowMenu();
   
   CEGuiBase->RenderUI();
   
   _asm popad;
   return pEndScene( pDevice );
}


d3d.h

Code: Select all

#ifndef __D3D
#define __D3D

#include <d3d9.h>
#include <d3dx9.h>

typedef HRESULT ( WINAPI* oReset )( LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters );
typedef HRESULT   ( WINAPI * oEndScene )( LPDIRECT3DDEVICE9  pDevice );
HRESULT WINAPI myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters);
HRESULT WINAPI myEndScene( LPDIRECT3DDEVICE9  pDevice );

extern oReset pReset;
extern oEndScene pEndScene;

#endif __D3D




CEGUIBase.cpp

Code: Select all

#include "ods.h"
#include "CEGUIBase.h"
#include "resources.h"

CEGUI::GeometryBuffer* d_logoGeometry;
bool overlayHandler(const CEGUI::EventArgs& args);

CEGUIBase::CEGUIBase(LPDIRECT3DDEVICE9 pDevice) :
   d_lastFrameTime(0),
   d_resourceProvider(0),
   d_imageCodec(0),
   d_renderer(0),
   pDevice(pDevice)
{
   try {
      new CEGUI::DefaultLogger();
      CEGUI::DefaultLogger::getSingleton().setLoggingLevel(CEGUI::Informative);
      /*TO-DO: Obtain Path from ConfigFile */
      CEGUI::DefaultLogger::getSingleton().setLogFilename("D:\\CEGUI_LOG\\GEGUI.log");
      this->d_renderer = &CEGUI::Direct3D9Renderer::bootstrapSystem(this->pDevice);
      this->initialiseResourceGroupDirectories();
      this->initialiseDefaultResourceGroups();
      //this->d_Context = &CEGUI::System::getSingleton().getDefaultGUIContext();
      
   }
   catch (CEGUI::Exception e)
    {
      fods("CEGUI Error: %s\n",e.what());
   }
}


CEGUIBase::~CEGUIBase()
{

}

VOID CEGUIBase::initialiseResourceGroupDirectories()
{
   CEGUI::DefaultResourceProvider* rp =
      static_cast<CEGUI::DefaultResourceProvider*>
      (CEGUI::System::getSingleton().getResourceProvider());
   /* TO-DO :  use config file.... */
   const char* dataPathPrefix = CEGUI_DATAPATH;
   fods("%s\n",dataPathPrefix);
    char resourcePath[MAX_PATH];
   size_t PathSize = strlen(CEGUI_DATAPATH);
   fods("%i\n",PathSize);

   sprintf_s(resourcePath, PathSize + 10 ,"%s/%s", dataPathPrefix, "schemes/");
   rp->setResourceGroupDirectory("schemes", resourcePath);
    sprintf_s(resourcePath, PathSize + 12 ,"%s/%s", dataPathPrefix, "imagesets/");
    rp->setResourceGroupDirectory("imagesets", resourcePath);
    sprintf_s(resourcePath, PathSize + 8 ,"%s/%s", dataPathPrefix, "fonts/");
    rp->setResourceGroupDirectory("fonts", resourcePath);
    sprintf_s(resourcePath, PathSize + 10 ,"%s/%s", dataPathPrefix, "layouts/");
    rp->setResourceGroupDirectory("layouts", resourcePath);
    sprintf_s(resourcePath, PathSize + 12 ,"%s/%s", dataPathPrefix, "looknfeel/");
    rp->setResourceGroupDirectory("looknfeels", resourcePath);
    sprintf_s(resourcePath, PathSize + 14 ,"%s/%s", dataPathPrefix, "lua_scripts/");
    rp->setResourceGroupDirectory("lua_scripts", resourcePath);
    sprintf_s(resourcePath, PathSize + 14 ,"%s/%s", dataPathPrefix, "xml_schemas/");
    rp->setResourceGroupDirectory("schemas", resourcePath);   
    sprintf_s(resourcePath, PathSize + 13 ,"%s/%s", dataPathPrefix, "animations/");
    rp->setResourceGroupDirectory("animations", resourcePath);

}

VOID CEGUIBase::initialiseDefaultResourceGroups()
{
   CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
   CEGUI::Font::setDefaultResourceGroup("fonts");
   CEGUI::Scheme::setDefaultResourceGroup("schemes");
   CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
   CEGUI::WindowManager::setDefaultResourceGroup("layouts");
   CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
   CEGUI::AnimationManager::setDefaultResourceGroup("animations");

    CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
   if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
      parser->setProperty("SchemaDefaultResourceGroup", "schemas");
}

BOOL CEGUIBase::RenderUI()
{
   static bool WaitingForReset = false;
   HRESULT coop;
   
   CEGUI::System& guiSystem = CEGUI::System::getSingleton();
   DWORD thisTime = GetTickCount();
   float elapsed = static_cast<float>(thisTime - this->d_lastFrameTime);
   
   
   this->d_lastFrameTime = thisTime;
   guiSystem.injectTimePulse( elapsed / 1000.0f );
   coop = this->pDevice->TestCooperativeLevel();
   if( coop == D3DERR_DEVICELOST || coop == D3DERR_DEVICENOTRESET )
   {
      if ( !WaitingForReset )
      {
         WaitingForReset = true;
         static_cast<CEGUI::Direct3D9Renderer*>(d_renderer)->preD3DReset();
      }
      return true;
   }
   else if ( coop == D3D_OK )
   {
      if ( WaitingForReset )
      {
         WaitingForReset = false;
         //d_renderer->postD3DReset();
         static_cast<CEGUI::Direct3D9Renderer*>(d_renderer)->postD3DReset();
            return true;
      }
   }

   try
   {
      IDirect3DStateBlock9* pStateBlock = NULL;
      this->pDevice->CreateStateBlock( D3DSBT_ALL, &pStateBlock );
       CEGUI::System::getSingleton().renderAllGUIContexts();
   
      if ( pStateBlock )
      {
         pStateBlock->Apply();
         pStateBlock->Release();
         return true;
      }
   }
   catch ( CEGUI::Exception e )
   {
      fods( "MyGUIRender() -> renderGUI() FAILED: Error message: %s", e.what() );
   }
    return false;
}



CEGUIBase.h

Code: Select all

#ifndef __CEGUIBASE
#define __CEGUIBASE

#include <d3d9.h>
#include "CEGUI/CEGUI.h"
#include "CEGUI/RendererModules/Direct3D9/Renderer.h"
#include "CEGUI/System.h"

using namespace CEGUI;

class CEGUIBase
{
   public:
      CEGUIBase(LPDIRECT3DDEVICE9 pDevice);
      ~CEGUIBase();
      BOOL RenderUI();
   private:
      VOID initialiseResourceGroupDirectories();
      VOID initialiseDefaultResourceGroups();
   protected:               
      LPDIRECT3DDEVICE9 pDevice;
      CEGUI::Renderer * d_renderer;
      CEGUI::ResourceProvider* d_resourceProvider;
      CEGUI::ImageCodec* d_imageCodec;
      DWORD d_lastFrameTime;
};

#endif __CEGUIBASE


CEGUIMainMenu.cpp:

Code: Select all

#include "CEGUIMainMenu.h"
#include "ods.h"
#include "CEGUI/CEGUI.h"


CEGUIMainMenu::CEGUIMainMenu() :
      wRoot(0),
      guiContext(0),
      wnd(0)
{

   this->guiContext = &CEGUI::System::getSingleton().getDefaultGUIContext();
   //SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
   SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
    guiContext->getMouseCursor().setDefaultImage("TaharezLook/MouseArrow");
   CEGUI::WindowManager& winMgr = WindowManager::getSingleton();
   this->wRoot = (DefaultWindow*)winMgr.createWindow("DefaultWindow", "Root");
    Font& defaultFont = FontManager::getSingleton().createFromFile("DejaVuSans-12.font");
    guiContext->setDefaultFont(&defaultFont);
    guiContext->setRootWindow(wRoot);
    wnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "Demo1 Window");
    this->wRoot->addChild(wnd);
    this->wnd->setPosition(UVector2(cegui_reldim(0.25f), cegui_reldim( 0.25f)));
   this->wnd->setSize(USize(cegui_reldim(0.5f), cegui_reldim( 0.5f)));
    this->wnd->setMaxSize(USize(cegui_reldim(1.0f), cegui_reldim( 1.0f)));
    this->wnd->setMinSize(USize(cegui_reldim(0.1f), cegui_reldim( 0.1f)));
    this->wnd->setText("Hello!! World!");
   this->wnd->hide();
   this->wnd->subscribeEvent(CEGUI::Window::EventMouseButtonDown,  Event::Subscriber(&CEGUIMainMenu::handleMainMenuClicked, this));

}

/*************************************************************************
    Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
VOID CEGUIMainMenu::ShowMenu()
{
   this->wnd->show();
}

VOID CEGUIMainMenu::HideMenu()
{
   this->wnd->hide();
}

bool CEGUIMainMenu::handleMainMenuClicked(const CEGUI::EventArgs& args)
{
    fods("CLICKED1\n");
     return false;
}


CEGUIMainMenu.h:

Code: Select all

#ifndef __MAINMENU
#define __MAINMENU

#include "CEGUI/String.h"
#include "CEGUI/ForwardRefs.h"
#include <d3d9.h>
#include "CEGUIBase.h"

using namespace CEGUI;

class CEGUIMainMenu
{
   public:
      CEGUIMainMenu();
      ~CEGUIMainMenu();
      VOID ShowMenu();
      VOID HideMenu();
   private:
      bool handleMainMenuClicked(const CEGUI::EventArgs& args);
      CEGUI::DefaultWindow*   wRoot;
      CEGUI::GUIContext * guiContext;
   
      CEGUI::FrameWindow* wnd;
};


#endif


CEGUIInjections.cpp

Code: Select all

#include "CEGUIInjections.h"
#include "ods.h"


HWND hWndServer = NULL;
bool s_mouseInWindow = false;
RECT clientArea;
int MAX_SCXSIZE = GetSystemMetrics(SM_CXSCREEN);
int MAX_SCYSIZE = GetSystemMetrics(SM_CYSCREEN);


CEGUIInjections::CEGUIInjections()
{

}


CEGUIInjections::~CEGUIInjections()
{

}


bool CEGUIInjections::InjectToCEGUI( LPMSG msg ,WPARAM wParam, LPARAM lParam)
{
   this->thisTime = GetTickCount();
   this->elapsed = static_cast<float>(this->thisTime - this->d_lastFrameTime);
   this->d_lastFrameTime = thisTime;
   switch( msg->message  )
   {

      case WM_CHAR:
         this->injectChar((CEGUI::utf32)wParam);
         SendMessage( hWndServer, WM_CHAR, 0, 0);
        break;

       case WM_MOUSELEAVE:
           this->mouseLeaves();
         SendMessage( hWndServer, WM_MOUSELEAVE, 0, 0);
        break;

      case WM_NCMOUSEMOVE:
         this->mouseLeaves();
         SendMessage( hWndServer, UWM_MOUSEMOVE, 0, 0);
      break;
      
      case WM_MOUSEMOVE:
         GetCursorPos(&this->Point);
         ScreenToClient(msg->hwnd,&this->Point);
         this->injectMousePosition((float)Point.x ,(float)Point.y);
         SendMessage( hWndServer, UWM_MOUSEMOVE, 0, 0);
        break;

      case WM_LBUTTONUP:
         this->injectMouseButtonUp(CEGUI::LeftButton);
         SendMessage( hWndServer, UWM_MOUSELBUTTONUP, 0 , 0 );
        break;

      case WM_LBUTTONDOWN:
         this->injectMouseButtonDown(CEGUI::LeftButton);
         SendMessage( hWndServer, UWM_MOUSELBUTTONUP, 0 , 0 );
        break;

      case WM_RBUTTONDOWN:
         injectMouseButtonDown(CEGUI::RightButton);
         SendMessage( hWndServer, WM_RBUTTONDOWN, 0 , 0 );
        break;

      case WM_RBUTTONUP:
         this->injectMouseButtonUp(CEGUI::RightButton);
         SendMessage( hWndServer, WM_RBUTTONUP, 0 , 0 );
        break;

       case WM_MBUTTONDOWN:
         this->injectMouseButtonDown(CEGUI::MiddleButton);
         SendMessage( hWndServer, WM_MBUTTONDOWN, 0 , 0 );
        break;

      case WM_MBUTTONUP:
         this->injectMouseButtonUp(CEGUI::MiddleButton);
         SendMessage( hWndServer, WM_MBUTTONUP, 0 , 0 );
        break;

      case 0x020A: // WM_MOUSEWHEEL:
         this->injectMouseWheelChange(static_cast<float>((short)HIWORD(wParam)) / static_cast<float>(120));
         SendMessage( hWndServer, 0x020A, 0 , 0 );
        break;
               
      default:
      break;
   }
   return true;
}



bool CEGUIInjections::injectKeyDown(const CEGUI::Key::Scan& ceguiKey)
{
   if (Key::Escape != ceguiKey)
   {
      if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
         return ceguiSystem->getDefaultGUIContext().injectKeyDown(ceguiKey);
      else
         return false;
   }
   else
      //TO-DO:: ESC Must quit the actual menu
      //setQuitting(true);
      return false;
      
   
   return false;
}

bool CEGUIInjections::injectKeyUp(const CEGUI::Key::Scan& ceguiKey)
{
   if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectKeyUp(ceguiKey);
   }
   return false;
}

bool CEGUIInjections::injectChar(int character)
{
   if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectChar(character);
   }
   return false;
}

bool CEGUIInjections::injectMouseButtonDown(const CEGUI::MouseButton& ceguiMouseButton)
{
   if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectMouseButtonDown(ceguiMouseButton);
   }
   return false;
}

bool CEGUIInjections::injectMouseButtonUp(const CEGUI::MouseButton& ceguiMouseButton)
{
   if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectMouseButtonUp(ceguiMouseButton);
   }
   return false;
}

bool CEGUIInjections::injectMouseWheelChange(float position)
{
   if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectMouseWheelChange(position);
   }
   return false;
}

bool CEGUIInjections::injectMousePosition(float x, float y)
{
   if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectMousePosition(x,y);
   }
   return false;
}


void CEGUIInjections::mouseLeaves(void)
{
   if (!s_mouseInWindow)
    {
        s_mouseInWindow = false;
        ShowCursor(true);
    }
    if (CEGUI::System* ceguiSystem = CEGUI::System::getSingletonPtr())
   {
      ceguiSystem->injectTimePulse( elapsed / 1000.0f );
      ceguiSystem->getDefaultGUIContext().injectMouseLeaves();
   }
}


void CEGUIInjections::mouseEnters(void)
{
    if (!s_mouseInWindow)
    {
        s_mouseInWindow = true;
        ShowCursor(false);
    }
}



CEGUIInjections.h

Code: Select all

#ifndef __CEGUI_INJECTIONS
#define __CEGUI_INJECTIONS

#include "windows.h"
#include "CEGUIBase.h"

using namespace CEGUI;

class CEGUIInjections
{
   public:
      CEGUIInjections();
      ~CEGUIInjections();
      bool InjectToCEGUI( LPMSG msg ,WPARAM wParam, LPARAM lParam);
   private:
      virtual bool injectKeyDown(const CEGUI::Key::Scan& ceguiKey);
      virtual bool injectKeyUp(const CEGUI::Key::Scan& ceguiKey);
      virtual bool injectChar(int character);
      virtual bool injectMouseButtonDown(const CEGUI::MouseButton& ceguiMouseButton);
      virtual bool injectMouseButtonUp(const CEGUI::MouseButton& ceguiMouseButton);
      virtual bool injectMouseWheelChange(float position);
      virtual bool injectMousePosition(float x, float y);
      virtual void mouseLeaves(void);
      virtual void mouseEnters(void);
      DWORD d_lastFrameTime;
      DWORD thisTime;
      float elapsed;
      UINT UWM_MOUSEMOVE;
      UINT UWM_MOUSELBUTTONUP;
      UINT UWM_MOUSELBUTTONDOWN;
      UINT UWM_MOUSERBUTTONUP;
      UINT UWM_MOUSERBUTTONDOWN;
      UINT UWM_MOUSELDBCLICK;
      UINT UWN_KEYSTROKE;
      POINT Point;
      RECT Rect;
      
};



#endif


resources.h

Code: Select all

#ifndef __RESOURCES
#define __RESOURCES

#define CEGUI_DATAPATH "D:\\CEGUI_DATA"


#endif __RESOURCES



That's everything you need for the DLL , we won't need anything else except the injector, I don't have a real example for that one , but it will be something like this :


Code: Select all


typedef void (__stdcall *pFunc)(void);
typedef void (__cdecl  *pD3DFunc)(void);


static HMODULE hmodDll = NULL;
static pFunc pSetHookFunc;
static pFunc pRemHookFunc;
static pD3DFunc pPrepareD3D;

int main()
{
   hmodDll = LoadLibrary("Ovr_dll.dll");
   hmodDll = LoadLibrary("Ovr_dll.dll");
   if ( hmodDll == NULL )
      HookError = TRUE;
   
   pSetHookFunc  = (pFunc)GetProcAddress(hmodDll,"SetWHook");
   if ( pSetHookFunc == NULL )
      HookError = TRUE;
   
   pRemHookFunc  = (pFunc)GetProcAddress(hmodDll,"RemoveWHook");
   if ( pSetHookFunc == NULL )
      HookError = TRUE;

        pSetHookFunc();

        //On leave..
        pRemHookFunc();
}




If everything compiles correctly you will have 2 Exe and 1 Dll , execute The injector , then dxwindow.exe and within dxwindow.exe if you press Insert you could see CEGUI Window and interact with it.

Tryd it with other D3D9 Games and works too.

I hope it helps someone someday.