📄 thredwnd.c
字号:
/*
Copyright 2001-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
**********************************************************************
THREDWND.C holds the code for the thread display window
**********************************************************************
*/
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>
#include "header.h"
#include "operands.h"
#include "opcodes.h"
#include <ctype.h>
#include "cvinfo.h"
extern HWND hwndSourceTab;
extern THREAD *StoppedThread;
extern HINSTANCE hInstance;
extern HWND hwndClient, hwndStatus, hwndFrame;
extern PROCESS DebugProcess;
extern enum DebugState uState;
HWND hwndThread;
static char szThreadClassName[] = "xccThreadClass";
static char szThreadBlankClassName[] = "xccThreadClass2";
static HWND hwndCtrl, hwndBlank;
static int DisplayThreads;
static LOGFONT fontdata =
{
16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH |
FF_DONTCARE, "Courier New"
};
static HFONT ThreadFont;
static int ThreadAddress, ThreadLines;
static int curpos;
static char *szThreadTitle = "Thread Window";
void ThreadDoPaint(HWND hwnd)
{
int i;
THREAD *list = DebugProcess.threads;
int Address = ThreadAddress;
char buf[256], *p;
HBRUSH wbrush = GetStockObject(WHITE_BRUSH);
PAINTSTRUCT ps;
CONTEXT context;
HDC dc;
HFONT oldFont;
RECT rect;
int lines;
GetClientRect(hwnd, &rect);
lines = (rect.bottom - rect.top) / 16;
dc = BeginPaint(hwnd, &ps);
FillRect(dc, &rect, wbrush);
SelectObject(dc, ThreadFont);
while (list && Address)
{
list = list->next;
Address -= 1;
}
if (DisplayThreads)
{
for (i = 0; i < lines && list; i++)
{
char name[200];
int eip = list->regs.Eip;
if (!FindFunctionName(name, eip))
name[0] = 0;
if (list->idThread == StoppedThread->idThread)
strcat(name, "*");
sprintf(buf, "%08x %08X: %s", list->idThread, eip, name);
if (i == curpos)
{
int oldtext = GetTextColor(dc);
int oldbk = GetBkColor(dc);
SetTextColor(dc, oldbk);
SetBkColor(dc, oldtext);
TextOut(dc, 0, i *16+rect.top, buf, strlen(buf));
SetTextColor(dc, oldtext);
SetBkColor(dc, oldbk);
}
else
TextOut(dc, 0, i *16+rect.top, buf, strlen(buf));
list = list->next;
\
}
}
SelectObject(dc, oldFont);
EndPaint(hwnd, &ps);
}
//-------------------------------------------------------------------------
LRESULT CALLBACK _export ThreadBlankProc(HWND hwnd, UINT iMessage, WPARAM
wParam, LPARAM lParam)
{
int i, lines;
RECT r;
char module[256];
THREAD *sl;
switch (iMessage)
{
case WM_PAINT:
ThreadDoPaint(hwnd);
return 0;
case WM_RESTACK:
if (DisplayThreads)
{
int i = 0;
THREAD *list = DebugProcess.threads;
while (list)
i++, list = list->next;
SetScrollRange(hwnd, SB_VERT, 0, i - 1, TRUE);
ThreadLines = i;
ThreadAddress = 0;
}
else
SetScrollRange(hwnd, SB_VERT, 0, 1, TRUE);
break;
case WM_SETFOCUS:
SendMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0);
break;
case WM_KILLFOCUS:
break;
case WM_LBUTTONDOWN:
lines = HIWORD(lParam);
if (lines / 16+ThreadAddress < ThreadLines)
{
curpos = lines / 16;
InvalidateRect(hwnd, 0, TRUE);
}
// fall through
case WM_RBUTTONDOWN:
SetFocus(hwnd);
break;
case WM_LBUTTONDBLCLK:
PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0);
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_RETURN:
sl = DebugProcess.threads;
lines = ThreadAddress + curpos;
while (sl && lines)
{
sl = sl->next;
lines--;
}
if (sl)
{
int eip = sl->regs.Eip;
if (GetBreakpointLine(eip, module, &lines))
{
char *p;
char nmodule[256];
static DWINFO x;
FindModuleName(nmodule, module);
strcpy(x.dwName, nmodule);
p = strrchr(nmodule, '\\');
if (p)
strcpy(x.dwTitle, p + 1);
else
strcpy(x.dwTitle, nmodule);
x.dwLineNo = lines;
CreateDrawWindow(&x);
}
}
break;
case VK_UP:
if (curpos)
curpos--;
else if (ThreadAddress)
ThreadAddress--;
InvalidateRect(hwnd, 0, 0);
break;
case VK_DOWN:
GetClientRect(hwnd, &r);
lines = r.bottom / 16;
if (curpos < ThreadLines - 1)
{
if (curpos < lines - 1)
curpos++;
else if (ThreadAddress < ThreadLines - 1)
ThreadAddress++;
InvalidateRect(hwnd, 0, TRUE);
}
break;
}
break;
case WM_VSCROLL:
GetClientRect(hwnd, &r);
lines = r.bottom / 16;
switch (LOWORD(wParam))
{
case SB_BOTTOM:
ThreadAddress = ThreadLines - (lines *1);
break;
case SB_TOP:
ThreadAddress = 0;
break;
case SB_ENDSCROLL:
return 0;
case SB_LINEDOWN:
ThreadAddress += 1;
break;
case SB_LINEUP:
ThreadAddress -= 1;
break;
case SB_PAGEDOWN:
ThreadAddress += 1 *(lines - 1);
break;
case SB_PAGEUP:
ThreadAddress -= 1 *(lines - 1);
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
ThreadAddress = HIWORD(wParam);
break;
}
if (ThreadAddress < 0)
ThreadAddress = 0;
if (ThreadAddress >= ThreadLines)
ThreadAddress = ThreadLines - 1;
InvalidateRect(hwnd, 0, 0);
SetScrollPos(hwnd, SB_VERT, ThreadAddress, TRUE);
return 0;
}
return DefWindowProc(hwnd, iMessage, wParam, lParam);
}
//-------------------------------------------------------------------------
LRESULT CALLBACK _export ThreadProc(HWND hwnd, UINT iMessage, WPARAM wParam,
LPARAM lParam)
{
int i, lines;
HDC dc;
TEXTMETRIC metric;
DEBUG_EVENT *xc;
HFONT oldFont;
LOGBRUSH brushstr;
RECT r;
char module[256];
THREAD *sl;
switch (iMessage)
{
case WM_MDIACTIVATE:
SendMessage(hwndCtrl, LCF_SETACTIVE, 0, lParam == (LPARAM)hwnd);
if (lParam == (LPARAM)hwnd)
{
SendMessage(hwndSourceTab, WM_SETACTIVETAB, 0, (LPARAM)hwnd);
SetFocus(hwndBlank);
}
return TRUE;
case WM_SETFOCUS:
SetFocus(hwndBlank);
break;
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
case WM_COMMAND:
break;
case WM_RESTACK:
DisplayThreads = uState != notDebugging && wParam;
SendMessage(hwndBlank, WM_RESTACK, wParam, lParam);
break;
case WM_CREATE:
hwndThread = hwnd;
GetClientRect(hwnd, &r);
hwndCtrl = CreateControlWindow(DID_THREADWND, hwnd, &r, (int)(
(LPMDICREATESTRUCT)(*(int*)lParam))->lParam, szThreadTitle);
ThreadFont = CreateFontIndirect(&fontdata);
SendMessage(hwndCtrl, LCF_ADJUSTRECT, 0, (LPARAM) &r);
hwndBlank = CreateWindow(szThreadBlankClassName, 0, WS_CHILD +
WS_VSCROLL + WS_CLIPSIBLINGS + WS_BORDER + WS_VISIBLE, r.left,
r.top, r.right - r.left, r.bottom - r.top, hwndCtrl, 0,
hInstance, 0);
break;
case WM_CLOSE:
dmgrHideWindow(DID_THREADWND, TRUE);
return 0;
case WM_DESTROY:
dmgrRemoveClient((CCW_params*)GetWindowLong(hwndCtrl, 0));
DestroyWindow(hwndBlank);
hwndThread = 0;
DeleteObject(ThreadFont);
break;
case WM_INITMENUPOPUP:
return 0;
case WM_SIZE:
r.left = r.top = 0;
r.right = LOWORD(lParam);
r.bottom = HIWORD(lParam);
MoveWindow(hwndCtrl, 0, 0, r.right, r.bottom, TRUE);
SendMessage(hwndCtrl, LCF_ADJUSTRECT, 0, (LPARAM) &r);
MoveWindow(hwndBlank, r.left, r.top, r.right - r.left, r.bottom -
r.top, TRUE);
break;
default:
break;
}
return DefMDIChildProc(hwnd, iMessage, wParam, lParam);
}
//-------------------------------------------------------------------------
void RegisterThreadWindow(void)
{
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.style = CS_HREDRAW + CS_VREDRAW + CS_DBLCLKS;
wc.lpfnWndProc = &ThreadProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szThreadClassName;
RegisterClass(&wc);
wc.lpfnWndProc = &ThreadBlankProc;
wc.lpszClassName = szThreadBlankClassName;
RegisterClass(&wc);
}
//-------------------------------------------------------------------------
HWND CreateThreadWindow(void)
{
CCW_params p;
MDICREATESTRUCT mc;
HWND rv;
RECT r;
if (hwndThread)
{
SendMessage(hwndThread, WM_SETFOCUS, 0, 0);
return hwndThread;
}
GetClientRect(hwndClient, &r);
mc.szClass = szThreadClassName;
mc.szTitle = szThreadTitle;
mc.hOwner = hInstance;
mc.x = CW_USEDEFAULT;
mc.y = CW_USEDEFAULT;
mc.cx = 30 * 8;
mc.cy = 19 * 8;
mc.style = WS_CLIPCHILDREN | WS_CHILD | WS_CLIPSIBLINGS | WS_DLGFRAME,
mc.lParam = (LPARAM)0;
rv = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM) &mc);
return rv;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -