Sync to Wine-0_9_2:

Vitaliy Margolen <wine-patch@kievinfo.com>
- Return false if index is out of bounds in GetItemT.
Francois Gouget <fgouget@free.fr>
- Remove spaces before '\n' in traces.
- Assorted spelling and case fixes.
Thomas Weidenmueller <wine-patches@reactsoft.com>
- Improved word wrapping and tab key handling.
Raphael Junqueira <fenix@club-internet.fr>
- Implement implement header callback support (HDN_GETDISPINFO notification):
- better factorisation
- unicode fixes
YunSong Hwang <hys545@dreamwiz.com>
- Update Korean translations.
Markus Amsler <markus.amsler@oribi.org>
- Reformat "see" section, to match c2man requirements.

svn path=/trunk/; revision=19585
This commit is contained in:
Gé van Geldorp 2005-11-25 23:05:28 +00:00
parent 598bbf9e8d
commit 35f5487496
5 changed files with 178 additions and 132 deletions

View file

@ -1,5 +1,6 @@
/* /*
* Copyright 2002 Won-kyu Park <wkpark@kldp.org> * Copyright 2002 Won-kyu Park <wkpark@kldp.org>
* Copyright 2005 YunSong Hwang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,20 +21,20 @@ LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140 IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Properties for " CAPTION "속성"
FONT 9, "MS Shell Dlg" FONT 9, "MS Shell Dlg"
BEGIN BEGIN
DEFPUSHBUTTON "확인", IDOK,4,122,50,14, WS_TABSTOP | WS_GROUP DEFPUSHBUTTON "확인", IDOK,4,122,50,14, WS_TABSTOP | WS_GROUP
PUSHBUTTON "취소", IDCANCEL,58,122,50,14 PUSHBUTTON "취소", IDCANCEL,58,122,50,14
PUSHBUTTON "적용(&A)", IDC_APPLY_BUTTON,112,122,50,14,WS_DISABLED PUSHBUTTON "적용(&A)", IDC_APPLY_BUTTON,112,122,50,14,WS_DISABLED
PUSHBUTTON "도움말", IDHELP,166,122,50,14,WS_TABSTOP|WS_GROUP PUSHBUTTON "도움말", IDHELP,166,122,50,14,WS_TABSTOP|WS_GROUP
CONTROL "Tab", IDC_TABCONTROL,"SysTabControl32",WS_CLIPSIBLINGS|WS_GROUP|WS_TABSTOP|TCS_MULTILINE,4,4,212,114 CONTROL "", IDC_TABCONTROL,"SysTabControl32",WS_CLIPSIBLINGS|WS_GROUP|WS_TABSTOP|TCS_MULTILINE,4,4,212,114
END END
IDD_WIZARD DIALOG DISCARDABLE 0, 0, 290, 159 IDD_WIZARD DIALOG DISCARDABLE 0, 0, 290, 159
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Wizard" CAPTION "마법사"
FONT 9, "MS Shell Dlg" FONT 9, "MS Shell Dlg"
BEGIN BEGIN
PUSHBUTTON "< 이전(&B)", IDC_BACK_BUTTON,71,138,50,14 PUSHBUTTON "< 이전(&B)", IDC_BACK_BUTTON,71,138,50,14
@ -42,26 +43,26 @@ BEGIN
PUSHBUTTON "취소", IDCANCEL,178,138,50,14 PUSHBUTTON "취소", IDCANCEL,178,138,50,14
PUSHBUTTON "도움말", IDHELP,235,138,50,14,WS_GROUP PUSHBUTTON "도움말", IDHELP,235,138,50,14,WS_GROUP
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
CONTROL "Tab", IDC_TABCONTROL,"SysTabControl32",WS_CLIPSIBLINGS | WS_DISABLED,7,7,258,5 CONTROL "", IDC_TABCONTROL,"SysTabControl32",WS_CLIPSIBLINGS | WS_DISABLED,7,7,258,5
LTEXT "", IDC_SUNKEN_LINEHEADER,0,35,290,1,SS_LEFT | SS_SUNKEN | WS_CHILD | WS_VISIBLE LTEXT "", IDC_SUNKEN_LINEHEADER,0,35,290,1,SS_LEFT | SS_SUNKEN | WS_CHILD | WS_VISIBLE
END END
IDD_TBCUSTOMIZE DIALOG DISCARDABLE 10, 20, 357, 125 IDD_TBCUSTOMIZE DIALOG DISCARDABLE 10, 20, 357, 125
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Customize Toolbar" CAPTION "도구바 사용자 정의"
FONT 9, "MS Shell Dlg" FONT 9, "MS Shell Dlg"
BEGIN BEGIN
DEFPUSHBUTTON "닫기(&C)", IDCANCEL,308,6,44,14 DEFPUSHBUTTON "닫기(&C)", IDCANCEL,308,6,44,14
PUSHBUTTON "다시(&e)", IDC_RESET_BTN,308,23,44,14 PUSHBUTTON "다시(&e)", IDC_RESET_BTN,308,23,44,14
PUSHBUTTON "도움말(&H)", IDC_HELP_BTN,308,40,44,14 PUSHBUTTON "도움말(&H)", IDC_HELP_BTN,308,40,44,14
PUSHBUTTON "Move &Up", IDC_MOVEUP_BTN,308,74,44,14 PUSHBUTTON "위로 이동(&U)", IDC_MOVEUP_BTN,308,74,44,14
PUSHBUTTON "Move &Down", IDC_MOVEDN_BTN,308,91,44,14 PUSHBUTTON "아래로 이동(&D)", IDC_MOVEDN_BTN,308,91,44,14
LTEXT "A&vailable buttons:", -1,4,5,84,10 LTEXT "가능한 버튼(&v)", -1,4,5,84,10
LISTBOX IDC_AVAILBTN_LBOX,4,17,120,100, LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP LISTBOX IDC_AVAILBTN_LBOX,4,17,120,100, LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
PUSHBUTTON "&Add ->", IDOK, 131, 42, 44, 14 PUSHBUTTON "더하기(&A) ->", IDOK, 131, 42, 44, 14
PUSHBUTTON "<- &Remove", IDC_REMOVE_BTN,131,62,44,14 PUSHBUTTON "<- 제거하기(&R)", IDC_REMOVE_BTN,131,62,44,14
LTEXT "&Toolbar buttons:", -1,182,5,78,10 LTEXT "도구바 버튼(&T):", -1,182,5,78,10
LISTBOX IDC_TOOLBARBTN_LBOX, 182,17,120,100,LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP LISTBOX IDC_TOOLBARBTN_LBOX, 182,17,120,100,LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
END END
@ -73,10 +74,10 @@ STRINGTABLE DISCARDABLE
STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE
{ {
IDM_TODAY "오늘:" IDM_TODAY "오늘:"
IDM_GOTODAY "Go to today" IDM_GOTODAY "오늘로 가기"
} }
STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE
{ {
IDS_SEPARATOR "Separator" IDS_SEPARATOR "분리자"
} }

View file

@ -813,11 +813,10 @@ HEADER_GetItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode)
if (phdi->mask == 0) if (phdi->mask == 0)
return TRUE; return TRUE;
if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem)) if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
lpItem = NULL; return FALSE;
else
lpItem = &infoPtr->items[nItem]; lpItem = &infoPtr->items[nItem];
if (phdi->mask & HDI_BITMAP) if (phdi->mask & HDI_BITMAP)
phdi->hbm = (lpItem != NULL) ? lpItem->hbm : 0; phdi->hbm = (lpItem != NULL) ? lpItem->hbm : 0;

View file

@ -2131,9 +2131,9 @@ REBAR_CommonSetupBand (HWND hwnd, LPREBARBANDINFOA lprbbi, REBAR_BAND *lpBand)
lpBand->hwndChild = lprbbi->hwndChild; lpBand->hwndChild = lprbbi->hwndChild;
lpBand->hwndPrevParent = lpBand->hwndPrevParent =
SetParent (lpBand->hwndChild, hwnd); SetParent (lpBand->hwndChild, hwnd);
/* below in trace fro WinRAR */ /* below in trace from WinRAR */
ShowWindow(lpBand->hwndChild, SW_SHOWNOACTIVATE | SW_SHOWNORMAL); ShowWindow(lpBand->hwndChild, SW_SHOWNOACTIVATE | SW_SHOWNORMAL);
/* above in trace fro WinRAR */ /* above in trace from WinRAR */
} }
else { else {
TRACE("child: %p prev parent: %p\n", TRACE("child: %p prev parent: %p\n",

View file

@ -1,7 +1,7 @@
/* /*
* SysLink control * SysLink control
* *
* Copyright 2004 Thomas Weidenmueller <w3seek@reactos.com> * Copyright 2004, 2005 Thomas Weidenmueller <w3seek@reactos.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -25,12 +25,6 @@
* Unless otherwise noted, we believe this code to be complete, as per * Unless otherwise noted, we believe this code to be complete, as per
* the specification mentioned above. * the specification mentioned above.
* If you discover missing features, or bugs, please note them below. * If you discover missing features, or bugs, please note them below.
*
* TODO:
* - Fix SHIFT+TAB and TAB issue (wrong link is selected when control gets the focus)
* - Better string parsing
* - Improve word wrapping
*
*/ */
#include <stdarg.h> #include <stdarg.h>
@ -52,6 +46,7 @@ INT WINAPI StrCmpNIW(LPCWSTR,LPCWSTR,INT);
typedef struct typedef struct
{ {
int nChars; int nChars;
int nSkip;
RECT rc; RECT rc;
} DOC_TEXTBLOCK, *PDOC_TEXTBLOCK; } DOC_TEXTBLOCK, *PDOC_TEXTBLOCK;
@ -78,7 +73,6 @@ typedef struct _DOC_ITEM
UINT state; /* Link state */ UINT state; /* Link state */
WCHAR *szID; /* Link ID string */ WCHAR *szID; /* Link ID string */
WCHAR *szUrl; /* Link URL string */ WCHAR *szUrl; /* Link URL string */
HRGN hRgn; /* Region of the link */
} Link; } Link;
struct struct
{ {
@ -100,6 +94,7 @@ typedef struct
COLORREF TextColor; /* Color of the text */ COLORREF TextColor; /* Color of the text */
COLORREF LinkColor; /* Color of links */ COLORREF LinkColor; /* Color of links */
COLORREF VisitedColor; /* Color of visited links */ COLORREF VisitedColor; /* Color of visited links */
WCHAR BreakChar; /* Break Character for the current font */
} SYSLINK_INFO; } SYSLINK_INFO;
static const WCHAR SL_LINKOPEN[] = { '<','a', 0 }; static const WCHAR SL_LINKOPEN[] = { '<','a', 0 };
@ -126,11 +121,6 @@ static VOID SYSLINK_FreeDocItem (PDOC_ITEM DocItem)
Free(DocItem->u.Link.szUrl); Free(DocItem->u.Link.szUrl);
} }
if(DocItem->Type == slLink && DocItem->u.Link.hRgn != NULL)
{
DeleteObject(DocItem->u.Link.hRgn);
}
/* we don't free Text because it's just a pointer to a character in the /* we don't free Text because it's just a pointer to a character in the
entire window text string */ entire window text string */
@ -215,9 +205,8 @@ static UINT SYSLINK_ParseText (SYSLINK_INFO *infoPtr, LPCWSTR Text)
{ {
BOOL ValidParam = FALSE, ValidLink = FALSE; BOOL ValidParam = FALSE, ValidLink = FALSE;
switch (*(current + 2)) if(*(current + 2) == '>')
{ {
case '>':
/* we just have to deal with a <a> tag */ /* we just have to deal with a <a> tag */
taglen = 3; taglen = 3;
ValidLink = TRUE; ValidLink = TRUE;
@ -226,8 +215,8 @@ static UINT SYSLINK_ParseText (SYSLINK_INFO *infoPtr, LPCWSTR Text)
linklen = 0; linklen = 0;
lpID = NULL; lpID = NULL;
lpUrl = NULL; lpUrl = NULL;
break; }
case ' ': else if(*(current + 2) == infoPtr->BreakChar)
{ {
/* we expect parameters, parse them */ /* we expect parameters, parse them */
LPCWSTR *CurrentParameter = NULL, tmp; LPCWSTR *CurrentParameter = NULL, tmp;
@ -285,27 +274,22 @@ CheckParameter:
* 1. another parameter is coming, so expect a ' ' (space) character * 1. another parameter is coming, so expect a ' ' (space) character
* 2. the tag is being closed, so expect a '<' character * 2. the tag is being closed, so expect a '<' character
*/ */
switch(*tmp) if(*tmp == infoPtr->BreakChar)
{ {
case ' ':
/* we expect another parameter, do the whole thing again */ /* we expect another parameter, do the whole thing again */
taglen++; taglen++;
tmp++; tmp++;
goto CheckParameter; goto CheckParameter;
}
case '>': else if(*tmp == '>')
{
/* the tag is being closed, we're done */ /* the tag is being closed, we're done */
ValidLink = TRUE; ValidLink = TRUE;
taglen++; taglen++;
break;
default:
tmp++;
break;
} }
else
tmp++;
} }
break;
}
} }
if(ValidLink && ValidParam) if(ValidLink && ValidParam)
@ -495,16 +479,26 @@ CheckParameter:
*/ */
static VOID SYSLINK_RepaintLink (SYSLINK_INFO *infoPtr, PDOC_ITEM DocItem) static VOID SYSLINK_RepaintLink (SYSLINK_INFO *infoPtr, PDOC_ITEM DocItem)
{ {
PDOC_TEXTBLOCK bl;
int n;
if(DocItem->Type != slLink) if(DocItem->Type != slLink)
{ {
ERR("DocItem not a link!\n"); ERR("DocItem not a link!\n");
return; return;
} }
if(DocItem->u.Link.hRgn != NULL) bl = DocItem->Blocks;
if (bl != NULL)
{ {
/* repaint the region */ n = DocItem->nText;
RedrawWindow(infoPtr->Self, NULL, DocItem->u.Link.hRgn, RDW_INVALIDATE | RDW_UPDATENOW);
while(n > 0)
{
InvalidateRect(infoPtr->Self, &bl->rc, TRUE);
n -= bl->nChars + bl->nSkip;
bl++;
}
} }
} }
@ -615,7 +609,8 @@ static PDOC_ITEM SYSLINK_GetPrevLink (SYSLINK_INFO *infoPtr, PDOC_ITEM Current)
* SYSLINK_WrapLine * SYSLINK_WrapLine
* Tries to wrap a line. * Tries to wrap a line.
*/ */
static BOOL SYSLINK_WrapLine (HDC hdc, LPWSTR Text, WCHAR BreakChar, int *LineLen, int nFit, LPSIZE Extent, int Width) static BOOL SYSLINK_WrapLine (HDC hdc, LPWSTR Text, WCHAR BreakChar, int *LineLen,
int nFit, LPSIZE Extent, int Width)
{ {
WCHAR *Current; WCHAR *Current;
@ -659,7 +654,6 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
PDOC_ITEM Current; PDOC_ITEM Current;
HGDIOBJ hOldFont; HGDIOBJ hOldFont;
int x, y, LineHeight; int x, y, LineHeight;
TEXTMETRICW tm;
GetClientRect(infoPtr->Self, &rc); GetClientRect(infoPtr->Self, &rc);
rc.right -= SL_RIGHTMARGIN; rc.right -= SL_RIGHTMARGIN;
@ -668,7 +662,6 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
if(rc.right - SL_LEFTMARGIN < 0 || rc.bottom - SL_TOPMARGIN < 0) return; if(rc.right - SL_LEFTMARGIN < 0 || rc.bottom - SL_TOPMARGIN < 0) return;
hOldFont = SelectObject(hdc, infoPtr->Font); hOldFont = SelectObject(hdc, infoPtr->Font);
GetTextMetricsW(hdc, &tm);
x = SL_LEFTMARGIN; x = SL_LEFTMARGIN;
y = SL_TOPMARGIN; y = SL_TOPMARGIN;
@ -684,13 +677,18 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
if(Current->nText == 0) if(Current->nText == 0)
{ {
ERR("DOC_ITEM with no text?!\n");
continue; continue;
} }
tx = Current->Text; tx = Current->Text;
n = Current->nText; n = Current->nText;
bl = Current->Blocks;
if (Current->Blocks != NULL)
{
Free(Current->Blocks);
Current->Blocks = NULL;
}
bl = NULL;
nBlocks = 0; nBlocks = 0;
if(Current->Type == slText) if(Current->Type == slText)
@ -704,41 +702,80 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
while(n > 0) while(n > 0)
{ {
if(GetTextExtentExPointW(hdc, tx, n, rc.right - x, &nFit, NULL, &szDim)) int SkipChars = 0;
/* skip break characters unless they're the first of the doc item */
if(tx != Current->Text || x == SL_LEFTMARGIN)
{
while(n > 0 && (*tx) == infoPtr->BreakChar)
{
tx++;
SkipChars++;
n--;
}
}
if((n == 0 && SkipChars != 0) ||
GetTextExtentExPointW(hdc, tx, n, rc.right - x, &nFit, NULL, &szDim))
{ {
int LineLen = n; int LineLen = n;
BOOL Wrap = SYSLINK_WrapLine(hdc, tx, tm.tmBreakChar, &LineLen, nFit, &szDim, rc.right - x); BOOL Wrap = FALSE;
if(LineLen == 0) if(n != 0)
{ {
if(x > SL_LEFTMARGIN) Wrap = SYSLINK_WrapLine(hdc, tx, infoPtr->BreakChar, &LineLen, nFit, &szDim, rc.right - x);
if(LineLen == 0)
{ {
/* move one line down, the word didn't fit into the line */ if(x > SL_LEFTMARGIN)
x = SL_LEFTMARGIN; {
y += LineHeight; /* move one line down, the word didn't fit into the line */
LineHeight = 0; x = SL_LEFTMARGIN;
continue; y += LineHeight;
LineHeight = 0;
continue;
}
else
{
/* the word starts at the beginning of the line and doesn't
fit into the line, so break it at the last character that fits */
LineLen = max(nFit, 1);
}
} }
else
if(LineLen != n)
{ {
/* the word starts at the beginning of the line and doesn't if(!GetTextExtentExPointW(hdc, tx, LineLen, rc.right - x, NULL, NULL, &szDim))
fit into the line, so break it at the last character that fits */ {
LineLen = max(nFit, 1); if(bl != NULL)
{
Free(bl);
bl = NULL;
}
break;
}
} }
} }
if(LineLen != n)
{
GetTextExtentExPointW(hdc, tx, LineLen, rc.right - x, NULL, NULL, &szDim);
}
if(bl != NULL) if(bl != NULL)
{ {
bl = ReAlloc(bl, ++nBlocks * sizeof(DOC_TEXTBLOCK)); PDOC_TEXTBLOCK nbl = ReAlloc(bl, (nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
if (nbl != NULL)
{
bl = nbl;
nBlocks++;
}
else
{
Free(bl);
bl = NULL;
}
} }
else else
{ {
bl = Alloc(++nBlocks * sizeof(DOC_TEXTBLOCK)); bl = Alloc((nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
if (bl != NULL)
nBlocks++;
} }
if(bl != NULL) if(bl != NULL)
@ -746,41 +783,23 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
cbl = bl + nBlocks - 1; cbl = bl + nBlocks - 1;
cbl->nChars = LineLen; cbl->nChars = LineLen;
cbl->nSkip = SkipChars;
cbl->rc.left = x; cbl->rc.left = x;
cbl->rc.top = y; cbl->rc.top = y;
cbl->rc.right = x + szDim.cx; cbl->rc.right = x + szDim.cx;
cbl->rc.bottom = y + szDim.cy; cbl->rc.bottom = y + szDim.cy;
x += szDim.cx; if(LineLen != 0)
LineHeight = max(LineHeight, szDim.cy);
/* (re)calculate the link's region */
if(Current->Type == slLink)
{ {
if(nBlocks <= 1) x += szDim.cx;
LineHeight = max(LineHeight, szDim.cy);
if(Wrap)
{ {
if(Current->u.Link.hRgn != NULL) x = SL_LEFTMARGIN;
{ y += LineHeight;
DeleteObject(Current->u.Link.hRgn); LineHeight = 0;
}
/* initialize the link's hRgn */
Current->u.Link.hRgn = CreateRectRgnIndirect(&cbl->rc);
} }
else if(Current->u.Link.hRgn != NULL)
{
HRGN hrgn;
hrgn = CreateRectRgnIndirect(&cbl->rc);
/* add the rectangle */
CombineRgn(Current->u.Link.hRgn, Current->u.Link.hRgn, hrgn, RGN_OR);
DeleteObject(hrgn);
}
}
if(Wrap)
{
x = SL_LEFTMARGIN;
y += LineHeight;
LineHeight = 0;
} }
} }
else else
@ -793,11 +812,16 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
} }
else else
{ {
ERR("GetTextExtentExPoint() failed?!\n");
n--; n--;
} }
} }
Current->Blocks = bl;
if(nBlocks != 0)
{
Current->Blocks = bl;
}
else
Current->Blocks = NULL;
} }
SelectObject(hdc, hOldFont); SelectObject(hdc, hOldFont);
@ -849,6 +873,7 @@ static LRESULT SYSLINK_Draw (SYSLINK_INFO *infoPtr, HDC hdc)
while(n > 0) while(n > 0)
{ {
tx += bl->nSkip;
ExtTextOutW(hdc, bl->rc.left, bl->rc.top, ETO_OPAQUE | ETO_CLIPPED, &bl->rc, tx, bl->nChars, NULL); ExtTextOutW(hdc, bl->rc.left, bl->rc.top, ETO_OPAQUE | ETO_CLIPPED, &bl->rc, tx, bl->nChars, NULL);
if((Current->Type == slLink) && (Current->u.Link.state & LIS_FOCUSED) && infoPtr->HasFocus) if((Current->Type == slLink) && (Current->u.Link.state & LIS_FOCUSED) && infoPtr->HasFocus)
{ {
@ -858,7 +883,7 @@ static LRESULT SYSLINK_Draw (SYSLINK_INFO *infoPtr, HDC hdc)
SetBkColor(hdc, PrevColor); SetBkColor(hdc, PrevColor);
} }
tx += bl->nChars; tx += bl->nChars;
n -= bl->nChars; n -= bl->nChars + bl->nSkip;
bl++; bl++;
} }
} }
@ -896,6 +921,7 @@ static HFONT SYSLINK_SetFont (SYSLINK_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
{ {
HDC hdc; HDC hdc;
LOGFONTW lf; LOGFONTW lf;
TEXTMETRICW tm;
HFONT hOldFont = infoPtr->Font; HFONT hOldFont = infoPtr->Font;
infoPtr->Font = hFont; infoPtr->Font = hFont;
@ -911,10 +937,12 @@ static HFONT SYSLINK_SetFont (SYSLINK_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
if(hdc != NULL) if(hdc != NULL)
{ {
/* create a new underline font */ /* create a new underline font */
if(GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf)) if(GetTextMetricsW(hdc, &tm) &&
GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf))
{ {
lf.lfUnderline = TRUE; lf.lfUnderline = TRUE;
infoPtr->LinkFont = CreateFontIndirectW(&lf); infoPtr->LinkFont = CreateFontIndirectW(&lf);
infoPtr->BreakChar = tm.tmBreakChar;
} }
else else
{ {
@ -1132,6 +1160,34 @@ static LRESULT SYSLINK_GetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
return TRUE; return TRUE;
} }
/***********************************************************************
* SYSLINK_PtInDocItem
* Determines if a point is in the region of a document item
*/
static BOOL SYSLINK_PtInDocItem (PDOC_ITEM DocItem, POINT pt)
{
PDOC_TEXTBLOCK bl;
int n;
bl = DocItem->Blocks;
if (bl != NULL)
{
n = DocItem->nText;
while(n > 0)
{
if (PtInRect(&bl->rc, pt))
{
return TRUE;
}
n -= bl->nChars + bl->nSkip;
bl++;
}
}
return FALSE;
}
/*********************************************************************** /***********************************************************************
* SYSLINK_HitTest * SYSLINK_HitTest
* Determines the link the user clicked on. * Determines the link the user clicked on.
@ -1145,8 +1201,7 @@ static LRESULT SYSLINK_HitTest (SYSLINK_INFO *infoPtr, PLHITTESTINFO HitTest)
{ {
if(Current->Type == slLink) if(Current->Type == slLink)
{ {
if((Current->u.Link.hRgn != NULL) && if(SYSLINK_PtInDocItem(Current, HitTest->pt))
PtInRegion(Current->u.Link.hRgn, HitTest->pt.x, HitTest->pt.y))
{ {
HitTest->item.mask = 0; HitTest->item.mask = 0;
HitTest->item.iLink = id; HitTest->item.iLink = id;
@ -1252,25 +1307,13 @@ static LRESULT SYSLINK_SetFocus (SYSLINK_INFO *infoPtr, HWND PrevFocusWindow)
infoPtr->HasFocus = TRUE; infoPtr->HasFocus = TRUE;
#if 1 /* We always select the first link, even if we activated the control using
/* FIXME - How to detect whether SHIFT+TAB or just TAB has been pressed? SHIFT+TAB. This is the default behavior */
* The problem is we could get this message without keyboard input, too
*/
Focus = SYSLINK_GetFocusLink(infoPtr, NULL);
if(Focus == NULL && (Focus = SYSLINK_GetNextLink(infoPtr, NULL)))
{
SYSLINK_SetFocusLink(infoPtr, Focus);
}
#else
/* This is a temporary hack since I'm not really sure how to detect which link to select.
See message above! */
Focus = SYSLINK_GetNextLink(infoPtr, NULL); Focus = SYSLINK_GetNextLink(infoPtr, NULL);
if(Focus != NULL) if(Focus != NULL)
{ {
SYSLINK_SetFocusLink(infoPtr, Focus); SYSLINK_SetFocusLink(infoPtr, Focus);
} }
#endif
SYSLINK_RepaintLink(infoPtr, Focus); SYSLINK_RepaintLink(infoPtr, Focus);
@ -1307,8 +1350,7 @@ static PDOC_ITEM SYSLINK_LinkAtPt (SYSLINK_INFO *infoPtr, POINT *pt, int *LinkId
for(Current = infoPtr->Items; Current != NULL; Current = Current->Next) for(Current = infoPtr->Items; Current != NULL; Current = Current->Next)
{ {
if((Current->Type == slLink) && (Current->u.Link.hRgn != NULL) && if((Current->Type == slLink) && SYSLINK_PtInDocItem(Current, *pt) &&
PtInRegion(Current->u.Link.hRgn, pt->x, pt->y) &&
(!MustBeEnabled || (MustBeEnabled && (Current->u.Link.state & LIS_ENABLED)))) (!MustBeEnabled || (MustBeEnabled && (Current->u.Link.state & LIS_ENABLED))))
{ {
if(LinkId != NULL) if(LinkId != NULL)
@ -1335,6 +1377,8 @@ static LRESULT SYSLINK_LButtonDown (SYSLINK_INFO *infoPtr, DWORD Buttons, POINT
Current = SYSLINK_LinkAtPt(infoPtr, pt, &id, TRUE); Current = SYSLINK_LinkAtPt(infoPtr, pt, &id, TRUE);
if(Current != NULL) if(Current != NULL)
{ {
SetFocus(infoPtr->Self);
Old = SYSLINK_SetFocusLink(infoPtr, Current); Old = SYSLINK_SetFocusLink(infoPtr, Current);
if(Old != NULL && Old != Current) if(Old != NULL && Old != Current)
{ {
@ -1342,7 +1386,6 @@ static LRESULT SYSLINK_LButtonDown (SYSLINK_INFO *infoPtr, DWORD Buttons, POINT
} }
infoPtr->MouseDownID = id; infoPtr->MouseDownID = id;
SYSLINK_RepaintLink(infoPtr, Current); SYSLINK_RepaintLink(infoPtr, Current);
SetFocus(infoPtr->Self);
} }
return 0; return 0;
@ -1460,7 +1503,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
infoPtr = (SYSLINK_INFO *)GetWindowLongPtrW(hwnd, 0); infoPtr = (SYSLINK_INFO *)GetWindowLongPtrW(hwnd, 0);
if (!infoPtr && message != WM_CREATE) if (!infoPtr && message != WM_CREATE)
return DefWindowProcW( hwnd, message, wParam, lParam ); goto HandleDefaultMessage;
switch(message) { switch(message) {
case WM_PRINTCLIENT: case WM_PRINTCLIENT:
@ -1482,8 +1525,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
return TRUE; return TRUE;
} }
/* let the default window proc handle this message */ /* let the default window proc handle this message */
return DefWindowProcW(hwnd, message, wParam, lParam); goto HandleDefaultMessage;
} }
case WM_SIZE: case WM_SIZE:
@ -1505,7 +1547,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
case WM_SETTEXT: case WM_SETTEXT:
SYSLINK_SetText(infoPtr, (LPWSTR)lParam); SYSLINK_SetText(infoPtr, (LPWSTR)lParam);
return DefWindowProcW(hwnd, message, wParam, lParam); goto HandleDefaultMessage;
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
{ {
@ -1536,7 +1578,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
return 0; return 0;
} }
} }
return DefWindowProcW(hwnd, message, wParam, lParam); goto HandleDefaultMessage;
} }
case WM_GETDLGCODE: case WM_GETDLGCODE:
@ -1638,6 +1680,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
infoPtr->TextColor = GetSysColor(COLOR_WINDOWTEXT); infoPtr->TextColor = GetSysColor(COLOR_WINDOWTEXT);
infoPtr->LinkColor = GetSysColor(COLOR_HIGHLIGHT); infoPtr->LinkColor = GetSysColor(COLOR_HIGHLIGHT);
infoPtr->VisitedColor = GetSysColor(COLOR_HIGHLIGHT); infoPtr->VisitedColor = GetSysColor(COLOR_HIGHLIGHT);
infoPtr->BreakChar = ' ';
TRACE("SysLink Ctrl creation, hwnd=%p\n", hwnd); TRACE("SysLink Ctrl creation, hwnd=%p\n", hwnd);
SYSLINK_SetText(infoPtr, ((LPCREATESTRUCTW)lParam)->lpszName); SYSLINK_SetText(infoPtr, ((LPCREATESTRUCTW)lParam)->lpszName);
return 0; return 0;
@ -1652,8 +1695,11 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
return 0; return 0;
default: default:
HandleDefaultMessage:
if ((message >= WM_USER) && (message < WM_APP)) if ((message >= WM_USER) && (message < WM_APP))
ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam ); {
ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam );
}
return DefWindowProcW(hwnd, message, wParam, lParam); return DefWindowProcW(hwnd, message, wParam, lParam);
} }
} }

View file

@ -1507,7 +1507,7 @@ TOOLTIPS_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
/* NB this API is broken, there is no way for the app to determine /* NB this API is broken, there is no way for the app to determine
what size buffer it requires nor a way to specify how long the what size buffer it requires nor a way to specify how long the
one it supplies is. We'll assume it's upto INFOTIPSIZE */ one it supplies is. We'll assume it's up to INFOTIPSIZE */
WideCharToMultiByte(CP_ACP, 0, infoPtr->tools[nTool].lpszText, -1, WideCharToMultiByte(CP_ACP, 0, infoPtr->tools[nTool].lpszText, -1,
lpToolInfo->lpszText, INFOTIPSIZE, NULL, NULL); lpToolInfo->lpszText, INFOTIPSIZE, NULL, NULL);