YSTest: HostedGUI.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

HostedGUI.cpp
浏览该文件的文档.
1 /*
2 © 2013-2016 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::CheckPositiveScalar,
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 ClearKeyStates;
40 # include "YSLib/Service/YModules.h"
41 # include YFM_YSLib_Service_YBlit // for ystdex::pvoid, YSLib::BlitLines;
42 # include <Shellapi.h> // for ::ShellExecuteW;
43 # include <ystdex/mixin.hpp> // for ystdex::wrap_mixin_t;
44 #elif YCL_Android
45 # include YFM_Android_YCLib_Android
46 # include <android/native_window.h>
47 # include "YSLib/Service/YModules.h"
48 # include YFM_YSLib_Service_YBlit // for YSLib::BlitLines;
49 #endif
50 #if YCL_HostedUI_XCB || YCL_Android
51 # include "YSLib/Service/YModules.h"
52 # include YFM_YSLib_Service_YGDI
53 #endif
54
55 using namespace YSLib;
56 using namespace Drawing;
58 using YSLib::string;
60 using platform::string_view;
61
62 #if YF_Hosted
63
64 namespace platform_ex
65 {
66
67 void
68 HostWindowDelete::operator()(pointer p) const ynothrow
69 {
70 # if YCL_HostedUI_XCB
71 default_delete<XCB::WindowData>()(p.get());
72 # elif YCL_Win32
73 // NOTE: The window could be already destroyed in window procedure.
74 if(::IsWindow(p))
75 // XXX: Error ignored.
76 ::DestroyWindow(p);
77 # elif YCL_Android
78 // XXX: Error ignored.
79 ::ANativeWindow_release(p);
80 # endif
81 }
82
83
84 # if YCL_Win32
85 void
86 GDIObjectDelete::operator()(pointer h) const ynothrow
87 {
88 static_assert(std::is_same<pointer, ::HGDIOBJ>::value,
89 "Mismatched type found.");
90
91 YCL_CallWin32F_Trace(DeleteObject, h);
92 }
93 # endif
94
95 namespace
96 {
97
98 # if YCL_HostedUI_XCB || YCL_Android
99 SDst
101 CheckStride(SDst buf_stride, SDst w)
102 {
103 if(buf_stride < w)
104 // XXX: Use more specified exception type.
105 throw std::runtime_error("Stride is small than width.");
106 return buf_stride;
107 }
108 # elif YCL_Win32
109 void
111 MoveWindow(::HWND h_wnd, SPos x, SPos y)
112 {
113 YCL_CallWin32F(SetWindowPos, h_wnd, {}, x, y, 0, 0, SWP_ASYNCWINDOWPOS
114 | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING
115 | SWP_NOSIZE | SWP_NOZORDER);
116 }
117
119 void
120 ResizeWindow(::HWND h_wnd, SDst w, SDst h)
121 {
122 YCL_CallWin32F(SetWindowPos, h_wnd, {}, 0, 0, int(w), int(h),
123 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER
124 | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
125 }
126
128 ::RECT
129 FetchWindowRect(::HWND h_wnd)
130 {
131 ::RECT rect;
132
133 YCL_CallWin32F(GetWindowRect, h_wnd, &rect);
134 return rect;
135 }
136
138
139 Size
140 FetchSizeFromBounds(const ::RECT& rect)
141 {
142 return {CheckScalar<SDst>(rect.right - rect.left, "width"),
143 CheckScalar<SDst>(rect.bottom - rect.top, "height")};
144 }
145
147 Rect
148 FetchRectFromBounds(const ::RECT& rect)
149 {
150 return {rect.left, rect.top, FetchSizeFromBounds(rect)};
151 }
152
154 inline WindowStyle
155 FetchWindowStyle(::HWND h_wnd)
156 {
157 return WindowStyle(::GetWindowLongW(h_wnd, GWL_STYLE));
158 }
159
160 void
161 AdjustWindowBounds(::RECT& rect, ::HWND h_wnd, bool b_menu = false)
162 {
163 YCL_CallWin32F(AdjustWindowRect, &rect, FetchWindowStyle(h_wnd), b_menu);
164 YAssert(rect.right - rect.left >= 0 && rect.bottom - rect.top >= 0,
165 "Invalid boundary found.");
166 }
167
169 void
170 SetWindowBounds(::HWND h_wnd, int x, int y, SDst w, SDst h)
171 {
172 YCL_CallWin32F(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().get())
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_CallWin32F(ClientToScreen, GetNativeHandle(), &point);
265 return {point.x, point.y};
266 }
267 Size
268 WindowReference::GetClientSize() const
269 {
270 ::RECT rect;
271
272 YCL_CallWin32F(GetClientRect, GetNativeHandle(), &rect);
273 return {rect.right, rect.bottom};
274 }
275 Point
276 WindowReference::GetCursorLocation() const
277 {
278 ::POINT cursor;
279
280 YCL_CallWin32F(GetCursorPos, &cursor);
281 YCL_CallWin32F(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 byte a;
295
296 YCL_CallWin32F(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, CheckScalar<SPos>(r.GetRight(), "width"),
314 CheckScalar<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_CallWin32F(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_CallWin32F(SetWindowTextW, GetNativeHandle(), str);
340 }
341
342 void
343 WindowReference::Close()
344 {
345 YTraceDe(Debug, "Closing window reference '%p'...", ystdex::pvoid(this));
346 YCL_CallWin32F(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_CallWin32F(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, CheckScalar<SPos>(s.Width, "width"),
383 CheckScalar<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 CheckPositiveScalar<SDst>(
401 ::ANativeWindow_getWidth(GetNativeHandle()), "width");
402 }
403 SDst
404 WindowReference::GetHeight() const
405 {
406 return CheckPositiveScalar<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.get()), r, g);
417 }
418 # elif YCL_Win32
419 YF_API ::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), CheckPositiveScalar<long>(
431 s.Width, "width"), -CheckPositiveScalar<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_CallWin32F(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, CheckScalar<SPos>(s.Width, "width"),
453 CheckScalar<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);
486
487 DefDeMoveCtor(ScreenBufferData)
488 };
489
490 ScreenBufferData::ScreenBufferData(const Size& s, SDst buf_stride)
491 : CompactPixmap({}, CheckStride(buf_stride, s.Width), s.Height)
492 {}
493 # endif
494
495
496 # if YCL_HostedUI_XCB || YCL_Android
497 ScreenBuffer::ScreenBuffer(const Size& s)
498 : ScreenBuffer(s, s.Width)
499 {}
500 ScreenBuffer::ScreenBuffer(const Size& s, SDst buf_stride)
501 : p_impl(new ScreenBufferData(s, buf_stride)), width(s.Width)
502 {}
503 ScreenBuffer::ScreenBuffer(ScreenBuffer&& sbuf) ynothrow
504 : p_impl(new ScreenBufferData(std::move(*sbuf.p_impl))), width(sbuf.width)
505 {
506 sbuf.width = 0;
507 }
508 # elif YCL_Win32
509 ScreenBuffer::ScreenBuffer(const Size& s)
510 : size(s), p_bitmap(CreateCompatibleDIBSection(s, p_buffer))
511 {}
512 ScreenBuffer::ScreenBuffer(ScreenBuffer&&) ynothrow = default;
513 # endif
514 ImplDeDtor(ScreenBuffer)
515
516 ScreenBuffer&
517 ScreenBuffer::operator=(ScreenBuffer&& sbuf) ynothrow
518 {
519 sbuf.swap(*this);
520 return *this;
521 }
522
523 # if YCL_HostedUI_XCB || YCL_Android
524 BitmapPtr
525 ScreenBuffer::GetBufferPtr() const ynothrow
526 {
527 return Deref(p_impl).GetBufferPtr();
528 }
529 YSLib::Drawing::Graphics
530 ScreenBuffer::GetContext() const ynothrow
531 {
532 return Deref(p_impl).GetContext();
533 }
534 Size
535 ScreenBuffer::GetSize() const ynothrow
536 {
537 return {width, Deref(p_impl).GetHeight()};
538 }
539 YSLib::SDst
540 ScreenBuffer::GetStride() const ynothrow
541 {
542 return Deref(p_impl).GetWidth();
543 }
544
545 void
546 ScreenBuffer::Resize(const Size& s)
547 {
548 // TODO: Expand stride for given width using a proper strategy.
549 Deref(p_impl).SetSize(s);
550 width = s.Width;
551 }
552 # elif YCL_Win32
553 void
554 ScreenBuffer::Resize(const Size& s)
555 {
556 if(s != size)
557 *this = ScreenBuffer(s);
558 }
559
560 void
561 ScreenBuffer::Premultiply(ConstBitmapPtr p_buf) ynothrow
562 {
563 YAssertNonnull(p_buf);
564 // NOTE: Since the stride is guaranteed equal to the width, the storage for
565 // pixels can be supposed to be contiguous.
566 std::transform(p_buf, p_buf + size.Width * size.Height, p_buffer,
567 [](const Pixel& pixel) ynothrow{
568 const auto a(pixel.GetA());
569
570 return Pixel{MonoType(pixel.GetB() * a / 0xFF),
571 MonoType(pixel.GetG() * a / 0xFF),
572 MonoType(pixel.GetR() * a / 0xFF), a};
573 });
574 }
575 # endif
576
577 void
578 ScreenBuffer::UpdateFrom(ConstBitmapPtr p_buf) ynothrow
579 {
580 # if YCL_HostedUI_XCB || YCL_Android
581 // TODO: Expand stride for given width using a proper strategy.
582 CopyBitmapBuffer(Deref(p_impl).GetBufferPtr(), p_buf, GetSize());
583 # elif YCL_Win32
584 // NOTE: Since the pitch is guaranteed equal to the width, the storage for
585 // pixels can be supposed to be contiguous.
586 CopyBitmapBuffer(GetBufferPtr(), p_buf, size);
587 # endif
588 }
589
590 # if YCL_Win32
591 void
592 ScreenBuffer::UpdateFromBounds(ConstBitmapPtr p_buf, const Rect& r) ynothrow
593 {
594 BlitLines<false, false>(CopyLine<true>(), GetBufferPtr(), Nonnull(p_buf),
595 size, size, r.GetPoint(), r.GetPoint(), r.GetSize());
596 }
597
598 void
599 ScreenBuffer::UpdatePremultipliedTo(NativeWindowHandle h_wnd, AlphaType a,
600 const Point& pt)
601 {
602 GSurface<> sf(h_wnd);
603
604 sf.UpdatePremultiplied(*this, h_wnd, a, pt);
605 }
606 # endif
607
608 void
609 ScreenBuffer::UpdateTo(NativeWindowHandle h_wnd, const Point& pt) ynothrow
610 {
611 # if YCL_HostedUI_XCB || YCL_Android
612 UpdateContentTo(h_wnd, {pt, GetSize()}, GetContext());
613 # elif YCL_Win32
614 GSurface<> sf(h_wnd);
615
616 sf.Update(*this, pt);
617 # endif
618 }
619 #if YCL_Win32
620 void
621 ScreenBuffer::UpdateToBounds(NativeWindowHandle h_wnd, const Rect& r,
622 const Point& sp) ynothrow
623 {
624 GSurface<> sf(h_wnd);
625
626 sf.UpdateBounds(*this, r, sp);
627 }
628 #endif
629
630 void
631 ScreenBuffer::swap(ScreenBuffer& sbuf) ynothrow
632 {
633 # if YCL_HostedUI_XCB || YCL_Android
634 Deref(p_impl).swap(Deref(sbuf.p_impl)),
635 std::swap(width, sbuf.width);
636 # elif YCL_Win32
637 std::swap(size, sbuf.size),
638 std::swap(p_buffer, sbuf.p_buffer),
639 std::swap(p_bitmap, sbuf.p_bitmap);
640 # endif
641 }
642
643
644 # if YCL_Win32
645 WindowMemorySurface::WindowMemorySurface(::HDC h_dc)
646 : h_owner_dc(h_dc), h_mem_dc(::CreateCompatibleDC(h_dc))
647 {}
648 WindowMemorySurface::~WindowMemorySurface()
649 {
650 ::DeleteDC(h_mem_dc);
651 }
652
653 void
654 WindowMemorySurface::Update(ScreenBuffer& sbuf, const Point& pt) ynothrow
655 {
656 UpdateBounds(sbuf, {pt, sbuf.GetSize()});
657 }
658
659 void
660 WindowMemorySurface::UpdateBounds(ScreenBuffer& sbuf, const Rect& r,
661 const Point& sp) ynothrow
662 {
663 const auto h_old(::SelectObject(h_mem_dc, sbuf.GetNativeHandle()));
664
665 YCL_CallWin32F_Trace(BitBlt, h_owner_dc, int(r.X), int(r.Y), int(r.Width),
666 int(r.Height), h_mem_dc, int(sp.X), int(sp.Y), SRCCOPY);
667 // XXX: Error ignored?
668 ::SelectObject(h_mem_dc, h_old);
669 }
670
671 void
672 WindowMemorySurface::UpdatePremultiplied(ScreenBuffer& sbuf,
673 NativeWindowHandle h_wnd, YSLib::Drawing::AlphaType a, const Point& pt)
674 ynothrow
675 {
676 const auto h_old(::SelectObject(h_mem_dc, sbuf.GetNativeHandle()));
677 auto rect(FetchWindowRect(h_wnd));
678 ::SIZE size{rect.right - rect.left, rect.bottom - rect.top};
679 ::POINT ptx{pt.X, pt.Y};
680 ::BLENDFUNCTION bfunc{AC_SRC_OVER, 0, a, AC_SRC_ALPHA};
681
682 YCL_CallWin32F_Trace(UpdateLayeredWindow, h_wnd, h_owner_dc,
683 ystdex::aligned_store_cast<::POINT*>(&rect), &size, h_mem_dc, &ptx, 0,
684 &bfunc, ULW_ALPHA);
685 ::SelectObject(h_mem_dc, h_old);
686 }
687
688
689 WindowDeviceContext::WindowDeviceContext(NativeWindowHandle h_wnd)
690 // NOTE: Painting using %::GetDC and manually managing clipping areas
691 // instead of %::GetDCEx, for performance and convenience calculation
692 // of input boundary.
693 : WindowDeviceContextBase(h_wnd, ::GetDC(h_wnd))
694 {}
695 WindowDeviceContext::~WindowDeviceContext()
696 {
697 ::ReleaseDC(hWindow, hDC);
698 }
699
700
701 WindowRegionDeviceContext::WindowRegionDeviceContext(NativeWindowHandle h_wnd)
702 : WindowDeviceContextBase(h_wnd,
703 ::BeginPaint(h_wnd, ystdex::aligned_store_cast<::PAINTSTRUCT*>(&ps)))
704 {}
705 WindowRegionDeviceContext::~WindowRegionDeviceContext()
706 {
707 ::EndPaint(hWindow, ystdex::aligned_store_cast<::PAINTSTRUCT*>(&ps));
708 }
709
710 Rect
711 WindowRegionDeviceContext::GetInvalidatedArea() const
712 {
713 return FetchRectFromBounds(
714 ystdex::aligned_store_cast<const ::PAINTSTRUCT&>(ps).rcPaint);
715 }
716
717
718 WindowClass::WindowClass(const wchar_t* class_name, ::WNDPROC wnd_proc,
719 unsigned style, ::HBRUSH h_bg, ::HINSTANCE h_inst)
720 // NOTE: Intentionally no %CS_OWNDC or %CS_CLASSDC, so %::ReleaseDC
721 // is always needed.
722 : WindowClass(::WNDCLASSW{style, wnd_proc ? wnd_proc
723 : HostWindow::WindowProcedure, 0, 0, h_inst
724 ? h_inst : ::GetModuleHandleW({}), ::LoadIconW({}, IDI_APPLICATION),
725 ::LoadCursorW({}, IDC_ARROW), h_bg, nullptr, Nonnull(class_name)})
726 {}
727 WindowClass::WindowClass(const ::WNDCLASSW& wc)
728 : WindowClass(wc.lpszClassName, YCL_CallWin32F(RegisterClassW, &wc),
729 wc.hInstance)
730 {}
731 WindowClass::WindowClass(const ::WNDCLASSEXW& wc)
732 : WindowClass(wc.lpszClassName, YCL_CallWin32F(RegisterClassExW, &wc),
733 wc.hInstance)
734 {}
735 WindowClass::WindowClass(wstring_view class_name,
736 unsigned short class_atom, ::HINSTANCE h_inst)
737 : name((Nonnull(class_name.data()), class_name)), atom(class_atom),
738 h_instance(h_inst)
739 {
740 if(YB_UNLIKELY(atom == 0))
741 throw std::invalid_argument("Invalid atom value found.");
742 YTraceDe(Notice, "Window class '%s' of atom '%hu' registered.",
743 name.empty() ? "<unknown>" : WCSToUTF8(name).c_str(), atom);
744 }
745 WindowClass::~WindowClass()
746 {
747 ::UnregisterClassW(reinterpret_cast<const wchar_t*>(atom), h_instance);
748 FilterExceptions([this]{
749 YTraceDe(Notice, "Window class '%s' of atom '%hu' unregistered.",
750 name.empty() ? "<unknown>" : WCSToUTF8(name).c_str(), atom);
751 }, yfsig);
752 }
753 # endif
754
755
756 HostWindow::HostWindow(NativeWindowHandle h)
757 : WindowReference(h)
758 # if YCL_HostedUI_XCB
759 , WM_PROTOCOLS(platform::Deref(h.get()).LookupAtom("WM_PROTOCOLS"))
760 , WM_DELETE_WINDOW(h.get()->LookupAtom("WM_DELETE_WINDOW"))
761 # endif
762 # if YCL_HostedUI_XCB || YCL_Win32
763 , MessageMap()
764 # endif
765 {
766 # if YCL_HostedUI_XCB
767 h.get()->GetConnectionRef().Check();
768 # elif YCL_Win32
769 YAssert(::IsWindow(h), "Invalid window handle found.");
770 YAssert(::GetWindowThreadProcessId(h, {}) == ::GetCurrentThreadId(),
771 "Window not created on current thread found.");
772 YAssert(::GetWindowLongPtrW(h, GWLP_USERDATA) == 0,
773 "Invalid user data of window found.");
774
775 wchar_t buf[size(WindowClassName)];
776
777 YCL_CallWin32F(GetClassNameW, GetNativeHandle(), buf,
778 size(WindowClassName));
779 if(std::wcscmp(buf, WindowClassName) != 0)
780 throw GeneralEvent("Wrong windows class name found.");
781 ::SetLastError(0);
782 if(YB_UNLIKELY(::SetWindowLongPtrW(GetNativeHandle(), GWLP_USERDATA,
783 ::LONG_PTR(this)) == 0 && GetLastError() != 0))
784 YCL_Raise_Win32Exception("SetWindowLongPtrW");
785 YCL_CallWin32F(SetWindowPos, GetNativeHandle(), {}, 0, 0, 0, 0,
786 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW
787 | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
788
789 ::RAWINPUTDEVICE rid{0x01, 0x02, 0, nullptr};
790
791 YCL_CallWin32F(RegisterRawInputDevices, &rid, 1, sizeof(rid));
792 MessageMap[WM_DESTROY] += []() ynothrow{
793 ::PostQuitMessage(0);
794 YTraceDe(Debug, "Host quit message posted.");
795 };
796 # elif YCL_Android
797 ::ANativeWindow_acquire(GetNativeHandle());
798 # endif
799 }
800
801 HostWindow::~HostWindow()
802 {
803 const unique_ptr_from<HostWindowDelete> p_wnd(GetNativeHandle());
804
805 # if YCL_Win32
806 // XXX: Error ignored.
807 ::SetWindowLongPtrW(p_wnd.get(), GWLP_USERDATA, ::LONG_PTR());
808 # endif
809 }
810
811 # if YCL_Win32
812 Point
813 HostWindow::MapPoint(const Point& pt) const
814 {
815 return pt;
816 }
817
818 ::LRESULT __stdcall
819 HostWindow::WindowProcedure(::HWND h_wnd, unsigned msg, ::WPARAM w_param,
820 ::LPARAM l_param) ynothrowv
821 {
822 if(const auto p = reinterpret_cast<HostWindow*>(
823 ::GetWindowLongPtrW(h_wnd, GWLP_USERDATA)))
824 {
825 auto& m(p->MessageMap);
826
827 try
828 {
829 const auto i(m.find(msg));
830
831 if(i != m.cend())
832 {
833 ::LRESULT res(0);
834
835 i->second(w_param, l_param, res);
836 return res;
837 }
838 }
839 CatchExpr(..., YTraceDe(Warning, "HostWindow::WindowPrecedure failed."))
840 }
841 return ::DefWindowProcW(h_wnd, msg, w_param, l_param);
842 }
843 # endif
844
845
846 WindowInputHost::WindowInputHost(HostWindow& wnd)
847 : Window(wnd)
848 # if YCL_Win32
849 , has_hosted_caret(::CreateCaret(wnd.GetNativeHandle(), {}, 1, 1))
850 # endif
851 {
852 # if YCL_Win32
853 auto& m(wnd.MessageMap);
854
855 yunseq(
856 m[WM_MOVE] += [this]{
857 UpdateCandidateWindowLocation();
858 },
859 m[WM_KILLFOCUS] += []{
860 ClearKeyStates();
861 },
862 m[WM_INPUT] += [this](::WPARAM, ::LPARAM l_param) ynothrow{
863 ystdex::pun_storage_t<::RAWINPUT> buf;
864 unsigned size(sizeof(buf));
865
866 // TODO: Use '{}' to simplify after CWG 1368 resolved by C++14. See
867 // $2015-09 @ %Documentation::Workflow::Annual2015.
868 ystdex::trivially_fill_n(&buf);
869 if(YB_LIKELY(::GetRawInputData(::HRAWINPUT(l_param), RID_INPUT, &buf,
870 &size, sizeof(::RAWINPUTHEADER)) != unsigned(-1)))
871 {
872 const auto p_raw(ystdex::replace_cast<::RAWINPUT*>(&buf));
873
874 if(YB_LIKELY(p_raw->header.dwType == RIM_TYPEMOUSE))
875 {
876 if(p_raw->data.mouse.usButtonFlags == RI_MOUSE_WHEEL)
877 // NOTE: This value is safe to cast because it is
878 // specified as a signed value, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645578(v=vs.85).aspx.
879 RawMouseButton = short(p_raw->data.mouse.usButtonData);
880 }
881 }
882 },
883 m[WM_CHAR] += [this](::WPARAM w_param, ::LPARAM l_param){
884 lock_guard<recursive_mutex> lck(input_mutex);
885 size_t n(l_param & 0x7FFF);
886
887 while(n-- != 0)
888 comp_str += char16_t(w_param);
889 },
890 m[WM_IME_COMPOSITION] += [this]{
891 UpdateCandidateWindowLocation();
892 }
893 );
894 ystdex::unseq_apply([&](int msg){
895 BindDefaultWindowProc(wnd.GetNativeHandle(), m, unsigned(msg));
896 }, WM_MOVE, WM_IME_COMPOSITION);
897 # endif
898 }
899 WindowInputHost::~WindowInputHost()
900 {
901 # if YCL_Win32
902 if(has_hosted_caret)
903 ::DestroyCaret();
904 # endif
905 }
906
907 # if YCL_Win32
908 void
909 WindowInputHost::UpdateCandidateWindowLocation()
910 {
911 lock_guard<recursive_mutex> lck(input_mutex);
912
913 UpdateCandidateWindowLocationUnlocked();
914 }
915 void
916 WindowInputHost::UpdateCandidateWindowLocation(const Point& pt)
917 {
918 if(pt != Point::Invalid)
919 {
920 lock_guard<recursive_mutex> lck(input_mutex);
921
922 caret_location = pt;
923 UpdateCandidateWindowLocationUnlocked();
924 }
925 }
926 void
927 WindowInputHost::UpdateCandidateWindowLocationUnlocked()
928 {
929 if(YB_LIKELY(caret_location != Point::Invalid))
930 {
931 YTraceDe(Informative, "Update composition form position: %s.",
932 to_string(caret_location).c_str());
933
934 const auto h_wnd(Nonnull(Window.GetNativeHandle()));
935
936 if(const auto h_imc = ::ImmGetContext(h_wnd))
937 {
938 // FIXME: Correct location?
939 const auto client_pt(caret_location + Window.GetClientLocation()
940 - Window.GetClientLocation());
941
942 ::CANDIDATEFORM cand_form{0, CFS_CANDIDATEPOS,
943 {client_pt.X, client_pt.Y}, {0, 0, 0, 0}};
944
945 // TODO: Error handling.
946 ::ImmSetCandidateWindow(h_imc, &cand_form);
947 ::ImmReleaseContext(h_wnd, h_imc);
948 }
949 // FIXME: Correct implementation for non-Chinese IME.
950 // NOTE: See comment on %IMM32Manager::MoveImeWindow in
951 // https://src.chromium.org/viewvc/chrome/trunk/src/ui/base/ime/win/imm32_manager.cc.
952 ::SetCaretPos(caret_location.X, caret_location.Y);
953 }
954 }
955 # endif
956
957
958 # if YCL_Win32
959 class Clipboard::Data : public GlobalLocked
960 {
961 using GlobalLocked::GlobalLocked;
962 };
963
964
965 Clipboard::Clipboard(NativeWindowHandle h_wnd)
966 {
967 // FIXME: Spin for remote desktops?
968 YCL_CallWin32F(OpenClipboard, h_wnd);
969 }
970 Clipboard::~Clipboard()
971 {
972 YCL_CallWin32F_Trace(CloseClipboard, );
973 }
974
975 bool
976 Clipboard::IsAvailable(FormatType fmt) ynothrow
977 {
978 return bool(::IsClipboardFormatAvailable(fmt));
979 }
980
981 void
982 Clipboard::CheckAvailable(FormatType fmt)
983 {
984 YCL_CallWin32F(IsClipboardFormatAvailable, fmt);
985 }
986
987 void
988 Clipboard::Clear() ynothrow
989 {
990 YCL_CallWin32F_Trace(EmptyClipboard, );
991 }
992
993 NativeWindowHandle
994 Clipboard::GetOpenWindow() ynothrow
995 {
996 return ::GetOpenClipboardWindow();
997 }
998
999 bool
1000 Clipboard::Receive(YSLib::string& str)
1001 {
1002 return ReceiveRaw(CF_TEXT, [&](const Data& d) ynothrowv{
1003 str = d.GetPtr<char>().get();
1004 });
1005 }
1006 bool
1007 Clipboard::Receive(YSLib::String& str)
1008 {
1009 return ReceiveRaw(CF_UNICODETEXT, [&](const Data& d) ynothrowv{
1010 str = d.GetPtr<char16_t>().get();
1011 });
1012 }
1013
1014 bool
1015 Clipboard::ReceiveRaw(FormatType fmt, std::function<void(const Data&)> f)
1016 {
1017 if(IsAvailable(fmt))
1018 if(const auto h = ::GetClipboardData(fmt))
1019 {
1020 const Data d(h);
1021
1022 Nonnull(f)(d);
1023 return true;
1024 }
1025 return {};
1026 }
1027
1028 void
1029 Clipboard::Send(string_view sv)
1030 {
1031 YAssertNonnull(sv.data());
1032 SendRaw(CF_TEXT, CopyGlobalString<char>(sv));
1033 }
1034 void
1035 Clipboard::Send(u16string_view sv)
1036 {
1037 YAssertNonnull(sv.data());
1038 SendRaw(CF_UNICODETEXT, CopyGlobalString<char16_t>(sv));
1039 }
1040 void
1041 Clipboard::Send(ConstBitmapPtr p_bmp, const Size& s)
1042 {
1043 YAssertNonnull(p_bmp),
1044 YAssert(s != Size::Invalid, "Invalid size found.");
1045
1046 auto p(MakeMoveableGlobalMemory(sizeof(::BITMAPV5HEADER)
1047 + GetAreaOf(s) * sizeof(Pixel)));
1048 {
1049 const GlobalLocked gl(Nonnull(p));
1050 const auto p_buf(gl.GetPtr<::BITMAPV5HEADER>().get());
1051
1052 *p_buf = {sizeof(::BITMAPV5HEADER), CheckPositiveScalar<long>(s.Width,
1053 "width"), -CheckPositiveScalar<long>(s.Height, "height"), 1, 32,
1054 BI_BITFIELDS, static_cast<unsigned long>(sizeof(Pixel)
1055 * GetAreaOf(s)), 0, 0, 0, 0, 0x00FF0000, 0x0000FF00, 0x000000FF,
1056 0xFF000000, 0x73524742/*LCS_sRGB*/, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}
1057 }, 0, 0, 0, LCS_GM_IMAGES, 0, 0, 0},
1058 CopyBitmapBuffer(ystdex::aligned_store_cast<Pixel*>(p_buf + 1),
1059 p_bmp, s);
1060 }
1061 SendRaw(CF_DIBV5, p.release());
1062 }
1063
1064 void
1065 Clipboard::SendRaw(FormatType fmt, void* h)
1066 {
1067 Clear();
1068 YCL_CallWin32F(SetClipboardData, fmt, h);
1069 }
1070
1071
1072 void
1073 ExecuteShellCommand(const wchar_t* cmd, const wchar_t* args, bool use_admin,
1074 const wchar_t* dir, int n_cmd_show, NativeWindowHandle h_parent)
1075 {
1076 // TODO: Set current working directory as %USERPROFILE%?
1077 auto res(int(std::intptr_t(::ShellExecuteW(h_parent,
1078 use_admin ? L"runas" : nullptr, Nonnull(cmd), args, dir, n_cmd_show))));
1079
1080 switch(res)
1081 {
1082 case 0:
1083 case SE_ERR_OOM:
1084 // TODO: Use inherited class of exception.
1085 throw std::bad_alloc();
1086 case SE_ERR_SHARE:
1087 case SE_ERR_DLLNOTFOUND:
1088 res = SE_ERR_SHARE ? ERROR_SHARING_VIOLATION : ERROR_DLL_NOT_FOUND;
1089 case ERROR_FILE_NOT_FOUND: // NOTE: Same as %SE_ERR_FNF.
1090 case ERROR_PATH_NOT_FOUND: // NOTE: Same as %SE_ERR_PNF.
1091 case ERROR_ACCESS_DENIED: // NOTE: Same as %SE_ERR_ACCESSDENIED.
1092 case ERROR_BAD_FORMAT:
1093 throw Win32Exception(ErrorCode(res), "ShellExecuteW", Err);
1094 case SE_ERR_ASSOCINCOMPLETE:
1095 case SE_ERR_NOASSOC:
1096 case SE_ERR_DDETIMEOUT:
1097 case SE_ERR_DDEFAIL:
1098 case SE_ERR_DDEBUSY:
1099 {
1100 using boxed_exception = ystdex::wrap_mixin_t<std::runtime_error, int>;
1101
1102 TryExpr(throw boxed_exception{std::runtime_error("ShellExecuteW"), res})
1103 catch(boxed_exception& e)
1104 {
1105 const auto throw_ex([=](int ec) YB_ATTR(noreturn){
1106 std::throw_with_nested(Win32Exception(ErrorCode(ec),
1107 ystdex::sfmt("ShellExecuteW: %d", res), Err));
1108 });
1109
1110 switch(e.value)
1111 {
1112 case SE_ERR_ASSOCINCOMPLETE:
1113 case SE_ERR_NOASSOC:
1114 throw_ex(ERROR_NO_ASSOCIATION);
1115 case SE_ERR_DDETIMEOUT:
1116 case SE_ERR_DDEFAIL:
1117 case SE_ERR_DDEBUSY:
1118 throw_ex(ERROR_DDE_FAIL);
1119 default:
1120 break;
1121 }
1122 }
1123 YAssert(false, "Invalid state found.");
1124 }
1125 default:
1126 if(res > 32)
1127 YTraceDe(Informative, "ExecuteShellCommand: ::ShellExecute call"
1128 " succeed with return value %d.", res);
1129 else
1130 throw LoggedEvent(ystdex::sfmt("ExecuteShellCommand:"
1131 " ::ShellExecuteW call failed" " with unknown error '%d'.",
1132 res), Err);
1133 }
1134 }
1135 # endif
1136
1137 } // namespace platform_ex;
1138
1139 #endif
1140
platform::p
while p p
Definition: YCLib/FileSystem.h:225
ystdex::trivially_fill_n
_type * trivially_fill_n(_type *first, size_t n=1, byte value={})
填充字节序列。
Definition: algorithm.hpp:363
YSLib::Drawing::x
The boundary is out of the const Rect SDst SPos x
Definition: YDraw.h:127
YSLib::Drawing::w
The boundary is out of the const Rect SDst w
Definition: YDraw.h:127
ystdex::to_string
std::string to_string(const std::thread::id &)
转换 thread::id 为字符串表示。
ystdex::sfmt
auto sfmt(const _tChar *fmt,...) -> decltype(vsfmt(fmt, std::declval< std::va_list >()))
以 C 标准输出格式的输出 std::basic_string 实例的对象。
Definition: string.hpp:1140
ystdex::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:415
platform::containers::string
basic_string< char > string
Definition: Container.h:101
platform::Nonnull
_type && Nonnull(_type &&p) ynothrow
断言并返回非空指针。
Definition: Debug.h:411
platform::Descriptions::Warning
Definition: YCommon.h:157
platform::Descriptions::Informative
Definition: YCommon.h:159
YSLib::Text::buf
const char * buf
Definition: TextFile.h:77
platform_ex::ClearKeyStates
YF_API void ClearKeyStates()
清除按键缓冲。
Definition: Input.cpp:159
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
ystdex::unseq_apply
void unseq_apply(_func &&f, _tParams &&...args)
无序调用。
Definition: functional.hpp:241
YSLib::Drawing::CopyLine
扫描线：按指定扫描顺序复制一行像素。
Definition: YBlit.h:443
platform::KeyCodes::DS::L
Definition: Keys.h:227
YSLib::GeneralEvent
std::runtime_error GeneralEvent
一般运行时异常事件类。
Definition: YException.h:45
YSLib::PostQuitMessage
YF_API void PostQuitMessage(int=0, Messaging::Priority p=DefaultQuitPriority)
以指定错误码和优先级发起 Shell 终止请求。
Definition: YApplication.cpp:85
YSLib::UI::Close
void Close(IWidget &wgt)
Definition: YWidget.cpp:92
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
YSLib::UI::Resize
大小调整。
Definition: YWidgetEvent.h:383
ystdex::ntctscpy
enable_if_irreplaceable_char_t< _tChar, _tChar * > ntctscpy(_tChar *s1, const _tChar *s2)
复制 NTCTS 。
Definition: cstring.h:250
YSLib::Drawing::GBinaryGroup::X
_type X
Definition: YGDIBase.h:63
YSLib::Drawing::Size::Width
SDst Width
Definition: YGDIBase.h:302
YSLib::Drawing::CompactPixmap
标准矩形像素图缓冲区。
Definition: YGDI.h:243
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:760
YSLib::FilterExceptions
bool FilterExceptions(_func f, const char *desc={}, RecordLevel lv=Alert, ExceptionTracer trace=ExtractAndTrace) ynothrow
调用函数并过滤宿主异常。
Definition: YException.h:202
YSLib::UI::args
yconstfn const string _tParams && args
Definition: Loader.h:131
CatchExpr
#define CatchExpr(_ex,...)
指定表达式作为异常处理器。
Definition: YBaseMacro.h:129
platform::AlphaType
octet AlphaType
Definition: Video.h:289
YSLib::EventPriority
std::uint8_t EventPriority
事件优先级。
Definition: YEvent.hpp:217
YSLib::Drawing::GBinaryGroup::Y
_type Y
分量。
Definition: YGDIBase.h:63
CHRLib::d
_tDst * d
Definition: CharacterProcessing.h:139
YSLib::LoggedEvent
记录日志的异常事件类。
Definition: YException.h:49
ystdex::data
auto data(_tRange &c) -> decltype(c.data())
Definition: range.hpp:280
ystdex::wstring_view
basic_string_view< wchar_t > wstring_view
Definition: string_view.hpp:418
ystdex::pun_storage_t
aligned_storage_t< sizeof(_type), _vAlign > pun_storage_t
显式转换的替代对齐存储对齐存储类型。
Definition: type_pun.hpp:114
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:46
yfsig
#define yfsig
展开为表示函数签名的预定义变量的宏。
Definition: ydef.h:702
YSLib::UI::IsVisible
IsVisible
Definition: YWidget.h:101
YCL_CallWin32F
#define YCL_CallWin32F(_fn,...)
Definition: MinGW32.h:179
YSLib::Drawing::ConstBitmapPtr
const Pixel * ConstBitmapPtr
Definition: YGraphics.h:44
YSLib::UI::ImplDeDtor
ImplDeDtor(Thumb) void DecorateAsCloseButton(Thumb &tmb)
Definition: Button.cpp:125
YSLib::UI::Invalidate
YF_API void Invalidate(IWidget &, const Rect &)
无效化：使相对部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.cpp:108
CHRLib::char16_t
char16_t((*c_ptr<< CHAR_BIT)|c_ptr[1])) inline PDefH(char16_t
取 c_ptr 指向的小端序双字节字符。
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:305
platform_ex::Windows::unsigned
YF_API unsigned
Definition: MinGW32.h:630
YSLib::ynothrow
YB_PURE const _type size_t n ynothrow
Definition: YCoreUtilities.h:168
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:438
YModules.h
platform
默认平台命名空间。
Definition: Container.h:47
std
Definition: memory.hpp:1100
platform::Deref
yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:440
exception.h
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:114
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:42
TryExpr
#define TryExpr(...)
指定表达式在 try 块中求值。
Definition: YBaseMacro.h:120
YB_ATTR
#define YB_ATTR(...)
GNU 风格属性。
Definition: ydef.h:347
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
YSLib::YAssert
YAssert(!(v< Deref(a)),"Value less than lower bound found.")
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
platform_ex
平台扩展命名空间。
Definition: Android.h:45
YSLib::Drawing::GetHeight
tr GetHeight())) inline PDefH(void
按字体高度和行距调整文本区域的底边距。
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:540
ystdex
特性测试宏。
Definition: ydef.h:796
YSLib::Text::str
const char const char * str
Definition: TextFile.h:77
DefDeMoveCtor
#define DefDeMoveCtor(_t)
Definition: YBaseMacro.h:166
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:293
ystdex::pvoid
enable_if_t< or_< is_object< _type >, is_void< _type > >::value, void * > pvoid(_type *p)
取 void* 类型的指针。
Definition: addressof.hpp:101
YSLib::Drawing::BitmapPtr
Pixel * BitmapPtr
Definition: YGraphics.h:42
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
YSLib::UI::Move
移动：位置调整。
Definition: YWidgetEvent.h:382
Drawing
YSLib::UI::Show
YF_API void Show(IWidget &)
显示部件。
Definition: YWidget.cpp:202
YB_ALLOCATOR
#define YB_ALLOCATOR
指示修饰的是分配器，或返回分配器调用的函数或函数模板。
Definition: ydef.h:406
YCL_HostedUI_XCB
#define YCL_HostedUI_XCB
在宿主用户界面使用 X C 绑定。
Definition: Platform.h:381
YModules.h
YSLib::IO::int
YF_API int
Definition: File.h:49
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
YSLib::i
return i
Definition: YCoreUtilities.h:176
ystdex::u16string_view
basic_string_view< char16_t > u16string_view
Definition: string_view.hpp:416
YSLib::Drawing::GBinaryGroup< SPos >::Invalid
static const GBinaryGroup Invalid
无效（不在屏幕坐标系中）对象。
Definition: YGDIBase.h:58
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:808
YSLib::Drawing::CopyBitmapBuffer
void CopyBitmapBuffer(_tOut p_dst, _tIn p_src, const Size &s)
Definition: YGraphics.h:50
mixin.hpp
基于类继承的混入接口。
YSLib::UI::e
void e
Definition: YWidget.h:352
platform::Descriptions::Debug
Definition: YCommon.h:160
YB_LIKELY
#define YB_LIKELY(_expr)
Definition: ydef.h:437
ystdex::single_thread::lock_guard
Definition: pseudo_mutex.h:197
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: YGDIBase.h:302
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:167
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
ystdex::aligned_store_cast
ystdex::enable_if_t< and_< is_object_pointer< _pDst >, is_aligned_storable< _tSrc, remove_pointer_t< _pDst > > >::value, _pDst > aligned_store_cast(_tSrc *v)
保证对齐存储的显式转换。
Definition: type_pun.hpp:155
platform::if
if(!p) p
ystdex::mixin
混入对象。
Definition: mixin.hpp:45
platform_ex::Windows::WCSToUTF8
const char *str string_view sv WCSToUTF8
Definition: MinGW32.h:657
YSLib::UI::Window
窗口。
Definition: YWindow.h:44
YCL_Raise_Win32Exception
#define YCL_Raise_Win32Exception(...)
取转换为 errno 的 Win32 错误。
Definition: MinGW32.h:132
YSLib::UI::bool
IWidget bool b bool
Definition: YControl.h:121
YB_ATTR_returns_nonnull
#define YB_ATTR_returns_nonnull
指示返回非空属性。
Definition: ydef.h:390
platform::Descriptions::Err
Definition: YCommon.h:156
YSLib::IO::f
const string &path const String &path _func f
Definition: YSLib/Service/FileSystem.h:430
YSLib::UI::name
yconstfn const string & name
Definition: Loader.h:130
YSLib::Drawing::GGraphics
二维图形接口上下文模板。
Definition: YGraphics.h:62
YSLib::Drawing::g
The boundary is out of the const Graphics & g
Definition: YDraw.h:161
ystdex::unimplemented
异常：未实现的操作。
Definition: ystdex/exception.h:135
platform_ex::Windows::ErrorCode
unsigned long ErrorCode
Definition: MinGW32.h:54
platform::Descriptions::Notice
Definition: YCommon.h:158
ystdex::unique_raw
std::unique_ptr< _type > unique_raw(_pSrc *p)
Definition: memory.hpp:617
YSLib::Drawing::Size::Invalid
static const Size Invalid
无效对象。
Definition: YGDIBase.h:300
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
YCL_CallWin32F_Trace
#define YCL_CallWin32F_Trace(_fn,...)
Definition: MinGW32.h:202
platform::n
size_t n
Definition: YCLib/FileSystem.cpp:321
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:43
YSLib::Drawing::GBinaryGroup< SPos >