4#include "Stroika/Frameworks/StroikaPreComp.h"
8#include "Stroika/Frameworks/Led/IdleManager.h"
15#if qHookIMEEndCompositionMessageToWorkAroundWin2KIMEForNonUNICODEBug
21namespace Stroika::Frameworks::Led::Platform {
24 IdleMangerLinkerSupport::IdleMangerLinkerSupport ()
36 class IdleManagerOSImpl_Win32 :
public IdleManager::IdleManagerOSImpl {
38 IdleManagerOSImpl_Win32 ();
39 ~IdleManagerOSImpl_Win32 ();
42 virtual void StartSpendTimeCalls ()
override;
43 virtual void TerminateSpendTimeCalls ()
override;
48 nonvirtual
void OnTimer_Msg (UINT_PTR nEventID, TIMERPROC* proc);
51 nonvirtual
void CheckAndCreateIdleWnd ();
54 static LRESULT CALLBACK StaticWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
69 struct IdleMangerSetter {
72 IdleManager::SetIdleManagerOSImpl (&fIdleManagerOSImpl);
76 IdleManager::SetIdleManagerOSImpl (NULL);
78 IdleManagerOSImpl_Win32 fIdleManagerOSImpl;
80 struct IdleMangerSetter sIdleMangerSetter;
88 FunnyMSPageUpDownAdjustSelectionHelper::FunnyMSPageUpDownAdjustSelectionHelper ()
93 void FunnyMSPageUpDownAdjustSelectionHelper::CaptureInfo (TextInteractor& ti)
95 size_t pinPoint = ti.GetSelectionStart ();
96 ptrdiff_t rowNum = ti.CalculateRowDeltaFromCharDeltaFromTopOfWindow (
long (pinPoint) -
long (ti.GetMarkerPositionOfStartOfWindow ()));
97 fRowNum = ::abs (rowNum);
100 void FunnyMSPageUpDownAdjustSelectionHelper::CompleteAdjustment (TextInteractor& ti)
103 size_t totalRowsInWindow = ti.GetTotalRowsInWindow ();
104 Assert (totalRowsInWindow >= 1);
105 fRowNum = min (fRowNum, totalRowsInWindow - 1);
107 size_t newRowStart = ti.CalculateCharDeltaFromRowDeltaFromTopOfWindow (fRowNum) + ti.GetMarkerPositionOfStartOfWindow ();
108 size_t newRowEnd = ti.GetEndOfRowContainingPosition (newRowStart);
109 Assert (newRowEnd >= newRowStart);
111 TextImager::GoalColumnRecomputerControlContext skipRecompute (ti,
true);
113 size_t newSelStart = ti.GetRowRelativeCharAtLoc (TextImager::Tablet_Acquirer (&ti)->CvtFromTWIPSH (ti.GetSelectionGoalColumn ()), newRowStart);
115 newSelStart = min (newSelStart, newRowEnd);
118 ti.SetSelection (newSelStart, newSelStart);
131 void SimpleWin32WndProcHelper::Create (DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle,
int x,
int y,
132 int nWidth,
int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance)
135 if (lpClassName == NULL) {
136 tmpClassName = Characters::CString::Format (_T(
"LED_SimpleWin32WndProcHelper-%d-%p"), ::GetCurrentProcessId (), &StaticWndProc);
137 lpClassName = tmpClassName.c_str ();
139 static bool sRegistered =
false;
140 if (not sRegistered) {
142 memset (&wcex, 0,
sizeof (wcex));
143 wcex.cbSize =
sizeof (WNDCLASSEX);
144 wcex.lpfnWndProc = (WNDPROC)StaticWndProc;
145 wcex.lpszClassName = lpClassName;
146 ATOM regResult = ::RegisterClassEx (&wcex);
147 if (regResult == 0) {
148 DWORD laserErr = ::GetLastError ();
149 if (laserErr == ERROR_CLASS_ALREADY_EXISTS) {
160 [[maybe_unused]] HWND hWnd =
161 ::CreateWindowEx (dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance,
this);
162 Assert (hWnd == GetValidatedHWND ());
165 LRESULT CALLBACK SimpleWin32WndProcHelper::StaticWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
167 if (message == WM_CREATE) {
168 LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
170 SimpleWin32WndProcHelper* pThis =
reinterpret_cast<SimpleWin32WndProcHelper*
> (lpcs->lpCreateParams);
171 Assert (pThis->GetHWND () == NULL);
172 pThis->SetHWND (hWnd);
175 SimpleWin32WndProcHelper* pThis =
reinterpret_cast<SimpleWin32WndProcHelper*
> (::GetWindowLongPtr (hWnd, GWLP_USERDATA));
182 Assert (message == WM_GETMINMAXINFO or message == WM_NCCREATE or message == WM_NCCALCSIZE);
183 return ::DefWindowProc (hWnd, message, wParam, lParam);
186 Assert (pThis != NULL);
187 Assert (pThis->GetHWND () == hWnd);
188 return pThis->WndProc (message, wParam, lParam);
196 IdleManagerOSImpl_Win32::IdleManagerOSImpl_Win32 ()
198 , fSuggestedFrequency (0)
203 IdleManagerOSImpl_Win32::~IdleManagerOSImpl_Win32 ()
205 if (fIdleWnd != NULL) {
206 ::DestroyWindow (fIdleWnd);
210 void IdleManagerOSImpl_Win32::StartSpendTimeCalls ()
212 CheckAndCreateIdleWnd ();
216 int timeout =
static_cast<int> (fSuggestedFrequency.count () * 1000);
217 Verify ((fTimerID = ::SetTimer (fIdleWnd, eTimerEventID, timeout, NULL)) != 0);
221 void IdleManagerOSImpl_Win32::TerminateSpendTimeCalls ()
225 Verify (::KillTimer (fIdleWnd, eTimerEventID));
232 return fSuggestedFrequency;
237 if (fSuggestedFrequency != suggestedFrequency) {
238 fSuggestedFrequency = suggestedFrequency;
240 TerminateSpendTimeCalls ();
241 StartSpendTimeCalls ();
246 LRESULT CALLBACK IdleManagerOSImpl_Win32::StaticWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
248 if (message == WM_CREATE) {
249 LPCREATESTRUCT lpcs =
reinterpret_cast<LPCREATESTRUCT
> (lParam);
251 IdleManagerOSImpl_Win32* pThis =
reinterpret_cast<IdleManagerOSImpl_Win32*
> (lpcs->lpCreateParams);
252 ::SetWindowLongPtr (hWnd, GWLP_USERDATA,
reinterpret_cast<DWORD_PTR
> (pThis));
255 IdleManagerOSImpl_Win32* pThis =
reinterpret_cast<IdleManagerOSImpl_Win32*
> (::GetWindowLongPtr (hWnd, GWLP_USERDATA));
258 return ::DefWindowProc (hWnd, message, wParam, lParam);
261 Assert (pThis != NULL);
264 pThis->OnTimer_Msg (wParam,
reinterpret_cast<TIMERPROC*
> (lParam));
267 return ::DefWindowProc (hWnd, message, wParam, lParam);
270 void IdleManagerOSImpl_Win32::OnTimer_Msg (UINT_PTR , TIMERPROC* )
276#if defined(PM_QS_INPUT) || defined(PM_QS_PAINT)
278 if (::PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE | PM_QS_INPUT | PM_QS_PAINT) == 0) {
287 void IdleManagerOSImpl_Win32::CheckAndCreateIdleWnd ()
289 if (fIdleWnd == NULL) {
291 SDKString className = Characters::CString::Format (Led_SDK_TCHAROF (
"Led::IdleManagerOSImpl_Win32 (%p)"), &StaticWndProc);
293 if (sRegisteredClassName != className) {
295 memset (&wcex, 0,
sizeof (wcex));
296 wcex.cbSize =
sizeof (WNDCLASSEX);
297 wcex.lpfnWndProc = (WNDPROC)StaticWndProc;
298 wcex.lpszClassName = className.c_str ();
299 ATOM regResult = ::RegisterClassEx (&wcex);
300 if (regResult == 0) {
301 DWORD x = ::GetLastError ();
302 if (x == ERROR_CLASS_ALREADY_EXISTS) {
309 sRegisteredClassName = className;
311 fIdleWnd = ::CreateWindowEx (0, className.c_str (), _T(
""), 0, 0, 0, 1, 1, NULL, NULL, NULL,
this);
#define CompileTimeFlagChecker_SOURCE(NS_PREFIX, NAME, VALUE)
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
basic_string< SDKChar > SDKString