📄 tconsole.cpp
字号:
printf("%s\n", m_szCommand);
RunCommand();
}
}
m_szScriptName[0] = 0;
if(szSaveDir[0] != 0)
SetCurrentDirectory(szSaveDir);
if(fp != NULL)
fclose(fp);
return 0;
}
// Changes directory
int TConsole::Chdir(char ** Args)
{
int nError = ERROR_SUCCESS;
if(SetCurrentDirectory(Args[0]) == FALSE)
{
nError = GetLastError();
printf(IDS_CONSOLE_CANTCD, Args[0], nError);
}
return nError;
}
int TConsole::Dir(char ** Args)
{
WIN32_FIND_DATA wf;
SYSTEMTIME st;
FILETIME ftLocal;
HANDLE hFind = INVALID_HANDLE_VALUE;
BOOL bResult = TRUE;
char szDateFormat[0x20];
char szTimeFormat[0x20];
char szLine[MAX_PATH + 0x40];
char * szMask = Args[0];
LoadString(AfxGetResourceHandle(), IDS_DATEFORMAT, szDateFormat, sizeof(szDateFormat)-1);
LoadString(AfxGetResourceHandle(), IDS_TIMEFORMAT, szTimeFormat, sizeof(szTimeFormat)-1);
if(szMask == NULL)
szMask = "*";
hFind = FindFirstFile(szMask, &wf);
while(bResult && hFind != INVALID_HANDLE_VALUE)
{
char * p = szLine;
FileTimeToLocalFileTime(&wf.ftLastWriteTime, &ftLocal);
FileTimeToSystemTime(&ftLocal, &st);
p += GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, szDateFormat, p, sizeof(szLine)) - 1;
*p++ = ' ';
p += GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, szTimeFormat, p, sizeof(szLine)) - 1;
*p++ = ' ';
if(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
p += sprintf(p, "%10s ", "<DIR>");
else
p += sprintf(p, "%10u ", wf.nFileSizeLow);
p += sprintf(p, "%s\n", wf.cFileName);
printf(szLine);
bResult = FindNextFile(hFind, &wf);
}
if(hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
printf("\n");
return ERROR_SUCCESS;
}
int TConsole::Exit(char ** /* Args */)
{
PostMessage(m_hConsole, WM_CLOSECONSOLE, 0, 0);
return ERROR_SUCCESS;
}
int TConsole::Help(char ** Args)
{
TCommandInfo * pCmd;
// If no argument given, show help on help
if(Args[0] == NULL)
Args[0] = "help";
for(pCmd = m_Commands; pCmd->szCommand != NULL; pCmd++)
{
if(!stricmp(Args[0], pCmd->szCommand))
{
if(pCmd->nIDHelp != 0)
printf(pCmd->nIDHelp);
else
printf(IDS_HELP_NOHELP);
if(pCmd->nIDHelp == IDS_HELP_HELP)
{
for(pCmd = m_Commands; pCmd->szCommand != NULL; pCmd++)
{
printf("\n");
printf(pCmd->szCommand);
if(pCmd->szCmd != NULL)
printf(" (%s)", pCmd->szCmd);
}
}
printf("\n\n");
break;
}
}
return ERROR_SUCCESS;
}
int TConsole::RunCommand()
{
TCommandInfo * pCommand = NULL;
char * szCommand = m_szCommand;
char * szBuffer;
char * Args[0x20];
int bInQuota = 0;
int nArgs = 0;
// No command ==> No fun
if(szCommand[0] == 0)
return ERROR_SUCCESS;
// Pre-fill the arguments
m_nLevel++;
memset(Args, 0, sizeof(Args));
// Cut the command into words
for(szBuffer = szCommand; *szBuffer != 0 && nArgs < 0x20; )
{
if(*szBuffer == '"')
{
*szBuffer++ = 0;
bInQuota = !bInQuota;
continue;
}
if(0 < *szBuffer && bInQuota)
{
Args[nArgs++] = szBuffer;
while(0 < *szBuffer && *szBuffer != '"')
szBuffer++;
continue;
}
if(0x20 < *szBuffer)
{
Args[nArgs++] = szBuffer;
while(*szBuffer > 0x20)
szBuffer++;
continue;
}
if(0 < *szBuffer && *szBuffer <= 0x20)
*szBuffer++ = 0;
}
// Find the function
for(int i = 0; m_Commands[i].szCommand != NULL && pCommand == NULL; i++)
{
if(!stricmp(Args[0], m_Commands[i].szCommand))
pCommand = m_Commands + i;
if(m_Commands[i].szCmd != NULL && stricmp(Args[0], m_Commands[i].szCmd) == 0)
pCommand = m_Commands + i;
}
// If unknown command, show error
if(pCommand != NULL)
{
nArgs--;
if(nArgs < pCommand->nMinArgs)
printf(IDS_CONSOLE_FEWPARS, Args[0]);
else if(nArgs > pCommand->nMaxArgs)
printf(IDS_CONSOLE_MANYPARS, Args[0]);
else
(this->*pCommand->DoCommand)(&Args[1]);
}
else
printf(IDS_CONSOLE_UNKCMD, Args[0]);
// If returned from the first run, wait for a key.
m_nLevel--;
if(m_nLevel == 0 && m_nState == stRunning)
{
printf(IDS_CONSOLE_PRESSKEY);
m_nState = stGetch;
}
return 0;
}
//-----------------------------------------------------------------------------
// Message handlers
LRESULT TConsole::OnPaint(HWND hWnd, WPARAM, LPARAM)
{
HBITMAP hBmp = NULL;
RECT clientRect;
HDC hWinDC = NULL;
HDC hMemDC = NULL;
HDC hDC = NULL;
// If the drawing is currently disabled, do nothing.
if(m_bEnablePaint == FALSE)
return 0;
// Create a compatible bitmap with the size of the editbox client area
::GetClientRect(hWnd, &clientRect);
hDC = ::GetDC(NULL); // Device context of the entire screen
hBmp = CreateCompatibleBitmap(hDC, clientRect.right, clientRect.bottom);
::ReleaseDC(NULL, hDC);
// Create the compatible DC (Initially with the size of 1x1 pixel) and select the bitmap.
hMemDC = CreateCompatibleDC(NULL);
hBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
// Paint the window to our memory DC
IntersectClipRect(hMemDC, 0, 0, clientRect.right, clientRect.bottom);
CallWindowProc(m_pfnOldWndProc, hWnd, WM_ERASEBKGND, (WPARAM)hMemDC, 0);
CallWindowProc(m_pfnOldWndProc, hWnd, WM_PAINT, (WPARAM)hMemDC, 0);
// Copy the memory DC into the window DC. At the end, we have to
// validate the window rectangle to prevent sending a flood of WM_PAINTs
if((hWinDC = ::GetDC(hWnd)) != NULL)
{
::HideCaret(hWnd);
::BitBlt(hWinDC, 0, 0, clientRect.right, clientRect.bottom, hMemDC, 0, 0, SRCCOPY);
::ReleaseDC(hWnd, hWinDC);
::ValidateRect(hWnd, NULL);
::ShowCaret(hWnd);
}
// Delete all objects created in this function
hBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
DeleteObject(hBmp);
DeleteDC(hMemDC);
return TRUE;
}
LRESULT TConsole::OnCtlColorEdit(HWND /* hWnd */, WPARAM wParam, LPARAM /* lParam */)
{
HDC hDC = (HDC)wParam;
SetTextColor(hDC, RGB(255, 255, 255));
SetBkColor(hDC, RGB(0, 0, 0));
return (LRESULT)m_hBrush;
}
LRESULT TConsole::OnKeyDownUp(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int nStart, nEnd; // Start & End caret position
// Ignore keys if not waiting for them
if(m_nState != stGetch && m_nState != stConsole)
return 1;
switch(wParam)
{
case VK_DOWN: // Do nothing
case VK_UP:
case VK_PRIOR:
case VK_NEXT:
return 1;
case VK_LEFT:
case VK_BACK:
SendMessage(hWnd, EM_GETSEL, (WPARAM)&nStart, (LPARAM)&nEnd);
if(nStart <= m_nStart)
return 1;
break;
}
return CallWindowProc(m_pfnOldWndProc, hWnd, uMsg, wParam, lParam);
}
LRESULT TConsole::OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
int nStart, nEnd; // Start & End caret position
// If waiting for a key, Ignore keys if not waiting for them
if(m_nState == stGetch)
{
PostMessage(hWnd, WM_CLOSECONSOLE, 0, 0);
return 1;
}
// If console mode, read the command
else if(m_nState == stConsole)
{
switch(wParam)
{
case 0x08:
SendMessage(hWnd, EM_GETSEL, (WPARAM)&nStart, (LPARAM)&nEnd);
if(nStart <= m_nStart)
return 1;
break;
case 0x0D:
SaveCommand();
PostMessage(hWnd, WM_RUNCOMMAND, 0, 0);
break;
}
}
// In other modes, ignore the key
else
return 1;
return CallWindowProc(m_pfnOldWndProc, hWnd, WM_CHAR, wParam, lParam);
}
LRESULT TConsole::OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
LRESULT nResult;
HWND hParent = GetParent(hWnd);
// Notify parent that the console has been destroyed
if(hParent != NULL)
SendMessage(hParent, WM_CONSOLEDESTROYED, 0, 0);
// Destroy self
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)m_pfnOldWndProc);
SetWindowLong(hWnd, GWL_USERDATA, 0);
m_hConsole = NULL;
nResult = DefWindowProc(hWnd, WM_DESTROY, wParam, lParam);
// Close the last opened MPQ and restore directory
CloseLastAccessedMpq();
delete this;
return nResult;
}
LRESULT CALLBACK TConsole::ConsoleWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT Result;
int nStart; // Start caret position
int nEnd; // End caret position
switch(uMsg)
{
case WM_RUNCOMMAND: // If the command needs to be ran
RunCommand();
if(m_nState == stConsole)
ShowPrompt();
break;
case WM_CLOSECONSOLE: // If someone want us to close
DestroyWindow(hWnd);
return TRUE;
case WM_CTLCOLOREDIT: // Set the color
return OnCtlColorEdit(hWnd, wParam, lParam);
case WM_DESTROY: // If the window is being destroyed, unsubclass it
return OnDestroy(hWnd, wParam, lParam);
case WM_KEYDOWN:
case WM_KEYUP:
return OnKeyDownUp(hWnd, uMsg, wParam, lParam);
case WM_CHAR:
return OnChar(hWnd, wParam, lParam);
case EM_SETSEL: // Correct the position when EM_SETSEL
if((int)wParam < m_nStart)
wParam = m_nStart;
if((int)lParam < m_nStart)
lParam = m_nStart;
break;
case WM_ERASEBKGND: // Do not do anything on erasing background
return TRUE;
case WM_PAINT:
return OnPaint(hWnd, wParam, lParam);
}
// Call the original handler
Result = CallWindowProc(m_pfnOldWndProc, hWnd, uMsg, wParam, lParam);
// Check the cursor position (prevent recursion)
CallWindowProc(m_pfnOldWndProc, hWnd, EM_GETSEL, (WPARAM)&nStart, (LPARAM)&nEnd);
if(nStart < m_nStart || nEnd < m_nStart)
{
if(nStart < m_nStart)
nStart = m_nStart;
if(nEnd < m_nStart)
nEnd = m_nStart;
CallWindowProc(m_pfnOldWndProc, hWnd, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
}
return Result;
}
LRESULT CALLBACK TConsole::SubclassedWindowProc(HWND hConsole, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TConsole * pConsole = (TConsole *)GetWindowLong(hConsole, GWL_USERDATA);
if(pConsole != NULL)
return pConsole->ConsoleWindowProc(hConsole, uMsg, wParam, lParam);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -