241 lines
5.8 KiB
C++
Raw Normal View History

2024-07-21 19:28:47 +08:00
#include "window.h"
#include "controls.h"
#include "Lang/Lang.h"
#include <shellapi.h>
HICON GetExeIcon(const std::wstring &filePath)
{
2024-02-11 23:49:11 +08:00
SHFILEINFO fileInfo;
HICON hIcon = NULL;
2024-07-21 19:28:47 +08:00
if (SHGetFileInfo(filePath.c_str(), 0, &fileInfo, sizeof(fileInfo), SHGFI_ICON | SHGFI_LARGEICON))
{
2024-02-11 23:49:11 +08:00
hIcon = fileInfo.hIcon;
}
return hIcon;
}
2024-07-21 19:28:47 +08:00
void mainwindow::visfont()
{
if (hfont == 0)
hfont = parent->hfont;
if (hfont)
{
for (auto ctr : controls)
{
2024-04-25 15:44:28 +08:00
SendMessage(ctr->winId, WM_SETFONT, (LPARAM)hfont, TRUE);
}
}
}
2024-07-21 19:28:47 +08:00
void mainwindow::setfont(const Font &font)
{
hfont = font.hfont();
2024-02-09 09:25:26 +08:00
SendMessage(winId, WM_SETFONT, (WPARAM)hfont, TRUE);
2024-04-25 15:44:28 +08:00
visfont();
2024-07-21 19:28:47 +08:00
for (auto child : childrens)
{
child->setfont(font);
2024-04-25 15:44:28 +08:00
}
2024-02-07 20:59:24 +08:00
}
2024-07-21 19:28:47 +08:00
std::wstring basewindow::text()
{
2024-02-07 20:59:24 +08:00
int textLength = GetWindowTextLength(winId);
std::vector<wchar_t> buffer(textLength + 1);
GetWindowText(winId, buffer.data(), buffer.size());
return buffer.data();
}
2024-07-21 19:28:47 +08:00
void basewindow::settext(const std::wstring &text)
{
SetWindowText(winId, text.c_str());
2024-02-07 20:59:24 +08:00
}
2024-07-21 19:28:47 +08:00
void basewindow::setgeo(int x, int y, int w, int h)
{
MoveWindow(winId, x, y, w, h, TRUE);
on_size(w, h);
2024-02-07 20:59:24 +08:00
}
2024-07-21 19:28:47 +08:00
RECT basewindow::getgeo()
{
2024-02-07 20:59:24 +08:00
RECT rect;
2024-07-21 19:28:47 +08:00
GetWindowRect(winId, &rect);
2024-02-07 20:59:24 +08:00
return rect;
}
2024-07-21 19:28:47 +08:00
LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam)
{
2024-02-07 20:59:24 +08:00
switch (message)
{
2024-07-21 19:28:47 +08:00
case WM_SHOWWINDOW:
{
on_show();
visfont();
break;
}
case WM_SIZE:
{
int width = LOWORD(lParam);
int height = HIWORD(lParam);
on_size(width, height);
break;
}
case WM_NOTIFY:
{
NMHDR *pnmhdr = (NMHDR *)lParam;
for (auto ctl : controls)
2024-02-07 20:59:24 +08:00
{
2024-07-21 19:28:47 +08:00
if (pnmhdr->hwndFrom == ctl->winId)
{
ctl->dispatch_2(wParam, lParam);
break;
}
2024-02-07 20:59:24 +08:00
}
2024-07-21 19:28:47 +08:00
}
case WM_COMMAND:
{
if (lParam == 0)
2024-02-11 23:49:11 +08:00
{
2024-07-21 19:28:47 +08:00
for (auto ctl : controls)
2024-02-11 23:49:11 +08:00
{
2024-07-21 19:28:47 +08:00
if (lastcontexthwnd == ctl->winId)
2024-02-11 23:49:11 +08:00
{
2024-07-21 19:28:47 +08:00
if (ctl->menu)
ctl->menu.value().dispatch(wParam);
break;
2024-02-11 23:49:11 +08:00
}
}
}
2024-07-21 19:28:47 +08:00
else
for (auto ctl : controls)
{
if ((HWND)lParam == ctl->winId)
{
ctl->dispatch(wParam);
break;
2024-02-07 20:59:24 +08:00
}
}
2024-07-21 19:28:47 +08:00
break;
}
case WM_CONTEXTMENU:
{
bool succ = false;
lastcontexthwnd = 0;
for (auto ctl : controls)
2024-02-07 20:59:24 +08:00
{
2024-07-21 19:28:47 +08:00
if ((HWND)wParam == ctl->winId)
{
auto hm = ctl->on_menu();
ctl->menu = hm;
if (hm)
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TrackPopupMenu(hm.value().load(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
xPos, yPos, 0, winId, NULL);
lastcontexthwnd = ctl->winId;
succ = true;
2024-02-07 20:59:24 +08:00
}
2024-07-21 19:28:47 +08:00
break;
2024-02-07 20:59:24 +08:00
}
}
2024-07-21 19:28:47 +08:00
if (succ == false)
2024-02-07 20:59:24 +08:00
return DefWindowProc(winId, message, wParam, lParam);
2024-07-21 19:28:47 +08:00
break;
}
case WM_CLOSE:
{
on_close();
if (parent == 0)
PostQuitMessage(0);
else
ShowWindow(winId, SW_HIDE);
break;
2024-02-07 20:59:24 +08:00
}
2024-07-21 19:28:47 +08:00
default:
return DefWindowProc(winId, message, wParam, lParam);
}
2024-02-07 20:59:24 +08:00
return 0;
}
2024-07-21 19:28:47 +08:00
std::pair<int, int> mainwindow::calculateXY(int w, int h)
{
int cx, cy;
if (parent == 0)
{
2024-02-09 09:25:26 +08:00
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
cx = screenWidth / 2;
cy = screenHeight / 2;
}
2024-07-21 19:28:47 +08:00
else
{
auto rect = parent->getgeo();
cx = (rect.left + rect.right) / 2;
cy = (rect.top + rect.bottom) / 2;
2024-02-09 09:25:26 +08:00
}
2024-07-21 19:28:47 +08:00
return {cx - w / 2, cy - h / 2};
2024-02-09 09:25:26 +08:00
}
2024-07-21 19:28:47 +08:00
void mainwindow::setcentral(int w, int h)
{
auto [x, y] = calculateXY(w, h);
setgeo(x, y, w, h);
2024-02-09 09:25:26 +08:00
}
2024-07-21 19:28:47 +08:00
void mainwindow::setlayout(control *_l)
{
layout = _l;
2024-03-28 11:01:44 +08:00
}
2024-07-21 19:28:47 +08:00
mainwindow::mainwindow(mainwindow *_parent)
{
layout = 0;
const wchar_t CLASS_NAME[] = L"LunaHostWindow";
2024-02-07 20:59:24 +08:00
WNDCLASS wc = {};
wc.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
2024-07-21 19:28:47 +08:00
mainwindow *_window = reinterpret_cast<mainwindow *>(GetWindowLongPtrW(hWnd, GWLP_USERDATA));
if ((!_window) || (_window->winId != hWnd))
return DefWindowProc(hWnd, message, wParam, lParam);
return _window->wndproc(message, wParam, lParam);
2024-02-07 20:59:24 +08:00
};
wc.hInstance = GetModuleHandle(0);
wc.lpszClassName = CLASS_NAME;
2024-07-21 19:28:47 +08:00
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.hIcon = GetExeIcon(getModuleFilename().value()); // LoadIconW(GetModuleHandle(0),L"IDI_ICON1");
static auto _ = RegisterClass(&wc);
2024-02-07 20:59:24 +08:00
HWND hWnd = CreateWindowEx(
2024-07-21 19:28:47 +08:00
WS_EX_CLIENTEDGE, CLASS_NAME, CLASS_NAME, WS_OVERLAPPEDWINDOW,
2024-02-07 20:59:24 +08:00
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2024-07-21 19:28:47 +08:00
_parent ? _parent->winId : NULL, NULL, GetModuleHandle(0), this);
2024-02-07 20:59:24 +08:00
winId = hWnd;
2024-07-21 19:28:47 +08:00
parent = _parent;
if (parent)
2024-04-25 15:44:28 +08:00
parent->childrens.push_back(this);
2024-02-07 20:59:24 +08:00
SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this);
}
2024-07-21 19:28:47 +08:00
void mainwindow::show()
{
2024-02-07 20:59:24 +08:00
ShowWindow(winId, SW_SHOW);
SetForegroundWindow(winId);
}
2024-07-21 19:28:47 +08:00
void mainwindow::close()
{
2024-02-07 20:59:24 +08:00
ShowWindow(winId, SW_HIDE);
}
2024-07-21 19:28:47 +08:00
void mainwindow::run()
{
2024-02-07 20:59:24 +08:00
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
2024-07-21 19:28:47 +08:00
void mainwindow::on_close() {}
void mainwindow::on_show() {}
void mainwindow::on_size(int w, int h)
{
if (layout)
2024-03-28 11:01:44 +08:00
{
2024-07-21 19:28:47 +08:00
layout->setgeo(0, 0, w, h);
2024-03-28 11:01:44 +08:00
}
}
2024-07-21 19:28:47 +08:00
void basewindow::on_size(int w, int h) {}