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

📄 form.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/Form.h>#include <gui/System/Mona/Forms/Application.h>#include <gui/System/Mona/Forms/ControlPaint.h>#include <gui/System/Mona/Forms/Cursor.h>#include <gui/System/Drawing/Font.h>#include <gui/System/Math.h>#define BASE Controlusing namespace System;using namespace System::Drawing;static void EraseRectangle(_P<Bitmap> bmp, int x, int y, int w, int h){	int x1 = x, y1 = y, x2 = x + w, y2 = y + h;	int bw = bmp->get_Width(), bh = bmp->get_Height();	if (x1 < 0) x1 = 0;	if (y1 < 0) y1 = 0;	if (x2 > bw) x2 = bw;	if (y2 > bh) y2 = bh;	Color empty = Color::get_Empty();	for (int yy = y1; yy < y2; yy++)	{		Color* buf = &bmp->get()[x1 + yy * bw];		for (int xx = x1; xx < x2; xx++, buf++)		{			*buf = empty;		}	}}namespace System { namespace Mona { namespace Forms{	Form::Form() : isCloseButtonPushed(false), ncState(NCState_None), opacity(1.0)	{		this->offset = Point(2, Control::get_DefaultFont()->get_Height() + 8);#ifdef MONA		this->overlap = 0;#endif	}		Form::~Form()	{		this->Dispose();	}		void Form::Hide()	{		if (!this->get_Visible()) return;				BASE::Hide();		this->Erase();	}		void Form::Create()	{		BASE::Create();		Application::AddForm(this);		this->isCloseButtonPushed = false;		this->ncState = NCState_None;		this->formBuffer = new Bitmap(this->get_Width(), this->get_Height());		this->_object->FormBufferHandle = this->formBuffer->get_Handle();		this->_object->Opacity = (int)(this->opacity * 255.0);	}		void Form::Dispose()	{		BASE::Dispose();		Application::RemoveForm(this);		this->formBuffer = NULL;	}		void Form::Erase()	{		if (this->buffer == NULL) return;		#ifdef MONA		this->_object->Visible = false;		::monapi_call_mouse_set_cursor(MONAPI_FALSE);		MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_DRAWWINDOW, this->get_Handle());		::monapi_call_mouse_set_cursor(MONAPI_TRUE);		this->_object->Visible = this->get_Visible();#else		Size sz = this->get_Size();		_P<Bitmap> bmp = new Bitmap(sz.Width, sz.Height);		int len = sz.Width * sz.Height;		Color white = Color::get_White();		Color empty = Color::get_Empty();		for (int i = 0; i < len; i++)		{			(*bmp.get())[i] = (*this->buffer.get())[i].get_A() != 0 ? white : empty;		}		this->DrawImage(bmp);#endif	}		bool Form::CheckPoint(int x, int y)	{		return this->get_Bounds().Contains(x, y)			&& this->buffer->GetPixel(x - this->get_X(), y - this->get_Y()).get_A() != 0;	}		void Form::set_Opacity(double op)	{		if (op < 0.0) op = 0.0;		if (op > 1.0) op = 1.0;		this->opacity = op;		if (this->_object == NULL) return;				int v = (int)(op * 255.0);		if (this->_object->Opacity == v) return;				this->_object->Opacity = v;		this->Refresh();	}		void Form::OnPaint()	{		if (this->buffer == NULL || (this->_object->Flags & WINDOWFLAGS_NOBORDER) != 0) return;				_P<Graphics> g = Graphics::FromImage(this->buffer);		int w = this->get_Width(), h = this->get_Height(), oy = this->offset.Y;		_P<Font> f = Control::get_DefaultFont();		Size sz = g->MeasureString(this->get_Text(), f);		int tx = 2 + 2 + (oy - 8) + 2, tw = Math::Min(tx + sz.Width + 1 + 2 + 2, w);		Color tf = Color::get_Black(), tb = Color::FromArgb(0xff, 0xe0, 0);				// Title Bar		ControlPaint::DrawEngraved(g, 0, 0, tw, oy - 2);		if (tw < w) EraseRectangle(this->buffer, tw, 0, w - tw, oy - 2);		g->FillRectangle(tb, 2, 2, tw - 4, oy - 4);				// Close Button		ControlPaint::DrawEngraved(g, 4, 4, oy - 8, oy - 8);		if (this->isCloseButtonPushed)		{			g->FillRectangle(Color::FromArgb(0x80, 0x80, 0), 6, 6, oy - 12, oy - 12);		}				// Border		if (this->get_BackColor() != Color::get_Empty())		{			ControlPaint::DrawEngraved(g, 0, oy - 2, w, h - (oy - 2));		}				// Caption		g->set_ClientRectangle(Rectangle(tx, 4, w - tx - 4, oy - 8));		g->DrawString(this->get_Text(), f, tf, 0, 0);		g->DrawString(this->get_Text(), f, tf, 1, 0);				g->Dispose();	}		Control::NCState Form::NCHitTest(int x, int y)	{		if ((this->_object->Flags & WINDOWFLAGS_NOBORDER) != 0 || BASE::NCHitTest(x, y) == NCState_Client)		{			return NCState_Client;		}				int oy = this->offset.Y, xx = x + this->offset.X, yy = y + oy;		if (Rectangle(4, 4, oy - 8, oy - 8).Contains(xx, yy)) return NCState_CloseButton;		if (yy < oy) return NCState_TitleBar;		return NCState_None;	}	#ifndef MONA	void Form::DrawReversibleRectangle()	{		Rectangle r = this->get_Bounds();		r.X += this->ptRevRect.X - this->clickPoint.X;		r.Y += this->ptRevRect.Y - this->clickPoint.Y;		//r.X--; r.Y--; r.Width += 2; r.Height += 2;		for (int i = 0; i < 1; i++)		{			ControlPaint::DrawReversibleRectangle(r);			r.X++; r.Y++; r.Width -= 2; r.Height -= 2;		}	}#endif		void Form::OnNCMouseMove(_P<MouseEventArgs> e)	{		switch (this->ncState)		{			case NCState_CloseButton:			{				bool pushed = this->NCHitTest(e->X, e->Y) == NCState_CloseButton;				if (this->isCloseButtonPushed != pushed)				{					this->isCloseButtonPushed = pushed;					this->Refresh();				}				break;			}			case NCState_TitleBar:			{#ifdef MONA				Point p = this->PointToClient(Cursor::get_Position());				int ex = this->get_X() + (p.X - this->clickPoint.X), ey = this->get_Y() + (p.Y - this->clickPoint.Y);				if (this->ptRevRect.X != ex || this->ptRevRect.Y != ey)				{					this->ptRevRect = Point(ex, ey);					MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_MOVEOVERLAP, this->overlap,						MAKE_DWORD(ex, ey), MAKE_DWORD(this->get_Width(), this->get_Height()));				}#else				this->DrawReversibleRectangle();				this->ptRevRect = Point(e->X, e->Y);				this->DrawReversibleRectangle();#endif				break;			}			default:				break;		}				BASE::OnNCMouseMove(e);	}		void Form::OnNCMouseDown(_P<MouseEventArgs> e)	{		switch (this->ncState = this->NCHitTest(e->X, e->Y))		{			case NCState_CloseButton:				this->set_Capture(true);				this->isCloseButtonPushed = true;				this->Refresh();				break;			case NCState_TitleBar:			{				this->set_Capture(true);				this->ptRevRect = Point(e->X, e->Y);#ifdef MONA				MessageInfo msg;				MonAPI::Message::sendReceive(&msg, __gui_server, MSG_GUISERVER_CREATEOVERLAP,					this->get_X(), this->get_Y(),					MAKE_DWORD(this->get_Width(), this->get_Height()));				this->overlap = msg.arg2;#else				this->DrawReversibleRectangle();#endif				break;			}			default:				break;		}				BASE::OnNCMouseDown(e);	}		void Form::OnNCMouseUp(_P<MouseEventArgs> e)	{		bool destroy = this->NCHitTest(e->X, e->Y) == NCState_CloseButton && this->ncState == NCState_CloseButton;				switch (this->ncState)		{			case NCState_CloseButton:			{				this->set_Capture(false);				this->isCloseButtonPushed = false;				break;			}			case NCState_TitleBar:			{#ifdef MONA				MonAPI::Message::sendReceive(NULL, __gui_server, MSG_GUISERVER_DISPOSEOVERLAP, this->overlap);				this->overlap = 0;#else				this->DrawReversibleRectangle();#endif				this->set_Capture(false);				Point p = this->get_Location();				p.X += e->X - this->clickPoint.X;				p.Y += e->Y - this->clickPoint.Y;				this->set_Location(p);				break;			}			default:				this->Refresh();				break;		}				BASE::OnNCMouseUp(e);				this->ncState = NCState_None;		if (destroy) this->Dispose();	}		void Form::OnActivated(_P<EventArgs> e)	{		this->raise_Activated(this, e);	}		void Form::OnDeactivate(_P<EventArgs> e)	{		this->raise_Deactivate(this, e);	}}}}

⌨️ 快捷键说明

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