|
下面这个回调函数只处理了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-> resent (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;
}
|
|