#include "stdafx.h" #include "Common.h" extern HFONT hFont_TextEdit; extern int font_width,font_height; class CDrawReserve{ int x,y; COLORREF NowColor,NowBackColor; int bNowUnder; char *lpszBuffer; int length; int m_WndNum; HDC hdc; HBITMAP hMemBmp,hOldBitmap; HFONT hOldFont; SIZE ClientSize; int iControlTabSpace; int iOnePage_CharHeight; int iLineNumberTextCount; int iMax_OneLine_TextLength; public: HDC memdc; CDrawReserve(int WndNum,HDC _hDC,int cx,int cy,int ctrl_tab_space,int nMaxOnePageChar,int linenum_textcount,bool drawDirectly){ m_WndNum=WndNum; x=-1; y=-1; bNowUnder=0; ClientSize.cx=cx; ClientSize.cy=cy; iControlTabSpace=ctrl_tab_space; iOnePage_CharHeight=nMaxOnePageChar; iMax_OneLine_TextLength=cx/font_width+1; iLineNumberTextCount=linenum_textcount; if(drawDirectly){ hdc=0; memdc=_hDC; // メモリDCを使わず、直接描画する } else{ hdc=_hDC; memdc=CreateCompatibleDC(hdc); hMemBmp=CreateCompatibleBitmap(hdc,cx,cy); hOldBitmap=(HBITMAP)SelectObject(memdc,hMemBmp); } //背景色でメモリ画面を初期化 HBRUSH hBrush,hOldBrush; hBrush=CreateSolidBrush(tci.rgbBackground); hOldBrush=(HBRUSH)SelectObject(memdc,hBrush); PatBlt(memdc,ctrl_tab_space,0,cx-ctrl_tab_space,cy,PATCOPY); DeleteObject(hBrush); //背景ビットマップ #ifdef THETEXT if(pobj_DBTheme->hBackBmp){ HDC memdc2; memdc2=CreateCompatibleDC(memdc); SelectObject(memdc2,pobj_DBTheme->hBackBmp); BitBlt(memdc, cx-(pobj_DBTheme->sizeBackBmp.cx), cy-(pobj_DBTheme->sizeBackBmp.cy), pobj_DBTheme->sizeBackBmp.cx,pobj_DBTheme->sizeBackBmp.cy, memdc2,0,0,SRCCOPY); DeleteDC(memdc2); } #endif //フォントを設定 extern HFONT hFont_TextEdit; hOldFont=(HFONT)SelectObject(memdc,hFont_TextEdit); lpszBuffer=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1); length=0; } ~CDrawReserve(){ SelectObject(memdc,hOldFont); if(hdc){ SelectObject(memdc,hOldBitmap); DeleteObject(hMemBmp); DeleteDC(memdc); } HeapDefaultFree(lpszBuffer); } void draw(){ if(length==0) return; SetTextColor(memdc,NowColor); if(NowBackColor==tci.rgbBackground){ SetBkMode(memdc,TRANSPARENT); } else{ SetBkMode(memdc,OPAQUE); SetBkColor(memdc,NowBackColor); } HFONT hBeforeFont; if(bNowUnder){ //下線付きフォントに設定 extern HFONT hFont_HyperLink_TextEdit; hBeforeFont=(HFONT)SelectObject(memdc,hFont_HyperLink_TextEdit); } int offset=0; if(x<0){ offset=-x; //左端の全角文字の文字化けを避けるために10バイトの余裕を作る offset-=10; if(offset<0) offset=0; length-=offset; if(length<0) return; } if(length>iMax_OneLine_TextLength+10){ length=iMax_OneLine_TextLength+10; } int i; int *lpDxWidths; lpDxWidths=(int *)malloc((length+1)*sizeof(int)); for(i=0;ibEditor_LineNumber){ hBrush=CreateSolidBrush(RGB(220,220,220)); hOldBrush=(HBRUSH)SelectObject(memdc,hBrush); ///////////////////////////////////////////////////// // エディタ画面左端のコントロールタブの行番号を描画 ///////////////////////////////////////////////////// //灰色で塗りつぶす PatBlt(memdc, 0, 0, iControlTabSpace, ClientSize.cy, PATCOPY); extern HFONT hFont_LineNumber; int LineNumberFontHeight; HFONT hOldFont; hOldFont=(HFONT)SelectObject(memdc,hFont_LineNumber); SetTextColor(memdc,RGB(60,60,60)); SetBkColor(memdc,RGB(220,220,220)); SIZE size; GetTextExtentPoint32(memdc,"A",1,&size); LineNumberFontHeight=size.cy; //ブレークポイントの描画を準備 BreakPointsPerFile *pobj_FileBreakPoint=0; if( projectInfo.IsOpened() ){ pobj_FileBreakPoint= projectInfo.pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum]->path.c_str()); } else{ extern CDBBreakPoint *pobj_DBBreakPoint; pobj_FileBreakPoint=pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum]->path.c_str()); } int i,i2; char temporary[255],temp2[255]; if(ycheck(i-BaseY)){ bBreakPoint=1; } } if(bBreakPoint){ ActiveBasic::Resource::UniqueHIcon hicon(ActiveBasic::Resource::LoadIconAlt(hIconResInst, IDI_BREAKPOINT_FLAG, 16, 16)); DrawIconEx(memdc,3,i*font_height+(font_height-16)/2,hicon.get(),16,16,0,NULL,DI_NORMAL); } else{ sprintf(temp2,"%%%dd:",iLineNumberTextCount); sprintf(temporary,temp2,(i-BaseY)+1); TextOut(memdc, 3, i*font_height+(font_height-LineNumberFontHeight)/2, temporary, lstrlen(temporary)); } } SelectObject(memdc,hOldFont); //ブラシを破棄 SelectObject(memdc,hOldBrush); DeleteObject(hBrush); } else{ //////////////////////////////////////////// // エディタ画面左端のコントロールタブを描画 // ※行番号は非表示 //////////////////////////////////////////// hBrush=CreateSolidBrush(RGB(220,220,220)); hOldBrush=(HBRUSH)SelectObject(memdc,hBrush); PatBlt(memdc, 0, 0, iControlTabSpace, ClientSize.cy, PATCOPY); SelectObject(memdc,hOldBrush); DeleteObject(hBrush); } //メモリDCを使用している場合、その内容を画面に描画 if (hdc){ BitBlt(hdc,0,0,ClientSize.cx,ClientSize.cy,memdc,0,0,SRCCOPY); } } }; static bool IsRemoteSession() { OSVERSIONINFO vi = {sizeof vi}; BOOL ret = ::GetVersionEx(&vi); if (ret && vi.dwMajorVersion >= 5) { const int SM_REMOTESESSION = 0x1000; return GetSystemMetrics(SM_REMOTESESSION); } return false; } void TextEdit_DrawBuffer(HDC hdc,int WndNum,bool drawDirectly){ int i,i2; int x,y; int BaseX,BaseY,CharX; char *pBuf,temporary[255]; HWND hEdit; //背景モード、カラーの設定 COLORREF DefaultBackColor,CaretBackColor; DefaultBackColor=tci.rgbBackground; RECT ClientRect; hEdit=GetWindow(MdiInfo[WndNum]->hwnd,GW_CHILD); GetClientRect(hEdit,&ClientRect); //エディタ画面左端のコントロールタブ int iControlTabSpace; int iLineNumberTextCount; iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace; iLineNumberTextCount=MdiInfo[WndNum]->pMdiTextEdit->iLineNumberTextCount; //一ページ中に表示できる行数を取得 int OnePage_CharHeight; OnePage_CharHeight=(ClientRect.bottom/font_height)+1; //描画用クラス CDrawReserve obj_dr( WndNum, hdc, ClientRect.right-ClientRect.left,ClientRect.bottom-ClientRect.top, iControlTabSpace, OnePage_CharHeight, iLineNumberTextCount, drawDirectly || IsRemoteSession()); //テキストバッファをコード内で参照しやすいようにポインタ変数を利用する pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer; //選択範囲を取得 CHARRANGE CharRange; TextEdit_GetSel(WndNum,&CharRange); //ベース描画ポジションを取得(文字単位) BaseX=0; BaseY=0; GetScrollBaseCaretPos(MdiInfo[WndNum],&BaseX,&BaseY); if(pobj_nv->bEditor_CaretLine_BackGround){ //カーソル行の色を変える CaretBackColor=tci.rgbCursorBack; } else{ //カーソル行の色を変えない CaretBackColor=tci.rgbBackground; } HBRUSH hCaretBackBrush; hCaretBackBrush=CreateSolidBrush(CaretBackColor); BOOL IsStr=0; DWORD dwComment=0; BOOL bMultiLineComment; COLORREF NextColor,NextBackColor; int MaxX=0; x=BaseX; y=BaseY; CharX=0; //左端から何文字目かを示す int bHyperLinkUnderBar=0; //ハイパーリンク用下線の表示スイッチ for(i=0;;i++){ if(pBuf[i]=='\0'){ if(0<=y&&y<=OnePage_CharHeight){ if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){ //////////////////////////////////// // カーソル行では余白を塗りつぶす //////////////////////////////////// HBRUSH hTempBrush; hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush); //終端コードよりも右側はブラシで塗りつぶす PatBlt(obj_dr.memdc, x*font_width +iControlTabSpace, y*font_height, ClientRect.right-(x*font_width +iControlTabSpace), font_height, PATCOPY); //カーソル行 SelectObject(obj_dr.memdc,hTempBrush); } //行番号が末端行にも表示されるようにするために描画予約を行う obj_dr.DrawReserve( x, y, NULL, NULL, bHyperLinkUnderBar, "",0); } if(MaxXpMdiTextEdit->StartCaretPos.y==y-BaseY){ /////////////////////////////////////////////////////////// //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用) /////////////////////////////////////////////////////////// HBRUSH hTempBrush; //カーソル行 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush); PatBlt(obj_dr.memdc, x*font_width +iControlTabSpace, y*font_height, ClientRect.right-(x*font_width +iControlTabSpace), font_height, PATCOPY); //カーソル行 SelectObject(obj_dr.memdc,hTempBrush); } y++; x=BaseX; CharX=0; i--; continue; } if(MdiInfo[WndNum]->DocType==WNDTYPE_BASIC){ if(pBuf[i]=='\"'&&dwComment==0) IsStr^=1; //複数行に渡るコメントを考慮 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.size() ) == 0 && IsStr == 0 && dwComment == 0 ) { // /* dwComment=12; bMultiLineComment=1; } if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.size() ) == 0 && dwComment == 10 && bMultiLineComment ) { // */ dwComment=3; } //単行コメント if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.size() ) == 0 && dwComment == 0 && IsStr == 0 ) { // ' dwComment=10; bMultiLineComment=0; } if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ //単行コメント中での改行は、コメントを解除 if(dwComment&&bMultiLineComment==0){ IsStr=0; dwComment=0; } } if(dwComment!=0&&dwComment!=10) dwComment--; } if(MdiInfo[WndNum]->DocType==WNDTYPE_HTML){ //複数行に渡るコメントを考慮 if(pBuf[i]=='<'&&pBuf[i+1]=='!'&&pBuf[i+2]=='-'&&pBuf[i+3]=='-'&&IsStr==0&&dwComment==0){ dwComment=10; } if(pBuf[i]=='-'&&pBuf[i+1]=='-'&&pBuf[i+2]=='>'&& dwComment){ dwComment=4; } if(dwComment!=0&&dwComment!=10) dwComment--; } //ハイパーリンク用下線 if(MdiInfo[WndNum]->pMdiTextEdit->iUnderStart<=i&&ipMdiTextEdit->iUnderEnd) bHyperLinkUnderBar=1; else bHyperLinkUnderBar=0; if(0<=y&&y<=OnePage_CharHeight){ ////////////////////////////////// // 表示中ページでは文字単位で描画 ////////////////////////////////// //※i2に描画する文字数を格納する NextBackColor=DefaultBackColor; if(dwComment){ //複数行に渡るコメント NextColor=tci.rgbComment; } else{ //通常カラー NextColor=MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i]; } if(CharRange.cpMin<=i&&ipMdiTextEdit->StartCaretPos.y==y-BaseY){ //カーソル行 NextBackColor=CaretBackColor; } } if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 i2=2; obj_dr.DrawReserve( x, y, NextColor, NextBackColor, bHyperLinkUnderBar, pBuf+i,i2); i++; } else if(pBuf[i]=='\t'){ //タブ文字 int tab; tab=pobj_nv->TabSize; if((x-BaseX)%tab==0) i2=tab; else i2=tab-(x-BaseX)%tab; memset(temporary,' ',i2); temporary[i2]=0; obj_dr.DrawReserve( x, y, NextColor, NextBackColor, bHyperLinkUnderBar, temporary,i2); } else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ //改行文字は1スペースだけ空白を描画しておく(反転表示をするため) i2=1; temporary[0]=' '; temporary[1]=0; obj_dr.DrawReserve( x, y, NextColor, NextBackColor, bHyperLinkUnderBar, temporary,i2); if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){ /////////////////////////////////////////////////////////// //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用) /////////////////////////////////////////////////////////// HBRUSH hTempBrush; //カーソル行 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush); PatBlt(obj_dr.memdc, (x+i2)*font_width +iControlTabSpace, y*font_height, ClientRect.right-((x+i2)*font_width +iControlTabSpace), font_height, PATCOPY); //カーソル行 SelectObject(obj_dr.memdc,hTempBrush); } } else{ //通常のキャラ文字 i2=1; obj_dr.DrawReserve( x, y, NextColor, NextBackColor, bHyperLinkUnderBar, pBuf+i,i2); } } else{ //////////////////////////////////////// // 非表示ページでは文字数の計算だけ行う //////////////////////////////////////// //※i2に描画する文字数を格納する if(IsDBCSLeadByte(pBuf[i])){ //マルチバイト文字 i2=2; i++; } else if(pBuf[i]=='\t'){ //タブ文字 int tab; tab=pobj_nv->TabSize; if((x-BaseX)%tab==0) i2=tab; else i2=tab-(x-BaseX)%tab; } else{ //通常のキャラ文字(改行文字を含む) i2=1; } } if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){ y++; if(MaxXbRightTurn){ MaxX=0; } ResetScrollbar(WndNum,MaxX,(-BaseY)+y); }