⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display_window_win32.cpp

📁 这是一款2d游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*  $Id: display_window_win32.cpp,v 1.59 2003/11/11 14:59:44 sphair Exp $
**
**  ClanLib Game SDK
**  Copyright (C) 2003  The ClanLib Team
**  For a total list of contributers see the file CREDITS.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This library is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**  Lesser General Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

#include "dinput.h"
#include "Display/display_precomp.h"
#include "display_window_win32.h"
#include "input_device_win32keyboard.h"
#include "input_device_win32mouse.h"
#include "input_device_directinput.h"
#include "Core/System/Win32/init_win32.h"
#include "API/Display/input_event.h"
#include "API/Display/keys.h"
#include "API/Display/display_window_description.h"
#include "API/Core/Math/rect.h"
#include "API/Core/System/error.h"
#include "API/Core/System/clanstring.h"
#include "API/Core/System/log.h"

#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL    0x020A
#endif

#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN   0x020B
#define WM_XBUTTONUP     0x020C
#define WM_XBUTTONDBLCLK 0x020D
#endif

#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#endif

// My dinput.lib seem to be broken (the one with msvc7).
// It gives me a linker error about DirectInput8Create. Easier to create with cocreateinstance than
// download hundred megabytes. :) -- mbn 5 oct 2003
#define BROKEN_DINPUT

/////////////////////////////////////////////////////////////////////////////
// CL_DisplayWindow_Win32 construction:

CL_DisplayWindow_Win32::CL_DisplayWindow_Win32()
: hwnd(NULL), title("nonamed"), fullscreen(false),
	allow_resize(false), layered(false), bpp(0), saved_position(0, 0, 0, 0),
	left_ctrl_down(false), left_alt_down(false), left_shift_down(false),
	right_ctrl_down(false), right_alt_down(false), right_shift_down(false),
	mouse_pos(-1,-1), directinput(0)
{
	keyboard = CL_InputDevice(new CL_InputDevice_Win32Keyboard(this));
	mouse = CL_InputDevice(new CL_InputDevice_Win32Mouse(this));

	memset(keys_down, 0, 256);

#ifndef BROKEN_DINPUT
	HRESULT result = DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *) &directinput, 0);
	if (FAILED(result))
	{
		CL_Log::log("debug", "Unable to initialize direct input");
	}
#else
	// My directinput doesnt know this directinput8create function (hmm weird)
	// So creating it via CoCreateInstance instead..

	HRESULT result = CoInitialize(0);
	if (FAILED(result))
	{
		throw CL_Error("CL_DisplayWindow_Win32: Damn murphy must hate you. CoInitialize failed!");
	}

	result = CoCreateInstance(CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, IID_IDirectInput8A, (LPVOID *) &directinput);
	if (FAILED(result))
	{
		CL_Log::log("debug", "Unable to create direct input");
	}
	else
	{
		result = directinput->Initialize(GetModuleHandle(0), DIRECTINPUT_VERSION);
		if (FAILED(result))
		{
			directinput->Release();
			directinput = 0;

			CL_Log::log("debug", "Unable to initialize direct input");
		}
	}
#endif
}

CL_DisplayWindow_Win32::~CL_DisplayWindow_Win32()
{
	if (hwnd) destroy_window();
#ifndef BROKEN_DINPUT
	if (directinput) directinput->Release();
#else
	if (directinput) directinput->Release();
	CoUninitialize();
#endif
}

/////////////////////////////////////////////////////////////////////////////
// CL_DisplayWindow_Win32 attributes:

std::map<HWND, CL_DisplayWindow_Win32 *> CL_DisplayWindow_Win32::window_map;

int CL_DisplayWindow_Win32::get_width() const
{
	if (layered) return layered_position.get_width();

	RECT rect;
	GetClientRect(hwnd, &rect);
	return rect.right - rect.left;
}

int CL_DisplayWindow_Win32::get_height() const
{
	if (layered) return layered_position.get_height();

	RECT rect;
	GetClientRect(hwnd, &rect);
	return rect.bottom - rect.top;
}

bool CL_DisplayWindow_Win32::is_fullscreen() const
{
	return fullscreen;
}

bool CL_DisplayWindow_Win32::has_focus() const
{
	return (GetFocus() == hwnd);
}

static CL_PixelBuffer *buffer_todo = 0; // hack until we implement pixelbuffer

CL_PixelBuffer &CL_DisplayWindow_Win32::get_buffer(int i)
{
	return *buffer_todo;
}

const CL_PixelBuffer &CL_DisplayWindow_Win32::get_buffer(int i) const
{
	return *buffer_todo;
}

int CL_DisplayWindow_Win32::get_buffer_count() const
{
	return 1;
}

bool CL_DisplayWindow_Win32::get_keycode(int keycode) const
{
	return false;
}

/////////////////////////////////////////////////////////////////////////////
// CL_DisplayWindow_Win32 operations:

void CL_DisplayWindow_Win32::set_fullscreen(int width, int height, int bpp, int refresh_rate)
{
	CL_DisplayWindowDescription desc;
	desc.set_title(title);
	desc.set_size(CL_Size(width, height));
	desc.set_bpp(bpp);
	desc.set_refresh_rate(refresh_rate);
	desc.set_allow_resize(allow_resize);
	desc.set_fullscreen(true);
	desc.set_layered(layered);
	create_window(desc);
}

void CL_DisplayWindow_Win32::set_windowed()
{
	if (!fullscreen) return;

	CL_DisplayWindowDescription desc;
	desc.set_title(title);
	desc.set_allow_resize(allow_resize);
	desc.set_layered(layered);
	create_window(desc);
}

void CL_DisplayWindow_Win32::set_title(const std::string &_title)
{
	title = _title;
	SetWindowText(hwnd, title.c_str());
}

void CL_DisplayWindow_Win32::set_position(const CL_Rect &pos)
{
	layered_position = pos;
	SetWindowPos(hwnd, 0, pos.left, pos.top, pos.get_width(), pos.get_height(), SWP_NOREPOSITION|SWP_NOZORDER);
}

void CL_DisplayWindow_Win32::set_position(int x, int y)
{
	CL_Size size = layered_position.get_size();
	layered_position = CL_Rect(x, y, x+size.width, y+size.height);

	SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOREPOSITION|SWP_NOZORDER|SWP_NOSIZE);
}

void CL_DisplayWindow_Win32::set_size(int width, int height)
{
	layered_position.set_size(CL_Size(width, height));
	SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOREPOSITION|SWP_NOZORDER|SWP_NOMOVE);
}

void CL_DisplayWindow_Win32::set_buffer_count(int flipping_buffers)
{
}

void CL_DisplayWindow_Win32::update(const CL_Rect &rect)
{
}

void CL_DisplayWindow_Win32::flip()
{
}

void CL_DisplayWindow_Win32::create_window(const CL_DisplayWindowDescription &desc)
{
	if (hwnd)
	{
		modify_window(desc);
	}
	else
	{
		create_new_window(desc);
	}
}

void CL_DisplayWindow_Win32::modify_window(const CL_DisplayWindowDescription &desc)
{
	if (!fullscreen)
	{
		RECT rect;
		GetWindowRect(hwnd, &rect);

		saved_position.left = rect.left;
		saved_position.top = rect.top;
		saved_position.right = rect.right;
		saved_position.bottom = rect.bottom;
	}

	title = desc.get_title();
	fullscreen = desc.is_fullscreen();
	layered = desc.is_layered();
	layered_position = desc.get_position();
	allow_resize = desc.get_allow_resize();

	int x = 0;
	int y = 0;
	int width = desc.get_size().width;
	int height = desc.get_size().height;

	if (desc.is_fullscreen())
	{
		width = GetSystemMetrics(SM_CXSCREEN);
		height = GetSystemMetrics(SM_CYSCREEN);
	}
	else
	{
		int scr_width = GetSystemMetrics(SM_CXSCREEN);
		int scr_height = GetSystemMetrics(SM_CYSCREEN);

		x = scr_width/2 - width/2;
		y = scr_height/2 - height/2;
	}

	if (width == 0 && height == 0)
	{
		x = saved_position.left;
		y = saved_position.top;
		width = saved_position.get_width();
		height = saved_position.get_height();
	}

	int style;
	if (desc.is_fullscreen())
	{
		style = WS_POPUP;
	}
	else if (allow_resize)
	{
		style = WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
	}
	else
	{
		style = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX;
	}

	int ex_style = 0;
	if (desc.is_layered())
	{
		ex_style = WS_EX_LAYERED;
	}

	// get size of window with decorations to pass to CreateWindow
	RECT window_rect = { x, y, x+width, y+height };
	AdjustWindowRect( &window_rect, style, false );

	SetWindowLong(hwnd, GWL_STYLE, style);
	SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);

	if (desc.is_fullscreen())
	{
		// Make always on top
		SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_FRAMECHANGED);
	}
	else
	{
		// Clear always on top flag; size as requested by description struct.
		SetWindowPos(
			hwnd,
			HWND_TOP,
			window_rect.left,
			window_rect.top,
			window_rect.right-window_rect.left,
			window_rect.bottom-window_rect.top,
			SWP_FRAMECHANGED);
	}

	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);
}

void CL_DisplayWindow_Win32::create_new_window(const CL_DisplayWindowDescription &desc)
{
	title = desc.get_title();
	fullscreen = desc.is_fullscreen();
	layered = desc.is_layered();
	layered_position = desc.get_position();
	allow_resize = desc.get_allow_resize();

	WNDCLASS wndclass;

	wndclass.style = 0;
	wndclass.lpfnWndProc = (WNDPROC) CL_DisplayWindow_Win32::message_handler;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = CL_System_Win32::hInstance;
	wndclass.hIcon = NULL;
	wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wndclass.lpszMenuName = "ClanApplication";
	wndclass.lpszClassName = "ClanApplication";

	RegisterClass(&wndclass);

	int x = 0;
	int y = 0;
	int width = desc.get_size().width;
	int height = desc.get_size().height;

	if (desc.is_fullscreen())
	{
		width = GetSystemMetrics(SM_CXSCREEN);
		height = GetSystemMetrics(SM_CYSCREEN);
	}
	else
	{
		int scr_width = GetSystemMetrics(SM_CXSCREEN);
		int scr_height = GetSystemMetrics(SM_CYSCREEN);

		x = scr_width/2 - width/2;
		y = scr_height/2 - height/2;
	}

	if (width == 0 && height == 0)
	{
		x = saved_position.left;
		y = saved_position.top;
		width = saved_position.get_width();
		height = saved_position.get_height();
	}

	int style;
	if (desc.is_fullscreen())
	{
		style = WS_POPUP;
	}
	else if (allow_resize)
	{
		style = WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
	}
	else
	{
		style = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX;
	}

	int ex_style = 0;
	if (desc.is_layered())
	{
		ex_style = WS_EX_LAYERED;
	}

	// get size of window with decorations to pass to CreateWindow
	RECT window_rect = { x, y, x+width, y+height };
	AdjustWindowRect( &window_rect, style, false );

	hwnd = CreateWindowEx(
		ex_style,
		"ClanApplication",
		title.c_str(),
		style,
		window_rect.left,
		window_rect.top,
		window_rect.right - window_rect.left,
		window_rect.bottom - window_rect.top,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -