Esempio n. 1
0
void CToolBarTreeView::Draw()
{
	const int& cx = m_mdc.cx;
	const int& cy = m_mdc.cy;

	if (IsAppThemed())
	{
		HTHEME hTheme = OpenThemeData(m_hWnd, L"TREEVIEW");
		ASSERT(hTheme);
		RECT rc = {0, 0, cx, cy};
		DrawThemeBackground(hTheme, m_mdc, LBCP_BORDER_NOSCROLL, LBPSN_NORMAL, &rc, NULL);
		CloseThemeData(hTheme);

		// TODO: detect size of border (check for high DPI)
		DrawRect(m_mdc, 1, 1, cx - 2, SCY(24), GetSysColor(COLOR_BTNFACE), 96);
		DrawRect(m_mdc, 1, 1 + SCY(24) - 1, cx - 2, 1, GetSysColor(COLOR_BTNFACE), 192);
	}
	else
	{
		RECT rc = {0, 0, cx, cy};
		FillSolidRect(m_mdc, &rc, GetSysColor(COLOR_WINDOW));
		FillSolidRect(m_mdc, 1, 1, cx - 2, SCY(24), GetSysColor(COLOR_BTNFACE));
		DrawEdge(m_mdc, &rc, EDGE_SUNKEN, BF_RECT);
	}
}
Esempio n. 2
0
void threaded_process_v2_t::refresh_title_font()
{
	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));
	m_titlecolour = GetSysColor(COLOR_WINDOWTEXT);

	HTHEME thm_textstyle = IsThemeActive() && IsAppThemed() ? OpenThemeData(get_wnd(), L"TextStyle") : NULL;
	if (thm_textstyle)
	{
		if (SUCCEEDED(GetThemeFont(thm_textstyle, NULL, TEXT_MAININSTRUCTION, 0, TMT_FONT, &lf)))
		{
			m_titlefont = CreateFontIndirect(&lf);
			GetThemeColor(thm_textstyle, TEXT_MAININSTRUCTION, NULL, TMT_TEXTCOLOR, &m_titlecolour);
		}
		CloseThemeData(thm_textstyle);
	}

	if (!m_titlefont.is_valid())
	{
		uGetIconFont(&lf);
		lf.lfWeight = FW_BOLD;
		m_titlefont = CreateFontIndirect(&lf);
	}

	m_titlefont_height = uGetFontHeight(m_titlefont);
}
Esempio n. 3
0
CRect CPropPageFrameDefault::CalcCaptionArea()
{
	CRect	rect;
	GetClientRect(rect);
	if (IsAppThemed())
	{
		HTHEME hTheme = OpenThemeData(m_hWnd, L"Tab");
		if (hTheme)
		{
			CRect	rectContent;
			CDC		*pDc = GetDC();
			GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
			ReleaseDC(pDc);
			CloseThemeData(hTheme);

			if (GetShowCaption())
				rectContent.bottom = rect.top+GetCaptionHeight();
			else
				rectContent.bottom = rectContent.top;

			rect = rectContent;
		}
	}
	else
	{
		if (GetShowCaption())
			rect.bottom = rect.top+GetCaptionHeight();
		else
			rect.bottom = rect.top;
	}

	return rect;
}
Esempio n. 4
0
/////////////////////////////////////////////////////////////////////////////
// Added by Mathias Tunared 2002-07-27
//
BOOL CVisualStylesXP::UseVisualStyles()
{
	static BOOL bUse = -1;
	if( bUse != -1 )
		return bUse;

	HINSTANCE hinstDll;
	DLLVERSIONINFO dvi;
	ZeroMemory(&dvi, sizeof(dvi));

	hinstDll = LoadLibrary(TEXT("comctl32.dll"));
	if(hinstDll)
	{
		DLLGETVERSIONPROC pDllGetVersion;
		pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
		if(pDllGetVersion)
		{
			ZeroMemory(&dvi, sizeof(dvi));
			dvi.cbSize = sizeof(dvi);
			(*pDllGetVersion)(&dvi);
		}
		FreeLibrary(hinstDll);
	}

	if( dvi.dwMajorVersion == 6 && dvi.dwMinorVersion >= 0 )
	{
		bUse = TRUE;
		return IsAppThemed() && m_hThemeDll; // No need to test HTHEME, but...
	}
	else
	{
		bUse = FALSE;
		return FALSE;
	}
}
Esempio n. 5
0
// This function exists because sometimes IsAppThemed lies
BOOL CXpTheme::IsWindowThemed(HWND hWnd)
{_STT();
	if ( !IsAppThemed() ) return FALSE;

	// But sometimes IsAppThemed returns TRUE anyway so...
	CXpTheme xpthm( hWnd, "WINDOW" );
	return xpthm.IsTheme();
}
Esempio n. 6
0
 void init()
 {
     if ( !init_xp ) {
         init_xp = TRUE;
         use_xp = IsThemeActive() && IsAppThemed();
     }
     if ( use_xp )
         ref++;
 }
	void MainWindow::radioSetMuted(bool muted) {
		radioMuted = muted;
		if (currentStream)
			BASS_ChannelSetAttribute(currentStream, BASS_ATTRIB_VOL,
			radioGetVolume());

		if (OSUtil::IsVistaOrLater()) {
			SendMessage(volumePbar, PBM_SETSTATE, muted ?
				(isColorblindModeEnabled ? PBST_PAUSED : PBST_ERROR) :
				PBST_NORMAL, (LPARAM)0);
		} else if (IsAppThemed() == FALSE) {
			SendMessage(volumePbar, PBM_SETBARCOLOR,
				(WPARAM)0, (LPARAM)(muted ? RGB(255, 0, 0) : CLR_DEFAULT));
		}

		ShowWindow(volumePbar, SW_SHOW);
		if (muted)
			KillTimer(window, hideVolBarTimerId);
		else
			SetTimer(window, hideVolBarTimerId, 1000, nullptr);

		updateStatusLabel();

		if (OSUtil::IsWin7OrLater()) {
			ITaskbarList3 *taskbarList;
			if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, nullptr,
				CLSCTX_INPROC_SERVER, __uuidof(taskbarList),
				reinterpret_cast<void**>(&taskbarList)))) {

				HICON icon = LoadIcon(instance,
					MAKEINTRESOURCE(muted ? IDI_ICON_SOUND : IDI_ICON_MUTE));

				THUMBBUTTON thumbButtons[1];

				thumbButtons[0].dwMask = THB_ICON;
				thumbButtons[0].iId = thumbBarMuteBtnId;
				thumbButtons[0].hIcon = icon;

				taskbarList->ThumbBarUpdateButtons(window, 1, thumbButtons);

				DeleteObject((HGDIOBJ)icon);

				taskbarList->SetProgressValue(window, muted ? 100UL : 0UL,
					100UL);
				taskbarList->SetProgressState(window, muted ? TBPF_ERROR :
					TBPF_NOPROGRESS);

				taskbarList->Release();
			}
		}
	}
Esempio n. 8
0
HRESULT CMenuToolbarBase::ShowDW(BOOL fShow)
{
    ShowWindow(fShow ? SW_SHOW : SW_HIDE);

    // Ensure that the right image list is assigned to the toolbar
    UpdateImageLists();

    // For custom-drawing
    if (IsAppThemed())
        GetThemeSysBool(GetWindowTheme(m_hWnd), TMT_FLATMENUS);
    else
        SystemParametersInfo(SPI_GETFLATMENU, 0, &m_useFlatMenus, 0);

    return S_OK;
}
Esempio n. 9
0
void ColourButton::OnCustomDraw(NMHDR* nmhdr, LRESULT* result)
{
  NMCUSTOMDRAW* nmcd = (NMCUSTOMDRAW*)nmhdr;
  *result = CDRF_DODEFAULT;

  switch (nmcd->dwDrawStage)
  {
  case CDDS_PREPAINT:
    {
      CDC* dc = CDC::FromHandle(nmcd->hdc);
      CRect r(nmcd->rc);

      bool selected = ((nmcd->uItemState & CDIS_SELECTED) != 0);
      bool disabled = ((nmcd->uItemState & CDIS_DISABLED) != 0);
      bool focus = ((nmcd->uItemState & CDIS_FOCUS) != 0);
      if (SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS)
        focus = false;

      if (IsAppThemed())
      {
        HTHEME theme = OpenThemeData(this,L"Button");
        if (theme)
        {
          // Get the area to draw into
          GetThemeBackgroundContentRect(theme,dc,BP_PUSHBUTTON,PBS_NORMAL,r);
          CloseThemeData(theme);
        }
      }
      else
      {
        UINT state = DFCS_BUTTONPUSH|DFCS_ADJUSTRECT;
        if (disabled)
          state |= DFCS_INACTIVE;
        if (selected)
          state |= DFCS_PUSHED;
        dc->DrawFrameControl(r,DFC_BUTTON,state);

        if (selected)
          r.OffsetRect(1,1);
      }

      DrawControl(dc,r,disabled,focus);
      *result = CDRF_SKIPDEFAULT;
    }
    break;
  }
}
Esempio n. 10
0
/////////////////////////////////////////////////////////////////////////////
// Added by Mathias Tunared 2002-07-27
//
BOOL CVisualStylesXP::UseVisualStyles()
{
	static BOOL bUse = -1;
	if( bUse != -1 )
		return bUse;

	HINSTANCE hinstDll;
	DLLVERSIONINFO dvi;
	ZeroMemory(&dvi, sizeof(dvi));

	hinstDll = LoadLibrary(TEXT("comctl32.dll"));
	if(hinstDll)
	{
		DLLGETVERSIONPROC pDllGetVersion;
		pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
		if(pDllGetVersion)
		{
			ZeroMemory(&dvi, sizeof(dvi));
			dvi.cbSize = sizeof(dvi);
			(*pDllGetVersion)(&dvi);
		}
		FreeLibrary(hinstDll);
	}

	if( dvi.dwMajorVersion == 6 && dvi.dwMinorVersion == 0 )
	{
		//+++
		WCHAR szName [256];
		WCHAR szColor [256];

		if (!GetCurrentThemeName(szName, 255, szColor, 255, NULL, 0))
		{
			CString strWinXPThemeColor = szColor;
			if (strWinXPThemeColor.CompareNoCase (_T("normalcolor")) == 0 ||
				strWinXPThemeColor.CompareNoCase (_T("homestead")) == 0 ||
				strWinXPThemeColor.CompareNoCase (_T("metallic")) == 0)
			{
				bUse = TRUE;
				return IsAppThemed() && m_hThemeDll; // No need to test HTHEME, but...
			}
		}
	}

	bUse = FALSE;
	return FALSE;
}
Esempio n. 11
0
/////////////////////////////////////////////////////////////////////////////
// Added by Mathias Tunared 2002-07-27
//
BOOL CVisualStylesXP::UseVisualStyles()
{
	static BOOL bUse = -1;
	if( bUse != -1 )
		return bUse;

	HINSTANCE hinstDll;
	DLLVERSIONINFO dvi;
	ZeroMemory(&dvi, sizeof(dvi));

	hinstDll = LoadLibrary(_T("comctl32.dll"));
	if(hinstDll)
	{
		DLLGETVERSIONPROC pDllGetVersion;
		pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
		if(pDllGetVersion)
		{
			ZeroMemory(&dvi, sizeof(dvi));
			dvi.cbSize = sizeof(dvi);
			(*pDllGetVersion)(&dvi);
		}
		FreeLibrary(hinstDll);
	}

	if( dvi.dwMajorVersion == 6 && dvi.dwMinorVersion == 0 )
	{
		//+++
		WCHAR szName[MAX_PATH];
		WCHAR szColor[MAX_PATH];

		if (!GetCurrentThemeName(szName, MAX_PATH-1, szColor, MAX_PATH-1, NULL, 0))
		{
			TRACE(_T("theme=<%ls>  color=<%ls>\n"), szName, szColor);
			if ((_wcsicmp(szName, L"normalcolor") == 0) ||
				(_wcsicmp(szName, L"homestead") == 0) ||
				(_wcsicmp(szName, L"metallic") == 0))
			{
				bUse = TRUE;
				return IsAppThemed() && m_hThemeDll; // No need to test HTHEME, but...
			}
		}
	}

	bUse = FALSE;
	return FALSE;
}
Esempio n. 12
0
BOOL CPropPageFrameDefault::OnEraseBkgnd(CDC* pDC)
{
	if (IsAppThemed())
	{
		HTHEME hTheme = OpenThemeData(m_hWnd, L"TREEVIEW");
		if (hTheme)
		{
			CRect	rect;
			GetClientRect(rect);
			DrawThemeBackground(hTheme, pDC->m_hDC, 0, 0, rect, nullptr);
			CloseThemeData(hTheme);
		}
		return TRUE;
	}
	else
	{
		return CWnd::OnEraseBkgnd(pDC);
	}
}
Esempio n. 13
0
HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, IShellMenu* childShellMenu, BOOL keyInitiated)
{
    // Calculate the submenu position and exclude area
    RECT rc = { 0 };

    if (!GetItemRect(index, &rc))
        return E_FAIL;
    
    POINT a = { rc.left, rc.top };
    POINT b = { rc.right, rc.bottom };

    ClientToScreen(&a);
    ClientToScreen(&b);

    POINTL pt = { a.x, b.y };
    RECTL rcl = { a.x, a.y, b.x, b.y };

    if (m_initFlags & SMINIT_VERTICAL)
    {
        // FIXME: Hardcoding this here feels hacky.
        if (IsAppThemed())
        {
            pt.x = b.x - 1;
            pt.y = a.y - 1;
        }
        else
        {
            pt.x = b.x - 3;
            pt.y = a.y - 3;
        }
    }

    // Display the submenu
    m_isTrackingPopup = TRUE;

    m_menuBand->_ChangePopupItem(this, iItem);
    m_menuBand->_OnPopupSubMenu(childShellMenu, &pt, &rcl, keyInitiated);

    return S_OK;
}
Esempio n. 14
0
COLORREF get_default_theme_colour(HTHEME thm, colours::t_colours index)
{
	if (!thm || !IsAppThemed() || !IsThemeActive())
		return get_default_colour(index);
	switch (index)
	{
	case colours::COLOUR_TEXT:
		return GetThemeSysColor(thm, COLOR_WINDOWTEXT);
	case colours::COLOUR_SELECTED_TEXT:
		return GetThemeSysColor(thm, COLOR_HIGHLIGHTTEXT);
	case colours::COLOUR_BACK:
		return GetThemeSysColor(thm, COLOR_WINDOW);
	case colours::COLOUR_SELECTED_BACK:
		return GetThemeSysColor(thm, COLOR_HIGHLIGHT);
	case colours::COLOUR_FRAME:
		return GetThemeSysColor(thm, COLOR_WINDOWFRAME);
	case colours::COLOUR_SELECTED_BACK_NO_FOCUS:
		return GetThemeSysColor(thm, COLOR_BTNFACE);
	case colours::COLOUR_SELECTED_TEXT_NO_FOCUS:
		return GetThemeSysColor(thm, COLOR_BTNTEXT);
	default:
		return 0x0000FF;
	}
}
Esempio n. 15
0
void CReBar::Draw()
{
	int cx, cy;
	VERIFY(m_mdc.GetDimensions(&cx, &cy));

	// Draw background

	if (m_bBackgrWinDefault)
	{
		if (IsAppThemed())
		{
			HTHEME hTheme = OpenThemeData(m_hWnd, L"REBAR");
			RECT rc = {0, 0, cx, cy};
			DrawThemeBackground(hTheme, m_mdc, RP_BACKGROUND, 0, &rc, NULL);
			CloseThemeData(hTheme);
		}
		else
		{
			DrawRect(m_mdc, 0, 0, cx, cy, GetSysColor(COLOR_3DFACE));
			DrawRect(m_mdc, 0, cy - SCY(1), cx, SCY(1), GetSysColor(COLOR_3DSHADOW));
		}
	}
	else
	{
		DrawRectGradientV(m_mdc, 0, 0, cx, cy - SCY(1), m_clrBackgrT, m_clrBackgrB);
		DrawRect(m_mdc, 0, cy - SCY(1), cx, SCY(1), m_clrBackgrLine);
	}

	// Draw rounded background and border around search box

	m_sprSearchBox.Draw(m_mdc, cx - SCX(320), SCY(4), SCX(199), SCY(23), true);
	//m_sprSearchBox.Draw(m_mdc, cx - SCX(259), SCY(4), SCX(199), SCY(23), true);

	Invalidate(m_hWnd);
	PostMessage(m_hWnd, WM_PAINT);
}
Esempio n. 16
0
void CIconStatic::SetIcon(LPCTSTR pszIconID)
{
	m_strIconID = pszIconID;

	// If this function is called for the first time and we did not yet call 'SetWindowText', we take
	// the window label which is already specified for the window (the label which comes from the resource)
	CString strText;
	CStatic::GetWindowText(strText);
	CStatic::SetWindowText(_T(""));
	if (!strText.IsEmpty() && m_strText.IsEmpty())
		m_strText = strText;

	CRect rRect;
	GetClientRect(rRect);

	CDC *pDC = GetDC();
	CDC MemDC;
	CBitmap *pOldBMP;
	
	VERIFY( MemDC.CreateCompatibleDC(pDC) );

	CFont *pOldFont = MemDC.SelectObject(GetFont());

	CRect rCaption(0,0,0,0);
	MemDC.DrawText(m_strText, rCaption, DT_CALCRECT);
	ASSERT( rCaption.Width() >= 0 );
	ASSERT( rCaption.Height() >= 0 );
	if (rCaption.Height() < 16)
		rCaption.bottom = rCaption.top + 16;
	rCaption.right += 25;
	if (rRect.Width() >= 16 && rCaption.Width() > rRect.Width() - 16)
		rCaption.right = rCaption.left + rRect.Width() - 16;

	if (m_MemBMP.m_hObject)
		VERIFY( m_MemBMP.DeleteObject() );
	VERIFY( m_MemBMP.CreateCompatibleBitmap(pDC, rCaption.Width(), rCaption.Height()) );
	pOldBMP = MemDC.SelectObject(&m_MemBMP);

	// Get the background color from the parent window. This way the controls which are
	// embedded in a dialog window can get painted with the same background color as
	// the dialog window.
	HBRUSH hbr = (HBRUSH)GetParent()->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)MemDC.m_hDC, (LPARAM)m_hWnd);
	FillRect(MemDC, &rCaption, hbr);

	if (!m_strIconID.IsEmpty())
		VERIFY( DrawState( MemDC.m_hDC, NULL, NULL, (LPARAM)(HICON)CTempIconLoader(m_strIconID, 16, 16), NULL, 3, 0, 16, 16, DST_ICON | DSS_NORMAL) );

	// clear all alpha channel data
	BITMAP bmMem;
	if (m_MemBMP.GetObject(sizeof bmMem, &bmMem) >= sizeof bmMem && bmMem.bmBitsPixel == 32)
	{
		DWORD dwSize = m_MemBMP.GetBitmapBits(0, NULL);
		if (dwSize)
		{
			LPBYTE pPixels = (LPBYTE)malloc(dwSize);
			if (pPixels)
			{
				if (m_MemBMP.GetBitmapBits(dwSize, pPixels) == dwSize)
				{
					LPBYTE pLine = pPixels;
					int iLines = bmMem.bmHeight;
					while (iLines-- > 0)
					{
						LPDWORD pdwPixel = (LPDWORD)pLine;
						for (int x = 0; x < bmMem.bmWidth; x++)
							*pdwPixel++ &= 0x00FFFFFF;
						pLine += bmMem.bmWidthBytes;
					}
					m_MemBMP.SetBitmapBits(dwSize, pPixels);
				}
				free(pPixels);
			}
		}
	}

	rCaption.left += 22;
	
	if(IsThemeActive() && IsAppThemed())
    {
		HTHEME hTheme = OpenThemeData(NULL, L"BUTTON"); 
		DrawThemeText(hTheme, MemDC.m_hDC, BP_GROUPBOX, GBS_NORMAL, m_strText, m_strText.GetLength(), 
			DT_WORDBREAK | DT_CENTER | DT_WORD_ELLIPSIS, NULL, &rCaption); 
		CloseThemeData(hTheme);
	}
	else
	{
		MemDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		MemDC.DrawText(m_strText, rCaption, DT_SINGLELINE | DT_LEFT | DT_END_ELLIPSIS);
	}

	ReleaseDC(pDC);

	MemDC.SelectObject(pOldBMP);
	MemDC.SelectObject(pOldFont);
	
	if (m_wndPicture.m_hWnd == NULL)
		m_wndPicture.Create(NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, CRect(0,0,0,0), this);
	m_wndPicture.SetWindowPos(NULL, rRect.left+8, rRect.top, rCaption.Width()+22, rCaption.Height(), SWP_SHOWWINDOW);
	m_wndPicture.SetBitmap(m_MemBMP);

	CRect r;
	GetWindowRect(r);
	r.bottom = r.top + 20;
	GetParent()->ScreenToClient(&r);
	GetParent()->RedrawWindow(r);
}
Esempio n. 17
0
HWND CreateToolbarFromResource(HWND hWndParent)
{
	INITCOMMONCONTROLSEX icex;
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	icex.dwICC  = ICC_WIN95_CLASSES|ICC_COOL_CLASSES|ICC_BAR_CLASSES|ICC_USEREX_CLASSES;
	InitCommonControlsEx(&icex);

	// Declare and initialize local constants.
	int ImageListID;
	int resourceId = IDB_FILE_VIEW_24;
	int numButtons = 31;
	const int bmHeight = 16;
	const int bmWidth = 16;
	
	const DWORD buttonStylesasdfasdf = BTNS_AUTOSIZE;

	// Create the toolbar.
	HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 
									  WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
									  hWndParent, NULL, hInst, NULL);
	if (hWndToolbar == NULL)
		return NULL;


	resourceId = IDB_TOOLBAR256;

	HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(resourceId));

	// Create the image list.
	int cx = bmWidth;
	int cy = bmHeight;
	UINT nFlags = ILC_COLOR24 | ILC_MASK;
	int nInitial = 0;
	int nGrow = 0;
	hImageList = ImageList_Create(bmWidth, bmHeight, nFlags, 0, nGrow);
	ImageListID = ImageList_AddMasked(hImageList, hBitmap, RGB(0, 255, 0));


	// Set the image list.
	LRESULT r1 = SendMessage(hWndToolbar, TB_SETIMAGELIST, (WPARAM)ImageListID, (LPARAM)hImageList); 

	// Load the button images.
	//LRESULT r2 = SendMessage(hWndToolbar, TB_LOADIMAGES, 
				//(WPARAM)IDB_STD_SMALL_COLOR, 
				//(LPARAM)HINST_COMMCTRL);
	// Load the text from a resource.
	
	// In the string table, the text for all buttons is a single entry that 
	// appears as "~New~Open~Save~~". The separator character is arbitrary, 
	// but it must appear as the first character of the string. The message 
	// returns the index of the first item, and the items are numbered 
	// consecutively.
	
	int iNew = SendMessage(hWndToolbar, TB_ADDSTRING, (WPARAM)hInst, (LPARAM)0); 
 
	// Initialize button info.
	// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.
	
	::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
	::SendMessage(hWndToolbar, TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_HIDECLIPPEDBUTTONS);

	TBBUTTON *pButtons = new TBBUTTON[numButtons];

	for (int i = 0 ; i < numButtons ; i++)
	{
		pButtons[i].iBitmap = i;
		pButtons[i].idCommand = 20 + i;
		pButtons[i].fsState = (BYTE)TBSTATE_ENABLED;
		pButtons[i].fsStyle = (BYTE)TBSTYLE_FLAT;
		pButtons[i].dwData = 0;
		pButtons[i].iString = NULL;
	}

	//typedef struct _TBBUTTON {
	//    int iBitmap;
	//    int idCommand;
	//    BYTE fsState;
	//    BYTE fsStyle;
	//#ifdef _WIN64
	//    BYTE bReserved[6];          // padding for alignment
	//#elif defined(_WIN32)
	//    BYTE bReserved[2];          // padding for alignment
	//#endif
	//    DWORD_PTR dwData;
	//    INT_PTR iString;
	//} TBBUTTON, NEAR* PTBBUTTON, *LPTBBUTTON;

	BOOL b = IsAppThemed();

	// Add buttons.
	LRESULT a1 = SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
	LRESULT a2 = SendMessage(hWndToolbar, TB_ADDBUTTONS,       (WPARAM)numButtons,       (LPARAM)pButtons);

	// Resize the toolbar, and then show it.
	LRESULT a3 = SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0); 
	LRESULT a4 = ShowWindow(hWndToolbar,  TRUE);
	return hWndToolbar;
}
Esempio n. 18
0
LRESULT playlist_view::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
	switch (msg)
	{
	case WM_NCCREATE:
		wnd_playlist = wnd;
		initialised = true;
		list_playlist.add_item(this);
		g_playlist_message_window.add_ref();
		break;
	case WM_CREATE:
	{
		pfc::com_ptr_t<IDropTarget_playlist> IDT_playlist = new IDropTarget_playlist(this);
		RegisterDragDrop(wnd, IDT_playlist.get_ptr());
		if (true)
		{
			m_theme = IsThemeActive() && IsAppThemed() ? OpenThemeData(wnd, L"ListView") : NULL;
			SetWindowTheme(wnd, L"Explorer", NULL);
		}
		m_always_show_focus = config_object::g_get_data_bool_simple(standard_config_objects::bool_playback_follows_cursor, false);
		on_playlist_font_change();
		create_header(true);
		drawing_enabled = true;
		m_cache.initialise();
	}
	return 0;
	case WM_DESTROY:
		m_edit_save = false;
		exit_inline_edit();
		m_cache.deinitialise();
		RevokeDragDrop(wnd);
		SendMessage(wnd, WM_SETFONT, 0, 0);
		SendMessage(wnd_header, WM_SETFONT, 0, 0);
		{
			if (m_theme) CloseThemeData(m_theme);
			m_theme = NULL;
		}
		m_selection_holder.release();
		break;
	case WM_NCDESTROY:
		g_playlist_message_window.release();
		wnd_playlist = 0;
		initialised = false;
		list_playlist.remove_item(this);
		m_shown = false;
		//		if (!list_playlist.get_count())
		//		{
		//			g_playlist_entries.rebuild_all();
		//		}
		break;
	case WM_THEMECHANGED:
	{
		if (m_theme) CloseThemeData(m_theme);
		m_theme = IsThemeActive() && IsAppThemed() ? OpenThemeData(wnd, L"ListView") : 0;
	}
	break;
	case WM_SHOWWINDOW:
		if (wp == TRUE && lp == 0 && !m_shown)
		{
			static_api_ptr_t<playlist_manager> playlist_api;
			ensure_visible(playlist_api->activeplaylist_get_focus_item());
			m_shown = true;
		}
		break;
	case WM_WINDOWPOSCHANGED:
	{
		LPWINDOWPOS lpwp = (LPWINDOWPOS)lp;
		if (!(lpwp->flags & SWP_NOSIZE))
		{
			on_size(lpwp->cx, lpwp->cy);
		}
	}
	break;
	case WM_ERASEBKGND:
		return TRUE;
		break;
	case WM_PAINT:
	{
		PAINTSTRUCT ps;
		HDC dc_paint = BeginPaint(wnd, &ps);

		RECT rc_update, rc_playlist;
		get_playlist_rect(&rc_playlist);


		rc_update = ps.rcPaint;
		if (rc_update.top<rc_playlist.top) rc_update.top = rc_playlist.top;
		if (rc_update.bottom >= rc_update.top)
		{

			int item_height = get_item_height();

			int start_item = (rc_update.top - rc_playlist.top) / item_height;
			int end_item = (rc_update.bottom - rc_playlist.top) / item_height;

			if (((end_item - start_item) + 1)*item_height < rc_update.bottom - rc_update.top) end_item++;
			{
				draw_items(dc_paint, start_item, 1 + (end_item - start_item));
			}
		}
		EndPaint(wnd, &ps);
	}
	return 0;
	case WM_SETREDRAW:
		drawing_enabled = (wp != 0);
		return 0;
	case WM_MOUSEACTIVATE:
		if (GetFocus() != wnd)
			m_no_next_edit = true;
		return MA_ACTIVATE;
	case WM_UPDATEUISTATE:
		RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE);
		break;
	case WM_KILLFOCUS:
		RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
		m_selection_holder.release();
		break;
	case WM_SETFOCUS:
		//if (msg == WM_SETFOCUS && (HWND)wp != wnd)
		//m_no_next_edit = true;
		RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
		m_selection_holder = static_api_ptr_t<ui_selection_manager>()->acquire();
		m_selection_holder->set_playlist_selection_tracking();
		break;
	case WM_GETDLGCODE:
		return DLGC_WANTALLKEYS;
	case WM_KEYDOWN:
	{
		static_api_ptr_t<playlist_manager> playlist_api;
		uie::window_ptr p_this = this;
		//DWORD vk_slash = VkKeyScan('/');
		if (wp == VK_CONTROL) g_drag_lmb = true;
		if (m_prevent_wm_char_processing = process_keydown(msg, lp, wp, true)) return 0;
		else
		{
			SendMessage(wnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), NULL);
			if (wp == VK_HOME || wp == VK_DOWN || wp == VK_END || wp == VK_PRIOR || wp == VK_NEXT || wp == VK_UP)
			{
				int focus = playlist_api->activeplaylist_get_focus_item();
				int total = playlist_api->activeplaylist_get_item_count();

				if ((wp == VK_HOME || wp == VK_PRIOR || wp == VK_UP))
				{
					//	if (focus == 0) return 0;
				}
				if ((wp == VK_END || wp == VK_NEXT || wp == VK_DOWN))
				{
					//	if (focus == total - 1) return 0;
				}

				SCROLLINFO si;
				memset(&si, 0, sizeof(si));
				si.cbSize = sizeof(si);

				si.fMask = SIF_PAGE | SIF_POS;
				GetScrollInfo(wnd_playlist, SB_VERT, &si);

				int offset = 0;
				int scroll = scroll_item_offset;

				if (wp == VK_HOME)
					scroll = 0;
				else if (wp == VK_PRIOR && focus == scroll_item_offset)
					scroll -= si.nPage;
				else if (wp == VK_UP)
				{
					if (focus <= scroll_item_offset)
						scroll = focus - 1;
					else if (focus > si.nPos + si.nPage - 1)
						scroll = focus - 1 - si.nPage + 1;
				}
				else if (wp == VK_DOWN)
				{
					if (focus < scroll_item_offset)
						scroll = focus + 1;
					else if (focus >= si.nPos + si.nPage - 1)
						scroll = focus + 1 - si.nPage + 1;
				}
				else if (wp == VK_END)
					scroll = total - 1;
				else if (wp == VK_NEXT && focus == si.nPos + si.nPage - 1)
					scroll += si.nPage;

				drawing_enabled = false;

				si.nPos = scroll;
				si.fMask = SIF_POS;
				scroll_item_offset = SetScrollInfo(wnd_playlist, SB_VERT, &si, true);

				if (wp == VK_HOME)
					offset = 0 - focus;
				else if (wp == VK_PRIOR)
					offset = scroll_item_offset - focus;
				else if (wp == VK_END)
					offset = total - focus - 1;
				else if (wp == VK_NEXT)
					offset = get_last_viewable_item() - focus;
				else if (wp == VK_DOWN)
					offset = 1;
				else if (wp == VK_UP)
					offset = -1;


				//if (offset) 
				process_keydown(offset, ((HIWORD(lp) & KF_ALTDOWN) != 0), drawing_enabled, (HIWORD(lp) & KF_REPEAT) != 0);
				drawing_enabled = true;

				RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);

				return 0;
			}
			else if (wp == VK_SPACE)
			{
				int focus = playlist_api->activeplaylist_get_focus_item();
				set_sel_single(focus, true, false, false);
				return 0;
			}
			else if (wp == VK_RETURN)
			{
				bool ctrl_down = 0 != (GetKeyState(VK_CONTROL) & KF_UP);
				int focus = playlist_api->activeplaylist_get_focus_item();
				unsigned active = playlist_api->get_active_playlist();
				if (ctrl_down)
				{
					if (active != -1 && focus != -1)
						playlist_api->queue_add_item_playlist(active, focus);
				}
				else
				{
					//					playlist_api->set_playing_playlist(active);
					unsigned focus = playlist_api->activeplaylist_get_focus_item();
					//unsigned active = playlist_api->get_active_playlist();
					//playlist_api->playlist_set_playback_cursor(active, focus);
					playlist_api->activeplaylist_execute_default_action(focus);
					//static_api_ptr_t<play_control>()->play_start(play_control::track_command_settrack);
				}
				return 0;
			}
			else if (wp == VK_SHIFT)
			{
				if (!(HIWORD(lp) & KF_REPEAT)) g_shift_item_start = playlist_api->activeplaylist_get_focus_item();
			}
			else if (wp == VK_F2)
			{
				unsigned count = g_get_cache().active_column_get_active_count();
				if (count)
				{
					unsigned focus = playlist_api->activeplaylist_get_focus_item();
					if (focus != pfc_infinite)
					{
						t_size i, pcount = playlist_api->activeplaylist_get_item_count();
						bit_array_bittable sel(pcount);
						playlist_api->activeplaylist_get_selection_mask(sel);

						pfc::list_t<t_size> indices;
						indices.prealloc(32);
						for (i = 0; i<pcount; i++)
							if (sel[i]) indices.add_item(i);

						/*t_size start = focus, end = focus;

						if (sel[start] && pcount)
						{
						while (start>0 && sel[start-1]) start--;
						while (end<pcount-1 && sel[end+1]) end++;
						}*/

						unsigned count = g_get_cache().active_column_get_active_count();
						unsigned column;
						for (column = 0; column<count; column++)
						{
							if (!g_get_columns()[g_get_cache().active_column_active_to_actual(column)]->edit_field.is_empty())
							{
								//create_inline_edit_v2(start, end-start+1, column);
								create_inline_edit_v2(indices, column);
								break;
							}
						}
					}
				}
			}
			else if (wp == VK_DELETE)
			{
				playlist_api->activeplaylist_undo_backup();
				playlist_api->activeplaylist_remove_selection();
			}
			else if (wp == VK_F3)
			{
				standard_commands::main_playlist_search();
			}
			/*else if (vk_slash != -1 && wp == LOWORD(vk_slash))
			{
			HWND wnd_search = m_searcher.create(wnd);
			on_size();
			ShowWindow(wnd_search, SW_SHOWNORMAL);
			;
			}*/
		}
	}
	break;
	case WM_CHAR:
		if (!m_prevent_wm_char_processing)
		{
			//if (!(HIWORD(lp) & KF_REPEAT))
			{
				if ((GetKeyState(VK_CONTROL) & KF_UP))
				{
					static_api_ptr_t<playlist_manager> playlist_api;
					if (wp == 1) //Ctrl-A
					{
						playlist_api->activeplaylist_set_selection(bit_array_true(), bit_array_true());
						return 0;
					}
					else if (wp == 26) //Ctrl-Z
					{
						playlist_api->activeplaylist_undo_restore();
						return 0;
					}
					else if (wp == 25) //Ctrl-Y
					{
						playlist_api->activeplaylist_redo_restore();
						return 0;
					}
					else if (wp == 24) //Ctrl-X
					{
						playlist_utils::cut();
						return 0;
					}
					else if (wp == 3) //Ctrl-C
					{
						playlist_utils::copy();
						return 0;
					}
					else if (wp == 6) //Ctrl-F
					{
						standard_commands::main_playlist_search();
						return 0;
					}
					else if (wp == 22) //Ctrl-V
					{
						playlist_utils::paste(wnd);
						return 0;
					}
				}
			}
		}
		break;
	case WM_KEYUP:
		if (process_keydown(msg, lp, wp, true)) return 0;
		break;
	case WM_SYSKEYUP:
		if (process_keydown(msg, lp, wp, true)) return 0;
		break;
	case WM_SYSKEYDOWN:
	{
		uie::window_ptr p_this = this;
		if (m_prevent_wm_char_processing = process_keydown(msg, lp, wp, true)) return 0;
	}
	break;
	case WM_LBUTTONDOWN:
	{
		if (0 && g_tooltip)
		{
			MSG message;
			memset(&message, 0, sizeof(MSG));
			message.hwnd = wnd;
			message.message = msg;
			message.wParam = wp;
			message.lParam = lp;

			uSendMessage(g_tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message);
		}
		bool b_was_focused = GetFocus() == wnd;
		if (!b_was_focused)
			m_no_next_edit = true;
		//#ifdef INLINE_EDIT
		exit_inline_edit();
		//			g_no_next_edit = false;
		//#endif
		dragged = false;
		SetFocus(wnd);
		SetCapture(wnd);

		static_api_ptr_t<playlist_manager> playlist_api;
		g_drag_lmb = true;
		int focus = playlist_api->activeplaylist_get_focus_item();

		drag_start_lmb.x = GET_X_LPARAM(lp);
		drag_start_lmb.y = GET_Y_LPARAM(lp);

		int item_height = get_item_height();
		int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
		//		int idx = ((GET_Y_LPARAM(lp) -get_header_height()) / item_height) + scroll_item_offset;
		//		if( idx >= 0 && idx <playlist_api->activeplaylist_get_item_count()  && GET_X_LPARAM(lp) < g_playlist_entries.get_total_width_actual())

		if (idx >= 0)
		{

			//		playlist_oper * playlist_api = playlist_api;
			//				playlist_api->set_playback_cursor(idx);
			//#ifdef INLINE_EDIT
			m_prev_sel = (playlist_api->activeplaylist_is_item_selected(idx) && !m_wnd_edit && (playlist_api->activeplaylist_get_selection_count(2) == 1));
			//#endif

			if (!is_visible(idx)) SendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);

			if (wp & MK_CONTROL && wp & MK_SHIFT)
			{
				playlist_api->activeplaylist_move_selection(idx - focus);
				dragged = true;
				drag_type = 0;
			}
			else if (wp & MK_SHIFT)
			{
				drag_type = 2; dragitem = idx, dragstartitem = idx;

				int n = (cfg_alternative_sel ? focus : g_shift_item_start), t = idx;
				bool focus_sel = playlist_api->activeplaylist_is_item_selected(focus);


				set_sel_range(n, t, (cfg_alternative_sel != 0), (cfg_alternative_sel ? !focus_sel : false));
				playlist_api->activeplaylist_set_focus_item(idx);

				dragged = true;

			}
			else if (wp & MK_CONTROL)
			{
				/*			drag_type = 2; dragitem = idx,dragstartitem=idx;

				set_sel_single(idx, false, true, false);

				dragged = true;*/

			}
			else if (playlist_api->activeplaylist_is_item_selected(idx))
			{
				drag_type = 1; dragitem = idx, dragstartitem = idx;
				playlist_api->activeplaylist_undo_backup();
				playlist_api->activeplaylist_set_focus_item(idx);
				dragged = false;
			}
			else
			{
				drag_type = 2; dragitem = idx, dragstartitem = idx;//item irrelevant actually;

				set_sel_single(idx, false, true, true);

				/*			bit_array_bittable mask(playlist_api->activeplaylist_get_item_count());
				//		playlist_api->activeplaylist_is_item_selected_mask(mask);
				int n, t = playlist_api->activeplaylist_get_item_count();
				for (n = 0;n <t;n++) { if (n==idx) mask.set(n, true); else mask.set(n, false); }

				console::info("crap");
				playlist_api->set_sel_mask(mask);
				playlist_api->activeplaylist_set_focus_item(idx);*/

				dragged = false;
			}
		}
		else
		{
			//			console::info("wow");
			//				bit_array_bittable mask(playlist_api->activeplaylist_get_item_count());
			playlist_api->activeplaylist_set_selection(bit_array_true(), bit_array_false());
			dragged = true;
			drag_type = 0;
		}
	}

	break;
	case WM_RBUTTONUP:
		m_no_next_edit = false;
		break;
	case WM_MBUTTONUP:
	{
		m_no_next_edit = false;
		unsigned idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
		playlist_mclick_actions::run(cfg_playlist_middle_action, idx != -1, idx);
	}
	break;

	case WM_LBUTTONUP:
	{
		if (0 && g_tooltip)
		{
			MSG message;
			memset(&message, 0, sizeof(MSG));
			message.hwnd = wnd;
			message.message = msg;
			message.wParam = wp;
			message.lParam = lp;

			uSendMessage(g_tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message);
		}
		ReleaseCapture();
		g_drag_lmb = false;
		int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), true);   //((GET_Y_LPARAM(lp) -get_header_height()) / get_item_height()) + scroll_item_offset;
		static_api_ptr_t<playlist_manager> playlist_api;
		if (!dragged)
		{
			if (wp & MK_CONTROL)
			{
				//			int idx_down = hittest_item(drag_start_lmb.x, drag_start_lmb.y);
				if (idx >= 0) set_sel_single(idx, true, true, false);
			}
			else
			{

				//				int item_height = get_item_height();

				//			int idx = ((GET_Y_LPARAM(lp) - get_header_height()) / item_height) + scroll_item_offset;
				if (idx >= 0 /*&& idx < playlist_api->activeplaylist_get_item_count() && (GET_X_LPARAM(lp) < g_playlist_entries.get_total_width_actual())*/)
				{



					if (!m_no_next_edit && cfg_inline_edit && playlist_api->activeplaylist_is_item_selected(idx) && m_prev_sel /*&& !dragged*/)
					{
						//if (m_no_next_edit && GetCapture() == wnd) ReleaseCapture();

						{
							exit_inline_edit();
							if (main_window::config_get_inline_metafield_edit_mode() != main_window::mode_disabled)
							{
								m_edit_index = idx;
								long width;
								m_edit_column = hittest_column(GET_X_LPARAM(lp), width);
								if (m_edit_column >= 0 && !g_get_columns()[g_get_cache().active_column_active_to_actual(m_edit_column)]->edit_field.is_empty())
								{
									m_edit_timer = (SetTimer(wnd, EDIT_TIMER_ID, GetDoubleClickTime(), 0) != 0);
								}
							}
						}

					}

					int focus = playlist_api->activeplaylist_get_focus_item();
					set_sel_single(focus, false, false, true);
				}


			}
		}
		dragged = true;
		drag_type = 0;
		dragstartitem = 0;
		dragitem = 0;
		//#ifdef INLINE_EDIT
		m_no_next_edit = false;
		//#endif
	}
	break;
	case WM_MOUSEMOVE:
	{
		if (0 && g_tooltip)
		{
			MSG message;
			memset(&message, 0, sizeof(MSG));
			message.hwnd = wnd;
			message.message = msg;
			message.wParam = wp;
			message.lParam = lp;

			uSendMessage(g_tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message);
		}
		const unsigned cx_drag = (unsigned)abs(GetSystemMetrics(SM_CXDRAG));
		const unsigned cy_drag = (unsigned)abs(GetSystemMetrics(SM_CYDRAG));
		if (!g_dragging && ((g_dragging1 && wp & MK_RBUTTON && (abs(drag_start.x - GET_X_LPARAM(lp)) > cx_drag || abs(drag_start.y - GET_Y_LPARAM(lp)) > cy_drag)) || (g_drag_lmb && (wp & MK_LBUTTON) && (wp & MK_CONTROL) && (abs(drag_start_lmb.x - GET_X_LPARAM(lp)) > 3 || abs(drag_start_lmb.y - GET_Y_LPARAM(lp)) > 3))))
		{
			static_api_ptr_t<playlist_manager> playlist_api;
			metadb_handle_list data;
			playlist_api->activeplaylist_get_selected_items(data);
			if (data.get_count() > 0)
			{
				static_api_ptr_t<playlist_incoming_item_filter> incoming_api;
				IDataObject * pDataObject = incoming_api->create_dataobject(data);
				if (pDataObject)
				{
					//RegisterClipboardFormat(_T("foo_ui_columns");

					if (g_tooltip) { DestroyWindow(g_tooltip); g_tooltip = 0; last_idx = -1; last_column = -1; }
					DWORD blah;
					{
						pfc::com_ptr_t<IDropSource_playlist> p_IDropSource_playlist = new IDropSource_playlist(this);
						DoDragDrop(pDataObject, p_IDropSource_playlist.get_ptr(), DROPEFFECT_COPY, &blah);
					}
					pDataObject->Release();
				}
			}
			data.remove_all();
			g_dragging = false;
			g_dragging1 = false;
			g_drag_lmb = false;
			if (wp & MK_LBUTTON)
			{
				dragged = true;
				drag_type = 0;
				dragstartitem = 0;
				dragitem = 0;
			}
		}




		if (cfg_tooltip && (GET_Y_LPARAM(lp) > get_header_height()))
		{
			int item_height = get_item_height();
			int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
			long cx;
			int column = hittest_column(GET_X_LPARAM(lp), cx);
			//			unsigned act_col = g_cache.active_column_active_to_actual(column);

			if (column >= 0 && idx >= 0)
			{
				if (last_idx != (idx) || last_column != column)
				{
					if (!cfg_tooltips_clipped || is_item_clipped(idx, column))
					{
						pfc::string8 src;
						g_cache.active_get_display_name(idx, column, src);
						pfc::string8 temp;
						titleformat_compiler::remove_color_marks(src, temp);
						temp.replace_char(9, 0x20);
						CreateToolTip(temp);
					}
					else { DestroyWindow(g_tooltip); g_tooltip = 0; last_idx = -1; last_column = -1; }

					POINT a;
					a.x = cx + 3;
					a.y = (idx - scroll_item_offset) * item_height + get_header_height();
					ClientToScreen(wnd_playlist, &a);

					tooltip.top = a.y;
					tooltip.bottom = a.y + item_height;
					tooltip.left = a.x;
					tooltip.right = a.x + get_column_width(column);

				}
				last_idx = idx;
				last_column = column;
			}
			else { DestroyWindow(g_tooltip); g_tooltip = 0; last_idx = -1; last_column = -1; }
		}


		if (drag_type && (wp & MK_LBUTTON) && !(GetKeyState(VK_SHIFT) & KF_UP) && !(GetKeyState(VK_CONTROL) & KF_UP))
		{
			RECT rc;
			get_playlist_rect(&rc);
			static_api_ptr_t<playlist_manager> playlist_api;

			int total = playlist_api->activeplaylist_get_item_count();

			int item_height = get_item_height();
			int valid_idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), false);
			int idx = hittest_item_no_scroll(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), false);
			//    (GET_Y_LPARAM(lp) - get_header_height()) / (item_height);

			int items_count = ((rc.bottom - rc.top) / item_height) + 1;


			if ((idx + scroll_item_offset) != dragitem || GET_Y_LPARAM(lp) < get_header_height()) //(idx + scroll_item_offset) < playlist_api->activeplaylist_get_item_count()
			{
				if (idx >= items_count - 1)
				{

					bool need_redrawing = false;

					int focus = playlist_api->activeplaylist_get_focus_item();

					SCROLLINFO si;
					memset(&si, 0, sizeof(si));
					si.cbSize = sizeof(si);
					si.fMask = SIF_POS;
					GetScrollInfo(wnd_playlist, SB_VERT, &si);

					int old_offset = si.nPos;
					si.nPos += 3;

					scroll_item_offset = SetScrollInfo(wnd_playlist, SB_VERT, &si, true);

					if (old_offset != scroll_item_offset) need_redrawing = true;

					int t = scroll_item_offset + items_count - 2; //n=dragitem,

					if (t > total) t = total - 1;


					if (t != dragitem)
					{

						drawing_enabled = false;
						if (drag_type == 1)
							playlist_api->activeplaylist_move_selection((rc.bottom - rc.top) / item_height + scroll_item_offset - focus - 1);
						else if (drag_type == 2)
						{

							set_sel_range(dragstartitem, t, false);
							playlist_api->activeplaylist_set_focus_item(t);
						}

						dragitem = t;
						drawing_enabled = true;
						need_redrawing = true;

					}
					if (need_redrawing) RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);


				}
				else if (idx < 0 || GET_Y_LPARAM(lp) < get_header_height() || GET_Y_LPARAM(lp) < 0)
				{


					int focus = playlist_api->activeplaylist_get_focus_item();

					bool need_redrawing = false;

					SCROLLINFO si;
					memset(&si, 0, sizeof(si));
					si.cbSize = sizeof(si);
					si.fMask = SIF_POS;
					GetScrollInfo(wnd_playlist, SB_VERT, &si);
					int old_offset = si.nPos;
					si.nPos -= 3;
					scroll_item_offset = SetScrollInfo(wnd_playlist, SB_VERT, &si, true);

					if (old_offset != scroll_item_offset) need_redrawing = true;

					if (dragitem != scroll_item_offset)
					{
						drawing_enabled = false;
						if (drag_type == 1)
							playlist_api->activeplaylist_move_selection(scroll_item_offset - focus);
						else if (drag_type == 2)
						{

							set_sel_range(dragstartitem, scroll_item_offset, false);
							playlist_api->activeplaylist_set_focus_item(scroll_item_offset);
							RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
						}

						dragitem = scroll_item_offset;
						drawing_enabled = true;
						need_redrawing = true;
					}

					if (need_redrawing) RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);


				}
				else
				{
					int focus = playlist_api->activeplaylist_get_focus_item();

					if (drag_type == 1)
						playlist_api->activeplaylist_move_selection(idx + scroll_item_offset - focus);
					else if (drag_type == 2)
					{
						if (valid_idx >= 0)
						{
							drawing_enabled = false;
							set_sel_range(dragstartitem, valid_idx, false);
							playlist_api->activeplaylist_set_focus_item(valid_idx);
							drawing_enabled = true;
							RedrawWindow(wnd_playlist, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
						}

					}

					dragitem = valid_idx;
					dragged = true;
				}
			}

		}
		else if (!(wp & MK_LBUTTON)) drag_type = 0;
	}
	break;
	case WM_LBUTTONDBLCLK:
	{
		int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), true);

		if (idx >= 0)
		{
			//#ifdef INLINE_EDIT
			exit_inline_edit();
			m_no_next_edit = true;
			//#endif
			//if (!is_visible(idx)) uSendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0),0);

#if 0
			// DEATH's code
	case WM_LBUTTONDBLCLK:
	{
		int idx = item_from_point((short)HIWORD(lp));
		if (idx >= 0 && idx<(int)m_api->activeplaylist_get_item_count())
		{
			m_api->activeplaylist_set_focus_item(idx);
			static_api_ptr_t<play_control>()->play_start(play_control::TRACK_COMMAND_SETTRACK);
		}
	}
	return 0;
#endif
	static_api_ptr_t<playlist_manager> playlist_api;
	//unsigned active = playlist_api->get_active_playlist();
	//				playlist_api->set_playing_playlist(active);
	//playlist_api->playlist_set_playback_cursor(active, idx);
	//playlist_api->queue_flush();
	unsigned focus = playlist_api->activeplaylist_get_focus_item();
	playlist_api->activeplaylist_execute_default_action(focus);

		}
		else if (cfg_playlist_double.get_value().m_command != pfc::guid_null)
		{
			mainmenu_commands::g_execute(cfg_playlist_double.get_value().m_command);
		}

		dragged = true;
	}

	break;
	case WM_RBUTTONDOWN:
	{
		if (wnd_playlist) SetFocus(wnd_playlist);

		g_dragging1 = true;

		drag_start.x = GET_X_LPARAM(lp);
		drag_start.y = GET_Y_LPARAM(lp);

		static_api_ptr_t<playlist_manager> playlist_api;


		//		int item_height = get_item_height();
		//		int idx = ((GET_Y_LPARAM(lp) - get_header_height()) / item_height) + scroll_item_offset;
		int idx = hittest_item(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), true);
		if (idx != -1 && !is_visible(idx))
			SendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);

		if (idx >= 0 /*&& idx < playlist_api->activeplaylist_get_item_count() && (GET_X_LPARAM(lp) < g_playlist_entries.get_total_width_actual())*/)
		{

			if (!playlist_api->activeplaylist_is_item_selected(idx) && !(GetKeyState(VK_CONTROL) & KF_UP))
			{
				set_sel_single(idx, false, false, true);
			}
			playlist_api->activeplaylist_set_focus_item(idx);

		}


	}

	break;
	case WM_MOUSEWHEEL:
	{//GET_WHEEL_DELTA_WPARAM
		exit_inline_edit();
		if (1 || (wp & MK_CONTROL))
		{

			LONG_PTR style = GetWindowLongPtr(wnd_playlist, GWL_STYLE);
			if (!(style & WS_VSCROLL) || ((wp & MK_CONTROL) && (style & WS_HSCROLL)))
			{
				if ((style & WS_HSCROLL))
				{
					SCROLLINFO si;
					memset(&si, 0, sizeof(SCROLLINFO));
					si.fMask = SIF_PAGE;
					si.cbSize = sizeof(SCROLLINFO);
					GetScrollInfo(wnd, SB_HORZ, &si);

					int new_pos = horizontal_offset;
					int old_pos = horizontal_offset;

					unsigned scroll_lines = GetNumScrollLines();

					int zDelta = short(HIWORD(wp));

					if (scroll_lines == -1)
					{
						scroll_lines = si.nPage > 1 ? si.nPage - 1 : 1;
					}
					else scroll_lines *= 3;

					int delta = MulDiv(zDelta, scroll_lines, 120);

					if (!si.nPage) si.nPage++;

					if (delta < 0 && delta*-1 > si.nPage)
					{
						delta = si.nPage*-1;
						if (delta >1) delta--;
					}
					else if (delta > 0 && delta > si.nPage)
					{
						delta = si.nPage;
						if (delta >1) delta--;
					}

					scroll(scroll_horizontally, scroll_position_delta, -delta);

				}
				return 1;
			}
		}

		SCROLLINFO si;
		memset(&si, 0, sizeof(SCROLLINFO));
		si.fMask = SIF_PAGE;
		si.cbSize = sizeof(SCROLLINFO);
		GetScrollInfo(wnd, SB_VERT, &si);

		int new_pos = scroll_item_offset;
		int old_pos = scroll_item_offset;
		unsigned scroll_lines = GetNumScrollLines();

		int zDelta = short(HIWORD(wp));

		if (scroll_lines == -1)
		{
			scroll_lines = si.nPage > 1 ? si.nPage - 1 : 1;
		}

		int delta = MulDiv(zDelta, scroll_lines, 120);

		if (!si.nPage) si.nPage++;

		if (delta < 0 && delta*-1 > si.nPage)
		{
			delta = si.nPage*-1;
			if (delta >1) delta--;
		}
		else if (delta > 0 && delta > si.nPage)
		{
			delta = si.nPage;
			if (delta >1) delta--;
		}

		scroll(scroll_vertically, scroll_position_delta, -delta);
	}
	return 1;
	case WM_VSCROLL:
	{
		exit_inline_edit();
		scroll(scroll_vertically, scroll_sb, LOWORD(wp));
	}
	return 0;
	case WM_HSCROLL:
	{
		exit_inline_edit();
		scroll(scroll_horizontally, scroll_sb, LOWORD(wp));
	}
	return 0;
	case WM_MENUSELECT:
	{
		if (HIWORD(wp) & MF_POPUP)
		{
			m_status_override.release();
		}
		else
		{
			if (g_main_menu_a.is_valid() || g_main_menu_b.is_valid())
			{
				unsigned id = LOWORD(wp);

				bool set = false;

				pfc::string8 desc;

				if (g_main_menu_a.is_valid() && id < MENU_B_BASE)
				{
					set = g_main_menu_a->get_description(id - MENU_A_BASE, desc);
				}
				else if (g_main_menu_b.is_valid())
				{
					contextmenu_node * node = g_main_menu_b->find_by_id(id - MENU_B_BASE);
					if (node) set = node->get_description(desc);
				}

				service_ptr_t<ui_status_text_override> p_status_override;

				if (set)
				{
					get_host()->override_status_text_create(p_status_override);

					if (p_status_override.is_valid())
					{
						p_status_override->override_text(desc);
					}
				}
				m_status_override = p_status_override;
			}
		}
	}
	break;
	case WM_CONTEXTMENU:
	{
		uie::window_ptr p_this_temp = this;
		if ((HWND)wp == wnd_header)
		{
			POINT pt = { (short)LOWORD(lp), (short)HIWORD(lp) };
			POINT temp;
			temp.x = pt.x;
			temp.y = pt.y;
			ScreenToClient(wnd_header, &temp);
			HDHITTESTINFO hittest;
			hittest.pt.x = temp.x;
			hittest.pt.y = temp.y;


			uSendMessage(wnd_header, HDM_HITTEST, 0, (LPARAM)&hittest);

			enum { IDM_ASC = 1, IDM_DES = 2, IDM_SEL_ASC, IDM_SEL_DES, IDM_AUTOSIZE, IDM_PREFS, IDM_EDIT_COLUMN, IDM_CUSTOM_BASE };

			HMENU menu = CreatePopupMenu();
			HMENU selection_menu = CreatePopupMenu();
			if (!(hittest.flags & HHT_NOWHERE))
			{
				uAppendMenu(menu, (MF_STRING), IDM_ASC, "&Sort ascending");
				uAppendMenu(menu, (MF_STRING), IDM_DES, "Sort &descending");
				uAppendMenu(selection_menu, (MF_STRING), IDM_SEL_ASC, "Sort a&scending");
				uAppendMenu(selection_menu, (MF_STRING), IDM_SEL_DES, "Sort d&escending");
				uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)selection_menu, "Se&lection");
				uAppendMenu(menu, (MF_SEPARATOR), 0, "");
				uAppendMenu(menu, (MF_STRING), IDM_EDIT_COLUMN, "&Edit this column");
				uAppendMenu(menu, (MF_SEPARATOR), 0, "");
				uAppendMenu(menu, (MF_STRING | (cfg_nohscroll ? MF_CHECKED : MF_UNCHECKED)), IDM_AUTOSIZE, "&Auto-sizing columns");
				uAppendMenu(menu, (MF_STRING), IDM_PREFS, "&Preferences");
				uAppendMenu(menu, (MF_SEPARATOR), 0, "");

				pfc::string8 playlist_name;
				static_api_ptr_t<playlist_manager> playlist_api;
				playlist_api->activeplaylist_get_name(playlist_name);

				pfc::string8_fast_aggressive filter, name;

				int s, e = columns.get_count();
				for (s = 0; s<e; s++)
				{
					bool add = false;
					switch (columns[s]->filter_type)
					{
					case FILTER_NONE:
					{
						add = true;
						break;
					}
					case FILTER_SHOW:
					{
						if (wildcard_helper::test(playlist_name, columns[s]->filter, true))
						{
							add = true;
							/*				g_columns.get_string(s, name, STRING_NAME);
							uAppendMenu(menu,MF_STRING|MF_CHECKED,IDM_CUSTOM_BASE+s,name);*/
						}
					}
					break;
					case FILTER_HIDE:
					{
						if (!wildcard_helper::test(playlist_name, columns[s]->filter, true))
						{
							add = true;
							/*						g_columns.get_string(s, name, STRING_NAME);
							uAppendMenu(menu,MF_STRING|MF_CHECKED,IDM_CUSTOM_BASE+s,name);*/
						}
					}
					break;
					}
					if (add)
					{
						uAppendMenu(menu, MF_STRING | (columns[s]->show ? MF_CHECKED : MF_UNCHECKED), IDM_CUSTOM_BASE + s, columns[s]->name);
					}
				}


			}
			else
			{
				uAppendMenu(menu, (MF_STRING | (cfg_nohscroll ? MF_CHECKED : MF_UNCHECKED)), IDM_AUTOSIZE, "&Auto-sizing columns");
				uAppendMenu(menu, (MF_STRING), IDM_PREFS, "&Preferences");
			}


			menu_helpers::win32_auto_mnemonics(menu);

			int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, wnd, 0);
			DestroyMenu(menu);

			if (cmd == IDM_ASC)
			{

				g_set_sort(hittest.iItem, false);
			}
			else if (cmd == IDM_DES)
			{
				g_set_sort(hittest.iItem, true);
			}
			else if (cmd == IDM_SEL_ASC)
			{
				g_set_sort(hittest.iItem, false, true);
			}
			else if (cmd == IDM_SEL_DES)
			{
				g_set_sort(hittest.iItem, true, true);
			}
			else if (cmd == IDM_EDIT_COLUMN)
			{
				g_set_tab("Columns");
				cfg_cur_prefs_col = g_cache.active_column_active_to_actual(hittest.iItem); //get_idx
				static_api_ptr_t<ui_control>()->show_preferences(columns::config_get_playlist_view_guid());
			}
			else if (cmd == IDM_AUTOSIZE)
			{
				cfg_nohscroll = cfg_nohscroll == 0;
				update_all_windows();
				pvt::ng_playlist_view_t::g_on_autosize_change();
			}
			else if (cmd == IDM_PREFS)
			{
				static_api_ptr_t<ui_control>()->show_preferences(columns::config_get_main_guid());
			}
			else if (cmd >= IDM_CUSTOM_BASE)
			{
				if (t_size(cmd - IDM_CUSTOM_BASE) < columns.get_count())
				{
					columns[cmd - IDM_CUSTOM_BASE]->show = !columns[cmd - IDM_CUSTOM_BASE]->show; //g_columns
					//if (!cfg_nohscroll) 
					g_save_columns();
					//g_cache.flush_all();
					g_reset_columns();
					update_all_windows();
					pvt::ng_playlist_view_t::g_on_columns_change();
				}

			}
			return 0;
		}
		else if ((HWND)wp == wnd)
		{
			//DWORD mp = GetMessagePos();
			POINT px, pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
			static_api_ptr_t<playlist_manager> playlist_api;
			if (playlist_api->activeplaylist_get_selection_count(1) > 0 && 1)
			{
				if (pt.x == -1 && pt.y == -1)
				{
					int focus = playlist_api->activeplaylist_get_focus_item();
					unsigned last = get_last_viewable_item();
					if (focus == -1 || focus < scroll_item_offset || focus > last)
					{
						px.x = 0;
						px.y = 0;
					}
					else
					{
						RECT rc;
						get_playlist_rect(&rc);
						px.x = 0;
						unsigned item_height = get_item_height();
						px.y = (focus - scroll_item_offset)*(item_height)+item_height / 2 + rc.top;
					}
					pt = px;
					MapWindowPoints(wnd, HWND_DESKTOP, &pt, 1);
				}
				else
				{
					px = pt;
					ScreenToClient(wnd, &px);
					//int idx = hittest_item(px.x, px.y);
					//if (!is_visible(idx))
					//	SendMessage(wnd_playlist, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0),0);

				}
				//			int idx = hittest_item(px.x, px.y);

				enum { ID_PLAY = 1, ID_CUT, ID_COPY, ID_PASTE, ID_SELECTION, ID_CUSTOM_BASE = 0x8000 };
				HMENU menu = CreatePopupMenu();//LoadMenu(core_api::get_my_instance(),MAKEINTRESOURCE(IDR_TREEPOPUP));

				service_ptr_t<mainmenu_manager> p_manager_selection;
				service_ptr_t<contextmenu_manager> p_manager_context;
				p_manager_selection = standard_api_create_t<mainmenu_manager>();
				contextmenu_manager::g_create(p_manager_context);
				if (p_manager_selection.is_valid())
				{
					p_manager_selection->instantiate(mainmenu_groups::edit_part2_selection);
					p_manager_selection->generate_menu_win32(menu, ID_SELECTION, ID_CUSTOM_BASE - ID_SELECTION, standard_config_objects::query_show_keyboard_shortcuts_in_menus() ? contextmenu_manager::FLAG_SHOW_SHORTCUTS : 0);
					if (GetMenuItemCount(menu) > 0) uAppendMenu(menu, MF_SEPARATOR, 0, "");
				}

				AppendMenu(menu, MF_STRING, ID_CUT, L"Cut");
				AppendMenu(menu, MF_STRING, ID_COPY, L"Copy");
				if (playlist_utils::check_clipboard())
					AppendMenu(menu, MF_STRING, ID_PASTE, L"Paste");
				AppendMenu(menu, MF_SEPARATOR, 0, NULL);
				if (p_manager_context.is_valid())
				{
					const keyboard_shortcut_manager::shortcut_type shortcuts[] = { keyboard_shortcut_manager::TYPE_CONTEXT_PLAYLIST, keyboard_shortcut_manager::TYPE_CONTEXT };
					p_manager_context->set_shortcut_preference(shortcuts, tabsize(shortcuts));
					p_manager_context->init_context_playlist(standard_config_objects::query_show_keyboard_shortcuts_in_menus() ? contextmenu_manager::FLAG_SHOW_SHORTCUTS : 0);

					p_manager_context->win32_build_menu(menu, ID_CUSTOM_BASE, -1);
				}
				menu_helpers::win32_auto_mnemonics(menu);
				MENU_A_BASE = ID_SELECTION;
				MENU_B_BASE = ID_CUSTOM_BASE;

				g_main_menu_a = p_manager_selection;
				g_main_menu_b = p_manager_context;

				int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, wnd, 0);
				if (m_status_override.is_valid())
				{
					m_status_override.release();
				}

				DestroyMenu(menu);
				if (cmd)
				{
					if (cmd == ID_CUT)
					{
						playlist_utils::cut();
					}
					else if (cmd == ID_COPY)
					{
						playlist_utils::copy();
					}
					else if (cmd == ID_PASTE)
					{
						playlist_utils::paste(wnd);
					}
					else if (cmd >= ID_SELECTION && cmd<ID_CUSTOM_BASE)
					{
						if (p_manager_selection.is_valid())
						{
							p_manager_selection->execute_command(cmd - ID_SELECTION);
						}
					}
					else if (cmd >= ID_CUSTOM_BASE)
					{
						if (p_manager_context.is_valid())
						{
							p_manager_context->execute_by_id(cmd - ID_CUSTOM_BASE);
						}
					}
				}
				g_main_menu_a.release();
				g_main_menu_b.release();
			}


			//	contextmenu_manager::win32_run_menu_context_playlist(wnd, 0, config_object::g_get_data_bool_simple(standard_config_objects::bool_show_keyboard_shortcuts_in_menus, true) ? contextmenu_manager::FLAG_SHOW_SHORTCUTS : 0);
		}
	}
	return 0;

	//#ifdef INLINE_EDIT
	case WM_PARENTNOTIFY:
	{
		if (wp == WM_DESTROY)
		{
			if (m_wnd_edit && (HWND)lp == m_wnd_edit) m_wnd_edit = 0;
		}
	}
	break;
	case MSG_KILL_INLINE_EDIT:
		exit_inline_edit();
		return 0;

#if 1
	case WM_COMMAND:
		switch (wp)
		{
		case (EN_CHANGE << 16) | 667:
		{
			m_edit_changed = true;
		}
		break;
		}
		break;
#endif

	case WM_TIMER:
	{
		if (wp == EDIT_TIMER_ID)
		{
			create_inline_edit_v2(m_edit_index, m_edit_column);
			if (m_edit_timer)
			{
				KillTimer(wnd_playlist, EDIT_TIMER_ID);
				m_edit_timer = false;
			}
			return 0;
		}

	}
	break;

	//#endif
	case WM_NOTIFY:
		switch (((LPNMHDR)lp)->idFrom)
		{
		case ID_PLAYLIST_TOOLTIP:
			switch (((LPNMHDR)lp)->code)
			{
			case TTN_SHOW:

				RECT rc, rc_tt;

				rc = tooltip;
				GetWindowRect(g_tooltip, &rc_tt);

				int offset = MulDiv(get_item_height() - rc_tt.bottom + rc_tt.top, 1, 2);


				rc.top += offset;




				SetWindowPos(g_tooltip,
					NULL,
					rc.left, rc.top,
					0, 0,
					SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
				return TRUE;
			}
			break;
		case 5001:
			switch (((LPNMHDR)lp)->code)
			{
			case HDN_BEGINTRACKA:
			case HDN_BEGINTRACKW:
			{
				return (cfg_nohscroll ? TRUE : FALSE);
			}
			case HDN_ENDDRAG:
			{
				if (((LPNMHEADERA)lp)->iButton == 0)
				{

					if (((LPNMHEADERA)lp)->pitem && (((LPNMHEADERA)lp)->pitem->mask & HDI_ORDER))
					{

						int from = ((LPNMHEADERA)lp)->iItem;
						int to = ((LPNMHEADERA)lp)->pitem->iOrder;
						if (to >= 0 && from != to)
						{
							int act_from = g_cache.active_column_active_to_actual(from), act_to = g_cache.active_column_active_to_actual(to);

							columns.move(act_from, act_to);
							//if (!cfg_nohscroll) 
							g_save_columns();
							g_reset_columns();
							update_all_windows();
							pvt::ng_playlist_view_t::g_on_columns_change();
						}
					}
					else
					{
					}
				}
				return (TRUE);
			}
			case HDN_DIVIDERDBLCLICK:
				if (!cfg_nohscroll)
				{
					static_api_ptr_t<playlist_manager> playlist_api;
					HDC hdc;
					hdc = GetDC(wnd_playlist);
					int size;
					pfc::string8 text;

					SelectObject(hdc, g_font);


					int w = 0, n, t = playlist_api->activeplaylist_get_item_count();

					for (n = 0; n<t; n++)
					{
						//	playlist_api->format_title(n, text, g_playlist_entries.get_display_spec(((LPNMHEADER)lp)->iItem), NULL);
						g_cache.active_get_display_name(n, ((LPNMHEADER)lp)->iItem, text);
						size = ui_helpers::get_text_width_color(hdc, text, text.length());
						if (size > w) w = size;
					}

					//	g_playlist_entries.get_column(((LPNMHEADER)lp)->iItem)->_set_width(w+5);
					columns[g_cache.active_column_active_to_actual(((LPNMHEADER)lp)->iItem)]->width = w + 15;

					ReleaseDC(wnd_playlist, hdc);
					update_all_windows();
					g_save_columns();
					pvt::ng_playlist_view_t::g_on_column_widths_change();
				}

				return 0;
			case HDN_ITEMCLICK:
			{
				bool des = false;

				static_api_ptr_t<playlist_manager> playlist_api;

				unsigned col;
				bool descending;
				bool sorted = g_cache.active_get_playlist_sort(col, &descending);

				if (sorted && col == ((LPNMHEADER)lp)->iItem)
					des = !descending;

				g_set_sort(((LPNMHEADER)lp)->iItem, des /*, playlist_api->activeplaylist_get_selection_count(1) && cfg_sortsel != 0*/);

			}
			break;
			case HDN_ITEMCHANGED:
			{
				if (!cfg_nohscroll)
				{
					if (((LPNMHEADER)lp)->pitem->mask & HDI_WIDTH)
						columns[g_cache.active_column_active_to_actual(((LPNMHEADER)lp)->iItem)]->width = ((LPNMHEADER)lp)->pitem->cxy;
					update_all_windows(wnd_header);
					g_save_columns();
					pvt::ng_playlist_view_t::g_on_column_widths_change();
				}
			}
			break;
			}
			break;
		}

	}
	return uDefWindowProc(wnd, msg, wp, lp);
}
Esempio n. 19
0
LONG_PTR WINAPI HashVerifySetColor( PHASHVERIFYCONTEXT phvctx, LPNMLVCUSTOMDRAW pcd )
{
	switch (pcd->nmcd.dwDrawStage)
	{
		case CDDS_PREPAINT:
			return(CDRF_NOTIFYITEMDRAW);

		case CDDS_ITEMPREPAINT:
		{
			// We need to determine the highlight state during the item stage
			// because this information becomes subitem-specific if we try to
			// retrieve it when we actually need it in the subitem stage

			if (g_uWinVer >= 0x0600 && IsAppThemed())
			{
				// Clear the highlight bit...
				phvctx->dwFlags &= ~HVF_ITEM_HILITE;

				// uItemState is buggy; if LVS_SHOWSELALWAYS is set, uItemState
				// will ALWAYS have the CDIS_SELECTED bit set, regardless of
				// whether the item is actually selected, so a more expensive
				// test for the LVIS_SELECTED bit is needed...
				if ( pcd->nmcd.uItemState & CDIS_HOT ||
				     ListView_GetItemState(pcd->nmcd.hdr.hwndFrom, pcd->nmcd.dwItemSpec, LVIS_SELECTED) )
				{
					phvctx->dwFlags |= HVF_ITEM_HILITE;
				}
			}

			return(CDRF_NOTIFYSUBITEMDRAW);
		}

		case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
		{
			PHASHVERIFYITEM pItem;

			if (pcd->nmcd.dwItemSpec >= phvctx->cTotal)
				break;  // Invalid index

			pItem = phvctx->index[pcd->nmcd.dwItemSpec];

			// By default, we use the default foreground and background colors
			// except when the item is a mismatch or is unreadable, in which
			// case, we change the foreground color
			switch (pItem->uStatusID)
			{
				case HV_STATUS_MISMATCH:
					pcd->clrText = RGB(0xC0, 0x00, 0x00);
					break;

				case HV_STATUS_UNREADABLE:
					pcd->clrText = RGB(0x80, 0x80, 0x80);
					break;

				default:
					pcd->clrText = CLR_DEFAULT;
			}

			pcd->clrTextBk = CLR_DEFAULT;

			// The status column, however, deserves special treatment
			if (pcd->iSubItem == HV_COL_STATUS)
			{
				if (phvctx->dwFlags & HVF_ITEM_HILITE)
				{
					// Vista-style highlighting means that the foreground
					// color can show through, but not the background color
					if (pItem->uStatusID == HV_STATUS_MATCH)
						pcd->clrText = RGB(0x00, 0x80, 0x00);
				}
				else
				{
					switch (pItem->uStatusID)
					{
						case HV_STATUS_MATCH:
							pcd->clrText = RGB(0x00, 0x00, 0x00);
							pcd->clrTextBk = RGB(0x00, 0xE0, 0x00);
							break;

						case HV_STATUS_MISMATCH:
							pcd->clrText = RGB(0xFF, 0xFF, 0xFF);
							pcd->clrTextBk = RGB(0xC0, 0x00, 0x00);
							break;

						case HV_STATUS_UNREADABLE:
							pcd->clrText = RGB(0x00, 0x00, 0x00);
							pcd->clrTextBk = RGB(0xFF, 0xE0, 0x00);
							break;
					}
				}
			}

			break;
		}
	}

	return(CDRF_DODEFAULT);
}
Esempio n. 20
0
// static
void
nsUXThemeData::UpdateNativeThemeInfo()
{
  // Trigger a refresh of themed button metrics if needed
  sTitlebarInfoPopulatedThemed = (nsWindow::GetWindowsVersion() < VISTA_VERSION);

  sIsDefaultWindowsTheme = PR_FALSE;
  sThemeId = nsILookAndFeel::eWindowsTheme_Generic;

  if (!IsAppThemed() || !getCurrentThemeName) {
    sThemeId = nsILookAndFeel::eWindowsTheme_Classic;
    return;
  }

  WCHAR themeFileName[MAX_PATH + 1];
  WCHAR themeColor[MAX_PATH + 1];
  if (FAILED(getCurrentThemeName(themeFileName,
                                 MAX_PATH,
                                 themeColor,
                                 MAX_PATH,
                                 NULL, 0))) {
    sThemeId = nsILookAndFeel::eWindowsTheme_Classic;
    return;
  }

  LPCWSTR themeName = wcsrchr(themeFileName, L'\\');
  themeName = themeName ? themeName + 1 : themeFileName;

  WindowsTheme theme = WINTHEME_UNRECOGNIZED;
  for (int i = 0; i < NS_ARRAY_LENGTH(knownThemes); ++i) {
    if (!lstrcmpiW(themeName, knownThemes[i].name)) {
      theme = (WindowsTheme)knownThemes[i].type;
      break;
    }
  }

  if (theme == WINTHEME_UNRECOGNIZED)
    return;

  if (theme == WINTHEME_AERO || theme == WINTHEME_LUNA)
    sIsDefaultWindowsTheme = PR_TRUE;
  
  if (theme != WINTHEME_LUNA) {
    switch(theme) {
      case WINTHEME_AERO:
        sThemeId = nsILookAndFeel::eWindowsTheme_Aero;
        return;
      case WINTHEME_ZUNE:
        sThemeId = nsILookAndFeel::eWindowsTheme_Zune;
        return;
      case WINTHEME_ROYALE:
        sThemeId = nsILookAndFeel::eWindowsTheme_Royale;
        return;
      default:
        NS_WARNING("unhandled theme type.");
        return;
    }
  }

  // calculate the luna color scheme
  WindowsThemeColor color = WINTHEMECOLOR_UNRECOGNIZED;
  for (int i = 0; i < NS_ARRAY_LENGTH(knownColors); ++i) {
    if (!lstrcmpiW(themeColor, knownColors[i].name)) {
      color = (WindowsThemeColor)knownColors[i].type;
      break;
    }
  }

  switch(color) {
    case WINTHEMECOLOR_NORMAL:
      sThemeId = nsILookAndFeel::eWindowsTheme_LunaBlue;
      return;
    case WINTHEMECOLOR_HOMESTEAD:
      sThemeId = nsILookAndFeel::eWindowsTheme_LunaOlive;
      return;
    case WINTHEMECOLOR_METALLIC:
      sThemeId = nsILookAndFeel::eWindowsTheme_LunaSilver;
      return;
    default:
      NS_WARNING("unhandled theme color.");
      return;
  }
}
Esempio n. 21
0
HRESULT CMenuToolbarBase::CreateToolbar(HWND hwndParent, DWORD dwFlags)
{
    LONG tbStyles = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
        TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT | TBSTYLE_CUSTOMERASE |
        CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP;
    LONG tbExStyles = TBSTYLE_EX_DOUBLEBUFFER | WS_EX_TOOLWINDOW;

    if (dwFlags & SMINIT_VERTICAL)
    {
        // Activate vertical semantics
        tbStyles |= CCS_VERT;

#if USE_TBSTYLE_EX_VERTICAL
        tbExStyles |= TBSTYLE_EX_VERTICAL;
#endif
    }

    m_initFlags = dwFlags;

    // Get a temporary rect to use while creating the toolbar window.
    // Ensure that it is not a null rect.
    RECT rc;
    if (!::GetClientRect(hwndParent, &rc) ||
        (rc.left == rc.right) ||
        (rc.top == rc.bottom))
    {
        rc.left = 0;
        rc.top = 0;
        rc.right = 1;
        rc.bottom = 1;
    }

    SubclassWindow(CToolbar::Create(hwndParent, tbStyles, tbExStyles));

    SetWindowTheme(m_hWnd, L"", L"");

    if (IsAppThemed())
        GetThemeSysBool(GetWindowTheme(m_hWnd), TMT_FLATMENUS);
    else
        SystemParametersInfo(SPI_GETFLATMENU, 0, &m_useFlatMenus, 0);

    m_menuBand->AdjustForTheme(m_useFlatMenus);

    // If needed, create the pager.
    if (m_usePager)
    {
        LONG pgStyles = PGS_VERT | WS_CHILD | WS_VISIBLE;
        LONG pgExStyles = 0;

        HWND hwndPager = CreateWindowEx(
            pgExStyles, WC_PAGESCROLLER, NULL,
            pgStyles, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
            hwndParent, NULL, _AtlBaseModule.GetModuleInstance(), 0);

        m_pager.SubclassWindow(hwndPager);

        ::SetParent(m_hWnd, hwndPager);
        
        m_pager.SendMessageW(PGM_SETCHILD, 0, reinterpret_cast<LPARAM>(m_hWnd));
    }

    // Configure the image lists
    UpdateImageLists();

    return S_OK;
}
Esempio n. 22
0
void CClosableTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	CRect rect(lpDIS->rcItem);
	int nTabIndex = lpDIS->itemID;
	if (nTabIndex < 0)
		return;

	TCHAR szLabel[256];
	TC_ITEM tci;
	tci.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_STATE;
	tci.pszText = szLabel;
	tci.cchTextMax = _countof(szLabel);
	tci.dwStateMask = TCIS_HIGHLIGHTED;
	if (!GetItem(nTabIndex, &tci))
		return;
	szLabel[_countof(szLabel) - 1] = _T('\0');
	//TRACE("CClosableTabCtrl::DrawItem: item=%u, state=%08x, color=%08x, rc=%3d,%3d,%3dx%3d\n", nTabIndex, tci.dwState, GetTextColor(lpDIS->hDC), lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right - lpDIS->rcItem.left, lpDIS->rcItem.bottom - lpDIS->rcItem.top);

	CDC* pDC = CDC::FromHandle(lpDIS->hDC);
	if (!pDC)
		return;

	CRect rcFullItem(lpDIS->rcItem);
	bool bSelected = (lpDIS->itemState & ODS_SELECTED) != 0;

	///////////////////////////////////////////////////////////////////////////////////////
	// Adding support for XP Styles (Vista Themes) for owner drawn tab controls simply
	// does *not* work under Vista. Maybe it works under XP (did not try), but that is
	// meaningless because under XP a owner drawn tab control is already rendered *with*
	// the proper XP Styles. So, for XP there is no need to care about the theme API at all.
	//
	// However, under Vista, a tab control which has the TCS_OWNERDRAWFIXED
	// style gets additional 3D-borders which are applied by Vista *after* WM_DRAWITEM
	// was processed. Thus, there is no known workaround available to prevent Vista from
	// adding those old fashioned 3D-borders. We can render the tab control items within
	// the WM_DRAWITEM handler in whatever style we want, but Vista will in each case
	// overwrite the borders of each tab control item with old fashioned 3D-borders...
	//
	// To complete this experience, tab controls also do not support NMCUSTOMDRAW. So, the
	// only known way to customize a tab control is by using TCS_OWNERDRAWFIXED which does
	// however not work properly under Vista.
	//
	// The "solution" which is currently implemented to prevent Vista from drawing those
	// 3D-borders is by using "ExcludeClipRect" to reduce the drawing area which is used
	// by Windows after WM_DRAWITEM was processed. This "solution" is very sensitive to
	// the used rectangles and offsets in general. Incrementing/Decrementing one of the
	// "rcItem", "rcFullItem", etc. rectangles makes the entire "solution" flawed again
	// because some borders would become visible again.
	//
	HTHEME hTheme = NULL;
	int iPartId = TABP_TABITEM;
	int iStateId = TIS_NORMAL;
	bool bVistaHotTracked = false;
	bool bVistaThemeActive = theApp.IsVistaThemeActive();
	if (bVistaThemeActive)
	{
		// To determine if the current item is in 'hot tracking' mode, we need to evaluate
		// the current foreground color - there is no flag which would indicate this state 
		// more safely. This applies only for Vista and for tab controls which have the
		// TCS_OWNERDRAWFIXED style.
		bVistaHotTracked = pDC->GetTextColor() == GetSysColor(COLOR_HOTLIGHT);

		hTheme = OpenThemeData(m_hWnd, L"TAB");
		if (hTheme)
		{
			if (bSelected) {
				// get the real tab item rect
				rcFullItem.left += 1;
				rcFullItem.right -= 1;
				rcFullItem.bottom -= 1;
			}
			else
				rcFullItem.InflateRect(2, 2); // get the real tab item rect

			CRect rcBk(rcFullItem);
			if (bSelected)
			{
				iStateId = TTIS_SELECTED;
				if (nTabIndex == 0) {
					// First item
					if (nTabIndex == GetItemCount() - 1)
						iPartId = TABP_TOPTABITEMBOTHEDGE; // First & Last item
					else
						iPartId = TABP_TOPTABITEMLEFTEDGE;
				}
				else if (nTabIndex == GetItemCount() - 1) {
					// Last item
					iPartId = TABP_TOPTABITEMRIGHTEDGE;
				}
				else {
					iPartId = TABP_TOPTABITEM;
				}
			}
			else
			{
				rcBk.top += 2;
				iStateId = bVistaHotTracked ? TIS_HOT : TIS_NORMAL;
				if (nTabIndex == 0) {
					// First item
					if (nTabIndex == GetItemCount() - 1)
						iPartId = TABP_TABITEMBOTHEDGE; // First & Last item
					else
						iPartId = TABP_TABITEMLEFTEDGE;
				}
				else if (nTabIndex == GetItemCount() - 1) {
					// Last item
					iPartId = TABP_TABITEMRIGHTEDGE;
				}
				else {
					iPartId = TABP_TABITEM;
				}
			}
			if (IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId))
				DrawThemeParentBackground(m_hWnd, *pDC, &rcFullItem);
			DrawThemeBackground(hTheme, *pDC, iPartId, iStateId, &rcBk, NULL);
		}
	}

	// Following background clearing is needed for:
	//	WinXP/Vista (when used without an application theme)
	//	Vista (when used with an application theme but without a theme for the tab control)
	if (   (!IsThemeActive() || !IsAppThemed())
		|| (hTheme == NULL && bVistaThemeActive) )
		pDC->FillSolidRect(&lpDIS->rcItem, GetSysColor(COLOR_BTNFACE));

	int iOldBkMode = pDC->SetBkMode(TRANSPARENT);

	// Draw image on left side
	CImageList *piml = GetImageList();
	if (tci.iImage >= 0 && piml && piml->m_hImageList)
	{
		IMAGEINFO ii;
		piml->GetImageInfo(0, &ii);
		rect.left += bSelected ? 8 : 4;
		piml->Draw(pDC, tci.iImage, CPoint(rect.left, rect.top + 2), ILD_TRANSPARENT);
		rect.left += (ii.rcImage.right - ii.rcImage.left);
		if (!bSelected)
			rect.left += 4;
	}

	bool bCloseable = m_bCloseable;
	if (bCloseable && GetParent()->SendMessage(UM_QUERYTAB, nTabIndex))
		bCloseable = false;

	// Draw 'Close button' at right side
	if (bCloseable && m_ImgLstCloseButton.m_hImageList)
	{
		CRect rcCloseButton;
		GetCloseButtonRect(nTabIndex, rect, rcCloseButton, bSelected, bVistaThemeActive);

		HTHEME hThemeNC = bVistaThemeActive ? OpenThemeData(m_hWnd, _T("WINDOW")) : NULL;
		if (hThemeNC) {
			// Possible "Close" parts: WP_CLOSEBUTTON, WP_SMALLCLOSEBUTTON, WP_MDICLOSEBUTTON
			int iPartId = WP_SMALLCLOSEBUTTON;
			int iStateId = (bSelected || bVistaHotTracked) ? CBS_NORMAL : CBS_DISABLED;
			if (IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId))
				DrawThemeParentBackground(m_hWnd, *pDC, &rcCloseButton);
			DrawThemeBackground(hThemeNC, *pDC, iPartId, iStateId, rcCloseButton, NULL);
			CloseThemeData(hThemeNC);
		}
		else {
			m_ImgLstCloseButton.Draw(pDC, (bSelected || bVistaHotTracked) ? 0 : 1, rcCloseButton.TopLeft(), ILD_TRANSPARENT);
		}

		rect.right = rcCloseButton.left - 2;
		if (bSelected)
			rect.left += hTheme ? 4 : 2;
	}

	COLORREF crOldColor = CLR_NONE;
	if (tci.dwState & TCIS_HIGHLIGHTED)
		crOldColor = pDC->SetTextColor(RGB(192, 0, 0));
	else if (bVistaHotTracked)
		crOldColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));

	rect.top += bSelected ? 4 : 3;
	// Vista: Tab control has troubles with determining the width of a tab if the
	// label contains one '&' character. To get around this, we use the old code which
	// replaces one '&' character with two '&' characters and we do not specify DT_NOPREFIX
	// here when drawing the text.
	//
	// Vista: "DrawThemeText" can not be used in case we need a certain foreground color. Thus we always us
	// "DrawText" to always get the same font and metrics (just for safety).
	pDC->DrawText(szLabel, rect, DT_SINGLELINE | DT_TOP | DT_CENTER /*| DT_NOPREFIX*/);

	if (crOldColor != CLR_NONE)
		pDC->SetTextColor(crOldColor);
	pDC->SetBkMode(iOldBkMode);

	if (hTheme)
	{
		CRect rcClip(rcFullItem);
		if (bSelected) {
			rcClip.left -= 2 + 1;
			rcClip.right += 2 + 1;
		}
		else {
			rcClip.top += 2;
		}
		pDC->ExcludeClipRect(&rcClip);
		CloseThemeData(hTheme);
	}
}
Esempio n. 23
0
void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext)
{
    HTHEME hTheme;
    RECT rcWindow;
    HRGN hrgn, hrgn1;
    int CaptionHeight, iPart;
    WINDOWINFO wi;

    if(!IsAppThemed())
    {
        if(pcontext->HasThemeRgn)
        {
            pcontext->HasThemeRgn = FALSE;
            user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
        }
        return;
    }

    wi.cbSize = sizeof(wi);

    GetWindowInfo(hWnd, &wi);
            
    if((wi.dwStyle & WS_CAPTION)!=WS_CAPTION)
    {
        return;
    }

    /* Get the caption part id */
    if (wi.dwExStyle & WS_EX_TOOLWINDOW)
        iPart = WP_SMALLCAPTION;
    else if (wi.dwStyle & WS_MAXIMIZE)
        iPart = WP_MAXCAPTION;
    else
        iPart = WP_CAPTION;

    pcontext->HasThemeRgn = TRUE;

    CaptionHeight = wi.cyWindowBorders;
    CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );

    GetWindowRect(hWnd, &rcWindow);
    rcWindow.right -= rcWindow.left;
    rcWindow.bottom = CaptionHeight;
    rcWindow.top = 0;
    rcWindow.left = 0;

    hTheme = OpenThemeData (hWnd, L"WINDOW");

    GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);

    CloseThemeData(hTheme);

    GetWindowRect(hWnd, &rcWindow);
    rcWindow.right -= rcWindow.left;
    rcWindow.bottom -= rcWindow.top;
    rcWindow.top = CaptionHeight;
    rcWindow.left = 0;
    hrgn1 = CreateRectRgnIndirect(&rcWindow);

    CombineRgn(hrgn, hrgn, hrgn1, RGN_OR );

    DeleteObject(hrgn1);

    user32ApiHook.SetWindowRgn(hWnd, hrgn, TRUE);
}
LRESULT album_list_window::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{

	switch (msg)
	{
	case WM_CREATE:
	{
		list_wnd.add_item(this);

		initialised = true;

		modeless_dialog_manager::g_add(wnd);

		m_dd_theme = IsThemeActive() && IsAppThemed() ? OpenThemeData(wnd, VSCLASS_DRAGDROP) : NULL;

		create_tree();
		create_filter();

		if (cfg_populate) refresh_tree();

		static_api_ptr_t<library_manager_v3>()->register_callback(this);
	}
	break;
	case WM_THEMECHANGED:
	{
		if (m_dd_theme) CloseThemeData(m_dd_theme);
		m_dd_theme = IsThemeActive() && IsAppThemed() ? OpenThemeData(wnd, VSCLASS_DRAGDROP) : NULL;
	}
	break;
	/*case WM_GETMINMAXINFO:
	{
	LPMINMAXINFO mmi = LPMINMAXINFO(lp);
	mmi->ptMinTrackSize.y = cfg_height;
	return 0;
	}*/
	case WM_SIZE:
		on_size(LOWORD(lp), HIWORD(lp));
		break;
		/*	case DM_GETDEFID:
		return (DC_HASDEFID<<16|IDOK);
		case WM_GETDLGCODE:
		return DLGC_DEFPUSHBUTTON;*/
		//		break;
	case WM_TIMER:
		if (wp == EDIT_TIMER_ID)
		{
			refresh_tree();
			KillTimer(wnd, wp);
			m_timer = false;
		}
		break;
	case WM_COMMAND:
		switch (wp)
		{
		case IDC_FILTER | (EN_CHANGE << 16) :
			if (m_timer)
				KillTimer(wnd_edit, 500);
			m_timer = SetTimer(wnd, EDIT_TIMER_ID, 500, NULL) != 0;
			return TRUE;
		case IDOK:
			if (GetKeyState(VK_SHIFT) & KF_UP) do_playlist(p_selection, false);
			else if (GetKeyState(VK_CONTROL) & KF_UP) do_playlist(p_selection, true, true);
			else do_playlist(p_selection, true);
			return 0;
		}
		break;
	case WM_CONTEXTMENU:
	{
		enum { ID_SEND = 1, ID_ADD, ID_NEW, ID_AUTOSEND, ID_REFRESH, ID_FILT, ID_CONF, ID_VIEW_BASE };

		HMENU menu = CreatePopupMenu();

		POINT pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
		service_ptr_t<contextmenu_manager> p_menu_manager;

		unsigned IDM_MANAGER_BASE = 0;

		HWND list = wnd_tv;

		HTREEITEM treeitem = NULL;

		TVHITTESTINFO ti;
		memset(&ti, 0, sizeof(ti));

		if (pt.x != -1 && pt.y != -1)
		{
			ti.pt = pt;
			ScreenToClient(list, &ti.pt);
			uSendMessage(list, TVM_HITTEST, 0, (long)&ti);
			if (ti.hItem && (ti.flags & TVHT_ONITEM))
			{
				//FIX THIS AND AUTOSEND
				//TreeView_Select(list, ti.hItem, TVGN_DROPHILITE);
				//uSendMessage(list,TVM_SELECTITEM,TVGN_DROPHILITE,(long)ti.hItem);
				treeitem = ti.hItem;
			}
		}
		else
		{
			treeitem = TreeView_GetSelection(list);
			RECT rc;
			if (treeitem && TreeView_GetItemRect(wnd_tv, treeitem, &rc, TRUE))
			{
				MapWindowPoints(wnd_tv, HWND_DESKTOP, (LPPOINT)&rc, 2);

				pt.x = rc.left;
				pt.y = rc.top + (rc.bottom - rc.top) / 2;

			}
			else
			{
				GetMessagePos(&pt);
			}
		}

		TreeView_Select(list, treeitem, TVGN_DROPHILITE);

		HMENU menu_view = CreatePopupMenu();
		unsigned n, m = cfg_view_list.get_count();
		string8_fastalloc temp;
		temp.prealloc(32);

		uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(directory_structure_view_name, view) ? MF_CHECKED : 0), ID_VIEW_BASE + 0, directory_structure_view_name);

		list_t<string_simple, pfc::alloc_fast> views;

		views.add_item(string_simple(directory_structure_view_name));

		for (n = 0; n<m; n++)
		{
			temp = cfg_view_list.get_name(n);
			string_simple item(temp.get_ptr());

			if (item)
			{
				uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(temp, view) ? MF_CHECKED : 0), ID_VIEW_BASE + views.add_item(item), temp);
			}

		}


		IDM_MANAGER_BASE = ID_VIEW_BASE + views.get_count();

		uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)menu_view, "View");

		if (!m_populated && !cfg_populate)
			uAppendMenu(menu, MF_STRING, ID_REFRESH, "Populate");
		uAppendMenu(menu, MF_STRING | (m_filter ? MF_CHECKED : 0), ID_FILT, "Filter");
		uAppendMenu(menu, MF_STRING, ID_CONF, "Settings");

		bool show_shortcuts = standard_config_objects::query_show_keyboard_shortcuts_in_menus();

		node * p_node = NULL;
		TVITEMEX tvi;
		memset(&tvi, 0, sizeof(tvi));
		tvi.hItem = treeitem;
		tvi.mask = TVIF_HANDLE | TVIF_PARAM;
		TreeView_GetItem(list, &tvi);
		p_node = (node*)tvi.lParam;

		if (treeitem && p_node)
		{
			uAppendMenu(menu, MF_SEPARATOR, 0, "");
			uAppendMenu(menu, MF_STRING, ID_SEND, (show_shortcuts ? "&Send to playlist\tEnter" : "&Send to playlist"));
			uAppendMenu(menu, MF_STRING, ID_ADD, show_shortcuts ? "&Add to playlist\tShift+Enter" : "&Add to playlist");
			uAppendMenu(menu, MF_STRING, ID_NEW, show_shortcuts ? "Send to &new playlist\tCtrl+Enter" : "Send to &new playlist");
			uAppendMenu(menu, MF_STRING, ID_AUTOSEND, "Send to &autosend playlist");

			uAppendMenu(menu, MF_SEPARATOR, 0, "");

			contextmenu_manager::g_create(p_menu_manager);
			p_node->sort_entries();

			if (p_menu_manager.is_valid())
			{
				p_menu_manager->init_context(p_node->get_entries(), 0);

				p_menu_manager->win32_build_menu(menu, IDM_MANAGER_BASE, -1);
				menu_helpers::win32_auto_mnemonics(menu);
			}
		}

		int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, get_wnd(), 0);
		DestroyMenu(menu);

		TreeView_Select(list, NULL, TVGN_DROPHILITE);

		if (cmd)
		{
			if (p_menu_manager.is_valid() && (unsigned)cmd >= IDM_MANAGER_BASE)
			{
				p_menu_manager->execute_by_id(cmd - IDM_MANAGER_BASE);
			}
			else if (cmd >= ID_VIEW_BASE)
			{
				unsigned n = cmd - ID_VIEW_BASE;
				if (n<views.get_count())
				{
					view = views[n].get_ptr();
					refresh_tree();
				}
			}
			else if (cmd<ID_VIEW_BASE)
			{
				unsigned cmd2 = 0;
				switch (cmd)
				{
				case ID_NEW:
					do_playlist(p_node, true, true);
					break;
				case ID_SEND:
					do_playlist(p_node, true);
					break;
				case ID_ADD:
					do_playlist(p_node, false);
					break;
				case ID_AUTOSEND:
					do_autosend_playlist(p_node, view, true);
					break;
				case ID_CONF:
				{
					static_api_ptr_t<ui_control>()->show_preferences(g_guid_preferences_album_list_panel);
				}
				break;
				case ID_FILT:
				{
					m_filter = !m_filter;
					create_or_destroy_filter();
				}
				break;
				case ID_REFRESH:
					if (!m_populated && !cfg_populate)
						refresh_tree();
					break;
				}
				if (cmd2) uSendMessage(get_wnd(), WM_COMMAND, cmd2, 0);
			}
		}

		p_menu_manager.release();

		/*			if (treeitem_context && (treeitem_context != treeitem) && cfg_autosend)
		TreeView_SelectItem(wnd_tv,treeitem);*/


	}
	return 0;
	case WM_NOTIFY:
	{
		LPNMHDR hdr = (LPNMHDR)lp;

		switch (hdr->idFrom)
		{

		case IDC_TREE:
		{
			if (hdr->code == TVN_ITEMEXPANDING)
			{
				LPNMTREEVIEW param = (LPNMTREEVIEW)hdr;
				if (cfg_picmixer && (param->action == TVE_EXPAND))
				{
					TreeView_CollapseOtherNodes(param->hdr.hwndFrom, param->itemNew.hItem);
				}
			}

			else if (hdr->code == TVN_SELCHANGED)
			{
				LPNMTREEVIEW param = (LPNMTREEVIEW)hdr;

				p_selection = (node*)param->itemNew.lParam;
				if ((param->action == TVC_BYMOUSE || param->action == TVC_BYKEYBOARD))
				{
					if (cfg_autosend)
						do_autosend_playlist(p_selection, view);
				}
				if (m_selection_holder.is_valid())
				{
					m_selection_holder->set_selection(p_selection.is_valid() ? p_selection->get_entries() : metadb_handle_list());
				}
#if 0
				if (cfg_picmixer)
				{
					HTREEITEM ti_parent_old = TreeView_GetParent(param->hdr.hwndFrom, param->itemOld.hItem);
					HTREEITEM ti_parent_new = TreeView_GetParent(param->hdr.hwndFrom, param->itemNew.hItem);

					if (/*ti_parent_old != param->itemNew.hItem &&  */!TreeView_IsChild(param->hdr.hwndFrom, param->itemNew.hItem, param->itemOld.hItem))
					{
						HTREEITEM ti = //TreeView_GetLevel(param->hdr.hwndFrom, param->itemNew.hItem) < TreeView_GetLevel(param->hdr.hwndFrom, param->itemOld.hItem) ? 
							TreeView_GetCommonParentChild(param->hdr.hwndFrom, param->itemOld.hItem, param->itemNew.hItem)
							//: param->itemOld.hItem
							;
						if (ti && ti != TVI_ROOT) TreeView_Expand(param->hdr.hwndFrom, ti, TVE_COLLAPSE);
					}

					if (ti_parent_new)
					{

						HTREEITEM child = TreeView_GetChild(param->hdr.hwndFrom, ti_parent_new);
						while (child)
						{
							if (child != param->itemNew.hItem)
							{

							}
						}
					}
				}
#endif
			}
		}
		break;
		}

	}
	break;
	case WM_DESTROY:
		static_api_ptr_t<library_manager_v3>()->unregister_callback(this);
		modeless_dialog_manager::g_remove(wnd);
		destroy_tree();
		destroy_filter();
		m_selection_holder.release();
		m_root.release();
		p_selection.release();
		if (m_dd_theme)
		{
			CloseThemeData(m_dd_theme);
			m_dd_theme = NULL;
		}

		if (initialised)
		{
			list_wnd.remove_item(this);
			if (list_wnd.get_count() == 0)
			{
				DeleteFont(g_font);
				g_font = 0;
			}
			initialised = false;
		}
		break;
	}
	return DefWindowProc(wnd, msg, wp, lp);
}
Esempio n. 25
0
LRESULT track_bar::on_message(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
{
    switch(msg)
    {
    case WM_NCCREATE:
        break;
    case WM_CREATE:
    {
        if (IsThemeActive() && IsAppThemed())
        {
            m_theme = OpenThemeData(wnd, L"Trackbar");
        }
    }
    break;
    case WM_THEMECHANGED:
    {
        {
            if (m_theme)
            {
                CloseThemeData(m_theme);
                m_theme=0;
            }
            if (IsThemeActive() && IsAppThemed())
                m_theme = OpenThemeData(wnd, L"Trackbar");
        }
    }
    break;
    case WM_DESTROY:
    {
        if (m_hook_registered)
        {
            message_hook_manager::deregister_hook(message_hook_manager::type_keyboard, this);
            m_hook_registered=false;
        }
        {
            if (m_theme) CloseThemeData(m_theme);
            m_theme=0;
        }
    }
    break;
    case WM_NCDESTROY:
        break;
    case WM_SIZE:
        RedrawWindow(wnd, 0, 0, RDW_INVALIDATE|RDW_ERASE);
        break;
    case WM_MOUSEMOVE:
    {

        POINT pt = {GET_X_LPARAM(lp), GET_Y_LPARAM(lp)};
        if (m_dragging)
        {
            if (!m_last_mousemove.m_valid || wp != m_last_mousemove.m_wp || lp != m_last_mousemove.m_lp)
            {
                if (get_enabled())
                {
                    unsigned pos = calculate_position_from_point(pt);
                    set_position_internal(pos);
                    if (m_wnd_tooltip && m_host)
                    {
                        POINT pts = pt;
                        ClientToScreen(wnd, &pts);
                        track_bar_string temp;
                        m_host->get_tooltip_text(pos, temp);
                        update_tooltip(pts, temp.data());
                    }
                    if (m_host)
                        m_host->on_position_change(pos, true);
                }
            }
            m_last_mousemove.m_valid = true;
            m_last_mousemove.m_wp = wp;
            m_last_mousemove.m_lp = lp;
        }
        else
        {
            update_hot_status(pt);
        }
    }
    break;
    case WM_ENABLE:
    {
        RECT rc;
        get_thumb_rect(&rc);
        InvalidateRect(wnd, &rc, TRUE);
    }
    break;
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_XBUTTONDOWN:
    {
        if (get_enabled() && get_auto_focus() && GetFocus() != wnd)
            SetFocus(wnd);

        if (m_dragging)
        {
            destroy_tooltip();
            if (GetCapture() == wnd)
                ReleaseCapture();
            message_hook_manager::deregister_hook(message_hook_manager::type_keyboard, this);
            m_hook_registered=false;
            //SetFocus(IsWindow(m_wnd_prev) ? m_wnd_prev : uFindParentPopup(wnd));
            m_dragging = false;
            set_position_internal(m_position);
        }
    }
    break;
    case WM_LBUTTONDOWN:
    {
        if (get_enabled())
        {
            if (get_auto_focus() && GetFocus() != wnd)
                SetFocus(wnd);

            POINT pt;

            pt.x = GET_X_LPARAM(lp);
            pt.y = GET_Y_LPARAM(lp);

            RECT rc_client;
            GetClientRect(wnd, &rc_client);

            if (PtInRect(&rc_client, pt))
            {
                m_dragging = true;
                SetCapture(wnd);

                //SetFocus(wnd);
                message_hook_manager::register_hook(message_hook_manager::type_keyboard, this);
                m_hook_registered=true;

                unsigned pos = calculate_position_from_point(pt);
                set_position_internal(pos);
                POINT pts = pt;
                ClientToScreen(wnd, &pts);
                if (m_show_tooltips && m_host)
                {
                    track_bar_string temp;
                    m_host->get_tooltip_text(pos, temp);
                    create_tooltip(temp.data(), pts);
                }
            }
            m_last_mousemove.m_valid = false;
        }
    }
    return 0;
    case WM_LBUTTONUP:
    {
        if (m_dragging)
        {
            destroy_tooltip();
            if (GetCapture() == wnd)
                ReleaseCapture();
            m_dragging = false;
            if (get_enabled())
            {
                POINT pt;

                pt.x = GET_X_LPARAM(lp);
                pt.y = GET_Y_LPARAM(lp);

                unsigned pos = calculate_position_from_point(pt);
                set_position(pos);
            }
            //SetFocus(IsWindow(m_wnd_prev) ? m_wnd_prev : uFindParentPopup(wnd));
            message_hook_manager::deregister_hook(message_hook_manager::type_keyboard, this);
            m_hook_registered = false;
            if (m_host)
                m_host->on_position_change(m_display_position, false);

            m_last_mousemove.m_valid = false;
        }
    }
    return 0;
    case WM_KEYDOWN:
    case WM_KEYUP:
    {
        if ((wp == VK_ESCAPE || wp == VK_RETURN) && m_host && m_host->on_key(wp, lp))
            return 0;
        if ( !(lp & (1<<31)) && (wp == VK_LEFT || wp == VK_DOWN || wp == VK_RIGHT || wp == VK_UP))
        {
            bool down = (wp == VK_LEFT || wp == VK_UP) == false;//!get_direction();
            unsigned newpos = m_position;
            if (down && m_step > m_position)
                newpos = 0;
            else if (!down && m_step + m_position > m_range)
                newpos = m_range;
            else
                newpos += down ? -(int)m_step : m_step;
            if (newpos != m_position)
            {
                set_position(newpos);
                if (m_host)
                    m_host->on_position_change(m_position, false);
            }
        }
        if ( !(lp & (1<<31)) && (wp == VK_HOME || wp == VK_END))
        {
            bool down = (wp == VK_END) == false;//!get_direction();
            unsigned newpos = m_position;
            if (down) newpos = m_range;
            else newpos = 0;
            if (newpos != m_position)
            {
                set_position(newpos);
                if (m_host)
                    m_host->on_position_change(m_position, false);
            }
        }
    }
    break;
    case WM_MOUSEWHEEL:
    {
        UINT ucNumLines=3;  // 3 is the default
        SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &ucNumLines, 0);
        unsigned short fwKeys = GET_KEYSTATE_WPARAM(wp);
        short zDelta = GET_WHEEL_DELTA_WPARAM(wp);
        int xPos = GET_X_LPARAM(lp);
        int yPos = GET_Y_LPARAM(lp);
        if (ucNumLines == WHEEL_PAGESCROLL)
            ucNumLines = 3;
        int delta = MulDiv(m_step*zDelta, ucNumLines, WHEEL_DELTA);
        bool down = delta < 0;
        //if (get_direction()) down = down == false;
        if (!get_orientation()) down = down == false;
        if (m_mouse_wheel_reversed)
            down = down == false;
        unsigned offset = abs(delta);

        unsigned newpos = m_position;
        if (down && offset > m_position)
            newpos = 0;
        else if (!down && offset + m_position > m_range)
            newpos = m_range;
        else
            newpos += down ? -(int)offset : offset;
        if (newpos != m_position)
        {
            set_position(newpos);
            if (m_host)
                m_host->on_position_change(m_position, false);
        }
    }
    return 0;
#if 0
    case WM_KEYDOWN:
        if (wp == VK_ESCAPE)
        {
            destroy_tooltip();
            if (GetCapture() == wnd)
                ReleaseCapture();
            SetFocus(IsWindow(m_wnd_prev) ? m_wnd_prev : uFindParentPopup(wnd));
            m_dragging = false;
            set_position_internal(m_position);
            return 0;
        }
        break;
    case WM_SETFOCUS:
        m_wnd_prev = (HWND)wp;
        break;
#endif
    case WM_MOVE:
        RedrawWindow(wnd, NULL, NULL, RDW_ERASE|RDW_INVALIDATE);
        break;
    case WM_ERASEBKGND:
        return FALSE;
    case WM_PAINT:
    {
        RECT rc_client;
        GetClientRect(wnd, &rc_client);

        PAINTSTRUCT ps;

        HDC dc = BeginPaint(wnd, &ps);

        RECT rc_thumb;

        get_thumb_rect(&rc_thumb);

        RECT rc_track; //channel
        get_channel_rect(&rc_track);

        //Offscreen rendering to eliminate flicker
        HDC dc_mem = CreateCompatibleDC(dc);

        //Create a rect same size of update rect
        HBITMAP bm_mem = CreateCompatibleBitmap(dc, rc_client.right, rc_client.bottom);

        HBITMAP bm_old = (HBITMAP)SelectObject(dc_mem, bm_mem);

        //we should always be erasing first, so shouldn't be needed
        BitBlt(dc_mem, 0, 0, rc_client.right, rc_client.bottom, dc, 0, 0, SRCCOPY);
        if (ps.fErase)
        {
            draw_background(dc_mem, &rc_client);
        }

        draw_channel(dc_mem, &rc_track);
        draw_thumb(dc_mem, &rc_thumb);

        BitBlt(dc, 0, 0, rc_client.right, rc_client.bottom, dc_mem, 0, 0, SRCCOPY);
        SelectObject(dc_mem, bm_old);
        DeleteObject(bm_mem);
        DeleteDC(dc_mem);
        EndPaint(wnd, &ps);
    }
    return 0;

    }
    return DefWindowProc(wnd, msg, wp, lp);
}