2019-05-03 00:29:04 +02:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
#include "ColorsPage.h"
|
|
|
|
#include "ColorControl.h"
|
|
|
|
|
|
|
|
static BYTE ColorArray[4];
|
|
|
|
static int iColor;
|
|
|
|
|
|
|
|
// Routine Description:
|
|
|
|
// - Window proc for the color buttons
|
2019-05-30 18:20:42 +02:00
|
|
|
[[nodiscard]]
|
2019-05-17 22:32:51 +02:00
|
|
|
LRESULT CALLBACK ColorTableControlProc(HWND hColor, UINT wMsg, WPARAM wParam, LPARAM lParam)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
PAINTSTRUCT ps;
|
|
|
|
int ColorId;
|
|
|
|
RECT rColor;
|
|
|
|
RECT rTemp;
|
|
|
|
HDC hdc;
|
|
|
|
HWND hWnd;
|
|
|
|
HWND hDlg;
|
|
|
|
|
|
|
|
ColorId = GetWindowLong(hColor, GWL_ID);
|
|
|
|
hDlg = GetParent(hColor);
|
|
|
|
|
|
|
|
switch (wMsg) {
|
|
|
|
case WM_SETFOCUS:
|
|
|
|
if (ColorArray[iColor] != (BYTE)(ColorId - IDD_COLOR_1)) {
|
|
|
|
hWnd = GetDlgItem(hDlg, ColorArray[iColor]+IDD_COLOR_1);
|
|
|
|
SetFocus(hWnd);
|
|
|
|
}
|
|
|
|
__fallthrough;
|
|
|
|
case WM_KILLFOCUS:
|
|
|
|
hdc = GetDC(hDlg);
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_1);
|
|
|
|
GetWindowRect(hWnd, &rColor);
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_16);
|
|
|
|
GetWindowRect(hWnd, &rTemp);
|
|
|
|
rColor.right = rTemp.right;
|
|
|
|
ScreenToClient(hDlg, (LPPOINT)&rColor.left);
|
|
|
|
ScreenToClient(hDlg, (LPPOINT)&rColor.right);
|
|
|
|
InflateRect(&rColor, 2, 2);
|
|
|
|
DrawFocusRect(hdc, &rColor);
|
|
|
|
ReleaseDC(hDlg, hdc);
|
|
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
switch (wParam) {
|
|
|
|
case VK_UP:
|
|
|
|
case VK_LEFT:
|
|
|
|
if (ColorId > IDD_COLOR_1) {
|
|
|
|
SendMessage(hDlg, CM_SETCOLOR,
|
|
|
|
ColorId - 1 - IDD_COLOR_1, (LPARAM)hColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
|
|
case VK_RIGHT:
|
|
|
|
if (ColorId < IDD_COLOR_16) {
|
|
|
|
SendMessage(hDlg, CM_SETCOLOR,
|
|
|
|
ColorId + 1 - IDD_COLOR_1, (LPARAM)hColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VK_TAB:
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_1);
|
|
|
|
hWnd = GetNextDlgTabItem(hDlg, hWnd, GetKeyState(VK_SHIFT) < 0);
|
|
|
|
SetFocus(hWnd);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return DefWindowProc(hColor, wMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
SendMessage(hDlg, CM_SETCOLOR,
|
|
|
|
ColorId - IDD_COLOR_1, (LPARAM)hColor);
|
|
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
|
|
|
|
|
|
BeginPaint(hColor, &ps);
|
|
|
|
GetClientRect(hColor, &rColor);
|
|
|
|
|
|
|
|
// are we the selected color for the current object?
|
|
|
|
if (ColorArray[iColor] == (BYTE)(ColorId - IDD_COLOR_1)) {
|
|
|
|
// highlight the selected color
|
|
|
|
FrameRect(ps.hdc, &rColor, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
|
|
|
InflateRect(&rColor, -1, -1);
|
|
|
|
FrameRect(ps.hdc, &rColor, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
|
|
|
}
|
|
|
|
|
|
|
|
SimpleColorDoPaint(hColor, ps, ColorId);
|
|
|
|
EndPaint(hColor, &ps);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return SimpleColorControlProc(hColor, wMsg, wParam, lParam);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InitColorsDialog(HWND hDlg)
|
|
|
|
{
|
|
|
|
ColorArray[IDD_COLOR_SCREEN_TEXT - IDD_COLOR_SCREEN_TEXT] =
|
|
|
|
LOBYTE(gpStateInfo->ScreenAttributes) & 0x0F;
|
|
|
|
ColorArray[IDD_COLOR_SCREEN_BKGND - IDD_COLOR_SCREEN_TEXT] =
|
|
|
|
LOBYTE(gpStateInfo->ScreenAttributes >> 4);
|
|
|
|
ColorArray[IDD_COLOR_POPUP_TEXT - IDD_COLOR_SCREEN_TEXT] =
|
|
|
|
LOBYTE(gpStateInfo->PopupAttributes) & 0x0F;
|
|
|
|
ColorArray[IDD_COLOR_POPUP_BKGND - IDD_COLOR_SCREEN_TEXT] =
|
|
|
|
LOBYTE(gpStateInfo->PopupAttributes >> 4);
|
|
|
|
CheckRadioButton(hDlg,IDD_COLOR_SCREEN_TEXT,IDD_COLOR_POPUP_BKGND,IDD_COLOR_SCREEN_BKGND);
|
|
|
|
iColor = IDD_COLOR_SCREEN_BKGND - IDD_COLOR_SCREEN_TEXT;
|
|
|
|
|
|
|
|
// initialize size of edit controls
|
|
|
|
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_RED, EM_LIMITTEXT, 3, 0);
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_GREEN, EM_LIMITTEXT, 3, 0);
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_BLUE, EM_LIMITTEXT, 3, 0);
|
|
|
|
|
|
|
|
// initialize arrow controls
|
|
|
|
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_REDSCROLL, UDM_SETRANGE, 0,
|
|
|
|
MAKELONG(255, 0));
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_REDSCROLL, UDM_SETPOS, 0,
|
|
|
|
MAKELONG(GetRValue(AttrToRGB(ColorArray[iColor])), 0));
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_GREENSCROLL, UDM_SETRANGE, 0,
|
|
|
|
MAKELONG(255, 0));
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_GREENSCROLL, UDM_SETPOS, 0,
|
|
|
|
MAKELONG(GetGValue(AttrToRGB(ColorArray[iColor])), 0));
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_BLUESCROLL, UDM_SETRANGE, 0,
|
|
|
|
MAKELONG(255, 0));
|
|
|
|
SendDlgItemMessage(hDlg, IDD_COLOR_BLUESCROLL, UDM_SETPOS, 0,
|
|
|
|
MAKELONG(GetBValue(AttrToRGB(ColorArray[iColor])), 0));
|
|
|
|
|
|
|
|
CreateAndAssociateToolTipToControl(IDD_TRANSPARENCY, hDlg, IDS_TOOLTIP_OPACITY);
|
|
|
|
|
|
|
|
SendMessage(GetDlgItem(hDlg, IDD_TRANSPARENCY), TBM_SETRANGE, FALSE, (LPARAM)MAKELONG(TRANSPARENCY_RANGE_MIN, BYTE_MAX));
|
|
|
|
ToggleV2ColorControls(hDlg);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Routine Description:
|
|
|
|
// - Dialog proc for the color selection dialog box.
|
|
|
|
//
|
|
|
|
INT_PTR WINAPI ColorDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
UINT Value;
|
|
|
|
UINT Red;
|
|
|
|
UINT Green;
|
|
|
|
UINT Blue;
|
|
|
|
UINT Item;
|
|
|
|
HWND hWnd;
|
|
|
|
HWND hWndOld;
|
|
|
|
BOOL bOK;
|
|
|
|
static bool fHaveInitialized = false;
|
|
|
|
|
|
|
|
switch (wMsg) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
{
|
|
|
|
fHaveInitialized = true;
|
|
|
|
return InitColorsDialog(hDlg);
|
|
|
|
}
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
{
|
|
|
|
if (!fHaveInitialized) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Item = LOWORD(wParam);
|
|
|
|
switch (Item) {
|
|
|
|
case IDD_COLOR_SCREEN_TEXT:
|
|
|
|
case IDD_COLOR_SCREEN_BKGND:
|
|
|
|
case IDD_COLOR_POPUP_TEXT:
|
|
|
|
case IDD_COLOR_POPUP_BKGND:
|
|
|
|
hWndOld = GetDlgItem(hDlg, ColorArray[iColor]+IDD_COLOR_1);
|
|
|
|
|
|
|
|
iColor = Item - IDD_COLOR_SCREEN_TEXT;
|
|
|
|
|
|
|
|
// repaint new color
|
|
|
|
hWnd = GetDlgItem(hDlg, ColorArray[iColor]+IDD_COLOR_1);
|
|
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
|
|
|
|
|
|
// repaint old color
|
|
|
|
if (hWndOld != hWnd) {
|
|
|
|
InvalidateRect(hWndOld, NULL, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case IDD_COLOR_RED:
|
|
|
|
case IDD_COLOR_GREEN:
|
|
|
|
case IDD_COLOR_BLUE:
|
|
|
|
{
|
|
|
|
switch (HIWORD(wParam)) {
|
|
|
|
case EN_UPDATE:
|
|
|
|
if (!CheckNum (hDlg, Item)) {
|
|
|
|
Undo((HWND)lParam);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EN_CHANGE:
|
|
|
|
/*
|
|
|
|
* Update the state info structure
|
|
|
|
*/
|
|
|
|
Value = GetDlgItemInt(hDlg, Item, &bOK, TRUE);
|
|
|
|
if (bOK) {
|
|
|
|
if (Value > 255) {
|
|
|
|
UpdateItem(hDlg, Item, 255);
|
|
|
|
Value = 255;
|
|
|
|
}
|
|
|
|
if (Item == IDD_COLOR_RED) {
|
|
|
|
Red = Value;
|
|
|
|
} else {
|
|
|
|
Red = GetRValue(AttrToRGB(ColorArray[iColor]));
|
|
|
|
}
|
|
|
|
if (Item == IDD_COLOR_GREEN) {
|
|
|
|
Green = Value;
|
|
|
|
} else {
|
|
|
|
Green = GetGValue(AttrToRGB(ColorArray[iColor]));
|
|
|
|
}
|
|
|
|
if (Item == IDD_COLOR_BLUE) {
|
|
|
|
Blue = Value;
|
|
|
|
} else {
|
|
|
|
Blue = GetBValue(AttrToRGB(ColorArray[iColor]));
|
|
|
|
}
|
|
|
|
UpdateStateInfo(hDlg, ColorArray[iColor] + IDD_COLOR_1,
|
|
|
|
RGB(Red, Green, Blue));
|
|
|
|
UpdateApplyButton(hDlg);
|
|
|
|
}
|
|
|
|
__fallthrough;
|
|
|
|
|
|
|
|
case EN_KILLFOCUS:
|
|
|
|
/*
|
|
|
|
* Update the preview windows with the new value
|
|
|
|
*/
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_SCREEN_COLORS);
|
|
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_POPUP_COLORS);
|
|
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
|
|
hWnd = GetDlgItem(hDlg, ColorArray[iColor]+IDD_COLOR_1);
|
|
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case WM_NOTIFY:
|
|
|
|
{
|
|
|
|
const PSHNOTIFY * const pshn = (LPPSHNOTIFY)lParam;
|
|
|
|
switch (pshn->hdr.code) {
|
|
|
|
case PSN_APPLY:
|
|
|
|
/*
|
|
|
|
* Write out the state values and exit.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Ignore opacity in v1 console
|
|
|
|
if (g_fForceV2)
|
|
|
|
{
|
|
|
|
gpStateInfo->bWindowTransparency = (BYTE)SendDlgItemMessage(hDlg, IDD_TRANSPARENCY, TBM_GETPOS, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
EndDlgPage(hDlg, !pshn->lParam);
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case PSN_RESET:
|
|
|
|
// Ignore opacity in v1 console
|
|
|
|
if (g_fForceV2 && g_bPreviewOpacity != gpStateInfo->bWindowTransparency)
|
|
|
|
{
|
|
|
|
SetLayeredWindowAttributes(gpStateInfo->hWnd, 0, gpStateInfo->bWindowTransparency, LWA_ALPHA);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case PSN_SETACTIVE:
|
|
|
|
ToggleV2ColorControls(hDlg);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case PSN_KILLACTIVE:
|
|
|
|
/*
|
|
|
|
* Fake the dialog proc into thinking the edit control just
|
|
|
|
* lost focus so it'll update properly
|
|
|
|
*/
|
|
|
|
Item = GetDlgCtrlID(GetFocus());
|
|
|
|
if (Item)
|
|
|
|
{
|
|
|
|
SendMessage(hDlg, WM_COMMAND, MAKELONG(Item, EN_KILLFOCUS), 0);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case WM_VSCROLL:
|
|
|
|
/*
|
|
|
|
* Fake the dialog proc into thinking the edit control just
|
|
|
|
* lost focus so it'll update properly
|
|
|
|
*/
|
|
|
|
Item = GetDlgCtrlID((HWND)lParam) - 1;
|
|
|
|
SendMessage(hDlg, WM_COMMAND, MAKELONG(Item, EN_KILLFOCUS), 0);
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case WM_HSCROLL:
|
|
|
|
if (IDD_TRANSPARENCY == GetDlgCtrlID((HWND) lParam))
|
|
|
|
{
|
|
|
|
switch (LOWORD(wParam))
|
|
|
|
{
|
|
|
|
//When moving slider with the mouse
|
|
|
|
case TB_THUMBPOSITION:
|
|
|
|
case TB_THUMBTRACK:
|
|
|
|
g_bPreviewOpacity = (BYTE) HIWORD(wParam);
|
|
|
|
break;
|
|
|
|
|
|
|
|
//moving via keyboard
|
|
|
|
default:
|
|
|
|
g_bPreviewOpacity = (BYTE) SendMessage((HWND) lParam, TBM_GETPOS, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
PreviewOpacity(hDlg, g_bPreviewOpacity);
|
|
|
|
UpdateApplyButton(hDlg);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_SETCOLOR:
|
|
|
|
UpdateStateInfo(hDlg, iColor + IDD_COLOR_SCREEN_TEXT, (UINT)wParam);
|
|
|
|
UpdateApplyButton(hDlg);
|
|
|
|
|
|
|
|
hWndOld = GetDlgItem(hDlg, ColorArray[iColor]+IDD_COLOR_1);
|
|
|
|
|
|
|
|
ColorArray[iColor] = (BYTE)wParam;
|
|
|
|
|
|
|
|
/* Force the preview window to repaint */
|
|
|
|
|
|
|
|
if (iColor < (IDD_COLOR_POPUP_TEXT - IDD_COLOR_SCREEN_TEXT)) {
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_SCREEN_COLORS);
|
|
|
|
} else {
|
|
|
|
hWnd = GetDlgItem(hDlg, IDD_COLOR_POPUP_COLORS);
|
|
|
|
}
|
|
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
|
|
|
|
|
|
// repaint new color
|
|
|
|
hWnd = GetDlgItem(hDlg, ColorArray[iColor]+IDD_COLOR_1);
|
|
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
|
|
SetFocus(hWnd);
|
|
|
|
|
|
|
|
UpdateItem(hDlg, IDD_COLOR_RED,
|
|
|
|
GetRValue(AttrToRGB(ColorArray[iColor])));
|
|
|
|
UpdateItem(hDlg, IDD_COLOR_GREEN,
|
|
|
|
GetGValue(AttrToRGB(ColorArray[iColor])));
|
|
|
|
UpdateItem(hDlg, IDD_COLOR_BLUE,
|
|
|
|
GetBValue(AttrToRGB(ColorArray[iColor])));
|
|
|
|
|
|
|
|
// repaint old color
|
|
|
|
if (hWndOld != hWnd) {
|
|
|
|
InvalidateRect(hWndOld, NULL, TRUE);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// enables or disables color page dialog controls depending on whether V2 is enabled or not
|
|
|
|
void ToggleV2ColorControls(__in const HWND hDlg)
|
|
|
|
{
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDD_TRANSPARENCY), g_fForceV2);
|
|
|
|
SetOpacitySlider(hDlg);
|
|
|
|
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDD_OPACITY_GROUPBOX), g_fForceV2);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDD_OPACITY_LOW_LABEL), g_fForceV2);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDD_OPACITY_HIGH_LABEL), g_fForceV2);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDD_OPACITY_VALUE), g_fForceV2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PreviewOpacity(HWND hDlg, BYTE bOpacity)
|
|
|
|
{
|
|
|
|
// Ignore opacity in v1 console
|
|
|
|
if (g_fForceV2)
|
|
|
|
{
|
|
|
|
WCHAR wszOpacityValue[4];
|
|
|
|
HWND hWndConsole = gpStateInfo->hWnd;
|
|
|
|
|
|
|
|
StringCchPrintf(wszOpacityValue, ARRAYSIZE(wszOpacityValue), L"%d", (int) ((float) bOpacity / BYTE_MAX * 100));
|
|
|
|
SetDlgItemText(hDlg, IDD_OPACITY_VALUE, wszOpacityValue);
|
|
|
|
|
|
|
|
if (hWndConsole)
|
|
|
|
{
|
|
|
|
// TODO: CONSIDER:What happens when this code is eventually ported directly into the shell. Which "hWnd" does this apply to then? Desktop?
|
|
|
|
// Hopefully it is simply null. -RSE http://osgvsowi/2136073
|
|
|
|
SetLayeredWindowAttributes(hWndConsole, 0, bOpacity, LWA_ALPHA);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetOpacitySlider(__in HWND hDlg)
|
|
|
|
{
|
|
|
|
if (g_fForceV2)
|
|
|
|
{
|
|
|
|
if (0 == g_bPreviewOpacity) //if no preview opacity has been set yet...
|
|
|
|
{
|
|
|
|
g_bPreviewOpacity = (gpStateInfo->bWindowTransparency >= TRANSPARENCY_RANGE_MIN) ? gpStateInfo->bWindowTransparency : BYTE_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_bPreviewOpacity = BYTE_MAX; //always fully opaque in V1
|
|
|
|
}
|
|
|
|
|
|
|
|
SendMessage(GetDlgItem(hDlg, IDD_TRANSPARENCY), TBM_SETPOS, TRUE, (LPARAM)(g_bPreviewOpacity));
|
|
|
|
PreviewOpacity(hDlg, g_bPreviewOpacity);
|
|
|
|
}
|