📄 win32window.cpp
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Copyright (C) 1999 EMusic
Portions Copyright (C) 1999 Valters Vingolds
Portions Copyright (C) 2000 Chen Su
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: Win32Window.cpp,v 1.47 2000/12/29 21:28:47 robert Exp $
____________________________________________________________________________*/
// The debugger can't handle symbols more than 255 characters long.
// STL often creates symbols longer than that.
// When symbols are longer than 255 characters, the warning is disabled.
#ifdef WIN32
#pragma warning(disable:4786)
#define STRICT
#endif
#include <map>
#include <stdio.h>
#include "Theme.h"
#include "Win32Window.h"
#include "Win32Canvas.h"
#include "Win32Bitmap.h"
#include "Median.h"
#include "resource.h"
#include "utility.h"
#include "debug.h"
#define DB Debug_v("%s:%d\n", __FILE__, __LINE__);
const int iNumColorsInHist = 32768;
const int iNumColorsInPalette = 236;
const int iNumColorsTotal = 256;
const static char szAppName[] = BRANDING;
HINSTANCE g_hinst = NULL;
#define IDI_EXE_ICON 101
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#define WHEEL_DELTA 120
#endif
INT WINAPI DllMain (HINSTANCE hInstance,
ULONG ul_reason_being_called,
LPVOID lpReserved)
{
switch (ul_reason_being_called)
{
case DLL_PROCESS_ATTACH:
g_hinst = hInstance;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return 1;
}
static LRESULT WINAPI MainWndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
LRESULT result = 0;
Win32Window* ui = (Win32Window*)GetWindowLong(hwnd, GWL_USERDATA);
switch (msg)
{
case WM_CREATE:
{
// When we create the window we pass in a pointer to our
// UserInterface object...
// Tuck away the pointer in a safe place
ui = (Win32Window*)((LPCREATESTRUCT)lParam)->lpCreateParams;
assert(ui != NULL);
result = SetWindowLong(hwnd, GWL_USERDATA, (LONG)ui);
//ui->Init();
SetTimer(hwnd, 0, 250, NULL);
// We want people to be able to drop files on the player
DragAcceptFiles(hwnd, TRUE);
break;
}
default:
if (!ui)
return DefWindowProc( hwnd, msg, wParam, lParam );
return ui->WindowProc(hwnd, msg, wParam, lParam);
}
return result;
}
LRESULT Win32Window::WindowProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (m_bMindMeldInProgress)
return 0;
switch (msg)
{
case WM_CLOSE:
{
Rect oRect;
Pos oPos;
KillTimer(hwnd, 0);
GetWindowPosition(oRect);
oPos.x = oRect.x1;
oPos.y = oRect.y1;
SaveWindowPos(oPos);
PostQuitMessage(0);
m_pTheme->HandleControlMessage(string("Quit"), CM_Pressed);
break;
}
case WM_TIMER:
MouseLeaveCheck();
m_pMindMeldMutex->Acquire();
TimerEvent();
m_pMindMeldMutex->Release();
break;
case WM_DESTROY:
break;
case WM_PAINT:
m_pMindMeldMutex->Acquire();
Paint();
m_pMindMeldMutex->Release();
break;
case WM_MOUSEMOVE:
{
POINT pt;
Pos oPos;
pt.x = (int16)LOWORD(lParam);
pt.y = (int16)HIWORD(lParam);
ClientToScreen(hwnd, &pt);
oPos.x = pt.x;
oPos.y = pt.y;
m_pMindMeldMutex->Acquire();
HandleMouseMove(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_NCMOUSEMOVE:
{
Pos oPos;
oPos.x = (int16)LOWORD(lParam);
oPos.y = (int16)HIWORD(lParam);
m_pMindMeldMutex->Acquire();
HandleMouseMove(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_MOUSEWHEEL:
{
short iDelta;
iDelta = (int)(((short)HIWORD(wParam)) / WHEEL_DELTA);
m_pMindMeldMutex->Acquire();
HandleMouseWheelChange(iDelta);
m_pMindMeldMutex->Release();
break;
}
case WM_LBUTTONDOWN:
{
POINT pt;
Pos oPos;
pt.x = (int16)LOWORD(lParam);
pt.y = (int16)HIWORD(lParam);
ClientToScreen(hwnd, &pt);
oPos.x = pt.x;
oPos.y = pt.y;
m_pMindMeldMutex->Acquire();
HandleMouseLButtonDown(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_LBUTTONUP:
{
POINT pt;
Pos oPos;
pt.x = (int16)LOWORD(lParam);
pt.y = (int16)HIWORD(lParam);
ClientToScreen(hwnd, &pt);
oPos.x = pt.x;
oPos.y = pt.y;
m_pMindMeldMutex->Acquire();
HandleMouseLButtonUp(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_MBUTTONDOWN:
{
POINT pt;
Pos oPos;
pt.x = (int16)LOWORD(lParam);
pt.y = (int16)HIWORD(lParam);
ClientToScreen(hwnd, &pt);
oPos.x = pt.x;
oPos.y = pt.y;
m_pMindMeldMutex->Acquire();
HandleMouseMButtonDown(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_MBUTTONUP:
{
POINT pt;
Pos oPos;
pt.x = (int16)LOWORD(lParam);
pt.y = (int16)HIWORD(lParam);
ClientToScreen(hwnd, &pt);
oPos.x = pt.x;
oPos.y = pt.y;
m_pMindMeldMutex->Acquire();
HandleMouseMButtonUp(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_LBUTTONDBLCLK:
{
POINT pt;
Pos oPos;
pt.x = (int16)LOWORD(lParam);
pt.y = (int16)HIWORD(lParam);
ClientToScreen(hwnd, &pt);
oPos.x = pt.x;
oPos.y = pt.y;
m_pMindMeldMutex->Acquire();
HandleMouseLButtonDoubleClick(oPos);
m_pMindMeldMutex->Release();
break;
}
case WM_CHAR:
{
Keystroke((unsigned char)wParam);
break;
}
case WM_KEYDOWN:
{
if (wParam == VK_F1)
{
wParam = 'h';
Keystroke((unsigned char)wParam);
}
else
result = DefWindowProc( hwnd, msg, wParam, lParam );
break;
}
case WM_NOTIFY:
Notify(wParam, (LPNMHDR)lParam);
break;
case WM_DROPFILES:
DropFiles((HDROP) wParam);
break;
case WM_SYSCOMMAND:
{
if (!MenuCommand(wParam))
{
result = DefWindowProc( hwnd, msg, wParam, lParam );
}
break;
}
case WM_QUERYNEWPALETTE:
{
HDC hDc;
hDc = GetDC(m_hWnd);
SelectPalette(hDc, m_hPal, false);
RealizePalette(hDc);
break;
}
case WM_WINDOWPOSCHANGING:
break;
case MM_MIXM_CONTROL_CHANGE:
{
VolumeChanged();
break;
}
default:
result = DefWindowProc( hwnd, msg, wParam, lParam );
break;
}
return result;
}
Win32Window::Win32Window(Theme *pTheme, string &oName)
:Window(pTheme, oName)
{
m_pCanvas = new Win32Canvas(this);
m_hWnd = NULL;
m_pMindMeldMutex = new Mutex();
m_bMouseInWindow = false;
m_hPal = NULL;
m_bMindMeldInProgress = false;
}
Win32Window::~Win32Window(void)
{
if (m_hPal)
DeleteObject(m_hPal);
delete m_pMindMeldMutex;
}
Error Win32Window::Run(Pos &oPos)
{
WNDCLASS wc;
MSG msg;
Rect oRect;
HRGN hRgn;
HDC hDc;
int iMaxX, iMaxY;
Canvas *pCanvas;
m_oWindowPos = oPos;
memset(&wc, 0x00, sizeof(WNDCLASS));
wc.style = CS_OWNDC|CS_DBLCLKS ;
wc.lpfnWndProc = MainWndProc;
wc.hInstance = g_hinst;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = LoadIcon( g_hinst, MAKEINTRESOURCE(IDI_EXE_ICON) );
wc.hbrBackground = NULL;
wc.lpszClassName = szAppName;
RegisterClass(&wc);
hDc = GetDC(NULL);
iMaxX = GetDeviceCaps(hDc, HORZRES);
iMaxY = GetDeviceCaps(hDc, VERTRES);
ReleaseDC(NULL, hDc);
pCanvas = GetCanvas();
if (pCanvas)
{
pCanvas->GetBackgroundRect(oRect);
if (m_oWindowPos.x > iMaxX || m_oWindowPos.x + oRect.Width() < 0)
m_oWindowPos.x = 0;
if (m_oWindowPos.y > iMaxY || m_oWindowPos.y + oRect.Height() < 0)
m_oWindowPos.y = 0;
if(m_oWindowPos.x < 0 || m_oWindowPos.y < 0)
{
m_oWindowPos.x = (iMaxX - oRect.Width())/2;
m_oWindowPos.y = (iMaxY - oRect.Height())/2;
}
}
if (m_bLiveInToolbar)
m_hWnd = CreateWindowEx(WS_EX_TOOLWINDOW,
szAppName,
szAppName,
WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX,
m_oWindowPos.x,
m_oWindowPos.y,
oRect.Width(),
oRect.Height(),
NULL,
NULL,
g_hinst,
this);
else
m_hWnd = CreateWindow(szAppName,
szAppName,
WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX,
m_oWindowPos.x,
m_oWindowPos.y,
oRect.Width(),
oRect.Height(),
NULL,
NULL,
g_hinst,
this);
if( m_hWnd )
{
hRgn = ((Win32Canvas *)m_pCanvas)->GetMaskRgn();
if (hRgn)
SetWindowRgn(m_hWnd, hRgn, false);
ShowWindow( m_hWnd, SW_NORMAL);
if (m_bStayOnTop)
SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
UpdateWindow( m_hWnd );
m_pTheme->PostWindowCreate();
SetForegroundWindow(m_hWnd);
AddToSystemMenu(m_hWnd);
CreateTooltips();
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
m_hWnd = NULL;
oPos = m_oWindowPos;
return kError_NoErr;
}
void Win32Window::ProcessWaitingMessages(void)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0))
return;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void Win32Window::Init(void)
{
Window::Init();
((Win32Canvas *)m_pCanvas)->SetParent(this);
}
Error Win32Window::VulcanMindMeld(Window *pOther)
{
HRGN hRgn;
Error eRet;
Rect oRect;
RECT sRect;
m_pMindMeldMutex->Acquire();
m_bMindMeldInProgress = true;
KillTimer(m_hWnd, 0);
oRect.x1 = oRect.x2 = oRect.y1 = oRect.y2 = 0;
GetWindowPosition(oRect);
sRect.left = oRect.x1;
sRect.right = oRect.x2;
sRect.top = oRect.y1;
sRect.right = oRect.y2;
ShowWindow(m_hWnd, SW_HIDE);
eRet = Window::VulcanMindMeld(pOther);
m_pMindMeldMutex->Release();
if (m_hPal)
((Win32Canvas *)m_pCanvas)->SetPalette(m_hPal);
if (IsError(eRet))
{
m_bMindMeldInProgress = false;
SetTimer(m_hWnd, 0, 250, NULL);
return eRet;
}
if (m_hWnd)
{
Rect oNewRect, oSize;
hRgn = ((Win32Canvas *)m_pCanvas)->GetMaskRgn();
if (hRgn)
SetWindowRgn(m_hWnd, hRgn, false);
m_pCanvas->GetBackgroundRect(oSize);
GetReloadWindowPos(oRect, oSize.Width(), oSize.Height(), oNewRect);
SetWindowPos(m_hWnd, NULL, oNewRect.x1, oNewRect.y1,
oNewRect.Width(), oNewRect.Height(),
SWP_NOZORDER);
CreateTooltips();
ShowWindow(m_hWnd, SW_SHOW);
UpdateWindow(m_hWnd);
SetForegroundWindow(m_hWnd);
SetFocus(m_hWnd);
}
SetTimer(m_hWnd, 0, 250, NULL);
m_bMindMeldInProgress = false;
return kError_NoErr;
}
void Win32Window::Paint(void)
{
PAINTSTRUCT ps;
HDC hDc;
Rect oRect;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -