2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: frontends/gui/conwnd.c
5 * PURPOSE: GUI Console Window Class
6 * PROGRAMMERS: Gé van Geldorp
9 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
12 /* INCLUDES *******************************************************************/
25 /* GLOBALS ********************************************************************/
27 // #define PM_CREATE_CONSOLE (WM_APP + 1)
28 // #define PM_DESTROY_CONSOLE (WM_APP + 2)
31 #define CONGUI_MIN_WIDTH 10
32 #define CONGUI_MIN_HEIGHT 10
33 #define CONGUI_UPDATE_TIME 0
34 #define CONGUI_UPDATE_TIMER 1
36 #define CURSOR_BLINK_TIME 500
39 /**************************************************************\
40 \** Define the Console Leader Process for the console window **/
41 #define GWLP_CONWND_ALLOC (2 * sizeof(LONG_PTR))
42 #define GWLP_CONSOLE_LEADER_PID 0
43 #define GWLP_CONSOLE_LEADER_TID 4
46 SetConWndConsoleLeaderCID(IN PGUI_CONSOLE_DATA GuiData
)
48 PCONSOLE_PROCESS_DATA ProcessData
;
49 CLIENT_ID ConsoleLeaderCID
;
51 ProcessData
= CONTAINING_RECORD(GuiData
->Console
->ProcessList
.Blink
,
54 ConsoleLeaderCID
= ProcessData
->Process
->ClientId
;
55 SetWindowLongPtrW(GuiData
->hWindow
, GWLP_CONSOLE_LEADER_PID
,
56 (LONG_PTR
)(ConsoleLeaderCID
.UniqueProcess
));
57 SetWindowLongPtrW(GuiData
->hWindow
, GWLP_CONSOLE_LEADER_TID
,
58 (LONG_PTR
)(ConsoleLeaderCID
.UniqueThread
));
60 /**************************************************************/
62 HICON ghDefaultIcon
= NULL
;
63 HICON ghDefaultIconSm
= NULL
;
64 HCURSOR ghDefaultCursor
= NULL
;
66 typedef struct _GUICONSOLE_MENUITEM
69 const struct _GUICONSOLE_MENUITEM
*SubMenu
;
71 } GUICONSOLE_MENUITEM
, *PGUICONSOLE_MENUITEM
;
73 static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems
[] =
75 { IDS_MARK
, NULL
, ID_SYSTEM_EDIT_MARK
},
76 { IDS_COPY
, NULL
, ID_SYSTEM_EDIT_COPY
},
77 { IDS_PASTE
, NULL
, ID_SYSTEM_EDIT_PASTE
},
78 { IDS_SELECTALL
, NULL
, ID_SYSTEM_EDIT_SELECTALL
},
79 { IDS_SCROLL
, NULL
, ID_SYSTEM_EDIT_SCROLL
},
80 { IDS_FIND
, NULL
, ID_SYSTEM_EDIT_FIND
},
82 { 0, NULL
, 0 } /* End of list */
85 static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems
[] =
87 { IDS_EDIT
, GuiConsoleEditMenuItems
, 0 },
88 { IDS_DEFAULTS
, NULL
, ID_SYSTEM_DEFAULTS
},
89 { IDS_PROPERTIES
, NULL
, ID_SYSTEM_PROPERTIES
},
91 { 0, NULL
, 0 } /* End of list */
95 * Default 16-color palette for foreground and background
96 * (corresponding flags in comments).
98 const COLORREF s_Colors
[16] =
100 RGB(0, 0, 0), // (Black)
101 RGB(0, 0, 128), // BLUE
102 RGB(0, 128, 0), // GREEN
103 RGB(0, 128, 128), // BLUE | GREEN
104 RGB(128, 0, 0), // RED
105 RGB(128, 0, 128), // BLUE | RED
106 RGB(128, 128, 0), // GREEN | RED
107 RGB(192, 192, 192), // BLUE | GREEN | RED
109 RGB(128, 128, 128), // (Grey) INTENSITY
110 RGB(0, 0, 255), // BLUE | INTENSITY
111 RGB(0, 255, 0), // GREEN | INTENSITY
112 RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
113 RGB(255, 0, 0), // RED | INTENSITY
114 RGB(255, 0, 255), // BLUE | RED | INTENSITY
115 RGB(255, 255, 0), // GREEN | RED | INTENSITY
116 RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
119 /* FUNCTIONS ******************************************************************/
121 static LRESULT CALLBACK
122 ConWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
125 RegisterConWndClass(IN HINSTANCE hInstance
)
127 WNDCLASSEXW WndClass
;
130 ghDefaultIcon
= LoadImageW(hInstance
,
131 MAKEINTRESOURCEW(IDI_TERMINAL
),
133 GetSystemMetrics(SM_CXICON
),
134 GetSystemMetrics(SM_CYICON
),
136 ghDefaultIconSm
= LoadImageW(hInstance
,
137 MAKEINTRESOURCEW(IDI_TERMINAL
),
139 GetSystemMetrics(SM_CXSMICON
),
140 GetSystemMetrics(SM_CYSMICON
),
142 ghDefaultCursor
= LoadCursorW(NULL
, IDC_ARROW
);
144 WndClass
.cbSize
= sizeof(WNDCLASSEXW
);
145 WndClass
.lpszClassName
= GUI_CONWND_CLASS
;
146 WndClass
.lpfnWndProc
= ConWndProc
;
147 WndClass
.style
= CS_DBLCLKS
/* | CS_HREDRAW | CS_VREDRAW */;
148 WndClass
.hInstance
= hInstance
;
149 WndClass
.hIcon
= ghDefaultIcon
;
150 WndClass
.hIconSm
= ghDefaultIconSm
;
151 WndClass
.hCursor
= ghDefaultCursor
;
152 WndClass
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
); // The color of a terminal when it is switched off.
153 WndClass
.lpszMenuName
= NULL
;
154 WndClass
.cbClsExtra
= 0;
155 WndClass
.cbWndExtra
= GWLP_CONWND_ALLOC
;
157 WndClassAtom
= RegisterClassExW(&WndClass
);
158 if (WndClassAtom
== 0)
160 DPRINT1("Failed to register GUI console class\n");
164 NtUserConsoleControl(GuiConsoleWndClassAtom
, &WndClassAtom
, sizeof(ATOM
));
167 return (WndClassAtom
!= 0);
171 UnRegisterConWndClass(HINSTANCE hInstance
)
173 return !!UnregisterClassW(GUI_CONWND_CLASS
, hInstance
);
179 GetScreenBufferSizeUnits(IN PCONSOLE_SCREEN_BUFFER Buffer
,
180 IN PGUI_CONSOLE_DATA GuiData
,
182 OUT PUINT HeightUnit
)
184 if (Buffer
== NULL
|| GuiData
== NULL
||
185 WidthUnit
== NULL
|| HeightUnit
== NULL
)
190 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
192 *WidthUnit
= GuiData
->CharWidth
;
193 *HeightUnit
= GuiData
->CharHeight
;
195 else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
203 AppendMenuItems(HMENU hMenu
,
204 const GUICONSOLE_MENUITEM
*Items
)
207 WCHAR szMenuString
[255];
212 if (Items
[i
].uID
!= (UINT
)-1)
214 if (LoadStringW(ConSrvDllInstance
,
217 sizeof(szMenuString
) / sizeof(szMenuString
[0])) > 0)
219 if (Items
[i
].SubMenu
!= NULL
)
221 hSubMenu
= CreatePopupMenu();
222 if (hSubMenu
!= NULL
)
224 AppendMenuItems(hSubMenu
, Items
[i
].SubMenu
);
226 if (!AppendMenuW(hMenu
,
227 MF_STRING
| MF_POPUP
,
231 DestroyMenu(hSubMenu
);
252 } while (!(Items
[i
].uID
== 0 && Items
[i
].SubMenu
== NULL
&& Items
[i
].wCmdID
== 0));
256 CreateSysMenu(HWND hWnd
)
258 HMENU hMenu
= GetSystemMenu(hWnd
, FALSE
);
261 AppendMenuItems(hMenu
, GuiConsoleMainMenuItems
);
267 SendMenuEvent(PCONSOLE Console
, UINT CmdId
)
271 er
.EventType
= MENU_EVENT
;
272 er
.Event
.MenuEvent
.dwCommandId
= CmdId
;
274 DPRINT("Menu item ID: %d\n", CmdId
);
275 ConioProcessInputEvent(Console
, &er
);
279 Copy(PGUI_CONSOLE_DATA GuiData
);
281 Paste(PGUI_CONSOLE_DATA GuiData
);
283 UpdateSelection(PGUI_CONSOLE_DATA GuiData
, PCOORD coord
);
286 Mark(PGUI_CONSOLE_DATA GuiData
)
288 PCONSOLE Console
= GuiData
->Console
;
289 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= GuiData
->ActiveBuffer
;
291 /* Clear the old selection */
292 // UpdateSelection(GuiData, NULL);
293 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
295 /* Restart a new selection */
296 Console
->dwSelectionCursor
.X
= ActiveBuffer
->ViewOrigin
.X
;
297 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ViewOrigin
.Y
;
298 Console
->Selection
.dwSelectionAnchor
= Console
->dwSelectionCursor
;
299 UpdateSelection(GuiData
, &Console
->Selection
.dwSelectionAnchor
);
303 SelectAll(PGUI_CONSOLE_DATA GuiData
)
305 PCONSOLE Console
= GuiData
->Console
;
306 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= GuiData
->ActiveBuffer
;
308 /* Clear the old selection */
309 // UpdateSelection(GuiData, NULL);
310 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
313 * The selection area extends to the whole screen buffer's width.
315 Console
->Selection
.dwSelectionAnchor
.X
= 0;
316 Console
->Selection
.dwSelectionAnchor
.Y
= 0;
317 Console
->dwSelectionCursor
.X
= ActiveBuffer
->ScreenBufferSize
.X
- 1;
320 * Determine whether the selection must extend to just some part
321 * (for text-mode screen buffers) or to all of the screen buffer's
322 * height (for graphics ones).
324 if (GetType(ActiveBuffer
) == TEXTMODE_BUFFER
)
327 * We select all the characters from the first line
328 * to the line where the cursor is positioned.
330 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->CursorPosition
.Y
;
332 else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
335 * We select all the screen buffer area.
337 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ScreenBufferSize
.Y
- 1;
340 /* Restart a new selection */
341 Console
->Selection
.dwFlags
|= CONSOLE_MOUSE_SELECTION
;
342 UpdateSelection(GuiData
, &Console
->dwSelectionCursor
);
346 OnCommand(PGUI_CONSOLE_DATA GuiData
, WPARAM wParam
, LPARAM lParam
)
349 PCONSOLE Console
= GuiData
->Console
;
351 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
358 * In case the selected menu item belongs to the user-reserved menu id range,
359 * send to him a menu event and return directly. The user must handle those
360 * reserved menu commands...
362 if (GuiData
->CmdIdLow
<= (UINT
)wParam
&& (UINT
)wParam
<= GuiData
->CmdIdHigh
)
364 SendMenuEvent(Console
, (UINT
)wParam
);
368 /* ... otherwise, perform actions. */
371 case ID_SYSTEM_EDIT_MARK
:
375 case ID_SYSTEM_EDIT_COPY
:
379 case ID_SYSTEM_EDIT_PASTE
:
383 case ID_SYSTEM_EDIT_SELECTALL
:
387 case ID_SYSTEM_EDIT_SCROLL
:
388 DPRINT1("Scrolling is not handled yet\n");
391 case ID_SYSTEM_EDIT_FIND
:
392 DPRINT1("Finding is not handled yet\n");
395 case ID_SYSTEM_DEFAULTS
:
396 GuiConsoleShowConsoleProperties(GuiData
, TRUE
);
399 case ID_SYSTEM_PROPERTIES
:
400 GuiConsoleShowConsoleProperties(GuiData
, FALSE
);
409 LeaveCriticalSection(&Console
->Lock
);
412 Ret
= DefWindowProcW(GuiData
->hWindow
, WM_SYSCOMMAND
, wParam
, lParam
);
417 static PGUI_CONSOLE_DATA
418 GuiGetGuiData(HWND hWnd
)
420 /* This function ensures that the console pointer is not NULL */
421 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
422 return ( ((GuiData
== NULL
) || (GuiData
->hWindow
== hWnd
&& GuiData
->Console
!= NULL
)) ? GuiData
: NULL
);
426 ResizeConWnd(PGUI_CONSOLE_DATA GuiData
, DWORD WidthUnit
, DWORD HeightUnit
)
428 PCONSOLE_SCREEN_BUFFER Buff
= GuiData
->ActiveBuffer
;
433 Width
= Buff
->ViewSize
.X
* WidthUnit
+
434 2 * (GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXEDGE
));
435 Height
= Buff
->ViewSize
.Y
* HeightUnit
+
436 2 * (GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYEDGE
)) + GetSystemMetrics(SM_CYCAPTION
);
438 /* Set scrollbar sizes */
439 sInfo
.cbSize
= sizeof(SCROLLINFO
);
440 sInfo
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
442 if (Buff
->ScreenBufferSize
.Y
> Buff
->ViewSize
.Y
)
444 sInfo
.nMax
= Buff
->ScreenBufferSize
.Y
- 1;
445 sInfo
.nPage
= Buff
->ViewSize
.Y
;
446 sInfo
.nPos
= Buff
->ViewOrigin
.Y
;
447 SetScrollInfo(GuiData
->hWindow
, SB_VERT
, &sInfo
, TRUE
);
448 Width
+= GetSystemMetrics(SM_CXVSCROLL
);
449 ShowScrollBar(GuiData
->hWindow
, SB_VERT
, TRUE
);
453 ShowScrollBar(GuiData
->hWindow
, SB_VERT
, FALSE
);
456 if (Buff
->ScreenBufferSize
.X
> Buff
->ViewSize
.X
)
458 sInfo
.nMax
= Buff
->ScreenBufferSize
.X
- 1;
459 sInfo
.nPage
= Buff
->ViewSize
.X
;
460 sInfo
.nPos
= Buff
->ViewOrigin
.X
;
461 SetScrollInfo(GuiData
->hWindow
, SB_HORZ
, &sInfo
, TRUE
);
462 Height
+= GetSystemMetrics(SM_CYHSCROLL
);
463 ShowScrollBar(GuiData
->hWindow
, SB_HORZ
, TRUE
);
467 ShowScrollBar(GuiData
->hWindow
, SB_HORZ
, FALSE
);
470 /* Resize the window */
471 SetWindowPos(GuiData
->hWindow
, NULL
, 0, 0, Width
, Height
,
472 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOCOPYBITS
);
473 // NOTE: The SWP_NOCOPYBITS flag can be replaced by a subsequent call
474 // to: InvalidateRect(GuiData->hWindow, NULL, TRUE);
478 OnNcCreate(HWND hWnd
, LPCREATESTRUCTW Create
)
480 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
)Create
->lpCreateParams
;
489 DPRINT1("GuiConsoleNcCreate: No GUI data\n");
493 Console
= GuiData
->Console
;
495 GuiData
->hWindow
= hWnd
;
497 GuiData
->Font
= CreateFontW(LOWORD(GuiData
->GuiInfo
.FontSize
),
498 0, // HIWORD(GuiData->GuiInfo.FontSize),
501 GuiData
->GuiInfo
.FontWeight
,
508 NONANTIALIASED_QUALITY
,
509 FIXED_PITCH
| GuiData
->GuiInfo
.FontFamily
/* FF_DONTCARE */,
510 GuiData
->GuiInfo
.FaceName
);
512 if (NULL
== GuiData
->Font
)
514 DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
515 GuiData
->hWindow
= NULL
;
516 SetEvent(GuiData
->hGuiInitEvent
);
519 hDC
= GetDC(GuiData
->hWindow
);
522 DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
523 DeleteObject(GuiData
->Font
);
524 GuiData
->hWindow
= NULL
;
525 SetEvent(GuiData
->hGuiInitEvent
);
528 OldFont
= SelectObject(hDC
, GuiData
->Font
);
531 DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
532 ReleaseDC(GuiData
->hWindow
, hDC
);
533 DeleteObject(GuiData
->Font
);
534 GuiData
->hWindow
= NULL
;
535 SetEvent(GuiData
->hGuiInitEvent
);
538 if (!GetTextMetricsW(hDC
, &Metrics
))
540 DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
541 SelectObject(hDC
, OldFont
);
542 ReleaseDC(GuiData
->hWindow
, hDC
);
543 DeleteObject(GuiData
->Font
);
544 GuiData
->hWindow
= NULL
;
545 SetEvent(GuiData
->hGuiInitEvent
);
548 GuiData
->CharWidth
= Metrics
.tmMaxCharWidth
;
549 GuiData
->CharHeight
= Metrics
.tmHeight
+ Metrics
.tmExternalLeading
;
551 /* Measure real char width more precisely if possible. */
552 if (GetTextExtentPoint32W(hDC
, L
"R", 1, &CharSize
))
553 GuiData
->CharWidth
= CharSize
.cx
;
555 SelectObject(hDC
, OldFont
);
557 ReleaseDC(GuiData
->hWindow
, hDC
);
559 /* Initialize the terminal framebuffer */
560 GuiData
->hMemDC
= CreateCompatibleDC(NULL
);
561 GuiData
->hBitmap
= NULL
;
562 GuiData
->hSysPalette
= NULL
; /* Original system palette */
564 /* Update the icons of the window */
565 if (GuiData
->hIcon
!= ghDefaultIcon
)
567 DefWindowProcW(GuiData
->hWindow
, WM_SETICON
, ICON_BIG
, (LPARAM
)GuiData
->hIcon
);
568 DefWindowProcW(GuiData
->hWindow
, WM_SETICON
, ICON_SMALL
, (LPARAM
)GuiData
->hIconSm
);
571 // FIXME: Keep these instructions here ? ///////////////////////////////////
572 Console
->ActiveBuffer
->CursorBlinkOn
= TRUE
;
573 Console
->ActiveBuffer
->ForceCursorOff
= FALSE
;
574 ////////////////////////////////////////////////////////////////////////////
576 SetWindowLongPtrW(GuiData
->hWindow
, GWLP_USERDATA
, (DWORD_PTR
)GuiData
);
578 SetTimer(GuiData
->hWindow
, CONGUI_UPDATE_TIMER
, CONGUI_UPDATE_TIME
, NULL
);
579 CreateSysMenu(GuiData
->hWindow
);
581 DPRINT("OnNcCreate - setting start event\n");
582 SetEvent(GuiData
->hGuiInitEvent
);
584 return (BOOL
)DefWindowProcW(GuiData
->hWindow
, WM_NCCREATE
, 0, (LPARAM
)Create
);
589 EnterFullScreen(PGUI_CONSOLE_DATA GuiData
);
591 LeaveFullScreen(PGUI_CONSOLE_DATA GuiData
);
593 SwitchFullScreen(PGUI_CONSOLE_DATA GuiData
, BOOL FullScreen
);
595 GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData
);
598 OnActivate(PGUI_CONSOLE_DATA GuiData
, WPARAM wParam
)
600 PCONSOLE Console
= GuiData
->Console
;
601 WORD ActivationState
= LOWORD(wParam
);
603 DPRINT1("WM_ACTIVATE - ActivationState = %d\n");
605 if ( ActivationState
== WA_ACTIVE
||
606 ActivationState
== WA_CLICKACTIVE
)
608 if (GuiData
->GuiInfo
.FullScreen
)
610 EnterFullScreen(GuiData
);
611 // // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
612 // SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
615 else // if (ActivationState == WA_INACTIVE)
617 if (GuiData
->GuiInfo
.FullScreen
)
619 SendMessageW(GuiData
->hWindow
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
620 LeaveFullScreen(GuiData
);
621 // // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
622 // SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
627 * When we are in QuickEdit mode, ignore the next mouse signal
628 * when we are going to be enabled again via the mouse, in order
629 * to prevent e.g. an erroneous right-click from the user which
630 * would have as an effect to paste some unwanted text...
632 if (Console
->QuickEdit
&& (ActivationState
== WA_CLICKACTIVE
))
633 GuiData
->IgnoreNextMouseSignal
= TRUE
;
637 OnFocus(PGUI_CONSOLE_DATA GuiData
, BOOL SetFocus
)
639 PCONSOLE Console
= GuiData
->Console
;
642 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
644 er
.EventType
= FOCUS_EVENT
;
645 er
.Event
.FocusEvent
.bSetFocus
= SetFocus
;
646 ConioProcessInputEvent(Console
, &er
);
649 DPRINT1("TODO: Create console caret\n");
651 DPRINT1("TODO: Destroy console caret\n");
653 LeaveCriticalSection(&Console
->Lock
);
657 SmallRectToRect(PGUI_CONSOLE_DATA GuiData
, PRECT Rect
, PSMALL_RECT SmallRect
)
659 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
660 UINT WidthUnit
, HeightUnit
;
662 GetScreenBufferSizeUnits(Buffer
, GuiData
, &WidthUnit
, &HeightUnit
);
664 Rect
->left
= (SmallRect
->Left
- Buffer
->ViewOrigin
.X
) * WidthUnit
;
665 Rect
->top
= (SmallRect
->Top
- Buffer
->ViewOrigin
.Y
) * HeightUnit
;
666 Rect
->right
= (SmallRect
->Right
+ 1 - Buffer
->ViewOrigin
.X
) * WidthUnit
;
667 Rect
->bottom
= (SmallRect
->Bottom
+ 1 - Buffer
->ViewOrigin
.Y
) * HeightUnit
;
671 UpdateSelection(PGUI_CONSOLE_DATA GuiData
, PCOORD coord
)
673 PCONSOLE Console
= GuiData
->Console
;
676 SmallRectToRect(GuiData
, &oldRect
, &Console
->Selection
.srSelection
);
683 /* Exchange left/top with right/bottom if required */
684 rc
.Left
= min(Console
->Selection
.dwSelectionAnchor
.X
, coord
->X
);
685 rc
.Top
= min(Console
->Selection
.dwSelectionAnchor
.Y
, coord
->Y
);
686 rc
.Right
= max(Console
->Selection
.dwSelectionAnchor
.X
, coord
->X
);
687 rc
.Bottom
= max(Console
->Selection
.dwSelectionAnchor
.Y
, coord
->Y
);
689 SmallRectToRect(GuiData
, &newRect
, &rc
);
691 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
693 if (memcmp(&rc
, &Console
->Selection
.srSelection
, sizeof(SMALL_RECT
)) != 0)
697 /* Calculate the region that needs to be updated */
698 if ((rgn1
= CreateRectRgnIndirect(&oldRect
)))
700 if ((rgn2
= CreateRectRgnIndirect(&newRect
)))
702 if (CombineRgn(rgn1
, rgn2
, rgn1
, RGN_XOR
) != ERROR
)
704 InvalidateRgn(GuiData
->hWindow
, rgn1
, FALSE
);
714 InvalidateRect(GuiData
->hWindow
, &newRect
, FALSE
);
717 Console
->Selection
.dwFlags
|= CONSOLE_SELECTION_NOT_EMPTY
;
718 Console
->Selection
.srSelection
= rc
;
719 Console
->dwSelectionCursor
= *coord
;
721 if ((Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) == 0)
723 LPWSTR SelectionType
, WindowTitle
= NULL
;
726 /* Clear the old selection */
727 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
729 InvalidateRect(GuiData
->hWindow
, &oldRect
, FALSE
);
732 if (Console
->Selection
.dwFlags
& CONSOLE_MOUSE_SELECTION
)
734 SelectionType
= L
"Selection - ";
738 SelectionType
= L
"Mark - ";
741 Length
= Console
->Title
.Length
+ wcslen(SelectionType
) + 1;
742 WindowTitle
= ConsoleAllocHeap(0, Length
* sizeof(WCHAR
));
743 wcscpy(WindowTitle
, SelectionType
);
744 wcscat(WindowTitle
, Console
->Title
.Buffer
);
745 SetWindowText(GuiData
->hWindow
, WindowTitle
);
746 ConsoleFreeHeap(WindowTitle
);
748 Console
->Selection
.dwFlags
|= CONSOLE_SELECTION_IN_PROGRESS
;
749 ConioPause(Console
, PAUSED_FROM_SELECTION
);
754 /* Clear the selection */
755 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
757 InvalidateRect(GuiData
->hWindow
, &oldRect
, FALSE
);
760 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
761 ConioUnpause(Console
, PAUSED_FROM_SELECTION
);
763 SetWindowText(GuiData
->hWindow
, Console
->Title
.Buffer
);
769 GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer
,
770 PGUI_CONSOLE_DATA GuiData
,
772 PRECT rcFramebuffer
);
774 GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer
,
775 PGUI_CONSOLE_DATA GuiData
,
777 PRECT rcFramebuffer
);
780 OnPaint(PGUI_CONSOLE_DATA GuiData
)
783 PCONSOLE Console
= GuiData
->Console
;
784 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
788 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
793 ActiveBuffer
= GuiData
->ActiveBuffer
;
795 BeginPaint(GuiData
->hWindow
, &ps
);
796 if (ps
.hdc
!= NULL
&&
797 ps
.rcPaint
.left
< ps
.rcPaint
.right
&&
798 ps
.rcPaint
.top
< ps
.rcPaint
.bottom
)
800 EnterCriticalSection(&GuiData
->Lock
);
802 /* Compose the current screen-buffer on-memory */
803 if (GetType(ActiveBuffer
) == TEXTMODE_BUFFER
)
805 GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER
)ActiveBuffer
,
806 GuiData
, &ps
.rcPaint
, &rcPaint
);
808 else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
810 GuiPaintGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER
)ActiveBuffer
,
811 GuiData
, &ps
.rcPaint
, &rcPaint
);
814 /* Send it to screen */
818 rcPaint
.right
- rcPaint
.left
,
819 rcPaint
.bottom
- rcPaint
.top
,
825 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
827 SmallRectToRect(GuiData
, &rcPaint
, &Console
->Selection
.srSelection
);
829 /* Invert the selection */
830 if (IntersectRect(&rcPaint
, &ps
.rcPaint
, &rcPaint
))
832 InvertRect(ps
.hdc
, &rcPaint
);
836 LeaveCriticalSection(&GuiData
->Lock
);
838 EndPaint(GuiData
->hWindow
, &ps
);
842 LeaveCriticalSection(&Console
->Lock
);
844 DefWindowProcW(GuiData
->hWindow
, WM_PAINT
, 0, 0);
850 OnPaletteChanged(PGUI_CONSOLE_DATA GuiData
)
852 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= GuiData
->ActiveBuffer
;
854 // See WM_PALETTECHANGED message
855 // if ((HWND)wParam == hWnd) break;
857 // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
858 if (ActiveBuffer
->PaletteHandle
)
860 DPRINT("WM_PALETTECHANGED changing palette\n");
862 /* Specify the use of the system palette for the framebuffer */
863 SetSystemPaletteUse(GuiData
->hMemDC
, ActiveBuffer
->PaletteUsage
);
865 /* Realize the (logical) palette */
866 RealizePalette(GuiData
->hMemDC
);
871 IsSystemKey(WORD VirtualKeyCode
)
873 switch (VirtualKeyCode
)
875 /* From MSDN, "Virtual-Key Codes" */
894 OnKey(PGUI_CONSOLE_DATA GuiData
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
896 PCONSOLE Console
= GuiData
->Console
;
897 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
899 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
901 ActiveBuffer
= GuiData
->ActiveBuffer
;
903 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
)
905 WORD VirtualKeyCode
= LOWORD(wParam
);
907 if (msg
!= WM_KEYDOWN
) goto Quit
;
909 if (VirtualKeyCode
== VK_RETURN
)
911 /* Copy (and clear) selection if ENTER is pressed */
915 else if ( VirtualKeyCode
== VK_ESCAPE
||
916 (VirtualKeyCode
== 'C' && GetKeyState(VK_CONTROL
) & 0x8000) )
918 /* Cancel selection if ESC or Ctrl-C are pressed */
919 UpdateSelection(GuiData
, NULL
);
923 if ((Console
->Selection
.dwFlags
& CONSOLE_MOUSE_SELECTION
) == 0)
925 /* Keyboard selection mode */
926 BOOL Interpreted
= FALSE
;
927 BOOL MajPressed
= (GetKeyState(VK_SHIFT
) & 0x8000);
929 switch (VirtualKeyCode
)
934 if (Console
->dwSelectionCursor
.X
> 0)
935 Console
->dwSelectionCursor
.X
--;
943 if (Console
->dwSelectionCursor
.X
< ActiveBuffer
->ScreenBufferSize
.X
- 1)
944 Console
->dwSelectionCursor
.X
++;
952 if (Console
->dwSelectionCursor
.Y
> 0)
953 Console
->dwSelectionCursor
.Y
--;
961 if (Console
->dwSelectionCursor
.Y
< ActiveBuffer
->ScreenBufferSize
.Y
- 1)
962 Console
->dwSelectionCursor
.Y
++;
970 Console
->dwSelectionCursor
.X
= 0;
971 Console
->dwSelectionCursor
.Y
= 0;
978 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ScreenBufferSize
.Y
- 1;
985 Console
->dwSelectionCursor
.Y
-= ActiveBuffer
->ViewSize
.Y
;
986 if (Console
->dwSelectionCursor
.Y
< 0)
987 Console
->dwSelectionCursor
.Y
= 0;
995 Console
->dwSelectionCursor
.Y
+= ActiveBuffer
->ViewSize
.Y
;
996 if (Console
->dwSelectionCursor
.Y
>= ActiveBuffer
->ScreenBufferSize
.Y
)
997 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ScreenBufferSize
.Y
- 1;
1009 Console
->Selection
.dwSelectionAnchor
= Console
->dwSelectionCursor
;
1011 UpdateSelection(GuiData
, &Console
->dwSelectionCursor
);
1013 else if (!IsSystemKey(VirtualKeyCode
))
1015 /* Emit an error beep sound */
1016 SendNotifyMessage(GuiData
->hWindow
, PM_CONSOLE_BEEP
, 0, 0);
1023 /* Mouse selection mode */
1025 if (!IsSystemKey(VirtualKeyCode
))
1027 /* Clear the selection and send the key into the input buffer */
1028 UpdateSelection(GuiData
, NULL
);
1037 if ((Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) == 0)
1041 Message
.hwnd
= GuiData
->hWindow
;
1042 Message
.message
= msg
;
1043 Message
.wParam
= wParam
;
1044 Message
.lParam
= lParam
;
1046 ConioProcessKey(Console
, &Message
);
1050 LeaveCriticalSection(&Console
->Lock
);
1054 // FIXME: Remove after fixing OnTimer
1056 InvalidateCell(PGUI_CONSOLE_DATA GuiData
,
1060 OnTimer(PGUI_CONSOLE_DATA GuiData
)
1062 PCONSOLE Console
= GuiData
->Console
;
1063 PCONSOLE_SCREEN_BUFFER Buff
;
1065 SetTimer(GuiData
->hWindow
, CONGUI_UPDATE_TIMER
, CURSOR_BLINK_TIME
, NULL
);
1067 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
1069 Buff
= GuiData
->ActiveBuffer
;
1071 if (GetType(Buff
) == TEXTMODE_BUFFER
)
1073 InvalidateCell(GuiData
, Buff
->CursorPosition
.X
, Buff
->CursorPosition
.Y
);
1074 Buff
->CursorBlinkOn
= !Buff
->CursorBlinkOn
;
1076 if ((GuiData
->OldCursor
.x
!= Buff
->CursorPosition
.X
) ||
1077 (GuiData
->OldCursor
.y
!= Buff
->CursorPosition
.Y
))
1080 int OldScrollX
= -1, OldScrollY
= -1;
1081 int NewScrollX
= -1, NewScrollY
= -1;
1083 xScroll
.cbSize
= sizeof(SCROLLINFO
);
1084 xScroll
.fMask
= SIF_POS
;
1085 // Capture the original position of the scroll bars and save them.
1086 if (GetScrollInfo(GuiData
->hWindow
, SB_HORZ
, &xScroll
)) OldScrollX
= xScroll
.nPos
;
1087 if (GetScrollInfo(GuiData
->hWindow
, SB_VERT
, &xScroll
)) OldScrollY
= xScroll
.nPos
;
1089 // If we successfully got the info for the horizontal scrollbar
1090 if (OldScrollX
>= 0)
1092 if ((Buff
->CursorPosition
.X
< Buff
->ViewOrigin
.X
) ||
1093 (Buff
->CursorPosition
.X
>= (Buff
->ViewOrigin
.X
+ Buff
->ViewSize
.X
)))
1095 // Handle the horizontal scroll bar
1096 if (Buff
->CursorPosition
.X
>= Buff
->ViewSize
.X
)
1097 NewScrollX
= Buff
->CursorPosition
.X
- Buff
->ViewSize
.X
+ 1;
1103 NewScrollX
= OldScrollX
;
1106 // If we successfully got the info for the vertical scrollbar
1107 if (OldScrollY
>= 0)
1109 if ((Buff
->CursorPosition
.Y
< Buff
->ViewOrigin
.Y
) ||
1110 (Buff
->CursorPosition
.Y
>= (Buff
->ViewOrigin
.Y
+ Buff
->ViewSize
.Y
)))
1112 // Handle the vertical scroll bar
1113 if (Buff
->CursorPosition
.Y
>= Buff
->ViewSize
.Y
)
1114 NewScrollY
= Buff
->CursorPosition
.Y
- Buff
->ViewSize
.Y
+ 1;
1120 NewScrollY
= OldScrollY
;
1124 // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area
1125 // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar
1126 // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
1127 // and their associated scrollbar is left alone.
1128 if ((OldScrollX
!= NewScrollX
) || (OldScrollY
!= NewScrollY
))
1130 Buff
->ViewOrigin
.X
= NewScrollX
;
1131 Buff
->ViewOrigin
.Y
= NewScrollY
;
1132 ScrollWindowEx(GuiData
->hWindow
,
1133 (OldScrollX
- NewScrollX
) * GuiData
->CharWidth
,
1134 (OldScrollY
- NewScrollY
) * GuiData
->CharHeight
,
1140 if (NewScrollX
>= 0)
1142 xScroll
.nPos
= NewScrollX
;
1143 SetScrollInfo(GuiData
->hWindow
, SB_HORZ
, &xScroll
, TRUE
);
1145 if (NewScrollY
>= 0)
1147 xScroll
.nPos
= NewScrollY
;
1148 SetScrollInfo(GuiData
->hWindow
, SB_VERT
, &xScroll
, TRUE
);
1150 UpdateWindow(GuiData
->hWindow
);
1151 // InvalidateRect(GuiData->hWindow, NULL, FALSE);
1152 GuiData
->OldCursor
.x
= Buff
->CursorPosition
.X
;
1153 GuiData
->OldCursor
.y
= Buff
->CursorPosition
.Y
;
1157 else /* if (GetType(Buff) == GRAPHICS_BUFFER) */
1161 LeaveCriticalSection(&Console
->Lock
);
1165 OnClose(PGUI_CONSOLE_DATA GuiData
)
1167 PCONSOLE Console
= GuiData
->Console
;
1169 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
1172 // TODO: Prompt for termination ? (Warn the user about possible apps running in this console)
1175 * FIXME: Windows will wait up to 5 seconds for the thread to exit.
1176 * We shouldn't wait here, though, since the console lock is entered.
1177 * A copy of the thread list probably needs to be made.
1179 ConDrvConsoleProcessCtrlEvent(Console
, 0, CTRL_CLOSE_EVENT
);
1181 LeaveCriticalSection(&Console
->Lock
);
1186 OnNcDestroy(HWND hWnd
)
1188 PGUI_CONSOLE_DATA GuiData
= GuiGetGuiData(hWnd
);
1190 KillTimer(hWnd
, CONGUI_UPDATE_TIMER
);
1191 GetSystemMenu(hWnd
, TRUE
);
1195 /* Free the terminal framebuffer */
1196 if (GuiData
->hMemDC
) DeleteDC(GuiData
->hMemDC
);
1197 if (GuiData
->hBitmap
) DeleteObject(GuiData
->hBitmap
);
1198 // if (GuiData->hSysPalette) DeleteObject(GuiData->hSysPalette);
1199 if (GuiData
->Font
) DeleteObject(GuiData
->Font
);
1202 /* Free the GuiData registration */
1203 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (DWORD_PTR
)NULL
);
1205 return DefWindowProcW(hWnd
, WM_NCDESTROY
, 0, 0);
1209 PointToCoord(PGUI_CONSOLE_DATA GuiData
, LPARAM lParam
)
1211 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1213 UINT WidthUnit
, HeightUnit
;
1215 GetScreenBufferSizeUnits(Buffer
, GuiData
, &WidthUnit
, &HeightUnit
);
1217 Coord
.X
= Buffer
->ViewOrigin
.X
+ ((SHORT
)LOWORD(lParam
) / (int)WidthUnit
);
1218 Coord
.Y
= Buffer
->ViewOrigin
.Y
+ ((SHORT
)HIWORD(lParam
) / (int)HeightUnit
);
1220 /* Clip coordinate to ensure it's inside buffer */
1223 else if (Coord
.X
>= Buffer
->ScreenBufferSize
.X
)
1224 Coord
.X
= Buffer
->ScreenBufferSize
.X
- 1;
1228 else if (Coord
.Y
>= Buffer
->ScreenBufferSize
.Y
)
1229 Coord
.Y
= Buffer
->ScreenBufferSize
.Y
- 1;
1235 OnMouse(PGUI_CONSOLE_DATA GuiData
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1238 PCONSOLE Console
= GuiData
->Console
;
1240 if (GuiData
->IgnoreNextMouseSignal
)
1242 if (msg
!= WM_LBUTTONDOWN
&&
1243 msg
!= WM_MBUTTONDOWN
&&
1244 msg
!= WM_RBUTTONDOWN
&&
1245 msg
!= WM_MOUSEMOVE
)
1248 * If this mouse signal is not a button-down action or a move,
1249 * then it is the last signal being ignored.
1251 GuiData
->IgnoreNextMouseSignal
= FALSE
;
1256 * This mouse signal is a button-down action or a move.
1257 * Ignore it and perform default action.
1264 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
1270 if ( (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) ||
1271 (Console
->QuickEdit
) )
1275 case WM_LBUTTONDOWN
:
1277 /* Clear the old selection */
1278 // UpdateSelection(GuiData, NULL);
1279 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
1281 /* Restart a new selection */
1282 Console
->Selection
.dwSelectionAnchor
= PointToCoord(GuiData
, lParam
);
1283 SetCapture(GuiData
->hWindow
);
1284 Console
->Selection
.dwFlags
|= CONSOLE_MOUSE_SELECTION
| CONSOLE_MOUSE_DOWN
;
1285 UpdateSelection(GuiData
, &Console
->Selection
.dwSelectionAnchor
);
1294 if (!(Console
->Selection
.dwFlags
& CONSOLE_MOUSE_DOWN
)) break;
1296 // c = PointToCoord(GuiData, lParam);
1297 Console
->Selection
.dwFlags
&= ~CONSOLE_MOUSE_DOWN
;
1298 // UpdateSelection(GuiData, &c);
1304 case WM_LBUTTONDBLCLK
:
1306 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1308 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
1310 #ifdef IS_WHITESPACE
1311 #undef IS_WHITESPACE
1313 #define IS_WHITESPACE(c) \
1314 ((c) == L'\0' || (c) == L' ' || (c) == L'\t' || (c) == L'\r' || (c) == L'\n')
1316 PTEXTMODE_SCREEN_BUFFER TextBuffer
= (PTEXTMODE_SCREEN_BUFFER
)Buffer
;
1318 PCHAR_INFO ptrL
, ptrR
;
1320 /* Starting point */
1321 cL
= cR
= PointToCoord(GuiData
, lParam
);
1322 ptrL
= ptrR
= ConioCoordToPointer(TextBuffer
, cL
.X
, cL
.Y
);
1324 /* Enlarge the selection by checking for whitespace */
1325 while ((0 < cL
.X
) && !IS_WHITESPACE(ptrL
->Char
.UnicodeChar
)
1326 && !IS_WHITESPACE((ptrL
-1)->Char
.UnicodeChar
))
1331 while ((cR
.X
< TextBuffer
->ScreenBufferSize
.X
- 1) &&
1332 !IS_WHITESPACE(ptrR
->Char
.UnicodeChar
) &&
1333 !IS_WHITESPACE((ptrR
+1)->Char
.UnicodeChar
))
1340 * Update the selection started with the single
1341 * left-click that preceded this double-click.
1343 Console
->Selection
.dwSelectionAnchor
= cL
;
1344 Console
->dwSelectionCursor
= cR
;
1346 Console
->Selection
.dwFlags
|= CONSOLE_MOUSE_SELECTION
| CONSOLE_MOUSE_DOWN
;
1347 UpdateSelection(GuiData
, &Console
->dwSelectionCursor
);
1349 /* Ignore the next mouse move signal */
1350 GuiData
->IgnoreNextMouseSignal
= TRUE
;
1356 case WM_RBUTTONDOWN
:
1357 case WM_RBUTTONDBLCLK
:
1359 if (!(Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
))
1368 /* Ignore the next mouse move signal */
1369 GuiData
->IgnoreNextMouseSignal
= TRUE
;
1377 if (!(wParam
& MK_LBUTTON
)) break;
1378 if (!(Console
->Selection
.dwFlags
& CONSOLE_MOUSE_DOWN
)) break;
1380 c
= PointToCoord(GuiData
, lParam
); /* TODO: Scroll buffer to bring c into view */
1381 UpdateSelection(GuiData
, &c
);
1387 Err
= FALSE
; // TRUE;
1391 else if (Console
->InputBuffer
.Mode
& ENABLE_MOUSE_INPUT
)
1394 WORD wKeyState
= GET_KEYSTATE_WPARAM(wParam
);
1395 DWORD dwButtonState
= 0;
1396 DWORD dwControlKeyState
= 0;
1397 DWORD dwEventFlags
= 0;
1401 case WM_LBUTTONDOWN
:
1402 SetCapture(GuiData
->hWindow
);
1403 dwButtonState
= FROM_LEFT_1ST_BUTTON_PRESSED
;
1407 case WM_MBUTTONDOWN
:
1408 SetCapture(GuiData
->hWindow
);
1409 dwButtonState
= FROM_LEFT_2ND_BUTTON_PRESSED
;
1413 case WM_RBUTTONDOWN
:
1414 SetCapture(GuiData
->hWindow
);
1415 dwButtonState
= RIGHTMOST_BUTTON_PRESSED
;
1437 case WM_LBUTTONDBLCLK
:
1438 dwButtonState
= FROM_LEFT_1ST_BUTTON_PRESSED
;
1439 dwEventFlags
= DOUBLE_CLICK
;
1442 case WM_MBUTTONDBLCLK
:
1443 dwButtonState
= FROM_LEFT_2ND_BUTTON_PRESSED
;
1444 dwEventFlags
= DOUBLE_CLICK
;
1447 case WM_RBUTTONDBLCLK
:
1448 dwButtonState
= RIGHTMOST_BUTTON_PRESSED
;
1449 dwEventFlags
= DOUBLE_CLICK
;
1454 dwEventFlags
= MOUSE_MOVED
;
1458 dwButtonState
= GET_WHEEL_DELTA_WPARAM(wParam
) << 16;
1459 dwEventFlags
= MOUSE_WHEELED
;
1462 case WM_MOUSEHWHEEL
:
1463 dwButtonState
= GET_WHEEL_DELTA_WPARAM(wParam
) << 16;
1464 dwEventFlags
= MOUSE_HWHEELED
;
1474 if (wKeyState
& MK_LBUTTON
)
1475 dwButtonState
|= FROM_LEFT_1ST_BUTTON_PRESSED
;
1476 if (wKeyState
& MK_MBUTTON
)
1477 dwButtonState
|= FROM_LEFT_2ND_BUTTON_PRESSED
;
1478 if (wKeyState
& MK_RBUTTON
)
1479 dwButtonState
|= RIGHTMOST_BUTTON_PRESSED
;
1481 if (GetKeyState(VK_RMENU
) & 0x8000)
1482 dwControlKeyState
|= RIGHT_ALT_PRESSED
;
1483 if (GetKeyState(VK_LMENU
) & 0x8000)
1484 dwControlKeyState
|= LEFT_ALT_PRESSED
;
1485 if (GetKeyState(VK_RCONTROL
) & 0x8000)
1486 dwControlKeyState
|= RIGHT_CTRL_PRESSED
;
1487 if (GetKeyState(VK_LCONTROL
) & 0x8000)
1488 dwControlKeyState
|= LEFT_CTRL_PRESSED
;
1489 if (GetKeyState(VK_SHIFT
) & 0x8000)
1490 dwControlKeyState
|= SHIFT_PRESSED
;
1491 if (GetKeyState(VK_NUMLOCK
) & 0x0001)
1492 dwControlKeyState
|= NUMLOCK_ON
;
1493 if (GetKeyState(VK_SCROLL
) & 0x0001)
1494 dwControlKeyState
|= SCROLLLOCK_ON
;
1495 if (GetKeyState(VK_CAPITAL
) & 0x0001)
1496 dwControlKeyState
|= CAPSLOCK_ON
;
1497 /* See WM_CHAR MSDN documentation for instance */
1498 if (lParam
& 0x01000000)
1499 dwControlKeyState
|= ENHANCED_KEY
;
1501 er
.EventType
= MOUSE_EVENT
;
1502 er
.Event
.MouseEvent
.dwMousePosition
= PointToCoord(GuiData
, lParam
);
1503 er
.Event
.MouseEvent
.dwButtonState
= dwButtonState
;
1504 er
.Event
.MouseEvent
.dwControlKeyState
= dwControlKeyState
;
1505 er
.Event
.MouseEvent
.dwEventFlags
= dwEventFlags
;
1507 ConioProcessInputEvent(Console
, &er
);
1515 LeaveCriticalSection(&Console
->Lock
);
1519 return DefWindowProcW(GuiData
->hWindow
, msg
, wParam
, lParam
);
1525 GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer
,
1526 PGUI_CONSOLE_DATA GuiData
);
1528 GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer
,
1529 PGUI_CONSOLE_DATA GuiData
);
1532 Copy(PGUI_CONSOLE_DATA GuiData
)
1534 if (OpenClipboard(GuiData
->hWindow
) == TRUE
)
1536 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1538 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
1540 GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER
)Buffer
, GuiData
);
1542 else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
1544 GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER
)Buffer
, GuiData
);
1550 /* Clear the selection */
1551 UpdateSelection(GuiData
, NULL
);
1555 GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer
,
1556 PGUI_CONSOLE_DATA GuiData
);
1558 GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer
,
1559 PGUI_CONSOLE_DATA GuiData
);
1562 Paste(PGUI_CONSOLE_DATA GuiData
)
1564 if (OpenClipboard(GuiData
->hWindow
) == TRUE
)
1566 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1568 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
1570 GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER
)Buffer
, GuiData
);
1572 else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
1574 GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER
)Buffer
, GuiData
);
1582 OnGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData
, PMINMAXINFO minMaxInfo
)
1584 PCONSOLE Console
= GuiData
->Console
;
1585 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
1587 UINT WidthUnit
, HeightUnit
;
1589 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
1591 ActiveBuffer
= GuiData
->ActiveBuffer
;
1593 GetScreenBufferSizeUnits(ActiveBuffer
, GuiData
, &WidthUnit
, &HeightUnit
);
1595 windx
= CONGUI_MIN_WIDTH
* WidthUnit
+ 2 * (GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXEDGE
));
1596 windy
= CONGUI_MIN_HEIGHT
* HeightUnit
+ 2 * (GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYEDGE
)) + GetSystemMetrics(SM_CYCAPTION
);
1598 minMaxInfo
->ptMinTrackSize
.x
= windx
;
1599 minMaxInfo
->ptMinTrackSize
.y
= windy
;
1601 windx
= (ActiveBuffer
->ScreenBufferSize
.X
) * WidthUnit
+ 2 * (GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXEDGE
));
1602 windy
= (ActiveBuffer
->ScreenBufferSize
.Y
) * HeightUnit
+ 2 * (GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYEDGE
)) + GetSystemMetrics(SM_CYCAPTION
);
1604 if (ActiveBuffer
->ViewSize
.X
< ActiveBuffer
->ScreenBufferSize
.X
) windy
+= GetSystemMetrics(SM_CYHSCROLL
); // window currently has a horizontal scrollbar
1605 if (ActiveBuffer
->ViewSize
.Y
< ActiveBuffer
->ScreenBufferSize
.Y
) windx
+= GetSystemMetrics(SM_CXVSCROLL
); // window currently has a vertical scrollbar
1607 minMaxInfo
->ptMaxTrackSize
.x
= windx
;
1608 minMaxInfo
->ptMaxTrackSize
.y
= windy
;
1610 LeaveCriticalSection(&Console
->Lock
);
1614 OnSize(PGUI_CONSOLE_DATA GuiData
, WPARAM wParam
, LPARAM lParam
)
1616 PCONSOLE Console
= GuiData
->Console
;
1618 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
1620 if ((GuiData
->WindowSizeLock
== FALSE
) &&
1621 (wParam
== SIZE_RESTORED
|| wParam
== SIZE_MAXIMIZED
|| wParam
== SIZE_MINIMIZED
))
1623 PCONSOLE_SCREEN_BUFFER Buff
= GuiData
->ActiveBuffer
;
1624 DWORD windx
, windy
, charx
, chary
;
1625 UINT WidthUnit
, HeightUnit
;
1627 GetScreenBufferSizeUnits(Buff
, GuiData
, &WidthUnit
, &HeightUnit
);
1629 GuiData
->WindowSizeLock
= TRUE
;
1631 windx
= LOWORD(lParam
);
1632 windy
= HIWORD(lParam
);
1634 // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar)
1635 if (Buff
->ViewSize
.X
< Buff
->ScreenBufferSize
.X
) windy
+= GetSystemMetrics(SM_CYHSCROLL
); // window currently has a horizontal scrollbar
1636 if (Buff
->ViewSize
.Y
< Buff
->ScreenBufferSize
.Y
) windx
+= GetSystemMetrics(SM_CXVSCROLL
); // window currently has a vertical scrollbar
1638 charx
= windx
/ (int)WidthUnit
;
1639 chary
= windy
/ (int)HeightUnit
;
1641 // Character alignment (round size up or down)
1642 if ((windx
% WidthUnit
) >= (WidthUnit
/ 2)) ++charx
;
1643 if ((windy
% HeightUnit
) >= (HeightUnit
/ 2)) ++chary
;
1645 // Compensate for added scroll bars in new window
1646 if (charx
< Buff
->ScreenBufferSize
.X
) windy
-= GetSystemMetrics(SM_CYHSCROLL
); // new window will have a horizontal scroll bar
1647 if (chary
< Buff
->ScreenBufferSize
.Y
) windx
-= GetSystemMetrics(SM_CXVSCROLL
); // new window will have a vertical scroll bar
1649 charx
= windx
/ (int)WidthUnit
;
1650 chary
= windy
/ (int)HeightUnit
;
1652 // Character alignment (round size up or down)
1653 if ((windx
% WidthUnit
) >= (WidthUnit
/ 2)) ++charx
;
1654 if ((windy
% HeightUnit
) >= (HeightUnit
/ 2)) ++chary
;
1657 if ((charx
!= Buff
->ViewSize
.X
) || (chary
!= Buff
->ViewSize
.Y
))
1659 Buff
->ViewSize
.X
= (charx
<= Buff
->ScreenBufferSize
.X
) ? charx
: Buff
->ScreenBufferSize
.X
;
1660 Buff
->ViewSize
.Y
= (chary
<= Buff
->ScreenBufferSize
.Y
) ? chary
: Buff
->ScreenBufferSize
.Y
;
1663 ResizeConWnd(GuiData
, WidthUnit
, HeightUnit
);
1665 // Adjust the start of the visible area if we are attempting to show nonexistent areas
1666 if ((Buff
->ScreenBufferSize
.X
- Buff
->ViewOrigin
.X
) < Buff
->ViewSize
.X
) Buff
->ViewOrigin
.X
= Buff
->ScreenBufferSize
.X
- Buff
->ViewSize
.X
;
1667 if ((Buff
->ScreenBufferSize
.Y
- Buff
->ViewOrigin
.Y
) < Buff
->ViewSize
.Y
) Buff
->ViewOrigin
.Y
= Buff
->ScreenBufferSize
.Y
- Buff
->ViewSize
.Y
;
1668 InvalidateRect(GuiData
->hWindow
, NULL
, TRUE
);
1670 GuiData
->WindowSizeLock
= FALSE
;
1673 LeaveCriticalSection(&Console
->Lock
);
1677 OnMove(PGUI_CONSOLE_DATA GuiData
)
1679 PCONSOLE Console
= GuiData
->Console
;
1682 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
1684 // TODO: Simplify the code.
1685 // See: GuiConsoleNotifyWndProc() PM_CREATE_CONSOLE.
1687 /* Retrieve our real position */
1688 GetWindowRect(GuiData
->hWindow
, &rcWnd
);
1689 GuiData
->GuiInfo
.WindowOrigin
.x
= rcWnd
.left
;
1690 GuiData
->GuiInfo
.WindowOrigin
.y
= rcWnd
.top
;
1692 LeaveCriticalSection(&Console
->Lock
);
1696 // HACK: This functionality is standard for general scrollbars. Don't add it by hand.
1700 GuiConsoleHandleScrollbarMenu(VOID)
1704 hMenu = CreatePopupMenu();
1707 DPRINT("CreatePopupMenu failed\n");
1711 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
1712 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
1713 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
1714 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
1715 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
1716 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
1717 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
1718 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
1719 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
1720 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
1725 OnScroll(PGUI_CONSOLE_DATA GuiData
, UINT uMsg
, WPARAM wParam
)
1727 PCONSOLE Console
= GuiData
->Console
;
1728 PCONSOLE_SCREEN_BUFFER Buff
;
1731 int old_pos
, Maximum
;
1734 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return 0;
1736 Buff
= GuiData
->ActiveBuffer
;
1738 if (uMsg
== WM_HSCROLL
)
1741 Maximum
= Buff
->ScreenBufferSize
.X
- Buff
->ViewSize
.X
;
1742 pShowXY
= &Buff
->ViewOrigin
.X
;
1747 Maximum
= Buff
->ScreenBufferSize
.Y
- Buff
->ViewSize
.Y
;
1748 pShowXY
= &Buff
->ViewOrigin
.Y
;
1751 /* set scrollbar sizes */
1752 sInfo
.cbSize
= sizeof(SCROLLINFO
);
1753 sInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_PAGE
| SIF_TRACKPOS
;
1755 if (!GetScrollInfo(GuiData
->hWindow
, fnBar
, &sInfo
)) goto Quit
;
1757 old_pos
= sInfo
.nPos
;
1759 switch (LOWORD(wParam
))
1770 sInfo
.nPos
-= sInfo
.nPage
;
1774 sInfo
.nPos
+= sInfo
.nPage
;
1778 sInfo
.nPos
= sInfo
.nTrackPos
;
1779 ConioPause(Console
, PAUSED_FROM_SCROLLBAR
);
1782 case SB_THUMBPOSITION
:
1783 ConioUnpause(Console
, PAUSED_FROM_SCROLLBAR
);
1787 sInfo
.nPos
= sInfo
.nMin
;
1791 sInfo
.nPos
= sInfo
.nMax
;
1798 sInfo
.nPos
= max(sInfo
.nPos
, 0);
1799 sInfo
.nPos
= min(sInfo
.nPos
, Maximum
);
1801 if (old_pos
!= sInfo
.nPos
)
1803 USHORT OldX
= Buff
->ViewOrigin
.X
;
1804 USHORT OldY
= Buff
->ViewOrigin
.Y
;
1805 UINT WidthUnit
, HeightUnit
;
1807 *pShowXY
= sInfo
.nPos
;
1809 GetScreenBufferSizeUnits(Buff
, GuiData
, &WidthUnit
, &HeightUnit
);
1811 ScrollWindowEx(GuiData
->hWindow
,
1812 (OldX
- Buff
->ViewOrigin
.X
) * WidthUnit
,
1813 (OldY
- Buff
->ViewOrigin
.Y
) * HeightUnit
,
1820 sInfo
.fMask
= SIF_POS
;
1821 SetScrollInfo(GuiData
->hWindow
, fnBar
, &sInfo
, TRUE
);
1823 UpdateWindow(GuiData
->hWindow
);
1824 // InvalidateRect(GuiData->hWindow, NULL, FALSE);
1828 LeaveCriticalSection(&Console
->Lock
);
1833 static LRESULT CALLBACK
1834 ConWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1837 PGUI_CONSOLE_DATA GuiData
= NULL
;
1838 PCONSOLE Console
= NULL
;
1841 * - If it's the first time we create a window for the terminal,
1842 * just initialize it and return.
1844 * - If we are destroying the window, just do it and return.
1846 if (msg
== WM_NCCREATE
)
1848 return (LRESULT
)OnNcCreate(hWnd
, (LPCREATESTRUCTW
)lParam
);
1850 else if (msg
== WM_NCDESTROY
)
1852 return OnNcDestroy(hWnd
);
1856 * Now the terminal window is initialized.
1857 * Get the terminal data via the window's data.
1858 * If there is no data, just go away.
1860 GuiData
= GuiGetGuiData(hWnd
);
1861 if (GuiData
== NULL
) return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
1863 // TEMPORARY HACK until all of the functions can deal with a NULL GuiData->ActiveBuffer ...
1864 if (GuiData
->ActiveBuffer
== NULL
) return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
1867 * Just retrieve a pointer to the console in case somebody needs it.
1868 * It is not NULL because it was checked in GuiGetGuiData.
1869 * Each helper function which needs the console has to validate and lock it.
1871 Console
= GuiData
->Console
;
1873 /* We have a console, start message dispatching */
1877 OnActivate(GuiData
, wParam
);
1881 if (OnClose(GuiData
)) goto Default
;
1892 case WM_PALETTECHANGED
:
1894 DPRINT("WM_PALETTECHANGED called\n");
1897 * Protects against infinite loops:
1898 * "... A window that receives this message must not realize
1899 * its palette, unless it determines that wParam does not contain
1900 * its own window handle." (WM_PALETTECHANGED description - MSDN)
1902 * This message is sent to all windows, including the one that
1903 * changed the system palette and caused this message to be sent.
1904 * The wParam of this message contains the handle of the window
1905 * that caused the system palette to change. To avoid an infinite
1906 * loop, care must be taken to check that the wParam of this message
1907 * does not match the window's handle.
1909 if ((HWND
)wParam
== hWnd
) break;
1911 DPRINT("WM_PALETTECHANGED ok\n");
1912 OnPaletteChanged(GuiData
);
1913 DPRINT("WM_PALETTECHANGED quit\n");
1924 case WM_SYSDEADCHAR
:
1926 /* Detect Alt-Enter presses and switch back and forth to fullscreen mode */
1927 if (msg
== WM_SYSKEYDOWN
&& (HIWORD(lParam
) & KF_ALTDOWN
) && wParam
== VK_RETURN
)
1929 /* Switch only at first Alt-Enter press, and ignore subsequent key repetitions */
1930 if ((HIWORD(lParam
) & (KF_UP
| KF_REPEAT
)) != KF_REPEAT
)
1931 GuiConsoleSwitchFullScreen(GuiData
);
1936 OnKey(GuiData
, msg
, wParam
, lParam
);
1943 * The message was sent because we are manually triggering a change.
1944 * Check whether the mouse is indeed present on this console window
1945 * and take appropriate decisions.
1947 if (wParam
== -1 && lParam
== -1)
1952 /* Get the placement of the mouse */
1953 GetCursorPos(&mouseCoords
);
1955 /* On which window is placed the mouse ? */
1956 hWndHit
= WindowFromPoint(mouseCoords
);
1958 /* It's our window. Perform the hit-test to be used later on. */
1959 if (hWndHit
== hWnd
)
1961 wParam
= (WPARAM
)hWnd
;
1962 lParam
= DefWindowProcW(hWndHit
, WM_NCHITTEST
, 0,
1963 MAKELPARAM(mouseCoords
.x
, mouseCoords
.y
));
1967 /* Set the mouse cursor only when we are in the client area */
1968 if ((HWND
)wParam
== hWnd
&& LOWORD(lParam
) == HTCLIENT
)
1970 if (GuiData
->MouseCursorRefCount
>= 0)
1972 /* Show the cursor */
1973 SetCursor(GuiData
->hCursor
);
1977 /* Hide the cursor if the reference count is negative */
1988 case WM_LBUTTONDOWN
:
1989 case WM_MBUTTONDOWN
:
1990 case WM_RBUTTONDOWN
:
1994 case WM_LBUTTONDBLCLK
:
1995 case WM_MBUTTONDBLCLK
:
1996 case WM_RBUTTONDBLCLK
:
1999 case WM_MOUSEHWHEEL
:
2001 Result
= OnMouse(GuiData
, msg
, wParam
, lParam
);
2008 Result
= OnScroll(GuiData
, msg
, wParam
);
2012 case WM_CONTEXTMENU
:
2014 if (DefWindowProcW(hWnd
/*GuiData->hWindow*/, WM_NCHITTEST
, 0, lParam
) == HTCLIENT
)
2016 HMENU hMenu
= CreatePopupMenu();
2019 AppendMenuItems(hMenu
, GuiConsoleEditMenuItems
);
2020 TrackPopupMenuEx(hMenu
,
2022 GET_X_LPARAM(lParam
),
2023 GET_Y_LPARAM(lParam
),
2038 HMENU hMenu
= (HMENU
)wParam
;
2041 /* Enable or disable the Close menu item */
2042 EnableMenuItem(hMenu
, SC_CLOSE
, MF_BYCOMMAND
|
2043 (GuiData
->IsCloseButtonEnabled
? MF_ENABLED
: MF_GRAYED
));
2045 /* Enable or disable the Copy and Paste items */
2046 EnableMenuItem(hMenu
, ID_SYSTEM_EDIT_COPY
, MF_BYCOMMAND
|
2047 ((Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) &&
2048 (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
) ? MF_ENABLED
: MF_GRAYED
));
2049 // FIXME: Following whether the active screen buffer is text-mode
2050 // or graphics-mode, search for CF_UNICODETEXT or CF_BITMAP formats.
2051 EnableMenuItem(hMenu
, ID_SYSTEM_EDIT_PASTE
, MF_BYCOMMAND
|
2052 (!(Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) &&
2053 IsClipboardFormatAvailable(CF_UNICODETEXT
) ? MF_ENABLED
: MF_GRAYED
));
2056 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2058 SendMenuEvent(Console
, WM_INITMENU
);
2059 LeaveCriticalSection(&Console
->Lock
);
2066 if (HIWORD(wParam
) == 0xFFFF) // Allow all the menu flags
2068 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2070 SendMenuEvent(Console
, WM_MENUSELECT
);
2071 LeaveCriticalSection(&Console
->Lock
);
2080 Result
= OnCommand(GuiData
, wParam
, lParam
);
2086 OnFocus(GuiData
, (msg
== WM_SETFOCUS
));
2089 case WM_GETMINMAXINFO
:
2090 OnGetMinMaxInfo(GuiData
, (PMINMAXINFO
)lParam
);
2097 #if 0 // This code is here to prepare & control dynamic console SB resizing.
2100 PRECT dragRect
= (PRECT
)lParam
;
2104 DPRINT1("WMSZ_LEFT\n");
2107 DPRINT1("WMSZ_RIGHT\n");
2110 DPRINT1("WMSZ_TOP\n");
2113 DPRINT1("WMSZ_TOPLEFT\n");
2116 DPRINT1("WMSZ_TOPRIGHT\n");
2119 DPRINT1("WMSZ_BOTTOM\n");
2121 case WMSZ_BOTTOMLEFT
:
2122 DPRINT1("WMSZ_BOTTOMLEFT\n");
2124 case WMSZ_BOTTOMRIGHT
:
2125 DPRINT1("WMSZ_BOTTOMRIGHT\n");
2128 DPRINT1("wParam = %d\n", wParam
);
2131 DPRINT1("dragRect = {.left = %d ; .top = %d ; .right = %d ; .bottom = %d}\n",
2132 dragRect
->left
, dragRect
->top
, dragRect
->right
, dragRect
->bottom
);
2138 OnSize(GuiData
, wParam
, lParam
);
2141 case PM_RESIZE_TERMINAL
:
2143 PCONSOLE_SCREEN_BUFFER Buff
= GuiData
->ActiveBuffer
;
2147 DWORD Width
, Height
;
2148 UINT WidthUnit
, HeightUnit
;
2150 GetScreenBufferSizeUnits(Buff
, GuiData
, &WidthUnit
, &HeightUnit
);
2152 Width
= Buff
->ScreenBufferSize
.X
* WidthUnit
;
2153 Height
= Buff
->ScreenBufferSize
.Y
* HeightUnit
;
2155 /* Recreate the framebuffer */
2156 hDC
= GetDC(GuiData
->hWindow
);
2157 hnew
= CreateCompatibleBitmap(hDC
, Width
, Height
);
2158 ReleaseDC(GuiData
->hWindow
, hDC
);
2159 hold
= SelectObject(GuiData
->hMemDC
, hnew
);
2160 if (GuiData
->hBitmap
)
2162 if (hold
== GuiData
->hBitmap
) DeleteObject(GuiData
->hBitmap
);
2164 GuiData
->hBitmap
= hnew
;
2166 /* Resize the window to the user's values */
2167 GuiData
->WindowSizeLock
= TRUE
;
2168 ResizeConWnd(GuiData
, WidthUnit
, HeightUnit
);
2169 GuiData
->WindowSizeLock
= FALSE
;
2173 case PM_APPLY_CONSOLE_INFO
:
2175 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2177 GuiApplyUserSettings(GuiData
, (HANDLE
)wParam
, (BOOL
)lParam
);
2178 LeaveCriticalSection(&Console
->Lock
);
2183 case PM_CONSOLE_BEEP
:
2184 DPRINT1("Beep !!\n");
2188 // case PM_CONSOLE_SET_TITLE:
2189 // SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
2193 Result
= DefWindowProcW(hWnd
, msg
, wParam
, lParam
);