#include "stdafx.h"
#include "TWidget.h"
#include <afxwin.h>
#include "./MsgFunManage/MsgFunManage.h"
using namespace std;
namespace TUi
{
// 简单的测试了下
TWidget::TWidget(TWidget *hParent, TWidgetStdModel *Model)
{
wnd_This = 0;
m_hWnd = 0;
b_IsQuit = FALSE;
h_BkBrush = 0;
color_Background = RGB(255, 255, 255);
m_msgFunManage = new MsgFunManage;
map_SignalFuns.clear();
// 初始化窗口对象
if (InitWdiget(
hParent ? hParent->m_hWnd : 0, // 若为空,则传入0
Model ? Model : &TWidgetStdModel() // 若为空,就传入一个临时对象指针
))
{
hParent->list_ChildObject.push_back(this); // 加入父窗口的Child队列,由父窗口负责销毁子窗口
}
}
TWidget::TWidget(HWND hParent, TWidgetStdModel *Model)
{
wnd_This = 0;
m_hWnd = 0;
b_IsQuit = FALSE;
h_BkBrush = 0;
color_Background = RGB(255, 255, 255);
map_SignalFuns.clear();
m_msgFunManage = new MsgFunManage;
// 初始化窗口对象
InitWdiget(hParent,
Model ? Model : &TWidgetStdModel()); // 若为空,就传入一个临时对象指针
}
BOOL TWidget::InitWdiget(HWND hParent, TWidgetStdModel *Model)
{
if (hParent == NULL) // 创建顶级窗口
{
Model->AutoAdjustWndRect(FALSE);
Model->SetWndStyle(WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN);
Model->InitTopWidgetStyle();
// 注册并创建窗口
Create(hParent, Model);
return FALSE;
}
else // 创建子窗口
{
// 初始化子窗口风格和Names
Model->SetNames(TEXT("TChildWidget_1"));
Model->SetWndStyle(WS_VISIBLE | WS_CLIPSIBLINGS | WS_CHILDWINDOW);
Model->InitChildWidgetStyle();
Model->AutoAdjustWndRect(TRUE);
// 注册并创建窗口
Create(hParent, Model);
}
return TRUE;
}
BOOL TWidget::Create(HWND hParent, TWidgetStdModel *Model)
{
WNDCLASSEX wndcls;
HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(NULL, GWL_HINSTANCE);
// 注册窗口类
if (!(::GetClassInfoEx(hInst, Model->str_ClassName.c_str(), &wndcls))) // 是否被注册
{
memset(&wndcls, 0, sizeof(WNDCLASSEXA));
wndcls.hInstance = hInst;
wndcls.lpfnWndProc = TWidget::WindowProc;
if (Model->color_Background == RGB(255, 255, 255))
wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
else
{
color_Background = Model->color_Background;
h_BkBrush = CreateSolidBrush(color_Background);
wndcls.hbrBackground = h_BkBrush;
}
Model->SetWndClassEx(&wndcls);
// 注册窗口类,注册失败则循环注册
if (!RegisterClassEx(&wndcls))
{
Model->SetClassName(Model->AutoAdjustName(Model->str_ClassName));
if (!Model->str_ClassName.size())
return FALSE;
return Create(hParent, Model);
}
}
RECT rcWin = Model->rc_Win;
// 创建窗口
HWND hWin = ::CreateWindowEx(Model->dw_WndExStyle, Model->str_ClassName.c_str(),
Model->str_WndName.c_str(), Model->dw_WndStyle,
rcWin.left, rcWin.top, rcWin.right - rcWin.left, rcWin.bottom - rcWin.top,
hParent, Model->h_Menu, hInst, this);
if (hWin == NULL)
{
assert(0);
return FALSE;
}
wnd_This = CWnd::FromHandle(m_hWnd);
::ShowWindow(m_hWnd, SW_SHOW);
RECT rcClient;
GetClientRect(m_hWnd, &rcClient);
InvalidateRect(m_hWnd, &rcClient, TRUE);
return TRUE;
}
TWidget::~TWidget()
{
// delete 子控件对象
int iSize = list_ChildObject.size();
if (iSize)
{
for (int i = 0; i < iSize; ++i)
{
delete list_ChildObject[i];
}
}
if (h_BkBrush != 0)
{
DeleteObject(h_BkBrush);
}
delete m_msgFunManage;
wnd_This = 0;
m_hWnd = 0;
h_BkBrush = 0;
list_ChildObject.clear();
map_SignalFuns.clear();
}
void TWidget::DoModel(HWND hParent)
{
// 递归寻找主窗口
if (GetParent(hParent))
{
hParent = GetParent(hParent);
DoModel(hParent);
}
// 使窗口失效
if (::IsWindow(hParent))
{
::EnableWindow(hParent, FALSE);
}
// 不能是子窗口
if (::GetWindowLongPtr(m_hWnd,GWL_STYLE) & WS_CHILD)
{
assert(0);
}
MSG msg;
while (!this->b_IsQuit)
{
::GetMessage(&msg, NULL, 0, 0);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
// 恢复窗口
if (::IsWindow(hParent))
{
::EnableWindow(hParent, TRUE);
if (!::IsWindowVisible(hParent))
::ShowWindow(hParent,SW_SHOW);
::SetForegroundWindow(hParent);
}
}
void TWidget::Update()
{
RECT rcArea;
::GetClientRect(m_hWnd, &rcArea);
::InvalidateRect(m_hWnd, &rcArea, TRUE);
}
void TWidget::Update(const RECT* rcArea)
{
::InvalidateRect(m_hWnd, rcArea, TRUE);
}
void TWidget::Repaint()
{
RECT rcArea;
::GetClientRect(m_hWnd, &rcArea);
::InvalidateRect(m_hWnd, &rcArea, TRUE);
::UpdateWindow(m_hWnd);
}
void TWidget::Repaint(const RECT *rcArea)
{
::InvalidateRect(m_hWnd, rcArea, TRUE);
::UpdateWindow(m_hWnd);
}
void TWidget::AddMsgFun(UINT Msg, MsgFun msgFun)
{
m_msgFunManage->AddMsgFun(Msg, msgFun);
}
void TWidget::AdjustWidgetRect(float scaleWidth, float scaleHeight)
{
RECT rcWin;
::GetWindowRect(m_hWnd, &rcWin);
int iWidth = rcWin.right - rcWin.left;
int iHeight = rcWin.bottom - rcWin.top;
int iHOffset = (int)((iWidth * scaleWidth - iWidth) / 2);
int iVOffset = (int)((iHeight * scaleHeight - iHeight) / 2);
rcWin.left -= iHOffset;
rcWin.right += iHOffset;
rcWin.top -= iVOffset;
rcWin.bottom += iVOffset;
this->SetWindowRect(rcWin);
}
// void TWidget::ConnectSlot(int iSignal, const TWidget *pThis, SlotFun slotFun)
// {
// CallFun callFun = { (TWidget*)pThis, slotFun };
// map_SignalFuns.insert(MapSignalFun::value_type(iSignal, callFun));
// }
void TWidget::SetWindowRect(const RECT &rcWin)
{
::MoveWindow(m_hWnd, rcWin.left, rcWin.top,
rcWin.right - rcWin.left, rcWin.bottom - rcWin.top, TRUE);
}
void TWidget::SetWidgetTransparent(BYTE Alpha)
{
DWORD dwWndExStyle = GetWindowLongPtr(this->m_hWnd, GWL_EXSTYLE);
if (!(dwWndExStyle & WS_EX_LAYERED))
{
::SetWindowLongPtr(this->m_hWnd, GWL_EXSTYLE, dwWndExStyle | WS_EX_LAYERED);
}
::SetLayeredWindowAttributes(m_hWnd, color_Background, Alpha, LWA_ALPHA | LWA_COLORKEY);
}
void TWidget::SetBkTransparent()
{
DWORD dwWndExStyle = GetWindowLongPtr(this->m_hWnd, GWL_EXSTYLE);
if (!(dwWndExStyle & WS_EX_LAYERED))
{
::SetWindowLongPtr(this->m_hWnd, GWL_EXSTYLE, dwWndExStyle | WS_EX_LAYERED);
}
if (color_Background == RGB(255,255,255))
{
#ifdef _DEBUG
MessageBox(NULL, TEXT("Model Not Set SetBkTransparent() Function! The Transparent Color Is Not White!"), NULL, MB_OK);
#endif
assert(0);
}
::SetLayeredWindowAttributes(m_hWnd, color_Background, 0, LWA_COLORKEY);
}
void TWidget::SetWindowStyle(DWORD dwWndStyle)
{
::SetWindowLongPtr(m_hWnd, GWL_STYLE, dwWndStyle);
}
void TWidget::QuitWidget(BOOL bQuit)
{
b_IsQuit = bQuit;
}
void TWidget::SetThisPointer(HWND hWnd, LPARAM lParam)
{
this->m_hWnd = hWnd;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)this);
}
LRESULT TWidget::WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_PAINT:
{
TWidget *pThis = (TWidget*)::GetWindowLongPtr(hWnd, GWL_USERDATA);
pThis->OnPaint(WidParam(Msg, wParam, lParam));
}
break;
default:
{
TWidget *pThis = (TWidget*)::GetWindowLongPtr(hWnd, GWL_USERDATA);
if (!pThis)
break;
return pThis->WinProc(Msg, wParam, lParam);
}
case WM_COMMAND:
{
TWidget *pThis = (TWidget*)::GetWindowLongPtr(hWnd, GWL_USERDATA);
if (pThis)
pThis->OnCommand(WidParam(Msg, wParam, lParam));
}
break;
case WM_CREATE:
case WM_NCCREATE: // 在这个消息获取 类的 this 指针
{
TWidget *pThis = (TWidget*)::GetWindowLongPtr(hWnd, GWL_USERDATA);
if (pThis == 0)
{
// 得到CreateStruct->lpCreateParams = this 指针
LPCREATESTRUCT lcs = (LPCREATESTRUC