Update CtrlBreakpointList

This commit is contained in:
Kingcom 2013-09-29 11:19:13 +02:00
parent 9e2866d618
commit ed9c72e8eb
6 changed files with 163 additions and 231 deletions

View File

@ -131,11 +131,10 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
CtrlMemView *mem = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW)); CtrlMemView *mem = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
mem->setDebugger(_cpu); mem->setDebugger(_cpu);
breakpointList = new CtrlBreakpointList(); breakpointList = new CtrlBreakpointList(GetDlgItem(m_hDlg,IDC_BREAKPOINTLIST));
breakpointList->setCpu(cpu); breakpointList->setCpu(cpu);
breakpointList->setDisasm(ptr); breakpointList->setDisasm(ptr);
breakpointList->setDialogItem(GetDlgItem(m_hDlg,IDC_BREAKPOINTLIST)); breakpointList->reloadBreakpoints();
breakpointList->update();
threadList = new CtrlThreadList(GetDlgItem(m_hDlg,IDC_THREADLIST)); threadList = new CtrlThreadList(GetDlgItem(m_hDlg,IDC_THREADLIST));
threadList->reloadThreads(); threadList->reloadThreads();
@ -377,7 +376,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
} }
break; break;
case IDC_BREAKPOINTLIST: case IDC_BREAKPOINTLIST:
breakpointList->handleNotify(lParam); breakpointList->HandleNotify(lParam);
break; break;
case IDC_THREADLIST: case IDC_THREADLIST:
threadList->HandleNotify(lParam); threadList->HandleNotify(lParam);
@ -791,7 +790,7 @@ void CDisasm::SetDebugMode(bool _bDebug, bool switchPC)
{ {
Core_WaitInactive(TEMP_BREAKPOINT_WAIT_MS); Core_WaitInactive(TEMP_BREAKPOINT_WAIT_MS);
CBreakPoints::ClearTemporaryBreakPoints(); CBreakPoints::ClearTemporaryBreakPoints();
breakpointList->update(); breakpointList->reloadBreakpoints();
threadList->reloadThreads(); threadList->reloadThreads();
stackTraceView->loadStackTrace(); stackTraceView->loadStackTrace();
updateThreadLabel(false); updateThreadLabel(false);

View File

@ -61,7 +61,7 @@ public:
{ {
UpdateDialog(true); UpdateDialog(true);
SetDebugMode(Core_IsStepping(), false); SetDebugMode(Core_IsStepping(), false);
breakpointList->update(); breakpointList->reloadBreakpoints();
}; };
void UpdateDialog(bool _bComplete = false); void UpdateDialog(bool _bComplete = false);
// SetDebugMode // SetDebugMode

View File

@ -230,114 +230,60 @@ const char* CtrlThreadList::getCurrentThreadName()
// CtrlBreakpointList // CtrlBreakpointList
// //
void CtrlBreakpointList::setDialogItem(HWND hwnd) CtrlBreakpointList::CtrlBreakpointList(HWND hwnd): GenericListControl(hwnd,breakpointColumns,BPL_COLUMNCOUNT)
{ {
wnd = hwnd; SetSendInvalidRows(true);
Update();
SetWindowLongPtr(wnd,GWLP_USERDATA,(LONG_PTR)this);
oldProc = (WNDPROC) SetWindowLongPtr(wnd,GWLP_WNDPROC,(LONG_PTR)wndProc);
SendMessage(wnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.iSubItem = 0;
lvc.fmt = LVCFMT_LEFT;
RECT rect;
GetWindowRect(wnd,&rect);
int totalListSize = (rect.right-rect.left-20);
for (int i = 0; i < BPL_COLUMNCOUNT; i++)
{
lvc.cx = breakpointColumns[i].size * totalListSize;
lvc.pszText = breakpointColumns[i].name;
ListView_InsertColumn(wnd, i, &lvc);
}
} }
LRESULT CALLBACK CtrlBreakpointList::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) bool CtrlBreakpointList::WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue)
{ {
CtrlBreakpointList* bp = (CtrlBreakpointList*) GetWindowLongPtr(hwnd,GWLP_USERDATA); switch(msg)
switch(message)
{ {
case WM_SIZE:
{
int width = LOWORD(lParam);
RECT rect;
GetWindowRect(hwnd,&rect);
int totalListSize = (rect.right-rect.left-20);
for (int i = 0; i < BPL_COLUMNCOUNT; i++)
{
ListView_SetColumnWidth(hwnd,i,breakpointColumns[i].size * totalListSize);
}
}
break;
case WM_KEYDOWN: case WM_KEYDOWN:
returnValue = 0;
if(wParam == VK_RETURN) if(wParam == VK_RETURN)
{ {
int index = ListView_GetSelectionMark(hwnd); int index = GetSelectedIndex();
bp->editBreakpoint(index); editBreakpoint(index);
return 0; return true;
} else if (wParam == VK_DELETE) } else if (wParam == VK_DELETE)
{ {
int index = ListView_GetSelectionMark(hwnd); int index = GetSelectedIndex();
bp->removeBreakpoint(index); removeBreakpoint(index);
return 0; return true;
} else if (wParam == VK_TAB) } else if (wParam == VK_TAB)
{ {
SendMessage(GetParent(hwnd),WM_DEB_TABPRESSED,0,0); SendMessage(GetParent(GetHandle()),WM_DEB_TABPRESSED,0,0);
return 0; return true;
} else if (wParam == VK_SPACE) } else if (wParam == VK_SPACE)
{ {
int index = ListView_GetSelectionMark(hwnd); int index = GetSelectedIndex();
bp->toggleEnabled(index); toggleEnabled(index);
return true;
} }
break; break;
case WM_GETDLGCODE: case WM_GETDLGCODE:
if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN) if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN)
{ {
if (wParam == VK_TAB || wParam == VK_RETURN) return DLGC_WANTMESSAGE; if (wParam == VK_TAB || wParam == VK_RETURN)
{
returnValue = DLGC_WANTMESSAGE;
return true;
}
} }
break; break;
}; }
return (LRESULT)CallWindowProc((WNDPROC)bp->oldProc,hwnd,message,wParam,lParam); return false;
} }
void CtrlBreakpointList::update() void CtrlBreakpointList::reloadBreakpoints()
{ {
// Update the items we're displaying from the debugger. // Update the items we're displaying from the debugger.
displayedBreakPoints_ = CBreakPoints::GetBreakpoints(); displayedBreakPoints_ = CBreakPoints::GetBreakpoints();
displayedMemChecks_= CBreakPoints::GetMemChecks(); displayedMemChecks_= CBreakPoints::GetMemChecks();
Update();
int breakpointCount = getTotalBreakpointCount();
int items = ListView_GetItemCount(wnd);
while (items < breakpointCount)
{
LVITEM lvI;
lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
lvI.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
lvI.stateMask = 0;
lvI.iSubItem = 0;
lvI.state = 0;
lvI.iItem = items;
lvI.iImage = items;
ListView_InsertItem(wnd, &lvI);
items++;
}
while (items > breakpointCount)
{
ListView_DeleteItem(wnd,--items);
}
InvalidateRect(wnd,NULL,true);
UpdateWindow(wnd);
} }
void CtrlBreakpointList::editBreakpoint(int itemIndex) void CtrlBreakpointList::editBreakpoint(int itemIndex)
@ -346,7 +292,7 @@ void CtrlBreakpointList::editBreakpoint(int itemIndex)
int index = getBreakpointIndex(itemIndex, isMemory); int index = getBreakpointIndex(itemIndex, isMemory);
if (index == -1) return; if (index == -1) return;
BreakpointWindow win(wnd,cpu); BreakpointWindow win(GetHandle(),cpu);
if (isMemory) if (isMemory)
{ {
auto mem = displayedMemChecks_[index]; auto mem = displayedMemChecks_[index];
@ -465,138 +411,119 @@ int CtrlBreakpointList::getBreakpointIndex(int itemIndex, bool& isMemory)
return -1; return -1;
} }
void CtrlBreakpointList::handleNotify(LPARAM lParam) void CtrlBreakpointList::GetColumnText(wchar_t* dest, int row, int col)
{ {
const LPNMHDR header = (LPNMHDR)lParam; bool isMemory;
if (header->code == NM_DBLCLK) int index = getBreakpointIndex(row,isMemory);
{ if (index == -1) return;
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
gotoBreakpointAddress(item->iItem);
return;
}
if (header->code == NM_RCLICK)
{
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
showBreakpointMenu(item->iItem, item->ptAction);
return;
}
if (header->code == LVN_GETDISPINFO)
{
NMLVDISPINFO *dispInfo = (NMLVDISPINFO *)lParam;
bool isMemory; switch (col)
int index = getBreakpointIndex(dispInfo->item.iItem,isMemory); {
if (index == -1) return; case BPL_TYPE:
breakpointText = L"";
switch (dispInfo->item.iSubItem)
{ {
case BPL_TYPE: if (isMemory) {
{ switch (displayedMemChecks_[index].cond) {
if (isMemory) { case MEMCHECK_READ:
switch (displayedMemChecks_[index].cond) { wcscpy(dest,L"Read");
case MEMCHECK_READ: break;
breakpointText = L"Read"; case MEMCHECK_WRITE:
break; wcscpy(dest,L"Write");
case MEMCHECK_WRITE: break;
breakpointText = L"Write"; case MEMCHECK_READWRITE:
break; wcscpy(dest,L"Read/Write");
case MEMCHECK_READWRITE: break;
breakpointText = L"Read/Write";
break;
}
} else {
breakpointText = L"Execute";
} }
} else {
wcscpy(dest,L"Execute");
} }
break;
case BPL_OFFSET:
{
wchar_t temp[256];
if (isMemory) {
wsprintf(temp,L"0x%08X",displayedMemChecks_[index].start);
} else {
wsprintf(temp,L"0x%08X",displayedBreakPoints_[index].addr);
}
breakpointText = temp;
}
break;
case BPL_SIZELABEL:
{
if (isMemory) {
auto mc = displayedMemChecks_[index];
wchar_t temp[256];
if (mc.end == 0)
wsprintf(temp,L"0x%08X",1);
else
wsprintf(temp,L"0x%08X",mc.end-mc.start);
breakpointText = temp;
} else {
const char* sym = cpu->findSymbolForAddress(displayedBreakPoints_[index].addr);
if (sym != NULL)
{
breakpointText = ConvertUTF8ToWString(sym);
} else {
breakpointText = L"-";
}
}
}
break;
case BPL_OPCODE:
{
if (isMemory) {
breakpointText = L"-";
} else {
char temp[256];
disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp);
breakpointText = ConvertUTF8ToWString(temp);
}
}
break;
case BPL_CONDITION:
{
if (isMemory || displayedBreakPoints_[index].hasCond == false) {
breakpointText = L"-";
} else {
breakpointText = ConvertUTF8ToWString(displayedBreakPoints_[index].cond.expressionString);
}
}
break;
case BPL_HITS:
{
if (isMemory) {
wchar_t temp[256];
wsprintf(temp,L"%d",displayedMemChecks_[index].numHits);
breakpointText = temp;
} else {
breakpointText = L"-";
}
}
break;
case BPL_ENABLED:
{
if (isMemory) {
breakpointText = displayedMemChecks_[index].result & MEMCHECK_BREAK ? L"True" : L"False";
} else {
breakpointText = displayedBreakPoints_[index].enabled ? L"True" : L"False";
}
}
break;
default:
return;
} }
break;
if (breakpointText.empty()) case BPL_OFFSET:
breakpointText = L"Invalid"; {
dispInfo->item.pszText = &breakpointText[0]; if (isMemory) {
wsprintf(dest,L"0x%08X",displayedMemChecks_[index].start);
} else {
wsprintf(dest,L"0x%08X",displayedBreakPoints_[index].addr);
}
}
break;
case BPL_SIZELABEL:
{
if (isMemory) {
auto mc = displayedMemChecks_[index];
if (mc.end == 0)
wsprintf(dest,L"0x%08X",1);
else
wsprintf(dest,L"0x%08X",mc.end-mc.start);
} else {
const char* sym = cpu->findSymbolForAddress(displayedBreakPoints_[index].addr);
if (sym != NULL)
{
std::wstring s = ConvertUTF8ToWString(sym);
wcscpy(dest,s.c_str());
} else {
wcscpy(dest,L"-");
}
}
}
break;
case BPL_OPCODE:
{
if (isMemory) {
wcscpy(dest,L"-");
} else {
char temp[256];
disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp);
std::wstring s = ConvertUTF8ToWString(temp);
wcscpy(dest,s.c_str());
}
}
break;
case BPL_CONDITION:
{
if (isMemory || displayedBreakPoints_[index].hasCond == false) {
wcscpy(dest,L"-");
} else {
std::wstring s = ConvertUTF8ToWString(displayedBreakPoints_[index].cond.expressionString);
wcscpy(dest,s.c_str());
}
}
break;
case BPL_HITS:
{
if (isMemory) {
wsprintf(dest,L"%d",displayedMemChecks_[index].numHits);
} else {
wsprintf(dest,L"-");
}
}
break;
case BPL_ENABLED:
{
if (isMemory) {
wsprintf(dest,displayedMemChecks_[index].result & MEMCHECK_BREAK ? L"True" : L"False");
} else {
wsprintf(dest,displayedBreakPoints_[index].enabled ? L"True" : L"False");
}
}
break;
} }
} }
void CtrlBreakpointList::OnDoubleClick(int itemIndex, int column)
{
gotoBreakpointAddress(itemIndex);
}
void CtrlBreakpointList::OnRightClick(int itemIndex, int column, const POINT& point)
{
showBreakpointMenu(itemIndex,point);
}
void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt) void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
{ {
POINT screenPt(pt); POINT screenPt(pt);
ClientToScreen(wnd, &screenPt); ClientToScreen(GetHandle(), &screenPt);
bool isMemory; bool isMemory;
int index = getBreakpointIndex(itemIndex, isMemory); int index = getBreakpointIndex(itemIndex, isMemory);
@ -604,11 +531,11 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
{ {
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_NEWBREAKPOINT); HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_NEWBREAKPOINT);
switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, wnd, 0)) switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, GetHandle(), 0))
{ {
case ID_DISASM_ADDNEWBREAKPOINT: case ID_DISASM_ADDNEWBREAKPOINT:
{ {
BreakpointWindow bpw(wnd,cpu); BreakpointWindow bpw(GetHandle(),cpu);
if (bpw.exec()) bpw.addBreakpoint(); if (bpw.exec()) bpw.addBreakpoint();
} }
break; break;
@ -629,7 +556,7 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (bpPrev.enabled ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (bpPrev.enabled ? MF_CHECKED : MF_UNCHECKED));
} }
switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, wnd, 0)) switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, GetHandle(), 0))
{ {
case ID_DISASM_DISABLEBREAKPOINT: case ID_DISASM_DISABLEBREAKPOINT:
if (isMemory) { if (isMemory) {
@ -643,7 +570,7 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
break; break;
case ID_DISASM_ADDNEWBREAKPOINT: case ID_DISASM_ADDNEWBREAKPOINT:
{ {
BreakpointWindow bpw(wnd,cpu); BreakpointWindow bpw(GetHandle(),cpu);
if (bpw.exec()) bpw.addBreakpoint(); if (bpw.exec()) bpw.addBreakpoint();
} }
break; break;

View File

@ -25,10 +25,27 @@ private:
class CtrlDisAsmView; class CtrlDisAsmView;
class CtrlBreakpointList class CtrlBreakpointList: public GenericListControl
{ {
HWND wnd; public:
WNDPROC oldProc; CtrlBreakpointList(HWND hwnd);
void reloadBreakpoints();
void setCpu(DebugInterface* cpu)
{
this->cpu = cpu;
};
void setDisasm(CtrlDisAsmView* disasm)
{
this->disasm = disasm;
};
void showMenu(int itemIndex, const POINT &pt);
protected:
virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue);
virtual void GetColumnText(wchar_t* dest, int row, int col);
virtual int GetRowCount() { return getTotalBreakpointCount(); };
virtual void OnDoubleClick(int itemIndex, int column);
virtual void OnRightClick(int itemIndex, int column, const POINT& point);
private:
std::vector<BreakPoint> displayedBreakPoints_; std::vector<BreakPoint> displayedBreakPoints_;
std::vector<MemCheck> displayedMemChecks_; std::vector<MemCheck> displayedMemChecks_;
std::wstring breakpointText; std::wstring breakpointText;
@ -42,20 +59,6 @@ class CtrlBreakpointList
int getBreakpointIndex(int itemIndex, bool& isMemory); int getBreakpointIndex(int itemIndex, bool& isMemory);
void showBreakpointMenu(int itemIndex, const POINT &pt); void showBreakpointMenu(int itemIndex, const POINT &pt);
void toggleEnabled(int itemIndex); void toggleEnabled(int itemIndex);
public:
void setCpu(DebugInterface* cpu)
{
this->cpu = cpu;
};
void setDisasm(CtrlDisAsmView* disasm)
{
this->disasm = disasm;
};
void update();
void setDialogItem(HWND hwnd);
void handleNotify(LPARAM lParam);
void showMenu(int itemIndex, const POINT &pt);
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
}; };
class CtrlStackTraceView class CtrlStackTraceView

View File

@ -116,6 +116,7 @@ GenericListControl::GenericListControl(HWND hwnd, const GenericListViewColumn* _
ListView_InsertColumn(handle, i, &lvc); ListView_InsertColumn(handle, i, &lvc);
} }
SetSendInvalidRows(false);
valid = true; valid = true;
} }
@ -126,7 +127,7 @@ void GenericListControl::HandleNotify(LPARAM lParam)
if (mhdr->code == NM_DBLCLK) if (mhdr->code == NM_DBLCLK)
{ {
LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam; LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
if (item->iItem != -1 && item->iItem < GetRowCount()) if ((item->iItem != -1 && item->iItem < GetRowCount()) || sendInvalidRows)
OnDoubleClick(item->iItem,item->iSubItem); OnDoubleClick(item->iItem,item->iSubItem);
return; return;
} }
@ -134,7 +135,7 @@ void GenericListControl::HandleNotify(LPARAM lParam)
if (mhdr->code == NM_RCLICK) if (mhdr->code == NM_RCLICK)
{ {
const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam; const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam;
if (item->iItem != -1 && item->iItem < GetRowCount()) if ((item->iItem != -1 && item->iItem < GetRowCount()) || sendInvalidRows)
OnRightClick(item->iItem,item->iSubItem,item->ptAction); OnRightClick(item->iItem,item->iSubItem,item->ptAction);
return; return;
} }

View File

@ -26,6 +26,7 @@ public:
void Update(); void Update();
int GetSelectedIndex(); int GetSelectedIndex();
HWND GetHandle() { return handle; }; HWND GetHandle() { return handle; };
void SetSendInvalidRows(bool enabled) { sendInvalidRows = enabled; };
protected: protected:
virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) = 0; virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) = 0;
virtual void GetColumnText(wchar_t* dest, int row, int col) = 0; virtual void GetColumnText(wchar_t* dest, int row, int col) = 0;
@ -42,4 +43,5 @@ private:
int columnCount; int columnCount;
wchar_t stringBuffer[256]; wchar_t stringBuffer[256];
bool valid; bool valid;
bool sendInvalidRows;
}; };