YSTest: HostedGUI.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

HostedGUI.cpp
浏览该文件的文档.
1 /*
2 © 2013-2020 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
29 #include "YCLib/YModules.h"
30 #include YFM_YCLib_HostedGUI // for default_delete;
31 #include YFM_YSLib_Core_YCoreUtilities // for YSLib::CheckPositive,
32 // ystdex::aligned_store_cast;
33 #if YCL_Win32
34 # include YFM_Win32_YCLib_MinGW32
35 # include <ystdex/exception.h> // for ystdex::unimplemented;
36 # if SW_SHOWNORMAL != 1 || WS_POPUP != 0x80000000L || WS_EX_LTRREADING != 0L
37 # error "Wrong macro defined."
38 # endif
39 # include YFM_YCLib_Input // for platform::ClearKeyStates;
40 # include "YSLib/Service/YModules.h"
41 # include YFM_YSLib_Service_YBlit // for ystdex::pvoid, YSLib::BlitLines;
42 # include YFM_Win32_YCLib_NLS // for platform_ex::WCSToUTF8;
43 # include <Shellapi.h> // for ::ShellExecuteW;
44 # include <ystdex/mixin.hpp> // for ystdex::wrap_mixin_t;
45 #elif YCL_Android
46 # include YFM_Android_YCLib_Android
47 # include <android/native_window.h>
48 # include "YSLib/Service/YModules.h"
49 # include YFM_YSLib_Service_YBlit // for YSLib::BlitLines;
50 #endif
51 #if YCL_HostedUI_XCB || YCL_Android
52 # include "YSLib/Service/YModules.h"
53 # include YFM_YSLib_Service_YGDI
54 #endif
55
56 using namespace YSLib;
57 using namespace Drawing;
59 using YSLib::string;
61 using platform::string_view;
62
63 #if YF_Hosted
64
65 namespace platform_ex
66 {
67
68 void
69 HostWindowDelete::operator()(pointer p) const ynothrow
70 {
71 # if YCL_HostedUI_XCB
72 default_delete<XCB::WindowData>()(p);
73 # elif YCL_Win32
74 // NOTE: The window could be already destroyed in window procedure.
75 if(::IsWindow(p))
76 // XXX: Error ignored.
77 ::DestroyWindow(p);
78 # elif YCL_Android
79 // XXX: Error ignored.
80 ::ANativeWindow_release(p);
81 # endif
82 }
83
84
85 # if YCL_Win32
86 void
87 GDIObjectDelete::operator()(pointer h) const ynothrow
88 {
89 static_assert(std::is_same<pointer, ::HGDIOBJ>::value,
90 "Mismatched type found.");
91
92 YCL_TraceCallF_Win32(DeleteObject, h);
93 }
94 # endif
95
96 namespace
97 {
98
99 # if YCL_HostedUI_XCB || YCL_Android
100 SDst
102 CheckStride(SDst buf_stride, SDst w)
103 {
104 if(buf_stride < w)
105 // XXX: Use more specified exception type.
106 throw std::runtime_error("Stride is small than width.");
107 return buf_stride;
108 }
109 # elif YCL_Win32
110 void
112 MoveWindow(::HWND h_wnd, SPos x, SPos y)
113 {
114 YCL_CallF_Win32(SetWindowPos, h_wnd, {}, x, y, 0, 0, SWP_ASYNCWINDOWPOS
115 | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING
116 | SWP_NOSIZE | SWP_NOZORDER);
117 }
118
120 void
121 ResizeWindow(::HWND h_wnd, SDst w, SDst h)
122 {
123 YCL_CallF_Win32(SetWindowPos, h_wnd, {}, 0, 0, int(w), int(h),
124 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER
125 | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
126 }
127
129 ::RECT
130 FetchWindowRect(::HWND h_wnd)
131 {
132 ::RECT rect;
133
134 YCL_CallF_Win32(GetWindowRect, h_wnd, &rect);
135 return rect;
136 }
137
139
140 Size
141 FetchSizeFromBounds(const ::RECT& rect)
142 {
143 return {CheckArithmetic<SDst>(rect.right - rect.left, "width"),
144 CheckArithmetic<SDst>(rect.bottom - rect.top, "height")};
145 }
146
148 Rect
149 FetchRectFromBounds(const ::RECT& rect)
150 {
151 return {rect.left, rect.top, FetchSizeFromBounds(rect)};
152 }
153
155 inline WindowStyle
156 FetchWindowStyle(::HWND h_wnd)
157 {
158 return WindowStyle(::GetWindowLongW(h_wnd, GWL_STYLE));
159 }
160
161 void
162 AdjustWindowBounds(::RECT& rect, ::HWND h_wnd, bool b_menu = {})
163 {
164 YCL_CallF_Win32(AdjustWindowRect, &rect, FetchWindowStyle(h_wnd), b_menu);
165 FetchSizeFromBounds(rect);
166 }
167
169 void
170 SetWindowBounds(::HWND h_wnd, int x, int y, SDst w, SDst h)
171 {
172 YCL_CallF_Win32(SetWindowPos, h_wnd, {}, x, y, int(w), int(h),
173 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER
174 | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
175 }
177
178
180 inline unique_ptr_from<GlobalDelete>
181 MakeMoveableGlobalMemory(size_t size)
182 {
183 auto p(unique_raw(::GlobalAlloc(GMEM_MOVEABLE, size), GlobalDelete()));
184
185 if(YB_UNLIKELY(!p))
186 // TODO: Use inherited class of exception.
187 throw std::bad_alloc();
188 return p;
189 }
190
192 template<typename _tChar, class _tString>
193 YB_ALLOCATOR YB_ATTR_returns_nonnull void*
194 CopyGlobalString(const _tString& str)
195 {
196 const auto len(str.length());
197 auto p(MakeMoveableGlobalMemory((len + 1) * sizeof(_tChar)));
198 {
199 const GlobalLocked gl(Nonnull(p));
200 const auto p_buf(gl.GetPtr<_tChar>().get());
201
202 ystdex::ntctscpy(p_buf, str.data(), len);
203 }
204 return p.release();
205 }
206 # endif
207
208 } // unnamed namespace;
209
210
211 # if YCL_Win32
212 void
213 BindDefaultWindowProc(NativeWindowHandle h_wnd, MessageMap& m, unsigned msg,
214 EventPriority prior)
215 {
216 m[msg].Add(
217 [=](::WPARAM w_param, ::LPARAM l_param, ::LRESULT& res) ynothrow{
218 res = ::DefWindowProcW(h_wnd, msg, w_param, l_param);
219 }, prior);
220 }
221 # endif
222
223
224 # if YCL_HostedUI_XCB
225 XCB::WindowData&
226 WindowReference::Deref() const
227 {
228 if(const auto h = GetNativeHandle())
229 return *h;
230 throw std::runtime_error("Null window reference found.");
231 }
232 # elif YCL_Win32
233 bool
234 WindowReference::IsMaximized() const ynothrow
235 {
236 return ::IsZoomed(GetNativeHandle());
237 }
238 bool
239 WindowReference::IsMinimized() const ynothrow
240 {
241 return ::IsIconic(GetNativeHandle());
242 }
243 bool
244 WindowReference::IsVisible() const ynothrow
245 {
246 return ::IsWindowVisible(GetNativeHandle());
247 }
248
249 Rect
250 WindowReference::GetBounds() const
251 {
252 return FetchRectFromBounds(FetchWindowRect(GetNativeHandle()));
253 }
254 Rect
255 WindowReference::GetClientBounds() const
256 {
257 return {GetClientLocation(), GetClientSize()};
258 }
259 Point
260 WindowReference::GetClientLocation() const
261 {
262 ::POINT point{0, 0};
263
264 YCL_CallF_Win32(ClientToScreen, GetNativeHandle(), &point);
265 return {point.x, point.y};
266 }
267 Size
268 WindowReference::GetClientSize() const
269 {
270 ::RECT rect;
271
272 YCL_CallF_Win32(GetClientRect, GetNativeHandle(), &rect);
273 return {rect.right, rect.bottom};
274 }
275 Point
276 WindowReference::GetCursorLocation() const
277 {
278 ::POINT cursor;
279
280 YCL_CallF_Win32(GetCursorPos, &cursor);
281 YCL_CallF_Win32(ScreenToClient, GetNativeHandle(), &cursor);
282 return {cursor.x, cursor.y};
283 }
284 Point
285 WindowReference::GetLocation() const
286 {
287 const auto& rect(FetchWindowRect(GetNativeHandle()));
288
289 return {rect.left, rect.top};
290 }
291 YSLib::Drawing::AlphaType
292 WindowReference::GetOpacity() const
293 {
294 unsigned char a;
295
296 YCL_CallF_Win32(GetLayeredWindowAttributes, GetNativeHandle(), {}, &a, {});
297 return a;
298 }
299 Size
300 WindowReference::GetSize() const
301 {
302 return FetchSizeFromBounds(FetchWindowRect(GetNativeHandle()));
303 }
304
305 void
306 WindowReference::SetBounds(const Rect& r)
307 {
308 SetWindowBounds(GetNativeHandle(), r.X, r.Y, r.Width, r.Height);
309 }
310 void
311 WindowReference::SetClientBounds(const Rect& r)
312 {
313 ::RECT rect{r.X, r.Y, CheckArithmetic<SPos>(r.GetRight(), "width"),
314 CheckArithmetic<SPos>(r.GetBottom(), "height")};
315 const auto h_wnd(GetNativeHandle());
316
317 AdjustWindowBounds(rect, h_wnd);
318 SetWindowBounds(h_wnd, rect.left, rect.top, SDst(rect.right - rect.left),
319 SDst(rect.bottom - rect.top));
320 }
321 void
322 WindowReference::SetOpacity(YSLib::Drawing::AlphaType a)
323 {
324 YCL_CallF_Win32(SetLayeredWindowAttributes, GetNativeHandle(), 0, a,
325 LWA_ALPHA);
326 }
327 WindowReference
328 WindowReference::GetParent() const
329 {
330 // TODO: Implementation.
331 throw ystdex::unimplemented();
332 }
333
334 void
335 WindowReference::SetText(const wchar_t* str)
336 {
337 YTraceDe(Debug, "Setting text '%p' to window reference '%p'...",
338 ystdex::pvoid(str), ystdex::pvoid(this));
339 YCL_CallF_Win32(SetWindowTextW, GetNativeHandle(), str);
340 }
341
342 void
343 WindowReference::Close()
344 {
345 YTraceDe(Debug, "Closing window reference '%p'...", ystdex::pvoid(this));
346 YCL_CallF_Win32(SendNotifyMessageW, GetNativeHandle(), WM_CLOSE, 0, 0);
347 }
348
349 void
350 WindowReference::Invalidate()
351 {
352 YTraceDe(Debug, "Invalidating window reference '%p'...",
353 ystdex::pvoid(this));
354 YCL_CallF_Win32(InvalidateRect, GetNativeHandle(), {}, {});
355 }
356
357 void
358 WindowReference::Move(const Point& pt)
359 {
360 MoveWindow(GetNativeHandle(), pt.X, pt.Y);
361 }
362
363 void
364 WindowReference::MoveClient(const Point& pt)
365 {
366 ::RECT rect{pt.X, pt.Y, pt.X, pt.Y};
367 const auto h_wnd(GetNativeHandle());
368
369 AdjustWindowBounds(rect, h_wnd);
370 MoveWindow(h_wnd, rect.left, rect. top);
371 }
372
373 void
374 WindowReference::Resize(const Size& s)
375 {
376 ResizeWindow(GetNativeHandle(), s.Width, s.Height);
377 }
378
379 void
380 WindowReference::ResizeClient(const Size& s)
381 {
382 ::RECT rect{0, 0, CheckArithmetic<SPos>(s.Width, "width"),
383 CheckArithmetic<SPos>(s.Height, "height")};
384 const auto h_wnd(GetNativeHandle());
385
386 AdjustWindowBounds(rect, h_wnd);
387 ResizeWindow(h_wnd, SDst(rect.right - rect.left),
388 SDst(rect.bottom - rect.top));
389 }
390
391 bool
392 WindowReference::Show(int n_cmd_show) ynothrow
393 {
394 return ::ShowWindowAsync(GetNativeHandle(), n_cmd_show) != 0;
395 }
396 # elif YCL_Android
397 SDst
398 WindowReference::GetWidth() const
399 {
400 return CheckPositive<SDst>(
401 ::ANativeWindow_getWidth(GetNativeHandle()), "width");
402 }
403 SDst
404 WindowReference::GetHeight() const
405 {
406 return CheckPositive<SDst>(::ANativeWindow_getHeight(
407 GetNativeHandle()), "height");
408 }
409 # endif
410
411
412 # if YCL_HostedUI_XCB
413 void
414 UpdateContentTo(NativeWindowHandle h_wnd, const Rect& r, const ConstGraphics& g)
415 {
416 XCB::UpdatePixmapBuffer(Deref(h_wnd), r, g);
417 }
418 # elif YCL_Win32
419 ::HBITMAP
420 CreateCompatibleDIBSection(const YSLib::Drawing::Size& s, BitmapPtr& p_buffer)
421 {
422 // NOTE: There is no resolution information created. See https://msdn.microsoft.com/en-us/library/dd183494.aspx.
423 // NOTE: It would return %ERROR_INVALID_PARAMETER for many calls if
424 // allocated memory is not on 32-bit boundary. Anyway it is not a matter
425 // here because the pixel is at least 32-bit. See
426 // http://msdn2.microsoft.com/en-us/library/ms532292.aspx and https://msdn.microsoft.com/en-us/library/dd183494.aspx.
427 // NOTE: Bitmap format is hard coded here for explicit buffer
428 // compatibility. %::CreateCompatibleBitmap is not fit for unknown
429 // windows.
430 ::BITMAPINFO bmi{{sizeof(::BITMAPINFOHEADER), CheckPositive<long>(
431 s.Width, "width"), -CheckPositive<long>(s.Height,
432 "height") - 1, 1, 32, BI_RGB, static_cast<unsigned long>(
433 sizeof(Pixel) * s.Width * s.Height), 0, 0, 0, 0}, {}};
434 void* p_buf{};
435 const auto h(YCL_CallF_Win32(CreateDIBSection, {}, &bmi, DIB_RGB_COLORS,
436 &p_buf, {}, 0));
437
438 if(YB_LIKELY(p_buf))
439 p_buffer = static_cast< BitmapPtr>(p_buf);
440 else
441 // XXX: This should not occur unless there are bugs in implementation of
442 // %::CreateCompatibleDIBSection.
443 throw std::runtime_error("Failed writing pointer"
444 " @ CreateCompatibleDIBSection.");
445 return h;
446 }
447
448 NativeWindowHandle
449 CreateNativeWindow(const wchar_t* class_name, const Drawing::Size& s,
450 const wchar_t* title, WindowStyle wstyle, WindowStyle wstyle_ex)
451 {
452 ::RECT rect{0, 0, CheckArithmetic<SPos>(s.Width, "width"),
453 CheckArithmetic<SPos>(s.Height, "height")};
454
455 ::AdjustWindowRect(&rect, wstyle, false);
456 return ::CreateWindowExW(wstyle_ex, class_name, title, wstyle,
457 CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom
458 - rect.top, {}/*HWND_DESKTOP*/, {}, ::GetModuleHandleW({}), {});
459 }
460 # elif YCL_Android
461 void
462 UpdateContentTo(NativeWindowHandle h_wnd, const Rect& r, const ConstGraphics& g)
463 {
464 ::ANativeWindow_Buffer abuf;
465 ::ARect arect{r.X, r.Y, r.X + r.Width, r.Y + r.Height};
466 const auto res(::ANativeWindow_lock(Nonnull(h_wnd), &abuf, &arect));
467
468 if(YB_LIKELY(res == 0))
469 {
470 BlitLines<false, false>(CopyLine<true>(), BitmapPtr(abuf.bits),
471 g.GetBufferPtr(), WindowReference(h_wnd).GetSize(), g.GetSize(),
472 r.GetPoint(), {}, r.GetSize());
473 ::ANativeWindow_unlockAndPost(h_wnd);
474 }
475 else
476 YTraceDe(Warning, "::ANativeWindow_lock failed, error = %d.", int(res));
477 }
478 # endif
479
480
481 # if YCL_HostedUI_XCB || YCL_Android
482 class ScreenBufferData : public CompactPixmap
483 {
484 public:
485 ScreenBufferData(const Size&, SDst);
490 ~ScreenBufferData() override;
491
492 DefDeMoveCtor(ScreenBufferData)
493 };
494
495 ScreenBufferData::ScreenBufferData(const Size& s, SDst buf_stride)
496 : CompactPixmap({}, CheckStride(buf_stride, s.Width), s.Height)
497 {}
498 ImplDeDtor(ScreenBufferData)
499 # endif
500
501
502 # if YCL_HostedUI_XCB || YCL_Android
503 ScreenBuffer::ScreenBuffer(const Size& s)
504 : ScreenBuffer(s, s.Width)
505 {}
506 ScreenBuffer::ScreenBuffer(const Size& s, SDst buf_stride)
507 : p_impl(new ScreenBufferData(s, buf_stride)), width(s.Width)
508 {}
509 ScreenBuffer::ScreenBuffer(ScreenBuffer&& sbuf) ynothrow
510 : p_impl(new ScreenBufferData(std::move(*sbuf.p_impl))), width(sbuf.width)
511 {
512 sbuf.width = 0;
513 }
514 # elif YCL_Win32
515 ScreenBuffer::ScreenBuffer(const Size& s)
516 : size(s), p_bitmap(CreateCompatibleDIBSection(s, p_buffer))
517 {}
518 ScreenBuffer::ScreenBuffer(ScreenBuffer&&) ynothrow = default;
519 # endif
520 ImplDeDtor(ScreenBuffer)
521
522 # if YCL_HostedUI_XCB || YCL_Android
523 BitmapPtr
524 ScreenBuffer::GetBufferPtr() const ynothrow
525 {
526 return Deref(p_impl).GetBufferPtr();
527 }
528 YSLib::Drawing::Graphics
529 ScreenBuffer::GetContext() const ynothrow
530 {
531 return Deref(p_impl).GetContext();
532 }
533 Size
534 ScreenBuffer::GetSize() const ynothrow
535 {
536 return {width, Deref(p_impl).GetHeight()};
537 }
538 YSLib::SDst
539 ScreenBuffer::GetStride() const ynothrow
540 {
541 return Deref(p_impl).GetWidth();
542 }
543
544 void
545 ScreenBuffer::Resize(const Size& s)
546 {
547 // TODO: Expand stride for given width using a proper strategy.
548 Deref(p_impl).SetSize(s);
549 width = s.Width;
550 }
551 # elif YCL_Win32
552 void
553 ScreenBuffer::Resize(const Size& s)
554 {
555 if(s != size)
556 *this = ScreenBuffer(s);
557 }
558
559 void
560 ScreenBuffer::Premultiply(ConstBitmapPtr p_buf) ynothrow
561 {
562 YAssertNonnull(p_buf);
563 // NOTE: Since the stride is guaranteed equal to the width, the storage for
564 // pixels can be supposed to be contiguous.
565 std::transform(p_buf, p_buf + size.Width * size.Height, p_buffer,
566 [](const Pixel& pixel) ynothrow{
567 const auto a(pixel.GetA());
568
569 return Pixel{MonoType(pixel.GetB() * a / 0xFF),
570 MonoType(pixel.GetG() * a / 0xFF),
571 MonoType(pixel.GetR() * a / 0xFF), a};
572 });
573 }
574 # endif
575
576 void
577 ScreenBuffer::UpdateFrom(ConstBitmapPtr p_buf) ynothrow
578 {
579 # if YCL_HostedUI_XCB || YCL_Android
580 // TODO: Expand stride for given width using a proper strategy.
581 CopyBitmapBuffer(Deref(p_impl).GetBufferPtr(), p_buf, GetSize());
582 # elif YCL_Win32
583 // NOTE: Since the pitch is guaranteed equal to the width, the storage for
584 // pixels can be supposed to be contiguous.
585 CopyBitmapBuffer(GetBufferPtr(), p_buf, size);
586 # endif
587 }
588
589 # if YCL_Win32
590 void
591 ScreenBuffer::UpdateFromBounds(ConstBitmapPtr p_buf, const Rect& r) ynothrow
592 {
593 BlitLines<false, false>(CopyLine<true>(), GetBufferPtr(), Nonnull(p_buf),
594 size, size, r.GetPoint(), r.GetPoint(), r.GetSize());
595 }
596
597 void
598 ScreenBuffer::UpdatePremultipliedTo(NativeWindowHandle h_wnd, AlphaType a,
599 const Point& pt)
600 {
601 GSurface<> sf(h_wnd);
602
603 sf.UpdatePremultiplied(*this, h_wnd, a, pt);
604 }
605 # endif
606
607 void
608 ScreenBuffer::UpdateTo(NativeWindowHandle h_wnd, const Point& pt) ynothrow
609 {
610 # if YCL_HostedUI_XCB || YCL_Android
611 UpdateContentTo(h_wnd, {pt, GetSize()}, GetContext());
612 # elif YCL_Win32
613 GSurface<>(h_wnd).UpdateBounds(*this, {pt, GetSize()});
614 # endif
615 }
616 # if YCL_Win32
617 void
618 ScreenBuffer::UpdateToBounds(NativeWindowHandle h_wnd, const Rect& r,
619 const Point& sp) ynothrow
620 {
621 GSurface<>(h_wnd).UpdateBounds(*this, r, sp);
622 }
623 # endif
624
625 void
626 swap(ScreenBuffer& x, ScreenBuffer& y) ynothrow
627 {
628 # if YCL_HostedUI_XCB || YCL_Android
629 swap(Deref(x.p_impl), Deref(y.p_impl)),
630 std::swap(x.width, y.width);
631 # elif YCL_Win32
632 std::swap(x.size, y.size),
633 std::swap(x.p_buffer, y.p_buffer),
634 std::swap(x.p_bitmap, y.p_bitmap);
635 # endif
636 }
637
638
639 # if YCL_Win32
640 WindowMemorySurface::WindowMemorySurface(::HDC h_dc)
641 : h_owner_dc(h_dc), h_mem_dc(::CreateCompatibleDC(h_dc))
642 {}
643 WindowMemorySurface::~WindowMemorySurface()
644 {
645 ::DeleteDC(h_mem_dc);
646 }
647
648 void
649 WindowMemorySurface::UpdateBounds(ScreenBuffer& sbuf, const Rect& r,
650 const Point& sp) ynothrow
651 {
652 if(const auto h_native = sbuf.GetNativeHandle())
653 {
654 const auto h_old(::SelectObject(h_mem_dc, h_native));
655
656 if(h_old)
657 {
658 YCL_TraceCallF_Win32(BitBlt, h_owner_dc, int(r.X), int(r.Y),
659 int(r.Width), int(r.Height), h_mem_dc, int(sp.X), int(sp.Y),
660 SRCCOPY);
661 if(YB_UNLIKELY(!::SelectObject(h_mem_dc, h_old)))
662 YTraceDe(Err, "Restoring GDI object failed"
663 " @ WindowMemorySurface::UpdateBounds.");
664 }
665 else
666 YTraceDe(Err, "Setting GDI object failed"
667 " @ WindowMemorySurface::UpdateBounds.");
668 }
669 }
670
671 void
672 WindowMemorySurface::UpdatePremultiplied(ScreenBuffer& sbuf,
673 NativeWindowHandle h_wnd, YSLib::Drawing::AlphaType a, const Point& sp)
674 ynothrow
675 {
676 if(const auto h_native = sbuf.GetNativeHandle())
677 {
678 const auto h_old(::SelectObject(h_mem_dc, h_native));
679 auto rect(FetchWindowRect(h_wnd));
680 ::SIZE size{rect.right - rect.left, rect.bottom - rect.top};
681 ::POINT pt{sp.X, sp.Y};
682 ::BLENDFUNCTION bfunc{AC_SRC_OVER, 0, a, AC_SRC_ALPHA};
683
684 YCL_TraceCallF_Win32(UpdateLayeredWindow, h_wnd, h_owner_dc,
685 ystdex::aligned_store_cast<::POINT*>(&rect), &size, h_mem_dc, &pt,
686 0, &bfunc, ULW_ALPHA);
687 ::SelectObject(h_mem_dc, h_old);
688 }
689 }
690
691
692 WindowDeviceContext::WindowDeviceContext(NativeWindowHandle h_wnd)
693 // NOTE: Painting using %::GetDC and manually managing clipping areas
694 // instead of %::GetDCEx, for performance and convenience calculation
695 // of input boundary.
696 : WindowDeviceContextBase(h_wnd, ::GetDC(Nonnull(h_wnd)))
697 {
698 if(YB_UNLIKELY(!hDC))
699 throw LoggedEvent("Retrieving device context failure.");
700 }
701 WindowDeviceContext::~WindowDeviceContext()
702 {
703 ::ReleaseDC(hWindow, hDC);
704 }
705
706
707 struct PaintStructData::Data final : ::PAINTSTRUCT
708 {};
709
710
711 PaintStructData::PaintStructData()
712 : pun(ystdex::default_init, &ps)
713 {
714 static_assert(ystdex::is_aligned_storable<decltype(ps), Data>(),
715 "Invalid buffer found.");
716 }
717 ImplDeDtor(PaintStructData)
718
719
720 WindowRegionDeviceContext::WindowRegionDeviceContext(NativeWindowHandle h_wnd)
721 : PaintStructData(),
722 WindowDeviceContextBase(h_wnd, ::BeginPaint(Nonnull(h_wnd), &Get()))
723 {
724 if(YB_UNLIKELY(!hDC))
725 throw LoggedEvent("Device context initialization failure.");
726 }
727 WindowRegionDeviceContext::~WindowRegionDeviceContext()
728 {
729 // NOTE: Return value is ignored since it is always %TRUE.
730 ::EndPaint(hWindow, &Get());
731 }
732
733 bool
734 WindowRegionDeviceContext::IsBackgroundValid() const ynothrow
735 {
736 return !bool(Get().fErase);
737 }
738
739 Rect
740 WindowRegionDeviceContext::GetInvalidatedArea() const
741 {
742 return FetchRectFromBounds(Get().rcPaint);
743 }
744
745
746 WindowClass::WindowClass(const wchar_t* class_name, ::WNDPROC wnd_proc,
747 unsigned style, ::HBRUSH h_bg, ::HINSTANCE h_inst)
748 // NOTE: Intentionally no %CS_OWNDC or %CS_CLASSDC, so %::ReleaseDC
749 // is always needed.
750 : WindowClass(::WNDCLASSW{style, wnd_proc ? wnd_proc
751 : HostWindow::WindowProcedure, 0, 0, h_inst
752 ? h_inst : ::GetModuleHandleW({}), ::LoadIconW({}, IDI_APPLICATION),
753 ::LoadCursorW({}, IDC_ARROW), h_bg, nullptr, Nonnull(class_name)})
754 {}
755 WindowClass::WindowClass(const ::WNDCLASSW& wc)
756 : WindowClass(wc.lpszClassName, YCL_CallF_Win32(RegisterClassW, &wc),
757 wc.hInstance)
758 {}
759 WindowClass::WindowClass(const ::WNDCLASSEXW& wc)
760 : WindowClass(wc.lpszClassName, YCL_CallF_Win32(RegisterClassExW, &wc),
761 wc.hInstance)
762 {}
763 WindowClass::WindowClass(wstring_view class_name,
764 unsigned short class_atom, ::HINSTANCE h_inst)
765 : name((yunused(Nonnull(class_name.data())), class_name)), atom(class_atom),
766 h_instance(h_inst)
767 {
768 if(YB_UNLIKELY(atom == 0))
769 throw std::invalid_argument("Invalid atom value found.");
770 YTraceDe(Notice, "Window class '%s' of atom '%hu' registered.",
771 name.empty() ? "<unknown>" : WCSToUTF8(name).c_str(), atom);
772 }
773 WindowClass::~WindowClass()
774 {
775 ::UnregisterClassW(reinterpret_cast<const wchar_t*>(atom), h_instance);
776 FilterExceptions([this]{
777 YTraceDe(Notice, "Window class '%s' of atom '%hu' unregistered.",
778 name.empty() ? "<unknown>" : WCSToUTF8(name).c_str(), atom);
779 }, yfsig);
780 }
781 # endif
782
783
784 HostWindow::HostWindow(NativeWindowHandle h)
785 : WindowReference(Nonnull(h))
786 # if YCL_HostedUI_XCB
787 , WM_PROTOCOLS(platform::Deref(h).LookupAtom("WM_PROTOCOLS"))
788 , WM_DELETE_WINDOW(platform::Deref(h).LookupAtom("WM_DELETE_WINDOW"))
789 # endif
790 # if YCL_HostedUI_XCB || YCL_Win32
791 , MessageMap()
792 # endif
793 {
794 # if YCL_HostedUI_XCB
795 platform::Deref(h).GetConnectionRef().Check();
796 # elif YCL_Win32
797 YAssert(::IsWindow(h), "Invalid window handle found.");
798 YAssert(::GetWindowThreadProcessId(h, {}) == ::GetCurrentThreadId(),
799 "Window not created on current thread found.");
800 YAssert(::GetWindowLongPtrW(h, GWLP_USERDATA) == 0,
801 "Invalid user data of window found.");
802
803 wchar_t buf[size(WindowClassName)];
804
805 YCL_CallF_Win32(GetClassNameW, GetNativeHandle(), buf,
806 int(size(WindowClassName)));
807 if(std::wcscmp(buf, WindowClassName) != 0)
808 throw GeneralEvent("Wrong windows class name found.");
809 ::SetLastError(0);
810 if(YB_UNLIKELY(::SetWindowLongPtrW(GetNativeHandle(), GWLP_USERDATA,
811 ::LONG_PTR(this)) == 0 && GetLastError() != 0))
812 YCL_Raise_Win32E("SetWindowLongPtrW", yfsig);
813 YCL_CallF_Win32(SetWindowPos, GetNativeHandle(), {}, 0, 0, 0, 0,
814 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW
815 | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
816
817 ::RAWINPUTDEVICE rid{0x01, 0x02, 0, nullptr};
818
819 YCL_CallF_Win32(RegisterRawInputDevices, &rid, 1, sizeof(rid));
820 MessageMap[WM_DESTROY] += []() ynothrow{
821 ::PostQuitMessage(0);
822 YTraceDe(Debug, "Host quit message posted.");
823 };
824 # elif YCL_Android
825 ::ANativeWindow_acquire(GetNativeHandle());
826 # endif
827 }
828
829 HostWindow::~HostWindow()
830 {
831 const unique_ptr_from<HostWindowDelete> p_wnd(GetNativeHandle());
832
833 # if YCL_Win32
834 // XXX: Error ignored.
835 ::SetWindowLongPtrW(p_wnd.get(), GWLP_USERDATA, ::LONG_PTR());
836 # endif
837 }
838
839 # if YCL_Win32
840 Point
841 HostWindow::MapPoint(const Point& pt) const
842 {
843 return pt;
844 }
845
846 ::LRESULT __stdcall
847 HostWindow::WindowProcedure(::HWND h_wnd, unsigned msg, ::WPARAM w_param,
848 ::LPARAM l_param) ynothrowv
849 {
850 if(const auto p = reinterpret_cast<HostWindow*>(
851 ::GetWindowLongPtrW(h_wnd, GWLP_USERDATA)))
852 {
853 auto& m(p->MessageMap);
854
855 try
856 {
857 const auto i(m.find(msg));
858
859 if(i != m.cend())
860 {
861 ::LRESULT res(0);
862
863 i->second(w_param, l_param, res);
864 return res;
865 }
866 }
867 CatchExpr(..., YTraceDe(Warning, "HostWindow::WindowPrecedure failed."))
868 }
869 return ::DefWindowProcW(h_wnd, msg, w_param, l_param);
870 }
871 # endif
872
873
874 WindowInputHost::WindowInputHost(HostWindow& wnd)
875 : Window(wnd)
876 # if YCL_Win32
877 , has_hosted_caret(::CreateCaret(wnd.GetNativeHandle(), {}, 1, 1))
878 # endif
879 {
880 # if YCL_Win32
881 auto& m(wnd.MessageMap);
882
883 yunseq(
884 m[WM_MOVE] += [this]{
885 UpdateCandidateWindowLocation();
886 },
887 m[WM_KILLFOCUS] += []{
888 ClearKeyStates();
889 },
890 m[WM_INPUT] += [this](::WPARAM, ::LPARAM l_param) ynothrow{
891 ::RAWINPUT ri;
892 unsigned size(sizeof(ri));
893
894 // TODO: Use '{}' to simplify initialization after CWG 1368 resolved by
895 // C++14. See $2015-09 @ %Documentation::Workflow.
896 ystdex::trivially_fill_n(&ri);
897 if(YB_LIKELY(::GetRawInputData(::HRAWINPUT(l_param), RID_INPUT, &ri,
898 &size, sizeof(::RAWINPUTHEADER)) != unsigned(-1) && ri.header.dwType
899 == RIM_TYPEMOUSE) && ri.data.mouse.usButtonFlags == RI_MOUSE_WHEEL)
900 // NOTE: This value is safe to cast because it is
901 // specified as a signed value, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645578(v=vs.85).aspx.
902 RawMouseButton = short(ri.data.mouse.usButtonData);
903 },
904 m[WM_CHAR] += [this](::WPARAM w_param, ::LPARAM l_param){
905 lock_guard<recursive_mutex> lck(input_mutex);
906 size_t n(l_param & 0x7FFF);
907
908 while(n-- != 0)
909 comp_str += char16_t(w_param);
910 },
911 m[WM_IME_COMPOSITION] += [this]{
912 UpdateCandidateWindowLocation();
913 }
914 );
915 ystdex::unseq_apply([&](int msg){
916 BindDefaultWindowProc(wnd.GetNativeHandle(), m, unsigned(msg));
917 }, WM_MOVE, WM_IME_COMPOSITION);
918 # endif
919 }
920 WindowInputHost::~WindowInputHost()
921 {
922 # if YCL_Win32
923 if(has_hosted_caret)
924 ::DestroyCaret();
925 # endif
926 }
927
928 # if YCL_Win32
929 void
930 WindowInputHost::UpdateCandidateWindowLocation()
931 {
932 lock_guard<recursive_mutex> lck(input_mutex);
933
934 UpdateCandidateWindowLocationUnlocked();
935 }
936 void
937 WindowInputHost::UpdateCandidateWindowLocation(const Point& pt)
938 {
939 if(pt != Point::Invalid)
940 {
941 lock_guard<recursive_mutex> lck(input_mutex);
942
943 caret_location = pt;
944 UpdateCandidateWindowLocationUnlocked();
945 }
946 }
947 void
948 WindowInputHost::UpdateCandidateWindowLocationUnlocked()
949 {
950 if(YB_LIKELY(caret_location != Point::Invalid))
951 {
952 YTraceDe(Informative, "Update composition form position: %s.",
953 to_string(caret_location).c_str());
954
955 const auto h_wnd(Nonnull(Window.GetNativeHandle()));
956
957 if(const auto h_imc = ::ImmGetContext(h_wnd))
958 {
959 // FIXME: Correct location?
960 const auto client_pt(caret_location + Window.GetClientLocation()
961 - Window.GetClientLocation());
962
963 ::CANDIDATEFORM cand_form{0, CFS_CANDIDATEPOS,
964 {client_pt.X, client_pt.Y}, {0, 0, 0, 0}};
965
966 // TODO: Error handling.
967 ::ImmSetCandidateWindow(h_imc, &cand_form);
968 ::ImmReleaseContext(h_wnd, h_imc);
969 }
970 // FIXME: Correct implementation for non-Chinese IME.
971 // NOTE: See comment on %IMM32Manager::MoveImeWindow in
972 // https://src.chromium.org/viewvc/chrome/trunk/src/ui/base/ime/win/imm32_manager.cc.
973 ::SetCaretPos(caret_location.X, caret_location.Y);
974 }
975 }
976 # endif
977
978
979 # if YCL_Win32
980 class Clipboard::Data : public GlobalLocked
981 {
982 using GlobalLocked::GlobalLocked;
983 };
984
985
986 Clipboard::Clipboard(NativeWindowHandle h_wnd)
987 {
988 // FIXME: Spin for remote desktops?
989 YCL_CallF_Win32(OpenClipboard, h_wnd);
990 }
991 Clipboard::~Clipboard()
992 {
993 YCL_TraceCallF_Win32(CloseClipboard, );
994 }
995
996 bool
997 Clipboard::IsAvailable(FormatType fmt) ynothrow
998 {
999 return bool(::IsClipboardFormatAvailable(fmt));
1000 }
1001
1002 void
1003 Clipboard::CheckAvailable(FormatType fmt)
1004 {
1005 YCL_CallF_Win32(IsClipboardFormatAvailable, fmt);
1006 }
1007
1008 void
1009 Clipboard::Clear() ynothrow
1010 {
1011 YCL_TraceCallF_Win32(EmptyClipboard, );
1012 }
1013
1014 NativeWindowHandle
1015 Clipboard::GetOpenWindow() ynothrow
1016 {
1017 return ::GetOpenClipboardWindow();
1018 }
1019
1020 bool
1021 Clipboard::Receive(YSLib::string& str)
1022 {
1023 return ReceiveRaw(CF_TEXT, [&](const Data& d) ynothrowv{
1024 str = d.GetPtr<char>().get();
1025 });
1026 }
1027 bool
1028 Clipboard::Receive(YSLib::String& str)
1029 {
1030 return ReceiveRaw(CF_UNICODETEXT, [&](const Data& d) ynothrowv{
1031 str = d.GetPtr<char16_t>().get();
1032 });
1033 }
1034
1035 bool
1036 Clipboard::ReceiveRaw(FormatType fmt, YSLib::function<void(const Data&)> f)
1037 {
1038 if(IsAvailable(fmt))
1039 if(const auto h = ::GetClipboardData(fmt))
1040 {
1041 const Data d(h);
1042
1043 Nonnull(f)(d);
1044 return true;
1045 }
1046 return {};
1047 }
1048
1049 void
1050 Clipboard::Send(string_view sv)
1051 {
1052 YAssertNonnull(sv.data());
1053 SendRaw(CF_TEXT, CopyGlobalString<char>(sv));
1054 }
1055 void
1056 Clipboard::Send(u16string_view sv)
1057 {
1058 YAssertNonnull(sv.data());
1059 SendRaw(CF_UNICODETEXT, CopyGlobalString<char16_t>(sv));
1060 }
1061 void
1062 Clipboard::Send(ConstBitmapPtr p_bmp, const Size& s)
1063 {
1064 YAssertNonnull(p_bmp),
1065 YAssert(s != Size::Invalid, "Invalid size found.");
1066
1067 auto p(MakeMoveableGlobalMemory(sizeof(::BITMAPV5HEADER)
1068 + GetAreaOf(s) * sizeof(Pixel)));
1069 {
1070 const GlobalLocked gl(Nonnull(p));
1071 const auto p_buf(gl.GetPtr<::BITMAPV5HEADER>().get());
1072
1073 *p_buf = {sizeof(::BITMAPV5HEADER), CheckPositive<long>(s.Width,
1074 "width"), -CheckPositive<long>(s.Height, "height"), 1, 32,
1075 BI_BITFIELDS, static_cast<unsigned long>(sizeof(Pixel)
1076 * GetAreaOf(s)), 0, 0, 0, 0, 0x00FF0000, 0x0000FF00, 0x000000FF,
1077 0xFF000000, 0x73524742/*LCS_sRGB*/, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}
1078 }, 0, 0, 0, LCS_GM_IMAGES, 0, 0, 0},
1079 CopyBitmapBuffer(ystdex::aligned_store_cast<Pixel*>(p_buf + 1), p_bmp,
1080 s);
1081 }
1082 SendRaw(CF_DIBV5, p.release());
1083 }
1084
1085 void
1086 Clipboard::SendRaw(FormatType fmt, void* h)
1087 {
1088 Clear();
1089 YCL_CallF_Win32(SetClipboardData, fmt, h);
1090 }
1091
1092
1093 void
1094 ExecuteShellCommand(const wchar_t* cmd, const wchar_t* args, bool use_admin,
1095 const wchar_t* dir, int n_cmd_show, NativeWindowHandle h_parent)
1096 {
1097 // TODO: Set current working directory as %USERPROFILE%?
1098 auto res(int(std::intptr_t(::ShellExecuteW(h_parent,
1099 use_admin ? L"runas" : nullptr, Nonnull(cmd), args, dir, n_cmd_show))));
1100
1101 switch(res)
1102 {
1103 case 0:
1104 case SE_ERR_OOM:
1105 // TODO: Use inherited class of exception.
1106 throw std::bad_alloc();
1107 case SE_ERR_SHARE:
1108 case SE_ERR_DLLNOTFOUND:
1109 res = SE_ERR_SHARE ? ERROR_SHARING_VIOLATION : ERROR_DLL_NOT_FOUND;
1110 YB_ATTR_fallthrough;
1111 case ERROR_FILE_NOT_FOUND: // NOTE: Same as %SE_ERR_FNF.
1112 case ERROR_PATH_NOT_FOUND: // NOTE: Same as %SE_ERR_PNF.
1113 case ERROR_ACCESS_DENIED: // NOTE: Same as %SE_ERR_ACCESSDENIED.
1114 case ERROR_BAD_FORMAT:
1115 throw Win32Exception(ErrorCode(res), "ShellExecuteW", Err);
1116 case SE_ERR_ASSOCINCOMPLETE:
1117 case SE_ERR_NOASSOC:
1118 case SE_ERR_DDETIMEOUT:
1119 case SE_ERR_DDEFAIL:
1120 case SE_ERR_DDEBUSY:
1121 {
1122 using boxed_exception
1123 = ystdex::wrap_mixin_t<std::runtime_error, int>;
1124
1125 TryExpr(throw
1126 boxed_exception{std::runtime_error("ShellExecuteW"), res})
1127 catch(boxed_exception& e)
1128 {
1129 const auto throw_ex([=](int ec) YB_ATTR(noreturn){
1130 std::throw_with_nested(Win32Exception(ErrorCode(ec),
1131 ystdex::sfmt("ShellExecuteW: %d", res), Err));
1132 });
1133
1134 switch(e.value)
1135 {
1136 case SE_ERR_ASSOCINCOMPLETE:
1137 case SE_ERR_NOASSOC:
1138 throw_ex(ERROR_NO_ASSOCIATION);
1139 case SE_ERR_DDETIMEOUT:
1140 case SE_ERR_DDEFAIL:
1141 case SE_ERR_DDEBUSY:
1142 throw_ex(ERROR_DDE_FAIL);
1143 default:
1144 break;
1145 }
1146 }
1147 YAssert(false, "Invalid state found.");
1148 }
1149 YB_ATTR_fallthrough;
1150 default:
1151 if(res > 32)
1152 YTraceDe(Informative, "ExecuteShellCommand: ::ShellExecute call"
1153 " succeed with return value %d.", res);
1154 else
1155 throw LoggedEvent(ystdex::sfmt("ExecuteShellCommand:"
1156 " ::ShellExecuteW call failed" " with unknown error '%d'.",
1157 res), Err);
1158 }
1159 }
1160 # endif
1161
1162 } // namespace platform_ex;
1163
1164 #endif
1165
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
YSLib::swap
void swap(ValueNode &x, ValueNode &y) ynothrowv
Definition: ValueNode.cpp:95
platform::Nonnull
YB_PURE _type && Nonnull(_type &&p) ynothrowv
断言并返回非空参数。
Definition: Debug.h:518
size
size_t size
Definition: memory_resource.cpp:295
ystdex::cpp2017::swap
void swap(optional< _type > &x, optional< _type > &y)
Definition: optional.h:888
YSLib::UI::ynothrow
AView &y ynothrow
Definition: YWidgetView.cpp:47
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:536
YSLib::PostQuitMessage
YF_API void PostQuitMessage(int=0, Messaging::Priority p=DefaultQuitPriority)
以指定错误码和优先级发起 Shell 终止请求。
Definition: YApplication.cpp:87
YCL_HostedUI_XCB
#define YCL_HostedUI_XCB
在宿主用户界面使用 X C 绑定。
Definition: Platform.h:392
platform_ex::Windows::GlobalDelete
全局存储删除器。
Definition: Win32/include/YCLib/MinGW32.h:311
platform::references::unique_ptr_from
unique_ptr< ystdex::defer_element< ystdex::unique_ptr_pointer< void, _tDeleter >, _tDefault >, _tDeleter > unique_ptr_from
取删除器对应的 unique_ptr 实例。
Definition: Reference.h:110
ystdex::cpp2017::basic_string
Definition: string.hpp:77
platform_ex
平台扩展命名空间。
Definition: Android.h:46
mixin.hpp
基于类继承的混入接口。
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
ystdex::unseq_apply
void unseq_apply(_func &&f, _tParams &&... args)
无序调用。
Definition: function.hpp:314
YSLib::Drawing::x
const TextState &ts const TextState &ts const TextState &ts TextState SPos x
Definition: TextBase.h:190
YSLib::Drawing::GGraphics::Height
const SizeType sGraphics Height
Definition: YGraphics.h:136
yfsig
#define yfsig
展开为表示函数签名的预定义变量的宏。
Definition: ydef.h:1133
ystdex::cpp2017::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:437
DefDeMoveCtor
#define DefDeMoveCtor(_t)
Definition: YBaseMacro.h:167
ystdex::cpp2017::wstring_view
basic_string_view< wchar_t > wstring_view
Definition: string_view.hpp:440
ystdex::trivially_fill_n
_type * trivially_fill_n(_type *first, size_t n=1, byte value={})
填充字节序列。
Definition: algorithm.hpp:444
YSLib::IO::int
YF_API int
Definition: File.h:51
platform::if
if(!p) p
CHRLib::d
_tDst * d
Definition: CharacterProcessing.h:142
YSLib::Drawing::GBinaryGroup< SPos >::Invalid
static const GBinaryGroup Invalid
无效（不在屏幕坐标系中）对象。
Definition: YGDIBase.h:298
YCL_Raise_Win32E
#define YCL_Raise_Win32E(...)
取转换为 errno 的 Win32 错误。
Definition: Win32/include/YCLib/MinGW32.h:147
YB_ATTR_fallthrough
#define YB_ATTR_fallthrough
用于 switch 语句的 fallthrough 属性。
Definition: ydef.h:655
YSLib::GeneralEvent
std::runtime_error GeneralEvent
一般运行时异常事件类。
Definition: YException.h:46
ystdex::mixin
混入对象。
Definition: mixin.hpp:46
YSLib::UI::Move
@ Move
移动：位置调整。
Definition: YWidgetEvent.h:381
platform_ex::Windows::WCSToUTF8
const char *str string_view sv WCSToUTF8
Definition: NLS.h:79
YSLib::Drawing::sp
dst sp
Definition: YGDI.h:442
CHRLib::f
f(d, s)
YModules.h
YSLib 服务模块配置文件。
YSLib::UI::ImplDeDtor
ImplDeDtor(Thumb) void DecorateAsCloseButton(Thumb &tmb)
Definition: Button.cpp:125
YSLib::Drawing::Size::Invalid
static const Size Invalid
无效对象。
Definition: YGDIBase.h:542
YSLib::Drawing::g
The boundary is out of the const Graphics & g
Definition: YDraw.h:161
YSLib::UI::Window
窗口。
Definition: YWindow.h:45
ystdex::default_init
const struct ystdex::default_init_t default_init
ystdex::unimplemented
异常：未实现的操作。
Definition: ystdex/exception.h:135
platform_ex::ClearKeyStates
YF_API void ClearKeyStates()
清除按键缓冲。
Definition: Input.cpp:159
NPL::LexemeCategory::Data
@ Data
数据字面量。
YSLib::UI::Invalidate
YF_API void Invalidate(IWidget &, const Rect &)
无效化：使相对部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.cpp:108
YSLib::UI::args
yconstfn const string _tParams && args
Definition: Loader.h:131
YB_ATTR_returns_nonnull
#define YB_ATTR_returns_nonnull
指示返回非空属性。
Definition: ydef.h:761
YSLib::EventPriority
std::uint8_t EventPriority
事件优先级。
Definition: YEvent.hpp:396
platform_ex::Windows::h_parent
YF_API const wchar_t ::HKEY h_parent
Definition: Registry.h:128
YSLib::UI::Show
YF_API void Show(IWidget &)
显示部件。
Definition: YWidget.cpp:202
YB_ALLOCATOR
#define YB_ALLOCATOR
指示返回指针的函数或函数模板若为非空值则对应的存储不和其它对象指针共享别名。
Definition: ydef.h:785
ystdex::unique_raw
std::unique_ptr< _type > unique_raw(_pSrc *p)
Definition: memory.hpp:645
YSLib::YAssert
YAssert(!(v< Deref(a)), "Value less than lower bound found.")
YSLib::LoggedEvent
记录日志的异常事件类。
Definition: YException.h:51
YSLib::IO::_tString
const string &path const String &path class class class _tString
Definition: YSLib/Service/FileSystem.h:612
YSLib::Drawing::GGraphics
二维图形接口上下文模板。
Definition: YGraphics.h:63
ystdex::threading::lock_guard
Definition: pseudo_mutex.h:223
ystdex::cpp2017::data
auto data(_tRange &c) -> decltype(c.data())
Definition: range.hpp:581
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:47
platform::Descriptions::Notice
@ Notice
Definition: YCommon.h:184
platform::Descriptions::Informative
@ Informative
Definition: YCommon.h:185
YSLib::UI::name
yconstfn const string & name
Definition: Loader.h:130
YB_ATTR
#define YB_ATTR(...)
GNU 风格属性。
Definition: ydef.h:567
ystdex::sfmt
_tString sfmt(const typename string_traits< _tString >::value_type *fmt,...)
以 C 标准输出格式的输出 basic_string 实例的对象。
Definition: string.hpp:2028
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:165
YSLib::UI::bool
IWidget bool b bool
Definition: YControl.h:122
YSLib::Drawing::GBinaryGroup< SPos >
YSLib::i
return i
Definition: YCoreUtilities.h:177
YSLib::Drawing::GetSize
dst GetSize()
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1535
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:407
YSLib::FilterExceptions
bool FilterExceptions(_func f, const char *desc={}, RecordLevel lv=Alert, ExceptionTracer trace=ExtractAndTrace) ynothrow
调用函数并过滤宿主异常。
Definition: YException.h:225
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:44
platform::Descriptions::Err
@ Err
Definition: YCommon.h:182
YSLib::UI::Close
void Close(IWidget &wgt)
Definition: YWidget.cpp:92
YSLib::Drawing::CompactPixmap
标准矩形像素图缓冲区。
Definition: YGDI.h:233
YCL_CallF_Win32
#define YCL_CallF_Win32(_fn,...)
Definition: Win32/include/YCLib/MinGW32.h:199
YSLib::UI::Resize
@ Resize
大小调整。
Definition: YWidgetEvent.h:383
platform::KeyCodes::DS::L
@ L
Definition: Keys.h:228
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
YSLib::Drawing::GBinaryGroup::X
_type X
分量。
Definition: YGDIBase.h:305
ystdex::to_string
std::string to_string(const std::thread::id &)
转换 thread::id 为字符串表示。
platform::Descriptions::Warning
@ Warning
Definition: YCommon.h:183
YSLib::Drawing::AlphaType
octet AlphaType
Alpha 分量类型。
Definition: YGDIBase.h:49
YSLib::UI::e
void e
Definition: YWidget.h:356
CatchExpr
#define CatchExpr(_ex,...)
指定表达式作为异常处理器。
Definition: YBaseMacro.h:129
YSLib::Drawing::CopyLine
扫描线：按指定扫描顺序复制一行像素。
Definition: YBlit.h:444
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:788
ystdex::cpp2017::u16string_view
basic_string_view< char16_t > u16string_view
Definition: string_view.hpp:438
platform
默认平台命名空间。
Definition: Container.h:56
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
ystdex::pvoid
enable_if_t< or_< is_object< _type >, is_void< _type > >::value, void * > pvoid(_type *p)
取 void* 类型的指针。
Definition: addressof.hpp:166
exception.h
标准库异常扩展接口。
YB_LIKELY
#define YB_LIKELY(_expr)
Definition: ydef.h:827
YSLib::str
const char * str
Definition: YException.cpp:60
YCL_TraceCallF_Win32
#define YCL_TraceCallF_Win32(_fn,...)
Definition: Win32/include/YCLib/MinGW32.h:220
YSLib::ynothrow
YB_PURE const _type size_t n ynothrow
Definition: YCoreUtilities.h:169
YSLib::Drawing::ynothrow
YB_ATTR_nodiscard yconstfn YB_PURE x x x Bottom YB_ATTR_nodiscard yconstfn YB_PURE x Right y x Top y x Bottom y Bottom YB_ATTR_nodiscard yconstfn YB_PURE x Right y x Top y x Bottom y Bottom YB_ATTR_nodiscard yconstfn YB_PURE const Padding & ynothrow
Definition: YGDI.h:132
platform::Deref
YB_PURE yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:547
YSLib::Drawing::CopyBitmapBuffer
void CopyBitmapBuffer(_tOut p_dst, _tIn p_src, const Size &s)
Definition: YGraphics.h:50
CHRLib::char16_t
YB_ATTR_nodiscard YB_PURE char16_t((*c_ptr<< CHAR_BIT)|c_ptr[1])) YB_ATTR_nodiscard YB_PURE inline PDefH(char16_t
取 c_ptr 指向的小端序双字节字符。
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
YSLib::Text::buf
YB_ATTR_nodiscard YB_PURE const char * buf
Definition: TextFile.h:83
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
YSLib::Drawing::w
The boundary is out of the const Rect SDst w
Definition: YDraw.h:127
YModules.h
YCLib 库模块配置文件。
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
Definition: Dependency.h:140
ystdex::ntctscpy
enable_if_irreplaceable_char_t< _tChar, _tChar * > ntctscpy(_tChar *s1, const _tChar *s2)
复制 NTCTS 。
Definition: cstring.h:250
YSLib::Drawing::GBinaryGroup::Y
_type Y
Definition: YGDIBase.h:305
YSLib::Drawing::ConstBitmapPtr
const Pixel * ConstBitmapPtr
Definition: YGraphics.h:44
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:828
platform::p
return p p
Definition: YCLib/FileSystem.h:209
ystdex::function
function_base< function_traits< _fSig, empty_function_policy::throwing >, _fSig > function
函数包装类模板。
Definition: function.hpp:900
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:43
ystdex::cpp2017::string
basic_string< char > string
Definition: string.hpp:772
YSLib::Drawing::BitmapPtr
Pixel * BitmapPtr
Definition: YGraphics.h:42
YSLib::Drawing::GetHeight
YB_ATTR_nodiscard YB_PURE tr GetHeight())) inline PDefH(void
按字体高度和行距调整文本区域的底边距。
platform_ex::Windows::ErrorCode
unsigned long ErrorCode
Definition: Win32/include/YCLib/MinGW32.h:58
platform_ex::Windows::GlobalLocked
全局锁定存储。
Definition: Win32/include/YCLib/MinGW32.h:321
TryExpr
#define TryExpr(...)
指定表达式在 try 块中求值。
Definition: YBaseMacro.h:120
YSLib::UI::IsVisible
IsVisible
Definition: YWidget.h:101
yunused
#define yunused(...)
标记未使用的表达式。
Definition: ydef.h:1458
ystdex::is_aligned_storable
判断是否可对齐存储。
Definition: type_pun.hpp:74
NPL::get
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(NPL ref get()
Definition: NPLA.h:1737
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:168
platform::Descriptions::Debug
@ Debug
Definition: YCommon.h:186