From 6088470157012d593d1fd881e1cc7df2a5c86082 Mon Sep 17 00:00:00 2001 From: spx Date: Mon, 8 Feb 2010 14:12:47 +0000 Subject: [PATCH] - CHANGED: ConfigParser now reads value strictly. Note that this change affects the reading of various skin setting values. For instance: - OK FontSize=10 FontSize=0 - NG (uses default value instead) FontSize= FontSize=ABC FontSize=20ABC (has been parsed as "FontSize=20" until now.) - CHANGED: FontSize=0(invisible) is now able to use in Meter=STRING. - Fixed the problem that the window doesn't move into the screen correctly when KeepOnScreen is 1. --- Library/ConfigParser.cpp | 54 ++++++++++++++++++++++++++++++++++++---- Library/ConfigParser.h | 2 ++ Library/MeterString.cpp | 27 +++++++++++++++----- Library/MeterWindow.cpp | 39 +++++++++++++++-------------- Library/MeterWindow.h | 2 -- 5 files changed, 92 insertions(+), 32 deletions(-) diff --git a/Library/ConfigParser.cpp b/Library/ConfigParser.cpp index 2beccae4..9f066a5a 100644 --- a/Library/ConfigParser.cpp +++ b/Library/ConfigParser.cpp @@ -549,7 +549,7 @@ double CConfigParser::ReadFloat(LPCTSTR section, LPCTSTR key, double defValue) const std::wstring& result = ReadString(section, key, buffer); - return wcstod(result.c_str(), NULL); + return ParseDouble(result, defValue); } std::vector CConfigParser::ReadFloats(LPCTSTR section, LPCTSTR key) @@ -565,7 +565,7 @@ std::vector CConfigParser::ReadFloats(LPCTSTR section, LPCTSTR ke std::vector tokens = Tokenize(tmp, L";"); for (size_t i = 0; i < tokens.size(); i++) { - result.push_back((Gdiplus::REAL)wcstod(tokens[i].c_str(), NULL)); + result.push_back((Gdiplus::REAL)ParseDouble(tokens[i], 0)); } return result; } @@ -577,7 +577,7 @@ int CConfigParser::ReadInt(LPCTSTR section, LPCTSTR key, int defValue) const std::wstring& result = ReadString(section, key, buffer); - return _wtoi(result.c_str()); + return (int)ParseDouble(result, defValue, true); } // Works as ReadFloat except if the value is surrounded by parenthesis in which case it tries to evaluate the formula @@ -600,7 +600,8 @@ double CConfigParser::ReadFormula(LPCTSTR section, LPCTSTR key, double defValue) return resultValue; } - return wcstod(result.c_str(), NULL); + + return ParseDouble(result, defValue); } Color CConfigParser::ReadColor(LPCTSTR section, LPCTSTR key, Color defValue) @@ -637,6 +638,41 @@ std::vector CConfigParser::Tokenize(const std::wstring& str, const return tokens; } +/* +** ParseDouble +** +** This is a helper method that parses the floating-point value from the given string. +** If the given string is invalid format or causes overflow/underflow, returns given default value. +** +*/ +double CConfigParser::ParseDouble(const std::wstring& string, double defValue, bool rejectExp) +{ + if (rejectExp) + { + if (string.find_last_of(L"dDeE") != std::wstring::npos) // contains exponent part + { + return defValue; + } + } + + std::wstring::size_type pos1 = string.find_first_not_of(L" \t\r\n"); + if (pos1 != std::wstring::npos) + { + // Trim white-space + std::wstring temp(string, pos1, string.find_last_not_of(L" \t\r\n") - pos1 + 1); + + WCHAR* end = NULL; + errno = 0; + double resultValue = wcstod(temp.c_str(), &end); + if (end && *end == L'\0' && errno != ERANGE) + { + return resultValue; + } + } + + return defValue; +} + /* ** ParseColor ** @@ -658,6 +694,8 @@ Color CConfigParser::ParseColor(LPCTSTR string) if (token != NULL) { R = _wtoi(token); + R = max(R, 0); + R = min(R, 255); } else { @@ -667,6 +705,8 @@ Color CConfigParser::ParseColor(LPCTSTR string) if (token != NULL) { G = _wtoi(token); + G = max(G, 0); + G = min(G, 255); } else { @@ -676,6 +716,8 @@ Color CConfigParser::ParseColor(LPCTSTR string) if (token != NULL) { B = _wtoi(token); + B = max(B, 0); + B = min(B, 255); } else { @@ -685,6 +727,8 @@ Color CConfigParser::ParseColor(LPCTSTR string) if (token != NULL) { A = _wtoi(token); + A = max(A, 0); + A = min(A, 255); } else { @@ -701,7 +745,7 @@ Color CConfigParser::ParseColor(LPCTSTR string) start = string + 2; } - if (wcslen(string) > 6 && !isspace(string[6])) + if (wcslen(string) > 6 && !iswspace(string[6])) { swscanf(string, L"%02x%02x%02x%02x", &R, &G, &B, &A); } diff --git a/Library/ConfigParser.h b/Library/ConfigParser.h index a56777c1..a69cec4f 100644 --- a/Library/ConfigParser.h +++ b/Library/ConfigParser.h @@ -63,6 +63,8 @@ private: void SetDefaultVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow); void ReadVariables(); void ReplaceVariables(std::wstring& result); + + double ParseDouble(const std::wstring& string, double defValue, bool rejectExp = false); Gdiplus::Color ParseColor(LPCTSTR string); void ReadIniFile(const std::wstring& strFileName, int depth = 0); diff --git a/Library/MeterString.cpp b/Library/MeterString.cpp index 27348537..ef26bbcf 100644 --- a/Library/MeterString.cpp +++ b/Library/MeterString.cpp @@ -194,7 +194,7 @@ void CMeterString::Initialize() delete m_Font; m_Font = NULL; - if (!m_DynamicVariables || m_FontSize != 0) + if (m_FontSize != 0) { throw CError(std::wstring(L"Unable to create font: ") + m_FontFace, __LINE__, __FILE__); } @@ -254,6 +254,12 @@ void CMeterString::ReadConfig(const WCHAR* section) m_ClipString = 0!=parser.ReadInt(section, L"ClipString", 0); m_FontSize = (int)parser.ReadFormula(section, L"FontSize", 10); + + if (m_FontSize < 0) + { + m_FontSize = 10; + } + m_NumOfDecimals = parser.ReadInt(section, L"NumOfDecimals", -1); m_Angle = (Gdiplus::REAL)parser.ReadFloat(section, L"Angle", 0.0); @@ -359,7 +365,7 @@ void CMeterString::ReadConfig(const WCHAR* section) */ bool CMeterString::Update() { - if (CMeter::Update() && m_Font) + if (CMeter::Update()) { std::vector stringValues; @@ -416,9 +422,16 @@ bool CMeterString::Update() // Calculate the text size RectF rect; Graphics graphics(m_MeterWindow->GetDoubleBuffer()); - DrawString(graphics, &rect); - m_W = (int)rect.Width; - m_H = (int)rect.Height; + if (DrawString(graphics, &rect)) + { + m_W = (int)rect.Width; + m_H = (int)rect.Height; + } + else + { + m_W = 1; + m_H = 1; + } } return true; @@ -434,7 +447,7 @@ bool CMeterString::Update() */ bool CMeterString::Draw(Graphics& graphics) { - if(!CMeter::Draw(graphics) || m_Font == NULL) return false; + if(!CMeter::Draw(graphics)) return false; return DrawString(graphics, NULL); } @@ -447,6 +460,8 @@ bool CMeterString::Draw(Graphics& graphics) */ bool CMeterString::DrawString(Graphics& graphics, RectF* rect) { + if (m_Font == NULL) return false; + StringFormat stringFormat; if (m_AntiAlias) diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index c9b20bb9..89866a80 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -350,6 +350,11 @@ void CMeterWindow::Refresh(bool init) SetWindowLong(m_Window, GWL_EXSTYLE, style & ~WS_EX_TRANSPARENT); } + // Set the window region + CreateRegion(true); // Clear the region + Update(false); + CreateRegion(false); + if (m_KeepOnScreen) { MapCoordsToScreen(m_ScreenX, m_ScreenY, m_WindowW, m_WindowH); @@ -360,10 +365,7 @@ void CMeterWindow::Refresh(bool init) SetWindowPos(m_Window, NULL, m_ScreenX, m_ScreenY, m_WindowW, m_WindowH, SWP_NOZORDER | SWP_NOACTIVATE); m_WindowZPosition = zPos; - // Set the window region - CreateRegion(true); // Clear the region - Update(false); - CreateRegion(false); + ScreenToWindow(); // Start the timers if(0 == SetTimer(m_Window, METERTIMER, m_WindowUpdate, NULL)) @@ -474,8 +476,6 @@ void CMeterWindow::MoveWindow(int x, int y) ScreenToWindow(); - DebugLog(L"Move: to (%i, %i)(%s, %s)", m_ScreenX, m_ScreenY, m_WindowX.c_str(), m_WindowY.c_str()); - if (m_SavePosition) { WriteConfig(); @@ -2340,15 +2340,15 @@ void CMeterWindow::CreateRegion(bool clear) */ void CMeterWindow::Redraw() { - if (m_DoubleBuffer) delete m_DoubleBuffer; - m_DoubleBuffer = new Bitmap(m_WindowW, m_WindowH, PixelFormat32bppARGB); - if (m_ResetRegion) { ResizeWindow(false); CreateRegion(true); } + if (m_DoubleBuffer) delete m_DoubleBuffer; + m_DoubleBuffer = new Bitmap(m_WindowW, m_WindowH, PixelFormat32bppARGB); + Graphics graphics(GetDoubleBuffer()); if (m_Background) @@ -2994,6 +2994,17 @@ LRESULT CMeterWindow::OnCommand(WPARAM wParam, LPARAM lParam) { m_KeepOnScreen = !m_KeepOnScreen; WriteConfig(); + + if (m_KeepOnScreen) + { + int x = m_ScreenX; + int y = m_ScreenY; + MapCoordsToScreen(x, y, m_WindowW, m_WindowH); + if (x != m_ScreenX || y != m_ScreenY) + { + MoveWindow(x, y); + } + } } else if(wParam == ID_CONTEXT_SKINMENU_CLICKTHROUGH) { @@ -3192,8 +3203,6 @@ LRESULT CMeterWindow::OnSysCommand(WPARAM wParam, LPARAM lParam) m_Dragging = true; m_Dragged = false; - int startScreenX = m_ScreenX; - int startScreenY = m_ScreenY; std::wstring startWindowX = m_WindowX; std::wstring startWindowY = m_WindowY; @@ -3202,8 +3211,6 @@ LRESULT CMeterWindow::OnSysCommand(WPARAM wParam, LPARAM lParam) if (m_Dragged) { - DebugLog(L"Dragging: (%i, %i)(%s, %s) to (%i, %i)(%s, %s)", startScreenX, startScreenY, startWindowX.c_str(), startWindowY.c_str(), m_ScreenX, m_ScreenY, m_WindowX.c_str(), m_WindowY.c_str()); - ScreenToWindow(); // Write the new place of the window to config file @@ -3238,7 +3245,6 @@ LRESULT CMeterWindow::OnEnterSizeMove(WPARAM wParam, LPARAM lParam) { if (m_Dragging) { - //DebugLog(L"Dragging: start"); m_Dragged = true; // Don't post the WM_NCLBUTTONUP message! } @@ -3253,11 +3259,6 @@ LRESULT CMeterWindow::OnEnterSizeMove(WPARAM wParam, LPARAM lParam) */ LRESULT CMeterWindow::OnExitSizeMove(WPARAM wParam, LPARAM lParam) { - if (m_Dragging) - { - //DebugLog(L"Dragging: end"); - } - return 0; } diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index 1b785ba1..01134698 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -352,8 +352,6 @@ private: std::wstring m_SkinName; // Name of the current skin folder std::wstring m_SkinIniFile; // Name of the current skin iniFile - std::wstring m_ConfigEditor; - UINT m_Message; // The current window message int m_UpdateCounter;