📄 form.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 + -