mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-24 05:54:52 +01:00
219 lines
6.9 KiB
C++
219 lines
6.9 KiB
C++
|
#include "main.h"
|
||
|
#include "listskin.h"
|
||
|
#include "scrollwnd.h"
|
||
|
#include "../nu/CCVersion.h"
|
||
|
|
||
|
#ifndef LVS_EX_DOUBLEBUFFER //this will work XP only
|
||
|
#define LVS_EX_DOUBLEBUFFER 0x00010000
|
||
|
#endif
|
||
|
|
||
|
COLORREF Blender(COLORREF fg, COLORREF bg){
|
||
|
return RGB((GetRValue(fg)+GetRValue(bg))/2,(GetGValue(fg)+GetGValue(bg))/2,(GetBValue(fg)+GetBValue(bg))/2);
|
||
|
}
|
||
|
|
||
|
//listview's wndproc
|
||
|
static INT_PTR CALLBACK wndproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
ListSkin *ls=(ListSkin *)(LONG_PTR)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
|
||
|
INT_PTR r=handleListViewHeaderMsgs(hwndDlg,
|
||
|
ls->m_headerwnd,
|
||
|
ls->m_listwnd,
|
||
|
uMsg,
|
||
|
wParam,
|
||
|
lParam,
|
||
|
ls->sortShow,
|
||
|
ls->sortAscending,
|
||
|
ls->sortIndex);
|
||
|
if(r) return r;
|
||
|
if (uMsg == WM_ENABLE)
|
||
|
{
|
||
|
// custom handling of this allows us to handle disabled listview controls correctly
|
||
|
// so we don't have the part skinned / part OS colouring which happened before
|
||
|
InvalidateRect(hwndDlg,0,1);
|
||
|
ls->m_enabled = wParam;
|
||
|
return 1;
|
||
|
}
|
||
|
if (uMsg == WM_ERASEBKGND)
|
||
|
{
|
||
|
//fg> removes the header's region from the erasebackground's hdc clipping region
|
||
|
// so that they do not flicker when scrolling the list with the horizontal scrollbar
|
||
|
// in transparency mode
|
||
|
HDC dc = (HDC)wParam;
|
||
|
RECT r;
|
||
|
RECT hr;
|
||
|
GetClientRect(hwndDlg, &r);
|
||
|
GetClientRect(ListView_GetHeader(hwndDlg), &hr);
|
||
|
RECT lr;
|
||
|
SubtractRect(&lr, &r, &hr);
|
||
|
HRGN rgn = CreateRectRgnIndirect(&lr);
|
||
|
int rt = GetClipRgn(dc, rgn);
|
||
|
if (rt == 0) {
|
||
|
SelectClipRgn(dc, rgn);
|
||
|
} else if (rt > 0) {
|
||
|
HRGN trg = CreateRectRgnIndirect(&lr);
|
||
|
HRGN res = CreateRectRgn(0,0,0,0);
|
||
|
IntersectRgn(res, rgn, trg);
|
||
|
SelectClipRgn(dc, res);
|
||
|
DeleteRgn(res);
|
||
|
DeleteRgn(trg);
|
||
|
}
|
||
|
DeleteRgn(rgn);
|
||
|
}
|
||
|
if (uMsg == WM_KEYUP && wParam == VK_RETURN)
|
||
|
{
|
||
|
NMHDR nmh=
|
||
|
{
|
||
|
ls->m_listwnd,
|
||
|
GetDlgCtrlID(ls->m_listwnd),
|
||
|
NM_RETURN,
|
||
|
};
|
||
|
SendMessage(ls->m_hwnd,WM_NOTIFY,0,(LPARAM)&nmh);
|
||
|
return 0;
|
||
|
}
|
||
|
return CallWindowProc(ls->m_old_wndproc,hwndDlg,uMsg,wParam,lParam);
|
||
|
}
|
||
|
|
||
|
//dialog's wndproc
|
||
|
static INT_PTR CALLBACK mainwndproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
ListSkin *ls=(ListSkin *)(LONG_PTR)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
|
||
|
|
||
|
if(uMsg==WM_USER+0x411) return 0;//ls->m_changing_item_sel;
|
||
|
|
||
|
if(uMsg==WM_NOTIFY)
|
||
|
{
|
||
|
LPNMCUSTOMDRAW lpnmcd = (NMCUSTOMDRAW *)lParam;
|
||
|
//HWND listwnd=ls->m_listwnd;
|
||
|
HWND listwnd=lpnmcd->hdr.hwndFrom;
|
||
|
if(lpnmcd->hdr.code == NM_CUSTOMDRAW && lpnmcd->hdr.hwndFrom == listwnd)
|
||
|
{
|
||
|
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
|
||
|
NMCUSTOMDRAW &nmcd = lplvcd->nmcd;
|
||
|
//static bool bHighlighted = false;
|
||
|
|
||
|
switch(lplvcd->nmcd.dwDrawStage)
|
||
|
{
|
||
|
case CDDS_PREPAINT :
|
||
|
return CDRF_NOTIFYITEMDRAW;
|
||
|
|
||
|
// Modify item text and or background
|
||
|
case CDDS_ITEMPREPAINT:
|
||
|
{
|
||
|
int iRow = (int)nmcd.dwItemSpec;
|
||
|
|
||
|
bool bHighlighted = (ListView_GetItemState(listwnd, iRow, LVIS_SELECTED) != 0);
|
||
|
|
||
|
if (bHighlighted)
|
||
|
{
|
||
|
if(GetFocus()==listwnd && ls->m_enabled)
|
||
|
{
|
||
|
lplvcd->clrText = WADlg_getColor(WADLG_SELBAR_FGCOLOR);
|
||
|
lplvcd->clrTextBk = WADlg_getColor(WADLG_SELBAR_BGCOLOR);
|
||
|
} else {
|
||
|
lplvcd->clrText = (!ls->m_enabled?Blender(WADlg_getColor(WADLG_INACT_SELBAR_FGCOLOR),WADlg_getColor(WADLG_WNDBG)):WADlg_getColor(WADLG_INACT_SELBAR_FGCOLOR));
|
||
|
if(ls->m_enabled)
|
||
|
lplvcd->clrTextBk = WADlg_getColor(WADLG_INACT_SELBAR_BGCOLOR);
|
||
|
else
|
||
|
lplvcd->clrTextBk = WADlg_getColor(WADLG_ITEMBG);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(!ls->m_enabled)
|
||
|
{
|
||
|
lplvcd->clrText = Blender(WADlg_getColor(WADLG_INACT_SELBAR_FGCOLOR),WADlg_getColor(WADLG_WNDBG));
|
||
|
lplvcd->clrTextBk = WADlg_getColor(WADLG_ITEMBG);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Turn off listview highlight otherwise it uses the system colors!
|
||
|
//ls->m_changing_item_sel=1;
|
||
|
//ListView_SetItemState(listwnd, iRow, 0, LVIS_SELECTED);
|
||
|
lplvcd->nmcd.uItemState &= ~CDIS_SELECTED;
|
||
|
|
||
|
return CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT;
|
||
|
}
|
||
|
|
||
|
// Modify sub item text and/or background
|
||
|
case CDDS_ITEMPOSTPAINT:
|
||
|
{
|
||
|
//if(bHighlighted)
|
||
|
//{
|
||
|
// int iRow = (int)nmcd.dwItemSpec;
|
||
|
// Turn listview control's highlighting back on now that we have
|
||
|
// drawn the row in the colors we want.
|
||
|
//LockWindowUpdate(listwnd);
|
||
|
// lplvcd->nmcd.uItemState |= CDIS_SELECTED;
|
||
|
// ListView_SetItemState(listwnd, iRow, 0xff, LVIS_SELECTED);
|
||
|
//ls->m_changing_item_sel=0;
|
||
|
//LockWindowUpdate(NULL);
|
||
|
//CT> now validate the window so it doesn't flicker
|
||
|
//RECT r;
|
||
|
//ListView_GetItemRect(listwnd,iRow,&r,LVIR_BOUNDS);
|
||
|
//ValidateRect(listwnd,&r);
|
||
|
//}
|
||
|
}
|
||
|
default:
|
||
|
return CDRF_DODEFAULT;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return CallWindowProc(ls->m_old_mainwndproc,hwndDlg,uMsg,wParam,lParam);
|
||
|
}
|
||
|
|
||
|
//list header's wndproc
|
||
|
static INT_PTR CALLBACK header_wndproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
ListSkin *ls=(ListSkin *)(LONG_PTR)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
|
||
|
INT_PTR a=handleListViewHeaderPaintMsgs(ls->m_headerwnd,uMsg,wParam,lParam);
|
||
|
if(a) return a;
|
||
|
return CallWindowProc(ls->m_old_header_wndproc,hwndDlg,uMsg,wParam,lParam);
|
||
|
}
|
||
|
|
||
|
ListSkin::ListSkin(HWND hwnd)
|
||
|
{
|
||
|
m_hwnd=GetParent(hwnd);
|
||
|
m_listwnd=hwnd;
|
||
|
|
||
|
sortShow = FALSE;
|
||
|
sortAscending = TRUE;
|
||
|
sortIndex = 0;
|
||
|
|
||
|
if (comctlVersion >= PACKVERSION(6,0))
|
||
|
ListView_SetExtendedListViewStyleEx(m_listwnd, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);
|
||
|
m_headerwnd=ListView_GetHeader(hwnd);
|
||
|
SetWindowLongPtr(hwnd,GWLP_USERDATA, (LONGX86)(LONG_PTR)this);
|
||
|
m_old_wndproc=(WNDPROC)(LONG_PTR)SetWindowLongPtr(hwnd,GWLP_WNDPROC, (LONGX86)(LONG_PTR)wndproc);
|
||
|
SetWindowLongPtr(m_headerwnd,GWLP_USERDATA, (LONGX86)(LONG_PTR)this);
|
||
|
m_old_header_wndproc=(WNDPROC)(LONG_PTR)SetWindowLongPtr(m_headerwnd,GWLP_WNDPROC, (LONGX86)(LONG_PTR)header_wndproc);
|
||
|
m_scrollwnd=new ScrollWnd(hwnd, SCROLLBAR_LISTVIEW);
|
||
|
m_old_mainwndproc=NULL;
|
||
|
m_enabled = IsWindowEnabled(hwnd);
|
||
|
//m_changing_item_sel=0;
|
||
|
if(!GetWindowLongPtr(m_hwnd,GWLP_USERDATA))
|
||
|
{
|
||
|
SetWindowLongPtr(m_hwnd,GWLP_USERDATA, (LONGX86)(LONG_PTR)this);
|
||
|
m_old_mainwndproc=(WNDPROC)(LONG_PTR)SetWindowLongPtr(m_hwnd,GWLP_WNDPROC, (LONGX86)(LONG_PTR)mainwndproc);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ListSkin::~ListSkin()
|
||
|
{
|
||
|
delete m_scrollwnd;
|
||
|
m_scrollwnd=0;
|
||
|
SetWindowLongPtr(m_listwnd,GWLP_WNDPROC, (LONGX86)(LONG_PTR)m_old_wndproc);
|
||
|
SetWindowLongPtr(m_headerwnd,GWLP_WNDPROC, (LONGX86)(LONG_PTR)m_old_header_wndproc);
|
||
|
if(m_old_mainwndproc) SetWindowLongPtr(m_hwnd,GWLP_WNDPROC, (LONGX86)(LONG_PTR)m_old_mainwndproc);
|
||
|
}
|
||
|
|
||
|
void ListSkin::updateScrollWnd()
|
||
|
{
|
||
|
m_scrollwnd->update();
|
||
|
}
|
||
|
|
||
|
void ListSkin::disableHorzScroll()
|
||
|
{
|
||
|
m_scrollwnd->disableHorzScroll();
|
||
|
}
|