📄 vis_spectrum.cpp
字号:
case WM_PAINT:
{
// just update the current display
PAINTSTRUCT ps;
RECT Rect;
GetWindowRect(hWnd,&Rect);
HDC hDC;
hDC = BeginPaint(hWnd,&ps);
// use stretchblt incase of doublesize
StretchBlt(hDC,0,0,Rect.right - Rect.left, Rect.bottom - Rect.top,Plugin.hMemDC,0,0,STD_WIDTH,STD_HEIGHT,SRCCOPY);
EndPaint(hWnd,&ps);
return 0;
}
case WM_CHAR:
switch(wParam) {
// check for esc key
case VK_ESCAPE:
SendMessage(hWnd,WM_COMMAND,ID_CLOSEPLUGIN,0);
break;
default:
SendMessage(Plugin.hWndParent,uMsg,wParam,lParam);
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
case WM_COMMAND:
switch(LOWORD(wParam)) {
case ID_CLOSEPLUGIN:
SendMessage(hWnd,WM_CLOSE,0,0);
break;
case ID_CONFIG:
PostMessage(Plugin.hWndParent,WM_COMMAND,40221,0);
break;
case ID_ABOUT:
ShowWindow(CreateDialog(reinterpret_cast<HINSTANCE>(GetWindowLong(hWnd,GWL_HINSTANCE)),MAKEINTRESOURCE(IDD_ABOUTDLG),hWnd,AboutDlgProc),SW_SHOW);
break;
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
break;
case WM_DESTROY:
{
if(Plugin.Settings.bSaveWndPos) {
RECT rect;
char* szFileName = new char[256];
GetConfigFileName(&waModule,szFileName,256);
GetWindowRect(hWnd,&rect);
Plugin.Settings.ulLeft = rect.left;
Plugin.Settings.ulTop = rect.top;
WritePrivateProfileInt(PLUGIN_KEY,"ulLeft",Plugin.Settings.ulLeft,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"ulTop",Plugin.Settings.ulTop,szFileName);
delete[] szFileName;
// restore the original window procedure
SetWindowLong(Plugin.hWndParent,GWL_WNDPROC,(long)WndProcOld);
}
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return 0;
}
// Updates the rectangle and take into account the fact that
// it may be in doublesize mode.
void UpdateRect(LPRECT lpRect, HWND hWnd)
{
HDC hDC = GetDC(hWnd);
if(!Plugin.Settings.bDoubleSize) {
// update a cirtain rectangle on the window
BitBlt(hDC,lpRect->left,lpRect->top,lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, Plugin.hMemDC,lpRect->left,lpRect->top,SRCCOPY);
}
else {
StretchBlt(hDC,lpRect->left*2,lpRect->top*2,(lpRect->right - lpRect->left)*2, (lpRect->bottom - lpRect->top)*2, Plugin.hMemDC,lpRect->left,lpRect->top,lpRect->right - lpRect->left,lpRect->bottom - lpRect->top,SRCCOPY);
}
ReleaseDC(hWnd,hDC);
}
// The same as the windows function PtInRect only it takes into
// account the fact that the window may be in doublesize mode.
bool PointInRect(LPRECT lpRect, POINT& pt)
{
if(!Plugin.Settings.bDoubleSize) {
if(pt.x >= lpRect->left && pt.x <= lpRect->right && pt.y >= lpRect->top && pt.y <=lpRect->bottom)
return true;
}
else {
if(pt.x >= lpRect->left*2 && pt.x <= lpRect->right*2 && pt.y >= lpRect->top*2 && pt.y <= lpRect->bottom*2)
return true;
}
return false;
}
// Subclass callback for winamp so we can detect when the stop
// button is clicked or when the end of file is reached or whatever.
// Any funny bits not in the winamp api documentation (such as
// hidden messages or whatever) were found with Spy++.
// -- Note: Someone please find a stable method of subclassing the winamp
// window. I must be missing something.
LRESULT CALLBACK SubWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg==WM_COMMAND) {
switch(LOWORD(wParam)) {
case PLUGIN_TOGGLE:
// Prevents winamp from crashing when you close the plugin
PostMessage(Plugin.hWndMain,WM_CLOSE,0,0);
return 0;
case WINAMP_BUTTON2: // otherwise known as play
// if an effect is on, stop it.
KillUpdateThread();
break;
case WINAMP_BUTTON3: // otherwise known as pause
// drop the bars down, EFFECT_WAVE is not perfect, do not use.
InitUpdateThread(EFFECT_DROP);
break;
case WINAMP_BUTTON1: // skip back
case WINAMP_BUTTON5: // skip forward
// make sure that no effects are on
KillUpdateThread();
break;
case WINAMP_BUTTON4: { // the stop button
// drop the bars down
InitUpdateThread(EFFECT_DROP);
}
} // end of switch
}
else if(uMsg==WM_COPYDATA) {
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
// code for opening a new file
if(pcds->dwData == WINAMP_PLAYFILE) {
// kill the effect thread as we are now playing
KillUpdateThread();
}
}
else if(uMsg==WM_CLOSE) {
if(IsWindow(Plugin.hWndMain)) {
PostMessage(Plugin.hWndMain,WM_CLOSE,0,0);
PostMessage(Plugin.hWndParent,WM_CLOSE,0,0);
}
return 0;
}
else if(uMsg==WM_SYSCOMMAND) {
if(wParam == 0x00009D00 && lParam == 0x00010000) {
// this is when ctrl+shift+k is pressed
PostMessage(Plugin.hWndMain,WM_CLOSE,0,0);
// if you call the winamp window procedure it
// fucks up so just return instead.
return 0;
}
}
else if(uMsg==WM_USER+2) {
// end of file:
InitUpdateThread(EFFECT_DROP);
}
// Fixme: Get winamp to dock with us and get our window to move if
// docked with winamp.
/*else if(uMsg==WM_WINDOWPOSCHANGING) {
LPWINDOWPOS lpWndPos = reinterpret_cast<LPWINDOWPOS>(lParam);
RECT rcMe;
GetWindowRect(Plugin.hWndMain,&rcMe);
rect_list_dock(hWnd,&lpWndPos->x,&lpWndPos->y,Plugin.Settings.ulWindowSnap,&rcMe,1);
}*/
//call the original window procedure
return CallWindowProc((WNDPROC)WndProcOld,hWnd,uMsg,wParam,lParam);
}
// This thread function will create a drop effect on the bars
// if it is called and at the same time, update the main window.
// It is used when winamp is stopped or paused.
DWORD APIENTRY UpdateThread(LPVOID lpParam)
{
int nFunc = ((int)lpParam);
switch(nFunc) {
case EFFECT_DROP:
{
for(int i=0;i<576;i++) {
waModule.spectrumData[0][i] = 0;
}
for(i=0;i<255 && !kill_update_thread;i++) {
Sleep(waModule.delayMs);
OnPluginRender(&waModule);
}
PostMessage(Plugin.hWndMain,WM_USER,0,USR_CLOSETHREAD);
break;
}
case EFFECT_WAVE:
{
bool bFilterMap = Plugin.Settings.bFilter;
Plugin.Settings.bFilter = true;
for(int i=0;i<576;i++) {
waModule.spectrumData[0][i] = 0;
g_achDisplayData[i] = 0;
}
bool bForward = true;
while(!kill_update_thread) {
if(bForward) {
for(int i=0;i<256/Plugin.Settings.uchBarWidth && !kill_update_thread;i++) {
if(g_achDisplayData[i] > 0) g_achDisplayData[i] = 0;
Sleep(waModule.delayMs*2);
g_achScreenData[i] = 255;
g_achPeakData[0][i] = 255;
OnPluginRender(&waModule);
for(int j=0;j<Plugin.Settings.uchBarWidth;j++) {
Sleep(waModule.delayMs/2);
OnPluginRender(&waModule);
}
}
bForward = false;
}
else {
for(int i=(256/Plugin.Settings.uchBarWidth)-1;i>=0 && !kill_update_thread;i--) {
if(g_achDisplayData[i] > 0) g_achDisplayData[i] = 0;
Sleep(waModule.delayMs*2);
g_achScreenData[i] = 255;
g_achPeakData[0][i] = 255;
OnPluginRender(&waModule);
for(int j=0;j<Plugin.Settings.uchBarWidth;j++) {
Sleep(waModule.delayMs/2);
OnPluginRender(&waModule);
}
}
bForward = true;
}
}
Plugin.Settings.bFilter = bFilterMap;
break;
}
default:
break;
}
return 0;
}
void KillUpdateThread()
{
if(!hThread) return;
kill_update_thread = 1;
if (WaitForSingleObject(hThread,INFINITE) == WAIT_TIMEOUT)
{
TerminateThread(hThread,0);
}
if(hThread) CloseHandle(hThread);
hThread = NULL;
kill_update_thread = 0;
}
void InitUpdateThread(int nFunc)
{
DWORD dwID;
if(hThread) return;
kill_update_thread = 0;
hThread = CreateThread(NULL,0,UpdateThread,(LPVOID)nFunc,0,&dwID);
}
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_INITDIALOG:
g_bAboutActive = true;
break;
case WM_COMMAND:
{
switch(LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
g_bAboutActive = false;
EndDialog(hDlg,LOWORD(wParam));
break;
}
return FALSE;
}
default:
return FALSE;
}
return TRUE;
}
// Read in bar colour mappings from the skin bitmap. Also gets
// grid colour ,peak colour and background colour.
void GetColourMap()
{
HDC hDC = CreateCompatibleDC(NULL);
HGDIOBJ hOld = SelectObject(hDC,Plugin.hBmpSkin);
for(int i=0;i<256;i++) {
g_ulColourMap[i] = GetPixel(hDC,(255-(i))+18,144);
}
g_ulPeakColour = GetPixel(hDC,274,144);
g_ulBackColour = GetPixel(hDC,274,145);
g_ulGridColour = GetPixel(hDC,273,145);
SelectObject(hDC, hOld);
DeleteDC(hDC);
}
bool SetCurrentSkin(const char* lpszBitmap)
{
DeleteObject(Plugin.hBmpSkin);
if(lpszBitmap!=NULL) {
Plugin.hBmpSkin = (HBITMAP)LoadImage(NULL,lpszBitmap,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(!Plugin.hBmpSkin) Plugin.hBmpSkin = LoadBitmap(waModule.hDllInstance,MAKEINTRESOURCE(IDB_BMPSKIN));
}
else {
Plugin.hBmpSkin = LoadBitmap(waModule.hDllInstance,MAKEINTRESOURCE(IDB_BMPSKIN));
}
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin,0,0,STD_WIDTH,STD_HEIGHT,0,0);
GetColourMap();
// if dim titles then make it appear dimmed if in settings
if(Plugin.Settings.bDimTitleBar) {
if(Plugin.bInConfig) {
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, 0, 0, 275, 14, 0, 130);
}
}
// update the window
SendMessage(Plugin.hWndMain,WM_USER,0,USR_REDRAWWINDOW);
return true;
}
void LoadSkin()
{
char* FileName = new char[256];
char* skin = new char[256];
GetConfigFileName(&waModule,FileName,256);
GetPrivateProfileString(PLUGIN_KEY,"skin",0,skin,256,FileName);
SetCurrentSkin(skin);
delete[] skin;
delete[] FileName;
}
void SaveSkin(char* szName)
{
char* FileName = new char[256];
char* skin = new char[256];
GetConfigFileName(&waModule,FileName,256);
WritePrivateProfileString(PLUGIN_KEY,"skin",szName,FileName);
SetCurrentSkin(skin);
delete[] skin;
delete[] FileName;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -