From 1c664da5e02bb7b6baae6b75ac6f82f004e25734 Mon Sep 17 00:00:00 2001 From: cnjinhao Date: Fri, 2 Jan 2015 13:58:22 +0800 Subject: [PATCH] append screen source files --- include/nana/gui/screen.hpp | 52 ++++++++++ source/gui/screen.cpp | 194 ++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 include/nana/gui/screen.hpp create mode 100644 source/gui/screen.cpp diff --git a/include/nana/gui/screen.hpp b/include/nana/gui/screen.hpp new file mode 100644 index 00000000..679c5501 --- /dev/null +++ b/include/nana/gui/screen.hpp @@ -0,0 +1,52 @@ +/* +* Screen Informations +* Nana C++ Library(http://www.nanapro.org) +* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) +* +* Distributed under the Boost Software License, Version 1.0. +* (See accompanying file LICENSE_1_0.txt or copy at +* http://www.boost.org/LICENSE_1_0.txt) +* +* @file: nana/gui/screen.hpp +*/ + +#ifndef NANA_GUI_SCREEN_HPP +#define NANA_GUI_SCREEN_HPP +#include "basis.hpp" +#include +#include + +namespace nana +{ + /// The monitor display metrics + class display + { + public: + virtual ~display() = default; + + /// The index of monitor. + virtual std::size_t index() const = 0; + + /// Returns the positional coordinates and size of the display device in reference to the desktop area + virtual const ::nana::rectangle& area() const = 0; + }; + + class screen + { + public: + static ::nana::size desktop_size(); + static ::nana::size primary_monitor_size(); + static std::shared_ptr from_point(const point&); + static std::shared_ptr from_window(window); + + /// Returns the number of display monitors + std::size_t count() const; + + std::shared_ptr get_display(std::size_t index) const; + std::shared_ptr get_primary() const; + + void for_each(std::function) const; + }; +}//end namespace nana + +#endif \ No newline at end of file diff --git a/source/gui/screen.cpp b/source/gui/screen.cpp new file mode 100644 index 00000000..d40f6b8e --- /dev/null +++ b/source/gui/screen.cpp @@ -0,0 +1,194 @@ +/* + * Screen Informations + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/gui/screen.cpp + */ +#include +#include +#include +#include +#include +#if defined(NANA_WINDOWS) + #include +#endif + +namespace nana +{ + //class display + class real_display + : public display + { + public: + real_display(std::size_t number) + : index_(number) + { +#if defined(NANA_WINDOWS) + DISPLAY_DEVICE disp; + disp.cb = sizeof disp; + if (::EnumDisplayDevices(nullptr, static_cast(index_), &disp, 0)) + { + DEVMODE mode; + mode.dmSize = sizeof mode; + if (::EnumDisplaySettings(disp.DeviceName, ENUM_CURRENT_SETTINGS, &mode)) + { + area_.x = mode.dmPosition.x; + area_.y = mode.dmPosition.y; + area_.width = mode.dmPelsWidth; + area_.height = mode.dmPelsHeight; + return; + } + } +#else + if (0 == index_) + { + position_.x = position_.y = 0; + size_ = detail::native_interface::primary_monitor_size(); + return; + } +#endif + throw std::invalid_argument("Nana.Screen: Invalid monitor index."); + } + + real_display(std::size_t number, const ::nana::rectangle& r) + : index_(number), area_(r) + { + } + public: + //Implementation of display + std::size_t index() const override + { + return index_; + } + + const ::nana::rectangle& area() const override + { + return area_; + } + private: + const std::size_t index_; + ::nana::rectangle area_; + }; + + //class screen + + ::nana::size screen::desktop_size() + { +#if defined(NANA_WINDOWS) + auto w = static_cast(::GetSystemMetrics(SM_CXVIRTUALSCREEN)); + auto h = static_cast(::GetSystemMetrics(SM_CYVIRTUALSCREEN)); + return{w, h}; +#else + return ::nana::detail::native_interface::primary_monitor_size(); +#endif + } + + ::nana::size screen::primary_monitor_size() + { + return ::nana::detail::native_interface::primary_monitor_size(); + } + + std::shared_ptr screen::from_point(const point& pos) + { +#if defined(NANA_WINDOWS) + typedef HMONITOR(__stdcall * MonitorFromPointT)(POINT, DWORD); + + MonitorFromPointT mfp = reinterpret_cast(::GetProcAddress(::GetModuleHandleA("User32.DLL"), "MonitorFromPoint")); + if (mfp) + { + POINT native_pos = { pos.x, pos.y }; + HMONITOR monitor = mfp(native_pos, 2 /*MONITOR_DEFAULTTONEAREST*/); + + MONITORINFO mi; + mi.cbSize = sizeof mi; + if (::GetMonitorInfo(monitor, &mi)) + { + DISPLAY_DEVICE disp; + disp.cb = sizeof disp; + + DWORD index = 0; + while (::EnumDisplayDevices(nullptr, index++, &disp, 0)) + { + DEVMODE mode; + mode.dmSize = sizeof mode; + if (::EnumDisplaySettings(disp.DeviceName, ENUM_CURRENT_SETTINGS, &mode)) + { + if (mode.dmPosition.x == mi.rcWork.left && mode.dmPosition.y == mi.rcWork.top && + (mode.dmPelsWidth == mi.rcWork.right - mi.rcWork.left) && + (mode.dmPelsHeight == mi.rcWork.bottom - mi.rcWork.top)) + { + return std::make_shared(static_cast(index - 1), rectangle{ mode.dmPosition.x, mode.dmPosition.y, static_cast(mode.dmPelsWidth), static_cast(mode.dmPelsHeight) }); + } + } + } + } + } +#endif + return screen().get_primary(); + } + + std::shared_ptr screen::from_window(window wd) + { + ::nana::point pos; + API::calc_screen_point(wd, pos); + return from_point(pos); + } + + std::size_t screen::count() const + { +#if defined(NANA_WINDOWS) + DISPLAY_DEVICE disp; + disp.cb = sizeof disp; + + DWORD index = 0; + while (::EnumDisplayDevices(nullptr, index++, &disp, 0)); + return static_cast(index - 1); +#else + return 1; +#endif + } + + std::shared_ptr screen::get_display(std::size_t index) const + { + return std::make_shared(index); + } + + std::shared_ptr screen::get_primary() const + { +#if defined(NANA_WINDOWS) + //return rectangle(mi.rcWork.left, mi.rcWork.top, + // mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top); + DISPLAY_DEVICE disp; + disp.cb = sizeof disp; + + DWORD index = 0; + while (::EnumDisplayDevices(nullptr, index++, &disp, 0)) + { + DEVMODE mode; + mode.dmSize = sizeof mode; + if (::EnumDisplaySettings(disp.DeviceName, ENUM_CURRENT_SETTINGS, &mode)) + { + if (mode.dmPosition.x == 0 && mode.dmPosition.y == 0) + return std::make_shared(static_cast(index - 1), rectangle{ mode.dmPosition.x, mode.dmPosition.y, static_cast(mode.dmPelsWidth), static_cast(mode.dmPelsHeight) }); + } + } +#endif + return std::make_shared(0); + } + + void screen::for_each(std::function fn) const + { + auto n = count(); + for (decltype(n) i = 0; i < n; ++i) + { + real_display disp(i); + fn(disp); + } + } + //end class screen +} \ No newline at end of file