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

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

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

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