///////// // GdiDraw (non - drawplugin) // by Akt. // VS2003.NET OK VS2005は要修正(たぶん) // こういうのは専門でないので、誤りがある可能性が高いです。 // 実際に用いるときは、内容をよく理解し、適時修正して使用してください。 // MainSystemを取得するのに、うぃんすろうさんとこの関数を使ってます。 // が、MainSystemは引数から取得することも出来ます。その方法はSDKマニュアル参照してください。 // 参考文献 // Windowsプログラミング研究所 http://www13.plala.or.jp/kymats/index.html // Windowsプログラミング研究室 http://www.sm.rim.or.jp/~shishido/windows.html // Based DrawPluginサンプルコード by スゲーナスゴイデス ////////////////////////////////////////////////////////////////////////////////////////// //DrawPluginサンプルコード // // 2005.3.5 Coder. Winthrow orz // cl.exe /O1 /G5 /LD /EHsc CDrawTest.cpp // // コンパイル条件 // compiled : Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 // VC++ toolkit 2003, 要Microsoft coreSDK // 見えるところにUuid.lib必要 // ヘッダは、cppソースのあるディレクトリにInterfaceディレクトリを掘る // 参考:SYSTEM3.9SDKマニュアルとSYSTEM4 SDKマニュアル // DLLMainとか書くのが面倒なのでコンパイラ任せ(あ、だからBCCでコンパイルしても動かないのか?) ////////////////////////////////////////////////////////////////////////////////////////// #define PI 2.0 * acos(0.0) #include #include #include using namespace std; //必要なだけインクルードせよせよせよ…(残響音) //DLL 開発のInterfaceのところと、HLLのDrawPluginのInterfaceのところ #include "Interface\IInterface.h" #include "Interface\IString.h" #include "Interface\IVMArray2.h" #include "Interface\IMainSystem.h" #include "Interface\GMainSystem.h" #include "Interface\IWindow.h" #include "Interface\IMainSurface.h" #define DLLEXPORT __declspec(dllexport) //インターフェイス取得関数。関数テンプレートで実装してみるテスト(メンバ変数依存ってのもどうかと思うけど間違いは少ないかなー) template ITYPE* GetSys4IF(ITYPE* pType, LPCSTR szDllName, LPCSTR szCIName, const GUID* pGuid); //export関数 extern "C" DLLEXPORT void GdiDraw1(void); extern "C" DLLEXPORT void GdiDraw2(void); // HWND GethWnd(){ IMainSystem* m_pIMainSystem=NULL; IWindow* m_pIWindow=NULL; m_pIMainSystem=GetSys4IF(m_pIMainSystem,"MainSystem","GetInterface",&IID_IMainSystem); m_pIWindow=static_cast(m_pIMainSystem->GetInterface(&IID_IWindow)); HWND hw=(HWND)m_pIWindow->GetHWND(); return hw; } //DIB Sectionを用いて、描画を行う方法。 //SACTのグラフィックライブラリとの共存はたぶんできません。 // # DrawPluginとして、MainSurfaceでなく、個々のスプライトに対してDIB Sectionを行うなら可能です。 //作成と破棄を毎回繰り返していますが、無駄なのできちんとした使用の際は修正しましょう。 void GdiDraw1(void){ IMainSystem* m_pIMainSystem=NULL; IMainSurface* m_pIMainSurface=NULL; m_pIMainSystem=GetSys4IF(m_pIMainSystem,"MainSystem","GetInterface",&IID_IMainSystem); m_pIMainSurface=static_cast(m_pIMainSystem->GetInterface(&IID_IMainSurface)); //DIB Section(DDB copy to DIB) HWND hWnd=(HWND)GethWnd(); HDC hdc; HDC hdcBMP; HBITMAP hbmpBMP, hbmpOld; LPDWORD lpdwPixel; BITMAPINFO biBMP; ZeroMemory(&biBMP, sizeof(biBMP)); /* MainSurfaceサイズ、24ビットDIB用BITMAPINFO設定 */ biBMP.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); biBMP.bmiHeader.biBitCount = m_pIMainSurface->GetBpp(); biBMP.bmiHeader.biPlanes = 1; biBMP.bmiHeader.biWidth = m_pIMainSurface->GetWidth(); biBMP.bmiHeader.biHeight = -1 * m_pIMainSurface->GetHeight(); /* DIBSection作成 */ hbmpBMP = CreateDIBSection(NULL, &biBMP, DIB_RGB_COLORS, (void **)(&lpdwPixel), NULL, 0); /* ウインドウのHDC取得 */ hdc = GetDC(hWnd); /* DIBSection用メモリデバイスコンテキスト作成 */ hdcBMP = CreateCompatibleDC(hdc); /* ウインドウのHDC解放 */ ReleaseDC(hWnd, hdc); /* DIBSectionのHBITMAPをメモリデバイスコンテキストに選択 */ hbmpOld = (HBITMAP)SelectObject(hdcBMP, hbmpBMP); char *str = "表示テスト(GDIで表示されています)"; SetTextColor(hdcBMP, RGB(255, 0, 0)); TextOut(hdcBMP, 10, 10, (LPCSTR)str, strlen(str)); BYTE *stp=(BYTE*)m_pIMainSurface->GetPixel(0,0); memcpy(stp,lpdwPixel,m_pIMainSurface->GetWidth()*m_pIMainSurface->GetHeight()*m_pIMainSurface->GetBpp()/8); /* DIBSectionをメモリデバイスコンテキストの選択から外す */ SelectObject(hdcBMP, hbmpOld); /* DIBSectionを削除 */ DeleteObject(hbmpBMP); /* メモリデバイスコンテキストを削除 */ DeleteDC(hdcBMP); //本当は変更領域に対してのみやるべきです。 m_pIMainSurface->Update(0,0,m_pIMainSurface->GetWidth(),m_pIMainSurface->GetHeight()); } //MainSurfaceの内容を取得して、そこにDDBで加工して、さらに戻す方法。 //SACTのグラフィックライブラリとの共存は気合いを入れれば、できるかもしれません。 void GdiDraw2(void){ IMainSystem* m_pIMainSystem=NULL; IMainSurface* m_pIMainSurface=NULL; m_pIMainSystem=GetSys4IF(m_pIMainSystem,"MainSystem","GetInterface",&IID_IMainSystem); m_pIMainSurface=static_cast(m_pIMainSystem->GetInterface(&IID_IMainSurface)); //DIB->DDB->DIB HWND hWnd=(HWND)GethWnd(); HDC hdc; HBITMAP hBitmap,hOldBitmap; HDC hBuffer; BYTE * bPixelBits=(BYTE*)m_pIMainSurface->GetPixel(0,0); BITMAPINFO biBMP; ZeroMemory(&biBMP, sizeof(biBMP)); /* MAIN SURFACE用BITMAPINFO設定 */ biBMP.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); biBMP.bmiHeader.biBitCount = m_pIMainSurface->GetBpp(); biBMP.bmiHeader.biPlanes = 1; biBMP.bmiHeader.biWidth = m_pIMainSurface->GetWidth(); biBMP.bmiHeader.biHeight = -1 * m_pIMainSurface->GetHeight(); hdc = GetDC(hWnd); //DDB Make(copy from DIB) hBitmap = CreateDIBitmap( hdc , &biBMP.bmiHeader , CBM_INIT , bPixelBits , &biBMP , DIB_RGB_COLORS ); hBuffer = CreateCompatibleDC(hdc); hOldBitmap=(HBITMAP)SelectObject(hBuffer , hBitmap); //GetObject(hBitmap , sizeof (BITMAP) , &bitmap); char *str = "表示テスト(GDIで表示されています)"; SetTextColor(hBuffer, RGB(255, 0, 0)); TextOut(hBuffer, 10, 10, (LPCSTR)str, strlen(str)); SelectObject(hBuffer,hOldBitmap); //Copy To DIB GetDIBits(hdc,hBitmap,0,m_pIMainSurface->GetHeight(),bPixelBits,&biBMP,DIB_RGB_COLORS); DeleteDC(hBuffer); DeleteObject(hBitmap); ReleaseDC(hWnd , hdc); //本当は変更領域に対してのみやるべきです。 m_pIMainSurface->Update(0,0,m_pIMainSurface->GetWidth(),m_pIMainSurface->GetHeight()); } //======================================================================================== //Interfaceなんでも取得関数 GetSys4IF //返値は、pTypeで指定した型にキャストされている //ITYPE* pType Interfaceのポインタを保持するクラスのメンバ変数を指定(この関数はメンバ変数の型で処理されます) //LPCSTR szDLLName DLL名 //LPCSTR szCIName SYSTEM4用DLLごとにエクスポートされてるInterface取得用の関数名 //const GUID* pGUID 各COMクラスごとのGUIDのポインタ //返値がNULLだったらシパーイです。 //VC++ toolkit 2003で動作確認(古いコンパイラのことは知りません) //今回唯一VC++らしいことをやってみた template ITYPE* GetSys4IF( ITYPE* pType, LPCSTR szDllName, LPCSTR szCIName, const GUID* pGuid) { HMODULE hDLL = GetModuleHandle(szDllName); if(hDLL==NULL) { ::OutputDebugString("■ERROR - hDLL==NULL - GetSys4IF GetModuleHandle\n"); return NULL; } typedef IInterface*(*PFunc)(const GUID*); PFunc CreateInterface = (PFunc)GetProcAddress(hDLL, szCIName); //ここまではVC++では基本事項らしい if(CreateInterface==NULL) { ::OutputDebugString("■ERROR - CreateInterface==NULL - GetSys4IF GetProcAddress\n"); return NULL; } ITYPE* pTmp = (ITYPE*)CreateInterface(pGuid); if(pTmp==NULL) { ::OutputDebugString("■ERROR - pGuid==NULL - GetSys4IF CreateInterface\n"); } return pTmp; }