Module: wine Branch: master Commit: 254b97732befd7e7bd29f369d2878ef38bfd4488 URL: http://source.winehq.org/git/wine.git/?a=commit;h=254b97732befd7e7bd29f369d2...
Author: Thomas Weidenmueller wine-patches@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)