Viewing file: c/winamp_songname/songname.c | Back to directory listing
Author: Loren Segal | Last modified: February 20 2006 07:00 pm | Download

#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() {}