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

📄 control.cpp

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 CPP
字号:
// This file is in the public domain.// There are no restrictions on any sort of usage of this file.#ifdef MONA#include <monapi.h>#include <monapi/messages.h>extern dword __gui_server;#endif#include <gui/System/Mona/Forms/Application.h>#include <gui/System/Mona/Forms/Control.h>#include <gui/System/Mona/Forms/ControlPaint.h>#include <gui/System/Mona/Forms/Form.h>using namespace System;using namespace System::Collections;using namespace System::Drawing;#define DEFAULT_FORECOLOR Color::get_Black()#define DEFAULT_BACKCOLOR ControlPaint::get_Light()#ifdef MONAstatic _P<MonAPI::Screen> s_screen;_P<MonAPI::Screen> GetDefaultScreen(){	if (s_screen == NULL)	{		s_screen.Set(new MonAPI::Screen(), true);	}	return s_screen;}#elseextern unsigned char* screen_buffer;extern int screen_width, screen_height;#ifdef WIN32extern void MonaGUI_Invalidate();#endif#endifstatic Rectangle GetScreenRectangle(){#ifdef MONA	_P<MonAPI::Screen> scr = GetDefaultScreen();	return Rectangle(0, 0, scr->getWidth(), scr->getHeight());#else	return Rectangle(0, 0, screen_width, screen_height);#endif}void DrawImage(_P<Bitmap> dst, _P<Bitmap> src, int x, int y, int sx, int sy, int sw, int sh, bool srccopy){	int dw = dst->get_Width(), dh = dst->get_Height();	int x1 = x, y1 = y, x2 = x + sw, y2 = y + sh;	if (x1 < 0) x1 = 0;	if (y1 < 0) y1 = 0;	if (x2 > dw) x2 = dw;	if (y2 > dh) y2 = dh;	x1 += sx - x;	y1 += sy - y;	x2 += sx - x;	y2 += sy - y;	if (x1 < 0) x1 = 0;	if (y1 < 0) y1 = 0;	if (x2 > src->get_Width ()) x2 = src->get_Width ();	if (y2 > src->get_Height()) y2 = src->get_Height();	x1 -= sx;	y1 -= sy;	x2 -= sx;	y2 -= sy;	for (int yy = y1; yy < y2; yy++)	{		Color* pDst = &dst->get()[( x + x1) + ( y + yy) * dw];		Color* pSrc = &src->get()[(sx + x1) + (sy + yy) * src->get_Width()];		for (int xx = x1; xx < x2; xx++, pDst++, pSrc++)		{			if (srccopy || pSrc->get_A() != 0) *pDst = *pSrc;		}	}}namespace System { namespace Mona { namespace Forms{	static _P<Font> s_font;		_P<Font> Control::get_DefaultFont()	{		if (s_font == NULL) s_font = new Font(Application::defaultFontData);		return s_font;	}	Control::Control()	{		this->bounds = Rectangle(0, 0, 32, 32);		this->foreColor = DEFAULT_FORECOLOR;		this->backColor = DEFAULT_BACKCOLOR;		this->foreColorChanged = false;		this->backColorChanged = false;		this->visible = false;		this->capture = false;		this->transparencyKey = Color::get_Empty();		this->_object = NULL;		this->controls = new ControlCollection();		this->controls->target = this;	}		Control::~Control()	{		this->Dispose();	}		void Control::Show()	{		if (this->visible) return;				if (this->buffer == NULL) this->Create();		this->visible = true;		this->_object->Visible = this->visible;		this->Refresh();	}		void Control::Hide()	{		if (!this->visible) return;				this->visible = false;		if (this->parent != NULL) this->parent->Refresh();	}		void Control::Create()	{		if (this->buffer != NULL) return;				this->buffer = new Bitmap(this->get_Width(), this->get_Height());#ifdef MONA		MessageInfo msg;		if (MonAPI::Message::sendReceive(&msg, __gui_server, MSG_GUISERVER_CREATEWINDOW) != 0)		{			::printf("%s:%d:ERROR: can not connect to GUI server!\n", __FILE__, __LINE__);			this->Dispose();			return;		}		this->_object = (guiserver_window*)MonAPI::MemoryMap::map(msg.arg2);		if (this->_object == NULL)		{			::printf("%s:%d:ERROR: can not create window!\n", __FILE__, __LINE__);			this->Dispose();			return;		}		if (this->parent != NULL) this->_object->Parent = this->parent->get_Handle();		this->_object->X = this->get_X();		this->_object->Y = this->get_Y();		this->_object->Width  = this->get_Width();		this->_object->Height = this->get_Height();		this->_object->OffsetX = this->offset.X;		this->_object->OffsetY = this->offset.Y;		this->_object->BufferHandle = this->buffer->get_Handle();		this->_object->TransparencyKey = this->transparencyKey.ToArgb();#endif		int len = this->get_Width() * this->get_Height();		for (int i = 0; i < len; i++)		{			(*this->buffer.get())[i] = this->backColor;		}		if (this->parent != NULL)		{			if (!this->foreColorChanged) this->foreColor = this->parent->foreColor;			if (!this->backColorChanged) this->backColor = this->parent->backColor;		}				FOREACH_AL(_P<Control>, ctrl, this->controls)		{			ctrl->Create();		}		END_FOREACH_AL	}		void Control::Close()	{		this->Dispose();	}		void Control::Dispose()	{		this->Hide();		MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_DISPOSEWINDOW, this->get_Handle());		this->_object = NULL;		this->parent = NULL;		this->buffer = NULL;				this->TextChanged = NULL;		this->ForeColorChanged = NULL;		this->BackColorChanged = NULL;		this->MouseMove = NULL;		this->MouseDown = NULL;		this->MouseUp = NULL;		this->Click = NULL;		FOREACH_AL(_P<Control>, ctrl, this->controls)		{			ctrl->Dispose();		}		END_FOREACH_AL		this->controls->Clear();		//this->controls->target = NULL;	}		void Control::Refresh()	{		if (this->buffer == NULL) return;				this->RefreshInternal();#ifdef MONA		MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_DRAWWINDOW, this->get_TopLevelControl()->get_Handle());#endif	}		void Control::RefreshInternal()	{		if (this->buffer == NULL) return;				Rectangle r(0, 0, this->get_Width(), this->get_Height());		int x = 0, y = 0;		_P<Control> form;		for (_P<Control> c = this; c != NULL; c = c->parent)		{			if (!c->visible) return;						if (c->parent != NULL)			{				r.X += c->get_X();				r.Y += c->get_Y();				r.Intersect(Rectangle(Point(), c->parent->get_ClientSize()));				r.X += c->parent->offset.X;				r.Y += c->parent->offset.Y;				x += c->get_X() + c->parent->offset.X;				y += c->get_Y() + c->parent->offset.Y;			}			form = c;		}				this->OnPaint();		DrawImage(((Form*)form.get())->formBuffer, this->buffer, r.X, r.Y, r.X - x, r.Y - y, r.Width, r.Height, this->parent == NULL);		FOREACH_AL(_P<Control>, ctrl, this->controls)		{			ctrl->RefreshInternal();		}		END_FOREACH_AL	}		_P<Graphics> Control::CreateGraphics()	{		_P<Graphics> ret = Graphics::FromImage(this->buffer);		Size sz = this->get_ClientSize();		ret->set_ClientRectangle(Rectangle(this->offset.X, this->offset.Y, sz.Width, sz.Height));		return ret;	}		Point Control::PointToClient(Point p)	{		p -= this->get_Location() + this->offset;		return this->parent == NULL ? p : this->parent->PointToClient(p);	}		Point Control::PointToScreen(Point p)	{		p += this->get_Location() + this->offset;		return this->parent == NULL ? p : this->parent->PointToScreen(p);	}		_P<Control> Control::get_TopLevelControl()	{		return this->parent == NULL ? this : this->parent->get_TopLevelControl();	}		_P<Control> Control::FindControl(int x, int y)	{		if (!this->bounds.Contains(x, y)) return NULL;				x -= this->get_X();		y -= this->get_Y();		if (this->buffer->GetPixel(x, y).get_A() == 0) return NULL;				x -= this->offset.X;		y -= this->offset.Y;		Size sz = this->get_ClientSize();		if (x >= sz.Width || y >= sz.Height) return this;				FOREACH_AL(_P<Control>, c, this->controls)		{			_P<Control> fc = c->FindControl(x, y);			if (fc != NULL) return fc;		}		END_FOREACH_AL		return this;	}		void Control::set_Location(Point p)	{		if (this->get_Location() == p) return;				this->bounds.X = p.X;		this->bounds.Y = p.Y;		if (this->_object == NULL) return;				if (this->parent == NULL)		{			MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_MOVEWINDOW, this->get_Handle(), (dword)p.X, (dword)p.Y);		}		else		{			this->_object->X = p.X;			this->_object->Y = p.Y;			this->parent->Refresh();		}	}		Size Control::get_ClientSize()	{		int bw = this->offset.X;		return Size(this->get_Width() - bw * 2, this->get_Height() - this->offset.Y - bw);	}		void Control::set_ClientSize(Size sz)	{		int bw = this->offset.X;		this->set_Size(Size(sz.Width + bw * 2, sz.Height + this->offset.Y + bw));	}		void Control::set_Visible(bool v)	{		if (v) this->Show(); else this->Hide();	}		void Control::set_Capture(bool v)	{		if (v == this->capture) return;				this->capture = v;		MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_MOUSECAPTURE, this->get_Handle(), v ? 1 : 0);	}		void Control::set_Text(String text)	{		if (this->text == text) return;				this->text = text;		this->OnTextChanged(EventArgs::get_Empty());	}		void Control::OnTextChanged(_P<EventArgs> e)	{		this->raise_TextChanged(this, e);		if (this->buffer == NULL) return;				this->Refresh();	}		void Control::set_ForeColor(Color c)	{		if (this->foreColor == c) return;				this->foreColor = c;		this->foreColorChanged = true;		this->OnForeColorChanged(EventArgs::get_Empty());	}		void Control::OnForeColorChanged(_P<EventArgs> e)	{		this->raise_ForeColorChanged(this, e);		if (this->buffer == NULL) return;				this->Refresh();	}		void Control::set_BackColor(Color c)	{		if (this->backColor == c) return;				this->backColor = c;		this->backColorChanged = true;		this->OnBackColorChanged(EventArgs::get_Empty());	}		void Control::OnBackColorChanged(_P<EventArgs> e)	{		this->raise_BackColorChanged(this, e);		if (this->buffer == NULL) return;				this->Refresh();	}		void Control::set_TransparencyKey(Color c)	{		this->transparencyKey = c;		if (this->_object == NULL) return;				unsigned int v = c.ToArgb();		if (this->_object->TransparencyKey == v) return;				this->_object->TransparencyKey = v;		this->Refresh();	}		Control::NCState Control::NCHitTest(int x, int y)	{		return Rectangle(Point::get_Empty(), this->get_ClientSize()).Contains(x, y)			? NCState_Client : NCState_None;	}		void Control::WndProc(MessageType type, _P<EventArgs> e)	{		switch (type)		{			case WM_MOUSEMOVE:			{				_P<MouseEventArgs> arg = (MouseEventArgs*)e.get();				Point pt = arg->Button == 0 ? Point(arg->X, arg->Y) : this->clickPoint;				this->NCHitTest(pt.X, pt.Y) == NCState_Client					? this->OnMouseMove(arg) : this->OnNCMouseMove(arg);				break;			}			case WM_MOUSEDOWN:			{				_P<MouseEventArgs> arg = (MouseEventArgs*)e.get();				this->clickPoint = Point(arg->X, arg->Y);				this->NCHitTest(arg->X, arg->Y) == NCState_Client					? this->OnMouseDown(arg) : this->OnNCMouseDown(arg);				break;			}			case WM_MOUSEUP:			{				_P<MouseEventArgs> arg = (MouseEventArgs*)e.get();				this->NCHitTest(this->clickPoint.X, this->clickPoint.Y) == NCState_Client					? this->OnMouseUp(arg) : this->OnNCMouseUp(arg);				break;			}			default:				break;		}	}		void Control::OnMouseMove(_P<MouseEventArgs> e)	{		this->raise_MouseMove(this, e);	}		void Control::OnMouseDown(_P<MouseEventArgs> e)	{		this->raise_MouseDown(this, e);	}		void Control::OnMouseUp(_P<MouseEventArgs> e)	{		this->raise_MouseUp(this, e);	}		void Control::OnMouseEnter(_P<EventArgs> e)	{		this->raise_MouseEnter(this, e);	}		void Control::OnMouseLeave(_P<EventArgs> e)	{		this->raise_MouseLeave(this, e);	}		void Control::OnClick(_P<EventArgs> e)	{		this->raise_Click(this, e);	}			#define BASE ArrayList<_P<Control> >		void Control::ControlCollection::Add(_P<Control> control)	{		BASE::Add(control);				control->parent = this->target;		control->visible = true;	}}}}

⌨️ 快捷键说明

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