source: dev/trunk/ab5.0/abdev/abdev/DrawBuffer.cpp@ 772

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

Windows 7タスクバーへの対応を実装。
(#245)

File size: 14.8 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
275void TextEdit_DrawBuffer(HDC hdc,int WndNum,bool drawDirectly){
276 int i,i2;
277 int x,y;
278 int BaseX,BaseY,CharX;
279 char *pBuf,temporary[255];
280 HWND hEdit;
281
282
283 //背景モード、カラーの設定
284 COLORREF DefaultBackColor,CaretBackColor;
285 DefaultBackColor=tci.rgbBackground;
286
287 RECT ClientRect;
288 hEdit=GetWindow(MdiInfo[WndNum]->hwnd,GW_CHILD);
289 GetClientRect(hEdit,&ClientRect);
290
291 //エディタ画面左端のコントロールタブ
292 int iControlTabSpace;
293 int iLineNumberTextCount;
294 iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
295 iLineNumberTextCount=MdiInfo[WndNum]->pMdiTextEdit->iLineNumberTextCount;
296
297 //一ページ中に表示できる行数を取得
298 int OnePage_CharHeight;
299 OnePage_CharHeight=(ClientRect.bottom/font_height)+1;
300
301 //描画用クラス
302 CDrawReserve obj_dr(
303 WndNum,
304 hdc,
305 ClientRect.right-ClientRect.left,ClientRect.bottom-ClientRect.top,
306 iControlTabSpace,
307 OnePage_CharHeight,
308 iLineNumberTextCount,
309 drawDirectly || GetSystemMetrics(SM_REMOTESESSION));
310
311
312 //テキストバッファをコード内で参照しやすいようにポインタ変数を利用する
313 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
314
315 //選択範囲を取得
316 CHARRANGE CharRange;
317 TextEdit_GetSel(WndNum,&CharRange);
318
319 //ベース描画ポジションを取得(文字単位)
320 BaseX=0;
321 BaseY=0;
322 GetScrollBaseCaretPos(MdiInfo[WndNum],&BaseX,&BaseY);
323
324 if(pobj_nv->bEditor_CaretLine_BackGround){
325 //カーソル行の色を変える
326 CaretBackColor=tci.rgbCursorBack;
327 }
328 else{
329 //カーソル行の色を変えない
330 CaretBackColor=tci.rgbBackground;
331 }
332 HBRUSH hCaretBackBrush;
333 hCaretBackBrush=CreateSolidBrush(CaretBackColor);
334
335 BOOL IsStr=0;
336 DWORD dwComment=0;
337 BOOL bMultiLineComment;
338 COLORREF NextColor,NextBackColor;
339 int MaxX=0;
340 x=BaseX;
341 y=BaseY;
342 CharX=0; //左端から何文字目かを示す
343 int bHyperLinkUnderBar=0; //ハイパーリンク用下線の表示スイッチ
344 for(i=0;;i++){
345 if(pBuf[i]=='\0'){
346 if(0<=y&&y<=OnePage_CharHeight){
347 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
348 ////////////////////////////////////
349 // カーソル行では余白を塗りつぶす
350 ////////////////////////////////////
351
352 HBRUSH hTempBrush;
353 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
354
355 //終端コードよりも右側はブラシで塗りつぶす
356 PatBlt(obj_dr.memdc,
357 x*font_width +iControlTabSpace,
358 y*font_height,
359 ClientRect.right-(x*font_width +iControlTabSpace),
360 font_height,
361 PATCOPY);
362
363 //カーソル行
364 SelectObject(obj_dr.memdc,hTempBrush);
365 }
366
367 //行番号が末端行にも表示されるようにするために描画予約を行う
368 obj_dr.DrawReserve(
369 x,
370 y,
371 NULL,
372 NULL,
373 bHyperLinkUnderBar,
374 "",0);
375 }
376
377 if(MaxX<CharX) MaxX=CharX;
378
379 break;
380 }
381
382 if(IsRightTurn(pBuf,i,x)){
383 /////////////////
384 // 自動折り返し
385 /////////////////
386
387 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
388 ///////////////////////////////////////////////////////////
389 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
390 ///////////////////////////////////////////////////////////
391
392 HBRUSH hTempBrush;
393
394 //カーソル行
395 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
396
397 PatBlt(obj_dr.memdc,
398 x*font_width +iControlTabSpace,
399 y*font_height,
400 ClientRect.right-(x*font_width +iControlTabSpace),
401 font_height,
402 PATCOPY);
403
404 //カーソル行
405 SelectObject(obj_dr.memdc,hTempBrush);
406 }
407
408 y++;
409
410 x=BaseX;
411 CharX=0;
412 i--;
413 continue;
414 }
415
416 if(MdiInfo[WndNum]->DocType==WNDTYPE_BASIC){
417
418 if(pBuf[i]=='\"'&&dwComment==0) IsStr^=1;
419
420 //複数行に渡るコメントを考慮
421 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.size() ) == 0
422 && IsStr == 0
423 && dwComment == 0 )
424 {
425 // /*
426 dwComment=12;
427 bMultiLineComment=1;
428 }
429 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.size() ) == 0
430 && dwComment == 10
431 && bMultiLineComment )
432 {
433 // */
434 dwComment=3;
435 }
436
437 //単行コメント
438 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.size() ) == 0
439 && dwComment == 0
440 && IsStr == 0 )
441 {
442 // '
443 dwComment=10;
444 bMultiLineComment=0;
445 }
446
447 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
448 //単行コメント中での改行は、コメントを解除
449 if(dwComment&&bMultiLineComment==0){
450 IsStr=0;
451 dwComment=0;
452 }
453 }
454 if(dwComment!=0&&dwComment!=10) dwComment--;
455 }
456 if(MdiInfo[WndNum]->DocType==WNDTYPE_HTML){
457 //複数行に渡るコメントを考慮
458 if(pBuf[i]=='<'&&pBuf[i+1]=='!'&&pBuf[i+2]=='-'&&pBuf[i+3]=='-'&&IsStr==0&&dwComment==0){
459 dwComment=10;
460 }
461 if(pBuf[i]=='-'&&pBuf[i+1]=='-'&&pBuf[i+2]=='>'&&
462 dwComment){
463 dwComment=4;
464 }
465 if(dwComment!=0&&dwComment!=10) dwComment--;
466 }
467
468 //ハイパーリンク用下線
469 if(MdiInfo[WndNum]->pMdiTextEdit->iUnderStart<=i&&i<MdiInfo[WndNum]->pMdiTextEdit->iUnderEnd)
470 bHyperLinkUnderBar=1;
471 else bHyperLinkUnderBar=0;
472
473 if(0<=y&&y<=OnePage_CharHeight){
474 //////////////////////////////////
475 // 表示中ページでは文字単位で描画
476 //////////////////////////////////
477 //※i2に描画する文字数を格納する
478
479 NextBackColor=DefaultBackColor;
480 if(dwComment){
481 //複数行に渡るコメント
482 NextColor=tci.rgbComment;
483 }
484 else{
485 //通常カラー
486 NextColor=MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i];
487 }
488
489 if(CharRange.cpMin<=i&&i<CharRange.cpMax){
490 //選択されているバッファは反転表示する
491 NextColor=NextColor^0x00FFFFFF;
492 NextBackColor=NextBackColor^0x00FFFFFF;
493 }
494 else{
495 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
496 //カーソル行
497 NextBackColor=CaretBackColor;
498 }
499 }
500
501 if(IsDBCSLeadByte(pBuf[i])){
502 //マルチバイト文字
503 i2=2;
504 obj_dr.DrawReserve(
505 x,
506 y,
507 NextColor,
508 NextBackColor,
509 bHyperLinkUnderBar,
510 pBuf+i,i2);
511
512 i++;
513 }
514 else if(pBuf[i]=='\t'){
515 //タブ文字
516 int tab;
517 tab=pobj_nv->TabSize;
518
519 if((x-BaseX)%tab==0) i2=tab;
520 else i2=tab-(x-BaseX)%tab;
521 memset(temporary,' ',i2);
522 temporary[i2]=0;
523
524 obj_dr.DrawReserve(
525 x,
526 y,
527 NextColor,
528 NextBackColor,
529 bHyperLinkUnderBar,
530 temporary,i2);
531 }
532 else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
533 //改行文字は1スペースだけ空白を描画しておく(反転表示をするため)
534 i2=1;
535 temporary[0]=' ';
536 temporary[1]=0;
537 obj_dr.DrawReserve(
538 x,
539 y,
540 NextColor,
541 NextBackColor,
542 bHyperLinkUnderBar,
543 temporary,i2);
544
545
546 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
547 ///////////////////////////////////////////////////////////
548 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
549 ///////////////////////////////////////////////////////////
550
551 HBRUSH hTempBrush;
552
553 //カーソル行
554 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
555
556 PatBlt(obj_dr.memdc,
557 (x+i2)*font_width +iControlTabSpace,
558 y*font_height,
559 ClientRect.right-((x+i2)*font_width +iControlTabSpace),
560 font_height,
561 PATCOPY);
562
563 //カーソル行
564 SelectObject(obj_dr.memdc,hTempBrush);
565 }
566 }
567 else{
568 //通常のキャラ文字
569 i2=1;
570 obj_dr.DrawReserve(
571 x,
572 y,
573 NextColor,
574 NextBackColor,
575 bHyperLinkUnderBar,
576 pBuf+i,i2);
577 }
578 }
579 else{
580 ////////////////////////////////////////
581 // 非表示ページでは文字数の計算だけ行う
582 ////////////////////////////////////////
583 //※i2に描画する文字数を格納する
584
585 if(IsDBCSLeadByte(pBuf[i])){
586 //マルチバイト文字
587 i2=2;
588 i++;
589 }
590 else if(pBuf[i]=='\t'){
591 //タブ文字
592 int tab;
593 tab=pobj_nv->TabSize;
594
595 if((x-BaseX)%tab==0) i2=tab;
596 else i2=tab-(x-BaseX)%tab;
597 }
598 else{
599 //通常のキャラ文字(改行文字を含む)
600 i2=1;
601 }
602 }
603
604 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
605 y++;
606
607 if(MaxX<CharX) MaxX=CharX;
608
609 x=BaseX;
610 CharX=0;
611
612 i++;
613 }
614 else{
615 x+=i2;
616 CharX+=i2;
617 }
618 }
619
620 obj_dr.finish(BaseY);
621
622 DeleteObject(hCaretBackBrush);
623
624
625 //////////////////////////////////
626 // スクロールバーの範囲をセット
627 //////////////////////////////////
628
629 if(pobj_nv->bRightTurn){
630 MaxX=0;
631 }
632
633 ResetScrollbar(WndNum,MaxX,(-BaseY)+y);
634}
Note: See TracBrowser for help on using the repository browser.