Improved word wrapping and tab key handling.
This commit is contained in:
parent
8bbde0c4d4
commit
36f6bbb85c
|
@ -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,26 +274,21 @@ 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:
|
else
|
||||||
tmp++;
|
tmp++;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,10 +702,28 @@ 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(n != 0)
|
||||||
|
{
|
||||||
|
Wrap = SYSLINK_WrapLine(hdc, tx, infoPtr->BreakChar, &LineLen, nFit, &szDim, rc.right - x);
|
||||||
|
|
||||||
if(LineLen == 0)
|
if(LineLen == 0)
|
||||||
{
|
{
|
||||||
|
@ -729,16 +745,37 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
|
||||||
|
|
||||||
if(LineLen != n)
|
if(LineLen != n)
|
||||||
{
|
{
|
||||||
GetTextExtentExPointW(hdc, tx, LineLen, rc.right - x, NULL, NULL, &szDim);
|
if(!GetTextExtentExPointW(hdc, tx, LineLen, rc.right - x, NULL, NULL, &szDim))
|
||||||
|
{
|
||||||
|
if(bl != NULL)
|
||||||
|
{
|
||||||
|
Free(bl);
|
||||||
|
bl = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
bl = Alloc(++nBlocks * sizeof(DOC_TEXTBLOCK));
|
Free(bl);
|
||||||
|
bl = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bl = Alloc((nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
|
||||||
|
if (bl != NULL)
|
||||||
|
nBlocks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bl != NULL)
|
if(bl != NULL)
|
||||||
|
@ -746,36 +783,17 @@ 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;
|
||||||
|
|
||||||
|
if(LineLen != 0)
|
||||||
|
{
|
||||||
x += szDim.cx;
|
x += szDim.cx;
|
||||||
LineHeight = max(LineHeight, szDim.cy);
|
LineHeight = max(LineHeight, szDim.cy);
|
||||||
|
|
||||||
/* (re)calculate the link's region */
|
|
||||||
if(Current->Type == slLink)
|
|
||||||
{
|
|
||||||
if(nBlocks <= 1)
|
|
||||||
{
|
|
||||||
if(Current->u.Link.hRgn != NULL)
|
|
||||||
{
|
|
||||||
DeleteObject(Current->u.Link.hRgn);
|
|
||||||
}
|
|
||||||
/* 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)
|
if(Wrap)
|
||||||
{
|
{
|
||||||
x = SL_LEFTMARGIN;
|
x = SL_LEFTMARGIN;
|
||||||
|
@ -783,6 +801,7 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
|
||||||
LineHeight = 0;
|
LineHeight = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Failed to alloc DOC_TEXTBLOCK structure!\n");
|
ERR("Failed to alloc DOC_TEXTBLOCK structure!\n");
|
||||||
|
@ -793,12 +812,17 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("GetTextExtentExPoint() failed?!\n");
|
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(nBlocks != 0)
|
||||||
|
{
|
||||||
Current->Blocks = bl;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue