int far pascal zSetTextCharacterExtra( HDC pp1, int pp2 ) { int r; SaveRegs(); /* ** Log IN Parameters (No Create/Destroy Checking Yet!) */ LogIn( (LPSTR)"APICALL:SetTextCharacterExtra HDC+int+", pp1, pp2 ); /* ** Call the API! */ RestoreRegs(); GrovelDS(); r = SetTextCharacterExtra(pp1,pp2); UnGrovelDS(); SaveRegs(); /* ** Log Return Code & OUT Parameters (No Create/Destroy Checking Yet!) */ LogOut( (LPSTR)"APIRET:SetTextCharacterExtra int+++", r, (short)0, (short)0 ); RestoreRegs(); return( r ); }
/** * Paint the screen according to the rules of this emulation mode. * * @param HWND hwnd Handle to the application window. * @param LPVOID data The emulation mode data * @param HDC hdc The handle to the device context. * If this is NULL, GetDC will be called. * @param BOOLEAN force Force a repaint of the whole screen if true. * * @returns int 0 on success, greater than 0 otherwise. */ DWORD none_paint(HWND hwnd, LPVOID data, HDC hdc, BOOLEAN force) { NoneData* dat = (NoneData*)data; TEXTMETRIC tm; BYTE y = 0; BOOLEAN bGotDC = FALSE; if (hdc == NULL) { hdc = GetDC(hwnd); bGotDC = TRUE; } SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT)); GetTextMetrics(hdc, &tm); SetTextCharacterExtra(hdc, 1); SetBkColor(hdc, RGB(0, 0, 0)); SetTextColor(hdc, RGB(255, 255, 255)); for (y = 0; y < 24; y++) { TextOut(hdc, 0, y * (tm.tmExternalLeading + tm.tmHeight), dat->screen[y], _tcslen(dat->screen[y])); } if (bGotDC) { ReleaseDC(hwnd, hdc); } return 0; }
LRESULT CALLBACK RingsWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { HDC hdc; PAINTSTRUCT ps; HCURSOR hCursor; switch( msg ) { // case WM_CREATE: // return NULL; case WM_CHAR: HandleChar( hwnd, wParam ); return 0; case WM_PAINT: hCursor = SetCursor( LoadCursor( NULL, MAKEINTRESOURCE(IDC_WAIT) ) ); ShowCursor( TRUE ); //ClearDebug(); //dprintf( "Drawing rings" ); hdc = BeginPaint( hwnd, &ps ); SetDCMapMode( hdc, wMappingMode ); SetTextCharacterExtra( hdc, nCharExtra ); SetTextJustification( hdc, nBreakExtra, nBreakCount ); DrawDCAxis( hwnd, hdc ); DrawRings( hwnd, hdc ); CleanUpDC( hdc ); SelectObject( hdc, GetStockObject( BLACK_PEN ) ); EndPaint( hwnd, &ps ); //dprintf( " Finished drawing rings" ); ShowCursor( FALSE ); SetCursor( hCursor ); return 0; case WM_DESTROY: return 0; } return DefWindowProc( hwnd, msg, wParam, lParam ); }
static void test_dc_values(void) { HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); COLORREF color; int extra; ok( hdc != NULL, "CreateDC failed\n" ); color = SetBkColor( hdc, 0x12345678 ); ok( color == 0xffffff, "initial color %08x\n", color ); color = GetBkColor( hdc ); ok( color == 0x12345678, "wrong color %08x\n", color ); color = SetBkColor( hdc, 0xffffffff ); ok( color == 0x12345678, "wrong color %08x\n", color ); color = GetBkColor( hdc ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = SetBkColor( hdc, 0 ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = GetBkColor( hdc ); ok( color == 0, "wrong color %08x\n", color ); color = SetTextColor( hdc, 0xffeeddcc ); ok( color == 0, "initial color %08x\n", color ); color = GetTextColor( hdc ); ok( color == 0xffeeddcc, "wrong color %08x\n", color ); color = SetTextColor( hdc, 0xffffffff ); ok( color == 0xffeeddcc, "wrong color %08x\n", color ); color = GetTextColor( hdc ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = SetTextColor( hdc, 0 ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = GetTextColor( hdc ); ok( color == 0, "wrong color %08x\n", color ); extra = GetTextCharacterExtra( hdc ); ok( extra == 0, "initial extra %d\n", extra ); SetTextCharacterExtra( hdc, 123 ); extra = GetTextCharacterExtra( hdc ); ok( extra == 123, "initial extra %d\n", extra ); SetMapMode( hdc, MM_LOMETRIC ); extra = GetTextCharacterExtra( hdc ); ok( extra == 123, "initial extra %d\n", extra ); SetMapMode( hdc, MM_TEXT ); extra = GetTextCharacterExtra( hdc ); ok( extra == 123, "initial extra %d\n", extra ); DeleteDC( hdc ); }
void CEditView::Draw( HDC hDC, LPRECT prcClipBox, CSelection *pSel ) const { // prcClipBox is control-relative, not view-relative int nRowStart = ( max( m_rcView.top, prcClipBox->top ) - m_rcView.top ) / m_cyLine; int ySnap = m_rcView.top + nRowStart * m_cyLine; nRowStart += m_nTopIndex; int nRowEnd = m_nTopIndex + ( min( prcClipBox->bottom, m_rcView.bottom ) - m_rcView.top ) / m_cyLine; //#define _DRAWCHARGRID #ifdef _DRAWCHARGRID { RECT rc; if ( IntersectRect( &rc, prcClipBox, &m_rcView ) ) { rc.left = GetLeftMargin( TRUE, TRUE ); HPEN hPen = CreatePen( PS_SOLID, 0, RGB( 192, 192, 192 ) ); HPEN hPenOld = ( HPEN ) SelectObject( hDC, hPen ); int xStart = m_rcView.left + GetLeftMargin( TRUE, TRUE ) + ( ( prcClipBox->left - m_rcView.left ) / m_cxChar ) * m_cxChar; int xEnd = min( prcClipBox->right, m_rcView.right ); int yStart = ySnap; int yEnd = min( prcClipBox->bottom, m_rcView.bottom ); for ( int y = yStart; y <= yEnd; y += m_cyLine ) { MoveToEx( hDC, rc.left, y, NULL ); LineTo( hDC, rc.right, y ); } for ( int x = xStart; x <= xEnd; x += m_cxChar ) { MoveToEx( hDC, x, rc.top, NULL ); LineTo( hDC, x, rc.bottom ); } SelectObject( hDC, hPenOld ); DeleteObject( hPen ); } } #endif int nLastLine = m_pBuffer->GetLineCount() - 1; nLastLine = min( nLastLine, nRowEnd ); int nSelStartCol, nSelStartRow, nSelEndCol, nSelEndRow; BOOL bColumnSel = FALSE; int cxCaret = 0; if ( pSel ) { pSel->GetNormalizedViewSelection( nSelStartCol, nSelStartRow, nSelEndCol, nSelEndRow ); bColumnSel = pSel->IsColumnSel(); cxCaret = pSel->GetCaretWidth(); } int cxLeftMargin1 = GetLeftMargin( FALSE ); COLORREF crVDividerLines = m_pCtrl->GetVDividerLineColor(); // draw the left margin in a different color if ( cxLeftMargin1 ) { COLORREF crMargin = m_pCtrl->GetLeftMarginColor(); if ( crMargin != CLR_INVALID ) { RECT rc = m_rcView; rc.right = rc.left + cxLeftMargin1; SetBkColor( hDC, crMargin ); ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); } } // draw the line numbers in a different color int cxLeftMargin2 = GetLeftMargin( TRUE ); if ( cxLeftMargin2 != cxLeftMargin1 ) { COLORREF crLineNumbers = m_pCtrl->GetLineNumberBackColor(); if ( crLineNumbers != CLR_INVALID ) { RECT rc = m_rcView; rc.left = m_rcView.left + cxLeftMargin1; rc.right = m_rcView.left + cxLeftMargin2; SetBkColor( hDC, crLineNumbers ); ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); } } // draw the divider lines if ( crVDividerLines != CLR_INVALID ) { if ( cxLeftMargin1 ) DrawVDividerLine( hDC, m_rcView, m_rcView.left + cxLeftMargin1 ); if ( cxLeftMargin1 != cxLeftMargin2 ) DrawVDividerLine( hDC, m_rcView, m_rcView.left + cxLeftMargin2 ); } int cxLeftMargin3 = GetLeftMargin( TRUE, TRUE ); // draw the stuff in the left margin in one pass, rather than with each // line. This is much faster. int y = ySnap; int xLineNumber = m_rcView.left + cxLeftMargin1; int nLineNumRadix; BOOL bLineNumbers; // if line numbering, select the font once, or else things slow down a bit // if done for each line if ( ( bLineNumbers = m_pCtrl->LineNumberingEnabled( nLineNumRadix ) ) == TRUE ) { SetTextCharacterExtra( hDC, 0 ); SelectObject( hDC, m_pCtrl->GetLineNumberFont() ); SetTextColor( hDC, m_pCtrl->GetLineNumberForeColor() ); ::SetBkMode( hDC, TRANSPARENT ); } int cyDescentShiftNormal = m_pCtrl->m_font->cyDescentShift; int nLine; for ( nLine = nRowStart; nLine <= nLastLine; nLine++ ) { // draw the bookmark and images if present if ( cxLeftMargin1 > 0 ) { BOOL bHasBookmark = m_pBuffer->HasBookmark( nLine ); BYTE byImages = m_pBuffer->GetMarginImages( nLine ); if ( bHasBookmark || byImages ) { DrawLeftMarginImages( hDC, bHasBookmark, byImages, m_rcView.left, y ); } } // Draw the line number if asked to if ( bLineNumbers ) { DrawLineNumber( nLine, nLineNumRadix, hDC, xLineNumber, y - cyDescentShiftNormal ); } y += m_cyLine; } int x = m_rcView.left + cxLeftMargin3; int xDividerStart = m_rcView.left + cxLeftMargin2; // draw the text for ( nLine = nRowStart, y = ySnap; nLine <= nLastLine; nLine++, y += m_cyLine ) DrawLine( nLine, hDC, x, y, xDividerStart ); // draw the selection as a separate pass, because the text will overlap slightly // (for tighter display), and the invert code would end up double-inverting the // overlapping regions, resulting in normal display. if ( pSel ) { for ( nLine = nRowStart, y = ySnap; nLine <= nLastLine; nLine++, y += m_cyLine ) { if ( ( nLine >= nSelStartRow ) && ( nLine <= nSelEndRow ) ) { RECT rcInvert; rcInvert.top = y; rcInvert.bottom = y + m_cyLine; if ( bColumnSel ) { int xSel = nSelStartCol - m_nLeftIndex; xSel = max( 0, xSel ); rcInvert.left = m_rcView.left + xSel * m_cxChar + cxLeftMargin3; xSel = nSelEndCol - m_nLeftIndex; xSel = max( 0, xSel ); rcInvert.right = m_rcView.left + xSel * m_cxChar + cxLeftMargin3; if ( rcInvert.left == rcInvert.right ) { // Is a column selection and is 'empty' -- make selection appear as a // giant insertion cursor rcInvert.right = rcInvert.left + cxCaret; } } else { int xSel = ( nLine == nSelStartRow ) ? nSelStartCol - m_nLeftIndex : 0; xSel = max( 0, xSel ); rcInvert.left = m_rcView.left + xSel * m_cxChar + cxLeftMargin3; rcInvert.left = max( rcInvert.left, x ); xSel = ( nLine == nSelEndRow ) ? ( nSelEndCol - m_nLeftIndex ) : ( m_nRightIndex - m_nLeftIndex + 1 ); rcInvert.right = m_rcView.left + xSel * m_cxChar + cxLeftMargin3; rcInvert.right = max( rcInvert.right, x ); } int xMaxLeft = m_rcView.left + cxLeftMargin2; rcInvert.left = max( rcInvert.left, xMaxLeft ); rcInvert.right = max( rcInvert.right, xMaxLeft ); InvertRect( hDC, &rcInvert ); } } } if ( m_pCtrl->ShowHScrollBar() && m_pCtrl->ShowVScrollBar() ) { // Draw the size box HBRUSH hbr = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) ); RECT rcBox = m_rcAll; rcBox.left = rcBox.right - GetSystemMetrics( SM_CXVSCROLL ); rcBox.top = rcBox.bottom - GetSystemMetrics( SM_CYHSCROLL ); FillRect( hDC, &rcBox, hbr ); DeleteObject( hbr ); } }
void CEditView::DrawLine( int nLine, HDC hDC, int x, int y, int xDividerStart ) const { int nLineLen = m_pBuffer->GetLineLength( nLine ); BOOL bUseColor = ( m_pCtrl->UseColorSyntax() && ( nLineLen <= MAXCOL ) ); int nViewCol = m_nLeftIndex; int nBuffColStart = m_pBuffer->ConvertViewColToBufferCol( nLine, nViewCol, FALSE ); int xLeft = x; // highlight this line if appropriate BOOL bHighlight = m_pBuffer->IsHighlighted( nLine ); if ( bHighlight ) { // fill out the rest of the line with the highlight RECT rc = m_rcView; rc.left = x; rc.top = y; rc.bottom = y + m_cyLine; SetBkColor( hDC, m_pCtrl->GetHighlightedLineColor() ); ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); } BOOL bMBCS = DBCS_ACTIVE; #ifdef _UNICODE int nRightIndex = m_nRightIndex; #else int nRightIndex = m_nRightIndex + bMBCS * 2; // always paint two more TCHARs so multibyte chars aren't truncated #endif if ( nBuffColStart < nLineLen ) // else nothing to draw { // wait for nLine to become available (in case of background syntax parsing) m_pBuffer->WaitForLine( nLine ); LPCTSTR pszLineStart = m_pBuffer->GetLineText( nLine ); register LPCTSTR psz = pszLineStart + nBuffColStart; LPCTSTR pszStart = psz; ////////////////////////////////////////////////////////////////////////// // Step 1: Expand tabs // BOOL bViewWhitespace = m_pCtrl->DisplayWhitespace(); TCHAR szLine[ 1000 ]; CharFill( szLine, _T(' '), ARRAY_SIZE( szLine ) ); int cbTab = m_pBuffer->GetTabSize(); LPTSTR pszBuff = szLine; TCHAR chTab, chSpace; if ( bMBCS ) { chTab = _T('^'); chSpace = _T('`'); } else { chTab = _T('»'); chSpace = _T('·'); } while ( *psz && ( nViewCol <= nRightIndex ) ) { if ( *psz == _T('\t') ) { int nSpaces = ( ( nViewCol / cbTab ) * cbTab ) + cbTab - nViewCol; if ( nSpaces ) { if ( bViewWhitespace ) { if ( psz != pszStart || m_nLeftIndex == m_pBuffer->ConvertBufferColToViewCol( nLine, nBuffColStart ) ) { *pszBuff = chTab; } } pszBuff += nSpaces; nViewCol += nSpaces; } } else { if ( bViewWhitespace && *psz == _T(' ') ) { *pszBuff++ = chSpace; } else { *pszBuff++ = *psz; } nViewCol++; } psz++; } ////////////////////////////////////////////////////////////////////////// // Step 2: Parse the line and assign colors to everything // DWORD clrLine[ 100 ]; // hiword = token, loword = token offset in szLine int nColors = 0; if ( bUseColor ) { psz = pszLineStart; int nParseLen = m_pBuffer->ConvertViewColToBufferCol( nLine, nRightIndex ) + 20; // +20 is a reasonable max token length nParseLen = min( nParseLen, nLineLen ); nViewCol = 0; int nBuffCol = 0; int nFirstColorViewCol = m_nLeftIndex; BOOL bColorIsVisible = nViewCol >= nFirstColorViewCol; CLineParser Parser( m_pBuffer, nLine, nParseLen ); // pick up where the last line left off -- in a multi-line comment block (or not) clrLine[ nColors++ ] = MAKELPARAM( 0, ( WORD ) ( Parser.m_bInComment ? CBuffer::eMultiLineCommentStart : ( Parser.m_bInString ? CBuffer::eStringDelim : ( Parser.m_bInTag ? CBuffer::eTagText : CBuffer::eText ) ) ) ); while ( Parser.MoreComing() ) { Parser.AcceptToken(); int nTokenStartCol = nViewCol; nBuffCol += Parser.m_nTokenLen; if ( Parser.m_bHasTab ) { ASSERT( Parser.m_eToken == CBuffer::eText || Parser.m_eToken == CBuffer::eTagText || Parser.m_eToken == CBuffer::eStringDelim || Parser.m_eToken == CBuffer::eSingleLineComment ); nViewCol = m_pBuffer->ConvertBufferColToViewCol( nLine, nBuffCol ); } else { nViewCol += Parser.m_nTokenLen; } if ( !bColorIsVisible ) { // Assume this token (unless in a comment) will be the first token to cross the left edge clrLine[ 0 ] = MAKELPARAM( 0, ( WORD )( Parser.m_bInComment ? CBuffer::eMultiLineCommentStart : ( Parser.m_bInString ? CBuffer::eStringDelim : Parser.m_eToken ) ) ); if ( nViewCol > nFirstColorViewCol ) { ////////////////////////// // token is now in view // bColorIsVisible = TRUE; nTokenStartCol = nFirstColorViewCol; } } // record the token position if ( nTokenStartCol > nRightIndex ) { break; } if ( bColorIsVisible && !Parser.m_bWasInComment && !Parser.m_bIsCommentEndToken && !Parser.m_bWasInString && !Parser.m_bIsStringEndToken ) { clrLine[ nColors++ ] = MAKELPARAM( nTokenStartCol - m_nLeftIndex, ( WORD ) Parser.m_eToken ); } clrLine[ nColors ] = MAKELPARAM( ( nViewCol > m_nLeftIndex ? nViewCol : nRightIndex ) - m_nLeftIndex, ( WORD ) Parser.m_eToken ); // don't blow past the local array and corrupt the stack! if ( nColors >= ARRAY_SIZE( clrLine ) - 1 ) { nColors = 0; goto no_color; } } } else { no_color: clrLine[ nColors++ ] = MAKELPARAM( 0, ( WORD ) CBuffer::eText ); // draw text only as far as is necessary. We don't want to paint extra characters that aren't // in the buffer. If underline font used on plain text, the underline will extend to the edge of the window. // we don't want that. int nViewColEnd = m_pBuffer->ConvertBufferColToViewCol( nLine, nLineLen ); nViewColEnd = min( nRightIndex, nViewColEnd ); nViewColEnd = max( m_nLeftIndex, nViewColEnd ); clrLine[ nColors ] = MAKELPARAM( nViewColEnd - m_nLeftIndex, ( WORD ) CBuffer::eText ); } ////////////////////////////////////////////////////////////////////////// // Step 3: Output the line // ASSERT( nColors ); BOOL bFirstToken = TRUE; for ( int i = 0; i < nColors; i++ ) { DWORD dwColorInfo = clrLine[ i ]; CBuffer::LangToken eToken = ( CBuffer::LangToken ) HIWORD( dwColorInfo ); SetTextColor( hDC, m_pCtrl->GetTokenColor( eToken, TRUE ) ); COLORREF crBk = bHighlight ? m_pCtrl->GetHighlightedLineColor() : m_pCtrl->GetTokenColor( eToken, FALSE ); if ( crBk != CLR_INVALID ) { SetBkColor( hDC, crBk ); SetBkMode( hDC, OPAQUE ); } else { SetBkMode( hDC, TRANSPARENT ); } long cxExtraSpacing, cyDescentShift; SelectObject( hDC, m_pCtrl->GetTokenFont( eToken, cxExtraSpacing, cyDescentShift, m_pCtrl->m_font ) ); SetTextCharacterExtra( hDC, cxExtraSpacing ); int nTokenStart = LOWORD( dwColorInfo ); int nTokenNext = LOWORD( clrLine[ i + 1 ] ); int cbToken = nTokenNext - nTokenStart; if ( cbToken ) { #ifndef _UNICODE // The first visible token on the left of the line might be cutoff right // in the middle of a multi-byte char. We need to account for this by not // rendering the character (just leave whitespace). if ( bFirstToken && _ismbstrail( ( const unsigned char * ) pszLineStart, ( const unsigned char * ) pszStart ) ) { // scan backwards to the lead byte LPCTSTR pszLead = pszStart; while ( _ismbstrail( ( const unsigned char * ) pszLineStart, ( const unsigned char * ) --pszLead ) ) ; int cbChar = pszStart - pszLead; nTokenStart += cbChar; cbToken -= cbChar; x += ( cbChar * m_cxChar ); } #endif bFirstToken = FALSE; ExtTextOut( hDC, x, y - cyDescentShift, 0, NULL, szLine + nTokenStart, cbToken, NULL ); x += ( cbToken * m_cxChar ); } // don't worry about deselecting the font -- it will be cleaned up by any // calling method (as an optimization) } } ////////////////////////////////////////////////////////////////////////// // Step 4: give the parent window a crack at painting, too. // DWORD dwStyle = m_pBuffer->GetLineStyle( nLine ); if ( HAS_FLAG( dwStyle, CML_OWNERDRAW ) ) { CM_DRAWLINEDATA dld; dld.hDC = hDC; dld.rcLine.left = xLeft; dld.rcLine.top = y; dld.rcLine.right = m_rcView.right; dld.rcLine.bottom = y + m_cyLine; dld.nLine = nLine; dld.nLeftCol = m_nLeftIndex; dld.nRightCol = m_nRightIndex; dld.lParam = m_pBuffer->GetItemData( nLine ); dld.dwStyle = dwStyle; m_pCtrl->NotifyParent( CMN_DRAWLINE, ( NMHDR * ) &dld ); } // Draw divider line underneath the line if appropriate if ( m_pBuffer->HasDivider( nLine ) ) { COLORREF crDividerLine = m_pCtrl->GetHDividerLineColor(); COLORREF crWindow = m_pCtrl->GetWindowColor( TRUE ); // if line will blend in with the background, make it visible (opposite of window color). if ( crDividerLine == CLR_INVALID || crDividerLine == crWindow ) crDividerLine = ( ~crWindow & 0x00ffffff ); HPEN hPen = CreatePen( PS_SOLID, CY_DIVIDERLINE, crDividerLine ); HPEN hPenOld = ( HPEN ) SelectObject( hDC, hPen ); int yLine = y + m_cyLine - 1; MoveToEx( hDC, xDividerStart, yLine, NULL ); LineTo( hDC, m_rcView.right, yLine ); SelectObject( hDC, hPenOld ); DeleteObject( hPen ); } }