void CMagneticView::OnDraw(CDC* pDrawDC) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); // Don't draw anything if there isn't a loaded game if (pApp->GetGameLoaded() == 0) return; CDC BitmapDC; BitmapDC.CreateCompatibleDC(pDrawDC); CRect Client; GetClientRect(Client); CBitmap Bitmap; CSize Size(Client.Width(),Client.Height()); Bitmap.CreateCompatibleBitmap(pDrawDC,Size.cx,Size.cy); CBitmap* pOldBitmap = BitmapDC.SelectObject(&Bitmap); // Set up the font CFont* pOldFont = NULL; TEXTMETRIC FontInfo; pOldFont = BitmapDC.SelectObject(m_pTextFont); BitmapDC.GetTextMetrics(&FontInfo); int iFontHeight = (int)(FontInfo.tmHeight*1.1); int iPicWidth = 0; int iPicHeight = 0; CRect TextClient(Client); CSize Margins(GetMargins()); if (m_bStatusBar) { TextClient.top += iFontHeight; // Display the status line LONG lStatSpace = (LONG)(Client.Width()*0.075); SolidRect(&BitmapDC,CRect(Client.left,0,Client.right,iFontHeight), pApp->GetForeColour()); BitmapDC.SetTextColor(pApp->GetBackColour()); BitmapDC.SetBkColor(pApp->GetForeColour()); BitmapDC.TextOut(lStatSpace,0,m_strStatLocation,m_strStatLocation.GetLength()); BitmapDC.TextOut(lStatSpace*10,0,m_strStatScore,m_strStatScore.GetLength()); } // If the picture is to be drawn in the main window, leave enough // space and draw both background and picture if (pApp->GetShowGraphics() == CMagneticApp::ShowGraphics::MainWindow) { int dpi = DPI::getWindowDPI(this); iPicWidth = m_Picture.GetScaledWidth(dpi); iPicHeight = m_Picture.GetScaledHeight(dpi); if (iPicWidth > 0 && iPicHeight > 0) { TextClient.top += iPicHeight; int iOffset = m_bStatusBar ? iFontHeight : 0; BitmapDC.FillSolidRect(Client.left,Client.top+iOffset,Client.Width(), iPicHeight,pApp->GetGfxColour()); CRect PicArea((Client.Width()-iPicWidth)/2,iOffset, (Client.Width()+iPicWidth)/2,iOffset+iPicHeight); m_Picture.Paint(&BitmapDC,PicArea,m_AnimFrames); } } BitmapDC.FillSolidRect(TextClient,pApp->GetBackColour()); int y = TextClient.top; // Repaginate if necessary TrimOutput(); if (m_PageTable.GetSize() == 0) { Paginate(&BitmapDC,0,0); if (m_bMorePrompt) m_PageTable.RemoveAt(m_PageTable.GetSize()-1); } LPCSTR lpszOutput = m_strOutput; BitmapDC.SetTextColor(pApp->GetForeColour()); BitmapDC.SetBkColor(pApp->GetBackColour()); // Work out the number of lines of text to draw m_iMaxLines = (TextClient.Height()-(2*Margins.cy)) / iFontHeight; y += Margins.cy; // Starting position in the text output buffer int i = m_PageTable.GetSize() - m_iMaxLines - 1; // Adjust for a More... prompt int offset = 0; if (m_bMorePrompt) { if (iPicWidth > 0 && iPicHeight > 0) { if (m_iLines > m_iMaxLines) { if (m_iLines - m_iMaxLines - 1 > 0) { offset = m_iLines - m_iMaxLines - 1; i -= offset; } } } } if (i < 0) i = 0; // Draw the text int iCount = 0; while (i < m_PageTable.GetSize()-1-offset) { iCount = m_PageTable[i+1]-m_PageTable[i]-1; if (iCount > 0) { if (*(lpszOutput+m_PageTable[i]+iCount-1) == '\0') iCount--; } BitmapDC.TextOut(Margins.cx,y,lpszOutput+m_PageTable[i],iCount); y += iFontHeight; i++; } // Store information on the last line for updating later CRect LastLine(0,y-iFontHeight,TextClient.Width(),y); m_LastLineRect = LastLine; // Clear the end of the last line to allow input editing if (i > 0) { CSize TextLen = BitmapDC.GetTextExtent(lpszOutput+m_PageTable[i-1], m_PageTable[i]-m_PageTable[i-1]-1); LastLine.left += TextLen.cx + Margins.cx; SolidRect(&BitmapDC,LastLine,pApp->GetBackColour()); } // Remove the font BitmapDC.SelectObject(pOldFont); pDrawDC->BitBlt(0,0,Size.cx,Size.cy,&BitmapDC,0,0,SRCCOPY); BitmapDC.SelectObject(pOldBitmap); }
void CMagneticView::AddOutChar(char c) { static const int SCRIPT_WIDTH = 70; if (c == '\b') // Is this a delete character? { int len; len = m_strOutput.GetLength(); if (len > 0) m_strOutput = m_strOutput.Left(len-1); len = m_Scrollback.GetScrollback().GetLength(); if (len > 0) { m_Scrollback.GetScrollback() = m_Scrollback.GetScrollback().Left(len-1); } if (m_Scripting == Scripting::ScriptingOn) { len = m_strScript.GetLength(); if (len > 0) m_strScript = m_strScript.Left(len-1); } } else if (isprint(c) || (c == '\n')) { m_strOutput += c; // Update pagination information if (m_PageTable.GetSize() > 1) { int p1, p2; p1 = m_PageTable[m_PageTable.GetSize()-2]; p2 = m_PageTable[m_PageTable.GetSize()-1]-p1-1; m_PageTable.RemoveAt(m_PageTable.GetSize()-1); m_iLines += Paginate(m_pTextDC,p1,p2); } else m_iLines += Paginate(m_pTextDC,0,0); if ((m_iLines > m_iMaxLines) && (m_Recording != Recording::PlaybackOn)) { CFrameWnd* pFrame = (CFrameWnd*)(AfxGetApp()->m_pMainWnd); if (pFrame) { pFrame->SetMessageText("Press a key for more..."); pFrame->DragAcceptFiles(FALSE); } m_bMorePrompt = true; bool done; GetInput(done,false); // If the window has been closed, at this point even this view // object may be invalid. Check that the window is still present, // and if not, return without changing anything at all. pFrame = (CFrameWnd*)(AfxGetApp()->m_pMainWnd); if (pFrame == NULL) return; // Program ending m_bMorePrompt = false; pFrame->SetMessageText(AFX_IDS_IDLEMESSAGE); pFrame->DragAcceptFiles(TRUE); } if (c == '\n') m_Scrollback.GetScrollback() += '\r'; m_Scrollback.GetScrollback() += c; if (m_Scripting == Scripting::ScriptingOn) { switch (c) { case 10: if (m_pFileScript) fprintf(m_pFileScript,"%s\n",m_strScript); m_strScript.Empty(); break; case ' ': if (m_strScript.GetLength() > SCRIPT_WIDTH) { if (m_pFileScript) fprintf(m_pFileScript,"%s\n",m_strScript); m_strScript.Empty(); } else m_strScript += c; break; default: m_strScript += c; break; } } } }
// 全てを再計算する。 void Recalculate() { Paginate(); }