Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
621
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/flexwnd.cpp
Normal file
621
Library/dxx8/samples/Multimedia/DirectInput/DIConfig/flexwnd.cpp
Normal file
@@ -0,0 +1,621 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: flexwnd.cpp
|
||||
//
|
||||
// Desc: CFlexWnd is a generic class that encapsulates the functionalities
|
||||
// of a window. All other window classes are derived from CFlexWnd.
|
||||
//
|
||||
// Child classes can have different behavior by overriding the
|
||||
// overridable message handlers (OnXXX members).
|
||||
//
|
||||
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "common.hpp"
|
||||
#include "typeinfo.h"
|
||||
|
||||
BOOL CFlexWnd::sm_bWndClassRegistered = FALSE;
|
||||
WNDCLASSEX CFlexWnd::sm_WndClass;
|
||||
LPCTSTR CFlexWnd::sm_tszWndClassName = _T("Microsoft.CFlexWnd.WndClassName");
|
||||
HINSTANCE CFlexWnd::sm_hInstance = NULL;
|
||||
CFlexToolTip CFlexWnd::s_ToolTip; // Shared tooltip window object
|
||||
DWORD CFlexWnd::s_dwLastMouseMove; // Last GetTickCount() that we have a WM_MOUSEMOVE
|
||||
HWND CFlexWnd::s_hWndLastMouseMove; // Last window handle of WM_MOUSEMOVE
|
||||
LPARAM CFlexWnd::s_PointLastMouseMove; // Last point of WM_MOUSEMOVE
|
||||
HWND CFlexWnd::s_CurrPageHwnd; // For unhighlighting callouts when a click is made outside of a callout
|
||||
|
||||
|
||||
int NewID()
|
||||
{
|
||||
static int i = 0;
|
||||
return ++i;
|
||||
}
|
||||
|
||||
CFlexWnd::CFlexWnd() : m_nID(NewID()),
|
||||
m_hWnd(m_privhWnd), m_privhWnd(NULL), m_hRenderInto(NULL),
|
||||
m_bIsDialog(FALSE), m_bRender(FALSE),
|
||||
m_bReadOnly(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
CFlexWnd::~CFlexWnd()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CFlexWnd::Destroy()
|
||||
{
|
||||
if (m_hWnd != NULL)
|
||||
DestroyWindow(m_hWnd);
|
||||
|
||||
assert(m_privhWnd == NULL);
|
||||
}
|
||||
|
||||
BOOL CFlexWnd::IsDialog()
|
||||
{
|
||||
return HasWnd() && m_bIsDialog;
|
||||
}
|
||||
|
||||
void CFlexWnd::OnRender(BOOL bInternalCall)
|
||||
{
|
||||
// if parent is flexwnd and both are in render mode, pass to parent
|
||||
if (!m_hWnd)
|
||||
return;
|
||||
HWND hParent = GetParent(m_hWnd);
|
||||
if (!hParent)
|
||||
return;
|
||||
CFlexWnd *pParent = GetFlexWnd(hParent);
|
||||
if (!pParent)
|
||||
return;
|
||||
if (pParent->InRenderMode() && InRenderMode())
|
||||
pParent->OnRender(TRUE);
|
||||
}
|
||||
|
||||
BOOL CFlexWnd::OnEraseBkgnd(HDC hDC)
|
||||
{
|
||||
if (InRenderMode())
|
||||
return TRUE;
|
||||
|
||||
/* if (IsDialog())
|
||||
return FALSE;*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct GETFLEXWNDSTRUCT {
|
||||
int cbSize;
|
||||
BOOL bFlexWnd;
|
||||
CFlexWnd *pFlexWnd;
|
||||
};
|
||||
|
||||
// This function takes a HWND and returns a pointer to CFlexWnd if the HWND is a window
|
||||
// created by the UI.
|
||||
CFlexWnd *CFlexWnd::GetFlexWnd(HWND hWnd)
|
||||
{
|
||||
if (hWnd == NULL)
|
||||
return NULL;
|
||||
|
||||
GETFLEXWNDSTRUCT gfws;
|
||||
gfws.cbSize = sizeof(gfws);
|
||||
gfws.bFlexWnd = FALSE;
|
||||
gfws.pFlexWnd = NULL;
|
||||
SendMessage(hWnd, WM_GETFLEXWND, 0, (LPARAM)(LPVOID)(FAR GETFLEXWNDSTRUCT *)&gfws);
|
||||
|
||||
if (gfws.bFlexWnd)
|
||||
return gfws.pFlexWnd;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Basic window proc. It simply forward interesting messages to the appropriate handlers (OnXXX).
|
||||
// If child class defines this function, it should pass unhandled messages to CFlexWnd.
|
||||
LRESULT CFlexWnd::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_GETFLEXWND:
|
||||
{
|
||||
if ((LPVOID)lParam == NULL)
|
||||
break;
|
||||
|
||||
GETFLEXWNDSTRUCT &gfws = *((FAR GETFLEXWNDSTRUCT *)(LPVOID)lParam);
|
||||
|
||||
switch (gfws.cbSize)
|
||||
{
|
||||
case sizeof(GETFLEXWNDSTRUCT):
|
||||
gfws.bFlexWnd = TRUE;
|
||||
gfws.pFlexWnd = this;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT lpCreateStruct = (LPCREATESTRUCT)lParam;
|
||||
|
||||
LRESULT lr = OnCreate(lpCreateStruct);
|
||||
|
||||
if (lr != -1)
|
||||
OnInit();
|
||||
|
||||
return lr;
|
||||
}
|
||||
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
BOOL b = OnInitDialog();
|
||||
OnInit();
|
||||
return b;
|
||||
}
|
||||
|
||||
case WM_TIMER:
|
||||
OnTimer((UINT)wParam);
|
||||
return 0;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
return OnEraseBkgnd((HDC)wParam);
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
// Check the update rectangle. If we don't have it, exit immediately.
|
||||
if (typeid(*this) == typeid(CDeviceView) && !GetUpdateRect(m_hWnd, NULL, FALSE))
|
||||
return 0;
|
||||
PAINTSTRUCT ps;
|
||||
HDC hDC = BeginPaint(hWnd, &ps);
|
||||
if (InRenderMode())
|
||||
OnRender(TRUE);
|
||||
else
|
||||
DoOnPaint(hDC);
|
||||
EndPaint(hWnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
{
|
||||
WORD wNotifyCode = HIWORD(wParam);
|
||||
WORD wID = LOWORD(wParam);
|
||||
HWND hWnd = (HWND)lParam;
|
||||
return OnCommand(wNotifyCode, wID, hWnd);
|
||||
}
|
||||
|
||||
case WM_NOTIFY:
|
||||
return OnNotify(wParam, lParam);
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
POINT point = {int(LOWORD(lParam)), int(HIWORD(lParam))};
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE: OnMouseOver(point, wParam); break;
|
||||
case WM_LBUTTONDOWN: OnClick(point, wParam, TRUE); break;
|
||||
case WM_RBUTTONDOWN: OnClick(point, wParam, FALSE); break;
|
||||
case WM_LBUTTONDBLCLK: OnDoubleClick(point, wParam, TRUE); break;
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
// Send wheel msg to the window beneath the cursor
|
||||
HWND hWnd = WindowFromPoint(point);
|
||||
CFlexWnd *pWnd = NULL;
|
||||
if (hWnd)
|
||||
{
|
||||
pWnd = GetFlexWnd(hWnd);
|
||||
if (pWnd)
|
||||
pWnd->OnWheel(point, wParam);
|
||||
else
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
OnDestroy();
|
||||
m_privhWnd = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_bIsDialog)
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
static HMENU windex = 0;
|
||||
|
||||
BOOL CFlexWnd::EndDialog(int n)
|
||||
{
|
||||
if (!m_bIsDialog || m_hWnd == NULL)
|
||||
{
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ::EndDialog(m_hWnd, n);
|
||||
}
|
||||
|
||||
int CFlexWnd::DoModal(HWND hParent, int nTemplate, HINSTANCE hInst)
|
||||
{
|
||||
return DoModal(hParent, MAKEINTRESOURCE(nTemplate), hInst);
|
||||
}
|
||||
|
||||
HWND CFlexWnd::DoModeless(HWND hParent, int nTemplate, HINSTANCE hInst)
|
||||
{
|
||||
return DoModeless(hParent, MAKEINTRESOURCE(nTemplate), hInst);
|
||||
}
|
||||
|
||||
int CFlexWnd::DoModal(HWND hParent, LPCTSTR lpTemplate, HINSTANCE hInst)
|
||||
{
|
||||
if (m_hWnd != NULL)
|
||||
{
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hInst == NULL)
|
||||
hInst = CFlexWnd::sm_hInstance;
|
||||
|
||||
return (int)DialogBoxParam(hInst, lpTemplate, hParent,
|
||||
(DLGPROC)__BaseFlexWndDialogProc, (LPARAM)(void *)this);
|
||||
}
|
||||
|
||||
HWND CFlexWnd::DoModeless(HWND hParent, LPCTSTR lpTemplate, HINSTANCE hInst)
|
||||
{
|
||||
if (m_hWnd != NULL)
|
||||
{
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hInst == NULL)
|
||||
hInst = CFlexWnd::sm_hInstance;
|
||||
|
||||
return CreateDialogParam(hInst, lpTemplate, hParent,
|
||||
(DLGPROC)__BaseFlexWndDialogProc, (LPARAM)(void *)this);
|
||||
}
|
||||
|
||||
HWND CFlexWnd::Create(HWND hParent, const RECT &rect, BOOL bVisible)
|
||||
{
|
||||
++(*(LPBYTE*)&windex);
|
||||
return Create(hParent, _T("(unnamed)"), 0,
|
||||
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_EX_NOPARENTNOTIFY | (bVisible ? WS_VISIBLE : 0),
|
||||
rect, windex);
|
||||
}
|
||||
|
||||
HWND CFlexWnd::Create(HWND hParent, LPCTSTR tszName, DWORD dwExStyle, DWORD dwStyle, const RECT &rect, HMENU hMenu)
|
||||
{
|
||||
HWND hWnd = NULL;
|
||||
|
||||
if (m_hWnd != NULL)
|
||||
{
|
||||
assert(0);
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
if (hMenu == NULL && (dwStyle & WS_CHILD))
|
||||
{
|
||||
++(*(LPBYTE*)&windex);
|
||||
hMenu = windex;
|
||||
}
|
||||
|
||||
hWnd = CreateWindowEx(
|
||||
dwExStyle,
|
||||
CFlexWnd::sm_tszWndClassName,
|
||||
tszName,
|
||||
dwStyle,
|
||||
rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
hParent,
|
||||
hMenu,
|
||||
CFlexWnd::sm_hInstance,
|
||||
(void *)this);
|
||||
|
||||
assert(m_hWnd == hWnd);
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
void CFlexWnd::SetHWND(HWND hWnd)
|
||||
{
|
||||
assert(m_hWnd == NULL && hWnd != NULL);
|
||||
m_privhWnd = hWnd;
|
||||
assert(m_hWnd == m_privhWnd);
|
||||
|
||||
InitFlexWnd();
|
||||
}
|
||||
|
||||
void CFlexWnd::InitFlexWnd()
|
||||
{
|
||||
if (!HasWnd())
|
||||
return;
|
||||
|
||||
HWND hParent = GetParent(m_hWnd);
|
||||
CFlexWnd *pParent = GetFlexWnd(hParent);
|
||||
if (pParent && pParent->InRenderMode())
|
||||
SetRenderMode();
|
||||
}
|
||||
|
||||
TCHAR sg_tszFlexWndPointerProp[] = _T("CFlexWnd *");
|
||||
|
||||
LRESULT CALLBACK __BaseFlexWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
CFlexWnd *pThis = (CFlexWnd *)GetProp(hWnd, sg_tszFlexWndPointerProp);
|
||||
|
||||
if ((msg == WM_MOUSEMOVE || msg == WM_MOUSEWHEEL) && hWnd != CFlexWnd::s_ToolTip.m_hWnd)
|
||||
{
|
||||
// Filter out the message with same window handle and point.
|
||||
// Windows sometimes seems to send us WM_MOUSEMOVE message even though the mouse is not moved.
|
||||
if (CFlexWnd::s_hWndLastMouseMove != hWnd || CFlexWnd::s_PointLastMouseMove != lParam)
|
||||
{
|
||||
CFlexWnd::s_hWndLastMouseMove = hWnd;
|
||||
CFlexWnd::s_PointLastMouseMove = lParam;
|
||||
CFlexWnd::s_dwLastMouseMove = GetTickCount(); // Get timestamp
|
||||
CFlexWnd::s_ToolTip.SetEnable(FALSE);
|
||||
CFlexWnd::s_ToolTip.SetToolTipParent(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
|
||||
if (lpcs == NULL)
|
||||
break;
|
||||
|
||||
pThis = (CFlexWnd *)(void *)(lpcs->lpCreateParams);
|
||||
assert(sizeof(HANDLE) == sizeof(CFlexWnd *));
|
||||
SetProp(hWnd, sg_tszFlexWndPointerProp, (HANDLE)pThis);
|
||||
|
||||
if (pThis != NULL)
|
||||
{
|
||||
pThis->m_bIsDialog = FALSE;
|
||||
pThis->SetHWND(hWnd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pThis != NULL)
|
||||
return pThis->WndProc(hWnd, msg, wParam, lParam);
|
||||
else
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK __BaseFlexWndDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
CFlexWnd *pThis = (CFlexWnd *)GetProp(hWnd, sg_tszFlexWndPointerProp);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
pThis = (CFlexWnd *)(void *)lParam;
|
||||
assert(sizeof(HANDLE) == sizeof(CFlexWnd *));
|
||||
SetProp(hWnd, sg_tszFlexWndPointerProp, (HANDLE)pThis);
|
||||
if (pThis != NULL)
|
||||
{
|
||||
pThis->m_bIsDialog = TRUE;
|
||||
pThis->SetHWND(hWnd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pThis != NULL)
|
||||
return (BOOL)pThis->WndProc(hWnd, msg, wParam, lParam);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CFlexWnd::Invalidate()
|
||||
{
|
||||
if (m_hWnd != NULL)
|
||||
InvalidateRect(m_hWnd, NULL, TRUE);
|
||||
}
|
||||
|
||||
SIZE CFlexWnd::GetClientSize() const
|
||||
{
|
||||
RECT rect = {0, 0, 0, 0};
|
||||
if (m_hWnd != NULL)
|
||||
::GetClientRect(m_hWnd, &rect);
|
||||
SIZE size = {
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top};
|
||||
return size;
|
||||
}
|
||||
|
||||
void CFlexWnd::FillWndClass(HINSTANCE hInst)
|
||||
{
|
||||
sm_WndClass.cbSize = sizeof(WNDCLASSEX);
|
||||
sm_WndClass.style = CS_DBLCLKS;
|
||||
sm_WndClass.lpfnWndProc = __BaseFlexWndProc;
|
||||
sm_WndClass.cbClsExtra = 0;
|
||||
sm_WndClass.cbWndExtra = sizeof(CFlexWnd *);
|
||||
sm_WndClass.hInstance = sm_hInstance = hInst;
|
||||
sm_WndClass.hIcon = NULL;
|
||||
sm_WndClass.hCursor = NULL;
|
||||
sm_WndClass.hbrBackground = NULL;
|
||||
sm_WndClass.lpszMenuName = NULL;
|
||||
sm_WndClass.lpszClassName = sm_tszWndClassName;
|
||||
sm_WndClass.hIconSm = NULL;
|
||||
}
|
||||
|
||||
void CFlexWnd::RegisterWndClass(HINSTANCE hInst)
|
||||
{
|
||||
if (hInst == NULL)
|
||||
{
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
FillWndClass(hInst);
|
||||
RegisterClassEx(&sm_WndClass);
|
||||
sm_bWndClassRegistered = TRUE;
|
||||
}
|
||||
|
||||
void CFlexWnd::UnregisterWndClass(HINSTANCE hInst)
|
||||
{
|
||||
if (hInst == NULL)
|
||||
return;
|
||||
|
||||
UnregisterClass(sm_tszWndClassName, hInst);
|
||||
sm_bWndClassRegistered = FALSE;
|
||||
}
|
||||
|
||||
void CFlexWnd::GetClientRect(LPRECT lprect) const
|
||||
{
|
||||
if (lprect == NULL || m_hWnd == NULL)
|
||||
return;
|
||||
|
||||
::GetClientRect(m_hWnd, lprect);
|
||||
}
|
||||
|
||||
LPCTSTR CFlexWnd::GetDefaultClassName()
|
||||
{
|
||||
return CFlexWnd::sm_tszWndClassName;
|
||||
}
|
||||
|
||||
void CFlexWnd::SetRenderMode(BOOL bRender)
|
||||
{
|
||||
if (bRender == m_bRender)
|
||||
return;
|
||||
|
||||
m_bRender = bRender;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
BOOL CFlexWnd::InRenderMode()
|
||||
{
|
||||
return m_bRender;
|
||||
}
|
||||
|
||||
void EnumChildWindowsZDown(HWND hParent, WNDENUMPROC proc, LPARAM lParam)
|
||||
{
|
||||
if (hParent == NULL || proc == NULL)
|
||||
return;
|
||||
|
||||
HWND hWnd = GetWindow(hParent, GW_CHILD);
|
||||
|
||||
while (hWnd != NULL)
|
||||
{
|
||||
if (!proc(hWnd, lParam))
|
||||
break;
|
||||
|
||||
hWnd = GetWindow(hWnd, GW_HWNDNEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void EnumSiblingsAbove(HWND hParent, WNDENUMPROC proc, LPARAM lParam)
|
||||
{
|
||||
if (hParent == NULL || proc == NULL)
|
||||
return;
|
||||
|
||||
HWND hWnd = hParent;
|
||||
|
||||
while (1)
|
||||
{
|
||||
hWnd = GetWindow(hWnd, GW_HWNDPREV);
|
||||
|
||||
if (hWnd == NULL)
|
||||
break;
|
||||
|
||||
if (!proc(hWnd, lParam))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CALLBACK RenderIntoClipChild(HWND hWnd, LPARAM lParam)
|
||||
{
|
||||
CFlexWnd *pThis = (CFlexWnd *)(LPVOID)lParam;
|
||||
return pThis->RenderIntoClipChild(hWnd);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK RenderIntoRenderChild(HWND hWnd, LPARAM lParam)
|
||||
{
|
||||
CFlexWnd *pThis = (CFlexWnd *)(LPVOID)lParam;
|
||||
// Check if this is the immediate child. Do nothing if it's not immediate.
|
||||
HWND hParent = GetParent(hWnd);
|
||||
if (hParent != pThis->m_hWnd)
|
||||
return TRUE;
|
||||
return pThis->RenderIntoRenderChild(hWnd);
|
||||
}
|
||||
|
||||
BOOL CFlexWnd::RenderIntoClipChild(HWND hChild)
|
||||
{
|
||||
if (m_hRenderInto != NULL && HasWnd() && hChild && IsWindowVisible(hChild))
|
||||
{
|
||||
RECT rect;
|
||||
GetWindowRect(hChild, &rect);
|
||||
POINT ul = {rect.left, rect.top}, lr = {rect.right, rect.bottom};
|
||||
ScreenToClient(m_hWnd, &ul);
|
||||
ScreenToClient(m_hWnd, &lr);
|
||||
ExcludeClipRect(m_hRenderInto, ul.x, ul.y, lr.x, lr.y);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CFlexWnd::RenderIntoRenderChild(HWND hChild)
|
||||
{
|
||||
CFlexWnd *pChild = GetFlexWnd(hChild);
|
||||
if (m_hRenderInto != NULL && HasWnd() && pChild != NULL && IsWindowVisible(hChild))
|
||||
{
|
||||
RECT rect;
|
||||
GetWindowRect(hChild, &rect);
|
||||
POINT ul = {rect.left, rect.top};
|
||||
ScreenToClient(m_hWnd, &ul);
|
||||
pChild->RenderInto(m_hRenderInto, ul.x, ul.y);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CFlexWnd::RenderInto(HDC hDC, int x, int y)
|
||||
{
|
||||
if (hDC == NULL)
|
||||
return;
|
||||
|
||||
int sdc = SaveDC(hDC);
|
||||
{
|
||||
OffsetViewportOrgEx(hDC, x, y, NULL);
|
||||
SIZE size = GetClientSize();
|
||||
IntersectClipRect(hDC, 0, 0, size.cx, size.cy);
|
||||
|
||||
m_hRenderInto = hDC;
|
||||
|
||||
int sdc2 = SaveDC(hDC);
|
||||
{
|
||||
EnumChildWindows/*ZDown*/(m_hWnd, ::RenderIntoClipChild, (LPARAM)(PVOID)this);
|
||||
EnumSiblingsAbove(m_hWnd, ::RenderIntoClipChild, (LPARAM)(PVOID)this);
|
||||
DoOnPaint(hDC);
|
||||
}
|
||||
if (sdc2)
|
||||
RestoreDC(hDC, sdc2);
|
||||
|
||||
EnumChildWindows/*ZDown*/(m_hWnd, ::RenderIntoRenderChild, (LPARAM)(PVOID)this);
|
||||
|
||||
m_hRenderInto = NULL;
|
||||
}
|
||||
|
||||
if (sdc)
|
||||
RestoreDC(hDC, sdc);
|
||||
}
|
||||
|
||||
void CFlexWnd::SetCapture()
|
||||
{
|
||||
::SetCapture(m_hWnd);
|
||||
}
|
||||
|
||||
void CFlexWnd::ReleaseCapture()
|
||||
{
|
||||
::ReleaseCapture();
|
||||
}
|
||||
|
||||
void CFlexWnd::DoOnPaint(HDC hDC)
|
||||
{
|
||||
OnPaint(hDC);
|
||||
}
|
||||
Reference in New Issue
Block a user