/** * @brief Populate ListBox with names/revisions of DLLs matching given pattern. */ static void NTAPI DlgDirListDLLs(HWND hWnd, LPTSTR cPattern, int nIDListBox) { HDC hDC = GetDC(hWnd); HFONT hFont = (HFONT)SendDlgItemMessage(hWnd, nIDListBox, WM_GETFONT, 0, 0); int cxView = (int)SendDlgItemMessage(hWnd, nIDListBox, LB_GETHORIZONTALEXTENT, 0, 0) - 8; HGDIOBJ hObject = SelectObject(hDC, hFont); WIN32_FIND_DATA ff; HANDLE h = FindFirstFile(cPattern, &ff); if (h != INVALID_HANDLE_VALUE) { do { PathRemoveFileSpec(cPattern); PathAppend(cPattern, ff.cFileName); wsprintf(ff.cFileName, _T(" (dllbuild %04u)"), GetDllBuild(cPattern)); lstrcat(cPattern, ff.cFileName); int cxText = (int)(WORD)GetTabbedTextExtent(hDC, cPattern, lstrlen(cPattern), 0, 0); if (cxView < cxText) cxView = cxText; SendDlgItemMessage(hWnd, nIDListBox, LB_ADDSTRING, 0, (LPARAM)cPattern); } while (FindNextFile(h, &ff)); FindClose(h); } SelectObject(hDC, hObject); ReleaseDC(hWnd, hDC); SendDlgItemMessage(hWnd, nIDListBox, LB_SETHORIZONTALEXTENT, cxView + 8, 0); }
ULONG FASTCALL WU32GetTabbedTextExtent(PVDMFRAME pFrame) { ULONG ul; PSZ psz2; PINT p5; register PGETTABBEDTEXTEXTENT16 parg16; INT BufferT[256]; GETARGPTR(pFrame, sizeof(GETTABBEDTEXTEXTENT16), parg16); GETPSZPTR(parg16->f2, psz2); p5 = STACKORHEAPALLOC(parg16->f4 * sizeof(INT), sizeof(BufferT), BufferT); getintarray16(parg16->f5, parg16->f4, p5); ul = GETDWORD16(GetTabbedTextExtent(HDC32(parg16->f1), psz2, INT32(parg16->f3), INT32(parg16->f4), p5 )); STACKORHEAPFREE(p5, BufferT); FREEPSZPTR(psz2); FREEARGPTR(parg16); RETURN(ul); }
void CalcTextExtent(HDC DC, PCHAR Text, LPSIZE s) { int W, H, i, i0; char Temp[512]; DWORD dwExt; W = 0; H = 0; i = 0; do { i0 = i; while ((Text[i]!=0) && (Text[i]!=0x0d) && (Text[i]!=0x0a)) i++; memcpy(Temp,&Text[i0],i-i0); Temp[i-i0] = 0; if (Temp[0]==0) { Temp[0] = 0x20; Temp[1] = 0; } dwExt = GetTabbedTextExtent(DC,Temp,strlen(Temp),0,NULL); s->cx = LOWORD(dwExt); s->cy = HIWORD(dwExt); if (s->cx > W) W = s->cx; H = H + s->cy; if (Text[i]!=0) { i++; if ((Text[i]==0x0a) && (Text[i-1]==0x0d)) i++; } } while (Text[i]!=0); if ((i-i0 == 0) && (H > s->cy)) H = H - s->cy; s->cx = W; s->cy = H; }
/** * @param dwCachedLineNum - index of cached line. */ void CTextView::CacheLine(DWORD dwCachedLineNum) { if (dwCachedLineNum >= m_dwFirstCachedLine && dwCachedLineNum < m_dwFirstCachedLine + m_dwNumCachedLines) return; HDC hdc = GetDC(m_hwnd); HFONT hOldFont = g_pResManager->m_hFixedFont ? SelectFont(hdc, g_pResManager->m_hFixedFont) : NULL; TEXTMETRIC tmetr; ::GetTextMetrics(hdc, &tmetr); int nExtraWidth = tmetr.tmAveCharWidth + LOWORD(GetTabbedTextExtent(hdc, g_szEllipsis, g_dwEllipsisLength, 0, NULL)); int nMaxLineWidth = 0; DWORD dwNumLines = m_arrLines.GetCount(); _ASSERT(dwCachedLineNum < dwNumLines); // Put new line into the middle of cache const CLineInfo& rLineInfo = m_arrLines[(int)dwCachedLineNum]; DWORD dwFirstCachedLine = dwCachedLineNum, dwLastCachedLine = dwCachedLineNum, dwTotalSize = rLineInfo.m_dwLength; BOOL bCanMoveFirstCachedLine = TRUE, bCanMoveLastCachedLine = TRUE; do { if (bCanMoveFirstCachedLine) { BOOL bLineNumberChanged = FALSE; if (dwFirstCachedLine > 0) { const CLineInfo& rLineInfo = m_arrLines[(int)(dwFirstCachedLine - 1)]; if (dwTotalSize + rLineInfo.m_dwLength <= TEXT_CACHE_SIZE) { dwTotalSize += rLineInfo.m_dwLength; --dwFirstCachedLine; bLineNumberChanged = TRUE; } } bCanMoveFirstCachedLine = bLineNumberChanged; } if (bCanMoveLastCachedLine) { BOOL bLineNumberChanged = FALSE; if (dwLastCachedLine + 1 < dwNumLines) { const CLineInfo& rLineInfo = m_arrLines[(int)(dwLastCachedLine + 1)]; if (dwTotalSize + rLineInfo.m_dwLength <= TEXT_CACHE_SIZE) { dwTotalSize += rLineInfo.m_dwLength; ++dwLastCachedLine; bLineNumberChanged = TRUE; } } bCanMoveLastCachedLine = bLineNumberChanged; } } while (bCanMoveFirstCachedLine || bCanMoveLastCachedLine); DWORD dwNumCachedLines = dwLastCachedLine - dwFirstCachedLine + 1; DWORD dwFirstMappedLine, dwLastMappedLine, dwNumMappedLines, dwFirstLoadedLine, dwLastLoadedLine, dwNumLoadedLines, dwFromMemOffset, dwToMemOffset, dwLoadOffset, dwMemSize; if (m_dwFirstCachedLine <= dwFirstCachedLine && dwFirstCachedLine < m_dwFirstCachedLine + m_dwNumCachedLines) { dwFirstMappedLine = dwFirstCachedLine; dwNumMappedLines = m_dwNumCachedLines - (dwFirstCachedLine - m_dwFirstCachedLine); dwLastMappedLine = dwFirstMappedLine + dwNumMappedLines - 1; dwFirstLoadedLine = dwFirstMappedLine + dwNumMappedLines; dwNumLoadedLines = dwNumCachedLines - dwNumMappedLines; dwLastLoadedLine = dwFirstLoadedLine + dwNumLoadedLines - 1; const CLineInfo& rLineInfo1 = m_arrLines[(int)dwFirstMappedLine]; const CLineInfo& rLineInfo2 = m_arrLines[(int)dwLastMappedLine]; dwFromMemOffset = rLineInfo1.m_dwTextStart; dwToMemOffset = 0; dwLoadOffset = dwMemSize = rLineInfo2.m_dwTextStart + rLineInfo2.m_dwLength - rLineInfo1.m_dwTextStart; } else if (dwFirstCachedLine <= m_dwFirstCachedLine && m_dwFirstCachedLine < dwFirstCachedLine + dwNumCachedLines) { dwFirstMappedLine = m_dwFirstCachedLine; dwNumMappedLines = dwNumCachedLines - (m_dwFirstCachedLine - dwFirstCachedLine); dwLastMappedLine = dwFirstMappedLine + dwNumMappedLines - 1; dwFirstLoadedLine = dwFirstCachedLine; dwNumLoadedLines = dwNumCachedLines - dwNumMappedLines; dwLastLoadedLine = dwFirstLoadedLine + dwNumLoadedLines - 1; const CLineInfo& rLineInfo1 = m_arrLines[(int)dwFirstMappedLine]; const CLineInfo& rLineInfo2 = m_arrLines[(int)dwLastMappedLine]; dwFromMemOffset = rLineInfo1.m_dwTextStart; dwToMemOffset = 0; dwMemSize = rLineInfo2.m_dwTextStart + rLineInfo2.m_dwLength - rLineInfo1.m_dwTextStart; for (DWORD dwLineNum = dwFirstLoadedLine; dwLineNum <= dwLastLoadedLine; ++dwLineNum) { const CLineInfo& rLineInfo = m_arrLines[(int)dwLineNum]; dwToMemOffset += rLineInfo.m_dwLength; } dwLoadOffset = 0; } else { dwFirstMappedLine = dwLastMappedLine = dwNumMappedLines = dwFromMemOffset = dwToMemOffset = dwMemSize = 0; dwFirstLoadedLine = dwFirstCachedLine; dwNumLoadedLines = dwNumCachedLines; dwLastLoadedLine = dwFirstLoadedLine + dwNumLoadedLines - 1; dwLoadOffset = 0; } _ASSERTE(m_pTextCache != NULL); if (dwNumMappedLines > 0) { MoveMemory(m_pTextCache + dwToMemOffset, m_pTextCache + dwFromMemOffset, dwMemSize * sizeof(TCHAR)); for (DWORD dwLineNum = dwFirstMappedLine; dwLineNum <= dwLastMappedLine; ++dwLineNum) { CLineInfo& rLineInfo = m_arrLines[(int)dwLineNum]; rLineInfo.m_dwTextStart = dwToMemOffset; dwToMemOffset += rLineInfo.m_dwLength; } } if (dwNumLoadedLines > 0) { DWORD dwLineBufferPos = 0, dwLineNum = dwFirstLoadedLine; const CLineInfo& rLineInfo = m_arrLines[(int)dwLineNum]; SetFilePointer(m_hFile, rLineInfo.m_dwLineStart, NULL, FILE_BEGIN); while (dwLineNum <= dwLastLoadedLine) { DWORD dwNumRead = 0; if (! ReadFile(m_hFile, m_pLineBuffer + dwLineBufferPos, m_dwLineBufferSize - dwLineBufferPos, &dwNumRead, NULL)) return; dwNumRead += dwLineBufferPos; dwLineBufferPos = 0; if (dwNumRead == 0) break; while (dwLineNum <= dwLastLoadedLine) { CLineInfo& rLineInfo = m_arrLines[(int)dwLineNum]; DWORD dwLineSize; if (dwLineNum < dwLastLoadedLine) { const CLineInfo& rNextLineInfo = m_arrLines[(int)(dwLineNum + 1)]; dwLineSize = rNextLineInfo.m_dwLineStart - rLineInfo.m_dwLineStart; // line size including line end } else dwLineSize = rLineInfo.m_dwSize; DWORD dwBytesLeft = dwNumRead - dwLineBufferPos; if (dwLineSize > dwBytesLeft) { MoveMemory(m_pLineBuffer, m_pLineBuffer + dwLineBufferPos, dwBytesLeft); dwLineBufferPos = dwBytesLeft; break; } m_pDecoder->DecodeString(m_pLineBuffer + dwLineBufferPos, rLineInfo.m_dwSize, m_pTextCache + dwLoadOffset, rLineInfo.m_dwLength); int nLineWidth = LOWORD(GetTabbedTextExtent(hdc, m_pTextCache + dwLoadOffset, rLineInfo.m_dwLength, 0, NULL)); if (nMaxLineWidth < nLineWidth) nMaxLineWidth = nLineWidth; rLineInfo.m_dwTextStart = dwLoadOffset; dwLoadOffset += rLineInfo.m_dwLength; dwLineBufferPos += dwLineSize; ++dwLineNum; } } } m_dwFirstCachedLine = dwFirstCachedLine; m_dwNumCachedLines = dwNumCachedLines; nMaxLineWidth += nExtraWidth; if (m_nMaxLineWidth < nMaxLineWidth) { m_nMaxLineWidth = nMaxLineWidth; SCROLLINFO sinfo; ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cbSize = sizeof(sinfo); sinfo.fMask = SIF_RANGE; sinfo.nMin = 0; sinfo.nMax = nMaxLineWidth - 1; SetScrollInfo(m_hwnd, SB_HORZ, &sinfo, TRUE); } if (hOldFont) SelectFont(hdc, hOldFont); ReleaseDC(m_hwnd, hdc); }
void CTextView::LoadCache(void) { _ASSERTE(m_hFile != INVALID_HANDLE_VALUE); m_dwFirstCachedLine = m_dwNumCachedLines = 0; m_nMaxLineWidth = 0; DWORD dwNumLines = m_arrLines.GetCount(); if (dwNumLines > 0) { HDC hdc = GetDC(m_hwnd); HFONT hOldFont = g_pResManager->m_hFixedFont ? SelectFont(hdc, g_pResManager->m_hFixedFont) : NULL; TEXTMETRIC tmetr; ::GetTextMetrics(hdc, &tmetr); int nExtraWidth = tmetr.tmAveCharWidth + LOWORD(GetTabbedTextExtent(hdc, g_szEllipsis, g_dwEllipsisLength, 0, NULL)); if (m_pTextCache == NULL) { _ASSERTE(MAX_NUMBER_OF_SYMBOLS <= TEXT_CACHE_SIZE); m_pTextCache = new TCHAR[TEXT_CACHE_SIZE]; if (m_pTextCache == NULL) { ResetFile(); goto end; } } const CLineInfo& rLineInfo = m_arrLines[0]; SetFilePointer(m_hFile, rLineInfo.m_dwLineStart, NULL, FILE_BEGIN); DWORD dwLineBufferPos = 0, dwTextCachePos = 0; for (;;) { DWORD dwNumRead = 0; if (! ReadFile(m_hFile, m_pLineBuffer + dwLineBufferPos, m_dwLineBufferSize - dwLineBufferPos, &dwNumRead, NULL)) goto end; dwNumRead += dwLineBufferPos; dwLineBufferPos = 0; if (dwNumRead == 0) break; for (;;) { DWORD dwBytesLeft = dwNumRead - dwLineBufferPos; if (dwBytesLeft == 0) { dwLineBufferPos = 0; break; } CLineInfo& rLineInfo = m_arrLines[(int)m_dwNumCachedLines]; if (dwTextCachePos + rLineInfo.m_dwLength > TEXT_CACHE_SIZE) goto end; DWORD dwLineSize; if (m_dwNumCachedLines + 1 < dwNumLines) { const CLineInfo& rNextLineInfo = m_arrLines[(int)(m_dwNumCachedLines + 1)]; dwLineSize = rNextLineInfo.m_dwLineStart - rLineInfo.m_dwLineStart; // line size includes line end } else dwLineSize = rLineInfo.m_dwSize; if (dwLineSize > dwBytesLeft) { MoveMemory(m_pLineBuffer, m_pLineBuffer + dwLineBufferPos, dwBytesLeft); dwLineBufferPos = dwBytesLeft; break; } m_pDecoder->DecodeString(m_pLineBuffer + dwLineBufferPos, rLineInfo.m_dwSize, m_pTextCache + dwTextCachePos, rLineInfo.m_dwLength); int nLineWidth = LOWORD(GetTabbedTextExtent(hdc, m_pTextCache + dwTextCachePos, rLineInfo.m_dwLength, 0, NULL)); if (m_nMaxLineWidth < nLineWidth) m_nMaxLineWidth = nLineWidth; rLineInfo.m_dwTextStart = dwTextCachePos; dwTextCachePos += rLineInfo.m_dwLength; dwLineBufferPos += dwLineSize; ++m_dwNumCachedLines; } } end: m_nMaxLineWidth += nExtraWidth; ResizeTextView(TRUE); if (hOldFont) SelectFont(hdc, hOldFont); ReleaseDC(m_hwnd, hdc); } }
BOOL CCustomMenu::OnMeasureItem(WPARAM wParam,LPARAM lParam) { MEASUREITEMSTRUCT *pMeasureItem = NULL; MENUITEMINFO mii; pMeasureItem = (MEASUREITEMSTRUCT *)lParam; /* Only process if this notification is actually for a menu. */ if(pMeasureItem->CtlType == ODT_MENU) { mii.cbSize = sizeof(mii); mii.fMask = MIIM_FTYPE; GetMenuItemInfo(m_hMenu,pMeasureItem->itemID,FALSE,&mii); /* Is this item a separator? */ if((mii.fType & MFT_SEPARATOR) == MFT_SEPARATOR) { /* Width of a separator is 0. The separator height should be odd so that a line can be drawn through the middle, with equal space above and below. */ pMeasureItem->itemWidth = SEPARATOR_WIDTH; pMeasureItem->itemHeight = SEPARATOR_HEIGHT; } else { HDC hdc; HDC hdcTemp; NONCLIENTMETRICS ncm; HFONT hFont; TCHAR szMenuString[64]; DWORD dwStringDimensions; BOOL bRet; int iTabPos = 0; int nTabs = 0; hdc = GetDC(m_hwnd); hdcTemp = CreateCompatibleDC(hdc); ncm.cbSize = sizeof(ncm); bRet = SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(ncm),(PVOID)&ncm,0); if(bRet) { hFont = CreateFontIndirect(&ncm.lfMenuFont); } else { hFont = (HFONT)GetStockObject(SYSTEM_FONT); } SelectObject(hdcTemp,hFont); GetMenuString(m_hMenu,pMeasureItem->itemID,szMenuString, SIZEOF_ARRAY(szMenuString),MF_BYCOMMAND); while(szMenuString[iTabPos] != '\0' && szMenuString[iTabPos] != '\t') { iTabPos++; } if(szMenuString[iTabPos] == '\t') nTabs++; /* Determine the dimensions of the menu string. */ dwStringDimensions = GetTabbedTextExtent(hdcTemp, szMenuString,lstrlen(szMenuString),nTabs,&iTabPos); pMeasureItem->itemWidth = LOWORD(dwStringDimensions) + MENU_TEXT_INDENT_LEFT; pMeasureItem->itemHeight = max(HIWORD(dwStringDimensions) + MENU_TEXT_VERTICAL_SPACING,MINIMUM_MENU_ITEM_HEIGHT); DeleteObject(hFont); DeleteDC(hdcTemp); ReleaseDC(m_hwnd,hdc); } } return TRUE; }