#include <windows.h>
#include <Winuser.h>
#include "gen.h"
#include "winamp.h"
#include "resource.h"
#define _WIN32_WINNT 0x0400
#define WS_EX_LAYERED 0x80000
#define LWA_COLORKEY 1
#define LWA_ALPHA 2
#define TITLEBG_COLOR RGB(253, 220, 153)
#define CLIENTBG_COLOR RGB(254, 243, 199)
#define TITLE_HEIGHT 17
#define CLIENT_HEIGHT 50
#define WINDOW_HEIGHT (CLIENT_HEIGHT + TITLE_HEIGHT)
#define RIGHT_DESKTOP_SPACING 10
#define BOTTOM_DESKTOP_SPACING 10
#define ICON_WIDTH 14
#define ICON_HEIGHT 14
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
typedef DWORD (WINAPI *PSLWA)(HWND, DWORD, BYTE, DWORD);
PSLWA SetLayeredWindowAttributes;
void config();
void quit();
int init();
char szAppName[] = "Nullsoft Song Show";
HWND songWin = NULL, winText = NULL;
int tid;
HANDLE thrd = NULL;
RECT tray, crc;
char *songTitle, songInfo[4096];
typedef struct
{
BOOL mouseDown;
BOOL isDown;
RECT rect;
} button_t;
button_t xButton;
winampGeneralPurposePlugin plugin =
{
GPPHDR_VER,
"",
init,
config,
quit
};
void config()
{
}
void quit()
{
}
void unshowWindow()
{
Sleep(4000);
ShowWindow(songWin, 0);
}
void PaintWindow()
{
HDC hdc;
RECT crect, titlerect;
HICON xbutton;
xbutton = LoadIcon(plugin.hDllInstance, MAKEINTRESOURCE(xButton.isDown?IDI_ICON1:IDI_ICON2));
hdc = GetWindowDC(songWin);
SetRect(&titlerect, 0, 0, crc.right, TITLE_HEIGHT);
SetRect(&crect, 0, TITLE_HEIGHT, crc.right, crc.bottom);
SelectObject(hdc, CreateSolidBrush(TITLEBG_COLOR));
Rectangle(hdc, 0, 0, titlerect.right, titlerect.bottom+1);
SelectObject(hdc, CreateSolidBrush(CLIENTBG_COLOR));
Rectangle(hdc, 0, titlerect.bottom, crect.right, crect.bottom);
SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, songInfo, -1, &crect,
DT_CENTER | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
DrawIcon(hdc, titlerect.right-16, 3, xbutton);
ReleaseDC(songWin, hdc);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT pt;
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
if (PtInRect(&xButton.rect, pt))
{
xButton.isDown = TRUE;
}
else
{
xButton.isDown = FALSE;
}
switch(message)
{
case WM_MOVE:
{
RECT rect;
GetWindowRect(hwnd, &rect);
SetRect(&xButton.rect, rect.right-16, rect.top+3, rect.right-16+ICON_WIDTH, rect.right-16+ICON_HEIGHT);
}
return FALSE;
case WM_NCACTIVATE:
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&PaintWindow, 0, 0, 0);
return FALSE;
}
case WM_CLOSE:
ShowWindow(songWin, 0);
return TRUE;
case WM_PAINT:
if (lParam)
{
PaintWindow();
return TRUE;
}
else
return FALSE;
case WM_NCLBUTTONDOWN:
if (xButton.isDown)
{
xButton.mouseDown = TRUE;
SetCapture(hwnd);
PaintWindow();
}
return FALSE;
case WM_LBUTTONUP:
ShowWindow(hwnd, 0);
if (thrd) TerminateThread(thrd, 0);
ReleaseCapture();
xButton.mouseDown = FALSE;
return TRUE;
default:
return FALSE;
}
return TRUE;
}
void showSongWindow()
{
int ret, width, right, height;
TEXTMETRIC tm;
HDC hdc;
int sampleRate, bitRate;
if (thrd) TerminateThread(thrd, 0);
ret = SendMessage(plugin.hwndParent, WM_USER, 0, 104);
if (ret != 1)
{
ShowWindow(songWin, 0);
return;
}
ret = SendMessage(plugin.hwndParent, WM_USER, 0, 125);
songTitle = (char *)SendMessage(plugin.hwndParent, WM_USER, ret, 212);
if (songTitle == NULL) return;
sampleRate = SendMessage(plugin.hwndParent, WM_USER, 0, 126);
bitRate = SendMessage(plugin.hwndParent, WM_USER, 1, 126);
sprintf(songInfo, "\n%s\n%dkpbs %2dkhz\n%c",
songTitle, bitRate, sampleRate, '\0');
hdc = GetDC(songWin);
GetTextMetrics(hdc, &tm);
ReleaseDC(songWin, hdc);
width = strlen(songTitle) * tm.tmAveCharWidth + 30;
height = 4 * tm.tmHeight;
right = tray.left - (width/2) + 25;
if ((right+width) > (tray.right-RIGHT_DESKTOP_SPACING)) right -= ((right+width)-(tray.right-RIGHT_DESKTOP_SPACING));
SetRect(&crc, 0, 0, width, TITLE_HEIGHT + height);
//OffsetRect(&crc, tray.right-width-10, tray.top - 10 - WINDOW_HEIGHT);
SetWindowPos(songWin, HWND_TOPMOST,
right,
tray.top - (TITLE_HEIGHT+height) - BOTTOM_DESKTOP_SPACING,
width, TITLE_HEIGHT + height, 0);
UpdateWindow(songWin);
ShowWindow(songWin, 1);
SendMessage(songWin, WM_PAINT, 0, 1);
thrd = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&unshowWindow, 0, 0, &tid);
}
void *lpWndProcOld;
LRESULT CALLBACK mWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_SETTEXT)
showSongWindow();
return CallWindowProc(lpWndProcOld,hwnd,message,wParam,lParam);
}
int init()
{
HMODULE hDLL = LoadLibrary ("user32");
lpWndProcOld = (void *)GetWindowLong(plugin.hwndParent, GWL_WNDPROC);
SetWindowLong(plugin.hwndParent, GWL_WNDPROC, (long)mWndProc);
GetWindowRect(FindWindowEx(FindWindow("Shell_TrayWnd", NULL), NULL, "TrayNotifyWnd", NULL), &tray);
SetLayeredWindowAttributes = (PSLWA)GetProcAddress(hDLL, "SetLayeredWindowAttributes");
songWin = CreateDialog(plugin.hDllInstance, MAKEINTRESOURCE(IDD_DIALOG1), plugin.hwndParent, WndProc);
if(songWin == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
xButton.isDown = FALSE;
SetWindowLong(songWin, GWL_EXSTYLE,
GetWindowLong(songWin, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(songWin, 0, (255 * 90) / 100, LWA_ALPHA);
return 0;
}
__declspec( dllexport ) winampGeneralPurposePlugin *winampGetGeneralPurposePlugin()
{
return &plugin;
}
void main() {} Powered by
GeSHi Syntax Highlighting software.
Author of all (other) material unless otherwise specified:
Loren Segal. Copyright 2005.