📄 mgcwinapplication.cpp
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement. The various license agreements may be found at
// the Magic Software web site. This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License/free.pdf
#include <windows.h>
#include <mmsystem.h>
#include "MgcApplication.h"
#include "MgcCommand.h"
#include <MgcOglRenderer.pkg>
#include <MgcSoftRenderer.pkg>
const int MgcApplication::KEY_ESCAPE = VK_ESCAPE;
const int MgcApplication::KEY_LEFT_ARROW = VK_LEFT;
const int MgcApplication::KEY_RIGHT_ARROW = VK_RIGHT;
const int MgcApplication::KEY_UP_ARROW = VK_UP;
const int MgcApplication::KEY_DOWN_ARROW = VK_DOWN;
const int MgcApplication::KEY_HOME = VK_HOME;
const int MgcApplication::KEY_END = VK_END;
const int MgcApplication::KEY_PAGE_UP = VK_PRIOR;
const int MgcApplication::KEY_PAGE_DOWN = VK_NEXT;
const int MgcApplication::KEY_INSERT = VK_INSERT;
const int MgcApplication::KEY_DELETE = VK_DELETE;
const int MgcApplication::KEY_F1 = VK_F1;
const int MgcApplication::KEY_F2 = VK_F2;
const int MgcApplication::KEY_F3 = VK_F3;
const int MgcApplication::KEY_F4 = VK_F4;
const int MgcApplication::KEY_F5 = VK_F5;
const int MgcApplication::KEY_F6 = VK_F6;
const int MgcApplication::KEY_F7 = VK_F7;
const int MgcApplication::KEY_F8 = VK_F8;
const int MgcApplication::KEY_F9 = VK_F9;
const int MgcApplication::KEY_F10 = VK_F10;
const int MgcApplication::KEY_F11 = VK_F11;
const int MgcApplication::KEY_F12 = VK_F12;
const int MgcApplication::MOUSE_LEFT_BUTTON = 0;
const int MgcApplication::MOUSE_MIDDLE_BUTTON = 1;
const int MgcApplication::MOUSE_RIGHT_BUTTON = 2;
const int MgcApplication::MOUSE_UP = 0;
const int MgcApplication::MOUSE_DOWN = 1;
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"MgcCore.lib")
#pragma comment(lib,"MgcEngine.lib")
#pragma comment(lib,"MgcOglRenderer.lib")
#pragma comment(lib,"MgcGPRenderer.lib")
#pragma comment(lib,"MgcSoftRenderer.lib")
//---------------------------------------------------------------------------
void MgcApplication::RequestTermination ()
{
PostMessage((HWND)ms_iWindowID,WM_DESTROY,0,0);
}
//----------------------------------------------------------------------------
MgcReal MgcApplication::GetTimeInSeconds ()
{
MgcReal fTime = 0.001*timeGetTime();
return fTime;
}
//----------------------------------------------------------------------------
void MgcApplication::MoveCamera ()
{
// GLUT does not have distinct callbacks for key-down versus key-up. So
// I have to reset the 'key down' flags each time. This leads to not so
// smooth camera motion. For Windows, we don't have this problem.
if ( m_bUArrowPressed )
MoveForward();
else if ( m_bDArrowPressed )
MoveBackward();
if ( m_bHomePressed )
MoveUp();
else if ( m_bEndPressed )
MoveDown();
if ( m_bLArrowPressed )
TurnLeft();
else if ( m_bRArrowPressed )
TurnRight();
if ( m_bPgUpPressed )
LookUp();
else if ( m_bPgDnPressed )
LookDown();
}
//----------------------------------------------------------------------------
static char* ProcessCommand (char* acArgument)
{
int iLength = strlen(acArgument);
// strip off quotes if command line was built from double-clicking a file
char* acProcessed = new char[iLength+1];
if ( acArgument[0] == '\"' )
{
strcpy(acProcessed,acArgument+1); // remove leading quote
if ( acArgument[iLength-1] == '\"' )
acProcessed[iLength-2] = '\0'; // remove trailing quote
}
else
{
strcpy(acProcessed,acArgument);
}
return acProcessed;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK WinProc (HWND hWnd, UINT uiMsg, WPARAM wParam,
LPARAM lParam)
{
// GLUT does not support callbacks for key-down and key-up events. As
// such, it is not possible to get smooth camera motion with the
// turret-based system while using GLUT. However, Windows does have
// key-down and key-up messages. The following hack is used to allow
// a Windows-based application to get the smooth motion.
//
// The key-pressed callbacks require the mouse coordinates to be passed
// as a pair of integers. For Windows, the low-order byte of the x value
// will contain the mouse x location. The high-order byte will contain
// either a 0 (WM_CHAR), 1 (WM_KEYDOWN), or 2 (WM_KEYUP). The y value
// contains the mouse location without encoding.
MgcApplication* pkTheApp = MgcApplication::GetApplication();
if ( !pkTheApp )
return DefWindowProc(hWnd,uiMsg,wParam,lParam);
switch ( uiMsg )
{
case WM_PAINT:
{
PAINTSTRUCT kPS;
HDC hDC = BeginPaint(hWnd,&kPS);
pkTheApp->OnDisplay();
EndPaint(hWnd,&kPS);
return 0;
}
case WM_MOVE:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMotion(iXPos,iYPos);
return 0;
}
case WM_SIZE:
{
int iWidth = int(LOWORD(lParam));
int iHeight = int(HIWORD(lParam));
pkTheApp->OnReshape(iWidth,iHeight);
return 0;
}
case WM_CHAR:
{
unsigned char ucKey = (unsigned char)(char)wParam;
POINT kPoint;
GetCursorPos(&kPoint);
int iXPos = (int) kPoint.x;
int iYPos = (int) kPoint.y;
pkTheApp->OnKeyPress(ucKey,iXPos,iYPos);
return 0;
}
case WM_KEYDOWN:
{
int iVirtKey = int(wParam);
if ( (VK_F1 <= iVirtKey && iVirtKey <= VK_F12)
|| (VK_PRIOR <= iVirtKey && iVirtKey <= VK_DOWN)
|| (iVirtKey == VK_INSERT) )
{
pkTheApp->OnSpecialKeyDown(iVirtKey);
}
else
{
pkTheApp->OnKeyDown(iVirtKey);
}
return 0;
}
case WM_KEYUP:
{
int iVirtKey = int(wParam);
if ( (VK_F1 <= iVirtKey && iVirtKey <= VK_F12)
|| (VK_PRIOR <= iVirtKey && iVirtKey <= VK_DOWN)
|| (iVirtKey == VK_INSERT) )
{
pkTheApp->OnSpecialKeyUp(iVirtKey);
}
else
{
pkTheApp->OnKeyUp(iVirtKey);
}
return 0;
}
case WM_LBUTTONDOWN:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMousePress(MgcApplication::MOUSE_LEFT_BUTTON,
MgcApplication::MOUSE_DOWN,iXPos,iYPos);
return 0;
}
case WM_LBUTTONUP:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMousePress(MgcApplication::MOUSE_LEFT_BUTTON,
MgcApplication::MOUSE_UP,iXPos,iYPos);
return 0;
}
case WM_MBUTTONDOWN:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMousePress(MgcApplication::MOUSE_MIDDLE_BUTTON,
MgcApplication::MOUSE_DOWN,iXPos,iYPos);
return 0;
}
case WM_MBUTTONUP:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMousePress(MgcApplication::MOUSE_MIDDLE_BUTTON,
MgcApplication::MOUSE_UP,iXPos,iYPos);
return 0;
}
case WM_RBUTTONDOWN:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMousePress(MgcApplication::MOUSE_RIGHT_BUTTON,
MgcApplication::MOUSE_DOWN,iXPos,iYPos);
return 0;
}
case WM_RBUTTONUP:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
pkTheApp->OnMousePress(MgcApplication::MOUSE_RIGHT_BUTTON,
MgcApplication::MOUSE_UP,iXPos,iYPos);
return 0;
}
case WM_MOUSEMOVE:
{
int iXPos = int(LOWORD(lParam));
int iYPos = int(HIWORD(lParam));
unsigned int uiKeys = (unsigned int)(wParam);
if ( (uiKeys & MK_LBUTTON)
|| (uiKeys & MK_MBUTTON)
|| (uiKeys & MK_RBUTTON) )
{
pkTheApp->OnMotion(iXPos,iYPos);
}
else
{
pkTheApp->OnPassiveMotion(iXPos,iYPos);
}
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd,uiMsg,wParam,lParam);
}
//---------------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR acArgument, int)
{
MgcApplication* pkTheApp = MgcApplication::GetApplication();
assert( pkTheApp );
if ( !pkTheApp )
return -1;
if ( acArgument && strlen(acArgument) > 0 )
{
char* acProcessed = ProcessCommand(acArgument);
pkTheApp->SetCommand(new MgcCommand(acProcessed));
delete[] acProcessed;
}
// register the window class
static char s_acWindowClass[] = "Wild Magic Application";
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = s_acWindowClass;
wc.lpszMenuName = 0;
RegisterClass(&wc);
// require the window to have the specified client area
RECT kRect = { 0, 0, pkTheApp->GetWidth()-1, pkTheApp->GetHeight()-1 };
AdjustWindowRect(&kRect,WS_OVERLAPPEDWINDOW,false);
// create the application window
HWND hWnd = CreateWindow (s_acWindowClass,pkTheApp->GetWindowTitle(),
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
kRect.right - kRect.left + 1,kRect.bottom - kRect.top + 1,0,0,
hInstance,0);
pkTheApp->SetWindowID((int)hWnd);
if ( MgcApplication::GetCommand()
&& MgcApplication::GetCommand()->Boolean("soft") )
{
pkTheApp->SetRenderer(new MgcSoftRenderer(hWnd,pkTheApp->GetWidth(),
pkTheApp->GetHeight()));
pkTheApp->SetCamera(new MgcGPCamera(pkTheApp->GetWidth(),
pkTheApp->GetHeight()));
}
else
{
pkTheApp->SetRenderer(new MgcOglRenderer(hWnd,pkTheApp->GetWidth(),
pkTheApp->GetHeight()));
pkTheApp->SetCamera(new MgcOglCamera(pkTheApp->GetWidth(),
pkTheApp->GetHeight()));
}
if ( !pkTheApp->OnInitialize() )
return -2;
// display the window
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
// allow the application to initialize before starting the message pump
MSG kMsg;
while ( TRUE )
{
if ( PeekMessage(&kMsg,0,0,0,PM_REMOVE) )
{
if ( kMsg.message == WM_QUIT )
break;
HACCEL hAccel = 0;
if ( !TranslateAccelerator(hWnd,hAccel,&kMsg) )
{
TranslateMessage(&kMsg);
DispatchMessage(&kMsg);
}
}
else
{
pkTheApp->OnIdle();
}
}
pkTheApp->OnTerminate();
return 0;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -