diff options
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/AboutDialog.cpp')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/mptrack/AboutDialog.cpp | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/AboutDialog.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/AboutDialog.cpp new file mode 100644 index 00000000..903729fe --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/mptrack/AboutDialog.cpp @@ -0,0 +1,589 @@ +/* + * AboutDialog.cpp + * --------------- + * Purpose: About dialog with credits, system information and a fancy demo effect. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "resource.h" +#include "AboutDialog.h" +#include "Image.h" +#include "Mptrack.h" +#include "TrackerSettings.h" +#include "BuildVariants.h" +#include "../common/version.h" +#include "../misc/mptWine.h" + + +OPENMPT_NAMESPACE_BEGIN + + +CAboutDlg *CAboutDlg::instance = nullptr; + +BEGIN_MESSAGE_MAP(CRippleBitmap, CWnd) + ON_WM_PAINT() + ON_WM_ERASEBKGND() + ON_WM_MOUSEMOVE() + ON_WM_MOUSEHOVER() + ON_WM_MOUSELEAVE() +END_MESSAGE_MAP() + + +CRippleBitmap::CRippleBitmap() +{ + m_bitmapSrc = LoadPixelImage(GetResource(MAKEINTRESOURCE(IDB_MPTRACK), _T("PNG"))); + m_bitmapTarget = std::make_unique<RawGDIDIB>(m_bitmapSrc->Width(), m_bitmapSrc->Height()); + m_offset1.assign(m_bitmapSrc->Pixels().size(), 0); + m_offset2.assign(m_bitmapSrc->Pixels().size(), 0); + m_frontBuf = m_offset2.data(); + m_backBuf = m_offset1.data(); + + // Pre-fill first and last row of output bitmap, since those won't be touched. + const RawGDIDIB::Pixel *in1 = m_bitmapSrc->Pixels().data(), *in2 = m_bitmapSrc->Pixels().data() + (m_bitmapSrc->Height() - 1) * m_bitmapSrc->Width(); + RawGDIDIB::Pixel *out1 = m_bitmapTarget->Pixels().data(), *out2 = m_bitmapTarget->Pixels().data() + (m_bitmapSrc->Height() - 1) * m_bitmapSrc->Width(); + for(uint32 i = 0; i < m_bitmapSrc->Width(); i++) + { + *(out1++) = *(in1++); + *(out2++) = *(in2++); + } + + MemsetZero(m_bi); + m_bi.biSize = sizeof(BITMAPINFOHEADER); + m_bi.biWidth = m_bitmapSrc->Width(); + m_bi.biHeight = -(int32)m_bitmapSrc->Height(); + m_bi.biPlanes = 1; + m_bi.biBitCount = 32; + m_bi.biCompression = BI_RGB; + m_bi.biSizeImage = m_bitmapSrc->Width() * m_bitmapSrc->Height() * 4; +} + + +CRippleBitmap::~CRippleBitmap() +{ + if(!m_showMouse) + { + ShowCursor(TRUE); + } +} + + +void CRippleBitmap::OnMouseMove(UINT nFlags, CPoint point) +{ + + // Rate limit in order to avoid too may ripples. + DWORD now = timeGetTime(); + if(now - m_lastRipple < UPDATE_INTERVAL) + return; + m_lastRipple = now; + + // Initiate ripples at cursor location + point.x = Util::ScalePixelsInv(point.x, m_hWnd); + point.y = Util::ScalePixelsInv(point.y, m_hWnd); + Limit(point.x, 1, int(m_bitmapSrc->Width()) - 2); + Limit(point.y, 2, int(m_bitmapSrc->Height()) - 3); + int32 *p = m_backBuf + point.x + point.y * m_bitmapSrc->Width(); + p[0] += (nFlags & MK_LBUTTON) ? 50 : 150; + p[0] += (nFlags & MK_MBUTTON) ? 150 : 0; + + int32 w = m_bitmapSrc->Width(); + // Make the initial point of this ripple a bit "fatter". + p[-1] += p[0] / 2; p[1] += p[0] / 2; + p[-w] += p[0] / 2; p[w] += p[0] / 2; + p[-w - 1] += p[0] / 4; p[-w + 1] += p[0] / 4; + p[w - 1] += p[0] / 4; p[w + 1] += p[0] / 4; + + m_damp = !(nFlags & MK_RBUTTON); + m_activity = true; + + // Wine will only ever generate MouseLeave message when the message + // queue is completely empty and the hover timeout has expired. + // This results in a hidden mouse cursor long after it had already left the + // control. + // Avoid hiding the mouse cursor on Wine. Interferring with the users input + // methods is an absolute no-go. + if(mpt::OS::Windows::IsWine()) + { + return; + } + + TRACKMOUSEEVENT me; + me.cbSize = sizeof(TRACKMOUSEEVENT); + me.hwndTrack = m_hWnd; + me.dwFlags = TME_LEAVE | TME_HOVER; + me.dwHoverTime = 1500; + + if(TrackMouseEvent(&me) && m_showMouse) + { + ShowCursor(FALSE); + m_showMouse = false; + } +} + + +void CRippleBitmap::OnMouseLeave() +{ + if(!m_showMouse) + { + ShowCursor(TRUE); + m_showMouse = true; + } +} + + +void CRippleBitmap::OnPaint() +{ + CPaintDC dc(this); + + CRect rect; + GetClientRect(rect); + StretchDIBits(dc.m_hDC, + 0, 0, rect.Width(), rect.Height(), + 0, 0, m_bitmapTarget->Width(), m_bitmapTarget->Height(), + m_bitmapTarget->Pixels().data(), + reinterpret_cast<BITMAPINFO *>(&m_bi), DIB_RGB_COLORS, SRCCOPY); +} + + +bool CRippleBitmap::Animate() +{ + // Were there any pixels being moved in the last frame? + if(!m_activity) + return false; + + DWORD now = timeGetTime(); + if(now - m_lastFrame < UPDATE_INTERVAL) + return true; + m_lastFrame = now; + m_activity = false; + + m_frontBuf = (m_frame ? m_offset2 : m_offset1).data(); + m_backBuf = (m_frame ? m_offset1 : m_offset2).data(); + + // Spread the ripples... + const int32 w = m_bitmapSrc->Width(), h = m_bitmapSrc->Height(); + const int32 numPixels = w * (h - 2); + const int32 *back = m_backBuf + w; + int32 *front = m_frontBuf + w; + for(int32 i = numPixels; i != 0; i--, back++, front++) + { + (*front) = (back[-1] + back[1] + back[w] + back[-w]) / 2 - (*front); + if(m_damp) (*front) -= (*front) >> 5; + } + + // ...and compute the final picture. + const int32 *offset = m_frontBuf + w; + const RawGDIDIB::Pixel *pixelIn = m_bitmapSrc->Pixels().data() + w; + RawGDIDIB::Pixel *pixelOut = m_bitmapTarget->Pixels().data() + w; + RawGDIDIB::Pixel *limitMin = m_bitmapSrc->Pixels().data(), *limitMax = m_bitmapSrc->Pixels().data() + m_bitmapSrc->Pixels().size() - 1; + for(int32 i = numPixels; i != 0; i--, pixelIn++, pixelOut++, offset++) + { + // Compute pixel displacement + const int32 xOff = offset[-1] - offset[1]; + const int32 yOff = offset[-w] - offset[w]; + + if(xOff | yOff) + { + const RawGDIDIB::Pixel *p = pixelIn + xOff + yOff * w; + Limit(p, limitMin, limitMax); + // Add a bit of shading depending on how far we're displacing the pixel... + pixelOut->r = mpt::saturate_cast<uint8>(p->r + (p->r * xOff) / 32); + pixelOut->g = mpt::saturate_cast<uint8>(p->g + (p->g * xOff) / 32); + pixelOut->b = mpt::saturate_cast<uint8>(p->b + (p->b * xOff) / 32); + // ...and mix it with original picture + pixelOut->r = (pixelOut->r + pixelIn->r) / 2u; + pixelOut->g = (pixelOut->g + pixelIn->g) / 2u; + pixelOut->b = (pixelOut->b + pixelIn->b) / 2u; + // And now some cheap image smoothing... + pixelOut[-1].r = (pixelOut->r + pixelOut[-1].r) / 2u; + pixelOut[-1].g = (pixelOut->g + pixelOut[-1].g) / 2u; + pixelOut[-1].b = (pixelOut->b + pixelOut[-1].b) / 2u; + pixelOut[-w].r = (pixelOut->r + pixelOut[-w].r) / 2u; + pixelOut[-w].g = (pixelOut->g + pixelOut[-w].g) / 2u; + pixelOut[-w].b = (pixelOut->b + pixelOut[-w].b) / 2u; + m_activity = true; // Also use this to update activity status... + } else + { + *pixelOut = *pixelIn; + } + } + + m_frame = !m_frame; + + InvalidateRect(NULL, FALSE); + + return true; +} + + +CAboutDlg::~CAboutDlg() +{ + instance = nullptr; +} + + +void CAboutDlg::OnOK() +{ + instance = nullptr; + if(m_TimerID != 0) + { + KillTimer(m_TimerID); + m_TimerID = 0; + } + DestroyWindow(); + delete this; +} + + +void CAboutDlg::OnCancel() +{ + OnOK(); +} + + +BOOL CAboutDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + mpt::ustring app; + app += MPT_UFORMAT("OpenMPT{} ({} ({} bit))")( + BuildVariants().GetBuildVariantDescription(BuildVariants().GetBuildVariant()), + mpt::OS::Windows::Name(mpt::OS::Windows::GetProcessArchitecture()), + mpt::arch_bits) + + U_("\n"); + app += U_("Version ") + Build::GetVersionStringSimple() + U_("\n\n"); + app += Build::GetURL(Build::Url::Website) + U_("\n"); + SetDlgItemText(IDC_EDIT3, mpt::ToCString(mpt::String::Replace(app, U_("\n"), U_("\r\n")))); + + m_bmp.SubclassDlgItem(IDC_BITMAP1, this); + + m_Tab.InsertItem(TCIF_TEXT, 0, _T("OpenMPT"), 0, 0, 0, 0); + m_Tab.InsertItem(TCIF_TEXT, 1, _T("Components"), 0, 0, 0, 0); + m_Tab.InsertItem(TCIF_TEXT, 2, _T("Credits"), 0, 0, 0, 0); + m_Tab.InsertItem(TCIF_TEXT, 3, _T("License"), 0, 0, 0, 0); + m_Tab.InsertItem(TCIF_TEXT, 4, _T("Resources"), 0, 0, 0, 0); + if(mpt::OS::Windows::IsWine()) m_Tab.InsertItem(TCIF_TEXT, 5, _T("Wine"), 0, 0, 0, 0); + m_Tab.SetCurSel(0); + + OnTabChange(nullptr, nullptr); + + if(m_TimerID != 0) + { + KillTimer(m_TimerID); + m_TimerID = 0; + } + m_TimerID = SetTimer(TIMERID_ABOUT_DEFAULT, CRippleBitmap::UPDATE_INTERVAL, nullptr); + + return TRUE; +} + + +void CAboutDlg::OnTimer(UINT_PTR nIDEvent) +{ + if(nIDEvent == m_TimerID) + { + m_bmp.Animate(); + } +} + + +void CAboutDlg::OnTabChange(NMHDR * /*pNMHDR*/ , LRESULT * /*pResult*/ ) +{ + m_TabEdit.SetWindowText(mpt::ToCString(mpt::String::Replace(GetTabText(m_Tab.GetCurSel()), U_("\n"), U_("\r\n")))); +} + + +#ifdef MPT_ENABLE_ARCH_INTRINSICS +static mpt::ustring ProcSupportToString(uint32 procSupport) +{ + std::vector<mpt::ustring> features; +#if MPT_COMPILER_MSVC +#if defined(MPT_ENABLE_ARCH_X86) + features.push_back(U_("x86")); +#endif +#if defined(MPT_ENABLE_ARCH_AMD64) + features.push_back(U_("amd64")); +#endif + struct ProcFlag + { + decltype(procSupport) flag; + const char *name; + }; + static constexpr ProcFlag flags[] = + { + { 0, "" }, +#if defined(MPT_ENABLE_ARCH_X86) || defined(MPT_ENABLE_ARCH_AMD64) + { CPU::feature::mmx, "mmx" }, + { CPU::feature::sse, "sse" }, + { CPU::feature::sse2, "sse2" }, + { CPU::feature::sse3, "sse3" }, + { CPU::feature::ssse3, "ssse3" }, + { CPU::feature::sse4_1, "sse4.1" }, + { CPU::feature::sse4_2, "sse4.2" }, + { CPU::feature::avx, "avx" }, + { CPU::feature::avx2, "avx2" }, +#endif + }; + for(const auto &f : flags) + { + if(procSupport & f.flag) features.push_back(mpt::ToUnicode(mpt::Charset::ASCII, f.name)); + } +#else + MPT_UNUSED_VARIABLE(procSupport); +#endif + return mpt::String::Combine(features, U_(" ")); +} +#endif // MPT_ENABLE_ARCH_INTRINSICS + + +mpt::ustring CAboutDlg::GetTabText(int tab) +{ + const mpt::ustring lf = U_("\n"); + const mpt::ustring yes = U_("yes"); + const mpt::ustring no = U_("no"); +#ifdef MPT_ENABLE_ARCH_INTRINSICS + const CPU::Info CPUInfo = CPU::Info::Get(); +#endif // MPT_ENABLE_ARCH_INTRINSICS + mpt::ustring text; + switch(tab) + { + case 0: + text = U_("OpenMPT - Open ModPlug Tracker\n\n") + + MPT_UFORMAT("Version: {}\n")(Build::GetVersionStringExtended()) + + MPT_UFORMAT("Source Code: {}\n")(SourceInfo::Current().GetUrlWithRevision() + UL_(" ") + SourceInfo::Current().GetStateString()) + + MPT_UFORMAT("Build Date: {}\n")(Build::GetBuildDateString()) + + MPT_UFORMAT("Compiler: {}\n")(Build::GetBuildCompilerString()) + + MPT_UFORMAT("Architecture: {}\n")(mpt::OS::Windows::Name(mpt::OS::Windows::GetProcessArchitecture())) + + MPT_UFORMAT("Required Windows Kernel Level: {}\n")(mpt::OS::Windows::Version::GetName(mpt::OS::Windows::Version::GetMinimumKernelLevel())) + + MPT_UFORMAT("Required Windows API Level: {}\n")(mpt::OS::Windows::Version::GetName(mpt::OS::Windows::Version::GetMinimumAPILevel())); + { + text += U_("Required CPU features: "); + std::vector<mpt::ustring> features; + #if MPT_COMPILER_MSVC + #if defined(_M_X64) + features.push_back(U_("x86-64")); + if(CPU::GetMinimumFeatures() & CPU::feature::avx) features.push_back(U_("avx")); + if(CPU::GetMinimumFeatures() & CPU::feature::avx2) features.push_back(U_("avx2")); + #elif defined(_M_IX86) + if(CPU::GetMinimumFeatures() & CPU::feature::sse) features.push_back(U_("sse")); + if(CPU::GetMinimumFeatures() & CPU::feature::sse2) features.push_back(U_("sse2")); + if(CPU::GetMinimumFeatures() & CPU::feature::avx) features.push_back(U_("avx")); + if(CPU::GetMinimumFeatures() & CPU::feature::avx2) features.push_back(U_("avx2")); + #else + if(CPU::GetMinimumFeatures() & CPU::feature::sse) features.push_back(U_("sse")); + if(CPU::GetMinimumFeatures() & CPU::feature::sse2) features.push_back(U_("sse2")); + if(CPU::GetMinimumFeatures() & CPU::feature::avx) features.push_back(U_("avx")); + if(CPU::GetMinimumFeatures() & CPU::feature::avx2) features.push_back(U_("avx2")); + #endif + #endif + text += mpt::String::Combine(features, U_(" ")); + text += lf; + } +#ifdef MPT_ENABLE_ARCH_INTRINSICS + text += MPT_UFORMAT("Optional CPU features used: {}\n")(ProcSupportToString(CPU::GetEnabledFeatures())); +#endif // MPT_ENABLE_ARCH_INTRINSICS + text += lf; + text += MPT_UFORMAT("System Architecture: {}\n")(mpt::OS::Windows::Name(mpt::OS::Windows::GetHostArchitecture())); +#ifdef MPT_ENABLE_ARCH_INTRINSICS + text += MPT_UFORMAT("CPU: {}, Family {}, Model {}, Stepping {}\n") + ( mpt::ToUnicode(mpt::Charset::ASCII, (std::strlen(CPUInfo.VendorID) > 0) ? std::string(CPUInfo.VendorID) : std::string("Generic")) + , CPUInfo.Family + , CPUInfo.Model + , CPUInfo.Stepping + ); + text += MPT_UFORMAT("CPU Name: {}\n")(mpt::ToUnicode(mpt::Charset::ASCII, (std::strlen(CPUInfo.BrandID) > 0) ? std::string(CPUInfo.BrandID) : std::string(""))); + text += MPT_UFORMAT("Available CPU features: {}\n")(ProcSupportToString(CPUInfo.AvailableFeatures)); +#endif // MPT_ENABLE_ARCH_INTRINSICS + text += MPT_UFORMAT("Operating System: {}\n\n")(mpt::OS::Windows::Version::GetName(mpt::OS::Windows::Version::Current())); + text += MPT_UFORMAT("OpenMPT Install Path{1}: {0}\n")(theApp.GetInstallPath(), theApp.IsPortableMode() ? U_(" (portable)") : U_("")); + text += MPT_UFORMAT("OpenMPT Executable Path{1}: {0}\n")(theApp.GetInstallBinArchPath(), theApp.IsPortableMode() ? U_(" (portable)") : U_("")); + text += MPT_UFORMAT("Settings{1}: {0}\n")(theApp.GetConfigFileName(), theApp.IsPortableMode() ? U_(" (portable)") : U_("")); + break; + case 1: + { + std::vector<std::string> components = ComponentManager::Instance()->GetRegisteredComponents(); + if(!TrackerSettings::Instance().ComponentsKeepLoaded) + { + text += U_("Components are loaded and unloaded as needed.\n\n"); + for(const auto &component : components) + { + ComponentInfo info = ComponentManager::Instance()->GetComponentInfo(component); + mpt::ustring name = mpt::ToUnicode(mpt::Charset::ASCII, (info.name.substr(0, 9) == "Component") ? info.name.substr(9) : info.name); + if(!info.settingsKey.empty()) + { + name = mpt::ToUnicode(mpt::Charset::ASCII, info.settingsKey); + } + text += name + lf; + } + } else + { + for(int available = 1; available >= 0; --available) + { + if(available) + { + text += U_("Loaded Components:\n"); + } else + { + text += U_("\nUnloaded Components:\n"); + } + for(const auto &component : components) + { + ComponentInfo info = ComponentManager::Instance()->GetComponentInfo(component); + if(available && info.state != ComponentStateAvailable) continue; + if(!available && info.state == ComponentStateAvailable) continue; + mpt::ustring name = mpt::ToUnicode(mpt::Charset::ASCII, (info.name.substr(0, 9) == "Component") ? info.name.substr(9) : info.name); + if(!info.settingsKey.empty()) + { + name = mpt::ToUnicode(mpt::Charset::ASCII, info.settingsKey); + } + text += MPT_UFORMAT("{}: {}") + ( name + , info.state == ComponentStateAvailable ? U_("ok") : + info.state == ComponentStateUnavailable? U_("missing") : + info.state == ComponentStateUnintialized ? U_("not loaded") : + info.state == ComponentStateBlocked ? U_("blocked") : + info.state == ComponentStateUnregistered ? U_("unregistered") : + U_("unknown") + ); + if(info.type != ComponentTypeUnknown) + { + text += MPT_UFORMAT(" ({})") + ( info.type == ComponentTypeBuiltin ? U_("builtin") : + info.type == ComponentTypeSystem ? U_("system") : + info.type == ComponentTypeSystemInstallable ? U_("system, optional") : + info.type == ComponentTypeBundled ? U_("bundled") : + info.type == ComponentTypeForeign ? U_("foreign") : + U_("unknown") + ); + } + text += lf; + } + } + } + } + break; + case 2: + text += Build::GetFullCreditsString(); + break; + case 3: + text += Build::GetLicenseString(); + break; + case 4: + text += U_("Website:\n") + Build::GetURL(Build::Url::Website); + text += U_("\n\nForum:\n") + Build::GetURL(Build::Url::Forum); + text += U_("\n\nBug Tracker:\n") + Build::GetURL(Build::Url::Bugtracker); + text += U_("\n\nUpdates:\n") + Build::GetURL(Build::Url::Updates); + break; + case 5: + try + { + if(!theApp.GetWine()) + { + text += U_("Wine integration not available.\n"); + } else + { + + mpt::Wine::Context & wine = *theApp.GetWine(); + + text += MPT_UFORMAT("Windows: {}\n") + ( mpt::OS::Windows::Version::Current().IsWindows() ? yes : no + ); + text += MPT_UFORMAT("Windows version: {}\n") + ( + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::Win81) ? U_("Windows 8.1") : + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::Win8) ? U_("Windows 8") : + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::Win7) ? U_("Windows 7") : + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::WinVista) ? U_("Windows Vista") : + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::WinXP) ? U_("Windows XP") : + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::Win2000) ? U_("Windows 2000") : + mpt::OS::Windows::Version::Current().IsAtLeast(mpt::OS::Windows::Version::WinNT4) ? U_("Windows NT4") : + U_("unknown") + ); + text += MPT_UFORMAT("Windows original: {}\n") + ( mpt::OS::Windows::IsOriginal() ? yes : no + ); + + text += U_("\n"); + + text += MPT_UFORMAT("Wine: {}\n") + ( mpt::OS::Windows::IsWine() ? yes : no + ); + text += MPT_UFORMAT("Wine Version: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.VersionContext().RawVersion()) + ); + text += MPT_UFORMAT("Wine Build ID: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.VersionContext().RawBuildID()) + ); + text += MPT_UFORMAT("Wine Host Sys Name: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.VersionContext().RawHostSysName()) + ); + text += MPT_UFORMAT("Wine Host Release: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.VersionContext().RawHostRelease()) + ); + + text += U_("\n"); + + text += MPT_UFORMAT("uname -m: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.Uname_m()) + ); + text += MPT_UFORMAT("HOME: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.HOME()) + ); + text += MPT_UFORMAT("XDG_DATA_HOME: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.XDG_DATA_HOME()) + ); + text += MPT_UFORMAT("XDG_CACHE_HOME: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.XDG_CACHE_HOME()) + ); + text += MPT_UFORMAT("XDG_CONFIG_HOME: {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.XDG_CONFIG_HOME()) + ); + + text += U_("\n"); + + text += MPT_UFORMAT("OpenMPT folder: {}\n") + ( theApp.GetInstallPath().ToUnicode() + ); + text += MPT_UFORMAT("OpenMPT folder (host): {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.PathToPosix(theApp.GetInstallPath())) + ); + text += MPT_UFORMAT("OpenMPT config folder: {}\n") + ( theApp.GetConfigPath().ToUnicode() + ); + text += MPT_UFORMAT("OpenMPT config folder (host): {}\n") + ( mpt::ToUnicode(mpt::Charset::UTF8, wine.PathToPosix(theApp.GetConfigPath())) + ); + text += MPT_UFORMAT("Host root: {}\n") + ( wine.PathToWindows("/").ToUnicode() + ); + + } + } catch(const mpt::Wine::Exception & e) + { + text += U_("Exception: ") + mpt::get_exception_text<mpt::ustring>(e) + U_("\n"); + } + break; + } + return text; +} + + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TABABOUT, m_Tab); + DDX_Control(pDX, IDC_EDITABOUT, m_TabEdit); +} + + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + ON_WM_TIMER() + ON_NOTIFY(TCN_SELCHANGE, IDC_TABABOUT, &CAboutDlg::OnTabChange) +END_MESSAGE_MAP() + + + +OPENMPT_NAMESPACE_END |