下面这段代码可以让OpenGL游戏窗口化,显示正常,但是DirectX游戏窗口化可以,然而窗口化后,游戏屏幕全是黑的,怎样让DirectX游戏窗口化呢?
DirectX游戏是独占模式的,怎样才能取消其独占呢?// MyGame.cpp : 通用游戏窗口话程序,一般能改变分辨率的游戏都可以使用
//阿龙软件出品.#include "stdafx.h"
#include <afxdllx.h>
#include "MyGame.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif#pragma data_seg("ShareData")
HHOOK glhHook=NULL;
HINSTANCE glhInstance=NULL;
UINT KeyPressed;
UINT AutoTalkFlag;
HWND hwndmu;
HHOOK hHook;
HINSTANCE pHinstance;
bool bs=false;
WNDPROC oldproc;
#pragma data_seg()void __declspec(dllexport) WINAPI InstallHook(BOOL,DWORD);BOOL WINAPI UnInstallHook();
LRESULT CALLBACK HookProc(int ,WPARAM ,LPARAM);
LRESULT CALLBACK MyMsgProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam);
bool __stdcall winmu(void);
BOOL WINAPI UnInstallHook();static AFX_EXTENSION_MODULE MyGameDLL = { NULL, NULL };extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved); if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("MyGame.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(MyGameDLL, hInstance))
return 0; //new CDynLinkLibrary(MyGameDLL);
pHinstance = hInstance;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("MyGame.DLL Terminating!\n");
// Terminate the library before destructors are called
//AfxTermExtensionModule(MyGameDLL);
}
return 1; // ok
}
void __declspec(dllexport) WINAPI InstallHook(BOOL IsHook,DWORD dwThreadId)
{
if(IsHook)
{
hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc,pHinstance,dwThreadId);
}
else
{
UnInstallHook();
}
}
LRESULT CALLBACK HookProc(int ncode,WPARAM wparam,LPARAM lparam)
{
if(ncode<0)
return CallNextHookEx(hHook,ncode,wparam,lparam);
//用一个bool变量让我们的MyGame()只调用一次
if (!bs)
MyGame();
bs=true;
return CallNextHookEx(hHook,ncode,wparam,lparam);
}
bool __stdcall MyGame(void)
{
long style;
long exstyle;
DEVMODE devmode;
hwndmu=GetForegroundWindow();
// hwndmu=(HWND)FindWindow(NULL,"Dweep");
if(EnumDisplaySettings(0, 0, &devmode))
{
devmode.dmPelsWidth=1024;
devmode.dmPelsHeight=768;
devmode.dmBitsPerPel=32;
devmode.dmDisplayFrequency=75;
ChangeDisplaySettings(&devmode,0);
}
//修改窗体的style属性
style= GetWindowLong(hwndmu,GWL_STYLE);
style=style | WS_CAPTION ;
SetWindowLong(hwndmu,GWL_STYLE,style);
//修改窗体的exstyle属性
exstyle=GetWindowLong(hwndmu,GWL_EXSTYLE);
exstyle=exstyle | WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
SetWindowLong(hwndmu,GWL_EXSTYLE,exstyle);
//设置窗体的位置,取消其最前端显示,
SetWindowPos(hwndmu,HWND_NOTOPMOST,0,0,800,600,SWP_SHOWWINDOW); //
ShowWindow(hwndmu,SW_SHOWNORMAL);
//修改窗体的回调函数地址到我们自己定义的回调函数
oldproc=(WNDPROC)GetWindowLong(hwndmu,GWL_WNDPROC);
if(SetWindowLong(hwndmu,GWL_WNDPROC,(long)MyMsgProc)==0)
return false;
return true;
}
LRESULT CALLBACK MyMsgProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam)
{
//消息过滤
switch (umsg)
{
case WM_ACTIVATEAPP:
case WM_ACTIVATE:
case WM_KILLFOCUS:
case WM_SETFOCUS:
case WM_CLOSE:
return 0;
case WM_TIMER:
if(wparam==0x3e9)
KillTimer(hwnd,wparam);
break;
}
return CallWindowProc(oldproc,hwnd,umsg,wparam,lparam);
}
BOOL WINAPI UnInstallHook()
{
UnhookWindowsHookEx(hHook);
return TRUE;
}
DirectX游戏是独占模式的,怎样才能取消其独占呢?// MyGame.cpp : 通用游戏窗口话程序,一般能改变分辨率的游戏都可以使用
//阿龙软件出品.#include "stdafx.h"
#include <afxdllx.h>
#include "MyGame.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif#pragma data_seg("ShareData")
HHOOK glhHook=NULL;
HINSTANCE glhInstance=NULL;
UINT KeyPressed;
UINT AutoTalkFlag;
HWND hwndmu;
HHOOK hHook;
HINSTANCE pHinstance;
bool bs=false;
WNDPROC oldproc;
#pragma data_seg()void __declspec(dllexport) WINAPI InstallHook(BOOL,DWORD);BOOL WINAPI UnInstallHook();
LRESULT CALLBACK HookProc(int ,WPARAM ,LPARAM);
LRESULT CALLBACK MyMsgProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam);
bool __stdcall winmu(void);
BOOL WINAPI UnInstallHook();static AFX_EXTENSION_MODULE MyGameDLL = { NULL, NULL };extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved); if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("MyGame.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(MyGameDLL, hInstance))
return 0; //new CDynLinkLibrary(MyGameDLL);
pHinstance = hInstance;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("MyGame.DLL Terminating!\n");
// Terminate the library before destructors are called
//AfxTermExtensionModule(MyGameDLL);
}
return 1; // ok
}
void __declspec(dllexport) WINAPI InstallHook(BOOL IsHook,DWORD dwThreadId)
{
if(IsHook)
{
hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc,pHinstance,dwThreadId);
}
else
{
UnInstallHook();
}
}
LRESULT CALLBACK HookProc(int ncode,WPARAM wparam,LPARAM lparam)
{
if(ncode<0)
return CallNextHookEx(hHook,ncode,wparam,lparam);
//用一个bool变量让我们的MyGame()只调用一次
if (!bs)
MyGame();
bs=true;
return CallNextHookEx(hHook,ncode,wparam,lparam);
}
bool __stdcall MyGame(void)
{
long style;
long exstyle;
DEVMODE devmode;
hwndmu=GetForegroundWindow();
// hwndmu=(HWND)FindWindow(NULL,"Dweep");
if(EnumDisplaySettings(0, 0, &devmode))
{
devmode.dmPelsWidth=1024;
devmode.dmPelsHeight=768;
devmode.dmBitsPerPel=32;
devmode.dmDisplayFrequency=75;
ChangeDisplaySettings(&devmode,0);
}
//修改窗体的style属性
style= GetWindowLong(hwndmu,GWL_STYLE);
style=style | WS_CAPTION ;
SetWindowLong(hwndmu,GWL_STYLE,style);
//修改窗体的exstyle属性
exstyle=GetWindowLong(hwndmu,GWL_EXSTYLE);
exstyle=exstyle | WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
SetWindowLong(hwndmu,GWL_EXSTYLE,exstyle);
//设置窗体的位置,取消其最前端显示,
SetWindowPos(hwndmu,HWND_NOTOPMOST,0,0,800,600,SWP_SHOWWINDOW); //
ShowWindow(hwndmu,SW_SHOWNORMAL);
//修改窗体的回调函数地址到我们自己定义的回调函数
oldproc=(WNDPROC)GetWindowLong(hwndmu,GWL_WNDPROC);
if(SetWindowLong(hwndmu,GWL_WNDPROC,(long)MyMsgProc)==0)
return false;
return true;
}
LRESULT CALLBACK MyMsgProc(HWND hwnd,UINT umsg,WPARAM wparam,LPARAM lparam)
{
//消息过滤
switch (umsg)
{
case WM_ACTIVATEAPP:
case WM_ACTIVATE:
case WM_KILLFOCUS:
case WM_SETFOCUS:
case WM_CLOSE:
return 0;
case WM_TIMER:
if(wparam==0x3e9)
KillTimer(hwnd,wparam);
break;
}
return CallWindowProc(oldproc,hwnd,umsg,wparam,lparam);
}
BOOL WINAPI UnInstallHook()
{
UnhookWindowsHookEx(hHook);
return TRUE;
}
这回我们让 DirectX 程序与其他 Windows 程序同屏显示。
这个模式其实就是标准 Windows 程序的运行方式,所以称作 "Windowed Mode(窗口模式)" 。在窗口模式下,参照同时运行的其它程序来切换窗口、移动、调整大小等因素都必须考虑。
以窗口模式初始化 DirectX 的代码。
"320,240" 是窗口的初始大小,这里让它跟要显示的图象大小一样:
if (FAILED(hr = g_pDisplay->CreateWindowedDisplay(hWnd,320,240)))
{ ERMSG("Failed initializing DirectDraw.");
return hr;
}
窗口模式的 CALLBACK 函数。
用它来处理窗口的移动、调整大小等事件:
//★ MainWndProc()
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ switch (msg)
{ case WM_KEYDOWN:
PostMessage(hWnd,WM_CLOSE,0,0);
return 0L;
case WM_PAINT:
if (g_pDisplay)
{ // Display the new position of the sprite
if (DisplayFrame() == DDERR_SURFACELOST)
{ PostMessage(hWnd,WM_CLOSE,0,0);
}
}
break;
case WM_MOVE:
if (g_pDisplay) g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE:
// Check to see if we are losing our window...
if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam) g_bActive= FALSE;
else g_bActive= TRUE;
if (g_pDisplay) g_pDisplay->UpdateBounds();
break;
case WM_DESTROY:
// Cleanup and close the app
FreeDirectDraw();
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
本章的例子编译成功后,试试用鼠标拖曳来改变窗口大小。图象的大小、 Aspect Ratio(纵横比) 会适应窗口的大小而改变。
如果把 "WM_SIZE:" 下面这行注释起来跳过编译,再改变窗口大小的时候图象的大小就不会随着改变了:
// if (g_pDisplay) g_pDisplay->UpdateBounds();
其它的跟以前的程序一样。
窗口模式也能使用 Common 文件夹下那4个文件,跟上一节一样,我们也把它复制到工程文件夹。
下面说明工程的创建方法。1. 新建一个 Win32 Application 空白工程,命名为 "Winmode"。2. 向工程中新建一个 C++ Source File ,命名为 "winmode" ,向其中键入篇末附带的源程序。3. 把下面4个文件复制到工程文件夹(我是 G:\DirectX 8\Winmode\):
E:\Mssdk\samples\Multimedia\Common\include\ddutil.h
E:\Mssdk\samples\Multimedia\Common\include\dxutil.h
E:\Mssdk\samples\Multimedia\Common\src\ddutil.cpp
E:\Mssdk\samples\Multimedia\Common\src\dxutil.cpp
然后选择菜单 [Project|工程]-[Add To Project|添加到工程]-[Files...|文件...] ,向工程中添加这4个文件。4. 准备合适的图象文件(我是在 G:\DirectX 8\ 下放了张 "旷野中的小屋.bmp")。
我用的图象大小是 320*240 ,实际上随便多大都可以。下面是读取图象的代码,请改成你自己准备的路径和文件名:
if (FAILED(hr = g_pDisplay->CreateSurfaceFromBitmap
(&g_pBmpSurface,"G:\\DirectX 8\\旷野中的小屋.bmp",0,0)))5. 选择菜单 [Project|工程]-[Settings...|设定...] 打开[Project Settings|工程设定] 面板,点击 [Link|链接] 标签,向 [Object/library modules|对象、库模块] 栏内添加下面4个库文件:
dxguid.lib
ddraw.lib
dxerr8.lib
winmm.lib6. 编译并执行!
源程序:
/************************************************************************/
/*★ 用 Windowed Mode(窗口模式) 显示位图图象 2001-01-10 前田 稔 ★*/
/************************************************************************/
#define STRICT
#include <windows.h>
#include <ddraw.h>
#include <mmsystem.h>
#include "ddutil.h"// Defines, constants, and global variables
#define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
#define ERMSG(x) MessageBox(hWnd, x, "DirectDraw Samplee", MB_OK);CDisplay* g_pDisplay = NULL;
CSurface* g_pBmpSurface = NULL;
BOOL g_bActive = FALSE;// Function-prototypes
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd);
HRESULT InitDirectDraw(HWND hWnd);
VOID FreeDirectDraw();
HRESULT DisplayFrame();
//★ Windows Main
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow)
{ MSG msg;
HWND hWnd; if (FAILED(WinInit(hInst, nCmdShow, &hWnd))) return FALSE; if (FAILED(InitDirectDraw(hWnd)))
{ if (g_pDisplay)
g_pDisplay->GetDirectDraw()->SetCooperativeLevel(NULL, DDSCL_NORMAL); ERMSG("DirectDraw init failed. The sample will now exit.");
return FALSE;
} while(TRUE)
{ if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{ if (0 == GetMessage(&msg, NULL, 0, 0)) return (int)msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{ if (g_bActive)
{ if (FAILED(DisplayFrame()))
{ SAFE_DELETE(g_pDisplay);
ERMSG("Displaying the next frame failed. The sample will now exit.");
return FALSE;
}
}
else WaitMessage();
}
}
}//★ WinInit()
HRESULT WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd)
{ WNDCLASS wc;
HWND hWnd; // Register the Window Class
wc.lpszClassName = TEXT("BMP View");
wc.lpfnWndProc = MainWndProc;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0; if (RegisterClass(&wc) == 0) return E_FAIL; // Create and show the main window
hWnd = CreateWindowEx(0, TEXT("BMP View"), TEXT("WindowedMode"),
WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL);
if (hWnd==NULL) return E_FAIL; ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
*phWnd = hWnd; return S_OK;
}//★ InitDirectDraw()
HRESULT InitDirectDraw(HWND hWnd)
{ HRESULT hr; g_pDisplay = new CDisplay();
if (FAILED(hr = g_pDisplay->CreateWindowedDisplay(hWnd,320,240)))
{ ERMSG("Failed initializing DirectDraw.");
return hr;
} // Create a surface, and draw a bitmap resource on it.
if (FAILED(hr = g_pDisplay->CreateSurfaceFromBitmap
(&g_pBmpSurface,"G:\\DirectX 8\\旷野中的小屋.bmp",0,0)))
return hr; return S_OK;
}//★ FreeDirectDraw()
VOID FreeDirectDraw()
{ SAFE_DELETE(g_pBmpSurface);
SAFE_DELETE(g_pDisplay);
}//★ MainWndProc()
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ switch (msg)
{ case WM_KEYDOWN:
PostMessage(hWnd,WM_CLOSE,0,0);
return 0L;
case WM_PAINT:
if (g_pDisplay)
{ // Display the new position of the sprite
if (DisplayFrame() == DDERR_SURFACELOST)
{ PostMessage(hWnd,WM_CLOSE,0,0);
}
}
break;
case WM_MOVE:
if (g_pDisplay) g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE:
// Check to see if we are losing our window...
if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam) g_bActive= FALSE;
else g_bActive= TRUE;
if (g_pDisplay) g_pDisplay->UpdateBounds();
break;
case WM_DESTROY:
// Cleanup and close the app
FreeDirectDraw();
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}//★ DisplayFrame()
HRESULT DisplayFrame()
{ HRESULT hr; // Fill the back buffer with black, ignoring errors until the flip
g_pDisplay->Clear(0);
// Blt all the sprites onto the back buffer
g_pDisplay->Blt(0,0,g_pBmpSurface,NULL);
// We are in fullscreen mode, so perform a flip and return
if (FAILED(hr= g_pDisplay->Present())) return hr;
return S_OK;
}
可能我的意思没有表达清楚,我的目的并非是在游戏程序的代码中将其窗口化,而是外挂程序,在外挂程序中将已经运行的游戏窗口化。
谢谢你的代码。
继续等待高手指点。
呵呵,为了一边打游戏一边聊MM~~~~
这样的外挂现在很流行的,以窗口化为主,MU就被很多人窗口化了,但MU是OPENGL的。但我还没有发现DirectX游戏被窗口化的,想研究一下。
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>#include <ddraw.h> // include directdraw// DEFINES ////////////////////////////////////////////////// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"// default screen size
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8 // bits per pixel
#define MAX_COLORS 256 // maximum colors// TYPES //////////////////////////////////////////////////////// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;// MACROS /////////////////////////////////////////////////#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// initializes a direct draw struct
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }// GLOBALS ////////////////////////////////////////////////
HWND main_window_handle = NULL; // globally track main window
HINSTANCE hinstance_app = NULL; // globally track hinstance// directdraw stuffLPDIRECTDRAW7 lpdd = NULL; // dd object
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
PALETTEENTRY palette[256]; // color palette
PALETTEENTRY save_palette[256]; // used to save palettes
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
DDBLTFX ddbltfx; // used to fill
DDSCAPS2 ddscaps; // a direct draw surface capabilities struct
HRESULT ddrval; // result back from dd calls
DWORD start_clock_count = 0; // used for timing// these defined the general clipping rectangle
int min_clip_x = 0, // clipping rectangle
max_clip_x = SCREEN_WIDTH-1,
min_clip_y = 0,
max_clip_y = SCREEN_HEIGHT-1;// these are overwritten globally by DD_Init()
int screen_width = SCREEN_WIDTH, // width of screen
screen_height = SCREEN_HEIGHT, // height of screen
screen_bpp = SCREEN_BPP; // bits per pixel
char buffer[80]; // general printing buffer// FUNCTIONS //////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
char buffer[80]; // used to print strings// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
// return success
return(0);
} break;
case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
// end painting
EndPaint(hwnd,&ps); // return success
return(0);
} break;
{ // kill the application, this sends a WM_QUIT message
PostQuitMessage(0); // return success
return(0);
} break; default:break; } // end switch// process any messages that we didn't take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));} // end WinProc///////////////////////////////////////////////////////////int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_window_handle,WM_CLOSE,0,0);// return success or failure or your own return code here
return(1);} // end Game_Main////////////////////////////////////////////////////////////int Game_Init(void *parms = NULL, int num_parms = 0)
{
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization
// here// create IDirectDraw interface 7.0 object and test for error
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
return(0);// set cooperation to normal since this will be a windowed app
lpdd->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL);// return success or failure or your own return code here
return(1);} // end Game_Init/////////////////////////////////////////////////////////////int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
// this is called after the game is exited and the main event
// loop while is exited, do all you cleanup and shutdown here// simply blow away the IDirectDraw4 interface
if (lpdd)
{
lpdd->Release();
lpdd = NULL;
} // end if// return success or failure or your own return code here
return(1);} // end Game_Shutdown// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
HDC hdc; // graphics device context// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);// save hinstance in global
hinstance_app = hinstance;// register the window class
if (!RegisterClassEx(&winclass))
return(0);// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"DirectDraw Initialization Demo", // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, // initial x,y
400,300, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
return(0);// save main window handle
main_window_handle = hwnd;// initialize game here
Game_Init();// enter main event loop
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg); // send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
Game_Main();
} // end while// closedown game here
Game_Shutdown();// return to Windows like this
return(msg.wParam);} // end WinMain