open source
This commit is contained in:
@@ -0,0 +1,416 @@
|
||||
#include "WinEditBox.h"
|
||||
#include "../../source/conch/WindowsEnv/winWindows.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
extern HWND g_hWnd;
|
||||
|
||||
static HMENU IDL_EditBox = (HMENU) 100;
|
||||
|
||||
static void CheckError()
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error)
|
||||
{
|
||||
LOGE("[Error][Edit] Error no: %d", error);
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK EditWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
laya::WinEditBox* editBox = (laya::WinEditBox*) GetWindowLong(hWnd, GWL_USERDATA);
|
||||
if (!editBox)
|
||||
return true;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
//case WM_SETFOCUS:
|
||||
//{
|
||||
// laya::WinControl* winCtrl = laya::WinCtrlEvtManager::Get(hWnd);
|
||||
// if (winCtrl)
|
||||
// {
|
||||
// winCtrl->OnSetFocus();
|
||||
// }
|
||||
// break;
|
||||
//}
|
||||
//case WM_KILLFOCUS:
|
||||
//{
|
||||
// DestroyCaret();
|
||||
// break;
|
||||
//}
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
SendMessage(g_hWnd, message, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
|
||||
bool ret = editBox->OnNCCalcSize(wParam, lParam);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
return CallWindowProc(editBox->GetDefaultWndProc(), hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NCPAINT:
|
||||
{
|
||||
bool ret = editBox->OnNCPaint(wParam, lParam);
|
||||
if (!ret)
|
||||
{
|
||||
return CallWindowProc(editBox->GetDefaultWndProc(), hWnd, message, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
editBox->OnPaint();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return CallWindowProc(editBox->GetDefaultWndProc(), hWnd, message, wParam, lParam);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace laya {
|
||||
|
||||
/// style
|
||||
void WinEditBox::Style::SetLeft(int val)
|
||||
{
|
||||
left = val;
|
||||
UpdateSizeOrDirty();
|
||||
}
|
||||
|
||||
void WinEditBox::Style::SetTop(int val)
|
||||
{
|
||||
top = val;
|
||||
UpdateSizeOrDirty();
|
||||
}
|
||||
|
||||
void WinEditBox::Style::SetWidth(int val)
|
||||
{
|
||||
width = val;
|
||||
UpdateSizeOrDirty();
|
||||
}
|
||||
|
||||
void WinEditBox::Style::SetHeight(int val)
|
||||
{
|
||||
height = val;
|
||||
UpdateSizeOrDirty();
|
||||
}
|
||||
|
||||
void WinEditBox::Style::SetFontSize(int val)
|
||||
{
|
||||
fontSize = val + 2;
|
||||
if (m_owner->IsFocus())
|
||||
{
|
||||
m_owner->UpdateFont();
|
||||
m_owner->ForceUpdateWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WinEditBox::Style::SetBgColor(COLORREF val)
|
||||
{
|
||||
bgColor = val;
|
||||
UpdatePaintOrDirty();
|
||||
}
|
||||
|
||||
void WinEditBox::Style::SetFontColor(COLORREF val)
|
||||
{
|
||||
fontColor = val;
|
||||
UpdatePaintOrDirty();
|
||||
}
|
||||
|
||||
void WinEditBox::Style::UpdatePaintOrDirty()
|
||||
{
|
||||
if (m_owner->IsFocus())
|
||||
{
|
||||
m_owner->ForceUpdateWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WinEditBox::Style::UpdateSizeOrDirty()
|
||||
{
|
||||
if (m_owner->IsFocus())
|
||||
{
|
||||
m_owner->UpdateSize();
|
||||
m_owner->ForceUpdateWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// WinEditBox
|
||||
|
||||
WinEditBox::WinEditBox() :
|
||||
m_hSingleEditWnd(0),
|
||||
m_hMultiEditWnd(0),
|
||||
m_isFocus(false),
|
||||
m_isMultiLine(false),
|
||||
m_isInitialized(false),
|
||||
m_refCount(0),
|
||||
m_defaultWndProc(NULL)
|
||||
{
|
||||
m_style = new Style(this);
|
||||
m_font = CreateFont(m_style->fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("Arial"));
|
||||
|
||||
// Send Message for creating
|
||||
SendMessage(g_hWnd, WMU_CREATE_CTRL, NULL, (LPARAM)this);
|
||||
}
|
||||
|
||||
WinEditBox::~WinEditBox()
|
||||
{
|
||||
WinCtrlEvtManager::Remove(m_hSingleEditWnd);
|
||||
WinCtrlEvtManager::Remove(m_hMultiEditWnd);
|
||||
|
||||
SetWindowLong(m_hSingleEditWnd, GWL_USERDATA, (LONG)0);
|
||||
SetWindowLong(m_hMultiEditWnd, GWL_USERDATA, (LONG)0);
|
||||
|
||||
delete m_style;
|
||||
m_style = nullptr;
|
||||
|
||||
DestroyWindow(m_hSingleEditWnd);
|
||||
DestroyWindow(m_hMultiEditWnd);
|
||||
}
|
||||
|
||||
void WinEditBox::Init()
|
||||
{
|
||||
if (!m_isInitialized)
|
||||
{
|
||||
m_isInitialized = true;
|
||||
m_hSingleEditWnd = CreateWindow(WC_EDIT, TEXT(""), WS_CHILD | ES_AUTOHSCROLL, m_style->left, m_style->top, m_style->width, m_style->height, g_hWnd, IDL_EditBox, (HINSTANCE)GetWindowLong(g_hWnd, GWL_HINSTANCE), NULL);
|
||||
|
||||
m_hMultiEditWnd = CreateWindow(WC_EDIT, TEXT(""), WS_CHILD | ES_MULTILINE | ES_WANTRETURN, m_style->left, m_style->top, m_style->width, m_style->height, g_hWnd, IDL_EditBox, (HINSTANCE)GetWindowLong(g_hWnd, GWL_HINSTANCE), NULL);
|
||||
|
||||
|
||||
CheckError();
|
||||
if (m_isMultiLine)
|
||||
{
|
||||
m_defaultWndProc = (WNDPROC)SetWindowLong(m_hMultiEditWnd, GWL_WNDPROC, (LONG)EditWndProc);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_defaultWndProc = (WNDPROC)SetWindowLong(m_hSingleEditWnd, GWL_WNDPROC, (LONG)EditWndProc);
|
||||
}
|
||||
|
||||
SetWindowLong(m_hSingleEditWnd, GWL_USERDATA, (LONG)this);
|
||||
SetWindowLong(m_hMultiEditWnd, GWL_USERDATA, (LONG)this);
|
||||
|
||||
WinCtrlEvtManager::Add(m_hSingleEditWnd, this);
|
||||
WinCtrlEvtManager::Add(m_hMultiEditWnd, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WinEditBox::UpdateSize()
|
||||
{
|
||||
::SetWindowPos(GetCurHWND(), NULL, m_style->left, m_style->top, m_style->width, m_style->height, NULL);
|
||||
}
|
||||
|
||||
void WinEditBox::UpdateFont()
|
||||
{
|
||||
m_font = CreateFont(m_style->fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("Arial"));
|
||||
|
||||
SendMessage(GetCurHWND(), WM_SETFONT, (WPARAM)m_font, true);
|
||||
}
|
||||
|
||||
void WinEditBox::SetFocus(bool isFocus)
|
||||
{
|
||||
if (m_isFocus == isFocus)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_isFocus = isFocus;
|
||||
if (!GetCurHWND())
|
||||
m_isFocus = false;
|
||||
|
||||
|
||||
if (m_style->isDirty)
|
||||
{
|
||||
UpdateSize();
|
||||
UpdateFont();
|
||||
m_style->isDirty = false;
|
||||
}
|
||||
|
||||
if (m_isFocus)
|
||||
{
|
||||
SetText(m_text.c_str());
|
||||
}
|
||||
|
||||
if (m_isFocus)
|
||||
{
|
||||
::SetFocus(GetCurHWND());
|
||||
ShowWindow(GetCurHWND(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
::SetFocus(NULL);
|
||||
ShowWindow(GetCurHWND(), SW_HIDE);
|
||||
}
|
||||
|
||||
ForceUpdateWindow();
|
||||
}
|
||||
|
||||
void WinEditBox::SetMutiLine(bool val)
|
||||
{
|
||||
if (m_isMultiLine == val)
|
||||
return;
|
||||
|
||||
SetWindowLong(GetCurHWND(), GWL_WNDPROC, (LONG)m_defaultWndProc);
|
||||
m_isMultiLine = val;
|
||||
|
||||
m_defaultWndProc = (WNDPROC) SetWindowLong(GetCurHWND(), GWL_WNDPROC, (LONG)EditWndProc);
|
||||
|
||||
if (m_isFocus)
|
||||
{
|
||||
ShowWindow(m_hSingleEditWnd, !m_isMultiLine);
|
||||
ShowWindow(m_hMultiEditWnd, m_isMultiLine);
|
||||
}
|
||||
|
||||
ForceUpdateWindow();
|
||||
}
|
||||
|
||||
void WinEditBox::ForceUpdateWindow()
|
||||
{
|
||||
RECT r;
|
||||
GetClientRect(GetCurHWND(), &r);
|
||||
InvalidateRect(GetCurHWND(), &r, true);
|
||||
::UpdateWindow(GetCurHWND());
|
||||
}
|
||||
|
||||
void WinEditBox::RenderClient()
|
||||
{
|
||||
PAINTSTRUCT paint;
|
||||
HDC hdc = BeginPaint(GetCurHWND(), &paint);
|
||||
SetBkColor(hdc, m_style->bgColor);
|
||||
SetTextColor(hdc, m_style->fontColor);
|
||||
SelectObject(hdc, m_font);
|
||||
|
||||
FillRect(hdc, &m_ncRect, CreateSolidBrush(m_style->bgColor));
|
||||
DrawText(hdc, m_text.c_str(), -1, &m_ncRect, DT_LEFT | DT_TOP);
|
||||
|
||||
EndPaint(GetCurHWND(), &paint);
|
||||
}
|
||||
|
||||
void WinEditBox::GetTextFromWindow()
|
||||
{
|
||||
int length = GetWindowTextLength(GetCurHWND());
|
||||
m_text.resize(length + 1);
|
||||
GetWindowText(GetCurHWND(), &(*m_text.begin()), length + 1);
|
||||
}
|
||||
|
||||
const char* WinEditBox::GetText()
|
||||
{
|
||||
if (m_isFocus)
|
||||
{
|
||||
GetTextFromWindow();
|
||||
}
|
||||
|
||||
return m_text.c_str();
|
||||
}
|
||||
|
||||
void WinEditBox::SetText(const char* text)
|
||||
{
|
||||
m_text = text;
|
||||
SetWindowText(GetCurHWND(), m_text.c_str());
|
||||
|
||||
if (m_isFocus)
|
||||
{
|
||||
ForceUpdateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void WinEditBox::OnPaint()
|
||||
{
|
||||
GetClientRect(GetCurHWND(), &m_ncRect);
|
||||
RenderClient();
|
||||
}
|
||||
|
||||
void WinEditBox::OnCtrlColor(HDC hdc)
|
||||
{
|
||||
if (!m_isMultiLine)
|
||||
{
|
||||
SetWindowPos(GetCurHWND(), NULL, 0, 0, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
}
|
||||
|
||||
SetBkColor(hdc, m_style->bgColor);
|
||||
SetTextColor(hdc, m_style->fontColor);
|
||||
}
|
||||
|
||||
bool WinEditBox::OnNCCalcSize(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (m_isMultiLine)
|
||||
return false;
|
||||
|
||||
bool isValid = (bool)wParam;
|
||||
if (isValid)
|
||||
{
|
||||
RECT r;
|
||||
GetClientRect(GetCurHWND(), &r);
|
||||
|
||||
LPNCCALCSIZE_PARAMS lpParams = (LPNCCALCSIZE_PARAMS)lParam;
|
||||
lpParams->rgrc[0].top += (r.bottom - r.top) / 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinEditBox::OnNCPaint(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (m_isMultiLine)
|
||||
return false;
|
||||
|
||||
RenderClient();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WinEditBox::OnSetFocus()
|
||||
{
|
||||
//PAINTSTRUCT paint;
|
||||
//RECT r;
|
||||
//CopyRect(&r, &m_ncRect);
|
||||
////HideCaret(m_hWnd);
|
||||
|
||||
//HDC hdc = BeginPaint(GetCurHWND(), &paint);
|
||||
//DrawText(hdc, m_text.c_str(), -1, &r, DT_LEFT | DT_TOP | DT_CALCRECT);
|
||||
//EndPaint(GetCurHWND(), &paint);
|
||||
|
||||
//HideCaret(GetCurHWND());
|
||||
//CreateCaret(GetCurHWND(), NULL, 1, m_style->fontSize);
|
||||
//SetCaretPos(r.right, r.top);
|
||||
//ShowCaret(GetCurHWND());
|
||||
}
|
||||
|
||||
void WinEditBox::Retain()
|
||||
{
|
||||
m_refCount++;
|
||||
}
|
||||
|
||||
bool WinEditBox::Release()
|
||||
{
|
||||
m_refCount--;
|
||||
if (m_refCount <= 0)
|
||||
{
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <CommCtrl.h>
|
||||
#include "../../source/conch/WindowsEnv/WinCtrl.h"
|
||||
#include <string>
|
||||
|
||||
namespace laya {
|
||||
|
||||
class WinEditBox final : public WinControl{
|
||||
public:
|
||||
class Style {
|
||||
public:
|
||||
Style(WinEditBox* owner) : m_owner(owner)
|
||||
{
|
||||
bgColor = 0xffffff;
|
||||
fontColor = 0x0;
|
||||
left = -1000;
|
||||
top = -1000;
|
||||
width = 0;
|
||||
height = 0;
|
||||
fontSize = 10;
|
||||
|
||||
isDirty = false;
|
||||
}
|
||||
|
||||
void SetLeft(int val);
|
||||
void SetTop(int val);
|
||||
void SetWidth(int val);
|
||||
void SetHeight(int val);
|
||||
void SetFontSize(int val);
|
||||
void SetBgColor(COLORREF val);
|
||||
void SetFontColor(COLORREF val);
|
||||
|
||||
|
||||
private:
|
||||
void UpdatePaintOrDirty();
|
||||
void UpdateSizeOrDirty();
|
||||
|
||||
private:
|
||||
friend class WinEditBox;
|
||||
|
||||
COLORREF bgColor;
|
||||
COLORREF fontColor;
|
||||
int left;
|
||||
int top;
|
||||
int width;
|
||||
int height;
|
||||
int fontSize;
|
||||
|
||||
bool isDirty;
|
||||
|
||||
WinEditBox* m_owner;
|
||||
};
|
||||
|
||||
public:
|
||||
WinEditBox();
|
||||
virtual void Init() override;
|
||||
virtual ControlType GetType() override { return CT_Edit; }
|
||||
|
||||
WNDPROC GetDefaultWndProc() const { return m_defaultWndProc; }
|
||||
|
||||
Style& GetStyle() { return *m_style; }
|
||||
|
||||
bool IsFocus() const { return m_isFocus; }
|
||||
void SetFocus(bool isFocus);
|
||||
|
||||
void SetText(const char* text);
|
||||
const char* GetText();
|
||||
|
||||
void SetMutiLine(bool val);
|
||||
|
||||
void ForceUpdateWindow();
|
||||
|
||||
|
||||
// event
|
||||
virtual void OnPaint() override;
|
||||
virtual void OnCtrlColor(HDC hdc) override;
|
||||
virtual void OnSetFocus() override;
|
||||
|
||||
bool OnNCCalcSize(WPARAM wParam, LPARAM lParam);
|
||||
bool OnNCPaint(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// ref count
|
||||
void Retain();
|
||||
bool Release();
|
||||
|
||||
private:
|
||||
void UpdateSize();
|
||||
void UpdateFont();
|
||||
void RenderClient();
|
||||
void GetTextFromWindow();
|
||||
|
||||
HWND GetCurHWND() { return m_isMultiLine ? m_hMultiEditWnd : m_hSingleEditWnd;
|
||||
}
|
||||
|
||||
private:
|
||||
WinEditBox(const WinEditBox& other) = delete;
|
||||
void operator=(const WinEditBox& other) = delete;
|
||||
~WinEditBox();
|
||||
|
||||
private:
|
||||
bool m_isInitialized;
|
||||
|
||||
bool m_isFocus;
|
||||
std::string m_text;
|
||||
|
||||
bool m_isMultiLine;
|
||||
|
||||
Style* m_style;
|
||||
HWND m_hSingleEditWnd;
|
||||
HWND m_hMultiEditWnd;
|
||||
HFONT m_font;
|
||||
|
||||
WNDPROC m_defaultWndProc;
|
||||
|
||||
RECT m_ncRect;
|
||||
|
||||
int m_refCount;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user