代码拉取完成,页面将自动刷新
#pragma once
#include "ControlBase.h"
#include "Controls.h"
#include "helper.h"
#include <unordered_map>
static std::unordered_map<HWND, class Form *> ProgramForms = std::unordered_map<HWND, class Form *>();
static LRESULT CALLBACK ___MSG_Proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
class Form : public Control
{
public:
virtual UIClass Type() { return UIClass::UI_Form; }
HMENU Menu = NULL;
Form *Parent = NULL;
UINT Closed = WM_NULL;
DWORD Style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
READONLY_PROPERTY(SIZE, ClientSize);
GET(SIZE, ClientSize)
{
RECT crec = {};
GetClientRect(this->Handle, &crec);
return {crec.right - crec.left, crec.bottom - crec.top};
}
Form(std::wstring _text = L"NativeWindow", POINT _location = {0, 0}, SIZE _size = {600, 400})
{
this->Location = _location;
this->Size = _size;
static int classIndex = 0;
WNDCLASSW wndclass = {0};
auto wclass = FormatW(L"NativeWindow_%d", classIndex++);
{
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.lpfnWndProc = ___MSG_Proc;
wndclass.hInstance = GetModuleHandleA(NULL);
wndclass.hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(32512));
wndclass.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512));
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = wclass;
}
if (!RegisterClass(&wndclass))
{
return;
}
this->Handle = CreateWindowW(wclass,
_text.c_str(),
this->Style,
this->Location.x == 0 ? CW_USEDEFAULT : this->Location.x,
this->Location.y == 0 ? CW_USEDEFAULT : this->Location.y,
this->Size.cx == 0 ? CW_USEDEFAULT : this->Size.cx,
this->Size.cy == 0 ? CW_USEDEFAULT : this->Size.cy,
this->Parent ? this->Parent->Handle : NULL,
this->Menu,
GetModuleHandle(NULL),
NULL);
Render = new D2DGraphics(this->Handle);
ProgramForms[this->Handle] = this;
this->MostParent = this;
DragAcceptFiles(this->Handle, TRUE);
}
~Form()
{
delete Render;
DestroyWindow(this->Handle);
}
void Show()
{
if (this->Menu)
SetMenu(this->Handle, this->Menu);
SetWindowLong(this->Handle, GWL_STYLE, this->Style);
ShowWindow(this->Handle, SW_SHOWNORMAL);
}
void Hide()
{
ShowWindow(this->Handle, SW_HIDE);
}
static bool DoEvent()
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
return true;
}
Sleep(1);
return false;
}
static void DoFoceEvent()
{
MSG msg;
if (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
}
void Update() override
{
this->Render->BeginRender(this->BackColor);
if (this->Image)
{
this->RenderImage();
}
for (int i = 0; i < this->Count; i++)
{
auto c = this->operator[](i);
if (!c->Visable)
continue;
auto location = c->Location;
if (c->Render == NULL)
{
c->Render = this->Render;
}
c->Update();
}
for (auto fc : this->ForeGroundControls)
{
fc->Update();
}
this->Render->EndRender();
}
bool ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam, int xof, int yof) override
{
POINT mouse;
GetCursorPos(&mouse);
ScreenToClient(this->Handle, &mouse);
Control *HitControl = NULL;
switch (message)
{
case WM_MOUSEMOVE: // mouse move
{
if (GetKeyState(VK_LBUTTON) & 0x8000 && this->Selected)
{
if (this->Selected->IsVisual)
{
HitControl = this->Selected;
auto location = this->Selected->AbsLocation;
this->Selected->ProcessMessage(message, wParam, lParam, mouse.x - location.x, mouse.y - location.y);
break;
}
}
auto lastUnderMouse = this->UnderMouse;
this->UnderMouse = NULL;
bool is_First = true;
reExc:
for (int i = 0; i < this->Count; i++)
{
auto c = this->operator[](i);
if (!c->Visable)
continue;
auto location = c->Location;
auto size = c->ActualSize();
if (
mouse.x >= location.x &&
mouse.y >= location.y &&
mouse.x <= (location.x + size.cx) &&
mouse.y <= (location.y + size.cy))
{
if (is_First)
{
if (c->Type() == UIClass::UI_ComboBox)
{
HitControl = c;
this->UnderMouse = c;
c->ProcessMessage(message, wParam, lParam, mouse.x - location.x, mouse.y - location.y);
goto ext;
}
}
else
{
HitControl = c;
this->UnderMouse = c;
c->ProcessMessage(message, wParam, lParam, mouse.x - location.x, mouse.y - location.y);
}
}
}
if (is_First)
{
is_First = false;
goto reExc;
}
ext:
if (lastUnderMouse != this->UnderMouse)
{
if (this->UnderMouse)
this->UnderMouse->SingleUpdate();
// if (lastUnderMouse)
// lastUnderMouse->SingleUpdate();
}
}
break;
case WM_DROPFILES:
case WM_MOUSEWHEEL: // mouse wheel
case WM_LBUTTONDOWN: // mouse down
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_LBUTTONUP: // mouse up
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_LBUTTONDBLCLK: // mouse double click
{
if (WM_LBUTTONUP == message && this->Selected)
{
if (this->Selected->IsVisual)
{
HitControl = this->Selected;
auto location = this->Selected->AbsLocation;
this->Selected->ProcessMessage(message, wParam, lParam, mouse.x - location.x, mouse.y - location.y);
break;
}
}
bool is_First = true;
reExc1:
for (int i = 0; i < this->Count; i++)
{
auto c = this->operator[](i);
if (!c->Visable)
continue;
auto location = c->Location;
auto size = c->ActualSize();
if (
mouse.x >= location.x &&
mouse.y >= location.y &&
mouse.x <= (location.x + size.cx) &&
mouse.y <= (location.y + size.cy))
{
if (is_First)
{
if (c->Type() == UIClass::UI_ComboBox)
{
HitControl = c;
c->ProcessMessage(message, wParam, lParam, mouse.x - location.x, mouse.y - location.y);
goto ext1;
}
}
else
{
HitControl = c;
c->ProcessMessage(message, wParam, lParam, mouse.x - location.x, mouse.y - location.y);
}
}
}
if (is_First)
{
is_First = false;
goto reExc1;
}
ext1:;
}
break;
case WM_KEYDOWN: // keyboard down
{
if (this->Selected)
{
if (this->Selected->ProcessMessage(message, wParam, lParam, xof, yof))
{
if (this->Selected->IsVisual)
{
HitControl = this->Selected;
KeyEventArgs event_obj = KeyEventArgs((Keys)(wParam | 0));
this->OnKeyDown(this, event_obj);
}
}
}
else
{
KeyEventArgs event_obj = KeyEventArgs((Keys)(wParam | 0));
this->OnKeyDown(this, event_obj);
}
}
break;
case WM_KEYUP: // keyboard up
{
if (this->Selected)
{
if (this->Selected->ProcessMessage(message, wParam, lParam, xof, yof))
{
HitControl = this->Selected;
KeyEventArgs event_obj = KeyEventArgs((Keys)(wParam | 0));
this->OnKeyUp(this, event_obj);
}
}
else
{
KeyEventArgs event_obj = KeyEventArgs((Keys)(wParam | 0));
this->OnKeyUp(this, event_obj);
}
}
break;
case WM_SIZE:
{
RECT rec;
GetClientRect(this->Handle, &rec);
this->Size = SIZE{rec.right - rec.left, rec.bottom - rec.top};
this->SizeChanged(this);
this->Render->Resize();
this->Update();
}
break;
case WM_MOVE:
{
RECT client_rectangle;
GetClientRect(this->Handle, &client_rectangle);
this->Location = POINT{client_rectangle.left, client_rectangle.top};
this->Moved(this);
this->Update();
if (this->Parent)
this->Parent->Update();
}
break;
case WM_PAINT:
{
this->OnPaint(this);
this->Update();
}
break;
case WM_CHAR:
{
if (this->Selected)
{
if (this->Selected->ProcessMessage(message, wParam, lParam, xof, yof))
{
HitControl = this->Selected;
this->OnCharInput(this, (wchar_t)(wParam));
}
}
else
{
HitControl = this;
this->OnCharInput(this, (wchar_t)(wParam));
}
}
break;
case WM_IME_COMPOSITION: // input app action
{
if (this->Selected)
{
HitControl = this->Selected;
this->Selected->ProcessMessage(message, wParam, lParam, xof, yof);
}
}
break;
case WM_CLOSE:
{
ProgramForms.erase(this->Handle);
if (this->Parent)
{
this->Parent->RemoveControl(this);
}
Closed = WM_CLOSE;
delete this;
}
break;
};
if (WM_LBUTTONDOWN == message && HitControl == NULL && this->Selected && HitControl != this->Selected)
{
auto se = this->Selected;
this->Selected = NULL;
se->SingleUpdate();
}
return true;
}
Control *AddControl(Control *c)
{
if (c->Type() == UIClass::UI_Form)
{
((Form *)c)->Parent = this;
}
return Control::AddControl(c);
}
bool WaitForAllObjects()
{
return ((Closed & WM_CLOSE) == WM_CLOSE);
}
};
LRESULT CALLBACK ___MSG_Proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
auto window = ProgramForms[hWnd];
if (window)
{
window->ProcessMessage(message, wParam, lParam, 0, 0);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。