#include "Systembar.h"
const char szSystembarName[] = "BBSystembar";
extern BImage *pBImage;
extern Desk *pDesk;
extern Systembar *pSystembar;
extern TrayManager *pTrayManager;
extern Settings *pSettings;
extern MenuMaker *pMenuMaker;
extern Workspaces *pWorkspaces;
extern Toolbar *pToolbar;
extern Slit *pSlit;
Systembar::Systembar(HINSTANCE hInstance, bool DisableTray)
{
if (DisableTray) SysTrayDisabled = true;
else SysTrayDisabled = false;
hSystembarWnd = NULL;
hToolTips = NULL;
hBlackboxWnd = GetBBWnd();
hSystembarInstance = hInstance;
cachedBackground = CreateCompatibleDC(NULL);
cachedBackgroundExists = false;
cachedTaskButtonActive = CreateCompatibleDC(NULL);
cachedTaskButtonInactive = CreateCompatibleDC(NULL);
cachedTaskButtonsExist = false;
DockedToSlit = false;
SystembarPosInProgress = false;
GetSettings();
WNDCLASS wc;
ZeroMemory(&wc,sizeof(wc));
wc.lpfnWndProc = SystembarWndProc;
wc.hInstance = hSystembarInstance;
wc.lpszClassName = szSystembarName;
if (!RegisterClass(&wc))
{
MessageBox(0, "Error registering window class", szSystembarName, MB_OK | MB_ICONERROR | MB_TOPMOST);
Log("Systembar: Error registering window class", NULL);
return;
}
hSystembarWnd = CreateWindowEx(
WS_EX_TOOLWINDOW,
szSystembarName,
NULL,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
SystembarX, SystembarY,
SystembarWidth, SystembarHeight,
NULL,
NULL,
hSystembarInstance,
NULL);
if (!hSystembarWnd)
{
UnregisterClass(szSystembarName,hSystembarInstance);
MessageBox(0, "Error creating window", szSystembarName, MB_OK | MB_ICONERROR | MB_TOPMOST);
Log("Systembar: Error creating window", NULL);
return;
}
int msgs[] = { BB_RECONFIGURE, BB_TOGGLESYSTEMBAR, BB_ADDTASK, BB_REMOVETASK, BB_REDRAW, BB_ACTIVETASK, BB_ACTIVATESHELLWINDOW, 0 };
SendMessage(hBlackboxWnd, BB_REGISTERMESSAGE, (WPARAM)hSystembarWnd, (LPARAM)msgs);
MakeSticky(hSystembarWnd);
SetClassLongPtr(hSystembarWnd, GCL_STYLE, CS_DBLCLKS | GetClassLongPtr(hSystembarWnd, GCL_STYLE));
DragAcceptFiles(hSystembarWnd, true);
if (!stricmp(pSettings->systembarPlacement, "DockedToSlit"))
{
ShowWindow(hSystembarWnd, SW_SHOWNOACTIVATE);
SendMessage(pSlit->hSlitWnd, SLIT_ADD, NULL, (LPARAM)hSystembarWnd);
DockedToSlit = true;
}
else
{
if (!stricmp(pSettings->systembarPlacement, "DockedToToolbar"))
{
if (pSettings->toolbarOnTop) SetWindowPos(hSystembarWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
else SetWindowPos(hSystembarWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
SetTransparency(hSystembarWnd, pSettings->toolbarTransparencyAlpha);
}
else
{
if (pSettings->systembarOnTop) SetWindowPos(hSystembarWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
else SetWindowPos(hSystembarWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
SetTransparency(hSystembarWnd, pSettings->systembarTransparencyAlpha);
}
ShowWindow(hSystembarWnd, pSettings->systembarHidden ? SW_HIDE : SW_SHOWNOACTIVATE);
}
INITCOMMONCONTROLSEX ic;
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
ic.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&ic);
if (!pSettings->systembarTooltipsDisabled) CreateTooltipsWindow();
WinEnumeratorCount = 0;
blockNextMouseClick = false;
saveWidthOnRestart = false;
ZeroMemory(&WindowList, sizeof(WindowList));
}
Systembar::~Systembar()
{
if (pSlit && DockedToSlit) SendMessage(pSlit->hSlitWnd, SLIT_REMOVE, NULL, (LPARAM)hSystembarWnd);
for (int i=0; i < WinEnumeratorCount; i++)
{
memset(&WindowList[i], 0, sizeof(TaskButton));
}
int msgs[] = { BB_RECONFIGURE, BB_TOGGLESYSTEMBAR, BB_ADDTASK, BB_REMOVETASK, BB_REDRAW, BB_ACTIVETASK, BB_ACTIVATESHELLWINDOW, 0 };
SendMessage(hBlackboxWnd, BB_UNREGISTERMESSAGE, (WPARAM)hSystembarWnd, (LPARAM)msgs);
if (hSystembarWnd) DestroyWindow(hSystembarWnd);
if (hToolTips) DestroyWindow(hToolTips);
UnregisterClass(szSystembarName,hSystembarInstance);
DeleteDC(cachedTaskButtonInactive);
DeleteDC(cachedTaskButtonActive);
DeleteDC(cachedBackground);
}
void Systembar::Initialize()
{
EnumWindows(WinEnumerator, 0);
}
LRESULT CALLBACK SystembarWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC buf = CreateCompatibleDC(NULL);
RECT r;
int updateRectWidth = ps.rcPaint.right - ps.rcPaint.left;
int updateRectHeight = ps.rcPaint.bottom - ps.rcPaint.top;
HBITMAP bufbmp = CreateCompatibleBitmap(hdc, pSystembar->SystembarWidth, pSystembar->SystembarHeight);
HBITMAP oldbuf = (HBITMAP)SelectObject(buf, bufbmp);
if (!pSystembar->cachedBackgroundExists)
{
HBITMAP tempBitmap = CreateCompatibleBitmap(hdc, pSystembar->SystembarWidth, pSystembar->SystembarHeight);
HBITMAP oldBitmap = (HBITMAP)SelectObject(pSystembar->cachedBackground, tempBitmap);
DeleteObject(oldBitmap);
GetClientRect(hwnd, &r);
MakeGradient(pSystembar->cachedBackground, r, pSettings->Toolbar->type, pSettings->Toolbar->Color, pSettings->Toolbar->ColorTo, pSettings->Toolbar->interlaced, pSettings->Toolbar->bevelstyle, pSettings->Toolbar->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, pSettings->Toolbar->borderWidth);
DeleteObject(tempBitmap);
pSystembar->cachedBackgroundExists = true;
}
BitBlt(buf, ps.rcPaint.left, ps.rcPaint.top, updateRectWidth, updateRectHeight, pSystembar->cachedBackground, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
int iconPos = pSystembar->DrawSysTray(buf);
if (!pSystembar->SysTrayDisabled)
{
if (pTrayManager->ShowBalloonTooltip)
{
r.left = r.top = pSettings->Toolbar->borderWidth + 2;
r.right = pSystembar->SystembarWidth - iconPos - 2;
int xmin = r.left + ICON_SIZE + 8;
int xmax = r.right - 5;
r.bottom = pSystembar->SystembarHeight - pSettings->Toolbar->borderWidth - 2;
BYTE red, green, blue;
COLORREF bColor, bColorTo, bTextColor, bShadowColor;
red = GetRValue(pSettings->ActiveTask->Color);
green = GetGValue(pSettings->ActiveTask->Color);
blue = GetBValue(pSettings->ActiveTask->Color);
bColor = RGB((BYTE)blue, (BYTE)green, (BYTE)red);
red = GetRValue(pSettings->ActiveTask->ColorTo);
green = GetGValue(pSettings->ActiveTask->ColorTo);
blue = GetBValue(pSettings->ActiveTask->ColorTo);
bColorTo = RGB((BYTE)blue, (BYTE)green, (BYTE)red);
red = GetRValue(pSettings->ActiveTask->TextColor);
green = GetGValue(pSettings->ActiveTask->TextColor);
blue = GetBValue(pSettings->ActiveTask->TextColor);
bTextColor = RGB((BYTE)blue, (BYTE)green, (BYTE)red);
red = GetRValue(pSettings->activeTaskShadowColor);
green = GetGValue(pSettings->activeTaskShadowColor);
blue = GetBValue(pSettings->activeTaskShadowColor);
bShadowColor = RGB((BYTE)blue, (BYTE)green, (BYTE)red);
MakeGradient(buf, r, pSettings->ActiveTask->type, bColor, bColorTo, false, pSettings->ActiveTask->bevelstyle, pSettings->ActiveTask->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, 1);
SIZE size;
HFONT font = CreateFont(pSettings->Toolbar->FontHeight, 0, 0, 0, pSettings->Toolbar->FontWeight, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, pSettings->Toolbar->Font);
HGDIOBJ oldfont = SelectObject(buf, font);
SetBkMode(buf, TRANSPARENT);
GetTextExtentPoint32(buf, pTrayManager->BalloonTooltipText, strlen(pTrayManager->BalloonTooltipText), &size);
r.left = ((r.right - r.left - size.cx)/2) + 12;
r.right = r.left + size.cx;
if (r.left < xmin) r.left = xmin;
if (r.right > xmax) r.right = xmax;
DrawTextWithShadow(buf, pTrayManager->BalloonTooltipText, r, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS, bTextColor, bShadowColor, pSettings->ActiveTask->FontShadow);
DeleteObject(SelectObject(buf, oldfont));
RECT iconRect;
iconRect.left = r.left - ICON_SIZE - 2;
iconRect.right = r.left + ICON_SIZE;
iconRect.top = r.top + 1;
iconRect.bottom = r.top + ICON_SIZE;
HICON bIcon = LoadIcon(NULL, pTrayManager->BalloonTooltipIcon);
DrawIconEx(buf, iconRect.left, iconRect.top, bIcon, ICON_SIZE, ICON_SIZE, 0, NULL, DI_NORMAL);
DeleteObject(bIcon);
if (pTrayManager->BalloonTooltipItem.hWnd != NULL)
{
PostMessage(pTrayManager->BalloonTooltipItem.hWnd, pTrayManager->BalloonTooltipItem.uCallbackMessage, pTrayManager->BalloonTooltipItem.uID, NIN_BALLOONSHOW);
}
}
else
{
r.left = r.top = pSettings->Toolbar->borderWidth + 2;
r.right = pSystembar->SystembarWidth - iconPos - 2;
r.bottom = pSystembar->SystembarHeight - pSettings->Toolbar->borderWidth - 2;
if (!pSettings->taskbarOnToolbar) pSystembar->DrawTaskbar(buf, iconPos, r);
else if (pToolbar) pToolbar->DrawWindowLabel(buf, r);
}
}
else
{
r.left = r.top = pSettings->Toolbar->borderWidth + 2;
r.right = pSystembar->SystembarWidth - iconPos - 2;
r.bottom = pSystembar->SystembarHeight - pSettings->Toolbar->borderWidth - 2;
if (!pSettings->taskbarOnToolbar) pSystembar->DrawTaskbar(buf, iconPos, r);
else if (pToolbar) pToolbar->DrawWindowLabel(buf, r);
}
BitBlt(hdc, 0, 0, pSystembar->SystembarWidth, pSystembar->SystembarHeight, buf, 0, 0, SRCCOPY);
SelectObject(buf, oldbuf);
DeleteDC(buf);
DeleteObject(bufbmp);
DeleteObject(oldbuf);
EndPaint(hwnd, &ps);
return 0;
}
break;
case BB_ADDTASK:
{
pSystembar->AddWindow((HWND)wParam);
}
break;
case BB_REMOVETASK:
{
pSystembar->RemoveWindow((HWND)wParam);
}
break;
case BB_ACTIVETASK:
{
for (int i=0; i < pSystembar->WinEnumeratorCount; i++)
{
if (pSystembar->WindowList[i].Window == (HWND)wParam)
{
pSystembar->WindowList[i].Active = true;
}
else
{
pSystembar->WindowList[i].Active = false;
}
}
if (pSettings->taskbarOnToolbar && pToolbar) InvalidateRect(pToolbar->hToolbarWnd, &pToolbar->winlabelRect, false);
else if (pSystembar) InvalidateRect(pSystembar->hSystembarWnd, &pSystembar->MainRect, false);
}
break;
case BB_REDRAW:
{
for (int i=0; i < pSystembar->WinEnumeratorCount; i++)
{
if (pSystembar->WindowList[i].Window == (HWND)wParam)
{
if (pSettings->taskbarOnToolbar && pToolbar) InvalidateRect(pToolbar->hToolbarWnd, &pSystembar->WindowList[i].r, false);
else if (pSystembar) InvalidateRect(pSystembar->hSystembarWnd, &pSystembar->WindowList[i].r, false);
break;
}
}
}
break;
case BB_ACTIVATESHELLWINDOW:
{
for (int i=0; i < pSystembar->WinEnumeratorCount; i++)
pSystembar->WindowList[i].Active = false;
if (pSettings->taskbarOnToolbar && pToolbar) InvalidateRect(pToolbar->hToolbarWnd, &pToolbar->winlabelRect, false);
else if (pSystembar) InvalidateRect(pSystembar->hSystembarWnd, &pSystembar->MainRect, false);
}
break;
case WM_DROPFILES:
{
if (pSystembar->MouseButtonOnTaskbar(hwnd, message, wParam, lParam))
{
return 0;
}
else
{
static TCHAR filename[MAX_LINE_LENGTH];
DragQueryFile((HDROP)wParam, 0, filename, sizeof(filename));
if (PathIsDirectory(filename))
{
MessageBox(0, "Trying to fool me, eh?\n...drag'n'drop a style file instead!", "xoblite", MB_OK | MB_TOPMOST);
DragFinish((HDROP)wParam);
return 0;
}
else
{
if (strlen(ReadString(filename, "menu.frame:", "")))
{
SendMessage(pSystembar->hBlackboxWnd, BB_SETSTYLE, 0, (LPARAM)filename);
DragFinish((HDROP)wParam);
}
else
{
MessageBox(0, "Trying to fool me, eh?\n...drag'n'drop a style file instead!", "xoblite", MB_OK | MB_TOPMOST);
DragFinish((HDROP)wParam);
}
return 0;
}
}
}
break;
case BB_RECONFIGURE:
{
if (stricmp(pSettings->systembarPlacement, "DockedToToolbar")) pSystembar->UpdatePosition();
}
break;
case BB_TOGGLESYSTEMBAR:
{
if (!pSystembar->DockedToSlit)
{
if (!pSettings->systembarHidden) pSettings->systembarHidden = true;
else pSettings->systembarHidden = false;
WriteBool(pSettings->extrcFile, "xoblite.systembar.hidden:", pSettings->systembarHidden);
if (!pSettings->systembarHidden) pSystembar->UpdatePosition();
ShowWindow(pSystembar->hSystembarWnd, pSettings->systembarHidden ? SW_HIDE : SW_SHOWNOACTIVATE);
}
else MessageBox(GetBBWnd(), "Please note that the systembar window can not \nbe independently hidden while docked to the slit. \n\n...try hiding the slit window instead.", "xoblite", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
}
break;
case WM_CLOSE:
return 0;
case WM_DISPLAYCHANGE:
{
if (pSettings->systembarHidden) break;
if (stricmp(pSettings->systembarPlacement, "DockedToToolbar")) pSystembar->UpdatePosition();
if (!pSystembar->SysTrayDisabled) pSystembar->UpdateToolTipPositions();
}
break;
case WM_WINDOWPOSCHANGING:
{
if (pSettings->systembarPlacement[0] == 'M' && pSettings->systembarSnapToEdges)
{
if (pSystembar)
{
if (!pSystembar->DockedToSlit && IsWindowVisible(hwnd)) SnapWindowToEdge((WINDOWPOS*)lParam, pSettings->edgeSnapThreshold, true);
}
}
}
break;
case WM_EXITSIZEMOVE:
{
if (pSystembar->SystembarPosInProgress)
{
pSystembar->SystembarPosInProgress = false;
RECT r;
GetWindowRect(pSystembar->hSystembarWnd, &r);
pSystembar->SystembarX = r.left;
pSystembar->SystembarY = r.top;
sprintf(pSettings->systembarPlacement, "Manual x%d y%d", pSystembar->SystembarX, pSystembar->SystembarY);
pSystembar->UpdatePosition();
}
return 0;
}
case WM_NCHITTEST:
{
if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && !pSystembar->DockedToSlit)
{
pSystembar->SystembarPosInProgress = true;
return HTCAPTION;
}
return HTCLIENT;
}
break;
case WM_MOUSEMOVE:
{
if (pSettings->toolbarAutoHide && pToolbar)
{
if (!stricmp(pSettings->systembarPlacement, "DockedToToolbar"))
{
if (IsInString(pSettings->toolbarPlacement, "Bottom"))
{
if (HIWORD(lParam) == (pSystembar->SystembarHeight - 1)) pToolbar->AutoShow();
}
else
{
if (HIWORD(lParam) == 0) pToolbar->AutoShow();
}
}
}
}
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MBUTTONDBLCLK:
{
if (pSystembar->MouseButtonOnTaskbar(hwnd, message, wParam, lParam))
{
return DefWindowProc(hwnd, message, wParam, lParam);
}
else
{
if (!pSettings->systrayHidden && !pSystembar->SysTrayDisabled)
{
int offsetIconX = 2 + pSettings->Toolbar->borderWidth;
int offsetIconY = pSystembar->SystembarHeight/2 - ICON_SIZE/2;
int relX = pSystembar->SystembarWidth - LOWORD(lParam) - offsetIconX;
int relY = HIWORD(lParam);
if (relY >= offsetIconY && relY <= (offsetIconY + ICON_SIZE))
{
for (int i = 0; i < (int)pTrayManager->trayIconList.size(); i++)
{
if ((relX > (i * (ICON_SIZE + 2))) && (relX <= ((i+1) * (ICON_SIZE + 2))))
{
if (pTrayManager->trayIconList[i]->hWnd)
{
if (message == WM_RBUTTONDOWN || message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN) SetForegroundWindow(pTrayManager->trayIconList[i]->hWnd);
PostMessage(pTrayManager->trayIconList[i]->hWnd, pTrayManager->trayIconList[i]->uCallbackMessage, pTrayManager->trayIconList[i]->uID, LPARAM(message));
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
}
}
}
if (message == WM_LBUTTONUP)
{
POINT pt;
int pointx = LOWORD(lParam);
int pointy = HIWORD(lParam);
pt.x = pointx;
pt.y = pointy;
if (PtInRect(&pSystembar->ToggleTrayButtonRect, pt))
{
pSystembar->ToggleSysTray();
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
if (message == WM_LBUTTONDOWN || message == WM_LBUTTONUP)
{
pMenuMaker->Hide();
if ((GetAsyncKeyState(VK_SHIFT) & 0x8000) && !pSystembar->DockedToSlit)
{
if (!stricmp(pSettings->systembarPlacement, "DockedToToolbar") && pToolbar) pToolbar->UpdatePosition();
else pSystembar->UpdatePosition();
}
}
if (message == WM_RBUTTONUP)
{
if (pSystembar->blockNextMouseClick)
{
pSystembar->blockNextMouseClick = false;
return DefWindowProc(hwnd, message, wParam, lParam);
}
if (GetAsyncKeyState(VK_MENU) & 0x8000) SendMessage(GetBBWnd(), BB_MENU, 0, 0);
else SendMessage(GetBBWnd(), BB_MENU, 3, 0);
return DefWindowProc(hwnd, message, wParam, lParam);
}
if (message == WM_MBUTTONUP)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000) PostMessage(GetBBWnd(), BB_TOGGLEPLUGINS, 0, 0);
else if (stricmp(pSettings->systembarPlacement, "DockedToToolbar")) PostMessage(GetBBWnd(), BB_TOGGLETOOLBAR, 0, 0);
else PostMessage(GetBBWnd(), BB_TOGGLESLIT, 0, 0);
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
break;
case WM_XBUTTONDOWN:
{
if (pSystembar->MouseButtonOnTaskbar(hwnd, message, wParam, lParam))
{
return DefWindowProc(hwnd, message, wParam, lParam);
}
else if (HIWORD(wParam) == XBUTTON1)
{
if (!pSettings->taskbarOnToolbar)
{
if (GetAsyncKeyState(VK_MENU) & 0x8000) pSystembar->RestoreAllWindows();
else pSystembar->MinimizeAllWindows();
}
else BBExecute(GetDesktopWindow(), NULL, "control.exe", "desk.cpl,,3", NULL, SW_SHOWNORMAL, false);
}
else if (HIWORD(wParam) == XBUTTON2)
{
if (!pSettings->taskbarOnToolbar) pSystembar->RestoreAllWindows();
else BBExecute(GetDesktopWindow(), NULL, "control.exe", "mmsys.cpl", NULL, SW_SHOWNORMAL, false);
}
}
break;
case WM_XBUTTONUP: { } break;
case WM_MOUSEWHEEL:
{
if (!(GetAsyncKeyState(VK_CONTROL) & 0x8000)) break;
if (IsInString(pSettings->systembarPlacement, "DockedTo")) break;
bool sizechanged = false;
if (GET_WHEEL_DELTA_WPARAM(wParam) < 0)
{
if (pSettings->systembarWidthPercent > 30)
{
sizechanged = true;
pSettings->systembarWidthPercent--;
}
}
else
{
if (pSettings->systembarWidthPercent < 100)
{
sizechanged = true;
pSettings->systembarWidthPercent++;
}
}
if (sizechanged)
{
pSystembar->GetSettings();
pSystembar->cachedBackgroundExists = false;
pSystembar->cachedTaskButtonsExist = false;
InvalidateRect(pSystembar->hSystembarWnd, NULL, false);
MoveWindow(pSystembar->hSystembarWnd, pSystembar->SystembarX, pSystembar->SystembarY, pSystembar->SystembarWidth, pSystembar->SystembarHeight, true);
if (pSettings->toolbarOnTop) SetWindowPos(pSystembar->hSystembarWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
else SetWindowPos(pSystembar->hSystembarWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
if (!pSystembar->SysTrayDisabled) pSystembar->UpdateToolTipPositions();
pSystembar->saveWidthOnRestart = true;
}
}
break;
case WM_TIMER:
{
if (wParam == SYSTEMBAR_XOBLOON_TIMER)
{
if (!pSystembar->SysTrayDisabled)
{
if (pTrayManager->ShowBalloonTooltip)
{
KillTimer(pSystembar->hSystembarWnd, SYSTEMBAR_XOBLOON_TIMER);
pTrayManager->ShowBalloonTooltip = false;
if (pTrayManager->BalloonTooltipItem.hWnd != NULL)
{
PostMessage(pTrayManager->BalloonTooltipItem.hWnd, pTrayManager->BalloonTooltipItem.uCallbackMessage, pTrayManager->BalloonTooltipItem.uID, NIN_BALLOONTIMEOUT);
}
InvalidateRect(pSystembar->hSystembarWnd, NULL, false);
return true;
}
}
}
return 0;
}
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
bool Systembar::MouseButtonOnTaskbar(HWND hwnd, unsigned int message, WPARAM wParam, LPARAM lParam)
{
if (!SysTrayDisabled)
{
if (pTrayManager->ShowBalloonTooltip)
{
pTrayManager->ShowBalloonTooltip = false;
if (pTrayManager->BalloonTooltipItem.hWnd != NULL)
{
PostMessage(pTrayManager->BalloonTooltipItem.hWnd, pTrayManager->BalloonTooltipItem.uCallbackMessage, pTrayManager->BalloonTooltipItem.uID, NIN_BALLOONUSERCLICK);
}
InvalidateRect(hSystembarWnd, NULL, false);
return true;
}
}
if (pSettings->taskbarHidden) return false;
if (pSettings->taskbarOnToolbar && (hwnd == pSystembar->hSystembarWnd)) return false;
POINT pt;
if (message == WM_DROPFILES)
{
GetCursorPos(&pt);
ScreenToClient(hwnd, &pt);
}
else
{
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
}
if (!PtInRect(&MainRect, pt)) return false;
HWND Window;
int mousex;
if (pSettings->taskbarCurrentOnly) NumberOfTasks = CurrentOnlyCount;
else NumberOfTasks = WinEnumeratorCount;
if (pSettings->taskbarMode != 2)
{
TaskWidth = MainRect.right - MainRect.left;
if (NumberOfTasks > 0) TaskWidth = TaskWidth / NumberOfTasks;
}
else
{
if (pSettings->taskbarOnToolbar) TaskWidth = 18;
else TaskWidth = 22;
}
mousex = pt.x;
mousex = mousex - MainRect.left;
mousex = abs(mousex / TaskWidth);
if (mousex >= NumberOfTasks) return false;
if (pSettings->taskbarCurrentOnly)
{
int TaskOnWorkspaceNumber;
int counter = mousex + 1;
for (mousex = 0; counter != 0; mousex++)
{
TaskOnWorkspaceNumber = pWorkspaces->getDesktop(WindowList[mousex].Window);
if (TaskOnWorkspaceNumber == pWorkspaces->currentScreen || TaskOnWorkspaceNumber == 255)
counter--;
}
mousex--;
}
switch (message)
{
case WM_LBUTTONDOWN:
{
if (pMenuMaker) pMenuMaker->Hide();
if (GetAsyncKeyState(VK_MENU) & 0x8000)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
{
Window = WindowList[mousex].Window;
if (IsIconic(Window)) ShowWindow(Window, SW_RESTORE);
SetForegroundWindow(Window);
SendMessage(hBlackboxWnd, BB_BRINGTOFRONT, 0, (LPARAM)Window);
PostMessage(Window, WM_SYSCOMMAND, SC_MOVE, 0);
}
else RestoreAllWindows();
}
else if ((GetAsyncKeyState(VK_SHIFT) & 0x8000) && !DockedToSlit)
{
if (!stricmp(pSettings->systembarPlacement, "DockedToToolbar") && pToolbar) pToolbar->UpdatePosition();
else UpdatePosition();
}
else
{
Window = WindowList[mousex].Window;
if (IsIconic(Window)) ShowWindow(Window, SW_RESTORE);
SetForegroundWindow(Window);
SendMessage(hBlackboxWnd, BB_BRINGTOFRONT, 0, (LPARAM)Window);
}
return true;
}
break;
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
{
if (GetAsyncKeyState(VK_MENU) & 0x8000)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
{
Window = WindowList[mousex].Window;
if (IsIconic(Window)) ShowWindow(Window, SW_RESTORE);
SetForegroundWindow(Window);
SendMessage(hBlackboxWnd, BB_BRINGTOFRONT, 0, (LPARAM)Window);
PostMessage(Window, WM_SYSCOMMAND, SC_SIZE, 0);
}
else MinimizeAllWindows();
}
else if (GetAsyncKeyState(VK_SHIFT) & 0x8000) return true;
else
{
if ((message == WM_RBUTTONDOWN) && pSettings->taskbarCurrentOnly && (NumberOfTasks == 1)) blockNextMouseClick = true;
Window = WindowList[mousex].Window;
ShowWindow(Window, SW_MINIMIZE);
SendMessage(hBlackboxWnd, BB_WINDOWMINIMIZE, 0, (LPARAM)Window);
}
return true;
}
break;
case WM_MBUTTONDOWN:
{
Window = WindowList[mousex].Window;
if (IsIconic(Window)) ShowWindow(Window, SW_RESTORE);
SetForegroundWindow(Window);
if (GetAsyncKeyState(VK_MENU) & 0x8000)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000) return true;
else pDesk->ShadeWindow();
}
else
{
SendMessage(hBlackboxWnd, BB_BRINGTOFRONT, 0, (LPARAM)Window);
MakeSticky(Window);
if (GetAsyncKeyState(VK_MENU) & 0x8000) pWorkspaces->DeskLeft();
else pWorkspaces->DeskRight();
RemoveSticky(Window);
}
return true;
}
break;
case WM_LBUTTONUP:
{
return true;
}
break;
case WM_RBUTTONUP:
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000) SendMessage(GetBBWnd(), BB_MENU, 3, 0);
return true;
}
break;
case WM_MBUTTONUP:
{
if ((GetAsyncKeyState(VK_MENU) & 0x8000) && (GetAsyncKeyState(VK_SHIFT) & 0x8000))
{
Window = WindowList[mousex].Window;
if (IsIconic(Window)) ShowWindow(Window, SW_RESTORE);
SetForegroundWindow(Window);
PostMessage(Window, WM_SYSCOMMAND, SC_CLOSE, 0);
}
return true;
}
break;
case WM_XBUTTONDOWN:
{
if (HIWORD(wParam) == XBUTTON1)
{
if (GetAsyncKeyState(VK_MENU) & 0x8000) RestoreAllWindows();
else MinimizeAllWindows();
}
else if (HIWORD(wParam) == XBUTTON2)
{
RestoreAllWindows();
}
return true;
}
break;
case WM_XBUTTONUP: { } break;
case WM_DROPFILES:
{
Window = WindowList[mousex].Window;
if (IsIconic(Window)) ShowWindow(Window, SW_RESTORE);
SetForegroundWindow(Window);
SendMessage(hBlackboxWnd, BB_BRINGTOFRONT, 0, (LPARAM)Window);
PostMessage(Window, WM_DROPFILES, wParam, lParam);
return true;
}
break;
}
return false;
}
int Systembar::DrawSysTray(HDC hdc)
{
RECT iconRect;
int offsetIconX = 2 + pSettings->Toolbar->borderWidth;
int offsetIconY = SystembarHeight/2 - ICON_SIZE/2;
int iconPos = 0;
if (!SysTrayDisabled)
{
if (!pSettings->systrayHidden)
{
for (int i=0; i < (int)pTrayManager->trayIconList.size(); i++)
{
if (!pTrayManager->trayIconList[i]->hWnd) break;
iconPos = (i+1) * (ICON_SIZE + 2) + offsetIconX;
if (iconPos > (SystembarWidth - offsetIconX)) break;
iconRect.left = SystembarWidth - iconPos;
iconRect.top = offsetIconY;
iconRect.right = iconRect.left + ICON_SIZE;
iconRect.bottom = iconRect.top + ICON_SIZE;
if (pTrayManager->trayIconList[i]->hIcon) DrawSatHueIcon(hdc, pTrayManager->trayIconList[i]->hIcon, ICON_SIZE, iconRect, true, false);
SetRect(&pTrayManager->trayIconList[i]->iconRect, iconRect.left, iconRect.top, iconRect.right, iconRect.bottom);
}
iconPos = iconPos + 3;
ToggleTrayButtonRect.right = SystembarWidth - iconPos;
}
else
{
ToggleTrayButtonRect.right = SystembarWidth - pSettings->Toolbar->borderWidth - 3;
iconPos = pSettings->Toolbar->borderWidth + 3;
}
ToggleTrayButtonRect.left = ToggleTrayButtonRect.right - 8;
ToggleTrayButtonRect.top = pSettings->Toolbar->borderWidth + 3;
ToggleTrayButtonRect.bottom = SystembarHeight - pSettings->Toolbar->borderWidth - 3;
pBImage->CreateGradientByRect(hdc, ToggleTrayButtonRect, pSettings->Toolbar->type, pSettings->Toolbar->Color, pSettings->Toolbar->ColorTo, false, BEVEL_RAISED, BEVEL1, 1);
iconPos = iconPos + 8;
}
else iconPos = pSettings->Toolbar->borderWidth;
TrayRect.left = SystembarWidth - iconPos;
TrayRect.top = pSettings->Toolbar->borderWidth;
TrayRect.right = SystembarWidth - pSettings->Toolbar->borderWidth;
TrayRect.bottom = SystembarHeight - pSettings->Toolbar->borderWidth;
return iconPos;
}
void Systembar::DrawTaskbar(HDC hdc, int iconPos, RECT taskbarRect)
{
CopyRect(&MainRect, &taskbarRect);
MainDC = hdc;
if (!pSettings->taskbarFlashing) flashingHwnd = 0;
if (!pSettings->taskbarHidden)
{
if (pSettings->taskbarCurrentOnly)
{
CurrentOnlyCount = 0;
int TaskOnWorkspaceNumber;
for (int x = 0; x < WinEnumeratorCount; x++)
{
TaskOnWorkspaceNumber = pWorkspaces->getDesktop(WindowList[x].Window);
if (TaskOnWorkspaceNumber == pWorkspaces->currentScreen || TaskOnWorkspaceNumber == 255)
CurrentOnlyCount++;
}
NumberOfTasks = CurrentOnlyCount;
}
else NumberOfTasks = WinEnumeratorCount;
}
if (pSettings->taskbarHidden || NumberOfTasks == 0)
{
HFONT font = CreateFont(pSettings->Toolbar->FontHeight, 0, 0, 0, pSettings->Toolbar->FontWeight, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, pSettings->Toolbar->Font);
HGDIOBJ oldfont = SelectObject(MainDC, font);
SetBkMode(MainDC, TRANSPARENT);
SetTextColor(MainDC, pSettings->Toolbar->TextColor);
DrawText(MainDC, "xoblite", strlen("xoblite"), &MainRect, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS);
DeleteObject(SelectObject(MainDC, oldfont));
}
else DrawTaskButtons();
}
int Systembar::DrawTaskButtons()
{
if (pSettings->taskbarOnToolbar) iconSize = 11;
else iconSize = 14;
if (pSettings->taskbarMode != 2)
{
TaskWidth = MainRect.right - MainRect.left;
if (NumberOfTasks > 0) TaskWidth = TaskWidth / NumberOfTasks;
TaskWidthMinusPadding = TaskWidth - 2;
}
else
{
if (pSettings->taskbarOnToolbar)
{
TaskWidth = iconSize + 7;
TaskWidthMinusPadding = TaskWidth - 1;
}
else
{
TaskWidth = iconSize + 8;
TaskWidthMinusPadding = TaskWidth - 2;
}
}
TaskHeight = MainRect.bottom - MainRect.top;
if (!pSystembar->cachedTaskButtonsExist)
{
RECT r = {0, 0, TaskWidthMinusPadding, TaskHeight};
HBITMAP tempBitmapActive = CreateCompatibleBitmap(MainDC, TaskWidthMinusPadding, TaskHeight);
HBITMAP oldBitmapActive = (HBITMAP)SelectObject(cachedTaskButtonActive, tempBitmapActive);
DeleteObject(oldBitmapActive);
MakeGradient(cachedTaskButtonActive, r, pSettings->ActiveTask->type, pSettings->ActiveTask->Color, pSettings->ActiveTask->ColorTo, pSettings->ActiveTask->interlaced, pSettings->ActiveTask->bevelstyle, pSettings->ActiveTask->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, 1);
DeleteObject(tempBitmapActive);
HBITMAP tempBitmapInactive = CreateCompatibleBitmap(MainDC, TaskWidthMinusPadding, TaskHeight);
HBITMAP oldBitmapInactive = (HBITMAP)SelectObject(cachedTaskButtonInactive, tempBitmapInactive);
DeleteObject(oldBitmapInactive);
MakeGradient(cachedTaskButtonInactive, r, pSettings->InactiveTask->type, pSettings->InactiveTask->Color, pSettings->InactiveTask->ColorTo, pSettings->InactiveTask->interlaced, pSettings->InactiveTask->bevelstyle, pSettings->InactiveTask->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, 1);
DeleteObject(tempBitmapInactive);
pSystembar->cachedTaskButtonsExist = true;
}
int DrawnTasks = 0;
int TaskOnWorkspaceNumber;
ThisButton.bottom = MainRect.bottom;
ThisButton.top = MainRect.top;
for (int i = 0; i < WinEnumeratorCount; i++)
{
if (pSettings->taskbarCurrentOnly)
{
TaskOnWorkspaceNumber = pWorkspaces->getDesktop(WindowList[i].Window);
if (TaskOnWorkspaceNumber != pWorkspaces->currentScreen && TaskOnWorkspaceNumber != 255)
continue;
}
ThisButton.left = MainRect.left + (DrawnTasks * TaskWidth);
ThisButton.right = ThisButton.left + TaskWidthMinusPadding;
if (pSettings->taskbarMode != 2)
{
if (DrawnTasks == (NumberOfTasks - 1)) ThisButton.right = MainRect.right;
}
if (ThisButton.right > MainRect.right) break;
CopyRect(&WindowList[i].r, &ThisButton);
GetWindowText(WindowList[i].Window, ThisButtonWindowText, 255);
SetToolTip((UINT)WindowList[i].Window, WindowList[i].r, ThisButtonWindowText);
if (WindowList[i].Window == flashingHwnd)
{
MakeGradient(MainDC, ThisButton, pSettings->ActiveTask->type, pSettings->FlashingTask->Color, pSettings->FlashingTask->ColorTo, pSettings->InactiveTask->interlaced, pSettings->ActiveTask->bevelstyle, pSettings->ActiveTask->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, 1);
}
else if ((DrawnTasks == (NumberOfTasks - 1)) && (pSettings->taskbarMode != 2))
{
if (WindowList[i].Active) MakeGradient(MainDC, ThisButton, pSettings->ActiveTask->type, pSettings->ActiveTask->Color, pSettings->ActiveTask->ColorTo, pSettings->ActiveTask->interlaced, pSettings->ActiveTask->bevelstyle, pSettings->ActiveTask->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, 1);
else if (pSettings->taskbarInactiveBackground) MakeGradient(MainDC, ThisButton, pSettings->InactiveTask->type, pSettings->InactiveTask->Color, pSettings->InactiveTask->ColorTo, pSettings->InactiveTask->interlaced, pSettings->InactiveTask->bevelstyle, pSettings->InactiveTask->bevelposition, pSettings->bevelWidth, pSettings->Toolbar->borderColor, 1);
}
else
{
if (WindowList[i].Active) BitBlt(MainDC, ThisButton.left, ThisButton.top, TaskWidthMinusPadding, TaskHeight, cachedTaskButtonActive, 0, 0, SRCCOPY);
else if (pSettings->taskbarInactiveBackground) BitBlt(MainDC, ThisButton.left, ThisButton.top, TaskWidthMinusPadding, TaskHeight, cachedTaskButtonInactive, 0, 0, SRCCOPY);
}
if (pSettings->taskbarMode != 1)
{
ThisButtonWnd = WindowList[i].Window;
SendMessageTimeout(ThisButtonWnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG|SMTO_BLOCK, 200, (PDWORD_PTR)&ThisButtonIcon);
if (!ThisButtonIcon) ThisButtonIcon = (HICON)GetClassLongPtr(ThisButtonWnd, GCLP_HICONSM);
if (!ThisButtonIcon) SendMessageTimeout(ThisButtonWnd, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG|SMTO_BLOCK, 200, (PDWORD_PTR)&ThisButtonIcon);
if (!ThisButtonIcon) ThisButtonIcon = (HICON)GetClassLongPtr(ThisButtonWnd, GCLP_HICON);
if (pSettings->taskbarMode == 3) iconRect.left = ThisButton.left + 5;
else iconRect.left = ThisButton.left + 3;
iconRect.top = ThisButton.top + (TaskHeight/2) - (iconSize/2);
iconRect.right = iconRect.left + iconSize;
iconRect.bottom = iconRect.top + iconSize;
if (ThisButtonIcon) DrawSatHueIcon(MainDC, ThisButtonIcon, iconSize, iconRect, false, WindowList[i].Active);
ThisButton.left = iconRect.right + 3;
}
else ThisButton.left = ThisButton.left + 5;
ThisButton.right = ThisButton.right - 5;
if (pSettings->taskbarMode != 2)
{
HFONT font = CreateFont(pSettings->Toolbar->FontHeight, 0, 0, 0, pSettings->Toolbar->FontWeight, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, pSettings->Toolbar->Font);
HGDIOBJ oldfont = SelectObject(MainDC, font);
SetBkMode(MainDC, TRANSPARENT);
if (WindowList[i].Window == flashingHwnd) DrawTextWithShadow(MainDC, ThisButtonWindowText, ThisButton, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS, pSettings->FlashingTask->TextColor, pSettings->flashingTaskShadowColor, pSettings->ActiveTask->FontShadow);
else if (WindowList[i].Active) DrawTextWithShadow(MainDC, ThisButtonWindowText, ThisButton, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS, pSettings->ActiveTask->TextColor, pSettings->activeTaskShadowColor, pSettings->ActiveTask->FontShadow);
else DrawTextWithShadow(MainDC, ThisButtonWindowText, ThisButton, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS, pSettings->InactiveTask->TextColor, pSettings->inactiveTaskShadowColor, pSettings->InactiveTask->FontShadow);
DeleteObject(SelectObject(MainDC, oldfont));
}
if (WindowList[i].Window == flashingHwnd) flashingHwnd = 0;
DrawnTasks++;
}
return 1;
}
void Systembar::DrawSatHueIcon(HDC hdc, HICON icon, int size, RECT r, bool trayIcon, bool activeTask)
{
DrawIconEx(hdc, r.left, r.top, icon, size, size, 0, NULL, DI_NORMAL);
if (activeTask && !pSettings->taskbarActiveSatHue) return;
int saturation, hue;
if (trayIcon)
{
saturation = pSettings->systraySaturationValue;
hue = pSettings->systrayHueIntensity;
}
else
{
saturation = pSettings->taskbarSaturationValue;
hue = pSettings->taskbarHueIntensity;
}
if (saturation < 255 || hue > 0)
{
hueColor = pSettings->Toolbar->Color;
HDC iconhdc = CreateCompatibleDC(hdc);
HBITMAP iconbufbmp = ::CreateCompatibleBitmap(hdc, size, size);
HBITMAP oldiconbuf = (HBITMAP) ::SelectObject(iconhdc, iconbufbmp);
DrawIconEx(iconhdc, 0, 0, icon, size, size, 0, NULL, DI_MASK);
invsat = 255 - saturation;
invhue = 255 - hue;
for (int y=0; y < size; y++)
{
for (int x=0; x < size; x++)
{
if (!GetPixel(iconhdc, x, y))
{
pixel = GetPixel(hdc, (r.left + x), (r.top + y));
red = GetRValue(pixel);
green = GetGValue(pixel);
blue = GetBValue(pixel);
if (saturation < 255)
{
greyscale = (BYTE)(red*0.3086 + green*0.6094 + blue*0.0820);
red = (BYTE)((red*saturation + greyscale*invsat + 255)>>8);
green = (BYTE)((green*saturation + greyscale*invsat + 255)>>8);
blue = (BYTE)((blue*saturation + greyscale*invsat + 255)>>8);
}
if (hue > 0)
{
red = (BYTE)((red*invhue + GetRValue(hueColor)*hue + 255)>>8);
green = (BYTE)((green*invhue + GetGValue(hueColor)*hue + 255)>>8);
blue = (BYTE)((blue*invhue + GetBValue(hueColor)*hue + 255)>>8);
}
SetPixel(hdc, (r.left + x), (r.top + y), RGB(red, green, blue));
}
}
}
SelectObject(iconhdc, oldiconbuf);
DeleteObject(iconbufbmp);
DeleteDC(iconhdc);
}
}
void Systembar::GetSettings()
{
ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
int ToolbarHeight = 0;
if (pToolbar) ToolbarHeight = pToolbar->ToolbarHeight;
int minimumHeight = 22 + (pSettings->Toolbar->borderWidth * 2);
if (ToolbarHeight < minimumHeight) SystembarHeight = minimumHeight;
else SystembarHeight = ToolbarHeight;
if (!stricmp(pSettings->systembarPlacement, "DockedToSlit"))
{
SystembarWidth = (ScreenWidth * pSettings->systembarWidthPercent) / 100;
}
else if (!stricmp(pSettings->systembarPlacement, "DockedToToolbar"))
{
if (!pSettings->systembarHidden && pSettings->toolbarHidden) PostMessage(GetBBWnd(), BB_TOGGLETOOLBAR, 0, 0);
SystembarWidth = (ScreenWidth * pSettings->toolbarWidthPercent) / 100;
if (pSettings->toolbarPlacement[0] == 'M')
{
if (pToolbar)
{
RECT tbRect;
GetWindowRect(pToolbar->hTo