⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 widget.cpp

📁 一个Windows下的Linux专用虚拟机
💻 CPP
字号:
/* * This source code is a part of coLinux source package. * * Dan Aloni <da-x@gmx.net>, 2003 (c) * Ballard, Jonathan H.  <californiakidd@users.sourceforge.net>, 2004 (c) * * The code is licensed under the GPL. See the COPYING file at * the root directory. * */#include <windows.h>#include "widget.h"#include <colinux/user/console-base/main.h>extern "C" {#include <colinux/os/alloc.h>	// Not found in w32api/mingwextern PASCAL BOOL GetCurrentConsoleFont(HANDLE hConsoleOutput,                                         BOOL bMaximumWindow,                                         PCONSOLE_FONT_INFO lpCurrentFont);extern PASCAL COORD GetConsoleFontSize(HANDLE hConsoleOutput,                                       DWORD nFont);}static BOOL ctrl_exit;/* * Storage of current keyboard state. * For every virtual key (256), it is 0 (for released) or the scancode * of the key pressed (with 0xE0 in high byte if extended). */static WORD vkey_state[256];console_widget_t *co_console_widget_create(){	return new console_widget_NT_t();}BOOL WINAPIco_console_widget_control_handler(DWORD T){	DWORD r;	INPUT_RECORD c;	if (!(T == CTRL_CLOSE_EVENT || T == CTRL_LOGOFF_EVENT)) 		return false;	memset(&c, 0, sizeof(INPUT_RECORD));	c.EventType = KEY_EVENT;	WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &c, 1, &r);	return ctrl_exit = true;}console_widget_NT_t::console_widget_NT_t():  console_widget_t(){	allocated_console = false;	init_new_console();	memset(vkey_state, 0, sizeof(vkey_state));	buffer = 0;	screen = 0;	input = 0;	output = 0;	blank.Attributes = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED;	blank.Char.AsciiChar = ' ';	ctrl_exit = false;	SetConsoleCtrlHandler(co_console_widget_control_handler, true);}void console_widget_NT_t::init_new_console(){		allocated_console = false;	saved_hwnd = GetConsoleWindow();	if (saved_hwnd == (HWND)0) {		AllocConsole();		allocated_console = true;		saved_hwnd = GetConsoleWindow();	}	saved_input = GetStdHandle(STD_INPUT_HANDLE);	saved_output = GetStdHandle(STD_OUTPUT_HANDLE);	GetConsoleCursorInfo(saved_output, &saved_cursor);	GetConsoleMode(saved_input, &saved_mode);}void console_widget_NT_t::restore_console(){	FlushConsoleInputBuffer(saved_input);	SetConsoleMode(saved_input, saved_mode);	SetStdHandle(STD_INPUT_HANDLE, saved_input);	SetStdHandle(STD_OUTPUT_HANDLE, saved_output);	SetConsoleCursorInfo(saved_output, &saved_cursor);	if (allocated_console) {		FreeConsole();	}}co_rc_tconsole_widget_NT_t::set_window(console_window_t * W){	CONSOLE_CURSOR_INFO cci;	CONSOLE_FONT_INFO cfi;	COORD fs;	HWND hwnd;	RECT r;	window = W;	input = GetStdHandle(STD_INPUT_HANDLE);	SetConsoleMode(input, 0);	output = GetStdHandle(STD_OUTPUT_HANDLE);        GetCurrentConsoleFont(output, 0, &cfi);        fs = GetConsoleFontSize(output, cfi.nFont);        r.top = 0;        r.left = 0;        r.bottom = fs.Y * 25;        r.right = fs.X * 80;        AdjustWindowRect(&r, WS_CAPTION|WS_SYSMENU|WS_THICKFRAME                             |WS_MINIMIZEBOX|WS_MAXIMIZEBOX, 0);	hwnd = GetConsoleWindow();	SetWindowPos(hwnd, HWND_TOP, 0, 0,                     r.right - r.left, r.bottom - r.top,                     SWP_NOMOVE|SWP_SHOWWINDOW);        GetConsoleCursorInfo(output, &cursor);        cci = cursor;        cci.bVisible = 0;        SetConsoleCursorInfo(output, &cci);	size.X = 80 ;        size.Y = 25 ;	region.Top = 0;	region.Left = 0;        region.Right = 79;        region.Bottom = 24;        if( ! SetConsoleWindowInfo( output , TRUE , &region ) )         co_debug("SetConsoleWindowInfo() error 0x%lx", GetLastError());	screen =	    (CHAR_INFO *) co_os_malloc(sizeof (CHAR_INFO) * size.X * size.Y);	buffer =	    CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, 0,				      CONSOLE_TEXTMODE_BUFFER, 0);	if( ! SetConsoleScreenBufferSize( buffer , size ) )          co_debug("SetConsoleScreenBufferSize() error 0x%lx", GetLastError());	SetConsoleMode(buffer, 0);	cci.bVisible = true;	cci.dwSize = 10;	SetConsoleCursorInfo(buffer, &cci);	SetConsoleActiveScreenBuffer(buffer);	return CO_RC(OK);}console_widget_NT_t::~console_widget_NT_t(){	SetConsoleCtrlHandler(co_console_widget_control_handler, false);	if (screen)		co_os_free(screen);	CloseHandle(buffer);        SetConsoleCursorInfo(output, &cursor);	restore_console();}voidconsole_widget_NT_t::draw(){	if (console == NULL) {		COORD c = {0, 0};		DWORD z;		if (!FillConsoleOutputCharacter		    (buffer, blank.Char.AsciiChar, size.X * size.Y, c, &z))			co_debug("FillConsoleOutputCharacter() error 0x%lx",				 GetLastError());		if (!FillConsoleOutputAttribute		    (buffer, blank.Attributes, size.X * size.Y, c, &z))			co_debug("FillConsoleOutputAttribute() error 0x%lx",				 GetLastError());		return;	}	co_console_cell_t *cell = console->screen;	CHAR_INFO *ci = screen;	int count = size.X * size.Y;	do {		ci->Attributes = cell->attr;		(ci++)->Char.AsciiChar = (cell++)->ch;	} while (--count);	SMALL_RECT r = region;	COORD c = {0, 0};	if (!WriteConsoleOutput(buffer, screen, size, c, &r))		co_debug("WriteConsoleOutput() error 0x%lx", GetLastError());}voidconsole_widget_NT_t::update(){	SMALL_RECT r = region;	COORD c = { 0, 0 };	if (!ReadConsoleOutput(buffer, screen, size, c, &r))		co_debug("ReadConsoleOutput() error 0x%lx", GetLastError());	co_console_cell_t *cell = console->screen;	CHAR_INFO *ci = screen;	int count = size.X * size.Y;	do {		cell->attr = ci->Attributes;		(cell++)->ch = (ci++)->Char.AsciiChar;	} while (--count);}co_rc_tconsole_widget_NT_t::op_scroll_up(		const co_console_unit &T,		const co_console_unit &B,		const co_console_unit &L){	SMALL_RECT r;	COORD c;	r.Left = region.Left;	r.Right = region.Right;	r.Top = T;	r.Bottom = B;	c.X = 0;	c.Y = r.Top - L;	if (!ScrollConsoleScreenBuffer(buffer, &r, &r, c, &blank))		co_debug("ScrollConsoleScreenBuffer() error 0x%lx",			 GetLastError());	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_scroll_down(		const co_console_unit &T,		const co_console_unit &B,		const co_console_unit &L){	SMALL_RECT r;	COORD c;	r.Left = region.Left;	r.Right = region.Right;	r.Top = T;	r.Bottom = B;	c.X = 0;	c.Y = r.Top + L;	if (!ScrollConsoleScreenBuffer(buffer, &r, &r, c, &blank))		co_debug("ScrollConsoleScreenBuffer() error 0x%lx",			 GetLastError());	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_putcs(		const co_console_unit &Y,		const co_console_unit &X,		const co_console_character *D,		const co_console_unit &C){	int count;	if ((count = C) <= 0)		return CO_RC(ERROR);	if(Y >= size.Y || X >= size.X) {		co_debug("putc error");		return CO_RC(ERROR);	}	SMALL_RECT r;	COORD c;	c.X = r.Left = X;	c.Y = r.Top = r.Bottom = Y;	if (--count + r.Left > console->x)		count = console->x - r.Left;	r.Right = r.Left + count;	co_console_cell_t *cells = (co_console_cell_t *) D;	CHAR_INFO *ci = &screen[(size.X * r.Top) + r.Left];	do {		ci->Attributes = cells->attr;		(ci++)->Char.AsciiChar = (cells++)->ch;	} while (count--);	if (!WriteConsoleOutput(buffer, screen, size, c, &r))		co_debug("WriteConsoleOutput() error 0x%lx", GetLastError());	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_putc(		const co_console_unit &Y,		const co_console_unit &X,		const co_console_character &C){	SMALL_RECT r;	COORD c;	if (Y >= size.Y || X >= size.X) {		co_debug("putc error");		return CO_RC(ERROR);	}	c.X = r.Left = r.Right = X;	c.Y = r.Top = r.Bottom = Y;	CHAR_INFO *ci = &screen[(size.X * r.Top) + r.Left];	ci->Attributes = ((C & 0xFF00) >> 8);	ci->Char.AsciiChar = (C & 0x00FF);	if (!WriteConsoleOutput(buffer, screen, size, c, &r))		co_debug("WriteConsoleOutput() error 0x%lx", GetLastError());	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_cursor(		const co_cursor_pos_t & P){	COORD c;	c.X = P.x;	c.Y = P.y;	SetConsoleCursorPosition(buffer, c);	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_clear(		const co_console_unit &T,		const co_console_unit &L,		const co_console_unit &B,		const co_console_unit &R,		const co_console_character charattr){	SMALL_RECT r;	CHAR_INFO *s;	CHAR_INFO clear_blank;	COORD c;	long y, x;	if (B < T || R < L)		return CO_RC(ERROR);	if (T >= size.Y || L >= size.X)		return CO_RC(ERROR);	if (B >= size.Y || R >= size.X)		return CO_RC(ERROR);	clear_blank.Attributes = charattr >> 8;	clear_blank.Char.AsciiChar = charattr & 0xff;	y = T;	while(y <= B) {		s = &screen[(size.X * y) + (x = L)];		while(x++ <= R)			*(s++) = clear_blank;		y++;	}	r.Top = c.Y = T;	r.Left = c.X = L;	r.Bottom = B;	r.Right = R;		if (!WriteConsoleOutput(buffer, screen, size, c, &r))		co_debug("WriteConsoleOutput() error 0x%lx", GetLastError());	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_bmove(		const co_console_unit &Y,		const co_console_unit &X,		const co_console_unit &T,		const co_console_unit &L,		const co_console_unit &B,		const co_console_unit &R){	SMALL_RECT r;	COORD c;	c.Y = Y;	c.X = X;	r.Top = T;	r.Left = L;	r.Bottom = B;	r.Right = R;	if(!ScrollConsoleScreenBuffer(buffer, &r, &region, c, &blank))		co_debug("ScrollConsoleScreenBuffer() error 0x%lx", GetLastError());	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::op_invert(		const co_console_unit &Y,		const co_console_unit &X,		const co_console_unit &C){	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::loop(){	DWORD r;	if (!GetNumberOfConsoleInputEvents(input, &r))		return CO_RC(ERROR);	if (r == 0)		return CO_RC(OK);	INPUT_RECORD i;	ReadConsoleInput(input, &i, 1, &r);	if (ctrl_exit) {		window->detach();		return CO_RC(OK);	}	switch ( i.EventType )	{	case KEY_EVENT:		process_key_event(i.Event.KeyEvent);		break;	case FOCUS_EVENT:		/* MSDN says this events should be ignored ??? */		process_focus_event(i.Event.FocusEvent);		break;	case MOUSE_EVENT:		/* *TODO: must be enabled first also */		break;	}	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::title(const char *T){	SetConsoleTitle(T);	return CO_RC(OK);}co_rc_tconsole_widget_NT_t::idle(){	return CO_RC(OK);}void send_key( DWORD code ){	co_scan_code_t sc;	sc.down = 1;	/* to work with old kernels that don't ignore this field */	/* send e0 if extended key */	if ( code & 0xE000 )	{		sc.code = 0xE0;		co_user_console_handle_scancode( sc );	}	sc.code = code & 0xFF;	co_user_console_handle_scancode( sc );}void console_widget_NT_t::process_key_event( KEY_EVENT_RECORD& ker ){	const BYTE vkey     = static_cast<BYTE>( ker.wVirtualKeyCode );	const WORD flags    = ker.dwControlKeyState;	const bool released = (ker.bKeyDown == FALSE);	const bool extended = flags & ENHANCED_KEY;	WORD       code     = ker.wVirtualScanCode;	/* Special key processing */	switch ( vkey )	{	case VK_LWIN:	case VK_RWIN: {		// Check if LeftAlt+Win (detach from colinux)		if (!released && (flags & LEFT_ALT_PRESSED)) {			window->detach();			return;		}		// Signal Win key pressed/released		if (released)				vkey_state[255] &= ~1;		else				vkey_state[255] |=  1;		break;	}	case VK_DELETE: {		if (!released  && 		    ((flags & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&		     (flags & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) &&		     (flags & (SHIFT_PRESSED))))		{			window->send_ctrl_alt_del();			return;		}		break;	}	case VK_APPS:	// Window Context Menu		return;		// Let windows process this keys	case VK_MENU:		// Check if Win+LeftAlt (detach from colinux)		if ((vkey_state[255] & 1) && !released) {			window->detach();			return;		}		break;	}	/* Normal key processing */	if (extended)		code |= 0xE000; /* extended scan-code code */	if (released) {	/* key was released */		code |= 0x80;		if ( vkey_state[vkey] == 0 )			return;		/* ignore release of not pressed keys */		vkey_state[vkey] = 0;	} else { /* Key pressed */		vkey_state[vkey] = code | 0x80;	}	/* Send key scancode */	send_key(code);	return;}/* * console_widget_NT_t::process_focus_event * * MSDN says this event is used internally only and should be ignored. * But it seems to work ok, at least on XP ??? * I believe a broken focus handler is better than nothing, so here it is. */void console_widget_NT_t::process_focus_event( FOCUS_EVENT_RECORD& fer ){	if (fer.bSetFocus)		return;	for (int i = 0; i < 255; ++i) {		if (vkey_state[i]) {	// release it			send_key(vkey_state[i]);			vkey_state[i] = 0;		}	}	vkey_state[255] = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -