📄 window.c
字号:
GetWindowLong(hwnd, GWL_EXSTYLE); nexflag = exflag; if (cfg.alwaysontop != prev_cfg.alwaysontop) { if (cfg.alwaysontop) { nexflag |= WS_EX_TOPMOST; SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } else { nexflag &= ~(WS_EX_TOPMOST); SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } } if (cfg.sunken_edge) nexflag |= WS_EX_CLIENTEDGE; else nexflag &= ~(WS_EX_CLIENTEDGE); nflg = flag; if (is_full_screen() ? cfg.scrollbar_in_fullscreen : cfg.scrollbar) nflg |= WS_VSCROLL; else nflg &= ~WS_VSCROLL; if (cfg.resize_action == RESIZE_DISABLED || is_full_screen()) nflg &= ~WS_THICKFRAME; else nflg |= WS_THICKFRAME; if (cfg.resize_action == RESIZE_DISABLED) nflg &= ~WS_MAXIMIZEBOX; else nflg |= WS_MAXIMIZEBOX; if (nflg != flag || nexflag != exflag) { if (nflg != flag) SetWindowLong(hwnd, GWL_STYLE, nflg); if (nexflag != exflag) SetWindowLong(hwnd, GWL_EXSTYLE, nexflag); SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); init_lvl = 2; } } /* Oops */ if (cfg.resize_action == RESIZE_DISABLED && IsZoomed(hwnd)) { force_normal(hwnd); init_lvl = 2; } set_title(NULL, cfg.wintitle); if (IsIconic(hwnd)) { SetWindowText(hwnd, cfg.win_name_always ? window_name : icon_name); } if (strcmp(cfg.font.name, prev_cfg.font.name) != 0 || strcmp(cfg.line_codepage, prev_cfg.line_codepage) != 0 || cfg.font.isbold != prev_cfg.font.isbold || cfg.font.height != prev_cfg.font.height || cfg.font.charset != prev_cfg.font.charset || cfg.vtmode != prev_cfg.vtmode || cfg.bold_colour != prev_cfg.bold_colour || cfg.resize_action == RESIZE_DISABLED || cfg.resize_action == RESIZE_EITHER || (cfg.resize_action != prev_cfg.resize_action)) init_lvl = 2; InvalidateRect(hwnd, NULL, TRUE); reset_window(init_lvl); net_pending_errors(); } break; case IDM_COPYALL: term_copyall(term); break; case IDM_PASTE: term_do_paste(term); break; case IDM_CLRSB: term_clrsb(term); break; case IDM_RESET: term_pwron(term); if (ldisc) ldisc_send(ldisc, NULL, 0, 0); break; case IDM_ABOUT: showabout(hwnd); break; case IDM_HELP: WinHelp(hwnd, help_path, help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0); break; case SC_MOUSEMENU: /* * We get this if the System menu has been activated * using the mouse. */ show_mouseptr(1); break; case SC_KEYMENU: /* * We get this if the System menu has been activated * using the keyboard. This might happen from within * TranslateKey, in which case it really wants to be * followed by a `space' character to actually _bring * the menu up_ rather than just sitting there in * `ready to appear' state. */ show_mouseptr(1); /* make sure pointer is visible */ if( lParam == 0 ) PostMessage(hwnd, WM_CHAR, ' ', 0); break; case IDM_FULLSCREEN: flip_full_screen(); break; default: if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) { SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam); } if (wParam >= IDM_SPECIAL_MIN && wParam <= IDM_SPECIAL_MAX) { int i = (wParam - IDM_SPECIAL_MIN) / 0x10; /* * Ensure we haven't been sent a bogus SYSCOMMAND * which would cause us to reference invalid memory * and crash. Perhaps I'm just too paranoid here. */ if (i >= n_specials) break; if (back) back->special(backhandle, specials[i].code); net_pending_errors(); } } break;#define X_POS(l) ((int)(short)LOWORD(l))#define Y_POS(l) ((int)(short)HIWORD(l))#define TO_CHR_X(x) ((((x)<0 ? (x)-font_width+1 : (x))-offset_width) / font_width)#define TO_CHR_Y(y) ((((y)<0 ? (y)-font_height+1: (y))-offset_height) / font_height) case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: if (message == WM_RBUTTONDOWN && ((wParam & MK_CONTROL) || (cfg.mouse_is_xterm == 2))) { POINT cursorpos; show_mouseptr(1); /* make sure pointer is visible */ GetCursorPos(&cursorpos); TrackPopupMenu(popup_menus[CTXMENU].menu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, cursorpos.x, cursorpos.y, 0, hwnd, NULL); break; } { int button, press; switch (message) { case WM_LBUTTONDOWN: button = MBT_LEFT; press = 1; break; case WM_MBUTTONDOWN: button = MBT_MIDDLE; press = 1; break; case WM_RBUTTONDOWN: button = MBT_RIGHT; press = 1; break; case WM_LBUTTONUP: button = MBT_LEFT; press = 0; break; case WM_MBUTTONUP: button = MBT_MIDDLE; press = 0; break; case WM_RBUTTONUP: button = MBT_RIGHT; press = 0; break; default: button = press = 0; /* shouldn't happen */ } show_mouseptr(1); /* * Special case: in full-screen mode, if the left * button is clicked in the very top left corner of the * window, we put up the System menu instead of doing * selection. */ { char mouse_on_hotspot = 0; POINT pt; GetCursorPos(&pt);#ifndef NO_MULTIMON { HMONITOR mon; MONITORINFO mi; mon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); if (mon != NULL) { mi.cbSize = sizeof(MONITORINFO); GetMonitorInfo(mon, &mi); if (mi.rcMonitor.left == pt.x && mi.rcMonitor.top == pt.y) { mouse_on_hotspot = 1; } } }#else if (pt.x == 0 && pt.y == 0) { mouse_on_hotspot = 1; }#endif if (is_full_screen() && press && button == MBT_LEFT && mouse_on_hotspot) { SendMessage(hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, MAKELPARAM(pt.x, pt.y)); return 0; } } if (press) { click(button, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT, wParam & MK_CONTROL, is_alt_pressed()); SetCapture(hwnd); } else { term_mouse(term, button, translate_button(button), MA_RELEASE, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT, wParam & MK_CONTROL, is_alt_pressed()); ReleaseCapture(); } } return 0; case WM_MOUSEMOVE: { /* * Windows seems to like to occasionally send MOUSEMOVE * events even if the mouse hasn't moved. Don't unhide * the mouse pointer in this case. */ static WPARAM wp = 0; static LPARAM lp = 0; if (wParam != wp || lParam != lp || last_mousemove != WM_MOUSEMOVE) { show_mouseptr(1); wp = wParam; lp = lParam; last_mousemove = WM_MOUSEMOVE; } } /* * Add the mouse position and message time to the random * number noise. */ noise_ultralight(lParam); if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) && GetCapture() == hwnd) { Mouse_Button b; if (wParam & MK_LBUTTON) b = MBT_LEFT; else if (wParam & MK_MBUTTON) b = MBT_MIDDLE; else b = MBT_RIGHT; term_mouse(term, b, translate_button(b), MA_DRAG, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT, wParam & MK_CONTROL, is_alt_pressed()); } return 0; case WM_NCMOUSEMOVE: { static WPARAM wp = 0; static LPARAM lp = 0; if (wParam != wp || lParam != lp || last_mousemove != WM_NCMOUSEMOVE) { show_mouseptr(1); wp = wParam; lp = lParam; last_mousemove = WM_NCMOUSEMOVE; } } noise_ultralight(lParam); break; case WM_IGNORE_CLIP: ignore_clip = wParam; /* don't panic on DESTROYCLIPBOARD */ break; case WM_DESTROYCLIPBOARD: if (!ignore_clip) term_deselect(term); ignore_clip = FALSE; return 0; case WM_PAINT: { PAINTSTRUCT p; HideCaret(hwnd); hdc = BeginPaint(hwnd, &p); if (pal) { SelectPalette(hdc, pal, TRUE); RealizePalette(hdc); } term_paint(term, hdc, (p.rcPaint.left-offset_width)/font_width, (p.rcPaint.top-offset_height)/font_height, (p.rcPaint.right-offset_width-1)/font_width, (p.rcPaint.bottom-offset_height-1)/font_height, is_alt_pressed()); if (p.fErase || p.rcPaint.left < offset_width || p.rcPaint.top < offset_height || p.rcPaint.right >= offset_width + font_width*term->cols || p.rcPaint.bottom>= offset_height + font_height*term->rows) { HBRUSH fillcolour, oldbrush; HPEN edge, oldpen; fillcolour = CreateSolidBrush ( colours[(ATTR_DEFBG>>ATTR_BGSHIFT)*2]); oldbrush = SelectObject(hdc, fillcolour); edge = CreatePen(PS_SOLID, 0, colours[(ATTR_DEFBG>>ATTR_BGSHIFT)*2]); oldpen = SelectObject(hdc, edge); /* * Jordan Russell reports that this apparently * ineffectual IntersectClipRect() call masks a * Windows NT/2K bug causing strange display * problems when the PuTTY window is taller than * the primary monitor. It seems harmless enough... */ IntersectClipRect(hdc, p.rcPaint.left, p.rcPaint.top, p.rcPaint.right, p.rcPaint.bottom); ExcludeClipRect(hdc, offset_width, offset_height, offset_width+font_width*term->cols, offset_height+font_height*term->rows); Rectangle(hdc, p.rcPaint.left, p.rcPaint.top, p.rcPaint.right, p.rcPaint.bottom); // SelectClipRgn(hdc, NULL); SelectObject(hdc, oldbrush); DeleteObject(fillcolour); SelectObject(hdc, oldpen); DeleteObject(edge); } SelectObject(hdc, GetStockObject(SYSTEM_FONT)); SelectObject(hdc, GetStockObject(WHITE_PEN)); EndPaint(hwnd, &p); ShowCaret(hwnd); } return 0; case WM_NETEVENT: /* Notice we can get multiple netevents, FD_READ, FD_WRITE etc * but the only one that's likely to try to overload us is FD_READ. * This means buffering just one is fine. */ if (pending_netevent) enact_pending_netevent(); pending_netevent = TRUE; pend_netevent_wParam = wParam; pend_netevent_lParam = lParam; if (WSAGETSELECTEVENT(lParam) != FD_READ) enact_pending_netevent(); time(&last_movement); return 0; case WM_SETFOCUS: term->has_focus = TRUE; CreateCaret(hwnd, caretbm, font_width, font_height); ShowCaret(hwnd); flash_window(0); /* stop */ compose_state = 0; term_out(term); term_update(term); break; case WM_KILLFOCUS: show_mouseptr(1); term->has_focus = FALSE; DestroyCaret(); caret_x = caret_y = -1; /* ensure caret is replaced next time */ term_out(term); term_update(term); break; case WM_ENTERSIZEMOVE:#ifdef RDB_DEBUG_PATCH debug((27, "WM_ENTERSIZEMOVE"));#endif EnableSizeTip(1); resizing = TRUE; need_backend_resize = FALSE; break; case WM_EXITSIZEMOVE: EnableSizeTip(0); resizing = FALSE;#ifdef RDB_DEBUG_PATCH debug((27, "WM_EXITSIZEMOVE"));#endif if (need_backend_resize) { term_size(term, cfg.height, cfg.width, cfg.savelines); InvalidateRect(hwnd, NULL, TRUE); } break; case WM_SIZING: /* * This does two jobs: * 1) Keep the sizetip uptodate * 2) Make sure the window size is _stepped_ in units of the font size. */ if (cfg.resize_action != RESIZE_FONT && !is_alt_pressed()) { int width, height, w, h, ew, eh; LPRECT r = (LPRECT) lParam; if ( !need_backend_resize && cfg.resize_action == RESIZE_EITHER && (cfg.height != term->rows || cfg.width != term->cols )) { /* * Great! It seems that both the terminal size and the * font size have been changed and the user is now dragging. * * It will now be difficult to get back to the configured * font size! * * This would be easier but it seems to be too confusing. term_size(term, cfg.height, cfg.width, cfg.savelines); reset_window(2); */ cfg.height=term->rows; cfg.width=term->cols; InvalidateRect(hwnd, NULL, TRUE); need_backend_resize = TRUE; } width = r->right - r->left - extra_width; height = r->bottom - r->top - extra_height; w = (width + font_width / 2) / font_width; if (w < 1) w = 1; h = (height + font_height / 2) / font_height; if (h < 1) h = 1; UpdateSizeTip(hwnd, w, h); ew = width - w * font_width; eh = height - h * font_height; if (ew != 0) { if (wParam == WMSZ_LEFT || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_TOPLEFT) r->left += ew; else r->right -= ew; } if (eh != 0) { if (wParam == WMSZ_TOP || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_TOPLEFT) r->top += eh; else r->bottom -= eh; } if (ew || eh) return 1; else return 0; } else { int width, height, w, h, rv = 0; int ex_width = extra_width + (cfg.window_border - offset_width) * 2; int ex_height = extra_height + (cfg.window_border - offset_height) * 2; LPRECT r = (LPRECT) lParam; width = r->right - r->left - ex_width; height = r->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -