#include "stdafx.h" #include "common.h" void ShowCommandMessage(void); BOOL CheckGrammar(char *buffer){ int i,IsStr,PareNum; for(i=0,IsStr=0,PareNum=0;;i++){ if(buffer[i]=='\"') IsStr^=1; else if(buffer[i]=='(') PareNum++; else if(buffer[i]==')') PareNum--; else if(buffer[i]=='\0'||(buffer[i]=='\r'&&buffer[i+1]=='\n')){ if(IsStr||PareNum) return 0; if(buffer[i]=='\0') break; i++; continue; } else if(buffer[i]=='\''&&IsStr==0){ while(!(buffer[i]=='\0'||(buffer[i]=='\r'&&buffer[i+1]=='\n'))) i++; i--; continue; } } return 1; } char *GetUserSourceCode(void){ //単体ファイルのときはそのファイルを、プロジェクトのときはpjname.abの内容を取得 extern HANDLE hHeap; int i; char temporary[MAX_PATH],*pBuf; if( projectInfo.IsOpened() ){ //プロジェクトが開かれているとき lstrcpy(temporary,projectInfo.fileSystem.root.files[0].GetFullPath().c_str()); for(i=0;ihwnd){ if(lstrcmpi(MdiInfo[i]->path.c_str(),temporary)==0) break; } } if(i==MdiInfo.size()){ //ファイルから開く pBuf=ReadBuffer(temporary); } else{ //エディタから読み込む pBuf=(char *)HeapAlloc(hHeap,0,lstrlen(MdiInfo[i]->pMdiTextEdit->buffer)+1); lstrcpy(pBuf,MdiInfo[i]->pMdiTextEdit->buffer); } } else{ //単体ソースコードのとき int WndNum; WndNum=GetWndNum(GetWindow(hClient,GW_CHILD)); pBuf=(char *)HeapAlloc(hHeap,0,lstrlen(MdiInfo[WndNum]->pMdiTextEdit->buffer)+1); lstrcpy(pBuf,MdiInfo[WndNum]->pMdiTextEdit->buffer); } //ファイルをインクルード pBuf=IncludeFiles(pBuf); return pBuf; } BOOL SetCommandMessageToMethodCheck(char *Command){ extern METHODCHECKINFO MethodCheckInfo; int CmdValue; CmdValue=IsBasicReservedWord(Command); if(CmdValue==COM_ABSTRACT) lstrcpy(MethodCheckInfo.msg,"Abstract Sub/Function ([arglist]) [As type]]"); else if(CmdValue==COM_BEEP) lstrcpy(MethodCheckInfo.msg,"Beep"); else if(CmdValue==COM_CHDIR) lstrcpy(MethodCheckInfo.msg,"ChDir directory$"); else if(CmdValue==COM_CIRCLE) lstrcpy(MethodCheckInfo.msg,"Circle (x, y), radius, [color], [start], [end], [aspect], [f], [brushcolor]"); else if(CmdValue==COM_CLOSE) lstrcpy(MethodCheckInfo.msg,"Close [filenumber]"); else if(CmdValue==COM_CLASS) lstrcpy(MethodCheckInfo.msg,"Class name"); else if(CmdValue==COM_CLS) lstrcpy(MethodCheckInfo.msg,"Cls [number]"); else if(CmdValue==COM_COLOR) lstrcpy(MethodCheckInfo.msg,"Color color, [backcolor]"); else if(CmdValue==COM_CONST) lstrcpy(MethodCheckInfo.msg,"Const constname = expression"); else if(CmdValue==COM_DEBUG) lstrcpy(MethodCheckInfo.msg,"Debug"); else if(CmdValue==COM_DECLARE) lstrcpy(MethodCheckInfo.msg,"Declare Sub/Function name Lib \"libname\" [Alias \"aliasname\"] ([arglist]) [As type]]"); else if(CmdValue==COM_DEF) lstrcpy(MethodCheckInfo.msg,"Def func([parms] [,parms2])=expression"); else if(CmdValue==COM_DIM) lstrcpy(MethodCheckInfo.msg,"Dim variable [(subscripts)] As type, ..."); else if(CmdValue==COM_END) lstrcpy(MethodCheckInfo.msg,"End [type]"); else if(CmdValue==COM_ENUM) lstrcpy(MethodCheckInfo.msg,"Enum name"); else if(CmdValue==COM_FIELD) lstrcpy(MethodCheckInfo.msg,"Field #filenumber, fieldbyte"); else if(CmdValue==COM_FOR) lstrcpy(MethodCheckInfo.msg,"For variable=start To end [Step step]"); else if(CmdValue==COM_FUNCTION) lstrcpy(MethodCheckInfo.msg,"Function name ([arglist]) [As type]"); else if(CmdValue==COM_GET) lstrcpy(MethodCheckInfo.msg,"Get #filenumber, recode, StrBuffer"); else if(CmdValue==COM_GOSUB) lstrcpy(MethodCheckInfo.msg,"GoSub label"); else if(CmdValue==COM_GOTO) lstrcpy(MethodCheckInfo.msg,"Goto label"); else if(CmdValue==COM_IF) lstrcpy(MethodCheckInfo.msg,"If judgment Then truecommand [Else falsecommand]"); else if(CmdValue==COM_INHERITS) lstrcpy(MethodCheckInfo.msg,"Inherits BaseClass"); else if(CmdValue==COM_INPUT) lstrcpy(MethodCheckInfo.msg,"Input [# filenumber, ] variable, [...]"); else if(CmdValue==COM_INTERFACE) lstrcpy(MethodCheckInfo.msg,"Interface name"); else if(CmdValue==COM_KILL) lstrcpy(MethodCheckInfo.msg,"Kill filename$"); else if(CmdValue==COM_LET) lstrcpy(MethodCheckInfo.msg,"[Let] variable = expression"); else if(CmdValue==COM_LINE) lstrcpy(MethodCheckInfo.msg,"Line [(sx, sy)] -[Step] (ex, ey), [color], [B/Bf], [color2]"); else if(CmdValue==COM_LOCATE) lstrcpy(MethodCheckInfo.msg,"Locate x, y"); else if(CmdValue==COM_LOOP) lstrcpy(MethodCheckInfo.msg,"Loop while/until judgment"); else if(CmdValue==COM_MKDIR) lstrcpy(MethodCheckInfo.msg,"MkDir directory$"); else if(CmdValue==COM_MSGBOX) lstrcpy(MethodCheckInfo.msg,"MsgBox hWnd, String$, [Title$], [BoxType], [retAns]"); else if(CmdValue==COM_NAMESPACE) lstrcpy(MethodCheckInfo.msg,"Namespace namespaceStr"); else if(CmdValue==COM_NEXT) lstrcpy(MethodCheckInfo.msg,"Next"); else if(CmdValue==COM_OPEN) lstrcpy(MethodCheckInfo.msg,"Open filename$ [For Input/Output/Append] As number"); else if(CmdValue==COM_PAINT) lstrcpy(MethodCheckInfo.msg,"Paint (x, y), brushcolor, [linecolor]"); else if(CmdValue==COM_PRINT) lstrcpy(MethodCheckInfo.msg,"Print outdata, [...]"); else if(CmdValue==COM_PRIVATE) lstrcpy(MethodCheckInfo.msg,"Private"); else if(CmdValue==COM_PROTECTED) lstrcpy(MethodCheckInfo.msg,"Protected"); else if(CmdValue==COM_PSET) lstrcpy(MethodCheckInfo.msg,"PSet (x, y), [color]"); else if(CmdValue==COM_PUBLIC) lstrcpy(MethodCheckInfo.msg,"Public"); else if(CmdValue==COM_PUT) lstrcpy(MethodCheckInfo.msg,"Put #filenumber, recode, StrBuffer"); else if(CmdValue==COM_RANDOMIZE) lstrcpy(MethodCheckInfo.msg,"Randomize [number]"); else if(CmdValue==COM_REM) lstrcpy(MethodCheckInfo.msg,"Rem [comment]"); else if(CmdValue==COM_RETURN) lstrcpy(MethodCheckInfo.msg,"Return"); else if(CmdValue==COM_SELECT) lstrcpy(MethodCheckInfo.msg,"Select Case testexpression"); else if(CmdValue==COM_SUB) lstrcpy(MethodCheckInfo.msg,"Sub name ([arglist])"); else if(CmdValue==COM_TYPE) lstrcpy(MethodCheckInfo.msg,"Type name"); else if(CmdValue==COM_TYPEDEF) lstrcpy(MethodCheckInfo.msg,"TypeDef newtype = basetype"); else if(CmdValue==COM_VIRTUAL) lstrcpy(MethodCheckInfo.msg,"Virtual Sub/Function ([arglist]) [As type]]"); else if(CmdValue==COM_OVERRIDE) lstrcpy(MethodCheckInfo.msg,"Override Sub/Function ([arglist]) [As type]]"); else if(CmdValue==COM_WEND) lstrcpy(MethodCheckInfo.msg,"Wend"); else if(CmdValue==COM_WHILE) lstrcpy(MethodCheckInfo.msg,"While judgment"); else if(CmdValue==COM_WINDOW) lstrcpy(MethodCheckInfo.msg,"Window hWnd, OwnerWnd, x, y, width, height, title$, style, [class$], [ID], [callbackfunction], [ExStyle]"); else if(CmdValue==COM_WITH) lstrcpy(MethodCheckInfo.msg,"With object"); else if(CmdValue==COM_WRITE) lstrcpy(MethodCheckInfo.msg,"Write [data, ...]"); else return 0; return 1; } void ChangeReturnCode(char *buffer){ //改行コードのCRLFをLFに変換 int i,i2; for(i=0,i2=0;;i++,i2++){ if(buffer[i]=='\r'&&buffer[i+1]=='\n') i++; buffer[i2]=buffer[i]; if(buffer[i]=='\0') break; } } void DeleteComment(char *buffer){ //注釈「'」の取り除き int i,i2,i3,IsStr; char *temporary; temporary=(char *)GlobalAlloc(GMEM_FIXED,lstrlen(buffer)+1); for(i=0,i2=0,i3=0,IsStr=0;;i++,i2++){ if(buffer[i]=='\"') IsStr^=1; if(buffer[i]=='\n'||buffer[i]=='\0'){ i2--; while(temporary[i2]==' '||temporary[i2]=='\t') i2--; i2++; if(i3){ //複数行に渡る注釈文の中に改行が存在するとき memset(temporary+i2,'\n',i3); i2+=i3; i3=0; } } if(buffer[i]=='\''&&IsStr==0){ //注釈文 i2--; while(temporary[i2]==' '||temporary[i2]=='\t') i2--; i2++; while(buffer[i]!='\n'&&buffer[i]!='\0') i++; } if(buffer[i]=='/'&&buffer[i+1]=='*'&&IsStr==0){ //注釈文(複数行) i+=2; i3=0; while(!(buffer[i]=='*'&&buffer[i+1]=='/')){ if(buffer[i]=='\n') i3++; if(buffer[i]=='\0') break; i++; } if(buffer[i]){ i+=2; } i--; i2--; continue; } temporary[i2]=buffer[i]; if(buffer[i]=='\0') break; } lstrcpy(buffer,temporary); GlobalFree(temporary); } BOOL GetDefualtFunctionParameter(char *pBuf,char *FuncName,char *Parameter){ int i,i2; char temporary[VN_SIZE]; ///////////////////////////////////////// // ソースコードから関数定義位置を取得 ///////////////////////////////////////// for(i=0;;i++){ while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Class",5)==0&&(pBuf[i+5]==' '||pBuf[i+5]=='\t')|| memicmp(pBuf+i,"Interface",9)==0&&(pBuf[i+9]==' '||pBuf[i+9]=='\t')|| memicmp(pBuf+i,"Type",4)==0&&(pBuf[i+4]==' '||pBuf[i+4]=='\t')){ /* Class 〜 End Class Interface 〜 End Interface Type 〜 End Type は飛び越す */ while(1){ if(pBuf[i]=='\0'){ i2=0; break; } if(memicmp(pBuf+i,"End",3)==0){ /* End Class End Interface End Type の検出 */ i+=3; while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Class",5)==0&&(!IsVariableChar(pBuf[i+5]))|| memicmp(pBuf+i,"Interface",9)==0&&(!IsVariableChar(pBuf[i+9]))|| memicmp(pBuf+i,"Type",4)==0&&(!IsVariableChar(pBuf[i+4]))){ i2=0; break; } } //次の行をサーチ for(;;i++){ if(pBuf[i]=='\0') break; i2=IsCommandDelimitation(pBuf,i); if(i2){ i+=i2; break; } } JumpBlank(pBuf,&i); } } if(memicmp(pBuf+i,"Declare",7)==0&&(pBuf[i+7]==' '||pBuf[i+7]=='\t')){ i+=8; while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9; else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4; else goto NextCommand; while(pBuf[i]==' '||pBuf[i]=='\t') i++; for(i2=0;;i++,i2++){ if(!IsVariableChar(pBuf[i])){ temporary[i2]=0; break; } temporary[i2]=pBuf[i]; } if(lstrcmp(temporary,FuncName)==0){ //関数名が一致したとき break; } } if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')|| memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){ if(pBuf[i]=='f'||pBuf[i]=='F') i+=9; else i+=4; while(pBuf[i]==' '||pBuf[i]=='\t') i++; for(i2=0;;i++,i2++){ if(!IsVariableChar(pBuf[i])){ temporary[i2]=0; break; } temporary[i2]=pBuf[i]; } if(lstrcmpi(temporary,"Export")==0){ //"Export"を飛び越す while(pBuf[i]==' '||pBuf[i]=='\t') i++; for(i2=0;;i++,i2++){ if(!IsVariableChar(pBuf[i])){ temporary[i2]=0; break; } temporary[i2]=pBuf[i]; } } if(lstrcmp(temporary,FuncName)==0){ //関数名が一致したとき break; } } NextCommand: for(;;i++){ i2=IsCommandDelimitation(pBuf,i); if(i2){ if(i2==2) i++; break; } } if(pBuf[i]=='\0') return 0; } for(;;i++){ if(pBuf[i]=='(') break; if(IsCommandDelimitation(pBuf,i)) return 0; } //関数名をコピー lstrcpy(Parameter,FuncName); i2=lstrlen(Parameter); ////////////////////////////////////////////////////// //パラメータをコピー //(コメントの挿入、途中改行などの状況を考慮する) ////////////////////////////////////////////////////// for(;;i++,i2++){ if(IsVariableChar(pBuf[i-1])==0&&pBuf[i-1]!=')'&&IS_BLANK(pBuf[i])|| pBuf[i]=='\''|| pBuf[i]=='/'&&pBuf[i+1]=='*') JumpBlank(pBuf,&i); if(IsCommandDelimitation(pBuf,i)){ if(IS_RETURN(pBuf,i)&& pBuf[i-1]=='_'||pBuf[i-1]=='('||pBuf[i-1]==','){ //改行を許可 i2--; if(Parameter[i2]=='_') i2--; i+=2; continue; } Parameter[i2]=0; break; } Parameter[i2]=pBuf[i]; } //文法チェック if(!CheckGrammar(Parameter)) return 0; return 1; } BOOL GetClassMemberFunctionParameter(char *pBuf,char *ClassName,char *nest,char *Parameter){ extern HANDLE hHeap; extern char *pHeaderBuf; extern char *pUserSource; int i,i2; char temporary[8192]; DWORD dwClassType; BOOL bRet; ///////////////////////////////////////// // ソースコードからクラス定義位置を取得 ///////////////////////////////////////// i=GetClassPos(pBuf,ClassName,&dwClassType); if(pBuf[i]=='\0') return 0; //クラス、配列の構成要素を解析する char VarName[VN_SIZE]; //変数名 char array[VN_SIZE]; //第1次配列 char lpPtrOffset[VN_SIZE]; //第2次配列 char NestMember[VN_SIZE]; //入れ子メンバ int RefType; //"."参照のときは0、"->"参照のときは1 lstrcpy(VarName,nest); if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)) return 0; if(RefType){ //////////////////// // 入れ子構造の場合 //////////////////// //メンバ変数の型であるクラスの名前を取得 char ClassName[VN_SIZE]; BOOL bArray; if(!GetClassNameFromClassMember(pBuf,i,VarName,ClassName,&bArray)) return 0; //TypeDef宣言を考慮してオリジナルなクラス名を取得 GetOriginalClassName(ClassName); if(!CheckReferType(ClassName,bArray,array,RefType)) return 0; //ユーザーのソースコードをサーチ bRet=GetClassMemberFunctionParameter(pUserSource,ClassName,NestMember,Parameter); if(!bRet){ //失敗したときはbasic.sbpをサーチ bRet=GetClassMemberFunctionParameter(pHeaderBuf,ClassName,NestMember,Parameter); } return bRet; } //////////////////////// // メンバ情報を取得 //////////////////////// DWORD dwProc; if(memicmp(pBuf+i,"Inherits",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){ i+=9; while(pBuf[i]==' '||pBuf[i]=='\t') i++; //////////////////////// // 継承先クラスをサーチ //////////////////////// for(i2=0;;i++,i2++){ if(!IsVariableChar(pBuf[i])){ temporary[i2]=0; break; } temporary[i2]=pBuf[i]; } //ユーザーのソースコードをサーチ bRet=GetClassMemberFunctionParameter(pUserSource,temporary,nest,Parameter); if(!bRet){ //失敗したときはbasic.sbpをサーチ bRet=GetClassMemberFunctionParameter(pHeaderBuf,temporary,nest,Parameter); } if(bRet) return 1; } //メンバ変数、関数を取得 while(1){ if(pBuf[i]=='\0') break; if(memicmp(pBuf+i,"End",3)==0){ /* End Class End Interface End Type の検出 */ i2=i+3; while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++; if(memicmp(pBuf+i2,"Class",5)==0&&(!IsVariableChar(pBuf[i2+5]))|| memicmp(pBuf+i2,"Interface",9)==0&&(!IsVariableChar(pBuf[i2+9]))|| memicmp(pBuf+i2,"Type",4)==0&&(!IsVariableChar(pBuf[i2+4]))) break; } if(memicmp(pBuf+i,"Abstract",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')|| memicmp(pBuf+i,"Virtual",7)==0&&(pBuf[i+7]==' '||pBuf[i+7]=='\t')|| memicmp(pBuf+i,"Override",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')|| memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')|| memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){ //メンバ関数のとき if(pBuf[i]=='a'||pBuf[i]=='A'){ i+=9; dwProc=ESC_ABSTRACT; while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9; else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4; } else if(pBuf[i]=='v'||pBuf[i]=='V'){ i+=8; while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){ i+=9; dwProc=ESC_FUNCTION; } else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){ i+=4; dwProc=ESC_SUB; } } else if(pBuf[i]=='o'||pBuf[i]=='O'){ i+=9; while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){ i+=9; dwProc=ESC_FUNCTION; } else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){ i+=4; dwProc=ESC_SUB; } } else if(pBuf[i]=='f'||pBuf[i]=='F'){ i+=9; dwProc=ESC_FUNCTION; } else if(pBuf[i]=='s'||pBuf[i]=='S'){ i+=4; dwProc=ESC_SUB; } while(pBuf[i]==' '||pBuf[i]=='\t') i++; } else{ //メンバ変数のとき dwProc=0; } if(dwProc){ //変数名または関数名を取得 for(i2=0;;i++,i2++){ if(!IsVariableChar(pBuf[i])){ temporary[i2]=0; break; } temporary[i2]=pBuf[i]; } if(lstrcmp(temporary,nest)==0){ //ターゲットとなるメンバ関数が見つかったとき for(;;i++){ if(pBuf[i]=='(') break; if(IsCommandDelimitation(pBuf,i)) return 0; } lstrcpy(Parameter,nest); i2=lstrlen(Parameter); for(;;i++,i2++){ if(IsCommandDelimitation(pBuf,i)){ Parameter[i2]=0; break; } Parameter[i2]=pBuf[i]; } if(!CheckGrammar(Parameter)) return 0; return 1; } } //次の行をサーチ for(;;i++){ if(pBuf[i]=='\0') break; i2=IsCommandDelimitation(pBuf,i); if(i2){ i+=i2; break; } } JumpBlank(pBuf,&i); if((dwProc==ESC_SUB||dwProc==ESC_FUNCTION)&&dwClassType!=ESC_INTERFACE){ //End Sub、End Functionまでジャンプする while(1){ if(pBuf[i]=='\0'){ i2=0; break; } if(memicmp(pBuf+i,"End",3)==0){ /* End Sub End Function の検出 */ i+=3; while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(memicmp(pBuf+i,"Sub",3)==0&&(!IsVariableChar(pBuf[i+3]))|| memicmp(pBuf+i,"Function",8)==0&&(!IsVariableChar(pBuf[i+8]))){ i2=1; break; } if(memicmp(pBuf+i,"Class",5)==0&&(!IsVariableChar(pBuf[i+5]))|| memicmp(pBuf+i,"Interface",9)==0&&(!IsVariableChar(pBuf[i+9]))|| memicmp(pBuf+i,"Type",4)==0&&(!IsVariableChar(pBuf[i+4]))){ i2=0; break; } } //次の行をサーチ for(;;i++){ if(pBuf[i]=='\0') break; i2=IsCommandDelimitation(pBuf,i); if(i2){ i+=i2; break; } } JumpBlank(pBuf,&i); } if(i2==0){ //コード解析が不正に終了 return 1; } //次の行をサーチ for(;;i++){ if(pBuf[i]=='\0') break; i2=IsCommandDelimitation(pBuf,i); if(i2){ i+=i2; break; } } JumpBlank(pBuf,&i); } } return 0; } BOOL GetParameterString(char *pEditBuf,int iPos,char *FuncName,char *Parameter){ extern char *pHeaderBuf; extern char *pUserSource; BOOL bRet; //ユーザーソースコードを取得 if(pUserSource==0) pUserSource=GetUserSourceCode(); //クラス、配列の構成要素を解析する char VarName[VN_SIZE]; //変数名 char array[VN_SIZE]; //第1次配列 char lpPtrOffset[VN_SIZE]; //第2次配列 char NestMember[VN_SIZE]; //入れ子メンバ int RefType; //"."参照のときは0、"->"参照のときは1 lstrcpy(VarName,FuncName); if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)) return 0; if(RefType==0){ // キャレット位置のコード領域を判定(クラス/ローカル/グローバル) int iProcPos; char NowClass[VN_SIZE]; GetCodeAreaType(pEditBuf,iPos,&iProcPos,NowClass); if(NowClass[0]&&iProcPos!=-1){ //クラスメンバ関数領域 bRet=GetClassMemberFunctionParameter(pUserSource,NowClass,FuncName,Parameter); if(!bRet){ bRet=GetClassMemberFunctionParameter(pHeaderBuf,NowClass,FuncName,Parameter); } if(bRet) return 1; } //通常関数 bRet=GetDefualtFunctionParameter(pUserSource,FuncName,Parameter); if(!bRet){ bRet=GetDefualtFunctionParameter(pHeaderBuf,FuncName,Parameter); } } else{ //メンバ関数 char ClassName[VN_SIZE]; BOOL bArray; //オブジェクトのクラス名を取得 if(!GetVariableClassName(pEditBuf,iPos,VarName,ClassName,&bArray)) return 0; //TypeDef宣言を考慮してオリジナルなクラス名を取得 GetOriginalClassName(ClassName); if(!CheckReferType(ClassName,bArray,array,RefType)) return 0; bRet=GetClassMemberFunctionParameter(pUserSource,ClassName,NestMember,Parameter); if(!bRet){ bRet=GetClassMemberFunctionParameter(pHeaderBuf,ClassName,NestMember,Parameter); } } DeleteComment(Parameter); return bRet; } void ShowParameterHint(int WndNum){ extern HANDLE hHeap; extern METHODCHECKINFO MethodCheckInfo; int i,i2,i3,IsStr,IsComment,PareNum,iPos; char *pBuf; char temp2[8192]; pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer; //キャレットが示すバッファインデックスを取得 iPos=GetBufferIndexFromCaretPos( pBuf, MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x, MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y); static int Before_StartCaretY; BOOL Before_StartCaretSwitch=0; if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y!=Before_StartCaretY){ Before_StartCaretY=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y; Before_StartCaretSwitch=1; } if(!MethodCheckInfo.hWnd){ //////////////////////////////////////////////// // 新規の場合は選択されている行の先頭位置を取得 //////////////////////////////////////////////// for(i=iPos;i>0;i--){ if(pBuf[i-1]=='\r'&&pBuf[i]=='\n'){ i++; break; } } MethodCheckInfo.HeadPos=i; //注釈中かどうかを判定 for(i2=0,IsStr=0,IsComment=0;i2=MethodCheckInfo.HeadPos) break; } if(i2>=MethodCheckInfo.HeadPos){ IsComment=1; break; } continue; } //注釈(単行) if(pBuf[i2]=='\''&&IsStr==0){ while(!(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n')){ if(pBuf[i2]=='\0'){ i2--; break; } i2++; if(i2>=MethodCheckInfo.HeadPos) break; } if(i2>=MethodCheckInfo.HeadPos){ IsComment=1; break; } continue; } if(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n'){ IsComment=0; IsStr=0; } } if(IsComment){ //注釈文の位置のときは抜け出す return; } } else{ /*既存のパラメータヒントが存在し、 以前の先頭位置よりも手前にカーソルが移動されたときは破棄する*/ if(iPos<=MethodCheckInfo.HeadPos){ DestroyWindow(MethodCheckInfo.hWnd); MethodCheckInfo.hWnd=0; } } //////////////////////////////////////// // ダブルクォートの中かどうかを判別する //////////////////////////////////////// IsStr=0; IsComment=0; PareNum=0; for(i2=MethodCheckInfo.HeadPos;i2=iPos) break; } if(i2>=iPos){ IsComment=1; break; } continue; } //注釈(単行) if(pBuf[i2]=='\''&&IsStr==0){ while(!(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n')){ if(pBuf[i2]=='\0'){ i2--; break; } i2++; if(i2>=iPos) break; } if(i2>=iPos){ IsComment=1; break; } continue; } if(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n'){ if(PareNum==0){ //複数行にパラメータ記述がなされないとき DestroyWindow(MethodCheckInfo.hWnd); MethodCheckInfo.hWnd=0; return; } IsComment=0; IsStr=0; } } if(IsStr){ if(!MethodCheckInfo.hWnd){ return; } i=i3-1; } else i=iPos-1; for(PareNum=0;i>=MethodCheckInfo.HeadPos;i--){ if(pBuf[i]=='\"'){ i--; while(pBuf[i]!='\"'){ i--; if(i0){ i3=i+1; i--; while(pBuf[i]==' '||pBuf[i]=='\t') i--; for(i2=0;i>=0;i--,i2++){ if(!IsVariableChar(pBuf[i])){ if(pBuf[i-1]=='-'&&pBuf[i]=='>'){ // "->" を含ませる i--; i2++; continue; } break; } } i++; memcpy(temp2,pBuf+i,i2); temp2[i2]=0; if(i3<=iPos){ for(i2=0,IsStr=0,PareNum=0;i3='0'&&pBuf[i]<='9') i++; while(pBuf[i]==' '||pBuf[i]=='\t') i++; for(i2=0;;i++,i2++){ if(!IsVariableChar(pBuf[i])){ temp2[i2]=0; break; } temp2[i2]=pBuf[i]; } while(pBuf[i]==' '||pBuf[i]=='\t') i++; if(pBuf[i]=='(') i++; if(i<=iPos){ for(i2=0,IsStr=0,PareNum=0;ipMdiTextEdit->hEdit); //ちらつき防止 DestroyWindow(MethodCheckInfo.hWnd); MethodCheckInfo.hWnd=0; } } break; } } extern char *pUserSource; if(pUserSource){ HeapDefaultFree(pUserSource); pUserSource=0; } } ////////////////////////////////////// // パラメータヒントのインターフェイス ////////////////////////////////////// int DrawParam_StartScreenPosX; int DrawParam_PosY; int DrawParam_TextHeight; int DrawParam_MaxX; void TextOut_ToParmHint(HDC hdc,HFONT hFont,char *buffer,SIZE *pSize){ int i,i2; HFONT hOldFont; i=lstrlen(buffer); hOldFont=(HFONT)SelectObject(hdc,hFont); i2=pSize->cx; GetTextExtentPoint32(hdc,buffer,i,pSize); if(DrawParam_StartScreenPosX+i2+pSize->cx >= ScreenX){ DrawParam_PosY+=DrawParam_TextHeight; i2=10; } TextOut(hdc,i2,DrawParam_PosY,buffer,i); pSize->cx+=i2; if(DrawParam_MaxXcx) DrawParam_MaxX=pSize->cx; SelectObject(hdc,hOldFont); } void DrawParameterHint(HDC hdc,SIZE *pSize){ extern METHODCHECKINFO MethodCheckInfo; int i,i2,i3,counter; char temporary[8192]; HFONT hOldFont; SetBkMode(hdc,TRANSPARENT); DrawParam_PosY=2; //命令語、関数の識別名 for(i=0;;i++){ temporary[i]=MethodCheckInfo.msg[i]; if(MethodCheckInfo.msg[i]=='\0') break; if(MethodCheckInfo.msg[i]==' '||MethodCheckInfo.msg[i]=='('){ i++; temporary[i]=0; break; } } hOldFont=(HFONT)SelectObject(hdc,MethodCheckInfo.hFont); TextOut(hdc,2,2,temporary,lstrlen(temporary)); GetTextExtentPoint32(hdc,temporary,lstrlen(temporary),pSize); SelectObject(hdc,hOldFont); pSize->cx+=2; DrawParam_TextHeight=pSize->cy; DrawParam_MaxX=pSize->cx; for(i2=0,counter=0;;i++,i2++){ if(MethodCheckInfo.msg[i]=='('){ i3=GetStringInPare(temporary+i2,MethodCheckInfo.msg+i); i+=i3-1; i2+=i3-1; } if(MethodCheckInfo.msg[i]==','|| MethodCheckInfo.msg[i]==')'|| MethodCheckInfo.msg[i]=='\0'){ temporary[i2]=0; if(MethodCheckInfo.ParmNum==counter){ //太字フォントパラメータ TextOut_ToParmHint(hdc,MethodCheckInfo.hBoldFont,temporary,pSize); } else{ //通常フォントパラメータ TextOut_ToParmHint(hdc,MethodCheckInfo.hFont,temporary,pSize); } counter++; if(MethodCheckInfo.msg[i]==','){ temporary[0]=','; temporary[1]=' '; temporary[2]=0; TextOut_ToParmHint(hdc,MethodCheckInfo.hFont,temporary,pSize); i++; while(MethodCheckInfo.msg[i]==' '||MethodCheckInfo.msg[i]=='\t') i++; i--; } else if(MethodCheckInfo.msg[i]==')'){ lstrcpy(temporary,MethodCheckInfo.msg+i); TextOut_ToParmHint(hdc,MethodCheckInfo.hFont,temporary,pSize); break; } else if(MethodCheckInfo.msg[i]=='\0') break; i2=-1; continue; } temporary[i2]=MethodCheckInfo.msg[i]; } pSize->cx=DrawParam_MaxX+20; pSize->cy=DrawParam_PosY+DrawParam_TextHeight+2; } void ShowHelp_FromParamHint(void){ extern METHODCHECKINFO MethodCheckInfo; int i; char temporary[MAX_PATH],temp2[255]; HH_AKLINK ak; for(i=0;;i++){ if(MethodCheckInfo.msg[i]=='('||MethodCheckInfo.msg[i]==' '|| MethodCheckInfo.msg[i]=='\0'){ temp2[i]=0; break; } temp2[i]=MethodCheckInfo.msg[i]; } memset(&ak, 0, sizeof(HH_AKLINK)); ak.cbStruct = sizeof(HH_AKLINK); ak.pszKeywords = temp2; ak.fIndexOnFail=1; sprintf(temporary,"%sBasicHelp.chm",pj_editor_Dir); HtmlHelp(NULL,temporary,HH_KEYWORD_LOOKUP,(DWORD)&ak); } LRESULT CALLBACK MethodCheckWindow(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern METHODCHECKINFO MethodCheckInfo; HDC hdc; HPEN hOldPen; HBRUSH hBrush,hOldBrush; PAINTSTRUCT ps; SIZE size; RECT rect; POINT pos; switch(message){ case WM_CREATE: GetCaretPos(&pos); ClientToScreen(GetWindow(hClient,GW_CHILD),&pos); DrawParam_StartScreenPosX=pos.x; SetTimer(hwnd,1,50,0); return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); //枠を描画 GetClientRect(hwnd,&rect); hBrush=CreateSolidBrush(RGB(255,255,180)); hOldPen=(HPEN)SelectObject(hdc,GetStockObject(BLACK_PEN)); hOldBrush=(HBRUSH)SelectObject(hdc,hBrush); Rectangle(hdc,0,0,rect.right,rect.bottom); SelectObject(hdc,hOldPen); SelectObject(hdc,hOldBrush); DeleteObject(hBrush); //パラメータヒントを描画 DrawParameterHint(hdc,&size); //[?]マークを描画 HBITMAP hBmp,hOldBmp; HDC memdc; hBmp=(HBITMAP)LoadImage(hResInst,MAKEINTRESOURCE(IDB_PARAMHINT_QUESTION),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE); memdc=CreateCompatibleDC(hdc); hOldBmp=(HBITMAP)SelectObject(memdc,hBmp); GetClientRect(hwnd,&rect); BitBlt(hdc,rect.right-14,rect.bottom-14,13,13,memdc,0,0,SRCCOPY); SelectObject(memdc,hOldBmp); DeleteDC(memdc); DeleteObject(hBmp); EndPaint(hwnd,&ps); return 0; case WM_TIMER: //[?]マークを描画 static BOOL bOnMouse; GetClientRect(hwnd,&rect); GetCursorPos(&pos); ScreenToClient(hwnd,&pos); if(rect.right-14<=pos.x&&pos.x<=rect.right-1&& rect.bottom-14<=pos.y&&pos.y<=rect.bottom-1){ if(bOnMouse) return 0; hdc=GetDC(hwnd); hBmp=(HBITMAP)LoadImage(hResInst,MAKEINTRESOURCE(IDB_PARAMHINT_QUESTION2),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE); memdc=CreateCompatibleDC(hdc); hOldBmp=(HBITMAP)SelectObject(memdc,hBmp); GetClientRect(hwnd,&rect); BitBlt(hdc,rect.right-14,rect.bottom-14,13,13,memdc,0,0,SRCCOPY); SelectObject(memdc,hOldBmp); DeleteDC(memdc); DeleteObject(hBmp); ReleaseDC(hwnd,hdc); bOnMouse=1; } else{ if(!bOnMouse) return 0; hdc=GetDC(hwnd); hBmp=(HBITMAP)LoadImage(hResInst,MAKEINTRESOURCE(IDB_PARAMHINT_QUESTION),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE); memdc=CreateCompatibleDC(hdc); hOldBmp=(HBITMAP)SelectObject(memdc,hBmp); GetClientRect(hwnd,&rect); BitBlt(hdc,rect.right-14,rect.bottom-14,13,13,memdc,0,0,SRCCOPY); SelectObject(memdc,hOldBmp); DeleteDC(memdc); DeleteObject(hBmp); ReleaseDC(hwnd,hdc); bOnMouse=0; } return 0; case WM_ACTIVATE: if(LOWORD(wParam)==WA_ACTIVE||LOWORD(wParam)==WA_CLICKACTIVE){ SetFocus(GetWindow(hClient,GW_CHILD)); if(LOWORD(wParam)==WA_CLICKACTIVE){ GetClientRect(hwnd,&rect); GetCursorPos(&pos); ScreenToClient(hwnd,&pos); if(rect.right-14<=pos.x&&pos.x<=rect.right-1&& rect.bottom-14<=pos.y&&pos.y<=rect.bottom-1){ ShowHelp_FromParamHint(); } } } return 0; case WM_DESTROY: MethodCheckInfo.BeforeMethodName[0]=0; return 0; } return DefWindowProc(hwnd,message,wParam,lParam); } void ShowCommandMessage(void){ extern METHODCHECKINFO MethodCheckInfo; int i; int sw; if(pobj_nv->dwParameterHint==1){ //ポップアップ表示 extern HINSTANCE hInst; extern METHODCHECKINFO MethodCheckInfo; HDC hdc,memdc; RECT rect,rc2; SIZE size; POINT pos; if(!MethodCheckInfo.hWnd){ MethodCheckInfo.hWnd=CreateWindow("MethodCheckWindow",NULL,WS_POPUP, 0,0,0,0, hOwner,NULL,hInst,0); sw=1; } else sw=0; i=GetWndNum(GetWindow(hClient,GW_CHILD)); hdc=GetDC(MethodCheckInfo.hWnd); memdc=CreateCompatibleDC(hdc); DrawParameterHint(memdc,&size); DeleteDC(memdc); ReleaseDC(MethodCheckInfo.hWnd,hdc); GetWindowRect(MdiInfo[i]->hwnd,&rect); GetCaretPos(&pos); ClientToScreen(MdiInfo[i]->pMdiTextEdit->hEdit,&pos); rect.left=pos.x-20; rect.top=pos.y-pobj_nv->lf.lfHeight; if(sw){ MoveWindow(MethodCheckInfo.hWnd,rect.left,rect.top,size.cx,size.cy,1); ShowWindow(MethodCheckInfo.hWnd,SW_SHOWNOACTIVATE); } else{ GetWindowRect(MethodCheckInfo.hWnd,&rc2); MoveWindow(MethodCheckInfo.hWnd, rc2.left, rect.top, size.cx, size.cy, 1); InvalidateRect(MethodCheckInfo.hWnd,NULL,0); } } //ステータスバーに表示 else if(pobj_nv->dwParameterHint==2) SetStatusText(MethodCheckInfo.msg); }