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

Last change on this file since 655 was 655, checked in by dai_9181, 15 years ago

FileManager周りをリファクタリング

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