#include "../BasicCompiler_Common/common.h" //デバッグ用 #include "../BasicCompiler_Common/debug.h" //変数リストのツリーハンドル HWND hVarTree_Global,hVarTree_Local,hVarTree_This; int VarList_Array(HWND hVarTree,HTREEITEM hParent,DWORD offset,int type,int *SubScripts,LONG_PTR lpIndex); void VarList_Member(HWND hVarTree,HTREEITEM hParent,DWORD pTopOffset,CClass *pobj_c,BOOL bPtr); void VarList_Insert(HWND hVarTree,TV_INSERTSTRUCT *lptv,char *VarName,int type,DWORD offset,LONG_PTR lpIndex){ extern HANDLE hDebugProcess; int i2; char temporary[255],temp2[255]; DWORD dwData,dwAccessByte; double dbl; float flt; WORD wData; BYTE byteData; HTREEITEM hParent; if(type==DEF_OBJECT){ sprintf(lptv->item.pszText,"%s %s(&H%X)",VarName,STRING_OBJECT,offset); lptv->item.iImage=1; lptv->item.iSelectedImage=1; hParent=TreeView_InsertItem(hVarTree,lptv); VarList_Member(hVarTree,hParent,offset,(CClass *)lpIndex,0); return; } if(type==DEF_PTR_OBJECT){ i2=ReadProcessMemory(hDebugProcess,(void *)offset,&dwData,sizeof(DWORD),&dwAccessByte); sprintf(lptv->item.pszText,"%s %s(&H%X)",VarName,STRING_POINTEROFOBJECT,dwData); lptv->item.iImage=4; lptv->item.iSelectedImage=4; hParent=TreeView_InsertItem(hVarTree,lptv); if(i2) VarList_Member(hVarTree,hParent,dwData,(CClass *)lpIndex,1); return; } else{ if(type==DEF_PTR_BYTE){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&dwData,sizeof(DWORD),&dwAccessByte)){ for(i2=0;;i2++){ if(!ReadProcessMemory(hDebugProcess,(void *)(dwData+i2),&temporary[i2],1,&dwAccessByte)){ i2=-1; break; } if(temporary[i2]=='\0') break; if(i2==64){ lstrcpy(temporary+i2,"..."); break; } } if(i2==-1) sprintf(lptv->item.pszText,"%s %d(&H%X)",VarName,dwData,dwData); else sprintf(lptv->item.pszText,"%s %d(&H%X) \"%s\"",VarName,dwData,dwData,temporary); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_DOUBLE){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&dbl,sizeof(double),&dwAccessByte)){ sprintf(lptv->item.pszText,"%s %.15g",VarName,dbl); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_SINGLE){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&flt,sizeof(float),&dwAccessByte)){ sprintf(lptv->item.pszText,"%s %.6g",VarName,flt); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_INT64){ _int64 i64data; if(ReadProcessMemory(hDebugProcess,(void *)offset,&i64data,sizeof(_int64),&dwAccessByte)){ _i64toa(i64data,temporary,10); _i64toa(i64data,temp2,16); CharUpper(temp2); sprintf(lptv->item.pszText,"%s %s(&H%s)",VarName,temporary,temp2); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_QWORD){ _int64 i64data; if(ReadProcessMemory(hDebugProcess,(void *)offset,&i64data,sizeof(_int64),&dwAccessByte)){ _ui64toa(i64data,temporary,10); _ui64toa(i64data,temp2,16); CharUpper(temp2); sprintf(lptv->item.pszText,"%s %s(&H%s)",VarName,temporary,temp2); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_LONG){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&dwData,sizeof(DWORD),&dwAccessByte)){ sprintf(lptv->item.pszText,"%s %d(&H%X)",VarName,dwData,dwData); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_DWORD||IsPtrType(type)){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&dwData,sizeof(DWORD),&dwAccessByte)){ sprintf(lptv->item.pszText,"%s %u(&H%X)",VarName,dwData,dwData); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_INTEGER || (isUnicode&&type==DEF_CHAR)){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&wData,sizeof(WORD),&dwAccessByte)){ sprintf(lptv->item.pszText,"%s %d(&H%X)",VarName,(short)wData,(short)wData); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_WORD){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&wData,sizeof(WORD),&dwAccessByte)){ sprintf(lptv->item.pszText,"%s %u(&H%X)",VarName,wData,wData); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_SBYTE || (isUnicode==false&&type==DEF_CHAR)){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&byteData,sizeof(BYTE),&dwAccessByte)){ temporary[0]=byteData; temporary[1]=0; sprintf(lptv->item.pszText,"%s %d(&H%X)'%s'",VarName,(char)byteData,byteData,temporary); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_BYTE){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&byteData,sizeof(BYTE),&dwAccessByte)){ temporary[0]=byteData; temporary[1]=0; sprintf(lptv->item.pszText,"%s %d(&H%X)'%s'",VarName,byteData,byteData,temporary); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type==DEF_BOOLEAN){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&byteData,sizeof(BYTE),&dwAccessByte)){ if( byteData ) lstrcpy( temporary, "True" ); else lstrcpy( temporary, "False" ); sprintf(lptv->item.pszText,"%s %s",VarName,temporary); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } lptv->item.iImage=2; lptv->item.iSelectedImage=2; } TreeView_InsertItem(hVarTree,lptv); } void VarList_Member(HWND hVarTree,HTREEITEM hParent,DWORD pTopOffset,CClass *pobj_c,BOOL bPtr){ int i,i2; char VarData[VN_SIZE],VarName[VN_SIZE]; TV_INSERTSTRUCT tv; memset(&tv,0,sizeof(TV_INSERTSTRUCT)); tv.hInsertAfter=TVI_LAST; tv.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tv.hParent=hParent; tv.item.pszText=VarData; for(i=0;iiMemberNum;i++){ if(bPtr){ lstrcpy(VarName,"->"); lstrcat(VarName,pobj_c->ppobj_Member[i]->name); } else{ lstrcpy(VarName,"."); lstrcat(VarName,pobj_c->ppobj_Member[i]->name); } LONG_PTR offset = pobj_c->GetMemberOffset( pobj_c->ppobj_Member[i]->name, &i2 ); if(pobj_c->ppobj_Member[i]->SubScripts[0]!=-1){ //構造体内の配列 sprintf(VarData,"%s %s(&H%X)",VarName,STRING_ARRAY,pTopOffset+offset); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree,&tv); VarList_Array(hVarTree,hParent, pTopOffset+offset, pobj_c->ppobj_Member[i]->TypeInfo.type, pobj_c->ppobj_Member[i]->SubScripts, pobj_c->ppobj_Member[i]->TypeInfo.u.lpIndex); } else{ //メンバ変数 VarList_Insert(hVarTree, &tv, VarName, pobj_c->ppobj_Member[i]->TypeInfo.type, pTopOffset+offset, pobj_c->ppobj_Member[i]->TypeInfo.u.lpIndex); } } } int VarList_Array(HWND hVarTree,HTREEITEM hParent,DWORD offset,int type,int *SubScripts,LONG_PTR lpIndex){ int i,i2,i3,ElementNum,MemCounter,UseCount[255],TypeSize; char temporary[VN_SIZE],temp2[DIGIT_SIZE]; TV_INSERTSTRUCT tv; memset(&tv,0,sizeof(TV_INSERTSTRUCT)); tv.hInsertAfter=TVI_LAST; tv.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tv.hParent=hParent; tv.item.pszText=temporary; TypeSize=GetTypeSize(type,lpIndex); for(i=0;i<255;i++){ if(SubScripts[i]==-1) break; UseCount[i]=0; } UseCount[i]=-2; MemCounter=0; while(1){ UseCount[i]++; for(ElementNum=0;SubScripts[i-ElementNum]ScopeLevel!=0){ if(rva_to_real(pVar->ScopeStartAddress) <= pobj_dti->lplpObp[0] && pobj_dti->lplpObp[0] < rva_to_real(pVar->ScopeEndAddress)){ //範囲内 } else{ //範囲外 continue; } } if(!pobj_nv->bShow_DefaultSystem_Var){ if(memcmp(pVar->name,"_System_",8)==0|| memcmp(pVar->name,"_DebugSys_",10)==0|| memcmp(pVar->name,"_PromptSys_",11)==0) continue; } if(!pobj_nv->bShow_Rad_Var){ if(memcmp(pVar->name,"_RadSys_",8)==0) continue; } if(!pobj_nv->bShow_GUID_Var){ if(memcmp(pVar->name,"GUID_",5)==0|| memcmp(pVar->name,"IID_",4)==0|| memcmp(pVar->name,"CLSID_",6)==0) continue; } //静的メンバ if(strstr(pVar->name,".")) continue; if(pVar->bArray){ sprintf(temporary,"%s %s(&H%X)", pVar->name, STRING_ARRAY, ImageBase+MemPos_RWSection+pVar->offset); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree_Global,&tv); VarList_Array(hVarTree_Global,hParent, ImageBase+MemPos_RWSection+pVar->offset, pVar->type, pVar->SubScripts, pVar->u.index); } else{ VarList_Insert(hVarTree_Global, &tv, pVar->name, pVar->type, ImageBase+MemPos_RWSection+pVar->offset, pVar->u.index); } } } void RefreshLocalVar(void){ int i,i2,i3,sw; char temporary[VN_SIZE]; TV_INSERTSTRUCT tv; HTREEITEM hParent; ULONG_PTR lpData; LONG_PTR offset; ULONG_PTR lpAccBytes; TreeView_DeleteAllItems(hVarTree_Local); memset(&tv,0,sizeof(TV_INSERTSTRUCT)); tv.hInsertAfter=TVI_LAST; tv.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tv.hParent=TVI_ROOT; tv.item.pszText=temporary; extern HANDLE hDebugProcess; extern HWND hDebugWnd; i2=SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; if(pobj_dti->lplpSpBase[i2]==0) return; extern SUBINFO **ppSubHash; SUBINFO *psi; for(i3=0,sw=0;i3CompileAddress) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(psi->EndOpAddr)){ sw=1; break; } psi=psi->pNextData; } if(sw) break; } if(!psi) return; for(i=0;iVarNum;i++){ VARIABLE *pVar=&psi->pVar[i]; //スコープ外の場合は無視 if(pVar->ScopeLevel!=0){ if(rva_to_real(pVar->ScopeStartAddress) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(pVar->ScopeEndAddress)){ //範囲内 } else{ //範囲外 continue; } } if(pVar->bArray){ sprintf(temporary,"%s %s(&H%X)", pVar->name, STRING_ARRAY, pobj_dti->lplpSpBase[i2]+pVar->offset); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree_Local,&tv); VarList_Array(hVarTree_Local,hParent, pobj_dti->lplpSpBase[i2]+pVar->offset, pVar->type, pVar->SubScripts, pVar->u.index); } else{ offset=pobj_dti->lplpSpBase[i2]+pVar->offset; if(pVar->fRef){ ReadProcessMemory(hDebugProcess,(void *)offset,&lpData,sizeof(ULONG_PTR),&lpAccBytes); offset=lpData; } VarList_Insert(hVarTree_Local,&tv, pVar->name, pVar->type, offset, pVar->u.index); } } ///////////////////////////// // Thisオブジェクトのリスト ///////////////////////////// TreeView_DeleteAllItems(hVarTree_This); if(!psi->pobj_ParentClass) return; //Thisポインタを取得 LONG_PTR pThis; for(i=0;iVarNum;i++){ if(lstrcmp(psi->pVar[i].name,"_System_LocalThis")==0) break; } if(i==psi->VarNum) return; lpData=pobj_dti->lplpSpBase[i2]+psi->pVar[i].offset; ReadProcessMemory(hDebugProcess,(void *)lpData,&pThis,sizeof(LONG_PTR),&lpAccBytes); for(i=0;ipobj_ParentClass->iMemberNum;i++){ offset = psi->pobj_ParentClass->GetMemberOffset( psi->pobj_ParentClass->ppobj_Member[i]->name, &i2 ); if(psi->pobj_ParentClass->ppobj_Member[i]->SubScripts[0]!=-1){ //配列 sprintf(temporary,"%s %s(&H%X)", psi->pobj_ParentClass->ppobj_Member[i]->name, STRING_ARRAY, offset); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree_This,&tv); VarList_Array(hVarTree_This,hParent, pThis+offset, psi->pobj_ParentClass->ppobj_Member[i]->TypeInfo.type, psi->pobj_ParentClass->ppobj_Member[i]->SubScripts, psi->pobj_ParentClass->ppobj_Member[i]->TypeInfo.u.lpIndex); } else{ VarList_Insert(hVarTree_This,&tv, psi->pobj_ParentClass->ppobj_Member[i]->name, psi->pobj_ParentClass->ppobj_Member[i]->TypeInfo.type, pThis+offset, psi->pobj_ParentClass->ppobj_Member[i]->TypeInfo.u.lpIndex); } } } void RefreshGlobalVar_with_WindowLock(void){ extern HWND hDebugWnd; //処理時間を短くするため、一時的に非表示にする LockWindowUpdate(hDebugWnd); ShowWindow(GetParent(hVarTree_Global),SW_HIDE); //リフレッシュ RefreshGlobalVar(); LockWindowUpdate(NULL); ShowWindow(GetParent(hVarTree_Global),SW_SHOW); } void RefreshLocalVar_with_WindowLock(void){ extern HWND hDebugWnd; //処理時間を短くするため、一時的に非表示にする LockWindowUpdate(hDebugWnd); ShowWindow(GetParent(hVarTree_Local),SW_HIDE); //リフレッシュ RefreshLocalVar(); LockWindowUpdate(NULL); ShowWindow(GetParent(hVarTree_Local),SW_SHOW); } void SetCalcToWatchList(HWND hListView,int iItem,char *buffer){ int i; char temporary[255],temp2[255]; //エスケープシーケンスをセット SetEscapeSequenceFormat(buffer); //ブランクを除去 KillStringSpaces(buffer); //カッコを相互チェック if(!CheckParenthesis2(buffer)){ ListView_SetItemText(hListView,iItem,1,"式の解析に失敗"); return; } double dbl; _int64 i64data; i=StaticCalculation(true, buffer,0,&i64data,0,1); if(IsRealNumberType(i)){ memcpy(&dbl,&i64data,sizeof(double)); } if(i==0){ ListView_SetItemText(hListView,iItem,1,"式の解析に失敗"); } else if(i==-1){ ListView_SetItemText(hListView,iItem,1,STRING_CANNOTACCESS); } else{ if(IsRealNumberType(i)) sprintf(temporary,"%.15g (&H%08X)",dbl,(int)dbl); else if(Is64Type(i)){ _i64toa(i64data,temporary,10); _i64toa(i64data,temp2,16); CharUpper(temp2); sprintf(temporary+lstrlen(temporary)," (&H%s)",temp2); } else sprintf(temporary,"%d (&H%08X)",(long)i64data,(long)i64data); ListView_SetItemText(hListView,iItem,1,temporary); } } void RefreshWatchList(void){ extern HWND hDebugWnd; HWND hListView; int i,i2; char temporary[VN_SIZE]; hListView=GetDlgItem(hDebugWnd,IDC_WATCHLIST); i2=ListView_GetItemCount(hListView); for(i=0;iiProcLevel+1;i3++){ for(i2=0;i2lplpObp[i3]&& pobj_dti->lplpObp[i3]<=(pLineInfo[i2+1].TopObp+ImageBase+MemPos_CodeSection)) break; } if(i2==MaxLineInfoNum) pobj_dti->lpdwCp[i3]=-1; else{ pobj_dti->lpdwCp[i3]=pLineInfo[i2].TopCp; } } for(i3=0;i3<(int)pobj_dti->iProcLevel+1;i3++){ if(pobj_dti->lpdwCp[i3]==-1){ pobj_dti->iProcLevel--; for(i2=i3;i2<(int)pobj_dti->iProcLevel+1;i2++){ pobj_dti->lplpObp[i2]=pobj_dti->lplpObp[i2+1]; pobj_dti->lplpSpBase[i2]=pobj_dti->lplpSpBase[i2+1]; pobj_dti->lpdwCp[i2]=pobj_dti->lpdwCp[i2+1]; } i3--; continue; } } if(!GetLineNum(pobj_dti->lpdwCp[pobj_dti->iProcLevel],&i2,temporary)){ extern HWND hMainDlg; //"デバッグ情報の取得に失敗" MessageBox(hMainDlg,STRING_DEBUG_FAILED,"ActiveBasic error",MB_OK); return 0; } ShowErrorLine(i2,temporary); //プロシージャ コンボボックス extern SUBINFO **ppSubHash; SUBINFO *psi; int sw; SendMessage(hProcCombo,CB_RESETCONTENT,0,0); for(i2=pobj_dti->iProcLevel;i2>=0;i2--){ for(i3=0,sw=0;i3CompileAddress) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(psi->EndOpAddr)){ lstrcpy(temporary,psi->name); sw=1; break; } psi=psi->pNextData; } if(sw) break; } if(!psi){ if(i2==0){ lstrcpy(temporary,"Global"); pobj_dti->lplpSpBase[i2]=0; } else lstrcpy(temporary,"error"); } SendMessage(hProcCombo,CB_ADDSTRING,0,(long)temporary); } SendMessage(hProcCombo,CB_SETCURSEL,0,0); return pobj_dti->iProcLevel; } //IDC_THREADCOMBOプロシージャ LRESULT CALLBACK ThreadComboProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern WNDPROC OldThreadComboProc; int i2; DWORD dwThreadID; char temporary[255]; switch(message){ case WM_COMMAND: if(HIWORD(wParam)==CBN_SELCHANGE){ SendMessage(hwnd,CB_GETLBTEXT,SendMessage(hwnd,CB_GETCURSEL,0,0),(long)temporary); sscanf(temporary+2,"%X",&dwThreadID); i2=0; while(_DebugSys_dwThreadID[i2]!=dwThreadID) i2++; //次回のステップ実行対象を指定 extern int NextStepThreadNum; NextStepThreadNum=i2; //スレッド情報をリフレッシュ pobj_dti->Reflesh(i2); SetDebugProcCombo(GetDlgItem(GetParent(hwnd),IDC_PROCCOMBO)); SendDlgItemMessage(GetParent(hwnd),IDC_PROCCOMBO,WM_COMMAND,MAKELONG(0,CBN_SELCHANGE),0); } break; } return CallWindowProc(OldThreadComboProc,hwnd,message,wParam,lParam); } //IDC_PROCCOMBOプロシージャ LRESULT CALLBACK ProcComboProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern WNDPROC OldProcComboProc; int i2,i3; char temporary[MAX_PATH]; switch(message){ case WM_COMMAND: if(HIWORD(wParam)==CBN_SELCHANGE){ i2=SendMessage(hwnd,CB_GETCURSEL,0,0); GetLineNum(pobj_dti->lpdwCp[pobj_dti->iProcLevel-i2],&i3,temporary); ShowErrorLine(i3,temporary); RefreshLocalVar_with_WindowLock(); } break; } return CallWindowProc(OldProcComboProc,hwnd,message,wParam,lParam); } void InitVarList(DWORD dwThreadId){ extern HWND hDebugWnd; int i2,i3,i5; char temporary[255]; //スレッド SendDlgItemMessage(hDebugWnd,IDC_THREADCOMBO,CB_RESETCONTENT,0,0); extern DWORD _DebugSys_dwThreadID[256]; for(i2=0;i2<256;i2++){ if(_DebugSys_dwThreadID[i2]){ sprintf(temporary,"&H%08X",_DebugSys_dwThreadID[i2]); SendDlgItemMessage(hDebugWnd,IDC_THREADCOMBO,CB_ADDSTRING,0,(LPARAM)temporary); if(_DebugSys_dwThreadID[i2]==dwThreadId){ extern int NextStepThreadNum; NextStepThreadNum=i2; } } } sprintf(temporary,"&H%08X",dwThreadId); i5=(int)SendDlgItemMessage(hDebugWnd,IDC_THREADCOMBO,CB_FINDSTRING,0,(LPARAM)temporary); SendDlgItemMessage(hDebugWnd,IDC_THREADCOMBO,CB_SETCURSEL,i5,0); i2=SetDebugProcCombo(GetDlgItem(hDebugWnd,IDC_PROCCOMBO)); /////////////////////////////////////////////// // 実行中のプロシージャのローカル変数をセット /////////////////////////////////////////////// extern VARIABLE *LocalVar; extern int MaxLocalVarNum; int sw; MaxLocalVarNum=0; pobj_CompilingClass=0; i2=SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; if(pobj_dti->lplpSpBase[i2]){ extern SUBINFO **ppSubHash; SUBINFO *psi; for(i3=0,sw=0;i3CompileAddress) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(psi->EndOpAddr)){ sw=1; break; } psi=psi->pNextData; } if(sw) break; } if(psi){ LocalVar=psi->pVar; MaxLocalVarNum=psi->VarNum; pobj_CompilingClass=psi->pobj_ParentClass; } } //////////////////////// // 変数リストを再表示 //////////////////////// //処理時間を短くするため、一時的に非表示にする LockWindowUpdate(hDebugWnd); ShowWindow(GetParent(hVarTree_Global),SW_HIDE); ShowWindow(GetDlgItem(hDebugWnd,IDC_WATCHLIST),SW_HIDE); //リフレッシュ RefreshLocalVar(); RefreshGlobalVar(); RefreshWatchList(); LockWindowUpdate(NULL); ShowWindow(GetParent(hVarTree_Global),SW_SHOW); ShowWindow(GetDlgItem(hDebugWnd,IDC_WATCHLIST),SW_SHOW); } ////////////////////////////////////// // エディタに埋め込み表示のデバッガ ////////////////////////////////////// BOOL CALLBACK DebuggerButtonsProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern HINSTANCE hInst; extern DWORD dwStepRun; //デバッガ用ツールバー #define BMPNUM_DEBUGGERTOOLBAR 3 #define BTNNUM_DEBUGGERTOOLBAR 4 TBBUTTON DebuggerToolBar[]={ {0,IDC_DEBUG_START,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}, {1,IDC_DEBUG_STEPOVER,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, {2,IDC_DEBUG_STEPIN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, }; TOOLTIPTEXT *pTipText; static HIMAGELIST hImageList,hImageList_Disabled; switch(message){ case WM_INITDIALOG: //ツールバーを生成 extern HWND hDebuggerToolbar; hDebuggerToolbar=CreateToolbarEx(hwnd,WS_CHILD|WS_VISIBLE|CCS_NODIVIDER|TBSTYLE_FLAT|TBSTYLE_TOOLTIPS|WS_CLIPSIBLINGS, NULL, 0,0,0, DebuggerToolBar, BTNNUM_DEBUGGERTOOLBAR, /*アイテムの個数*/ 0,0,16,15,sizeof(TBBUTTON)); hImageList = ImageList_LoadImage(hInst, MAKEINTRESOURCE(IDR_DEBUGGERTOOLBAR), 16, 0, RGB(192,192,192),IMAGE_BITMAP, LR_CREATEDIBSECTION); SendMessage(hDebuggerToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageList); hImageList_Disabled = ImageList_LoadImage(hInst, MAKEINTRESOURCE(IDR_DEBUGGERTOOLBAR_DISABLED), 16, 0, RGB(192,192,192),IMAGE_BITMAP, LR_CREATEDIBSECTION); SendMessage(hDebuggerToolbar, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)hImageList_Disabled); break; case WM_COMMAND: switch(LOWORD(wParam)){ case IDC_DEBUG_START: DestroyWindow(GetParent(hwnd)); return 1; case IDC_DEBUG_STEPIN: Debugger_StepIn(); return 1; case IDC_DEBUG_STEPOVER: Debugger_StepOver(); return 1; } break; case WM_NOTIFY: pTipText=(TOOLTIPTEXT *)lParam; if(pTipText->hdr.code==TTN_NEEDTEXT){ //ツールチップを表示 switch(pTipText->hdr.idFrom){ case IDC_DEBUG_START: pTipText->lpszText="実行"; break; case IDC_DEBUG_STEPOVER: pTipText->lpszText="ステップ アウト"; break; case IDC_DEBUG_STEPIN: pTipText->lpszText="ステップ イン"; break; } } break; case WM_SIZE: MoveWindow(hDebuggerToolbar,0,0,LOWORD(lParam),HIWORD(lParam),1); return 1; case WM_DESTROY: ImageList_Destroy(hImageList); ImageList_Destroy(hImageList_Disabled); return 1; } return 0; } WNDPROC OldTabProc; LRESULT CALLBACK TabProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern HINSTANCE hInst; static HMENU hDummyMenu,hMenu=0; switch(message){ case WM_CONTEXTMENU: if(hMenu==0){ hDummyMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_DEBUGGER_VARLIST_MENU)); hMenu=GetSubMenu(hDummyMenu,0); } MENUITEMINFO mi; mi.cbSize=sizeof(MENUITEMINFO); mi.fMask=MIIM_STATE; mi.fState=MFS_CHECKED; if(pobj_nv->bShow_DefaultSystem_Var) SetMenuItemInfo(hMenu,IDM_SHOW_DEFAULTSYSTEM_VAR,0,&mi); if(pobj_nv->bShow_Rad_Var) SetMenuItemInfo(hMenu,IDM_SHOW_RAD_VAR,0,&mi); if(pobj_nv->bShow_GUID_Var) SetMenuItemInfo(hMenu,IDM_SHOW_GUID_VAR,0,&mi); TrackPopupMenu(hMenu,TPM_LEFTALIGN,LOWORD(lParam),HIWORD(lParam),0,hwnd,0); break; case WM_COMMAND: mi.cbSize=sizeof(MENUITEMINFO); mi.fMask=MIIM_STATE; switch(LOWORD(wParam)){ case IDM_SHOW_DEFAULTSYSTEM_VAR: if(pobj_nv->bShow_DefaultSystem_Var){ pobj_nv->bShow_DefaultSystem_Var=0; mi.fState=MFS_UNCHECKED; } else{ pobj_nv->bShow_DefaultSystem_Var=1; mi.fState=MFS_CHECKED; } SetMenuItemInfo(hMenu,IDM_SHOW_DEFAULTSYSTEM_VAR,0,&mi); RefreshGlobalVar_with_WindowLock(); break; case IDM_SHOW_RAD_VAR: if(pobj_nv->bShow_Rad_Var){ pobj_nv->bShow_Rad_Var=0; mi.fState=MFS_UNCHECKED; } else{ pobj_nv->bShow_Rad_Var=1; mi.fState=MFS_CHECKED; } SetMenuItemInfo(hMenu,IDM_SHOW_RAD_VAR,0,&mi); RefreshGlobalVar_with_WindowLock(); break; case IDM_SHOW_GUID_VAR: if(pobj_nv->bShow_GUID_Var){ pobj_nv->bShow_GUID_Var=0; mi.fState=MFS_UNCHECKED; } else{ pobj_nv->bShow_GUID_Var=1; mi.fState=MFS_CHECKED; } SetMenuItemInfo(hMenu,IDM_SHOW_GUID_VAR,0,&mi); RefreshGlobalVar_with_WindowLock(); break; } break; case WM_DESTROY: DestroyMenu(hMenu); hMenu=0; break; } return CallWindowProc(OldTabProc,hwnd,message,wParam,lParam); } BOOL CALLBACK DlgDebugger(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern HANDLE hHeap; extern HINSTANCE hInst; extern DWORD dwStepRun; extern double width_ratio_VarList; RECT rect; int i,i2,i3; char temporary[VN_SIZE]; LV_DISPINFO *lvinfo; LVITEM ListView_Item; static POINT pos_VarList; static POINT pos_WatchList; switch(message){ case WM_INITDIALOG: extern HWND hDebugWnd; hDebugWnd=hwnd; //変数リストの初期位置を取得 GetWindowRect(GetDlgItem(hwnd,IDC_VARPOS),&rect); pos_VarList.x=rect.left; pos_VarList.y=rect.top; ScreenToClient(hwnd,&pos_VarList); //ウォッチリストの初期位置を取得 pos_WatchList.x=pos_VarList.x+(rect.right-rect.left)+LEVER_THICK; pos_WatchList.y=0; //ツールバーのベースウィンドウを生成 static HWND hBase_ToolBar; hBase_ToolBar=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DEBUGGER_TOOLBARBASE),hwnd,DebuggerButtonsProc); MoveWindow(hBase_ToolBar,50,0,20*BTNNUM_DEBUGGERTOOLBAR,22,1); extern WNDPROC OldThreadComboProc; OldThreadComboProc=(WNDPROC)GetWindowLong(GetDlgItem(hwnd,IDC_THREADCOMBO),GWL_WNDPROC); SetWindowLong(GetDlgItem(hwnd,IDC_THREADCOMBO),GWL_WNDPROC,(long)ThreadComboProc); extern WNDPROC OldProcComboProc; OldProcComboProc=(WNDPROC)GetWindowLong(GetDlgItem(hwnd,IDC_PROCCOMBO),GWL_WNDPROC); SetWindowLong(GetDlgItem(hwnd,IDC_PROCCOMBO),GWL_WNDPROC,(long)ProcComboProc); /////////////////////////// // タブコントロールを生成 /////////////////////////// static HWND hTab; HFONT hFont; hFont=(HFONT)SendMessage(hwnd,WM_GETFONT,0,0); hTab=CreateWindow(WC_TABCONTROL,NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, 0,0,0,0,hwnd,0,hInst,0); SendMessage(hTab,WM_SETFONT,(long)hFont,0); OldTabProc=(WNDPROC)GetWindowLong(hTab,GWL_WNDPROC); SetWindowLong(hTab,GWL_WNDPROC,(long)TabProc); //タブを設定 TC_ITEM tcItem; tcItem.mask=TCIF_TEXT; tcItem.pszText="グローバル"; SendMessage(hTab,TCM_INSERTITEM,0,(LPARAM)&tcItem); tcItem.mask=TCIF_TEXT; tcItem.pszText="ローカル"; SendMessage(hTab,TCM_INSERTITEM,1,(LPARAM)&tcItem); tcItem.mask=TCIF_TEXT; tcItem.pszText="This"; SendMessage(hTab,TCM_INSERTITEM,2,(LPARAM)&tcItem); //グローバル変数リストのツリーを作成 hVarTree_Global=CreateWindowEx(WS_EX_CLIENTEDGE,WC_TREEVIEW,"", WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS, 0,0,0,0, hTab,0,hInst,0); //ローカル変数リストのツリーを作成 hVarTree_Local=CreateWindowEx(WS_EX_CLIENTEDGE,WC_TREEVIEW,"", WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS, 0,0,0,0, hTab,0,hInst,0); //This変数リストのツリーを作成 hVarTree_This=CreateWindowEx(WS_EX_CLIENTEDGE,WC_TREEVIEW,"", WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS, 0,0,0,0, hTab,0,hInst,0); ShowWindow(hVarTree_Global,SW_SHOW); //イメージリスト読み込み、設定 static HIMAGELIST hVariOrderImageList; hVariOrderImageList=ImageList_Create(16,16,ILC_COLOR4|ILC_MASK,4,0); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARARRAY))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARSTRUCT))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARDATA))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARSTR))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARPTRSTRUCT))); TreeView_SetImageList(hVarTree_Global,hVariOrderImageList,TVSIL_NORMAL); TreeView_SetImageList(hVarTree_Local,hVariOrderImageList,TVSIL_NORMAL); TreeView_SetImageList(hVarTree_This,hVariOrderImageList,TVSIL_NORMAL); ///////////////////////// // ウォッチリスト ///////////////////////// //コラムの設定 static HWND hListView; LV_COLUMN ListView_Column; DWORD dwStyle; hListView=GetDlgItem(hwnd,IDC_WATCHLIST); GetClientRect(hListView,&rect); dwStyle=ListView_GetExtendedListViewStyle(hListView); dwStyle|=LVS_EX_FULLROWSELECT; ListView_SetExtendedListViewStyle(hListView,dwStyle); ListView_Column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; ListView_Column.fmt=LVCFMT_LEFT; extern int width_WatchColumn_Expression; ListView_Column.cx=width_WatchColumn_Expression; ListView_Column.pszText="ウォッチ式"; ListView_Column.iSubItem=0; ListView_InsertColumn(hListView,0,&ListView_Column); extern int width_WatchColumn_Value; ListView_Column.cx=width_WatchColumn_Value; ListView_Column.pszText="値"; ListView_Column.iSubItem=1; ListView_InsertColumn(hListView,1,&ListView_Column); //アイテムの設定 ListView_Item.mask=LVIF_TEXT; ListView_Item.iSubItem=0; for(i=0;iWatchNum;i++){ ListView_Item.pszText=pobj_nv->ppWatchStr[i]; ListView_Item.iItem=i; ListView_InsertItem(hListView,&ListView_Item); } ListView_Item.pszText="..."; ListView_Item.iItem=i; ListView_InsertItem(hListView,&ListView_Item); /////////////////////// // 変数リストの初期化 /////////////////////// InitVarList((DWORD)lParam); break; case WM_NOTIFY: NMHDR *hdr; hdr=(NMHDR *)lParam; if(hdr->hwndFrom==hTab&&hdr->code==TCN_SELCHANGE){ i=TabCtrl_GetCurSel(hTab); if(i==0){ //グローバル変数を表示 ShowWindow(hVarTree_Global,SW_SHOW); ShowWindow(hVarTree_Local,SW_HIDE); ShowWindow(hVarTree_This,SW_HIDE); } else if(i==1){ //ローカル変数を表示 ShowWindow(hVarTree_Global,SW_HIDE); ShowWindow(hVarTree_Local,SW_SHOW); ShowWindow(hVarTree_This,SW_HIDE); } else if(i==2){ //This変数を表示 ShowWindow(hVarTree_Global,SW_HIDE); ShowWindow(hVarTree_Local,SW_HIDE); ShowWindow(hVarTree_This,SW_SHOW); } } if(hdr->hwndFrom==hListView){ lvinfo=(LV_DISPINFO *)hdr; if(hdr->code==NM_DBLCLK){ i2=ListView_GetItemCount(hListView); for(i=0;icode==LVN_BEGINLABELEDIT){ hEdit=ListView_GetEditControl(hListView); GetWindowText(hEdit,temporary,VN_SIZE); if(lstrcmp(temporary,"...")==0) SetWindowText(hEdit,""); } if(hdr->code==LVN_ENDLABELEDIT){ GetWindowText(hEdit,temporary,VN_SIZE); if(temporary[0]=='\0'){ if(ListView_GetItemCount(hListView)-1==lvinfo->item.iItem) break; //空白入力の場合はそのアイテムを削除する ListView_DeleteItem(hListView,lvinfo->item.iItem); break; } ListView_SetItemText(hListView,lvinfo->item.iItem,0,temporary); //演算結果を表示 SetCalcToWatchList(hListView,lvinfo->item.iItem,temporary); if(lvinfo->item.iItem==ListView_GetItemCount(hListView)-1){ //リストアイテムを追加 ListView_Item.mask=LVIF_TEXT; ListView_Item.pszText="..."; ListView_Item.iItem=lvinfo->item.iItem+1; ListView_Item.iSubItem=0; ListView_InsertItem(hListView,&ListView_Item); } } if(hdr->code==LVN_KEYDOWN){ LV_KEYDOWN *plvKeydown; plvKeydown=(LV_KEYDOWN *)hdr; if(plvKeydown->wVKey==VK_DELETE){ i2=ListView_GetItemCount(hListView); for(i=i2-2;i>=0;i--){ if(ListView_GetItemState(hListView,i,LVIS_SELECTED)){ ListView_DeleteItem(hListView,i); i3=i; } } ListView_SetItemState(hListView,i3,LVIS_SELECTED,LVIS_SELECTED); } } } break; case WM_SIZE: //変数リストの位置 int width_VarList; width_VarList= (int)((double)(LOWORD(lParam)-pos_VarList.x)*width_ratio_VarList); MoveWindow(hTab, pos_VarList.x, pos_VarList.y, width_VarList, HIWORD(lParam)-pos_VarList.y, 1); GetClientRect(hTab,&rect); TabCtrl_AdjustRect(hTab,FALSE,&rect); rect.left-=2; rect.right++; rect.bottom++; MoveWindow(hVarTree_Global, rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,1); MoveWindow(hVarTree_Local, rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,1); MoveWindow(hVarTree_This, rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,1); pos_WatchList.x=pos_VarList.x+width_VarList+LEVER_THICK; pos_WatchList.y=0; //ウォッチリストの位置 MoveWindow(GetDlgItem(hwnd,IDC_WATCHLIST), pos_WatchList.x, pos_WatchList.y, LOWORD(lParam)-pos_WatchList.x, HIWORD(lParam)-pos_WatchList.y, 1); return 1; case WM_VARLIST_CLOSE: DestroyWindow(hwnd); return 1; case WM_DESTROY: ImageList_Destroy(hVariOrderImageList); ////////////////////////////////////////////////////////////// // ウォッチリストの以前の内容を破棄し、新しい内容に書き換える ////////////////////////////////////////////////////////////// for(i=0;iWatchNum;i++){ HeapDefaultFree(pobj_nv->ppWatchStr[i]); } HeapDefaultFree(pobj_nv->ppWatchStr); pobj_nv->WatchNum=ListView_GetItemCount(hListView)-1; pobj_nv->ppWatchStr=(char **)HeapAlloc(hHeap,0,pobj_nv->WatchNum*sizeof(char *)+1); for(i=0;iWatchNum;i++){ ListView_GetItemText(hListView,i,0,temporary,VN_SIZE); pobj_nv->ppWatchStr[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(pobj_nv->ppWatchStr[i],temporary); } ////////////////////////////// // デバッグダイアログを破棄 ////////////////////////////// hDebugWnd=0; extern BOOL bClipCompileView; if(bClipCompileView){ extern HWND hOwnerEditor; SendMessage(hOwnerEditor,WM_DESTROYDEBUGGERVIEW,0,0); } return 1; /////////////////////// // デバッグコマンド /////////////////////// case WM_DEBUG_CONTINUE: DestroyWindow(hwnd); return 1; case WM_STEP_IN: Debugger_StepIn(); return 1; case WM_STEP_OVER: Debugger_StepOver(); return 1; case WM_STEP_CURSOR: Debugger_StepCursor(); return 1; } return 0; } ////////////////////////////////// // ポップアップ表示の変数リスト ////////////////////////////////// BOOL CALLBACK DlgVarList(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){ extern HANDLE hHeap; extern HINSTANCE hInst; extern DWORD dwStepRun; RECT rect; POINT pos; SIZE size; switch(message){ case WM_INITDIALOG: extern HWND hDebugWnd; hDebugWnd=hwnd; pos.x=pobj_nv->VarDlgRect.left; pos.y=pobj_nv->VarDlgRect.top; size.cx=pobj_nv->VarDlgRect.right-pobj_nv->VarDlgRect.left; size.cy=pobj_nv->VarDlgRect.bottom-pobj_nv->VarDlgRect.top; MoveWindow(hwnd,pos.x,pos.y,size.cx,size.cy,1); extern WNDPROC OldThreadComboProc; OldThreadComboProc=(WNDPROC)GetWindowLong(GetDlgItem(hwnd,IDC_THREADCOMBO),GWL_WNDPROC); SetWindowLong(GetDlgItem(hwnd,IDC_THREADCOMBO),GWL_WNDPROC,(long)ThreadComboProc); extern WNDPROC OldProcComboProc; OldProcComboProc=(WNDPROC)GetWindowLong(GetDlgItem(hwnd,IDC_PROCCOMBO),GWL_WNDPROC); SetWindowLong(GetDlgItem(hwnd,IDC_PROCCOMBO),GWL_WNDPROC,(long)ProcComboProc); //イメージリスト読み込み、設定 static HIMAGELIST hVariOrderImageList; hVariOrderImageList=ImageList_Create(16,16,ILC_COLOR4|ILC_MASK,4,0); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARARRAY))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARSTRUCT))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARDATA))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARSTR))); ImageList_AddIcon(hVariOrderImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_VARPTRSTRUCT))); TreeView_SetImageList(GetDlgItem(hwnd,IDC_VARTREE),hVariOrderImageList,TVSIL_NORMAL); InitVarList((DWORD)lParam); break; case WM_COMMAND: switch(LOWORD(wParam)){ case IDCANCEL: DestroyWindow(hwnd); return 1; case IDC_STEPIN: Debugger_StepIn(); return 1; case IDC_STEPOVER: Debugger_StepOver(); return 1; } break; case WM_SIZE: GetWindowRect(GetDlgItem(hwnd,IDC_VARTREE),&rect); pos.x=rect.left; pos.y=rect.top; ScreenToClient(hwnd,&pos); MoveWindow(GetDlgItem(hwnd,IDC_VARTREE),0,pos.y,LOWORD(lParam),HIWORD(lParam)-pos.y,TRUE); SetWindowPos(GetDlgItem(hwnd,IDCANCEL),0,LOWORD(lParam)-91,9,0,0,SWP_NOSIZE); return 1; case WM_VARLIST_CLOSE: DestroyWindow(hwnd); return 1; case WM_DESTROY: ImageList_Destroy(hVariOrderImageList); GetWindowRect(hwnd,&pobj_nv->VarDlgRect); hDebugWnd=0; return 1; } return 0; }