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:
@@ -0,0 +1,218 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: flextooltip.cpp
|
||||
//
|
||||
// Desc: Implements a tooltip class that displays a text string as a tooltip.
|
||||
// CFlexTooltip (derived from CFlexWnd) is used throughout the UI when
|
||||
// a control needs to have a tooltip.
|
||||
//
|
||||
// Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
UINT_PTR CFlexToolTip::s_uiTimerID;
|
||||
DWORD CFlexToolTip::s_dwLastTimeStamp; // Last time stamp for mouse move
|
||||
TOOLTIPINIT CFlexToolTip::s_TTParam; // Parameters to initialize the tooltip
|
||||
|
||||
// TimerFunc is called periodically. It checks if a tooltip should be displayed.
|
||||
// If a window has indicated a need for tooltip, TimerFunc will initialize
|
||||
// for displaying here. CFlexWnd will do the actual displaying, since
|
||||
// it has to monitor WM_MOUSEMOVE message to be sure that tooltips only
|
||||
// display after a period of inactivity.
|
||||
void CALLBACK CFlexToolTip::TimerFunc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
||||
{
|
||||
// If it has been one sec already since last mouse move, display the tooltip
|
||||
if (dwTime > CFlexWnd::s_dwLastMouseMove + 1000)
|
||||
{
|
||||
if (s_TTParam.hWndParent && !CFlexWnd::s_ToolTip.IsEnabled())
|
||||
{
|
||||
// Check if the mouse cursor is outside the window. If so, don't activate tooltip.
|
||||
POINT pt;
|
||||
RECT rect;
|
||||
GetCursorPos(&pt);
|
||||
ScreenToClient(s_TTParam.hWndParent, &pt);
|
||||
::GetClientRect(s_TTParam.hWndParent, &rect);
|
||||
if (!PtInRect(&rect, pt))
|
||||
return;
|
||||
|
||||
SetParent(CFlexWnd::s_ToolTip.m_hWnd, s_TTParam.hWndParent);
|
||||
CFlexWnd::s_ToolTip.SetSBWidth(s_TTParam.iSBWidth);
|
||||
CFlexWnd::s_ToolTip.SetID(s_TTParam.dwID);
|
||||
CFlexWnd::s_ToolTip.SetNotifyWindow(s_TTParam.hWndNotify);
|
||||
CFlexWnd::s_ToolTip.SetText(s_TTParam.tszCaption);
|
||||
CFlexWnd::s_ToolTip.SetEnable(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We use the constructor and destructor to load and unload WINMM.DLL since the UI will only create this once.
|
||||
|
||||
CFlexToolTip::CFlexToolTip() :
|
||||
m_tszText(NULL), m_hNotifyWnd(NULL), m_dwID(0), m_bEnabled(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
CFlexToolTip::~CFlexToolTip()
|
||||
{
|
||||
delete[] m_tszText;
|
||||
}
|
||||
|
||||
HWND CFlexToolTip::Create(HWND hParent, const RECT &rect, BOOL bVisible, int iSBWidth)
|
||||
{
|
||||
m_iSBWidth = iSBWidth;
|
||||
return CFlexWnd::Create(hParent, rect, bVisible);
|
||||
}
|
||||
|
||||
// Set the tooltip position. pt is the upper-left point in screen coordinates.
|
||||
// bOffsetForMouseCursor is TRUE if the tooltip is to be displayed next to mouse cursor. SetPosition()
|
||||
// will offset the position of the tooltip so that the cursor doesn't block the text of the tooltip.
|
||||
void CFlexToolTip::SetPosition(POINT pt, BOOL bOffsetForMouseCursor)
|
||||
{
|
||||
// Check the top, right and bottom edges. If they are outside the main config window
|
||||
RECT rc;
|
||||
RECT cliprc;
|
||||
RECT parentrc;
|
||||
GetWindowRect(GetParent(), &parentrc);
|
||||
GetClientRect(&rc);
|
||||
GetWindowRect(GetParent(), &cliprc);
|
||||
cliprc.right -= DEFAULTVIEWSBWIDTH*2;
|
||||
if (bOffsetForMouseCursor)
|
||||
{
|
||||
pt.y -= rc.bottom; // Align the lower left corner to the cursor
|
||||
pt.x += 1; pt.y -= 1; // Offset x and y by 2 pixels so that when the mouse is moved up or right, we don't get over the tooltip window.
|
||||
}
|
||||
if (pt.y < cliprc.top) pt.y += cliprc.top - pt.y; // Top
|
||||
if (pt.x + rc.right > (cliprc.right - m_iSBWidth)) pt.x += cliprc.right - m_iSBWidth - (pt.x + rc.right); // Right
|
||||
if (pt.y + rc.bottom > cliprc.bottom) pt.y += cliprc.bottom - (pt.y + rc.bottom); // Bottom
|
||||
ScreenToClient(GetParent(), &pt);
|
||||
SetWindowPos(m_hWnd, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE);
|
||||
}
|
||||
|
||||
void CFlexToolTip::SetText(LPCTSTR tszText, POINT *textpos)
|
||||
{
|
||||
// Figure out window size and position
|
||||
RECT rc = {0, 0, 320, 480}; // Only go to half the window width max
|
||||
HDC hDC = CreateCompatibleDC(NULL);
|
||||
if (hDC != NULL)
|
||||
{
|
||||
DrawText(hDC, CFlexToolTip::s_TTParam.tszCaption, -1, &rc, DT_CALCRECT);
|
||||
// DrawText(hDC, m_tszText, -1, &rc, DT_CALCRECT);
|
||||
SetWindowPos(m_hWnd, HWND_TOP, 0, 0, rc.right, rc.bottom, 0); // Set window pos as needed by text
|
||||
DeleteDC(hDC);
|
||||
}
|
||||
|
||||
POINT pt;
|
||||
if (textpos)
|
||||
{
|
||||
pt = *textpos;
|
||||
SetPosition(pt, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCursorPos(&pt);
|
||||
SetPosition(pt);
|
||||
}
|
||||
SetWindowPos(m_hWnd, HWND_TOP, 0, 0, rc.right, rc.bottom, SWP_NOMOVE); // Set size
|
||||
}
|
||||
|
||||
void CFlexToolTip::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
|
||||
{
|
||||
ClientToScreen(m_hWnd, &point);
|
||||
ScreenToClient(m_hNotifyWnd, &point);
|
||||
if (bLeft)
|
||||
PostMessage(m_hNotifyWnd, WM_LBUTTONDOWN, fwKeys, point.x | (point.y << 16));
|
||||
else
|
||||
PostMessage(m_hNotifyWnd, WM_RBUTTONDOWN, fwKeys, point.x | (point.y << 16));
|
||||
}
|
||||
|
||||
void CFlexToolTip::OnDoubleClick(POINT point, WPARAM fwKeys, BOOL bLeft)
|
||||
{
|
||||
ClientToScreen(m_hWnd, &point);
|
||||
ScreenToClient(m_hNotifyWnd, &point);
|
||||
if (bLeft)
|
||||
PostMessage(m_hNotifyWnd, WM_LBUTTONDBLCLK, fwKeys, point.x | (point.y << 16));
|
||||
else
|
||||
PostMessage(m_hNotifyWnd, WM_RBUTTONDBLCLK, fwKeys, point.x | (point.y << 16));
|
||||
}
|
||||
|
||||
void CFlexToolTip::OnPaint(HDC hDC)
|
||||
{
|
||||
HDC hBDC = NULL, hODC = NULL;
|
||||
CBitmap *pbm = NULL;
|
||||
|
||||
if (!InRenderMode())
|
||||
{
|
||||
hODC = hDC;
|
||||
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
|
||||
if (pbm != NULL)
|
||||
{
|
||||
hBDC = pbm->BeginPaintInto();
|
||||
if (hBDC != NULL)
|
||||
{
|
||||
hDC = hBDC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InternalPaint(hDC);
|
||||
|
||||
if (!InRenderMode())
|
||||
{
|
||||
if (pbm != NULL)
|
||||
{
|
||||
if (hBDC != NULL)
|
||||
{
|
||||
pbm->EndPaintInto(hBDC);
|
||||
pbm->Draw(hODC);
|
||||
}
|
||||
delete pbm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFlexToolTip::InternalPaint(HDC hDC)
|
||||
{
|
||||
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbBk);
|
||||
if (hPen != NULL)
|
||||
{
|
||||
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
|
||||
|
||||
HGDIOBJ hBrush = CreateSolidBrush(m_rgbBk);
|
||||
if (hBrush != NULL)
|
||||
{
|
||||
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
|
||||
RECT rc = {0,0,0,0};
|
||||
|
||||
GetClientRect(&rc);
|
||||
DrawText(hDC, CFlexToolTip::s_TTParam.tszCaption, -1, &rc, DT_LEFT);
|
||||
|
||||
SelectObject(hDC, hOldBrush);
|
||||
DeleteObject(hBrush);
|
||||
}
|
||||
|
||||
SelectObject(hDC, hOldPen);
|
||||
DeleteObject(hPen);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CFlexToolTip::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CFlexToolTip::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
||||
{
|
||||
// Create a timer
|
||||
CFlexToolTip::s_uiTimerID = SetTimer(m_hWnd, 6, 50, CFlexToolTip::TimerFunc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CFlexToolTip::OnDestroy()
|
||||
{
|
||||
// Kill the timer
|
||||
if (CFlexToolTip::s_uiTimerID)
|
||||
{
|
||||
KillTimer(m_hWnd, 6);
|
||||
CFlexToolTip::s_uiTimerID = 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user