[BUG_FIXED] (Author: Pekka Pöyry) Filename rendered incorrectly on tab bar while it contains '&' character.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1349 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2015-02-28 13:17:37 +00:00
parent 8d3583ccfd
commit 473769cd58
3 changed files with 76 additions and 5 deletions

View File

@ -138,10 +138,34 @@ void DocTabView::bufferUpdated(Buffer * buffer, int mask)
} }
} }
//We must make space for the added ampersand characters.
TCHAR encodedLabel[2 * MAX_PATH];
if (mask & BufferChangeFilename) if (mask & BufferChangeFilename)
{ {
tie.mask |= TCIF_TEXT; tie.mask |= TCIF_TEXT;
tie.pszText = (TCHAR *)buffer->getFileName(); tie.pszText = (TCHAR *)encodedLabel;
{
const TCHAR* in = buffer->getFileName();
TCHAR* out = encodedLabel;
//This code will read in one character at a time and duplicate every first ampersand(&).
//ex. If input is "test & test && test &&&" then output will be "test && test &&& test &&&&".
//Tab's caption must be encoded like this because otherwise tab control would make tab too small or too big for the text.
while (*in != 0)
if (*in == '&')
{
*out++ = '&';
*out++ = '&';
while (*(++in) == '&')
*out++ = '&';
}
else
*out++ = *in++;
*out = '\0';
}
} }
::SendMessage(_hSelf, TCM_SETITEM, index, reinterpret_cast<LPARAM>(&tie)); ::SendMessage(_hSelf, TCM_SETITEM, index, reinterpret_cast<LPARAM>(&tie));

View File

@ -223,6 +223,14 @@ void TabBar::reSizeTo(RECT & rc2Ajust)
} }
} }
void TabBarPlus::destroy()
{
TabBar::destroy();
::DestroyWindow(_tooltips);
_tooltips = NULL;
}
void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isTraditional, bool isMultiLine) void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isTraditional, bool isMultiLine)
{ {
Window::init(hInst, parent); Window::init(hInst, parent);
@ -238,7 +246,7 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isTrad
int multiLine = isMultiLine?(_isTraditional?TCS_MULTILINE:0):0; int multiLine = isMultiLine?(_isTraditional?TCS_MULTILINE:0):0;
int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE |\ int style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE |\
TCS_TOOLTIPS | TCS_FOCUSNEVER | TCS_TABS | vertical | multiLine; TCS_FOCUSNEVER | TCS_TABS | vertical | multiLine;
style |= TCS_OWNERDRAWFIXED; style |= TCS_OWNERDRAWFIXED;
@ -257,6 +265,23 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isTrad
{ {
throw std::runtime_error("TabBarPlus::init : CreateWindowEx() function return null"); throw std::runtime_error("TabBarPlus::init : CreateWindowEx() function return null");
} }
_tooltips = ::CreateWindowEx(
0,
TOOLTIPS_CLASS,
NULL,
TTS_ALWAYSTIP | TTS_NOPREFIX,
0, 0, 0, 0,
_hParent,
NULL,
_hInst,
0);
if (!_tooltips)
{
throw std::runtime_error("TabBarPlus::init : tooltip CreateWindowEx() function return null");
}
::SendMessage(_hSelf, TCM_SETTOOLTIPS, (WPARAM)_tooltips, 0);
if (!_isTraditional) if (!_isTraditional)
{ {
if (!_hwndArray[_nbCtrl]) if (!_hwndArray[_nbCtrl])
@ -796,7 +821,26 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct)
SelectObject(hDC, _hLargeFont); SelectObject(hDC, _hLargeFont);
} }
int Flags = DT_SINGLELINE; int Flags = DT_SINGLELINE | DT_NOPREFIX;
TCHAR decodedLabel[MAX_PATH];
{
const TCHAR* in = label;
TCHAR* out = decodedLabel;
//This code will read in one character at a time and remove every first ampersand(&).
//ex. If input "test && test &&& test &&&&" then output will be "test & test && test &&&".
//Tab's caption must be encoded like this because otherwise tab control would make tab too small or too big for the text.
while (*in != 0)
if (*in == '&')
while (*(++in) == '&')
*out++ = *in;
else
*out++ = *in++;
*out = '\0';
}
if (_drawTabCloseButton) if (_drawTabCloseButton)
{ {
@ -848,7 +892,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct)
Flags |= DT_BOTTOM; Flags |= DT_BOTTOM;
} }
::DrawText(hDC, label, lstrlen(label), &rect, Flags); ::DrawText(hDC, decodedLabel, lstrlen(decodedLabel), &rect, Flags);
::RestoreDC(hDC, nSavedDC); ::RestoreDC(hDC, nSavedDC);
} }

View File

@ -144,7 +144,7 @@ class TabBarPlus : public TabBar
public : public :
TabBarPlus() : TabBar(), _isDragging(false), _tabBarDefaultProc(NULL), _currentHoverTabItem(-1),\ TabBarPlus() : TabBar(), _isDragging(false), _tabBarDefaultProc(NULL), _currentHoverTabItem(-1),\
_isCloseHover(false), _whichCloseClickDown(-1), _lmbdHit(false) {}; _isCloseHover(false), _whichCloseClickDown(-1), _lmbdHit(false), _tooltips(NULL) {};
enum tabColourIndex { enum tabColourIndex {
activeText, activeFocusedTop, activeUnfocusedTop, inactiveText, inactiveBg activeText, activeFocusedTop, activeUnfocusedTop, inactiveText, inactiveBg
}; };
@ -155,6 +155,8 @@ public :
virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isTraditional = false, bool isMultiLine = false); virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isTraditional = false, bool isMultiLine = false);
virtual void destroy();
static bool doDragNDropOrNot() { static bool doDragNDropOrNot() {
return _doDragNDrop; return _doDragNDrop;
}; };
@ -234,6 +236,7 @@ protected:
bool _isCloseHover; bool _isCloseHover;
int _whichCloseClickDown; int _whichCloseClickDown;
bool _lmbdHit; // Left Mouse Button Down Hit bool _lmbdHit; // Left Mouse Button Down Hit
HWND _tooltips;
LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);