#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" //デバッグ用 #include "../BasicCompiler_Common/debug.h" using namespace ActiveBasic::Compiler; //変数リストのツリーハンドル HWND hVarTree_Global,hVarTree_Local,hVarTree_This; int VarList_Array(HWND hVarTree,HTREEITEM hParent,LONG_PTR offset,const Type &type,const Subscripts &subscripts); void VarList_Member(HWND hVarTree,HTREEITEM hParent,LONG_PTR pTopOffset,const CClass &objClass,BOOL bPtr); void VarList_Insert(HWND hVarTree,TV_INSERTSTRUCT *lptv,const char *VarName,const Type &type,LONG_PTR offset){ extern HANDLE hDebugProcess; int i2; char temporary[255],temp2[255]; LONG_PTR pData; SIZE_T accessBytes; double dbl; float flt; WORD wData; BYTE byteData; HTREEITEM hParent; _int64 i64data; if( type.IsObject() || type.IsStruct() ){ i2=1; if( type.IsObject() ){ // 参照型ということを考慮する i2=ReadProcessMemory(hDebugProcess,(void *)offset,&pData,sizeof(void *),&accessBytes); offset = pData; } sprintf(lptv->item.pszText,"%s %s(&H%X)",VarName,STRING_OBJECT,(ULONG_PTR)offset); lptv->item.iImage=1; lptv->item.iSelectedImage=1; hParent=TreeView_InsertItem(hVarTree,lptv); if(i2 && offset) VarList_Member(hVarTree,hParent,offset,type.GetClass(),0); return; } else if( type.IsObjectPtr() || type.IsStructPtr() ){ i2=ReadProcessMemory(hDebugProcess,(void *)offset,&pData,sizeof(void *),&accessBytes); sprintf(lptv->item.pszText,"%s %s(&H%X)",VarName,STRING_POINTEROFOBJECT,(ULONG_PTR)pData); lptv->item.iImage=4; lptv->item.iSelectedImage=4; hParent=TreeView_InsertItem(hVarTree,lptv); if(i2) VarList_Member(hVarTree,hParent,pData,type.GetClass(),1); return; } else{ if(type.GetBasicType()==MAKE_PTR_TYPE(DEF_SBYTE,1)||type.GetBasicType()==MAKE_PTR_TYPE(DEF_BYTE,1)){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&pData,sizeof(void *),&accessBytes)){ for(i2=0;;i2++){ if(!ReadProcessMemory(hDebugProcess,(void *)(pData+i2),&temporary[i2],1,&accessBytes)){ 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,(ULONG_PTR)pData,(ULONG_PTR)pData); else sprintf(lptv->item.pszText,"%s %d(&H%X) \"%s\"",VarName,(ULONG_PTR)pData,(ULONG_PTR)pData,temporary); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type.IsDouble()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&dbl,sizeof(double),&accessBytes)){ sprintf(lptv->item.pszText,"%s %.15g",VarName,dbl); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type.IsSingle()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&flt,sizeof(float),&accessBytes)){ sprintf(lptv->item.pszText,"%s %.6g",VarName,flt); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type.IsInt64()){ _int64 i64data; if(ReadProcessMemory(hDebugProcess,(void *)offset,&i64data,sizeof(_int64),&accessBytes)){ _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.IsQWord()||(type.IsPointer()&&PTR_SIZE==sizeof(_int64))){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&i64data,sizeof(_int64),&accessBytes)){ _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.IsLong()){ long l; if(ReadProcessMemory(hDebugProcess,(void *)offset,&l,sizeof(long),&accessBytes)){ sprintf(lptv->item.pszText,"%s %d(&H%X)",VarName,l,l); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type.IsDWord()||(type.IsPointer()&&PTR_SIZE==sizeof(long))){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&i64data,sizeof(_int64),&accessBytes)){ sprintf(lptv->item.pszText,"%s %u(&H%X)",VarName,(int)i64data,(int)i64data); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type.IsInteger()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&wData,sizeof(WORD),&accessBytes)){ 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.IsWord()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&wData,sizeof(WORD),&accessBytes)){ sprintf(lptv->item.pszText,"%s %u(&H%X)",VarName,wData,wData); } else sprintf(lptv->item.pszText,"%s %s",VarName,STRING_CANNOTACCESS); } else if(type.IsSByte()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&byteData,sizeof(BYTE),&accessBytes)){ 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.IsByte()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&byteData,sizeof(BYTE),&accessBytes)){ 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.IsBoolean()){ if(ReadProcessMemory(hDebugProcess,(void *)offset,&byteData,sizeof(BYTE),&accessBytes)){ if( byteData ) lstrcpy( temporary, "True" ); else lstrcpy( temporary, "False" ); wsprintf(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,LONG_PTR pTopOffset,const CClass &objClass,BOOL bPtr) { char VarData[VN_SIZE],VarName[VN_SIZE]; if( objClass.HasSuperClass() ) { 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; // 基底クラス sprintf(tv.item.pszText,"Inherits %s",objClass.GetSuperClass().GetName().c_str()); tv.item.iImage=1; tv.item.iSelectedImage=1; HTREEITEM hTempParent=TreeView_InsertItem(hVarTree,&tv); VarList_Member(hVarTree,hTempParent,pTopOffset,objClass.GetSuperClass(),0); } 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; BOOST_FOREACH( Member *pMember, objClass.GetDynamicMembers() ){ if(bPtr){ lstrcpy(VarName,"->"); lstrcat(VarName,pMember->GetName().c_str()); } else{ lstrcpy(VarName,"."); lstrcat(VarName,pMember->GetName().c_str()); } LONG_PTR offset; offset=objClass.GetMemberOffset( pMember->GetName().c_str() ); if( pMember->GetSubscripts().size() > 0 ){ //構造体内の配列 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, pMember->GetType(), pMember->GetSubscripts() ); } else{ //メンバ変数 VarList_Insert(hVarTree, &tv, VarName, pMember->GetType(), pTopOffset+offset); } } } int VarList_Array(HWND hVarTree,HTREEITEM hParent,LONG_PTR offset,const Type &type, const Subscripts &subscripts ){ int i,i2,i3,ElementNum,MemCounter,UseCount[255]; 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; for(i=0;i<(int)subscripts.size();i++){ UseCount[i]=0; } UseCount[i]=-2; MemCounter=0; i--; while(1){ UseCount[i]++; for(ElementNum=0;subscripts[i-ElementNum]GetScopeLevel()!=0){ if(rva_to_real(pVar->GetScopeStartAddress()) <= pobj_dti->lplpObp[0] && pobj_dti->lplpObp[0] < rva_to_real(pVar->GetScopeEndAddress())){ //範囲内 } else{ //範囲外 continue; } } if(!pobj_nv->bShow_DefaultSystem_Var){ if(memcmp(pVar->GetName().c_str(),"_System_",8)==0|| memcmp(pVar->GetName().c_str(),"_DebugSys_",10)==0|| memcmp(pVar->GetName().c_str(),"_PromptSys_",11)==0) continue; } if(!pobj_nv->bShow_Rad_Var){ if(memcmp(pVar->GetName().c_str(),"_RadSys_",8)==0) continue; } if(!pobj_nv->bShow_GUID_Var){ if(memcmp(pVar->GetName().c_str(),"GUID_",5)==0|| memcmp(pVar->GetName().c_str(),"IID_",4)==0|| memcmp(pVar->GetName().c_str(),"CLSID_",6)==0) continue; } //静的メンバ if(strstr(pVar->GetName().c_str(),".")) continue; if(pVar->IsArray()){ sprintf(temporary,"%s %s(&H%X)", pVar->GetName().c_str(), STRING_ARRAY, ImageBase+MemPos_RWSection+pVar->GetOffsetAddress()); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree_Global,&tv); VarList_Array( hVarTree_Global, hParent, (LONG_PTR)(ImageBase+MemPos_RWSection + pVar->GetOffsetAddress()), pVar->GetType(), pVar->GetSubscripts() ); } else{ VarList_Insert(hVarTree_Global, &tv, pVar->GetName().c_str(), pVar->GetType(), (LONG_PTR)(ImageBase+MemPos_RWSection+pVar->GetOffsetAddress())); } } } void RefreshLocalVar(void){ int i2; char temporary[VN_SIZE]; TV_INSERTSTRUCT tv; HTREEITEM hParent; LONG_PTR offset; SIZE_T accessBytes; LONG_PTR lpData; 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=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; if(pobj_dti->lplpSpBase[i2]==0) return; UserProc *pUserProc = NULL; compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); if(rva_to_real(pUserProc->GetBeginOpAddress()) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(pUserProc->GetEndOpAddress())){ break; } } if(!pUserProc) return; BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){ //スコープ外の場合は無視 int scopeBeginAddressRva = pUserProc->GetBeginOpAddress() + pVar->GetScopeStartAddress(); int scopeEndAddressRva = pUserProc->GetBeginOpAddress() + pVar->GetScopeEndAddress(); if(pVar->GetScopeLevel()!=0) { if( rva_to_real( scopeBeginAddressRva ) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real( scopeEndAddressRva ) ) { //範囲内 } else{ //範囲外 continue; } } if(pVar->IsArray()){ sprintf(temporary,"%s %s(&H%X)", pVar->GetName().c_str(), STRING_ARRAY, pobj_dti->lplpSpBase[i2]+pVar->GetOffsetAddress()); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree_Local,&tv); VarList_Array( hVarTree_Local, hParent, pobj_dti->lplpSpBase[i2] + pVar->GetOffsetAddress(), pVar->GetType(), pVar->GetSubscripts() ); } else{ offset=pobj_dti->lplpSpBase[i2]+pVar->GetOffsetAddress(); if(pVar->IsRef()){ ReadProcessMemory(hDebugProcess,(void *)offset,&lpData,sizeof(LONG_PTR),&accessBytes); offset=lpData; } VarList_Insert(hVarTree_Local,&tv, pVar->GetName().c_str(), pVar->GetType(), offset); } } ///////////////////////////// // Thisオブジェクトのリスト ///////////////////////////// TreeView_DeleteAllItems(hVarTree_This); if( pUserProc->IsGlobalProcedure() ) return; //Thisポインタを取得 LONG_PTR pThis; const Variable *pVar = pUserProc->GetLocalVars().Find( LexicalAnalyzer::FullNameToSymbol( "_System_LocalThis" ) ); if( !pVar ){ return; } lpData=pobj_dti->lplpSpBase[i2]+pVar->GetOffsetAddress(); ReadProcessMemory(hDebugProcess,(void *)lpData,&pThis,sizeof(LONG_PTR),&accessBytes); if( pUserProc->GetParentClassPtr()->HasSuperClass() ) { TV_INSERTSTRUCT tv; memset(&tv,0,sizeof(TV_INSERTSTRUCT)); tv.hInsertAfter=TVI_LAST; tv.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tv.hParent=NULL; tv.item.pszText=temporary; // 基底クラス sprintf(tv.item.pszText,"Inherits %s",pUserProc->GetParentClassPtr()->GetSuperClass().GetName().c_str()); tv.item.iImage=1; tv.item.iSelectedImage=1; HTREEITEM hTempParent=TreeView_InsertItem(hVarTree_This,&tv); VarList_Member(hVarTree_This,hTempParent,pThis,pUserProc->GetParentClassPtr()->GetSuperClass(),0); } BOOST_FOREACH( Member *pMember, pUserProc->GetParentClassPtr()->GetDynamicMembers() ){ offset=pUserProc->GetParentClassPtr()->GetMemberOffset( pMember->GetName().c_str()); if( pMember->GetSubscripts().size() > 0 ){ //配列 sprintf(temporary,"%s %s(&H%X)", pMember->GetName().c_str(), STRING_ARRAY, (ULONG_PTR)offset); tv.item.iImage=0; tv.item.iSelectedImage=0; hParent=TreeView_InsertItem(hVarTree_This,&tv); VarList_Array( hVarTree_This, hParent, pThis + offset, pMember->GetType(), pMember->GetSubscripts() ); } else{ VarList_Insert(hVarTree_This,&tv, pMember->GetName().c_str(), pMember->GetType(), pThis+offset); } } } 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){ char temporary[255],temp2[255]; //エスケープシーケンスをセット SetEscapeSequenceFormat(buffer); KillStringSpaces(buffer); //カッコを相互チェック if(!CheckParenthesis2(buffer)){ ListView_SetItemText(hListView,iItem,1,"式の解析に失敗"); return; } double dbl; _int64 i64data; Type resultType; bool isMemoryAccessError; if( !StaticCalculation(true, buffer,0,&i64data,resultType,1,&isMemoryAccessError) ){ ListView_SetItemText(hListView,iItem,1,"式の解析に失敗"); } else if(isMemoryAccessError){ ListView_SetItemText(hListView,iItem,1,"アクセスできません"); } else{ if(resultType.IsReal()){ memcpy(&dbl,&i64data,sizeof(double)); sprintf(temporary,"%.15g (&H%08X)",dbl,(int)dbl); } else if(resultType.Is64()){ _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;i2<(int)oldSourceLines.size()-2;i2++){ if((ULONG_PTR)(oldSourceLines[i2].GetNativeCodePos()+ImageBase+MemPos_CodeSection)<=pobj_dti->lplpObp[i3]&& pobj_dti->lplpObp[i3]<=(ULONG_PTR)(oldSourceLines[i2+1].GetNativeCodePos()+ImageBase+MemPos_CodeSection)) break; } if(i2==oldSourceLines.size()-1) pobj_dti->lpdwCp[i3]=-1; else { pobj_dti->lpdwCp[i3]=oldSourceLines[i2].GetSourceCodePos(); pobj_dti->lpdwSourceIndex[i3]=oldSourceLines[i2].GetSourceIndex(); } } 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]; pobj_dti->lpdwSourceIndex[i2]=pobj_dti->lpdwSourceIndex[i2+1]; } i3--; continue; } } std::string dummyStr; if(!compiler.GetObjectModule().GetSource( pobj_dti->lpdwSourceIndex[pobj_dti->iProcLevel] ).GetLineInfo( pobj_dti->lpdwCp[pobj_dti->iProcLevel], i2, dummyStr )){ extern HWND hMainDlg; //"デバッグ情報の取得に失敗" MessageBox(hMainDlg,STRING_DEBUG_FAILED,"ActiveBasic error",MB_OK); return 0; } ShowErrorLine(i2,dummyStr.c_str()); //プロシージャ コンボボックス SendMessage(hProcCombo,CB_RESETCONTENT,0,0); for(i2=pobj_dti->iProcLevel;i2>=0;i2--){ UserProc *pUserProc = NULL; compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); if(rva_to_real(pUserProc->GetBeginOpAddress()) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(pUserProc->GetEndOpAddress())) { lstrcpy(temporary,pUserProc->GetName().c_str()); break; } } if(!pUserProc){ if(i2==0){ lstrcpy(temporary,"Global"); pobj_dti->lplpSpBase[i2]=0; } else lstrcpy(temporary,"error"); } SendMessage(hProcCombo,CB_ADDSTRING,0,(LPARAM)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),(LPARAM)temporary); sscanf(temporary+2,"%X",&dwThreadID); extern DWORD _DebugSys_dwThreadID[256]; 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; switch(message){ case WM_COMMAND: if(HIWORD(wParam)==CBN_SELCHANGE){ i2=(int)SendMessage(hwnd,CB_GETCURSEL,0,0); std::string dummyStr; compiler.GetObjectModule().GetSource( pobj_dti->lpdwSourceIndex[pobj_dti->iProcLevel] ).GetLineInfo( pobj_dti->lpdwCp[pobj_dti->iProcLevel-i2], i3, dummyStr ); ShowErrorLine(i3,dummyStr.c_str()); RefreshLocalVar_with_WindowLock(); } break; } return CallWindowProc(OldProcComboProc,hwnd,message,wParam,lParam); } void InitVarList(DWORD dwThreadId){ extern HWND hDebugWnd; int i2,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)); /////////////////////////////////////////////// // 実行中のプロシージャのローカル変数をセット /////////////////////////////////////////////// i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0); i2=pobj_dti->iProcLevel-i2; if(pobj_dti->lplpSpBase[i2]){ UserProc *pUserProc = NULL; compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); if(rva_to_real(pUserProc->GetBeginOpAddress()) <= pobj_dti->lplpObp[i2] && pobj_dti->lplpObp[i2] < rva_to_real(pUserProc->GetEndOpAddress())){ break; } } if(pUserProc){ compiler.StartProcedureCompile( pUserProc ); } } //////////////////////// // 変数リストを再表示 //////////////////////// //処理時間を短くするため、一時的に非表示にする 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: dwStepRun=1; return 1; case IDC_DEBUG_STEPOVER: dwStepRun=2; 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,(DLGPROC)DebuggerButtonsProc); MoveWindow(hBase_ToolBar,50,0,20*BTNNUM_DEBUGGERTOOLBAR,22,1); extern WNDPROC OldThreadComboProc; OldThreadComboProc=(WNDPROC)GetWindowLongPtr(GetDlgItem(hwnd,IDC_THREADCOMBO),GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hwnd,IDC_THREADCOMBO),GWLP_WNDPROC,(LONG_PTR)ThreadComboProc); extern WNDPROC OldProcComboProc; OldProcComboProc=(WNDPROC)GetWindowLongPtr(GetDlgItem(hwnd,IDC_PROCCOMBO),GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hwnd,IDC_PROCCOMBO),GWLP_WNDPROC,(LONG_PTR)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,(WPARAM)hFont,0); OldTabProc=(WNDPROC)GetWindowLongPtr(hTab,GWLP_WNDPROC); SetWindowLongPtr(hTab,GWLP_WNDPROC,(LONG_PTR)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; if( program.IsClipCompileView() ){ 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)GetWindowLongPtr(GetDlgItem(hwnd,IDC_THREADCOMBO),GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hwnd,IDC_THREADCOMBO),GWLP_WNDPROC,(LONG_PTR)ThreadComboProc); extern WNDPROC OldProcComboProc; OldProcComboProc=(WNDPROC)GetWindowLongPtr(GetDlgItem(hwnd,IDC_PROCCOMBO),GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hwnd,IDC_PROCCOMBO),GWLP_WNDPROC,(LONG_PTR)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: dwStepRun=1; return 1; case IDC_STEPOVER: dwStepRun=2; 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; }