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

📄 wg_application.cpp

📁 一个小巧的嵌入式图形系统wGUI, 可以用VC编译
💻 CPP
字号:
// wg_application.cpp//// CApplication interface////// Copyright (c) 2002 Rob Wiskow// rob-dev@boxedchaos.com//// 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 "wgui_include_config.h"#include "wg_application.h"#include "wg_error.h"#include "wg_debug.h"#include "std_ex.h"#include <iostream>#include <fstream>namespace wGui{// Static membersCApplication* CApplication::m_pInstance = 0;void CApplication::HandleSDLEvent(SDL_Event Event){	// this will turn an SDL event into a wGui message	switch (Event.type)	{	case SDL_VIDEORESIZE:		CMessageServer::Instance().QueueMessage(new TPointMessage(			CMessage::CTRL_RESIZE, 0, 0, CPoint(Event.resize.w, Event.resize.h)));		break;	case SDL_KEYDOWN:		CMessageServer::Instance().QueueMessage(new CKeyboardMessage(			CMessage::KEYBOARD_KEYDOWN, CApplication::Instance()->GetKeyFocus(), this,			Event.key.keysym.scancode, Event.key.keysym.mod,			Event.key.keysym.sym, Event.key.keysym.unicode));		break;	case SDL_KEYUP:		CMessageServer::Instance().QueueMessage(new CKeyboardMessage(			CMessage::KEYBOARD_KEYUP, CApplication::Instance()->GetKeyFocus(), this,			Event.key.keysym.scancode, Event.key.keysym.mod,			Event.key.keysym.sym, Event.key.keysym.unicode));		break;	case SDL_MOUSEBUTTONDOWN:		CMessageServer::Instance().QueueMessage(new CMouseMessage(			CMessage::MOUSE_BUTTONDOWN, CApplication::Instance()->GetMouseFocus(), this,			CPoint(Event.button.x, Event.button.y), CPoint(),			CMouseMessage::TranslateSDLButton(Event.button.button)));		break;	case SDL_MOUSEBUTTONUP:		CMessageServer::Instance().QueueMessage(new CMouseMessage(			CMessage::MOUSE_BUTTONUP, CApplication::Instance()->GetMouseFocus(), this,			CPoint(Event.button.x, Event.button.y), CPoint(),			CMouseMessage::TranslateSDLButton(Event.button.button)));		break;	case SDL_MOUSEMOTION:		CMessageServer::Instance().QueueMessage(new CMouseMessage(			CMessage::MOUSE_MOVE, CApplication::Instance()->GetMouseFocus(), this,			CPoint(Event.motion.x, Event.motion.y), CPoint(Event.motion.xrel, Event.motion.yrel),			CMouseMessage::TranslateSDLButtonState(Event.motion.state)));		break;	case SDL_QUIT:		CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_EXIT, 0, this));		break;	}}CApplication::CApplication(int argc, char** argv, std::string sFontFileName, bool bHandleExceptionsInternally) :	m_argc(argc),	m_argv(argv),	m_sFontFileName(sFontFileName),	m_iExitCode(EXIT_FAILURE),	m_bRunning(false),	m_bInited(false),	m_pKeyFocusWindow(0),	m_pMouseFocusWindow(0),	m_pDefaultFontEngine(0),	m_bHandleExceptionsInternally(bHandleExceptionsInternally),	m_bResourcePoolEnabled(true),	m_pCurrentCursorResourceHandle(0),	m_pSystemDefaultCursor(0){	if (m_pInstance)	{		throw(Wg_Ex_App("CApplication::CApplication : An instance of the CApplication already exists."));	}	m_pInstance = this;	if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) == -1)	{		throw(Wg_Ex_SDL(std::string("CApplication::CApplication : Could not initialize SDL: ") + SDL_GetError()));	}	//Setting the keyboard repeat rate using the SDL Default rates	if(SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL) == -1)	{		throw(Wg_Ex_SDL(std::string("CApplication::Capplication : Error setting SDL keyboard repeat rate.")));	}	m_pSystemDefaultCursor = SDL_GetCursor();	atexit(SDL_Quit);}CApplication::~CApplication(void){	if (m_pInstance == this)	{		m_pInstance = 0;	}	for(std::map<std::pair<std::string, unsigned char>, CFontEngine*>::iterator iter = m_FontEngines.begin(); iter != m_FontEngines.end(); ++iter)	{		delete iter->second;		iter->second = 0;	}}void CApplication::SetKeyFocus(CWindow* pWindow){	// notify the window that's losing focus to repaint itself	if (m_pKeyFocusWindow)	{		CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, m_pKeyFocusWindow, this));	}	m_pKeyFocusWindow = pWindow;}void CApplication::SetMouseFocus(CWindow* pWindow){	// notify the window that's losing focus to repaint itself	if (m_pMouseFocusWindow)	{		CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, m_pMouseFocusWindow, this));	}	m_pMouseFocusWindow = pWindow;}void CApplication::Init(void){	CMessageServer::Instance().RegisterMessageClient(this, CMessage::APP_EXIT, CMessageServer::PRIORITY_LAST);	SDL_EnableUNICODE(1);	// Now we have to find the wGui.conf file and load it into the Global Config	// Our ordered search path is (so the current directory will overwrite any common settings with the other directories):	// <global directory>	// <home directory>	// <current directory>	// global directory first	m_GlobalConfig.ReadFromFile(GLOBAL_CONFIG_PATH + "wgui.conf");	// now the home directory	m_GlobalConfig.ReadFromFile(USER_CONFIG_PATH + "wgui.conf");	// and finally the current directory	m_GlobalConfig.ReadFromFile("wgui.conf");	if (m_GlobalConfig.EntryExists("DEFAULTFONT"))	{		if (m_GlobalConfig.EntryExists("DEFAULTFONTSIZE"))		{			m_pDefaultFontEngine = GetFontEngine(m_GlobalConfig.GetStringEntry("DEFAULTFONT").second,				static_cast<unsigned char>(m_GlobalConfig.GetLongIntEntry("DEFAULTFONTSIZE").second));		}		else		{			m_pDefaultFontEngine = GetFontEngine(m_GlobalConfig.GetStringEntry("DEFAULTFONT").second);		}	}	m_bInited = true;}void CApplication::Exec(void){	try	{		if (!m_bInited)		{			throw(Wg_Ex_App("CApplication::Exec : Application Init() was not called!"));		}		m_bRunning = true;		SDL_Event event;		CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));		while (m_bRunning)		{			while (SDL_PollEvent(&event))			{				HandleSDLEvent(event);			}			while (!CMessageServer::Instance().MessageAvailable())			{				while (SDL_PollEvent(&event))				{					HandleSDLEvent(event);				}				SDL_Delay(5);			}			try			{				CMessageServer::Instance().DeliverMessage();			}			catch (Wg_Ex_Base& DEBUG_ONLY(e))			{				if (!m_bHandleExceptionsInternally)				{					throw;				}				// Since we're handling exceptions internally, and it's one of our own exceptions, we're just going to				// send something to the debug output and then continue processing the message queue				Trace("wGui exception while delivering message : " + e.std_what());			}		}	}	catch (Wg_Ex_Base& DEBUG_ONLY(e))	{		if (!m_bHandleExceptionsInternally)		{			throw;		}		// We are supposed to handle all exceptions internally, but something hasn't been handled at this point, so we need to exit gracefully		Trace("Unhandled wGui exception : " + e.std_what());	}	catch (std::exception& DEBUG_ONLY(e))	{		if (!m_bHandleExceptionsInternally)		{			throw;		}		// We are supposed to handle all exceptions internally, but something hasn't been handled at this point, so we need to exit gracefully		Trace("Unhandled std exception : " + std::string(e.what()));	}	catch (...)	{		if (!m_bHandleExceptionsInternally)		{			throw;		}		// We are supposed to handle all exceptions internally, but something hasn't been handled at this point, so we need to exit gracefully		Trace("Unhandled exception");	}}void CApplication::ApplicationExit(int iExitCode){	// push an event into the SDL queue so the SDLEventLoopThread can exit	// the actual contents of the event are not a concern as it serves just to trigger the SDL_WaitEvent	SDL_Event user_event;	user_event.type=SDL_USEREVENT;	user_event.user.code=0;	user_event.user.data1=0;	user_event.user.data2=0;	DEBUG_ONLY(int iResult =) SDL_PushEvent(&user_event);	TraceIf(iResult == -1, "CApplication::ApplicationExit - Unable to push SDL user_event.");	m_iExitCode = iExitCode;	m_bRunning = false;}CFontEngine* CApplication::GetFontEngine(std::string sFontFileName, unsigned char iFontSize){	// First search to see if the requested font engine already exists	t_FontEngineMap::iterator iterFontEngine = m_FontEngines.find(std::make_pair(sFontFileName, iFontSize));	CFontEngine* pFontEngine = 0;	if (iterFontEngine == m_FontEngines.end())	{		// Requested font engine doesn't exist, so create one and add it to the map		try		{			if (sFontFileName.find_first_of("\\/") != std::string::npos)			{				// if the Font File name that was passed in includes a path, just check there				std::ifstream FileTest(sFontFileName.c_str());				bool bFileExists = FileTest.is_open();				FileTest.close();				if (bFileExists)				{					pFontEngine = new CFontEngine(sFontFileName, iFontSize);				}			}			else			{				// otherwise check the Font Path from the global config				std::list<std::string> FontPaths = stdex::DetokenizeString(m_GlobalConfig.GetStringEntry("FONTPATH").second, ";");				for(std::list<std::string>::iterator iter = FontPaths.begin(); iter != FontPaths.end(); ++iter)				{					std::string sFullPath = *iter;					if (!iter->empty()  && (*iter)[iter->length()] != '\\' && (*iter)[iter->length()] != '/')					{						sFullPath += "/";					}					sFullPath += sFontFileName;					std::ifstream FileTest(sFullPath.c_str());					bool bFileExists = FileTest.is_open();					FileTest.close();					if (bFileExists)					{						pFontEngine = new CFontEngine(sFullPath, iFontSize);					}				}			}			if (pFontEngine)			{				m_FontEngines.insert(std::make_pair(std::make_pair(sFontFileName, iFontSize), pFontEngine));			}		}		catch (Wg_Ex_FreeType& DEBUG_ONLY(e))		{			if (!m_bHandleExceptionsInternally)			{				throw;			}			Trace("CApplication::GetFontEngine - Exception thrown while creating Font Engine : " + e.std_what());		}	}	else	{		pFontEngine = iterFontEngine->second;	}	return pFontEngine;}void CApplication::EnableResourcePool(bool bEnable){	m_bResourcePoolEnabled = bEnable;	if (bEnable == false)	{		m_ResourceHandlePool.clear();	}}bool CApplication::AddToResourcePool(CResourceHandle& ResourceHandle){	bool bSuccess = false;	if (m_bResourcePoolEnabled)	{		m_ResourceHandlePool.push_back(ResourceHandle);	}	return bSuccess;}void CApplication::SetMouseCursor(CCursorResourceHandle* pCursorResourceHandle){	// The auto pointer is used to make sure that the cursor handle is valid until we're done using the cursor	if (pCursorResourceHandle && pCursorResourceHandle != m_pCurrentCursorResourceHandle.get())	{		std::auto_ptr<CCursorResourceHandle> pNewCursorResourceHandle(new CCursorResourceHandle(*pCursorResourceHandle));		m_pCurrentCursorResourceHandle = pNewCursorResourceHandle;		SDL_SetCursor(m_pCurrentCursorResourceHandle->Cursor());	}	else	{		if( m_pCurrentCursorResourceHandle.get() )		{			#ifdef MSVC6  // VC6's auto pointers are really broken				delete m_pCurrentCursorResourceHandle.release();				m_pCurrentCursorResourceHandle = std::auto_ptr<CCursorResourceHandle>(0);			#else				m_pCurrentCursorResourceHandle.reset(0);			#endif // MSVC6			SDL_SetCursor(m_pSystemDefaultCursor);		}	}}bool CApplication::HandleMessage(CMessage* pMessage){	bool bHandled = false;	if (pMessage)	{		switch (pMessage->MessageType())		{		case CMessage::APP_EXIT :			ApplicationExit();			bHandled = true;			break;		default:			break;		}	}	return bHandled;}}

⌨️ 快捷键说明

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