source: dev/branches/egtra/ab5.0/abdev/abdev/DrawBuffer.cpp@ 778

Last change on this file since 778 was 778, checked in by イグトランス (egtra), 13 years ago

XP以前対応途中(Win98でabdevが起動するところまで)

File size: 15.1 KB
Line 
1#include "stdafx.h"
2
3#include "Common.h"
4
5extern HFONT hFont_TextEdit;
6extern int font_width,font_height;
7
8class CDrawReserve{
9 int x,y;
10 COLORREF NowColor,NowBackColor;
11 int bNowUnder;
12 char *lpszBuffer;
13 int length;
14 int m_WndNum;
15 HDC hdc;
16 HBITMAP hMemBmp,hOldBitmap;
17 HFONT hOldFont;
18 SIZE ClientSize;
19 int iControlTabSpace;
20 int iOnePage_CharHeight;
21 int iLineNumberTextCount;
22 int iMax_OneLine_TextLength;
23public:
24 HDC memdc;
25 CDrawReserve(int WndNum,HDC _hDC,int cx,int cy,int ctrl_tab_space,int nMaxOnePageChar,int linenum_textcount,bool drawDirectly){
26 m_WndNum=WndNum;
27 x=-1;
28 y=-1;
29 bNowUnder=0;
30 ClientSize.cx=cx;
31 ClientSize.cy=cy;
32 iControlTabSpace=ctrl_tab_space;
33 iOnePage_CharHeight=nMaxOnePageChar;
34 iMax_OneLine_TextLength=cx/font_width+1;
35 iLineNumberTextCount=linenum_textcount;
36 if(drawDirectly){
37 hdc=0;
38 memdc=_hDC; // メモリDCを使わず、直接描画する
39 }
40 else{
41 hdc=_hDC;
42 memdc=CreateCompatibleDC(hdc);
43 hMemBmp=CreateCompatibleBitmap(hdc,cx,cy);
44 hOldBitmap=(HBITMAP)SelectObject(memdc,hMemBmp);
45 }
46
47 //背景色でメモリ画面を初期化
48 HBRUSH hBrush,hOldBrush;
49 hBrush=CreateSolidBrush(tci.rgbBackground);
50 hOldBrush=(HBRUSH)SelectObject(memdc,hBrush);
51 PatBlt(memdc,ctrl_tab_space,0,cx-ctrl_tab_space,cy,PATCOPY);
52 DeleteObject(hBrush);
53
54 //背景ビットマップ
55#ifdef THETEXT
56 if(pobj_DBTheme->hBackBmp){
57 HDC memdc2;
58 memdc2=CreateCompatibleDC(memdc);
59 SelectObject(memdc2,pobj_DBTheme->hBackBmp);
60 BitBlt(memdc,
61 cx-(pobj_DBTheme->sizeBackBmp.cx),
62 cy-(pobj_DBTheme->sizeBackBmp.cy),
63 pobj_DBTheme->sizeBackBmp.cx,pobj_DBTheme->sizeBackBmp.cy,
64 memdc2,0,0,SRCCOPY);
65 DeleteDC(memdc2);
66 }
67#endif
68
69 //フォントを設定
70 extern HFONT hFont_TextEdit;
71 hOldFont=(HFONT)SelectObject(memdc,hFont_TextEdit);
72
73 lpszBuffer=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1);
74 length=0;
75 }
76 ~CDrawReserve(){
77 SelectObject(memdc,hOldFont);
78 if(hdc){
79 SelectObject(memdc,hOldBitmap);
80 DeleteObject(hMemBmp);
81
82 DeleteDC(memdc);
83 }
84 HeapDefaultFree(lpszBuffer);
85 }
86
87 void draw(){
88 if(length==0) return;
89 SetTextColor(memdc,NowColor);
90 if(NowBackColor==tci.rgbBackground){
91 SetBkMode(memdc,TRANSPARENT);
92 }
93 else{
94 SetBkMode(memdc,OPAQUE);
95 SetBkColor(memdc,NowBackColor);
96 }
97
98 HFONT hBeforeFont;
99 if(bNowUnder){
100 //下線付きフォントに設定
101 extern HFONT hFont_HyperLink_TextEdit;
102 hBeforeFont=(HFONT)SelectObject(memdc,hFont_HyperLink_TextEdit);
103 }
104
105 int offset=0;
106 if(x<0){
107 offset=-x;
108
109 //左端の全角文字の文字化けを避けるために10バイトの余裕を作る
110 offset-=10;
111 if(offset<0) offset=0;
112
113 length-=offset;
114 if(length<0) return;
115 }
116
117 if(length>iMax_OneLine_TextLength+10){
118 length=iMax_OneLine_TextLength+10;
119 }
120
121 int i;
122 int *lpDxWidths;
123 lpDxWidths=(int *)malloc((length+1)*sizeof(int));
124 for(i=0;i<length+1;i++){
125 lpDxWidths[i]=font_width;
126 }
127 ExtTextOut(memdc,
128 (x+offset)*(font_width) +iControlTabSpace,
129 y*font_height,
130 0,NULL,
131 lpszBuffer+offset,length,
132 lpDxWidths);
133
134 if(bNowUnder){
135 SelectObject(memdc,hBeforeFont);
136 }
137
138 free(lpDxWidths);
139 }
140
141 void DrawReserve(int nXStart,int nYStart,COLORREF NextColor,COLORREF NextBackColor,BOOL bUnder,LPSTR lpString,int cbString){
142 if(nYStart!=y || NextColor!=NowColor || NextBackColor!=NowBackColor || bUnder!=bNowUnder){
143 //描画
144 draw();
145
146 x=nXStart;
147 y=nYStart;
148 NowColor=NextColor;
149 NowBackColor=NextBackColor;
150 bNowUnder=bUnder;
151
152 lpszBuffer[0]=0;
153 length=0;
154 }
155
156 //予約
157 lpszBuffer=(char *)HeapReAlloc(hHeap,0,lpszBuffer,length+cbString+1);
158 memcpy(lpszBuffer+length,lpString,cbString);
159 length+=cbString;
160 lpszBuffer[length]=0;
161 }
162
163 void finish(int BaseY){
164 draw();
165
166 HBRUSH hBrush,hOldBrush;
167 if(pobj_nv->bEditor_LineNumber){
168 hBrush=CreateSolidBrush(RGB(220,220,220));
169 hOldBrush=(HBRUSH)SelectObject(memdc,hBrush);
170
171
172 /////////////////////////////////////////////////////
173 // エディタ画面左端のコントロールタブの行番号を描画
174 /////////////////////////////////////////////////////
175
176 //灰色で塗りつぶす
177 PatBlt(memdc,
178 0,
179 0,
180 iControlTabSpace,
181 ClientSize.cy,
182 PATCOPY);
183
184 extern HFONT hFont_LineNumber;
185 int LineNumberFontHeight;
186
187 HFONT hOldFont;
188 hOldFont=(HFONT)SelectObject(memdc,hFont_LineNumber);
189 SetTextColor(memdc,RGB(60,60,60));
190 SetBkColor(memdc,RGB(220,220,220));
191
192 SIZE size;
193 GetTextExtentPoint32(memdc,"A",1,&size);
194 LineNumberFontHeight=size.cy;
195
196
197 //ブレークポイントの描画を準備
198 BreakPointsPerFile *pobj_FileBreakPoint=0;
199 if( projectInfo.IsOpened() ){
200 pobj_FileBreakPoint=
201 projectInfo.pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum]->path.c_str());
202 }
203 else{
204 extern CDBBreakPoint *pobj_DBBreakPoint;
205 pobj_FileBreakPoint=pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum]->path.c_str());
206 }
207
208
209 int i,i2;
210 char temporary[255],temp2[255];
211 if(y<iOnePage_CharHeight) i2=y;
212 else i2=iOnePage_CharHeight;
213 for(i=0;i<=i2;i++){
214
215 BOOL bBreakPoint;
216 bBreakPoint=0;
217 if(pobj_FileBreakPoint){
218 if(pobj_FileBreakPoint->check(i-BaseY)){
219 bBreakPoint=1;
220 }
221 }
222
223 if(bBreakPoint){
224 DrawIconEx(memdc,3,i*font_height+(font_height-16)/2,
225 (HICON)LoadImage(hIconResInst,MAKEINTRESOURCE(IDI_BREAKPOINT_FLAG),IMAGE_ICON,16,16,LR_SHARED),
226 16,16,0,NULL,DI_NORMAL);
227 }
228 else{
229 sprintf(temp2,"%%%dd:",iLineNumberTextCount);
230 sprintf(temporary,temp2,(i-BaseY)+1);
231
232 TextOut(memdc,
233 3,
234 i*font_height+(font_height-LineNumberFontHeight)/2,
235 temporary,
236 lstrlen(temporary));
237 }
238 }
239
240 SelectObject(memdc,hOldFont);
241
242
243 //ブラシを破棄
244 SelectObject(memdc,hOldBrush);
245 DeleteObject(hBrush);
246 }
247 else{
248 ////////////////////////////////////////////
249 // エディタ画面左端のコントロールタブを描画
250 // ※行番号は非表示
251 ////////////////////////////////////////////
252
253 hBrush=CreateSolidBrush(RGB(220,220,220));
254 hOldBrush=(HBRUSH)SelectObject(memdc,hBrush);
255
256 PatBlt(memdc,
257 0,
258 0,
259 iControlTabSpace,
260 ClientSize.cy,
261 PATCOPY);
262
263 SelectObject(memdc,hOldBrush);
264 DeleteObject(hBrush);
265 }
266
267
268 //メモリDCを使用している場合、その内容を画面に描画
269 if (hdc){
270 BitBlt(hdc,0,0,ClientSize.cx,ClientSize.cy,memdc,0,0,SRCCOPY);
271 }
272 }
273};
274
275static bool IsRemoteSession()
276{
277 OSVERSIONINFO vi = {sizeof vi};
278 BOOL ret = ::GetVersionEx(&vi);
279 if (ret && vi.dwMajorVersion >= 5)
280 {
281 const int SM_REMOTESESSION = 0x1000;
282 return GetSystemMetrics(SM_REMOTESESSION);
283 }
284 return false;
285}
286
287void TextEdit_DrawBuffer(HDC hdc,int WndNum,bool drawDirectly){
288 int i,i2;
289 int x,y;
290 int BaseX,BaseY,CharX;
291 char *pBuf,temporary[255];
292 HWND hEdit;
293
294
295 //背景モード、カラーの設定
296 COLORREF DefaultBackColor,CaretBackColor;
297 DefaultBackColor=tci.rgbBackground;
298
299 RECT ClientRect;
300 hEdit=GetWindow(MdiInfo[WndNum]->hwnd,GW_CHILD);
301 GetClientRect(hEdit,&ClientRect);
302
303 //エディタ画面左端のコントロールタブ
304 int iControlTabSpace;
305 int iLineNumberTextCount;
306 iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
307 iLineNumberTextCount=MdiInfo[WndNum]->pMdiTextEdit->iLineNumberTextCount;
308
309 //一ページ中に表示できる行数を取得
310 int OnePage_CharHeight;
311 OnePage_CharHeight=(ClientRect.bottom/font_height)+1;
312
313 //描画用クラス
314 CDrawReserve obj_dr(
315 WndNum,
316 hdc,
317 ClientRect.right-ClientRect.left,ClientRect.bottom-ClientRect.top,
318 iControlTabSpace,
319 OnePage_CharHeight,
320 iLineNumberTextCount,
321 drawDirectly || IsRemoteSession());
322
323
324 //テキストバッファをコード内で参照しやすいようにポインタ変数を利用する
325 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
326
327 //選択範囲を取得
328 CHARRANGE CharRange;
329 TextEdit_GetSel(WndNum,&CharRange);
330
331 //ベース描画ポジションを取得(文字単位)
332 BaseX=0;
333 BaseY=0;
334 GetScrollBaseCaretPos(MdiInfo[WndNum],&BaseX,&BaseY);
335
336 if(pobj_nv->bEditor_CaretLine_BackGround){
337 //カーソル行の色を変える
338 CaretBackColor=tci.rgbCursorBack;
339 }
340 else{
341 //カーソル行の色を変えない
342 CaretBackColor=tci.rgbBackground;
343 }
344 HBRUSH hCaretBackBrush;
345 hCaretBackBrush=CreateSolidBrush(CaretBackColor);
346
347 BOOL IsStr=0;
348 DWORD dwComment=0;
349 BOOL bMultiLineComment;
350 COLORREF NextColor,NextBackColor;
351 int MaxX=0;
352 x=BaseX;
353 y=BaseY;
354 CharX=0; //左端から何文字目かを示す
355 int bHyperLinkUnderBar=0; //ハイパーリンク用下線の表示スイッチ
356 for(i=0;;i++){
357 if(pBuf[i]=='\0'){
358 if(0<=y&&y<=OnePage_CharHeight){
359 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
360 ////////////////////////////////////
361 // カーソル行では余白を塗りつぶす
362 ////////////////////////////////////
363
364 HBRUSH hTempBrush;
365 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
366
367 //終端コードよりも右側はブラシで塗りつぶす
368 PatBlt(obj_dr.memdc,
369 x*font_width +iControlTabSpace,
370 y*font_height,
371 ClientRect.right-(x*font_width +iControlTabSpace),
372 font_height,
373 PATCOPY);
374
375 //カーソル行
376 SelectObject(obj_dr.memdc,hTempBrush);
377 }
378
379 //行番号が末端行にも表示されるようにするために描画予約を行う
380 obj_dr.DrawReserve(
381 x,
382 y,
383 NULL,
384 NULL,
385 bHyperLinkUnderBar,
386 "",0);
387 }
388
389 if(MaxX<CharX) MaxX=CharX;
390
391 break;
392 }
393
394 if(IsRightTurn(pBuf,i,x)){
395 /////////////////
396 // 自動折り返し
397 /////////////////
398
399 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
400 ///////////////////////////////////////////////////////////
401 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
402 ///////////////////////////////////////////////////////////
403
404 HBRUSH hTempBrush;
405
406 //カーソル行
407 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
408
409 PatBlt(obj_dr.memdc,
410 x*font_width +iControlTabSpace,
411 y*font_height,
412 ClientRect.right-(x*font_width +iControlTabSpace),
413 font_height,
414 PATCOPY);
415
416 //カーソル行
417 SelectObject(obj_dr.memdc,hTempBrush);
418 }
419
420 y++;
421
422 x=BaseX;
423 CharX=0;
424 i--;
425 continue;
426 }
427
428 if(MdiInfo[WndNum]->DocType==WNDTYPE_BASIC){
429
430 if(pBuf[i]=='\"'&&dwComment==0) IsStr^=1;
431
432 //複数行に渡るコメントを考慮
433 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.size() ) == 0
434 && IsStr == 0
435 && dwComment == 0 )
436 {
437 // /*
438 dwComment=12;
439 bMultiLineComment=1;
440 }
441 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.size() ) == 0
442 && dwComment == 10
443 && bMultiLineComment )
444 {
445 // */
446 dwComment=3;
447 }
448
449 //単行コメント
450 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.size() ) == 0
451 && dwComment == 0
452 && IsStr == 0 )
453 {
454 // '
455 dwComment=10;
456 bMultiLineComment=0;
457 }
458
459 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
460 //単行コメント中での改行は、コメントを解除
461 if(dwComment&&bMultiLineComment==0){
462 IsStr=0;
463 dwComment=0;
464 }
465 }
466 if(dwComment!=0&&dwComment!=10) dwComment--;
467 }
468 if(MdiInfo[WndNum]->DocType==WNDTYPE_HTML){
469 //複数行に渡るコメントを考慮
470 if(pBuf[i]=='<'&&pBuf[i+1]=='!'&&pBuf[i+2]=='-'&&pBuf[i+3]=='-'&&IsStr==0&&dwComment==0){
471 dwComment=10;
472 }
473 if(pBuf[i]=='-'&&pBuf[i+1]=='-'&&pBuf[i+2]=='>'&&
474 dwComment){
475 dwComment=4;
476 }
477 if(dwComment!=0&&dwComment!=10) dwComment--;
478 }
479
480 //ハイパーリンク用下線
481 if(MdiInfo[WndNum]->pMdiTextEdit->iUnderStart<=i&&i<MdiInfo[WndNum]->pMdiTextEdit->iUnderEnd)
482 bHyperLinkUnderBar=1;
483 else bHyperLinkUnderBar=0;
484
485 if(0<=y&&y<=OnePage_CharHeight){
486 //////////////////////////////////
487 // 表示中ページでは文字単位で描画
488 //////////////////////////////////
489 //※i2に描画する文字数を格納する
490
491 NextBackColor=DefaultBackColor;
492 if(dwComment){
493 //複数行に渡るコメント
494 NextColor=tci.rgbComment;
495 }
496 else{
497 //通常カラー
498 NextColor=MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i];
499 }
500
501 if(CharRange.cpMin<=i&&i<CharRange.cpMax){
502 //選択されているバッファは反転表示する
503 NextColor=NextColor^0x00FFFFFF;
504 NextBackColor=NextBackColor^0x00FFFFFF;
505 }
506 else{
507 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
508 //カーソル行
509 NextBackColor=CaretBackColor;
510 }
511 }
512
513 if(IsDBCSLeadByte(pBuf[i])){
514 //マルチバイト文字
515 i2=2;
516 obj_dr.DrawReserve(
517 x,
518 y,
519 NextColor,
520 NextBackColor,
521 bHyperLinkUnderBar,
522 pBuf+i,i2);
523
524 i++;
525 }
526 else if(pBuf[i]=='\t'){
527 //タブ文字
528 int tab;
529 tab=pobj_nv->TabSize;
530
531 if((x-BaseX)%tab==0) i2=tab;
532 else i2=tab-(x-BaseX)%tab;
533 memset(temporary,' ',i2);
534 temporary[i2]=0;
535
536 obj_dr.DrawReserve(
537 x,
538 y,
539 NextColor,
540 NextBackColor,
541 bHyperLinkUnderBar,
542 temporary,i2);
543 }
544 else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
545 //改行文字は1スペースだけ空白を描画しておく(反転表示をするため)
546 i2=1;
547 temporary[0]=' ';
548 temporary[1]=0;
549 obj_dr.DrawReserve(
550 x,
551 y,
552 NextColor,
553 NextBackColor,
554 bHyperLinkUnderBar,
555 temporary,i2);
556
557
558 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
559 ///////////////////////////////////////////////////////////
560 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
561 ///////////////////////////////////////////////////////////
562
563 HBRUSH hTempBrush;
564
565 //カーソル行
566 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
567
568 PatBlt(obj_dr.memdc,
569 (x+i2)*font_width +iControlTabSpace,
570 y*font_height,
571 ClientRect.right-((x+i2)*font_width +iControlTabSpace),
572 font_height,
573 PATCOPY);
574
575 //カーソル行
576 SelectObject(obj_dr.memdc,hTempBrush);
577 }
578 }
579 else{
580 //通常のキャラ文字
581 i2=1;
582 obj_dr.DrawReserve(
583 x,
584 y,
585 NextColor,
586 NextBackColor,
587 bHyperLinkUnderBar,
588 pBuf+i,i2);
589 }
590 }
591 else{
592 ////////////////////////////////////////
593 // 非表示ページでは文字数の計算だけ行う
594 ////////////////////////////////////////
595 //※i2に描画する文字数を格納する
596
597 if(IsDBCSLeadByte(pBuf[i])){
598 //マルチバイト文字
599 i2=2;
600 i++;
601 }
602 else if(pBuf[i]=='\t'){
603 //タブ文字
604 int tab;
605 tab=pobj_nv->TabSize;
606
607 if((x-BaseX)%tab==0) i2=tab;
608 else i2=tab-(x-BaseX)%tab;
609 }
610 else{
611 //通常のキャラ文字(改行文字を含む)
612 i2=1;
613 }
614 }
615
616 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
617 y++;
618
619 if(MaxX<CharX) MaxX=CharX;
620
621 x=BaseX;
622 CharX=0;
623
624 i++;
625 }
626 else{
627 x+=i2;
628 CharX+=i2;
629 }
630 }
631
632 obj_dr.finish(BaseY);
633
634 DeleteObject(hCaretBackBrush);
635
636
637 //////////////////////////////////
638 // スクロールバーの範囲をセット
639 //////////////////////////////////
640
641 if(pobj_nv->bRightTurn){
642 MaxX=0;
643 }
644
645 ResetScrollbar(WndNum,MaxX,(-BaseY)+y);
646}
Note: See TracBrowser for help on using the repository browser.