Windows2000/private/windbg64/windbg/ncmdwin.c
2020-09-30 17:12:32 +02:00

489 lines
14 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
ncmdwin.c
Abstract:
New command window UI.
Author:
Carlos Klapp (a-caklap) 1997
Environment:
Win32, User Mode
--*/
#include "precomp.h"
#pragma hdrstop
#if defined( NEW_WINDOWING_CODE )
// Minimum window size
#define MINWND_SIZE 200
// Static data for structures
LPCSTR _COMMONWIN_DATA::lpcszName_CommonWinData = "Common Win Data Struct";
LPCSTR _CMDWIN_DATA::lpcszName_CmdWinData = "Cmd Win Data Struct";
PCOMMONWIN_DATA
GetCommonWinData(
HWND hwnd
)
{
if (!hwnd) {
return NULL;
}
PCOMMONWIN_DATA pWinData = (PCOMMONWIN_DATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
// Sanity check.
if (pWinData) {
pWinData->Validate();
}
return pWinData;
}
PCOMMONWIN_DATA
SetCommonWinData(
HWND hwnd,
PCOMMONWIN_DATA pWinData_New
)
{
PCOMMONWIN_DATA pWinData_Old = (PCOMMONWIN_DATA) SetWindowLongPtr(hwnd,
GWLP_USERDATA,
(LONG_PTR) pWinData_New
);
return pWinData_Old;
}
PCMDWIN_DATA
GetCmdWinData(
HWND hwnd
)
{
PCMDWIN_DATA pCmdWinData = (PCMDWIN_DATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
// Sanity check.
if (pCmdWinData) {
pCmdWinData->Validate();
}
return pCmdWinData;
}
PCMDWIN_DATA
SetCmdWinData(
HWND hwnd,
PCMDWIN_DATA pCmdWinData_New
)
{
PCMDWIN_DATA pCmdWinData_Old =
(PCMDWIN_DATA) (PVOID)
SetCommonWinData(
hwnd,
(PCOMMONWIN_DATA) (PVOID) pCmdWinData_New
);
// Sanity check.
if (pCmdWinData_Old) {
pCmdWinData_Old->Validate();
}
if (pCmdWinData_New) {
pCmdWinData_New->Validate();
}
return pCmdWinData_Old;
}
PCALLSWIN_DATA
GetCallsWinData(
HWND hwnd
)
{
PCALLSWIN_DATA pCallsWinData = (PCALLSWIN_DATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
// Sanity check.
if (pCallsWinData) {
pCallsWinData->Validate();
}
return pCallsWinData;
}
PCALLSWIN_DATA
SetCallsWinData(
HWND hwnd,
PCALLSWIN_DATA pCallsWinData_New
)
{
PCALLSWIN_DATA pCallsWinData_Old =
(PCALLSWIN_DATA) (PVOID)
SetCommonWinData(
hwnd,
(PCOMMONWIN_DATA) (PVOID) pCallsWinData_New
);
// Sanity check.
if (pCallsWinData_Old) {
pCallsWinData_Old->Validate();
}
if (pCallsWinData_New) {
pCallsWinData_New->Validate();
}
return pCallsWinData_Old;
}
HWND
NewCmd_CreateWindow(
HWND hwndParent
)
/*++
Routine Description:
Create the command window.
Arguments:
hwndParent - The parent window to the command window. In an MDI document,
this is usually the handle to the MDI client window: g_hwndMDIClient
Return Value:
If successful, creates a valid window handle to the new command window.
NULL if the window was not created.
--*/
{
char szClassName[MAX_MSG_TXT];
char szWinTitle[MAX_MSG_TXT];
CREATESTRUCT cs;
HWND hwnd;
// get class name
Dbg(LoadString(g_hInst, SYS_NewCmd_wClass, szClassName, sizeof(szClassName)));
// Get the title
{
char sz[MAX_MSG_TXT];
Dbg(LoadString(g_hInst, SYS_CmdWin_Title, sz, sizeof(sz)));
RemoveMnemonic(sz, szWinTitle);
}
ZeroMemory(&cs, sizeof(cs));
return CreateWindowEx(
WS_EX_MDICHILD | WS_EX_CONTROLPARENT, // Extended style
szClassName, // class name
szWinTitle, // title
WS_CLIPCHILDREN | WS_CLIPSIBLINGS
| WS_OVERLAPPEDWINDOW | WS_VISIBLE, // style
CW_USEDEFAULT, // x
CW_USEDEFAULT, // y
CW_USEDEFAULT, // width
CW_USEDEFAULT, // height
hwndParent, // parent
NULL, // menu
g_hInst, // hInstance
NULL // user defined data
);
}
LRESULT
CALLBACK
NewCmd_WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
PCMDWIN_DATA pCmdWinData = GetCmdWinData(hwnd);
switch (uMsg) {
default:
return DefMDIChildProc(hwnd, uMsg, wParam, lParam);
case WM_CREATE:
{
RECT rc;
Assert(NULL == pCmdWinData);
pCmdWinData = new CMDWIN_DATA;
if (!pCmdWinData) {
return -1; // Fail window creation
}
pCmdWinData->hwndHistory = CreateWindowEx(
WS_EX_CLIENTEDGE, // Extended style
"RichEdit", // class name
NULL, // title
WS_CLIPSIBLINGS
| WS_CHILD | WS_VISIBLE
| WS_HSCROLL | WS_VSCROLL
| ES_AUTOHSCROLL | ES_AUTOVSCROLL
| ES_MULTILINE | ES_READONLY, // style
0, // x
0, // y
100, //CW_USEDEFAULT, // width
100, //CW_USEDEFAULT, // height
hwnd, // parent
(HMENU) IDC_RICHEDIT_CMD_HISTORY, // control id
g_hInst, // hInstance
NULL); // user defined data
if (!pCmdWinData->hwndHistory) {
delete pCmdWinData;
return -1; // Fail window creation
}
pCmdWinData->hwndEdit = CreateWindowEx(
WS_EX_CLIENTEDGE, // Extended style
"RichEdit", // class name
NULL, // title
WS_CLIPSIBLINGS
| WS_CHILD | WS_VISIBLE
| WS_VSCROLL | ES_AUTOVSCROLL
| ES_MULTILINE, // style
0, // x
100, // y
100, //CW_USEDEFAULT, // width
100, //CW_USEDEFAULT, // height
hwnd, // parent
(HMENU) IDC_RICHEDIT_CMD_EDIT, // control id
g_hInst, // hInstance
NULL); // user defined data
if (!pCmdWinData->hwndEdit) {
delete pCmdWinData;
return -1; // Fail window creation
}
if (pCmdWinData->bHistoryActive) {
SetFocus(pCmdWinData->hwndHistory);
} else {
SetFocus(pCmdWinData->hwndEdit);
}
GetClientRect(hwnd, &rc);
pCmdWinData->nDividerPosition = rc.bottom / 2;
g_DebuggerWindows.hwndCmd = hwnd;
// Tell the edit controls, that we want notification of keyboard input
// This is so we can process the enter key, and then send that text into the
// History window.
SendMessage(pCmdWinData->hwndEdit, EM_SETEVENTMASK, 0, ENM_KEYEVENTS);
// store this in the window
SetCmdWinData(hwnd, pCmdWinData);
}
return 0;
case WU_INITDEBUGWIN:
PCTRLC_HANDLER
AddCtrlCHandler(
CTRLC_HANDLER_PROC pfnFunc,
DWORD dwParam
);
BOOL
DoCtrlCAsyncStop(
DWORD dwParam
);
// set up ctrlc handler
AddCtrlCHandler(DoCtrlCAsyncStop, FALSE);
// Initialize cmd processor, show initial prompt.
CmdSetDefaultCmdProc();
if (arNone != AutoRun) {
CmdDoPrompt(TRUE, TRUE);
}
return FALSE;
case WM_NOTIFY:
{
switch (wParam) {
case IDC_RICHEDIT_CMD_EDIT:
{
MSGFILTER * lpMsgFilter = (MSGFILTER *) lParam;
if (EN_MSGFILTER == lpMsgFilter->nmhdr.code) {
if (WM_CHAR == lpMsgFilter->msg && VK_RETURN == lpMsgFilter->wParam) {
long lLen;
TEXTRANGE TextRange;
// Get length.
// +1, we have to take into account the null terminator.
// +1 for the '>' character
// +4 for "\r\n\r\n"
lLen = (long) SendMessage(lpMsgFilter->nmhdr.hwndFrom,
WM_GETTEXTLENGTH,
0,
0
) +6;
// Get everything
TextRange.chrg.cpMin = 0;
TextRange.chrg.cpMax = -1;
TextRange.lpstrText = (PSTR) GlobalAlloc(GPTR, lLen);
if (NULL == TextRange.lpstrText) {
FatalErrorBox(ERR_Cannot_Allocate_Memory, NULL);
} else {
*(TextRange.lpstrText) = '>';
// Okay got the text
SendMessage(pCmdWinData->hwndEdit,
WM_GETTEXT,
lLen,
(LPARAM) (TextRange.lpstrText +1));
TextRange.chrg.cpMin = INT_MAX -1;
TextRange.chrg.cpMax = INT_MAX;
SendMessage(pCmdWinData->hwndHistory,
EM_EXSETSEL,
0,
(LPARAM) &TextRange.chrg);
strcat(TextRange.lpstrText, "\n");
SendMessage(pCmdWinData->hwndHistory,
EM_REPLACESEL,
FALSE,
(LPARAM) TextRange.lpstrText
);
SendMessage(pCmdWinData->hwndHistory,
EM_SCROLLCARET,
0,
0
);
SendMessage(pCmdWinData->hwndEdit,
WM_SETTEXT,
0,
(LPARAM) ""
);
GlobalFree(TextRange.lpstrText);
}
// ignore the event
return 1;
}
}
}
// process the event
return 0;
}
}
return 0;
case WM_GETMINMAXINFO:
{
LPMINMAXINFO lpMinMaxInfo = (LPMINMAXINFO) lParam;
lpMinMaxInfo->ptMinTrackSize.x = MINWND_SIZE;
lpMinMaxInfo->ptMinTrackSize.y = MINWND_SIZE;
}
return 0;
case WM_LBUTTONDOWN:
{
pCmdWinData->bTrackingMouse = TRUE;
SetCapture(hwnd);
}
return 0;
case WM_MOUSEMOVE:
{
if (MK_LBUTTON & wParam && pCmdWinData->bTrackingMouse) {
// We are resizing the History & Edit Windows
RECT rc;
GetClientRect(hwnd, &rc);
// y position centered vertically around the cursor
pCmdWinData->nDividerPosition = HIWORD(lParam) - GetSystemMetrics(SM_CYEDGE) /2;
SendMessage(hwnd,
WM_SIZE,
SIZE_RESTORED,
MAKELPARAM(rc.right, rc.bottom)
);
}
}
return 0;
case WM_LBUTTONUP:
{
pCmdWinData->bTrackingMouse = FALSE;
ReleaseCapture();
}
return 0;
case WM_SIZE:
{
int nWidth = LOWORD(lParam);
int nHeight = HIWORD(lParam);
const int nDividerHeight = GetSystemMetrics(SM_CYEDGE);
int nHistoryHeight = pCmdWinData->nDividerPosition;
MoveWindow(pCmdWinData->hwndHistory,0, 0, nWidth, nHistoryHeight, TRUE);
MoveWindow(pCmdWinData->hwndEdit, 0, nHistoryHeight + nDividerHeight,
nWidth, nHeight - nHistoryHeight - nDividerHeight, TRUE);
}
return 0;
case WM_DESTROY:
{
// Clean up
PVOID pv = SetCmdWinData(hwnd, NULL);
if (pv) {
delete pv;
}
g_DebuggerWindows.hwndCmd = NULL;
}
return 0;
}
}
#endif // NEW_WINDOWING_CODE