游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1777|回复: 3

关于一个游戏框架的问题, 哪位大虾给解决一下?

[复制链接]

3

主题

14

帖子

57

积分

注册会员

Rank: 2

积分
57
发表于 2007-12-7 16:23:00 | 显示全部楼层 |阅读模式
下面这个回调函数只处理了WM_NCCREATE消息(用来取得窗口句柄的地址), 把其他的消息交给mrWindow::MessageHandler (UINT iMessage, WPARAM wParam, LPARAM lParam)来处理

LRESULT CALLBACK mrWindow::WndProc (HWND hWindow, UINT iMessage,
                                    WPARAM wParam, LPARAM lParam)
{
mrWindow * pkWindow   = NULL;
mrBool32   bProcessed = mrFalse;

switch (iMessage)
{
  /* Window is creating - set custom information */
case WM_NCCREATE:
  SetWindowLong (hWindow, GWL_USERDATA,
                 (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
  break;
  /* Window message - Let our handler process it */
default:
   pkWindow = (mrWindow *) GetWindowLong (hWindow, GWL_USERDATA);
   if (NULL != pkWindow)
   {
    bProcessed = pkWindow->MessageHandler (iMessage, wParam, lParam);
   }
  break;
}
   /* Message not processed - let windows handle it */
if (mrFalse == bProcessed)
{
  return DefWindowProc (hWindow, iMessage, wParam, lParam);
}
return 0;
}

下面是mrWindow::MessageHandler (UINT iMessage, WPARAM wParam,  LPARAM lParam)

mrBool32 mrWindow::MessageHandler (UINT iMessage, WPARAM wParam,
                                   LPARAM lParam)
{
switch (iMessage)
{
  /* Close window */
case WM_CLOSE:
  PostQuitMessage (0);
  return mrTrue;
break;
  /* Not handled - let Windows handle */
default:
  return mrFalse;
break;
}
}

问题是MessageHandler函数在处理WM_CLOSE消息的时候居然调用PostQuitMessage(0); 我记得WM_CLOSE这个消息
是关闭窗口的时候接收的, 而且默认情况下会发送WM_DESTROY消息, 而PostQuitMessage(0)应该是写在WM_DESTROY这个消息里面, 按我的思路的话这样做的话会在关闭窗口的时候发出关闭进程而没有窗口的实例。

但是程序可以正常运行, 就是刚开始关闭窗口没反映, 调试发现接收到WM_CLOSE消息的时候 PostQuitMessage(0)
居然没有效果。 把WM_CLOSE改成WM_DESTROY(或者这里注释掉WM_CLOSE消息, 改在回调函数里面添加WM_DESTROY消息), 发现关闭窗口可以立即实现了, 但是进程里面却仍有实例进程存在。这是怎么回事?



我怕我说不清楚, 所以把源码给贴上来了

/* 'mrDatatypes.h' */

/* Include this file only once */
#pragma once

/* Basic type definitions */
typedef   char                mrInt8;
typedef   unsigned char       mrUInt8;
typedef   short               mrInt16;
typedef   unsigned short      mrUInt16;
typedef   long                mrInt32;
typedef   unsigned long       mrUInt32;
typedef   int                 mrInt;
typedef   unsigned int        mrUInt;

typedef   float               mrReal32;
typedef   double              mrReal64;

/* Composed definitions */
enum mrBool32
{
mrFalse                      = 0,
mrTrue                       = 1,

mrBool32_Force32             = 0xFFFFFFFF
};

//////////////////////////////////////////////////////////////

/* 'mrWindows.h' */

/* Mirus base types header */
#include "mrDatatypes.h"
/* Mirus error definitions header */
#include "mrError.h"
/* Windows header file */
#include <windows.h>

/* Include this file only once */
#pragma once

/* Mirus window framework */
class mrWindow
{
protected:
WNDCLASS  m_kWndClass;
HWND      m_hWindow;
MSG       m_kMessage;

public:
         /* Constructor / Destructor */
mrWindow (void);
~mrWindow (void);

  /* Window manipulation functions */
mrError32 Create (HINSTANCE hInstance, LPSTR szTitle,
                   mrInt iWidth = CW_USEDEFAULT,
                   mrInt iHeight = CW_USEDEFAULT,
                   mrUInt32 iStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE);
static LRESULT CALLBACK WndProc (HWND hWindow, UINT iMessage,
                         WPARAM wParam, LPARAM lParam);
void Run (void);

  /* Custom functions */
virtual mrBool32 MessageHandler (UINT iMessage, WPARAM wParam,
                                  LPARAM lParam);
virtual mrBool32 Frame (void) = 0;

  /* More functions */
void SetPosition (mrInt iWidth, mrInt iHeight);
POINT GetPosition (void);
void SetSize (mrInt iWidth, mrInt iHeight);
POINT GetSize (void);
void Show (mrInt iShow);
        HWND GetHandle (void);
};

//////////////////////////////////////////////////////

/* 'mrWindows.cpp' */

/* Complement header file */
#include "mrWindow.h"

/* Default constructor */
mrWindow::mrWindow (void)
{
/* Do nothing */
}

/* Default destructor */
mrWindow::~mrWindow (void)
{
/* Do nothing */
}

/* Create the window */
mrError32 mrWindow::Create (HINSTANCE hInstance, LPSTR szTitle, mrInt iWidth,
                            mrInt iHeight, mrUInt32 iStyle)
{
  /* 'Visual' proprieties */
m_kWndClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
m_kWndClass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
m_kWndClass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);

  /* System proprieties */
m_kWndClass.hInstance     = hInstance;
m_kWndClass.lpfnWndProc   = WndProc;
m_kWndClass.lpszClassName = "Mirus Window";

  /* Extra proprieties */
m_kWndClass.lpszMenuName  = NULL;

m_kWndClass.cbClsExtra = NULL;
m_kWndClass.cbWndExtra = NULL;
m_kWndClass.style      = NULL;

  /* Try to register class */
if (!RegisterClass (&m_kWndClass))
{
  return mrErrorRegisterClass;
}

  /* Create the window */
m_hWindow = CreateWindow ("Mirus Window", szTitle, iStyle, CW_USEDEFAULT,
                           CW_USEDEFAULT, iWidth, iHeight,
                           NULL, NULL, hInstance, (void *) this);
SetWindowText (m_hWindow, szTitle);

return mrNoError;
}

/* Normal message handler - direct messages to our own*/
LRESULT CALLBACK mrWindow::WndProc (HWND hWindow, UINT iMessage,
                                    WPARAM wParam, LPARAM lParam)
{
mrWindow * pkWindow   = NULL;
mrBool32   bProcessed = mrFalse;

switch (iMessage)
{
  /* Window is creating - set custom information */
case WM_NCCREATE:
  SetWindowLong (hWindow, GWL_USERDATA,
                 (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
  break;
  /* Window message - Let our handler process it */
default:
   pkWindow = (mrWindow *) GetWindowLong (hWindow, GWL_USERDATA);
   if (NULL != pkWindow)
   {
    bProcessed = pkWindow->MessageHandler (iMessage, wParam, lParam);
   }
  break;
}
   /* Message not processed - let windows handle it */
if (mrFalse == bProcessed)
{
  return DefWindowProc (hWindow, iMessage, wParam, lParam);
}
return 0;
}

/* Real time message loop */
void mrWindow::Run (void)
{
while (1)
{
   /* Query to see if there is any message in the queue */
  if (PeekMessage (&m_kMessage, m_hWindow, 0, 0, PM_REMOVE))
  {
    /* If it is the WM_QUIT message, quit the loop */
   if (WM_QUIT == m_kMessage.message)
   {
    break;
   }
    /* Process the message normally */
   else
   {
    TranslateMessage (&m_kMessage);
    DispatchMessage (&m_kMessage);
   }
  }
    /* No message, do frame */
  else
  {
   Frame ();
  }
}
}

/* Our message handler */
mrBool32 mrWindow::MessageHandler (UINT iMessage, WPARAM wParam,
                                   LPARAM lParam)
{
switch (iMessage)
{
  /* Close window */
case WM_CLOSE:
  PostQuitMessage (0);
  return mrTrue;
break;
  /* Not handled - let Windows handle */
default:
  return mrFalse;
break;
}
}

/* Set window position */
void mrWindow::SetPosition (mrInt iX, mrInt iY)
{
  /* Set window position */
SetWindowPos(m_hWindow, HWND_TOP, iX, iY, 0, 0, SWP_NOSIZE);
}

/* Get window position */
POINT mrWindow::GetPosition (void)
{
RECT  rcWindow;
POINT pPosition;
  /* Get window position */
GetWindowRect (m_hWindow, &rcWindow);

pPosition.x = rcWindow.left;
pPosition.y = rcWindow.top;

return pPosition;
}

/* Set window size */
void mrWindow::SetSize (mrInt iWidth, mrInt iHeight)
{
  /* Set window position */
SetWindowPos(m_hWindow, HWND_TOP, 0, 0, iWidth, iHeight, SWP_NOMOVE);
}

/* Gt window size */
POINT mrWindow::GetSize (void)
{
RECT  rcWindow;
POINT pSize;
  /* Get window position */
GetWindowRect (m_hWindow, &rcWindow);

pSize.x = rcWindow.right  - rcWindow.left;
pSize.y = rcWindow.bottom - rcWindow.top;

return pSize;
}

/* Modify window state */
void mrWindow::Show (mrInt iShow)
{
  /* Change window visibility */
ShowWindow (m_hWindow, iShow);
}

/* Return window handle */
HWND mrWindow::GetHandle (void)
{
        return m_hWindow;
}

/////////////////////////////////////////////////////////

/* '01 Main.cpp' */

/* Mirus window framework header */
#include "mrWindow.h"
/* Direct3D header */
#include <d3d8.h>

/* Custom derived class */
class D3DWindow : public mrWindow
{
  /* Direct 3D interfaces */
LPDIRECT3D8             m_pD3D;
LPDIRECT3DDEVICE8       m_pD3DDevice;
public:
  /* Constructor / Destructor */
D3DWindow (void) {};
~D3DWindow (void) {};

  /* Setup and shutdown Direct3D */
HRESULT SetupDirect3D (void);
HRESULT KillDirect3D (void);

  /* Window manipulation functions */
mrBool32 Frame (void);
};

/* Initializes Direct3D */
HRESULT D3DWindow::SetupDirect3D (void)
{
  /* Create the Direct3D object */
if (NULL == (m_pD3D = Direct3DCreate8 (D3D_SDK_VERSION) ) )
{
  return E_FAIL;
}

  /* Get the current display mode so we can know what bitdepth
     we are */
D3DDISPLAYMODE d3ddm;
if (FAILED (m_pD3D->GetAdapterDisplayMode (D3DADAPTER_DEFAULT,
                                            &d3ddm) ) )
{
  return E_FAIL;
}

  /* Fill in the present paramenters */
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
  /* We want windowed mode */
d3dpp.Windowed   = TRUE;
  /* Discard this */
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  /* Same format as the current format
     (we got this from g_pD3D->GetAdapterDisplayMode)  */
d3dpp.BackBufferFormat = d3ddm.Format;

  /* Create the device */
if (FAILED (m_pD3D->CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
                                   m_hWindow,
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                   &d3dpp,
                                   &m_pD3DDevice ) ) )
{
  return E_FAIL;
}

return D3D_OK;
}

/* Shutdowns Direct3D */
HRESULT D3DWindow::KillDirect3D (void)
{
   /* If any of the Direct3D objects exist, release them */
if ( NULL != m_pD3D)
{
  m_pD3D->Release ();
}
if ( NULL != m_pD3DDevice)
{
  m_pD3DDevice->Release ();
}

return D3D_OK;

}

/* Clears the screen to blue */
mrBool32 D3DWindow::Frame (void)
{
  /* Clear the window to blue */
m_pD3DDevice->Clear (0, NULL, D3DCLEAR_TARGET,
                      D3DCOLOR_XRGB (0,0,255), 1.0f, 0);

  /* Start rendering */
m_pD3DDevice->BeginScene();
m_pD3DDevice->EndScene();

  /* Present the rendered scene to the screen */
m_pD3DDevice-&gtresent (NULL, NULL, NULL, NULL);

return mrTrue;
}

/* "WinMain Vs. main" */
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInst,
                    LPSTR lpCmdLine, int nShowCmd)
{
  /* Our window */
D3DWindow  kWindow;

  /* Create window */
kWindow.Create (hInstance, "Init and Shutdown");

  /* Setup Direct3D */
kWindow.SetupDirect3D ();

  /* Enter message loop */
kWindow.Run ();

  /* Shutdown Direct3D */
kWindow.KillDirect3D ();

return 0;
}

3

主题

14

帖子

57

积分

注册会员

Rank: 2

积分
57
 楼主| 发表于 2007-12-7 16:26:00 | 显示全部楼层

Re:关于一个游戏框架的问题, 哪位大虾给解决一下?

该程序没有什么问题。

我现在想解决的是: 程序运行后, 能马上关闭窗口且也关闭了该程序的进程。

纳位大虾能指点一二, 小弟不胜感激!

27

主题

418

帖子

455

积分

中级会员

Rank: 3Rank: 3

积分
455
QQ
发表于 2007-12-8 03:45:00 | 显示全部楼层

Re:关于一个游戏框架的问题, 哪位大虾给解决一下?

我用Delphi的,不知道说什么。呵呵。
建议你去看看那本 Programming Windows.

3

主题

14

帖子

57

积分

注册会员

Rank: 2

积分
57
 楼主| 发表于 2007-12-8 10:13:00 | 显示全部楼层

Re:关于一个游戏框架的问题, 哪位大虾给解决一下?

已经看过了, 研究了2个月, 在学directx
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-17 17:06

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表