📄 ui.cpp
字号:
/***********************************************************************
Copyright 2002 Ben Rudiak-Gould.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA,
or visit <http://www.gnu.org/copyleft/gpl.html>.
***********************************************************************/
#define WIN32_LEAN_AND_MEAN
#define _WIN32_IE 0x400
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "ui.h"
#include <stdio.h>
void NestableWindow::GetClientSize(int* width, int* height) {
RECT r;
if (hwnd && ::GetClientRect(hwnd, &r)) {
*width = r.right-r.left;
*height = r.bottom-r.top;
} else {
*width = *height = 0;
}
}
LONG APIENTRY NestableWindow::StaticWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (message == WM_CREATE) {
LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam;
NestableWindow* self = (NestableWindow*)cs->lpCreateParams;
self->hwnd = hwnd;
SetWindowLong(hwnd, GWL_USERDATA, (LONG)self);
return self->OnCreate(cs);
} else {
NestableWindow* self = (NestableWindow*)GetWindowLong(hwnd, GWL_USERDATA);
if (!self) return DefWindowProc(hwnd, message, wParam, lParam);
switch (message) {
case WM_COMMAND:
if (lParam) {
int code = HIWORD(wParam);
HWND hwnd_control = (HWND)lParam;
NestableWindow* owner = (NestableWindow*)GetDlgCtrlID(hwnd_control);
if (!owner)
owner = (NestableWindow*)GetDlgCtrlID(GetParent(hwnd_control));
if (owner && owner->OnControlCommand(code)) return 0;
} else {
if (self->OnMenuCommand(LOWORD(wParam), HIWORD(wParam) & 1)) return 0;
}
break;
case WM_CONTEXTMENU:
{
NestableWindow* owner = (NestableWindow*)GetDlgCtrlID((HWND)wParam);
if ((void*)owner >= (void*)GetModuleHandle(0)) {
owner->OnContextMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
}
}
break;
case WM_CLOSE:
if (self->OnClose()) return 0; else break;
case WM_SIZE:
if (self->OnSize(LOWORD(lParam),HIWORD(lParam))) return 0; else break;
case WM_ACTIVATE:
if (self->OnActivate(LOWORD(wParam), !!HIWORD(wParam), HWND(lParam))) return 0; else break;
case WM_SETFOCUS:
if (self->OnSetFocus()) return 0; else break;
case WM_DESTROY:
self->hwnd = 0;
if (self->OnDestroy()) return 0; else break;
case WM_NOTIFY:
{
LPNMHDR nmhdr = (LPNMHDR)lParam;
NestableWindow* owner = (NestableWindow*)wParam;
if (!owner)
owner = (NestableWindow*)GetDlgCtrlID(GetParent(nmhdr->hwndFrom));
if (owner && owner->OnNotify(nmhdr)) return 0;
break;
}
case WM_MEASUREITEM:
if (((NestableWindow*)wParam)->OnMeasureItem((LPMEASUREITEMSTRUCT) lParam)) return 0; else break;
case WM_DRAWITEM:
if (((NestableWindow*)wParam)->OnDrawItem((LPDRAWITEMSTRUCT) lParam)) return 0; else break;
}
return self->WndProc(hwnd, message, wParam, lParam);
}
}
bool NestableWindow::OnNotify(LPNMHDR pnmhdr) {
if (pnmhdr->code == NM_DBLCLK || pnmhdr->code == NM_RETURN)
return OnDoubleClickOrEnterKey(pnmhdr);
else
return false;
}
void FrameWindow::SetChild(NestableWindow* new_child) {
NestableWindow* old_child = child;
child = new_child;
Resize();
if (new_child) new_child->Show();
if (old_child && old_child != new_child) old_child->Hide();
}
void FrameWindow::Resize() {
int width, height;
GetClientSize(&width, &height);
OnSize(width, height);
}
bool FrameWindow::OnSize(int width, int height) {
if (child) ::MoveWindow(child->GetHwnd(), 0, 0, width, height, TRUE);
return true;
}
bool FrameWindow::OnActivate(int activation_code, bool minimized, HWND other_window) {
if (activation_code == WA_ACTIVE) {
if (hwndSavedFocus) {
::SetFocus(hwndSavedFocus);
return true;
}
} else if (activation_code == WA_INACTIVE)
hwndSavedFocus = ::GetFocus();
return false;
}
FrameWindow::FrameWindow(const char name[], HMENU hmenu) {
child = 0;
hwndSavedFocus = NULL;
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_DBLCLKS /*| CS_NOCLOSE*/;
wcx.lpfnWndProc = StaticWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = GetModuleHandle(0);
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor(NULL, IDC_SIZEWE);
wcx.hbrBackground = GetStockBrush(NULL_BRUSH);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = "FrameWnd";
wcx.hIconSm = NULL;
RegisterClassEx(&wcx); // will fail if registered already
hwnd = 0;
::CreateWindow(
"FrameWnd", // class name
name, // window name
WS_OVERLAPPEDWINDOW, // style
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // coords
NULL, // parent
hmenu, // menu
GetModuleHandle(0), // hinstance
this); // lParam
// If window could not be created, return "failure"
if (!hwnd)
return;
// Make the window visible; update its client area; and return "success"
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
}
SplitterWndH::SplitterWndH(NestableWindow* parent)
: splitter_width(GetSystemMetrics(SM_CXSIZEFRAME))
{
Create(parent);
left = right = 0;
splitter_pos = 100;
resizing = -1;
}
void SplitterWndH::Create(NestableWindow* parent) {
int width, height;
parent->GetClientSize(&width, &height);
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_DBLCLKS /*| CS_NOCLOSE*/;
wcx.lpfnWndProc = StaticWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = GetModuleHandle(0);
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor(NULL, IDC_SIZEWE);
wcx.hbrBackground = HBRUSH(COLOR_3DFACE+1);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = "SplitterWnd";
wcx.hIconSm = NULL;
RegisterClassEx(&wcx); // will fail if registered already
hwnd = 0;
::CreateWindow(
"SplitterWnd", // class name
"", // window name
WS_CHILD | WS_CLIPCHILDREN, // style
0, 0, 0, 0, // coords
parent->GetHwnd(), // parent
NULL, // menu
GetModuleHandle(0), // hinstance
this); // lParam
// If window could not be created, return "failure"
if (!hwnd)
return;
// Make the window visible; update its client area; and return "success"
ShowWindow(hwnd, SW_SHOW);
}
void SplitterWndH::Resize() {
int width, height;
GetClientSize(&width, &height);
OnSize(width, height);
}
void SplitterWndH::SetLeft(NestableWindow* new_left) {
NestableWindow* old_left = left;
left = new_left;
Resize();
if (new_left) new_left->Show();
if (old_left && old_left != new_left) old_left->Hide();
}
void SplitterWndH::SetRight(NestableWindow* new_right) {
NestableWindow* old_right = right;
right = new_right;
Resize();
if (new_right) new_right->Show();
if (old_right && old_right != new_right) old_right->Hide();
}
LONG SplitterWndH::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -