代码拉取完成,页面将自动刷新
#pragma once
#include <d2d1.h>
#include <shellapi.h>
#include "Events.h"
#include "List.h"
#include "D2d/Colors.h"
#include "D2d/D2DGraphics.h"
#pragma comment(lib, "Imm32.lib")
enum class ImageSizeMode : char
{
ImageSizeMode_Normal,
ImageSizeMode_CenterImage,
ImageSizeMode_StretchIamge,
ImageSizeMode_Zoom
};
enum class UIClass : int
{
UI_Base,
UI_Form,
UI_Label,
UI_Button,
UI_PictureBox,
UI_TextBox,
UI_RichTextBox,
UI_PasswordBox,
UI_ComboBox,
UI_GridView,
UI_CheckBox,
UI_RadioBox,
UI_ProgressBar,
UI_TreeView,
UI_Panel,
UI_TabPage,
UI_TabControl,
UI_Switch
};
class Control
{
private:
POINT _location = {0, 0};
SIZE _size = {120, 20};
bool _visible = true;
D2D1_COLOR_F _backcolor = Colors::gray91;
D2D1_COLOR_F _forecolor = Colors::Black;
D2D1_COLOR_F _boldercolor = Colors::Black;
ID2D1Bitmap *_image = NULL;
std::wstring _text;
List<Control *> Children;
public:
HWND Handle = NULL;
Control *MostParent = NULL;
Control *UnderMouse = NULL;
Control *Selected = NULL;
D2DGraphics *Render;
virtual UIClass Type() { return UIClass::UI_Base; }
D2dFont *Font = NULL;
bool Enable = true;
bool Checked = false;
ImageSizeMode SizeMode;
Control *Parent = NULL;
OnPaintEvent OnPaint;
MouseWheelEvent OnMouseWheel;
MouseMoveEvent OnMouseMove;
MouseUpEvent OnMouseUp;
MouseDownEvent OnMouseDown;
MouseDoubleEvent OnMouseDoubleClick;
MouseClickEvent OnMouseClick;
KeyUpEvent OnKeyUp;
KeyDownEvent OnKeyDown;
OnCloseEvent OnClose;
SizeChangedEvent SizeChanged;
MovedEvent Moved;
OnCharInputEvent OnCharInput;
OnCheckedEvent OnChecked;
TextChangedEvent TextChanged;
DropFileEvent OnDropFile;
__int64 Tag = NULL;
List<Control *> ForeGroundControls;
Control()
: Enable(true),
_visible(true),
Checked(false),
Parent(nullptr),
Font(nullptr),
Tag(NULL),
SizeMode(ImageSizeMode::ImageSizeMode_Zoom),
MostParent(NULL),
_image(NULL),
_text(L"")
{
}
~Control()
{
if (this->Font)
{
delete this->Font;
}
for (auto c : this->Children)
{
delete c;
}
}
virtual bool IsContainer() { return false; }
virtual void Update() {}
virtual void SingleUpdate()
{
if (this->IsVisual == false)
return;
this->Render->BeginRender();
this->Update();
for (auto fc : this->MostParent->ForeGroundControls)
{
fc->Update();
}
this->Render->EndRender();
}
READONLY_PROPERTY(int, Count);
GET(int, Count)
{
return this->Children.Count;
}
Control *operator[](int index)
{
return this->Children[index];
}
Control *get(int index)
{
return this->Children[index];
}
Control *AddControl(Control *c)
{
if (c->Parent)
{
throw "This control already belongs to another container!";
return NULL;
}
if (this->Children.Contains(c))
{
return c;
}
this->Children.Add(c);
c->Parent = this;
c->MostParent = this->MostParent;
c->Render = this->Render;
return c;
}
D2D1_POINT_2F LastChildLR()
{
if (this->Children.Count)
{
auto last = this->Children.Last();
auto loc = last->Location;
auto siz = last->ActualSize();
return D2D1_POINT_2F{(float)loc.x + siz.cy, (float)loc.y + siz.cy};
}
return {0, 0};
}
D2D1_POINT_2F MaxChildLR()
{
D2D1_POINT_2F result = {0, 0};
if (this->Children.Count)
{
for (auto c : this->Children)
{
auto last = this->Children.Last();
auto loc = last->Location;
auto siz = last->ActualSize();
auto tmp = D2D1_POINT_2F{(float)loc.x + siz.cy, (float)loc.y + siz.cy};
if (tmp.x > result.x)
result.x = tmp.x;
if (tmp.y > result.y)
result.y = tmp.y;
}
}
return result;
}
void RemoveControl(Control *c)
{
this->Children.Remove(c);
c->Parent = NULL;
c->MostParent = NULL;
c->Render = NULL;
}
READONLY_PROPERTY(POINT, AbsLocation);
GET(POINT, AbsLocation)
{
Control *tmpc = this;
POINT tmpl = {0, 0};
if (tmpc->Type() == UIClass::UI_Form)
return tmpl;
while (true)
{
auto loc = tmpc->Location;
tmpl.x += loc.x;
tmpl.y += loc.y;
tmpc = tmpc->Parent;
if (tmpc->Type() == UIClass::UI_Form)
{
break;
}
}
return tmpl;
}
PROPERTY(D2D1_RECT_F, AbsRect);
GET(D2D1_RECT_F, AbsRect)
{
Control *tmpc = this;
auto absMin = this->AbsLocation;
auto absMax = POINT{absMin.x + this->ActualSize().cx, absMin.y + this->ActualSize().cy};
if (tmpc->Type() == UIClass::UI_Form)
return D2D1_RECT_F{(float)absMin.x, (float)absMin.y, (float)absMax.x, (float)absMax.y};
while (true)
{
auto _absMin = tmpc->AbsLocation;
auto _absMax = POINT{_absMin.x + tmpc->ActualSize().cx, _absMin.y + tmpc->ActualSize().cy};
auto rec = D2D1_RECT_F{(float)_absMin.x, (float)_absMin.y, (float)_absMax.x, (float)_absMax.y};
if (rec.left > absMin.x)
absMin.x = rec.left;
if (rec.top > absMin.y)
absMin.y = rec.top;
if (rec.right < absMax.x)
absMax.x = rec.right;
if (rec.bottom < absMax.y)
absMax.y = rec.bottom;
tmpc = tmpc->Parent;
if (tmpc->Type() == UIClass::UI_Form)
{
break;
}
}
return D2D1_RECT_F{(float)absMin.x, (float)absMin.y, (float)absMax.x, (float)absMax.y};
}
PROPERTY(bool, IsVisual);
GET(bool, IsVisual)
{
if (this->Visable == false)
return false;
Control *tmpc = this;
while (true)
{
if (tmpc->Visable == false)
return false;
tmpc = tmpc->Parent;
if (tmpc->Type() == UIClass::UI_Form)
{
break;
}
}
return true;
}
PROPERTY(bool, Visable);
GET(bool, Visable)
{
return _visible;
}
SET(bool, Visable)
{
if (_visible != value)
{
_visible = value;
if (this->Type() != UIClass::UI_Form && this->Parent && this->Parent->IsVisual == false)
return;
if (this->MostParent)
this->MostParent->Update();
}
}
PROPERTY(POINT, Location);
GET(POINT, Location)
{
return _location;
}
SET(POINT, Location)
{
this->Moved(this);
_location = value;
}
PROPERTY(SIZE, Size);
GET(SIZE, Size)
{
return _size;
}
SET(SIZE, Size)
{
this->SizeChanged(this);
_size = value;
}
READONLY_PROPERTY(float, Right);
GET(float, Right)
{
return this->Left + this->Width;
}
READONLY_PROPERTY(float, Bottom);
GET(float, Bottom)
{
return this->Top + this->Height;
}
PROPERTY(std::wstring, Text);
GET(std::wstring, Text)
{
return _text;
}
SET(std::wstring, Text)
{
if (value != _text)
this->TextChanged(this, _text, value);
_text = value;
}
PROPERTY(ID2D1Bitmap *, Image);
GET(ID2D1Bitmap *, Image)
{
return _image;
}
SET(ID2D1Bitmap *, Image)
{
_image = value;
}
PROPERTY(D2D1_COLOR_F, BolderColor);
GET(D2D1_COLOR_F, BolderColor)
{
return _boldercolor;
}
SET(D2D1_COLOR_F, BolderColor)
{
_boldercolor = value;
}
PROPERTY(D2D1_COLOR_F, BackColor);
GET(D2D1_COLOR_F, BackColor)
{
return _backcolor;
}
SET(D2D1_COLOR_F, BackColor)
{
_backcolor = value;
}
PROPERTY(D2D1_COLOR_F, ForeColor);
GET(D2D1_COLOR_F, ForeColor)
{
return _forecolor;
}
SET(D2D1_COLOR_F, ForeColor)
{
_forecolor = value;
}
PROPERTY(int, Left);
GET(int, Left)
{
return this->Location.x;
}
SET(int, Left)
{
this->_location = POINT{value, this->_location.y};
}
PROPERTY(int, Top);
GET(int, Top)
{
return this->Location.y;
}
SET(int, Top)
{
this->_location = POINT{this->_location.x, value};
}
PROPERTY(int, Width);
GET(int, Width)
{
return this->_size.cx;
}
SET(int, Width)
{
this->SizeChanged(this);
this->_size.cx = value;
}
PROPERTY(int, Height);
GET(int, Height)
{
return this->_size.cy;
}
SET(int, Height)
{
this->SizeChanged(this);
_size.cy = value;
}
virtual void RenderImage()
{
if (this->_image)
{
auto absLocation = this->AbsLocation;
auto size = this->_image->GetSize();
if (size.width > 0 && size.height > 0)
{
auto asize = this->ActualSize();
switch (this->SizeMode)
{
case ImageSizeMode::ImageSizeMode_Normal:
{
this->Render->DrawBitmap(this->_image, absLocation.x, absLocation.y, size.width, size.height);
}
break;
case ImageSizeMode::ImageSizeMode_CenterImage:
{
float xf = (asize.cx - size.width) / 2.0f;
float yf = (asize.cy - size.height) / 2.0f;
this->Render->DrawBitmap(this->_image, absLocation.x + xf, absLocation.y + yf, size.width, size.height);
}
break;
case ImageSizeMode::ImageSizeMode_StretchIamge:
{
this->Render->DrawBitmap(this->_image, absLocation.x, absLocation.y, asize.cx, asize.cy);
}
break;
case ImageSizeMode::ImageSizeMode_Zoom:
{
float xp = asize.cx / size.width;
float yp = asize.cy / size.height;
float tp = xp < yp ? xp : yp;
float tw = size.width * tp;
float th = size.height * tp;
float xf = (asize.cx - tw) / 2.0f;
float yf = (asize.cy - th) / 2.0f;
this->Render->DrawBitmap(this->_image, absLocation.x + xf, absLocation.y + yf, tw, th);
}
break;
default:
break;
}
}
}
}
virtual SIZE ActualSize()
{
return this->Size;
}
virtual bool ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam, int xof, int yof)
{
if (WM_LBUTTONDOWN == message)
{
if (this->MostParent->Selected && this->MostParent->Selected != this)
{
auto se = this->MostParent->Selected;
this->MostParent->Selected = this;
se->SingleUpdate();
}
}
switch (message)
{
case WM_DROPFILES:
{
HDROP hDropInfo = HDROP(wParam);
UINT uFileNum = DragQueryFile(hDropInfo, 0xffffffff, NULL, 0);
TCHAR strFileName[MAX_PATH];
List<std::wstring> files;
for (int i = 0; i < uFileNum; i++)
{
DragQueryFile(hDropInfo, i, strFileName, MAX_PATH);
files.Add(strFileName);
}
DragFinish(hDropInfo);
if (files.Count > 0)
{
this->OnDropFile(this, files);
}
}
break;
case WM_MOUSEWHEEL: // mouse wheel
{
MouseEventArgs event_obj = MouseEventArgs(MouseButtons::MouseButtons_None, 0, xof, yof, GET_WHEEL_DELTA_WPARAM(wParam));
this->OnMouseWheel(this, event_obj);
}
break;
case WM_MOUSEMOVE: // mouse move
{
MouseEventArgs event_obj = MouseEventArgs(MouseButtons::MouseButtons_None, 0, xof, yof, HIWORD(wParam));
this->OnMouseMove(this, event_obj);
}
break;
case WM_LBUTTONDOWN: // mouse down
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
{
if (WM_LBUTTONDOWN == message)
{
this->MostParent->Selected = this;
}
MouseEventArgs event_obj = MouseEventArgs(FromParamToMouseButtons(message), 0, xof, yof, HIWORD(wParam));
this->OnMouseDown(this, event_obj);
this->Update();
}
break;
case WM_LBUTTONUP: // mouse up
case WM_RBUTTONUP:
case WM_MBUTTONUP:
{
MouseEventArgs event_obj = MouseEventArgs(FromParamToMouseButtons(message), 0, xof, yof, HIWORD(wParam));
this->OnMouseUp(this, event_obj);
this->Update();
}
break;
case WM_LBUTTONDBLCLK: // mouse double click
{
MouseEventArgs event_obj = MouseEventArgs(FromParamToMouseButtons(message), 0, xof, yof, HIWORD(wParam));
this->OnMouseDoubleClick(this, event_obj);
}
break;
case WM_KEYDOWN: // keyboard down
{
KeyEventArgs event_obj = KeyEventArgs((Keys)(wParam | 0));
this->OnKeyDown(this, event_obj);
}
break;
case WM_KEYUP: // keyboard up
{
KeyEventArgs event_obj = KeyEventArgs((Keys)(wParam | 0));
this->OnKeyUp(this, event_obj);
}
break;
}
return true;
}
};
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。