Thomas Weidenmueller : comctl32:
Implement LM_GETIDEALSIZE for the syslink control.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Feb 20 14:18:49 CST 2007
Module: wine
Branch: master
Commit: 254b97732befd7e7bd29f369d2878ef38bfd4488
URL: http://source.winehq.org/git/wine.git/?a=commit;h=254b97732befd7e7bd29f369d2878ef38bfd4488
Author: Thomas Weidenmueller <wine-patches at reactsoft.com>
Date: Mon Feb 19 16:25:01 2007 +0100
comctl32: Implement LM_GETIDEALSIZE for the syslink control.
---
dlls/comctl32/syslink.c | 163 ++++++++++++++++++++++++++++++-----------------
include/commctrl.h | 1 +
2 files changed, 106 insertions(+), 58 deletions(-)
diff --git a/dlls/comctl32/syslink.c b/dlls/comctl32/syslink.c
index 304e407..d631244 100644
--- a/dlls/comctl32/syslink.c
+++ b/dlls/comctl32/syslink.c
@@ -643,18 +643,24 @@ static BOOL SYSLINK_WrapLine (HDC hdc, LPWSTR Text, WCHAR BreakChar, int *LineLe
* SYSLINK_Render
* Renders the document in memory
*/
-static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
+static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc, PRECT pRect)
{
RECT rc;
PDOC_ITEM Current;
HGDIOBJ hOldFont;
int x, y, LineHeight;
-
- GetClientRect(infoPtr->Self, &rc);
+ SIZE szDoc;
+
+ szDoc.cx = szDoc.cy = 0;
+
+ rc = *pRect;
rc.right -= SL_RIGHTMARGIN;
rc.bottom -= SL_BOTTOMMARGIN;
-
- if(rc.right - SL_LEFTMARGIN < 0 || rc.bottom - SL_TOPMARGIN < 0) return;
+
+ if(rc.right - SL_LEFTMARGIN < 0)
+ rc.right = MAXLONG;
+ if (rc.bottom - SL_TOPMARGIN < 0)
+ rc.bottom = MAXLONG;
hOldFont = SelectObject(hdc, infoPtr->Font);
@@ -715,6 +721,7 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
{
int LineLen = n;
BOOL Wrap = FALSE;
+ PDOC_TEXTBLOCK nbl;
if(n != 0)
{
@@ -753,30 +760,12 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
}
}
- if(bl != NULL)
- {
- PDOC_TEXTBLOCK nbl = ReAlloc(bl, (nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
- if (nbl != NULL)
- {
- bl = nbl;
- nBlocks++;
- }
- else
- {
- Free(bl);
- bl = NULL;
- nBlocks = 0;
- }
- }
- else
- {
- bl = Alloc(sizeof(DOC_TEXTBLOCK));
- if (bl != NULL)
- nBlocks++;
- }
-
- if(bl != NULL)
+ nbl = ReAlloc(bl, (nBlocks + 1) * sizeof(DOC_TEXTBLOCK));
+ if (nbl != NULL)
{
+ bl = nbl;
+ nBlocks++;
+
cbl = bl + nBlocks - 1;
cbl->nChars = LineLen;
@@ -785,7 +774,12 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
cbl->rc.top = y;
cbl->rc.right = x + szDim.cx;
cbl->rc.bottom = y + szDim.cy;
-
+
+ if (cbl->rc.right > szDoc.cx)
+ szDoc.cx = cbl->rc.right;
+ if (cbl->rc.bottom > szDoc.cy)
+ szDoc.cy = cbl->rc.bottom;
+
if(LineLen != 0)
{
x += szDim.cx;
@@ -801,6 +795,10 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
}
else
{
+ Free(bl);
+ bl = NULL;
+ nBlocks = 0;
+
ERR("Failed to alloc DOC_TEXTBLOCK structure!\n");
break;
}
@@ -820,6 +818,9 @@ static VOID SYSLINK_Render (SYSLINK_INFO *infoPtr, HDC hdc)
}
SelectObject(hdc, hOldFont);
+
+ pRect->right = pRect->left + szDoc.cx;
+ pRect->bottom = pRect->top + szDoc.cy;
}
/***********************************************************************
@@ -920,6 +921,7 @@ static HFONT SYSLINK_SetFont (SYSLINK_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
HDC hdc;
LOGFONTW lf;
TEXTMETRICW tm;
+ RECT rcClient;
HFONT hOldFont = infoPtr->Font;
infoPtr->Font = hFont;
@@ -931,24 +933,27 @@ static HFONT SYSLINK_SetFont (SYSLINK_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
}
/* Render text position and word wrapping in memory */
- hdc = GetDC(infoPtr->Self);
- if(hdc != NULL)
+ if (GetClientRect(infoPtr->Self, &rcClient))
{
- /* create a new underline font */
- if(GetTextMetricsW(hdc, &tm) &&
- GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf))
- {
- lf.lfUnderline = TRUE;
- infoPtr->LinkFont = CreateFontIndirectW(&lf);
- infoPtr->BreakChar = tm.tmBreakChar;
- }
- else
+ hdc = GetDC(infoPtr->Self);
+ if(hdc != NULL)
{
- ERR("Failed to create link font!\n");
- }
+ /* create a new underline font */
+ if(GetTextMetricsW(hdc, &tm) &&
+ GetObjectW(infoPtr->Font, sizeof(LOGFONTW), &lf))
+ {
+ lf.lfUnderline = TRUE;
+ infoPtr->LinkFont = CreateFontIndirectW(&lf);
+ infoPtr->BreakChar = tm.tmBreakChar;
+ }
+ else
+ {
+ ERR("Failed to create link font!\n");
+ }
- SYSLINK_Render(infoPtr, hdc);
- ReleaseDC(infoPtr->Self, hdc);
+ SYSLINK_Render(infoPtr, hdc, &rcClient);
+ ReleaseDC(infoPtr->Self, hdc);
+ }
}
if(bRedraw)
@@ -978,14 +983,19 @@ static LRESULT SYSLINK_SetText (SYSLINK_INFO *infoPtr, LPCWSTR Text)
/* let's parse the string and create a document */
if(SYSLINK_ParseText(infoPtr, Text) > 0)
{
+ RECT rcClient;
+
/* Render text position and word wrapping in memory */
- HDC hdc = GetDC(infoPtr->Self);
- if (hdc != NULL)
+ if (GetClientRect(infoPtr->Self, &rcClient))
{
- SYSLINK_Render(infoPtr, hdc);
- ReleaseDC(infoPtr->Self, hdc);
+ HDC hdc = GetDC(infoPtr->Self);
+ if (hdc != NULL)
+ {
+ SYSLINK_Render(infoPtr, hdc, &rcClient);
+ ReleaseDC(infoPtr->Self, hdc);
- InvalidateRect(infoPtr->Self, NULL, TRUE);
+ InvalidateRect(infoPtr->Self, NULL, TRUE);
+ }
}
}
@@ -1076,6 +1086,7 @@ static LRESULT SYSLINK_SetItem (SYSLINK_INFO *infoPtr, PLITEM Item)
else
{
Free(szId);
+
ERR("Unable to allocate memory for link url\n");
return FALSE;
}
@@ -1503,6 +1514,33 @@ static BOOL SYSLINK_NoNextLink (SYSLINK_INFO *infoPtr, BOOL Prev)
}
/***********************************************************************
+ * SYSLINK_GetIdealSize
+ * Calculates the ideal size of a link control at a given maximum width.
+ */
+static VOID SYSLINK_GetIdealSize (SYSLINK_INFO *infoPtr, int cxMaxWidth, LPSIZE lpSize)
+{
+ RECT rc;
+ HDC hdc;
+
+ rc.left = rc.top = rc.bottom = 0;
+ rc.right = cxMaxWidth;
+
+ hdc = GetDC(infoPtr->Self);
+ if (hdc != NULL)
+ {
+ HGDIOBJ hOldFont = SelectObject(hdc, infoPtr->Font);
+
+ SYSLINK_Render(infoPtr, hdc, &rc);
+
+ SelectObject(hdc, hOldFont);
+ ReleaseDC(infoPtr->Self, hdc);
+
+ lpSize->cx = rc.right;
+ lpSize->cy = rc.bottom;
+ }
+}
+
+/***********************************************************************
* SysLinkWindowProc
*/
static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
@@ -1542,11 +1580,15 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
case WM_SIZE:
{
- HDC hdc = GetDC(infoPtr->Self);
- if(hdc != NULL)
+ RECT rcClient;
+ if (GetClientRect(infoPtr->Self, &rcClient))
{
- SYSLINK_Render(infoPtr, hdc);
- ReleaseDC(infoPtr->Self, hdc);
+ HDC hdc = GetDC(infoPtr->Self);
+ if(hdc != NULL)
+ {
+ SYSLINK_Render(infoPtr, hdc, &rcClient);
+ ReleaseDC(infoPtr->Self, hdc);
+ }
}
return 0;
}
@@ -1651,6 +1693,11 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
return SYSLINK_GetItem(infoPtr, (PLITEM)lParam);
case LM_GETIDEALHEIGHT:
+ if (lParam)
+ {
+ /* LM_GETIDEALSIZE */
+ SYSLINK_GetIdealSize(infoPtr, (int)wParam, (LPSIZE)lParam);
+ }
return SYSLINK_GetIdealHeight(infoPtr);
case WM_SETFOCUS:
@@ -1660,10 +1707,10 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
return SYSLINK_KillFocus(infoPtr, (HWND)wParam);
case WM_ENABLE:
- infoPtr->Style &= ~WS_DISABLED;
- infoPtr->Style |= (wParam ? 0 : WS_DISABLED);
- InvalidateRect (infoPtr->Self, NULL, FALSE);
- return 0;
+ infoPtr->Style &= ~WS_DISABLED;
+ infoPtr->Style |= (wParam ? 0 : WS_DISABLED);
+ InvalidateRect (infoPtr->Self, NULL, FALSE);
+ return 0;
case WM_STYLECHANGED:
if (wParam == GWL_STYLE)
@@ -1710,7 +1757,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
HandleDefaultMessage:
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);
}
diff --git a/include/commctrl.h b/include/commctrl.h
index 1415a30..3225e1b 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -4889,6 +4889,7 @@ static const WCHAR WC_LINK[] = { 'S','y','s','L','i','n','k',0 };
/* SysLink messages */
#define LM_HITTEST (WM_USER + 768)
#define LM_GETIDEALHEIGHT (WM_USER + 769)
+#define LM_GETIDEALSIZE (LM_GETIDEALHEIGHT)
#define LM_SETITEM (WM_USER + 770)
#define LM_GETITEM (WM_USER + 771)
More information about the wine-cvs
mailing list