source: dev/trunk/ab5.0/abdev/abdev/ParameterHint.cpp@ 681

Last change on this file since 681 was 681, checked in by dai_9181, 16 years ago

・TinyXMLをabdevプロジェクトで使えるようにした。
・コードハイライターを汎用的に実装しなおした。syntaxファイルを読み込む仕様とした。

File size: 29.0 KB
Line 
1#include "stdafx.h"
2
3#include "common.h"
4
5void ShowCommandMessage(void);
6
7BOOL CheckGrammar(char *buffer){
8 int i,IsStr,PareNum;
9
10 for(i=0,IsStr=0,PareNum=0;;i++){
11 if(buffer[i]=='\"') IsStr^=1;
12 else if(buffer[i]=='(') PareNum++;
13 else if(buffer[i]==')') PareNum--;
14 else if(buffer[i]=='\0'||(buffer[i]=='\r'&&buffer[i+1]=='\n')){
15 if(IsStr||PareNum) return 0;
16 if(buffer[i]=='\0') break;
17 i++;
18 continue;
19 }
20 else if(buffer[i]=='\''&&IsStr==0){
21 while(!(buffer[i]=='\0'||(buffer[i]=='\r'&&buffer[i+1]=='\n'))) i++;
22 i--;
23 continue;
24 }
25 }
26 return 1;
27}
28
29char *GetUserSourceCode(void){
30 //単体ファイルのときはそのファイルを、プロジェクトのときはpjname.abの内容を取得
31 extern HANDLE hHeap;
32 int i;
33 char temporary[MAX_PATH],*pBuf;
34
35 if( projectInfo.IsOpened() ){
36 //プロジェクトが開かれているとき
37 lstrcpy(temporary,projectInfo.fileSystem.root.files[0].GetFullPath().c_str());
38
39 for(i=0;i<MdiInfo.size();i++){
40 if(MdiInfo[i]->hwnd){
41 if(lstrcmpi(MdiInfo[i]->path.c_str(),temporary)==0) break;
42 }
43 }
44 if(i==MdiInfo.size()){
45 //ファイルから開く
46 pBuf=ReadBuffer(temporary);
47 }
48 else{
49 //エディタから読み込む
50 pBuf=(char *)HeapAlloc(hHeap,0,lstrlen(MdiInfo[i]->pMdiTextEdit->buffer)+1);
51 lstrcpy(pBuf,MdiInfo[i]->pMdiTextEdit->buffer);
52 }
53 }
54 else{
55 //単体ソースコードのとき
56 int WndNum;
57
58 WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
59
60 pBuf=(char *)HeapAlloc(hHeap,0,lstrlen(MdiInfo[WndNum]->pMdiTextEdit->buffer)+1);
61 lstrcpy(pBuf,MdiInfo[WndNum]->pMdiTextEdit->buffer);
62 }
63
64 //ファイルをインクルード
65 pBuf=IncludeFiles(pBuf);
66
67 return pBuf;
68}
69
70BOOL SetCommandMessageToMethodCheck(char *Command){
71 extern METHODCHECKINFO MethodCheckInfo;
72 int CmdValue;
73
74 if( ActiveBasic::IDE::Program::ablang->IsExistReservedKeywordWithQuickHelp( Command ) )
75 {
76 lstrcpy( MethodCheckInfo.msg, ActiveBasic::IDE::Program::ablang->GetReservedKeywordWithQuickHelp( Command ).c_str() );
77 return 1;
78 }
79
80 return 0;
81}
82
83void ChangeReturnCode(char *buffer){
84 //改行コードのCRLFをLFに変換
85 int i,i2;
86 for(i=0,i2=0;;i++,i2++){
87 if(buffer[i]=='\r'&&buffer[i+1]=='\n') i++;
88 buffer[i2]=buffer[i];
89 if(buffer[i]=='\0') break;
90 }
91}
92void DeleteComment(char *buffer){ //注釈「'」の取り除き
93 int i,i2,i3,IsStr;
94 char *temporary;
95 temporary=(char *)GlobalAlloc(GMEM_FIXED,lstrlen(buffer)+1);
96 for(i=0,i2=0,i3=0,IsStr=0;;i++,i2++){
97 if(buffer[i]=='\"') IsStr^=1;
98 if(buffer[i]=='\n'||buffer[i]=='\0'){
99 i2--;
100 while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
101 i2++;
102
103 if(i3){
104 //複数行に渡る注釈文の中に改行が存在するとき
105 memset(temporary+i2,'\n',i3);
106 i2+=i3;
107 i3=0;
108 }
109 }
110 if(buffer[i]=='\''&&IsStr==0){
111 //注釈文
112 i2--;
113 while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
114 i2++;
115 while(buffer[i]!='\n'&&buffer[i]!='\0') i++;
116 }
117 if(buffer[i]=='/'&&buffer[i+1]=='*'&&IsStr==0){
118 //注釈文(複数行)
119 i+=2;
120 i3=0;
121 while(!(buffer[i]=='*'&&buffer[i+1]=='/')){
122 if(buffer[i]=='\n') i3++;
123 if(buffer[i]=='\0') break;
124 i++;
125 }
126 if(buffer[i]){
127 i+=2;
128 }
129 i--;
130 i2--;
131 continue;
132 }
133 temporary[i2]=buffer[i];
134 if(buffer[i]=='\0') break;
135 }
136 lstrcpy(buffer,temporary);
137 GlobalFree(temporary);
138}
139
140BOOL GetDefualtFunctionParameter(char *pBuf,char *FuncName,char *Parameter){
141 int i,i2;
142 char temporary[VN_SIZE];
143
144 /////////////////////////////////////////
145 // ソースコードから関数定義位置を取得
146 /////////////////////////////////////////
147
148 for(i=0;;i++){
149 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
150
151 if(memicmp(pBuf+i,"Class",5)==0&&(pBuf[i+5]==' '||pBuf[i+5]=='\t')||
152 memicmp(pBuf+i,"Interface",9)==0&&(pBuf[i+9]==' '||pBuf[i+9]=='\t')||
153 memicmp(pBuf+i,"Type",4)==0&&(pBuf[i+4]==' '||pBuf[i+4]=='\t')){
154 /* Class ~ End Class
155 Interface ~ End Interface
156 Type ~ End Type
157 は飛び越す */
158
159 while(1){
160 if(pBuf[i]=='\0'){
161 i2=0;
162 break;
163 }
164
165 if(memicmp(pBuf+i,"End",3)==0){
166 /* End Class
167 End Interface
168 End Type
169 の検出 */
170 i+=3;
171 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
172
173 if(memicmp(pBuf+i,"Class",5)==0&&(!IsVariableChar(pBuf[i+5]))||
174 memicmp(pBuf+i,"Interface",9)==0&&(!IsVariableChar(pBuf[i+9]))||
175 memicmp(pBuf+i,"Type",4)==0&&(!IsVariableChar(pBuf[i+4]))){
176 i2=0;
177 break;
178 }
179 }
180
181 //次の行をサーチ
182 for(;;i++){
183 if(pBuf[i]=='\0') break;
184 i2=IsCommandDelimitation(pBuf,i);
185 if(i2){
186 i+=i2;
187 break;
188 }
189 }
190 JumpBlank(pBuf,&i);
191 }
192 }
193
194 if(memicmp(pBuf+i,"Declare",7)==0&&(pBuf[i+7]==' '||pBuf[i+7]=='\t')){
195 i+=8;
196 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
197
198 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
199 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
200 else goto NextCommand;
201
202 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
203
204 for(i2=0;;i++,i2++){
205 if(!IsVariableChar(pBuf[i])){
206 temporary[i2]=0;
207 break;
208 }
209 temporary[i2]=pBuf[i];
210 }
211 if(lstrcmp(temporary,FuncName)==0){
212 //関数名が一致したとき
213 break;
214 }
215 }
216 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
217 memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){
218 if(pBuf[i]=='f'||pBuf[i]=='F') i+=9;
219 else i+=4;
220
221 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
222 for(i2=0;;i++,i2++){
223 if(!IsVariableChar(pBuf[i])){
224 temporary[i2]=0;
225 break;
226 }
227 temporary[i2]=pBuf[i];
228 }
229 if(lstrcmpi(temporary,"Export")==0){
230 //"Export"を飛び越す
231 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
232 for(i2=0;;i++,i2++){
233 if(!IsVariableChar(pBuf[i])){
234 temporary[i2]=0;
235 break;
236 }
237 temporary[i2]=pBuf[i];
238 }
239 }
240 if(lstrcmp(temporary,FuncName)==0){
241 //関数名が一致したとき
242 break;
243 }
244
245 }
246
247NextCommand:
248 for(;;i++){
249 i2=IsCommandDelimitation(pBuf,i);
250 if(i2){
251 if(i2==2) i++;
252 break;
253 }
254 }
255
256 if(pBuf[i]=='\0') return 0;
257 }
258
259 for(;;i++){
260 if(pBuf[i]=='(') break;
261 if(IsCommandDelimitation(pBuf,i)) return 0;
262 }
263
264 //関数名をコピー
265 lstrcpy(Parameter,FuncName);
266 i2=lstrlen(Parameter);
267
268
269 //////////////////////////////////////////////////////
270 //パラメータをコピー
271 //(コメントの挿入、途中改行などの状況を考慮する)
272 //////////////////////////////////////////////////////
273
274 for(;;i++,i2++){
275 if(IsVariableChar(pBuf[i-1])==0&&pBuf[i-1]!=')'&&IS_BLANK(pBuf[i])||
276 pBuf[i]=='\''||
277 pBuf[i]=='/'&&pBuf[i+1]=='*')
278 JumpBlank(pBuf,&i);
279
280 if(IsCommandDelimitation(pBuf,i)){
281 if(IS_RETURN(pBuf,i)&&
282 pBuf[i-1]=='_'||pBuf[i-1]=='('||pBuf[i-1]==','){
283 //改行を許可
284 i2--;
285 if(Parameter[i2]=='_') i2--;
286
287 i+=2;
288 continue;
289 }
290
291 Parameter[i2]=0;
292 break;
293 }
294 Parameter[i2]=pBuf[i];
295 }
296
297
298 //文法チェック
299 if(!CheckGrammar(Parameter)) return 0;
300
301
302 return 1;
303}
304BOOL GetClassMemberFunctionParameter(char *pBuf,char *ClassName,char *nest,char *Parameter){
305 extern HANDLE hHeap;
306 extern char *pHeaderBuf;
307 extern char *pUserSource;
308 int i,i2;
309 char temporary[8192];
310 DWORD dwClassType;
311 BOOL bRet;
312
313
314 /////////////////////////////////////////
315 // ソースコードからクラス定義位置を取得
316 /////////////////////////////////////////
317 i=GetClassPos(pBuf,ClassName,&dwClassType);
318 if(pBuf[i]=='\0') return 0;
319
320 //クラス、配列の構成要素を解析する
321 char VarName[VN_SIZE]; //変数名
322 char array[VN_SIZE]; //第1次配列
323 char lpPtrOffset[VN_SIZE]; //第2次配列
324 char NestMember[VN_SIZE]; //入れ子メンバ
325 int RefType; //"."参照のときは0、"->"参照のときは1
326 lstrcpy(VarName,nest);
327 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)) return 0;
328
329 if(RefType){
330 ////////////////////
331 // 入れ子構造の場合
332 ////////////////////
333
334 //メンバ変数の型であるクラスの名前を取得
335 char ClassName[VN_SIZE];
336 BOOL bArray;
337 if(!GetClassNameFromClassMember(pBuf,i,VarName,ClassName,&bArray)) return 0;
338
339 //TypeDef宣言を考慮してオリジナルなクラス名を取得
340 GetOriginalClassName(ClassName);
341
342 if(!CheckReferType(ClassName,bArray,array,RefType)) return 0;
343
344 //ユーザーのソースコードをサーチ
345 bRet=GetClassMemberFunctionParameter(pUserSource,ClassName,NestMember,Parameter);
346 if(!bRet){
347 //失敗したときはbasic.sbpをサーチ
348 bRet=GetClassMemberFunctionParameter(pHeaderBuf,ClassName,NestMember,Parameter);
349 }
350 return bRet;
351 }
352
353
354 ////////////////////////
355 // メンバ情報を取得
356 ////////////////////////
357 DWORD dwProc;
358
359 if(memicmp(pBuf+i,"Inherits",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){
360 i+=9;
361 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
362
363 ////////////////////////
364 // 継承先クラスをサーチ
365 ////////////////////////
366
367 for(i2=0;;i++,i2++){
368 if(!IsVariableChar(pBuf[i])){
369 temporary[i2]=0;
370 break;
371 }
372 temporary[i2]=pBuf[i];
373 }
374
375 //ユーザーのソースコードをサーチ
376 bRet=GetClassMemberFunctionParameter(pUserSource,temporary,nest,Parameter);
377 if(!bRet){
378 //失敗したときはbasic.sbpをサーチ
379 bRet=GetClassMemberFunctionParameter(pHeaderBuf,temporary,nest,Parameter);
380 }
381 if(bRet) return 1;
382 }
383
384 //メンバ変数、関数を取得
385 while(1){
386 if(pBuf[i]=='\0') break;
387 if(memicmp(pBuf+i,"End",3)==0){
388 /* End Class
389 End Interface
390 End Type
391 の検出 */
392 i2=i+3;
393 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
394
395 if(memicmp(pBuf+i2,"Class",5)==0&&(!IsVariableChar(pBuf[i2+5]))||
396 memicmp(pBuf+i2,"Interface",9)==0&&(!IsVariableChar(pBuf[i2+9]))||
397 memicmp(pBuf+i2,"Type",4)==0&&(!IsVariableChar(pBuf[i2+4]))) break;
398 }
399
400 if(memicmp(pBuf+i,"Abstract",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
401 memicmp(pBuf+i,"Virtual",7)==0&&(pBuf[i+7]==' '||pBuf[i+7]=='\t')||
402 memicmp(pBuf+i,"Override",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
403 memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
404 memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){
405 //メンバ関数のとき
406 if(pBuf[i]=='a'||pBuf[i]=='A'){
407 i+=9;
408 dwProc=ESC_ABSTRACT;
409
410 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
411 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
412 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
413 }
414 else if(pBuf[i]=='v'||pBuf[i]=='V'){
415 i+=8;
416
417 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
418 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){
419 i+=9;
420 dwProc=ESC_FUNCTION;
421 }
422 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){
423 i+=4;
424 dwProc=ESC_SUB;
425 }
426 }
427 else if(pBuf[i]=='o'||pBuf[i]=='O'){
428 i+=9;
429
430 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
431 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){
432 i+=9;
433 dwProc=ESC_FUNCTION;
434 }
435 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){
436 i+=4;
437 dwProc=ESC_SUB;
438 }
439 }
440 else if(pBuf[i]=='f'||pBuf[i]=='F'){
441 i+=9;
442 dwProc=ESC_FUNCTION;
443 }
444 else if(pBuf[i]=='s'||pBuf[i]=='S'){
445 i+=4;
446 dwProc=ESC_SUB;
447 }
448
449 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
450 }
451 else{
452 //メンバ変数のとき
453 dwProc=0;
454 }
455
456 if(dwProc){
457 //変数名または関数名を取得
458 for(i2=0;;i++,i2++){
459 if(!IsVariableChar(pBuf[i])){
460 temporary[i2]=0;
461 break;
462 }
463 temporary[i2]=pBuf[i];
464 }
465
466 if(lstrcmp(temporary,nest)==0){
467 //ターゲットとなるメンバ関数が見つかったとき
468 for(;;i++){
469 if(pBuf[i]=='(') break;
470 if(IsCommandDelimitation(pBuf,i)) return 0;
471 }
472
473 lstrcpy(Parameter,nest);
474 i2=lstrlen(Parameter);
475 for(;;i++,i2++){
476 if(IsCommandDelimitation(pBuf,i)){
477 Parameter[i2]=0;
478 break;
479 }
480 Parameter[i2]=pBuf[i];
481 }
482
483 if(!CheckGrammar(Parameter)) return 0;
484
485 return 1;
486 }
487 }
488
489 //次の行をサーチ
490 for(;;i++){
491 if(pBuf[i]=='\0') break;
492 i2=IsCommandDelimitation(pBuf,i);
493 if(i2){
494 i+=i2;
495 break;
496 }
497 }
498 JumpBlank(pBuf,&i);
499
500 if((dwProc==ESC_SUB||dwProc==ESC_FUNCTION)&&dwClassType!=ESC_INTERFACE){
501 //End Sub、End Functionまでジャンプする
502
503 while(1){
504 if(pBuf[i]=='\0'){
505 i2=0;
506 break;
507 }
508
509 if(memicmp(pBuf+i,"End",3)==0){
510 /* End Sub
511 End Function
512 の検出 */
513 i+=3;
514 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
515
516 if(memicmp(pBuf+i,"Sub",3)==0&&(!IsVariableChar(pBuf[i+3]))||
517 memicmp(pBuf+i,"Function",8)==0&&(!IsVariableChar(pBuf[i+8]))){
518 i2=1;
519 break;
520 }
521
522 if(memicmp(pBuf+i,"Class",5)==0&&(!IsVariableChar(pBuf[i+5]))||
523 memicmp(pBuf+i,"Interface",9)==0&&(!IsVariableChar(pBuf[i+9]))||
524 memicmp(pBuf+i,"Type",4)==0&&(!IsVariableChar(pBuf[i+4]))){
525 i2=0;
526 break;
527 }
528 }
529
530 //次の行をサーチ
531 for(;;i++){
532 if(pBuf[i]=='\0') break;
533 i2=IsCommandDelimitation(pBuf,i);
534 if(i2){
535 i+=i2;
536 break;
537 }
538 }
539 JumpBlank(pBuf,&i);
540 }
541
542 if(i2==0){
543 //コード解析が不正に終了
544 return 1;
545 }
546
547 //次の行をサーチ
548 for(;;i++){
549 if(pBuf[i]=='\0') break;
550 i2=IsCommandDelimitation(pBuf,i);
551 if(i2){
552 i+=i2;
553 break;
554 }
555 }
556 JumpBlank(pBuf,&i);
557 }
558 }
559
560 return 0;
561}
562BOOL GetParameterString(char *pEditBuf,int iPos,char *FuncName,char *Parameter){
563 extern char *pHeaderBuf;
564 extern char *pUserSource;
565 BOOL bRet;
566
567 //ユーザーソースコードを取得
568 if(pUserSource==0)
569 pUserSource=GetUserSourceCode();
570
571
572 //クラス、配列の構成要素を解析する
573 char VarName[VN_SIZE]; //変数名
574 char array[VN_SIZE]; //第1次配列
575 char lpPtrOffset[VN_SIZE]; //第2次配列
576 char NestMember[VN_SIZE]; //入れ子メンバ
577 int RefType; //"."参照のときは0、"->"参照のときは1
578 lstrcpy(VarName,FuncName);
579 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)) return 0;
580
581 if(RefType==0){
582 // キャレット位置のコード領域を判定(クラス/ローカル/グローバル)
583 int iProcPos;
584 char NowClass[VN_SIZE];
585 GetCodeAreaType(pEditBuf,iPos,&iProcPos,NowClass);
586
587 if(NowClass[0]&&iProcPos!=-1){
588 //クラスメンバ関数領域
589 bRet=GetClassMemberFunctionParameter(pUserSource,NowClass,FuncName,Parameter);
590 if(!bRet){
591 bRet=GetClassMemberFunctionParameter(pHeaderBuf,NowClass,FuncName,Parameter);
592 }
593
594 if(bRet) return 1;
595 }
596
597 //通常関数
598 bRet=GetDefualtFunctionParameter(pUserSource,FuncName,Parameter);
599 if(!bRet){
600 bRet=GetDefualtFunctionParameter(pHeaderBuf,FuncName,Parameter);
601 }
602 }
603 else{
604 //メンバ関数
605 char ClassName[VN_SIZE];
606 BOOL bArray;
607
608 //オブジェクトのクラス名を取得
609 if(!GetVariableClassName(pEditBuf,iPos,VarName,ClassName,&bArray)) return 0;
610
611 //TypeDef宣言を考慮してオリジナルなクラス名を取得
612 GetOriginalClassName(ClassName);
613
614 if(!CheckReferType(ClassName,bArray,array,RefType)) return 0;
615
616 bRet=GetClassMemberFunctionParameter(pUserSource,ClassName,NestMember,Parameter);
617 if(!bRet){
618 bRet=GetClassMemberFunctionParameter(pHeaderBuf,ClassName,NestMember,Parameter);
619 }
620 }
621
622 DeleteComment(Parameter);
623
624 return bRet;
625}
626
627void ShowParameterHint(int WndNum){
628 extern HANDLE hHeap;
629 extern METHODCHECKINFO MethodCheckInfo;
630 int i,i2,i3,IsStr,IsComment,PareNum,iPos;
631 char *pBuf;
632 char temp2[8192];
633
634 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
635
636 //キャレットが示すバッファインデックスを取得
637 iPos=GetBufferIndexFromCaretPos(
638 pBuf,
639 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x,
640 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y);
641
642 static int Before_StartCaretY;
643 BOOL Before_StartCaretSwitch=0;
644 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y!=Before_StartCaretY){
645 Before_StartCaretY=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y;
646 Before_StartCaretSwitch=1;
647 }
648
649 if(!MethodCheckInfo.hWnd){
650 ////////////////////////////////////////////////
651 // 新規の場合は選択されている行の先頭位置を取得
652 ////////////////////////////////////////////////
653
654 for(i=iPos;i>0;i--){
655 if(pBuf[i-1]=='\r'&&pBuf[i]=='\n'){
656 i++;
657 break;
658 }
659 }
660 MethodCheckInfo.HeadPos=i;
661
662 //注釈中かどうかを判定
663 for(i2=0,IsStr=0,IsComment=0;i2<MethodCheckInfo.HeadPos;i2++){
664 if(pBuf[i2]=='\"'){
665 i3=i2;
666 IsStr^=1;
667 }
668
669 //注釈(複数行)
670 if(pBuf[i2]=='/'&&pBuf[i2+1]=='*'&&IsStr==0&&IsComment==0){
671 i2+=2;
672 while(!(pBuf[i2]=='*'&&pBuf[i2+1]=='/')){
673 if(pBuf[i2]=='\0'){
674 i2--;
675 break;
676 }
677 i2++;
678 if(i2>=MethodCheckInfo.HeadPos) break;
679 }
680 if(i2>=MethodCheckInfo.HeadPos){
681 IsComment=1;
682 break;
683 }
684 continue;
685 }
686
687 //注釈(単行)
688 if(pBuf[i2]=='\''&&IsStr==0){
689 while(!(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n')){
690 if(pBuf[i2]=='\0'){
691 i2--;
692 break;
693 }
694 i2++;
695 if(i2>=MethodCheckInfo.HeadPos) break;
696 }
697 if(i2>=MethodCheckInfo.HeadPos){
698 IsComment=1;
699 break;
700 }
701 continue;
702 }
703
704 if(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n'){
705 IsComment=0;
706 IsStr=0;
707 }
708 }
709
710 if(IsComment){
711 //注釈文の位置のときは抜け出す
712 return;
713 }
714 }
715 else{
716 /*既存のパラメータヒントが存在し、
717 以前の先頭位置よりも手前にカーソルが移動されたときは破棄する*/
718 if(iPos<=MethodCheckInfo.HeadPos){
719 DestroyWindow(MethodCheckInfo.hWnd);
720 MethodCheckInfo.hWnd=0;
721 }
722 }
723
724
725 ////////////////////////////////////////
726 // ダブルクォートの中かどうかを判別する
727 ////////////////////////////////////////
728
729 IsStr=0;
730 IsComment=0;
731 PareNum=0;
732 for(i2=MethodCheckInfo.HeadPos;i2<iPos;i2++){
733 if(pBuf[i2]=='\"'){
734 i3=i2;
735 IsStr^=1;
736 }
737
738 if(pBuf[i2]=='('&&IsStr==0&&IsComment==0) PareNum++;
739 if(pBuf[i2]==')'&&IsStr==0&&IsComment==0) PareNum--;
740
741 //注釈(複数行)
742 if(pBuf[i2]=='/'&&pBuf[i2+1]=='*'&&IsStr==0&&IsComment==0){
743 i2+=2;
744 while(!(pBuf[i2]=='*'&&pBuf[i2+1]=='/')){
745 if(pBuf[i2]=='\0'){
746 i2--;
747 break;
748 }
749 i2++;
750 if(i2>=iPos) break;
751 }
752 if(i2>=iPos){
753 IsComment=1;
754 break;
755 }
756 continue;
757 }
758
759 //注釈(単行)
760 if(pBuf[i2]=='\''&&IsStr==0){
761 while(!(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n')){
762 if(pBuf[i2]=='\0'){
763 i2--;
764 break;
765 }
766 i2++;
767 if(i2>=iPos) break;
768 }
769 if(i2>=iPos){
770 IsComment=1;
771 break;
772 }
773 continue;
774 }
775
776 if(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n'){
777 if(PareNum==0){
778 //複数行にパラメータ記述がなされないとき
779 DestroyWindow(MethodCheckInfo.hWnd);
780 MethodCheckInfo.hWnd=0;
781 return;
782 }
783 IsComment=0;
784 IsStr=0;
785 }
786
787 }
788 if(IsStr){
789 if(!MethodCheckInfo.hWnd){
790 return;
791 }
792 i=i3-1;
793 }
794 else i=iPos-1;
795
796
797 for(PareNum=0;i>=MethodCheckInfo.HeadPos;i--){
798 if(pBuf[i]=='\"'){
799 i--;
800 while(pBuf[i]!='\"'){
801 i--;
802 if(i<MethodCheckInfo.HeadPos) break;
803 }
804 if(i<MethodCheckInfo.HeadPos) break;
805 continue;
806 }
807
808 //文の第一パラメータ時に表示する(すでに表示されている場合は無関係)
809 if((!MethodCheckInfo.hWnd)&&pBuf[i]==',') break;
810
811 if(pBuf[i]==')') PareNum--;
812 if(pBuf[i]=='('){
813 PareNum++;
814 if(PareNum>0){
815 i3=i+1;
816 i--;
817 while(pBuf[i]==' '||pBuf[i]=='\t') i--;
818 for(i2=0;i>=0;i--,i2++){
819 if(!IsVariableChar(pBuf[i])){
820 if(pBuf[i-1]=='-'&&pBuf[i]=='>'){
821 // "->" を含ませる
822 i--;
823 i2++;
824 continue;
825 }
826 break;
827 }
828 }
829 i++;
830 memcpy(temp2,pBuf+i,i2);
831 temp2[i2]=0;
832 if(i3<=iPos){
833 for(i2=0,IsStr=0,PareNum=0;i3<iPos;i3++){
834 if(pBuf[i3]=='\"') IsStr^=1;
835 if(pBuf[i3]=='('&&IsStr==0) PareNum++;
836 if(pBuf[i3]==')'&&IsStr==0){
837 PareNum--;
838 if(PareNum<0) break;
839 }
840 if(pBuf[i3]==','&&IsStr==0&&PareNum==0) i2++;
841 }
842 if(PareNum<0) i2=0x7FFFFFFF;
843 }
844 else i2=0x7FFFFFFF;
845
846 if(temp2[0]==0){
847 PareNum=0;
848 iPos=i;
849 continue;
850 }
851
852 if(lstrcmp(MethodCheckInfo.BeforeMethodName,temp2)!=0){
853 //新規の場合はパラメータ文字列を取得
854 if(!GetParameterString(pBuf,iPos,temp2,MethodCheckInfo.msg)){
855 PareNum=0;
856 iPos=i;
857 continue;
858 }
859 }
860 else if(MethodCheckInfo.ParmNum==i2&&Before_StartCaretSwitch==0){
861 //表示中のパラメータヒントに変更がないとき
862 //※行移動が行われた場合を除く
863 break;
864 }
865
866 //第何パラメータを太字にするかを示す
867 MethodCheckInfo.ParmNum=i2;
868
869 //パラメータヒントを表示
870 ShowCommandMessage();
871
872 lstrcpy(MethodCheckInfo.BeforeMethodName,temp2);
873 break;
874 }
875 }
876 if(i==MethodCheckInfo.HeadPos){
877
878 //行番号を飛び越す
879 while(pBuf[i]>='0'&&pBuf[i]<='9') i++;
880
881 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
882 for(i2=0;;i++,i2++){
883 if(!IsVariableChar(pBuf[i])){
884 temp2[i2]=0;
885 break;
886 }
887 temp2[i2]=pBuf[i];
888 }
889 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
890 if(pBuf[i]=='(') i++;
891 if(i<=iPos){
892 for(i2=0,IsStr=0,PareNum=0;i<iPos;i++){
893 if(pBuf[i]=='\"') IsStr^=1;
894 if(pBuf[i]=='('&&IsStr==0) PareNum++;
895 if(pBuf[i]==')'&&IsStr==0){
896 PareNum--;
897 if(PareNum<0) break;
898 }
899 if(pBuf[i]==','&&IsStr==0&&PareNum==0) i2++;
900 }
901 if(PareNum<0) temp2[0]=0;
902 }
903 else i2=0x7FFFFFFF;
904 if(SetCommandMessageToMethodCheck(temp2)){
905 //第何パラメータを太字にするかを示す
906 MethodCheckInfo.ParmNum=i2;
907
908 //パラメータヒントを表示
909 ShowCommandMessage();
910
911 lstrcpy(MethodCheckInfo.BeforeMethodName,temp2);
912 }
913 else{
914 if(MethodCheckInfo.hWnd){
915 UpdateWindow(MdiInfo[WndNum]->pMdiTextEdit->hEdit); //ちらつき防止
916
917 DestroyWindow(MethodCheckInfo.hWnd);
918 MethodCheckInfo.hWnd=0;
919 }
920 }
921 break;
922 }
923 }
924
925 extern char *pUserSource;
926 if(pUserSource){
927 HeapDefaultFree(pUserSource);
928 pUserSource=0;
929 }
930}
931
932
933//////////////////////////////////////
934// パラメータヒントのインターフェイス
935//////////////////////////////////////
936
937int DrawParam_StartScreenPosX;
938int DrawParam_PosY;
939int DrawParam_TextHeight;
940int DrawParam_MaxX;
941void TextOut_ToParmHint(HDC hdc,HFONT hFont,char *buffer,SIZE *pSize){
942 int i,i2;
943 HFONT hOldFont;
944
945 i=lstrlen(buffer);
946 hOldFont=(HFONT)SelectObject(hdc,hFont);
947
948 i2=pSize->cx;
949 GetTextExtentPoint32(hdc,buffer,i,pSize);
950 if(DrawParam_StartScreenPosX+i2+pSize->cx >= ScreenX){
951 DrawParam_PosY+=DrawParam_TextHeight;
952 i2=10;
953 }
954 TextOut(hdc,i2,DrawParam_PosY,buffer,i);
955 pSize->cx+=i2;
956
957 if(DrawParam_MaxX<pSize->cx) DrawParam_MaxX=pSize->cx;
958
959 SelectObject(hdc,hOldFont);
960}
961void DrawParameterHint(HDC hdc,SIZE *pSize){
962 extern METHODCHECKINFO MethodCheckInfo;
963 int i,i2,i3,counter;
964 char temporary[8192];
965 HFONT hOldFont;
966
967 SetBkMode(hdc,TRANSPARENT);
968
969 DrawParam_PosY=2;
970
971 //命令語、関数の識別名
972 for(i=0;;i++){
973 temporary[i]=MethodCheckInfo.msg[i];
974 if(MethodCheckInfo.msg[i]=='\0') break;
975 if(MethodCheckInfo.msg[i]==' '||MethodCheckInfo.msg[i]=='('){
976 i++;
977 temporary[i]=0;
978 break;
979 }
980 }
981 hOldFont=(HFONT)SelectObject(hdc,MethodCheckInfo.hFont);
982 TextOut(hdc,2,2,temporary,lstrlen(temporary));
983 GetTextExtentPoint32(hdc,temporary,lstrlen(temporary),pSize);
984 SelectObject(hdc,hOldFont);
985 pSize->cx+=2;
986 DrawParam_TextHeight=pSize->cy;
987
988 DrawParam_MaxX=pSize->cx;
989
990 for(i2=0,counter=0;;i++,i2++){
991 if(MethodCheckInfo.msg[i]=='('){
992 i3=GetStringInPare(temporary+i2,MethodCheckInfo.msg+i);
993 i+=i3-1;
994 i2+=i3-1;
995 }
996 if(MethodCheckInfo.msg[i]==','||
997 MethodCheckInfo.msg[i]==')'||
998 MethodCheckInfo.msg[i]=='\0'){
999 temporary[i2]=0;
1000 if(MethodCheckInfo.ParmNum==counter){
1001 //太字フォントパラメータ
1002 TextOut_ToParmHint(hdc,MethodCheckInfo.hBoldFont,temporary,pSize);
1003 }
1004 else{
1005 //通常フォントパラメータ
1006 TextOut_ToParmHint(hdc,MethodCheckInfo.hFont,temporary,pSize);
1007 }
1008 counter++;
1009
1010 if(MethodCheckInfo.msg[i]==','){
1011 temporary[0]=',';
1012 temporary[1]=' ';
1013 temporary[2]=0;
1014
1015 TextOut_ToParmHint(hdc,MethodCheckInfo.hFont,temporary,pSize);
1016
1017 i++;
1018 while(MethodCheckInfo.msg[i]==' '||MethodCheckInfo.msg[i]=='\t') i++;
1019 i--;
1020 }
1021 else if(MethodCheckInfo.msg[i]==')'){
1022 lstrcpy(temporary,MethodCheckInfo.msg+i);
1023
1024 TextOut_ToParmHint(hdc,MethodCheckInfo.hFont,temporary,pSize);
1025
1026 break;
1027 }
1028 else if(MethodCheckInfo.msg[i]=='\0') break;
1029
1030 i2=-1;
1031 continue;
1032 }
1033 temporary[i2]=MethodCheckInfo.msg[i];
1034 }
1035
1036 pSize->cx=DrawParam_MaxX+20;
1037 pSize->cy=DrawParam_PosY+DrawParam_TextHeight+2;
1038}
1039void ShowHelp_FromParamHint(void){
1040 extern METHODCHECKINFO MethodCheckInfo;
1041 int i;
1042 char temporary[MAX_PATH],temp2[255];
1043 HH_AKLINK ak;
1044
1045 for(i=0;;i++){
1046 if(MethodCheckInfo.msg[i]=='('||MethodCheckInfo.msg[i]==' '||
1047 MethodCheckInfo.msg[i]=='\0'){
1048 temp2[i]=0;
1049 break;
1050 }
1051 temp2[i]=MethodCheckInfo.msg[i];
1052 }
1053
1054 memset(&ak, 0, sizeof(HH_AKLINK));
1055 ak.cbStruct = sizeof(HH_AKLINK);
1056 ak.pszKeywords = temp2;
1057 ak.fIndexOnFail=1;
1058
1059 sprintf(temporary,"%sBasicHelp.chm",pj_editor_Dir);
1060 HtmlHelp(NULL,temporary,HH_KEYWORD_LOOKUP,(DWORD)&ak);
1061}
1062LRESULT CALLBACK MethodCheckWindow(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
1063 extern METHODCHECKINFO MethodCheckInfo;
1064 HDC hdc;
1065 HPEN hOldPen;
1066 HBRUSH hBrush,hOldBrush;
1067 PAINTSTRUCT ps;
1068 SIZE size;
1069 RECT rect;
1070 POINT pos;
1071
1072 switch(message){
1073 case WM_CREATE:
1074 GetCaretPos(&pos);
1075 ClientToScreen(GetWindow(hClient,GW_CHILD),&pos);
1076 DrawParam_StartScreenPosX=pos.x;
1077
1078 SetTimer(hwnd,1,50,0);
1079 return 0;
1080 case WM_PAINT:
1081 hdc=BeginPaint(hwnd,&ps);
1082
1083 //枠を描画
1084 GetClientRect(hwnd,&rect);
1085 hBrush=CreateSolidBrush(RGB(255,255,180));
1086 hOldPen=(HPEN)SelectObject(hdc,GetStockObject(BLACK_PEN));
1087 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
1088 Rectangle(hdc,0,0,rect.right,rect.bottom);
1089 SelectObject(hdc,hOldPen);
1090 SelectObject(hdc,hOldBrush);
1091 DeleteObject(hBrush);
1092
1093 //パラメータヒントを描画
1094 DrawParameterHint(hdc,&size);
1095
1096 //[?]マークを描画
1097 HBITMAP hBmp,hOldBmp;
1098 HDC memdc;
1099 hBmp=(HBITMAP)LoadImage(hResInst,MAKEINTRESOURCE(IDB_PARAMHINT_QUESTION),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
1100 memdc=CreateCompatibleDC(hdc);
1101 hOldBmp=(HBITMAP)SelectObject(memdc,hBmp);
1102 GetClientRect(hwnd,&rect);
1103 BitBlt(hdc,rect.right-14,rect.bottom-14,13,13,memdc,0,0,SRCCOPY);
1104 SelectObject(memdc,hOldBmp);
1105 DeleteDC(memdc);
1106 DeleteObject(hBmp);
1107
1108 EndPaint(hwnd,&ps);
1109 return 0;
1110 case WM_TIMER:
1111 //[?]マークを描画
1112 static BOOL bOnMouse;
1113 GetClientRect(hwnd,&rect);
1114 GetCursorPos(&pos);
1115 ScreenToClient(hwnd,&pos);
1116 if(rect.right-14<=pos.x&&pos.x<=rect.right-1&&
1117 rect.bottom-14<=pos.y&&pos.y<=rect.bottom-1){
1118 if(bOnMouse) return 0;
1119
1120 hdc=GetDC(hwnd);
1121
1122 hBmp=(HBITMAP)LoadImage(hResInst,MAKEINTRESOURCE(IDB_PARAMHINT_QUESTION2),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
1123 memdc=CreateCompatibleDC(hdc);
1124 hOldBmp=(HBITMAP)SelectObject(memdc,hBmp);
1125 GetClientRect(hwnd,&rect);
1126 BitBlt(hdc,rect.right-14,rect.bottom-14,13,13,memdc,0,0,SRCCOPY);
1127 SelectObject(memdc,hOldBmp);
1128 DeleteDC(memdc);
1129 DeleteObject(hBmp);
1130
1131 ReleaseDC(hwnd,hdc);
1132
1133 bOnMouse=1;
1134 }
1135 else{
1136 if(!bOnMouse) return 0;
1137
1138 hdc=GetDC(hwnd);
1139
1140 hBmp=(HBITMAP)LoadImage(hResInst,MAKEINTRESOURCE(IDB_PARAMHINT_QUESTION),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
1141 memdc=CreateCompatibleDC(hdc);
1142 hOldBmp=(HBITMAP)SelectObject(memdc,hBmp);
1143 GetClientRect(hwnd,&rect);
1144 BitBlt(hdc,rect.right-14,rect.bottom-14,13,13,memdc,0,0,SRCCOPY);
1145 SelectObject(memdc,hOldBmp);
1146 DeleteDC(memdc);
1147 DeleteObject(hBmp);
1148
1149 ReleaseDC(hwnd,hdc);
1150 bOnMouse=0;
1151 }
1152 return 0;
1153 case WM_ACTIVATE:
1154 if(LOWORD(wParam)==WA_ACTIVE||LOWORD(wParam)==WA_CLICKACTIVE){
1155 SetFocus(GetWindow(hClient,GW_CHILD));
1156
1157 if(LOWORD(wParam)==WA_CLICKACTIVE){
1158 GetClientRect(hwnd,&rect);
1159 GetCursorPos(&pos);
1160 ScreenToClient(hwnd,&pos);
1161 if(rect.right-14<=pos.x&&pos.x<=rect.right-1&&
1162 rect.bottom-14<=pos.y&&pos.y<=rect.bottom-1){
1163 ShowHelp_FromParamHint();
1164 }
1165 }
1166 }
1167 return 0;
1168 case WM_DESTROY:
1169 MethodCheckInfo.BeforeMethodName[0]=0;
1170 return 0;
1171 }
1172 return DefWindowProc(hwnd,message,wParam,lParam);
1173}
1174void ShowCommandMessage(void){
1175 extern METHODCHECKINFO MethodCheckInfo;
1176 int i;
1177 int sw;
1178
1179 if(pobj_nv->dwParameterHint==1){
1180 //ポップアップ表示
1181
1182 extern HINSTANCE hInst;
1183 extern METHODCHECKINFO MethodCheckInfo;
1184 HDC hdc,memdc;
1185 RECT rect,rc2;
1186 SIZE size;
1187 POINT pos;
1188 if(!MethodCheckInfo.hWnd){
1189 MethodCheckInfo.hWnd=CreateWindow("MethodCheckWindow",NULL,WS_POPUP,
1190 0,0,0,0,
1191 hOwner,NULL,hInst,0);
1192 sw=1;
1193 }
1194 else sw=0;
1195 i=GetWndNum(GetWindow(hClient,GW_CHILD));
1196
1197 hdc=GetDC(MethodCheckInfo.hWnd);
1198 memdc=CreateCompatibleDC(hdc);
1199 DrawParameterHint(memdc,&size);
1200 DeleteDC(memdc);
1201 ReleaseDC(MethodCheckInfo.hWnd,hdc);
1202
1203 GetWindowRect(MdiInfo[i]->hwnd,&rect);
1204 GetCaretPos(&pos);
1205 ClientToScreen(MdiInfo[i]->pMdiTextEdit->hEdit,&pos);
1206 rect.left=pos.x-20;
1207 rect.top=pos.y-pobj_nv->lf.lfHeight;
1208 if(sw){
1209 MoveWindow(MethodCheckInfo.hWnd,rect.left,rect.top,size.cx,size.cy,1);
1210 ShowWindow(MethodCheckInfo.hWnd,SW_SHOWNOACTIVATE);
1211 }
1212 else{
1213 GetWindowRect(MethodCheckInfo.hWnd,&rc2);
1214
1215 MoveWindow(MethodCheckInfo.hWnd,
1216 rc2.left,
1217 rect.top,
1218 size.cx,
1219 size.cy,
1220 1);
1221
1222 InvalidateRect(MethodCheckInfo.hWnd,NULL,0);
1223 }
1224 }
1225
1226 //ステータスバーに表示
1227 else if(pobj_nv->dwParameterHint==2)
1228 SetStatusText(MethodCheckInfo.msg);
1229}
Note: See TracBrowser for help on using the repository browser.