#include "stdafx.h" #include "common.h" CDebugger *pobj_Debugger; #define WM_DEBUG_CONTINUE WM_USER+200 #define WM_STEP_IN WM_USER+201 #define WM_STEP_OVER WM_USER+202 #define WM_STEP_CURSOR WM_USER+203 #define WM_DEBUG_STOP WM_USER+204 #define WM_DEBUG_PAUSE WM_USER+205 CDebugger::CDebugger(){ hwnd=0; bDebugging=0; } CDebugger::~CDebugger(){ } BOOL CDebugger::IsDebugging(void){ return bDebugging; } BOOL CDebugger::IsDebuggerView(void){ if(hwnd) return 1; return 0; } void CDebugger::resize(int x,int y,int cx,int cy){ MoveWindow(hwnd,x,y,cx,cy,1); } void CDebugger::ResetCommandEnabled(void){ if(bDebugging==0){ BOOL bEnableDocument=0, bBreakPoint=0; HWND hChild; hChild=GetWindow(hClient,GW_CHILD); if( projectInfo.IsOpened() ){ //有効(プロジェクトを開いているとき) bEnableDocument=1; } else{ if(IsWindow(hChild)){ if(MdiInfo[GetWndNum(hChild)]->DocType==WNDTYPE_BASIC){ //有効(Basicプログラムファイルを開いているとき) bEnableDocument=1; } } } if(IsWindow(hChild)){ if(MdiInfo[GetWndNum(hChild)]->DocType==WNDTYPE_BASIC){ //ブレークポイント有効(Basicプログラムファイルを開いているとき) bBreakPoint=1; } } int MenuMsg; if(bEnableDocument) MenuMsg=MF_BYCOMMAND|MF_ENABLED; else MenuMsg=MF_BYCOMMAND|MF_GRAYED; //リリースコンパイル pobj_MainMenu->EnableItem(IDM_RELEASECOMPILE,MenuMsg); pobj_ReleaseToolbar->EnableItem(IDM_RELEASECOMPILE,bEnableDocument); //リリース実行 pobj_MainMenu->EnableItem(IDM_RELEASERUN,MenuMsg); pobj_ReleaseToolbar->EnableItem(IDM_RELEASERUN,bEnableDocument); //デバッグコンパイル pobj_MainMenu->EnableItem(IDM_DEBUGCOMPILE,MenuMsg); pobj_DebuggerToolbar->EnableItem(IDM_DEBUGCOMPILE,bEnableDocument); //デバッグ実行 pobj_MainMenu->EnableItem(IDM_DEBUG,MenuMsg); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,bEnableDocument); if(bEnableDocument==0){ //ステップ実行 pobj_MainMenu->EnableItem(IDM_STEP_IN,MenuMsg); pobj_MainMenu->EnableItem(IDM_STEP_OVER,MenuMsg); pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MenuMsg); pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,bEnableDocument); pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,bEnableDocument); pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,bEnableDocument); //デバッグの一時停止 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MenuMsg); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,bEnableDocument); //デバッグの中断 pobj_MainMenu->EnableItem(IDM_DEBUG_STOP,MenuMsg); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_STOP,bEnableDocument); } if(bBreakPoint) MenuMsg=MF_BYCOMMAND|MF_ENABLED; else MenuMsg=MF_BYCOMMAND|MF_GRAYED; //ブレークポイント pobj_MainMenu->EnableItem(IDM_BREAKPOINT,MenuMsg); pobj_DebuggerToolbar->EnableItem(IDM_BREAKPOINT,bBreakPoint); //プラットフォームセレクト extern HWND hSelectCompilerCombo; EnableWindow(hSelectCompilerCombo,bEnableDocument); } } void CDebugger::SaftyCheck(void){ extern HWND hCompileView; if(!IsWindow(hCompileView)){ SendMessage(hOwner,WM_DESTROYDEBUGGERVIEW,0,0); SendMessage(hOwner,WM_DESTROYDEBUGGERBASE,0,0); SendMessage(hOwner,WM_DESTROYCOMPILEVIEW,0,0); } } ///////////////////////////////////////// // デバッグ開始 ///////////////////////////////////////// void CDebugger::begin(void){ bDebugging=1; if(pobj_MainMenu){ //リリースコンパイルを無効化 pobj_MainMenu->EnableItem(IDM_RELEASECOMPILE,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_RELEASECOMPILE,0); //デバッグコンパイルを無効化 pobj_MainMenu->EnableItem(IDM_DEBUGCOMPILE,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUGCOMPILE,0); //デバッグ実行を無効化 pobj_MainMenu->EnableItem(IDM_DEBUG,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,0); //ステップ実行を無効化 pobj_MainMenu->EnableItem(IDM_STEP_IN,MF_BYCOMMAND|MF_GRAYED); pobj_MainMenu->EnableItem(IDM_STEP_OVER,MF_BYCOMMAND|MF_GRAYED); pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,0); pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,0); pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,0); //デバッグの一時停止を有効化 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,1); //デバッグの中断を有効化 pobj_MainMenu->EnableItem(IDM_DEBUG_STOP,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_STOP,1); } } ///////////////////////////////////////// // デバッグ終了 ///////////////////////////////////////// void CDebugger::end(void){ bDebugging=0; if(pobj_MainMenu){ //リリースコンパイルを有効化 pobj_MainMenu->EnableItem(IDM_RELEASECOMPILE,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_RELEASECOMPILE,1); //デバッグコンパイルを有効化 pobj_MainMenu->EnableItem(IDM_DEBUGCOMPILE,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUGCOMPILE,1); //デバッグ実行を有効化 pobj_MainMenu->EnableItem(IDM_DEBUG,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,1); //ステップ実行を無効化 pobj_MainMenu->EnableItem(IDM_STEP_IN,MF_BYCOMMAND|MF_GRAYED); pobj_MainMenu->EnableItem(IDM_STEP_OVER,MF_BYCOMMAND|MF_GRAYED); pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,0); pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,0); pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,0); //デバッグの一時停止を無効化 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,0); //デバッグの中断を無効化 pobj_MainMenu->EnableItem(IDM_DEBUG_STOP,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_STOP,0); } } ///////////////////////////////////////// // 一時停止(ウォッチウィンドウが立ち上がる) ///////////////////////////////////////// void CDebugger::watch_start(HWND hDebuggerView){ hwnd=hDebuggerView; if(pobj_MainMenu){ //継続を有効化 pobj_MainMenu->EnableItem(IDM_DEBUG,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,1); //ステップ実行を有効化 pobj_MainMenu->EnableItem(IDM_STEP_IN,MF_BYCOMMAND|MF_ENABLED); pobj_MainMenu->EnableItem(IDM_STEP_OVER,MF_BYCOMMAND|MF_ENABLED); pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MF_BYCOMMAND|MF_ENABLED); pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,1); pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,1); pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,1); //デバッグの一時停止を無効化 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MF_BYCOMMAND|MF_GRAYED); pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,0); } } ///////////////////////////////////////// // デバッグを再開 ///////////////////////////////////////// void CDebugger::watch_quit(void){ hwnd=0; begin(); } void CDebugger::DebugContinue(void){ if(hwnd) SendMessage(hwnd,WM_DEBUG_CONTINUE,0,0); } void CDebugger::StepIn(void){ if(hwnd) SendMessage(hwnd,WM_STEP_IN,0,0); } void CDebugger::StepOver(void){ if(hwnd) SendMessage(hwnd,WM_STEP_OVER,0,0); } void CDebugger::StepToCursor(void){ if(hwnd){ int WndNum; WndNum=GetNowWndNum(); if(WndNum==-1) return; char temporary[MAX_PATH]; sprintf(temporary,"\"%s\",%d",MdiInfo[WndNum]->path.c_str(),MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y); char temp2[MAX_PATH]; GetTempPath(MAX_PATH,temp2); if(temp2[lstrlen(temp2)-1]!='\\') lstrcat(temp2,"\\"); lstrcat(temp2,"ab_breakpoint.tmp"); WriteBuffer(temp2,temporary,lstrlen(temporary)); SendMessage(hwnd,WM_STEP_CURSOR,0,0); } } void CDebugger::DebugStop(void){ extern HWND hCompileView; SendMessage(hCompileView,WM_DEBUG_STOP,0,0); } void CDebugger::DebugPause(void){ extern HWND hCompileView; SendMessage(hCompileView,WM_DEBUG_PAUSE,0,0); } ////////////////////////// // ブレークポイント ////////////////////////// BreakPointsPerFile::BreakPointsPerFile(const char *lpszFileName,int iLineNum){ this->lpszFileName=(char *)HeapAlloc(hHeap,0,lstrlen(lpszFileName)+1); lstrcpy(this->lpszFileName,lpszFileName); piLine=(int *)HeapAlloc(hHeap,0,sizeof(int)); piLine[0]=iLineNum; num=1; } BreakPointsPerFile::~BreakPointsPerFile(){ HeapDefaultFree(lpszFileName); HeapDefaultFree(piLine); } void BreakPointsPerFile::add(int iLineNum){ piLine=(int *)HeapReAlloc(hHeap,0,piLine,(num+1)*sizeof(int)); int i; for(i=0;iiLineNum){ for(int i2=num;i2>i;i2--){ piLine[i2]=piLine[i2-1]; } break; } } piLine[i]=iLineNum; num++; } void BreakPointsPerFile::remove(int iLineNum){ int i; for(i=0;icpMin;i++){ if(IsReturnCode(lpszBuffer+i)){ DelStartLine++; } } int DelEndLine=DelStartLine; for(;icpMax;i++){ if(IsReturnCode(lpszBuffer+i)){ DelEndLine++; } } //ブレークポイントを消去 for(i=0;ilpszFileName,lpszFileName)==0){ ppItem[i]->add(iLineNum); return; } } if(i==num){ ppItem=(BreakPointsPerFile **)HeapReAlloc(hHeap,0,ppItem,(num+1)*sizeof(BreakPointsPerFile *)); ppItem[num]=new BreakPointsPerFile(lpszFileName,iLineNum); num++; } } void CDBBreakPoint::remove( const char *lpszFileName,int iLineNum){ int i; for(i=0;ilpszFileName)==0){ ppItem[i]->remove(iLineNum); break; } } if(i==num) return; if(ppItem[i]->num==0){ delete ppItem[i]; num--; for(;ipath ).IsExistFile() ) { return; } int i,i2,sw=0; for(i=0;ipath.c_str(),ppItem[i]->lpszFileName)==0){ for(i2=0;i2num;i2++){ if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==ppItem[i]->piLine[i2]){ sw=1; break; } } break; } } if(sw==0){ //ブレークポイントを追加 insert(MdiInfo[WndNum]->path.c_str(),MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y); } else{ //ブレークポイントを削除 remove(MdiInfo[WndNum]->path.c_str(),MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y); } if(pobj_Debugger->IsDebugging()){ SaveToTempFile(); //デバッガにブレークポイント更新のメッセージを送る //未完成 } //エディタを再描画 InvalidateRect(MdiInfo[WndNum]->pMdiTextEdit->hEdit,NULL,0); } void CDBBreakPoint::SaveToTempFile(void){ char *buffer; int length=0; buffer=(char *)HeapAlloc(hHeap,0,65535); buffer[0]=0; int i,i2; for(i=0;ilpszFileName); length+=lstrlen(buffer+length); for(i2=0;i2num;i2++){ sprintf(buffer+length,",%d",ppItem[i]->piLine[i2]); length+=lstrlen(buffer+length); } lstrcpy(buffer+length,"\n"); length+=lstrlen(buffer+length); } HANDLE hFile; char temporary[MAX_PATH]; GetTempPath(MAX_PATH,temporary); if(temporary[lstrlen(temporary)-1]!='\\') lstrcat(temporary,"\\"); lstrcat(temporary,"ab_breakpoint.tmp"); //未完成 sprintf(temporary,"%sab_breakpoint.tmp",pj_editor_Dir); hFile=CreateFile(temporary,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_TEMPORARY,NULL); DWORD dwAccBytes; WriteFile(hFile,buffer,lstrlen(buffer),&dwAccBytes,NULL); CloseHandle(hFile); HeapDefaultFree(buffer); } BreakPointsPerFile *CDBBreakPoint::EnumLines(const char *lpszFilePath){ int i; for(i=0;ilpszFileName)==0){ return ppItem[i]; } } return 0; } void CDBBreakPoint::replace(const char *lpszFilePath,LPSTR lpszBuffer,CHARRANGE *pDelRange,CHARRANGE *pRange,LPSTR lpszNewStr){ int i; for(i=0;ilpszFileName,lpszFilePath)==0){ ppItem[i]->replace(lpszBuffer,pDelRange,pRange,lpszNewStr); return; } } }