📄 win_terminal.c
字号:
/* * mShell * Copyright 2006, Julien Lecomte * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in a * product, an acknowledgment in the product documentation would be appreciated * but is not required. * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * $Id: win_terminal.c,v 1.4 2006/04/06 14:45:12 julienlecomte Exp $ */#include "mshell_preconfig.h"#define WIN32_LEAN_AND_MEAN#include <windows.h>#include "mshell_resource.h"#include "mshell.h"extern TCHAR szPathSystem[];extern HWND hMDIWindow;extern HWND hMDIClient;DWORD WINAPI WaitForTerminalToExit (LPVOID /*LPTERMINAL_INFO*/ lpProp){ /* save what we use on stack in case lpProp has been freed */ HWND hParent = ((LPTERMINAL_INFO) lpProp)->hMdiChild; WaitForSingleObject (((LPTERMINAL_INFO) lpProp)->pi.hProcess, INFINITE); /* Process is either non-existent, or exited cleanly */ if (IsWindow (hParent)) SendMessage (hParent, WM_CLOSE, (WPARAM) NULL, (LPARAM) NULL); return 0;}LRESULT CALLBACK TerminalWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch (msg) { /* dump these back to the terminal */ case WM_MOUSEWHEEL: case WM_KEYDOWN: case WM_KEYUP: { LPTERMINAL_INFO lpTI = GetProp (hWnd, TERMINAL_PROP); PostMessage (lpTI->hTerminal, msg, wParam, lParam); return 0; } case WM_COMMAND: switch (LOWORD (wParam)) { /* Send these to the child */ case MENU_EDIT_CUT: case MENU_EDIT_COPY: case MENU_EDIT_PASTE: { MessageBox (hWnd, "/* TODO */", STR_MSHELL, MB_OK); return 0; } } return DefMDIChildProc (hWnd, msg, wParam, lParam); case WM_CREATE: { LPTERMINAL_INFO lpTI = (LPTERMINAL_INFO) ((LPMDICREATESTRUCT) ((LPCREATESTRUCT) lParam)->lpCreateParams)->lParam; LPTERMINAL_INFO lpProp = NULL; STARTUPINFO si; /* lpTI is actually somewhere on the stack, we'll copy it to heap */ lpProp = HeapAlloc (GetProcessHeap (), 0, sizeof(TERMINAL_INFO)); if (!lpProp) return -1; CopyMemory (lpProp, lpTI, sizeof(TERMINAL_INFO)); /* Don't use lpTI anymore */ lpProp->hMdiChild = hWnd; ZeroMemory (&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_FORCEOFFFEEDBACK | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; /* not used AFAIK by rxvt */ /* Change current directory before spawn */ SetCurrentDirectory (lpProp->szCurDir); /* Process can actually start correctly and then quit (normal quit or failure) */ if (!CreateProcess (NULL, lpProp->szCmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, lpProp->lpEnv, lpProp->szSysDir, &si, &lpProp->pi)) { HeapFree (GetProcessHeap (), 0, lpProp); return -1; } /* This is the window we're looking for * I'ld like to thank the RXVT developpers for assigning a unique classname to * their windows. */ TCHAR clsname[40]; sprintf (clsname, "rxvt%08x", (unsigned int) lpProp->pi.dwThreadId); /* Try to keep the search non-blocking */ lpProp->hTerminal = FindWindow (clsname, NULL); while (!lpProp->hTerminal) { switch (WaitForSingleObject (lpProp->pi.hProcess, 25)) { case WAIT_TIMEOUT: DEBUG_ECHO("WAIT_TIMEOUT\n"); break; case WAIT_FAILED: /* Close this window, it failed, process does not exist */ DEBUG_ECHO("WAIT_FAILED\n"); HeapFree (GetProcessHeap (), 0, lpProp); return -1; } lpProp->hTerminal = FindWindow (clsname, NULL); } SetParent (lpProp->hTerminal, lpProp->hMdiChild); ShowWindowAsync (lpProp->hTerminal, SW_SHOWNOACTIVATE); SetWindowLongPtr (lpProp->hTerminal, GWL_STYLE, WS_CHILD); SetWindowLongPtr (lpProp->hTerminal, GWL_EXSTYLE, WS_EX_NOACTIVATE); /* Create a thread that will notify us when process dies. * FIXME: If thread isn't created... */ CreateThread (NULL, 0, WaitForTerminalToExit, lpProp, 0, NULL); SetProp (hWnd, TERMINAL_PROP, lpProp); /* Set my icon depending if we're MSYS or MINGW32 */ HANDLE hIco = NULL; if (lpProp->ismsys == TRUE) hIco = LoadImage (GetModuleHandle (NULL), MAKEINTRESOURCE(ICO_MSYS), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); else if (lpProp->ismingw == TRUE) hIco = LoadImage (GetModuleHandle (NULL), MAKEINTRESOURCE(ICO_MINGW32), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); if (hIco) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIco); return 0; } case WM_DESTROY: { LPTERMINAL_INFO lpTI = GetProp (hWnd, TERMINAL_PROP); CloseHandle (lpTI->pi.hThread); CloseHandle (lpTI->pi.hProcess); RemoveProp (hWnd, TERMINAL_PROP); HeapFree (GetProcessHeap (), 0, lpTI); HANDLE hIco = (HANDLE) SendMessage (hWnd, WM_SETICON, ICON_SMALL, 0); if (hIco) DestroyIcon (hIco); return DefMDIChildProc (hWnd, msg, wParam, lParam); } case WM_WINDOWPOSCHANGED: { LPTERMINAL_INFO lpTI = GetProp (hWnd, TERMINAL_PROP); RECT rcClient; GetClientRect (hWnd, &rcClient); SetWindowPos (lpTI->hTerminal, NULL, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOZORDER); return DefMDIChildProc (hWnd, msg, wParam, lParam); } default: return DefMDIChildProc (hWnd, msg, wParam, lParam); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -