#include "Desk.h"
const char szDesktopName[] = "DesktopBackgroundClass";
int HeightList[MAX_LINE_LENGTH] = {NULL};
ATOM WindowTypeList[MAX_LINE_LENGTH] = {NULL};
extern Settings *pSettings;
extern MenuMaker *pMenuMaker;
extern Desk *pDesk;
extern Toolbar *pToolbar;
extern Systembar *pSystembar;
extern PluginManager *pPluginManager;
HINSTANCE deskInstance = NULL;
ATOM deskrc;
int ScreenWidth, ScreenHeight;
int ScreenTop, ScreenLeft;
#ifndef SPI_SETACTIVEWINDOWTRACKING
#define SPI_SETACTIVEWINDOWTRACKING 0x1001
#endif
#ifndef SPI_SETACTIVEWNDTRKZORDER
#define SPI_SETACTIVEWNDTRKZORDER 0x100D
#endif
#ifndef SPI_SETACTIVEWNDTRKTIMEOUT
#define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003
#endif
Desk::Desk(HINSTANCE hMainInstance)
{
SystemParametersInfo(SPI_SETACTIVEWNDTRKTIMEOUT, 0, (PVOID)pSettings->autoRaiseDelay, SPIF_SENDCHANGE);
if (!stricmp(pSettings->focusModel, "ClickToFocus"))
{
SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, 0, (PVOID)false, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETACTIVEWNDTRKZORDER, 0, (PVOID)false, SPIF_SENDCHANGE);
}
else if (!stricmp(pSettings->focusModel, "AutoRaiseSloppyFocus"))
{
SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, 0, (PVOID)true, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETACTIVEWNDTRKZORDER, 0, (PVOID)true, SPIF_SENDCHANGE);
}
else if (!stricmp(pSettings->focusModel, "SloppyFocus"))
{
SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, 0, (PVOID)true, SPIF_SENDCHANGE);
SystemParametersInfo(SPI_SETACTIVEWNDTRKZORDER, 0, (PVOID)false, SPIF_SENDCHANGE);
}
createDesktop(hMainInstance);
}
Desk::~Desk()
{
destroyDesktop();
}
bool Desk::createDesktop(HINSTANCE hInstance)
{
deskInstance = hInstance;
WNDCLASS wc;
ZeroMemory(&wc, sizeof(wc));
wc.hInstance = deskInstance;
wc.lpfnWndProc = DesktopWndProc;
wc.lpszClassName = szDesktopName;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
deskrc = RegisterClass(&wc);
if (!deskrc)
{
MessageBox(0, "Error registering desktop class", szDesktopName, MB_OK);
Log("Could not register desktop class", NULL);
return false;
}
if (pSettings->usingWin2kXP)
{
ScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
ScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
ScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
ScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
}
else
{
ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
ScreenLeft = 0;
ScreenTop = 0;
}
hDesktopWnd = CreateWindowEx(
WS_EX_TOOLWINDOW,
szDesktopName,
NULL,
WS_POPUP,
ScreenLeft,
ScreenTop,
ScreenWidth,
ScreenHeight,
NULL,
NULL,
deskInstance,
0);
if (!hDesktopWnd)
{
UnregisterClass(szDesktopName, deskInstance);
MessageBox(0, "Error creating desktop window", szDesktopName, MB_OK);
Log("Could not create desktop window", NULL);
return false;
}
MakeSticky(hDesktopWnd);
DragAcceptFiles(hDesktopWnd, true);
SetWindowPos(hDesktopWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
int msgs[] = { BB_WINDOWSHADE, BB_WINDOWLOWER, BB_WINDOWRAISE, BB_WINDOWGROWHEIGHT, BB_WINDOWGROWWIDTH, 0 };
SendMessage(GetBBWnd(), BB_REGISTERMESSAGE, (WPARAM)hDesktopWnd, (LPARAM)msgs);
return true;
}
void Desk::destroyDesktop()
{
int msgs[] = { BB_WINDOWSHADE, BB_WINDOWLOWER, BB_WINDOWRAISE, BB_WINDOWGROWHEIGHT, BB_WINDOWGROWWIDTH, 0 };
SendMessage(GetBBWnd(), BB_UNREGISTERMESSAGE, (WPARAM)hDesktopWnd, (LPARAM)msgs);
DestroyWindow(hDesktopWnd);
UnregisterClass(szDesktopName, deskInstance);
}
LRESULT CALLBACK DesktopWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
return 0;
case WM_KEYDOWN:
{
if (wParam == SC_CLOSE)
{
PostMessage(GetBBWnd(), BB_SHUTDOWN, 0, 0);
return 0;
}
else return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
break;
case WM_LBUTTONUP:
{
if (pMenuMaker)
{
if (pSettings->followActive) SetForegroundWindow(pToolbar->hToolbarWnd);
pMenuMaker->Hide();
}
}
break;
case WM_LBUTTONDOWN: { } break;
case WM_RBUTTONUP:
{
if (GetAsyncKeyState(VK_MENU) & 0x8000)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
{
if (pSettings->midclickStylesMenu) SendMessage(GetBBWnd(), BB_MENU, 1, 0);
else SendMessage(GetBBWnd(), BB_MENU, 6, 0);
}
else
{
if (pSettings->midclickStylesMenu) SendMessage(GetBBWnd(), BB_MENU, 5, 0);
else SendMessage(GetBBWnd(), BB_MENU, 1, 0);
}
}
else if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
{
if (pSettings->midclickStylesMenu) SendMessage(GetBBWnd(), BB_MENU, 6, 0);
else SendMessage(GetBBWnd(), BB_MENU, 5, 0);
}
else if (GetAsyncKeyState(VK_CONTROL) & 0x8000) BBExecute(GetDesktopWindow(), NULL, "control.exe", "desk.cpl,,3", NULL, SW_SHOWNORMAL, false);
else SendMessage(GetBBWnd(), BB_MENU, 0, 0);
}
break;
case WM_RBUTTONDOWN: { } break;
case WM_MBUTTONUP:
{
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000) PostMessage(GetBBWnd(), BB_TOGGLESLIT, 0, 0);
else PostMessage(GetBBWnd(), BB_TOGGLEPLUGINS, 0, 0);
}
else if (pSettings->midclickStylesMenu)
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000) SendMessage(GetBBWnd(), BB_MENU, 1, 0);
else if (GetAsyncKeyState(VK_MENU) & 0x8000) SendMessage(GetBBWnd(), BB_MENU, 6, 0);
else SendMessage(GetBBWnd(), BB_MENU, 5, 0);
}
else
{
if (GetAsyncKeyState(VK_SHIFT) & 0x8000) SendMessage(GetBBWnd(), BB_MENU, 6, 0);
else if (GetAsyncKeyState(VK_MENU) & 0x8000) SendMessage(GetBBWnd(), BB_MENU, 5, 0);
else SendMessage(GetBBWnd(), BB_MENU, 1, 0);
}
}
break;
case WM_MBUTTONDOWN: { } break;
case WM_XBUTTONDOWN:
{
if (HIWORD(wParam) == XBUTTON1)
{
BBExecute(GetDesktopWindow(), NULL, "control.exe", "desk.cpl,,3", NULL, SW_SHOWNORMAL, false);
}
else if (HIWORD(wParam) == XBUTTON2) BBExecute(GetDesktopWindow(), NULL, "control.exe", "mmsys.cpl", NULL, SW_SHOWNORMAL, false);
}
break;
case WM_XBUTTONUP: { } break;
case WM_SYSCOMMAND:
{
if (wParam == SC_CLOSE)
{
PostMessage(GetBBWnd(), BB_SHUTDOWN, 0, 0);
return 0;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
PaintDesktop(hDC);
EndPaint(hWnd, &ps);
}
return 0;
case WM_MOUSEACTIVATE:
{
return MA_NOACTIVATE;
}
case WM_ACTIVATE:
{
if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
SetActiveWindow(hWnd);
return 0;
}
case WM_QUERYENDSESSION:
case WM_ENDSESSION:
return SendMessage(hWnd, uMsg, wParam, lParam);
case WM_ERASEBKGND:
{
PaintDesktop((HDC)(wParam));
return true;
}
case WM_DISPLAYCHANGE:
{
if (pSettings->usingWin2kXP)
{
ScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
ScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
ScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
ScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
}
else
{
ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
ScreenLeft = 0;
ScreenTop = 0;
}
MoveWindow(hWnd, ScreenLeft, ScreenTop, ScreenWidth, ScreenHeight, true);
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, ScreenWidth, ScreenHeight, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
}
break;
case WM_WINDOWPOSCHANGING:
{
SetWindowPos(hWnd, HWND_BOTTOM, ScreenLeft, ScreenTop, ScreenWidth, ScreenHeight, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
break;
}
case WM_NCPAINT:
{
if (!wParam) SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
return 0;
}
case BB_WINDOWSHADE:
pDesk->ShadeWindow();
break;
case BB_WINDOWGROWHEIGHT:
pDesk->GrowWindowHeight();
break;
case BB_WINDOWGROWWIDTH:
pDesk->GrowWindowWidth();
break;
case BB_WINDOWLOWER:
pDesk->LowerWindow();
break;
case BB_WINDOWRAISE:
pDesk->RaiseWindow();
break;
case WM_DROPFILES:
{
static TCHAR filename[MAX_LINE_LENGTH];
DragQueryFile((HDROP)wParam, 0, filename, sizeof(filename));
char path[MAX_LINE_LENGTH];
strcpy(path, filename);
if (path[0] == '\"') StrRemoveEncap(path);
SendMessage(GetBBWnd(), BB_DRAGTODESKTOP, 0, (LPARAM)path);
int pointer = strlen(path) - 4;
if (!stricmp(&path[pointer], ".jpg")
|| !stricmp(&path[pointer], ".png")
|| !stricmp(&path[pointer], ".bmp")
|| !stricmp(&path[pointer], ".gif")
|| !stricmp(&path[pointer], ".tif")
|| !stricmp(&path[pointer], "jpeg"))
{
char arguments[MAX_LINE_LENGTH];
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
strcpy(arguments, "-center ");
else if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
strcpy(arguments, "-full ");
else strcpy(arguments, "-tile ");
if (strchr(path, ' '))
{
strcat(arguments, "\"");
strcat(arguments, path);
strcat(arguments, "\"");
}
else strcat(arguments, path);
char bbpath[MAX_LINE_LENGTH];
GetBlackboxPath(bbpath, sizeof(bbpath));
BBExecute(GetDesktopWindow(), NULL, "bsetbg.exe", arguments, bbpath, SW_SHOWNORMAL, false);
}
else if (!stricmp(&path[pointer], ".dll"))
{
char deskPlugPath[MAX_PATH];
strcpy(deskPlugPath, ">");
strcat(deskPlugPath, path);
pPluginManager->loadPlugin(deskPlugPath);
}
}
break;
case DOCK_ADD:
{
pDesk->vDeskWindows.push_back((HWND) lParam);
if(IsWindow((HWND)lParam))
{
SetWindowLong((HWND)lParam, GWL_STYLE, (GetWindowLong((HWND)lParam, GWL_STYLE) & ~WS_POPUP) | WS_CHILD);
SetParent((HWND)lParam, pDesk->hDesktopWnd);
}
}
break;
case DOCK_REMOVE:
{
vector<HWND>::iterator hwndDeskPlugin;
for (hwndDeskPlugin = pDesk->vDeskWindows.begin(); hwndDeskPlugin != pDesk->vDeskWindows.end(); hwndDeskPlugin++)
{
if (*hwndDeskPlugin == (HWND)lParam)
{
pDesk->vDeskWindows.erase(hwndDeskPlugin);
break;
}
}
if (IsWindow((HWND)lParam))
{
SetWindowLong((HWND)lParam, GWL_STYLE, (GetWindowLong((HWND)lParam, GWL_STYLE) & ~WS_CHILD) | WS_POPUP);
SetParent((HWND)lParam, NULL);
}
}
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void Desk::ShadeWindow()
{
int i, TitleBarHeight = GetSystemMetrics(SM_CYMIN);
RECT r;
bool IsUnshaded;
HWND currentwnd = pSystembar->GetCurrentWindow();
BOOL IsMaximized = IsZoomed(currentwnd);
GetWindowRect(currentwnd, &r);
IsUnshaded = (r.bottom - r.top > TitleBarHeight);
i = IsFlaggedShaded(currentwnd);
if (IsMaximized)
{
if (IsUnshaded)
WinShade(currentwnd, -1, IsMaximized);
else
WinUnshade(currentwnd, -1, IsMaximized);
}
else
{
if (i != -1)
{
if (IsUnshaded)
{
RemoveProp(currentwnd,"BBNormalHeight");
WinShade(currentwnd, -1, IsMaximized);
}
else
{
WinUnshade(currentwnd, i, IsMaximized);
}
}
else
{
WinShade(currentwnd, i, IsMaximized);
}
}
}
int Desk::IsFlaggedShaded(HWND hwnd)
{
return (GetProp(hwnd,"BBNormalHeight") != NULL);
}
void Desk::WinUnshade(HWND MoveHwnd, int ListIndex, BOOL Maximized)
{
int i = ListIndex;
RECT r;
int height;
SetForegroundWindow(MoveHwnd);
if (i == -1 && !Maximized) return;
if (Maximized)
{
RECT WorkArea;
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&WorkArea, SPIF_SENDCHANGE);
height = WorkArea.bottom - WorkArea.top;
}
else
{
height = (long)GetProp(MoveHwnd,"BBNormalHeight");
RemoveProp(MoveHwnd,"BBNormalHeight");
}
if (height == 0) return;
GetWindowRect(MoveHwnd, &r);
MoveWindow(MoveHwnd, r.left, r.top, r.right-r.left, height, TRUE);
InvalidateRect(MoveHwnd, NULL, false);
}
void Desk::WinShade(HWND MoveHwnd, int ListIndex, BOOL Maximized)
{
int i = ListIndex;
RECT r;
SetForegroundWindow(MoveHwnd);
if (i != -1) return;
GetWindowRect(MoveHwnd, &r);
if (!Maximized)
SetProp(MoveHwnd,"BBNormalHeight",(HANDLE)(r.bottom - r.top));
SetWindowPos(MoveHwnd, HWND_TOP,
r.left, r.top,
r.right - r.left,
GetSystemMetrics(SM_CYMIN), SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
return;
}
void Desk::GrowWindowHeight()
{
HWND currentwnd = pSystembar->GetCurrentWindow();
RECT r, WorkArea;
GetWindowRect(currentwnd, &r);
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&WorkArea, SPIF_SENDCHANGE);
MoveWindow(currentwnd, r.left, 0, r.right-r.left, WorkArea.bottom-WorkArea.top, TRUE);
InvalidateRect(currentwnd, NULL, false);
SetForegroundWindow(currentwnd);
}
void Desk::GrowWindowWidth()
{
HWND currentwnd = pSystembar->GetCurrentWindow();
RECT r, WorkArea;
GetWindowRect(currentwnd, &r);
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&WorkArea, SPIF_SENDCHANGE);
MoveWindow(currentwnd, 0, r.top, WorkArea.right-WorkArea.left, r.bottom-r.top, TRUE);
GetWindowRect(currentwnd, &r);
SetForegroundWindow(currentwnd);
}
void Desk::LowerWindow()
{
HWND currentwnd = pSystembar->GetCurrentWindow();
HWND bbwnd = GetBBWnd();
HWND bottomwnd = GetWindow(bbwnd, GW_HWNDLAST);
HWND hProgManWnd = FindWindow("Progman", "Program Manager");
if (bottomwnd == hProgManWnd) bottomwnd = GetWindow(bottomwnd, GW_HWNDPREV);
while (!(IsWindowVisible(bottomwnd)) | IsIconic(bottomwnd) | !(GetWindowTextLength(bottomwnd)))
{
bottomwnd = GetWindow(bottomwnd, GW_HWNDPREV);
if (bottomwnd == hProgManWnd) bottomwnd = GetWindow(bottomwnd, GW_HWNDPREV);
}
if (IsWindow(currentwnd) && IsWindow(bottomwnd))
SetWindowPos(currentwnd, bottomwnd, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
}
void Desk::RaiseWindow()
{
HWND currentwnd = pSystembar->GetCurrentWindow();
SetWindowPos(currentwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
}
syntax highlighting by