Example #1
0
//绘制发光文字
void DrawGlowingText(HDC hDC, int IDC)
{
	HWND hWnd = GetDlgItem(g_hMainWnd, IDC);
	char szText[128] = {0};
	GetWindowText(hWnd, szText, 128);

	RECT rcArea;
	GetWindowRect(hWnd, &rcArea);

	DWORD dwTextFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
	int iGlowSize = 10;

	//获取主题句柄
	HTHEME hThm = OpenThemeData(GetDesktopWindow(), L"TextStyle");
	//创建DIB
	HDC hMemDC = CreateCompatibleDC(hDC);
	BITMAPINFO bmpinfo = {0};
	bmpinfo.bmiHeader.biSize = sizeof(bmpinfo.bmiHeader);
	bmpinfo.bmiHeader.biBitCount = 32;
	bmpinfo.bmiHeader.biCompression = BI_RGB;
	bmpinfo.bmiHeader.biPlanes = 1;
	bmpinfo.bmiHeader.biWidth = rcArea.right - rcArea.left;
	bmpinfo.bmiHeader.biHeight = -(rcArea.bottom - rcArea.top);
	HBITMAP hBmp = CreateDIBSection(hMemDC, &bmpinfo, DIB_RGB_COLORS, 0, NULL, 0);
	if (hBmp == NULL) return;
	HGDIOBJ hBmpOld = SelectObject(hMemDC, hBmp);
	//绘制选项
	DTTOPTS dttopts = {0};
	dttopts.dwSize = sizeof(DTTOPTS);
	dttopts.dwFlags = DTT_GLOWSIZE | DTT_COMPOSITED;
	dttopts.iGlowSize = iGlowSize;	//发光的范围大小
	//绘制文本
	RECT rc = {0, 0, rcArea.right - rcArea.left, rcArea.bottom - rcArea.top};

	DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, szText, -1, NULL, 0);
	wchar_t *pwText;
	pwText = new wchar_t[dwNum];
	MultiByteToWideChar (CP_ACP, 0, szText, -1, pwText, dwNum);

	HRESULT hr = DrawThemeTextEx(hThm, hMemDC, TEXT_LABEL, 0, pwText, -1, dwTextFlags , &rc, &dttopts);
	if(FAILED(hr)) return;
	BitBlt(hDC, rcArea.left, rcArea.top, rcArea.right - rcArea.left, 
		rcArea.bottom - rcArea.top, hMemDC, 0, 0, SRCCOPY | CAPTUREBLT);
	//Clear
	SelectObject(hMemDC, hBmpOld);
	DeleteObject(hBmp);
	DeleteDC(hMemDC);
	CloseThemeData(hThm);
}
Example #2
0
void LTIndefProgressBar::OnDestroy()
{
	KillTimer(PROGRESS_TIMER);
	CWnd::OnDestroy();

	CloseThemeData(h_ThemeBar);
	h_ThemeBar = 0;

	delete p_BarBack;
	delete p_BarSlot;
	p_BarSlot = NULL;
	p_BarBack = NULL;

	// TODO: Add your message handler code here
}
Example #3
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;
  }
}
Example #4
0
HIMAGELIST makeCheckboxImageList(HWND hwnddc, HTHEME *theme)
{
	if (*theme != NULL) {
		HRESULT res;

		res = CloseThemeData(*theme);
		if (res != S_OK)
			xpanichresult("error closing theme", res);
		*theme = NULL;
	}
	// ignore error; if it can't be done, we can fall back to DrawFrameControl()
	if (*theme == NULL)		// try to open the theme
		*theme = OpenThemeData(hwnddc, L"button");
	if (*theme != NULL)		// use the theme
		return newCheckboxImageList(hwnddc, themeSize, themeImage, *theme);
	// couldn't open; fall back
	return newCheckboxImageList(hwnddc, dfcSize, dfcImage, *theme);
}
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);
	}
}
Example #6
0
 void cleanup()
 {
     init_xp = FALSE;
     if ( use_xp ) {
         if ( !--ref ) {
             use_xp  = FALSE;
             delete limboWidget;
             limboWidget = 0;
             delete tabbody;
             tabbody = 0;
             if ( handleMap ) {
                 QMap<QString, HTHEME>::Iterator it;
                 for ( it = handleMap->begin(); it != handleMap->end(); ++it )
                     CloseThemeData( it.data() );
                 delete handleMap;
                 handleMap = 0;
             }
         }
     }
 }
VOID PhpSearchInitializeTheme(
    _Inout_ PEDIT_CONTEXT Context
    )
{
    Context->CXWidth = PH_SCALE_DPI(20);
    Context->BrushNormal = GetSysColorBrush(COLOR_WINDOW);
    Context->BrushHot = CreateSolidBrush(RGB(205, 232, 255));
    Context->BrushPushed = CreateSolidBrush(RGB(153, 209, 255));

    if (IsThemeActive())
    {
        HTHEME themeDataHandle;

        if (themeDataHandle = OpenThemeData(Context->WindowHandle, VSCLASS_EDIT))
        {
            //IsThemePartDefined_I(themeDataHandle, EP_EDITBORDER_NOSCROLL, EPSHV_NORMAL);

            if (!SUCCEEDED(GetThemeInt(
                themeDataHandle,
                EP_EDITBORDER_NOSCROLL,
                EPSHV_NORMAL,
                TMT_BORDERSIZE,
                &Context->CXBorder
                )))
            {
                Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
            }

            CloseThemeData(themeDataHandle);
        }
        else
        {
            Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
        }
    }
    else
    {
        Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
    }
}
Example #8
0
BOOL AeroControlBase::DetermineGlowSize(int *piSize, LPCWSTR pszClassIdList /*= NULL*/)
{
    if (!piSize)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (!pszClassIdList)
        pszClassIdList = L"CompositedWindow::Window";

    HTHEME hThemeWindow = OpenThemeData(NULL, pszClassIdList);
    if (hThemeWindow != NULL)
    {
        VERIFY(SUCCEEDED(GetThemeInt(hThemeWindow, 0, 0, TMT_TEXTGLOWSIZE, piSize)));
        VERIFY(SUCCEEDED(CloseThemeData(hThemeWindow)));
        return TRUE;
    }

    SetLastError(ERROR_FILE_NOT_FOUND);
    return FALSE;
}
/********************************************
DrawBackground
	Purpose
		Provides a more straightforward way to draw a background by wrapping all the calls required into the dll,
		as well as using our theme data mappings to find the core info required.
		This version still takes a theme name instead of using our lookup
		table, it's used in cases where we hard code the theme part ( such a progress bars )
	Params
		hwnd      - the HWND of the control we draw to, or NUL
		hdc       - the device context for the dll to draw to
		theme     - the name of the theme to use
		iPartId   - the theme part to draw
		iStateId  - the state of the part to draw
		pRect     - represents the area we want to draw to
		pClipRect - is exposed, but is almost always NULL
	Return
		A  bool to indicate success or failure, which is used to control drawing in the old style throughout the library
*********************************************/
bool UGXPThemes::DrawBackground(HWND hwnd, HDC hdc, LPCWSTR theme, int partID, 
		int stateID,  const RECT *pRect, const RECT *pClipRect, bool useCache)
{
	bool success = false;

	if (useThemes)
	{
		HANDLE themeHandle = OpenThemeData(hwnd, theme, useCache);

		if (themeHandle)
		{
			// If the background is transparent, we draw using the Data cell type first,
			// which fills the background.  DrawThemeParentBackground just plain does not work
			// for us, perhaps because the parent is an owner drawn control ?
			// Of course, if the Data cell type has transparency, this will fail.
			if (IsThemeBackgroundPartiallyTransparent(themeHandle, partID, stateID))
			{
				//RECT temp = *pRect;
				UGThemeData * tdCell = LookupThemeData(XPCellTypeData, ThemeStateNormal);

				HANDLE hThemeCell = OpenThemeData(hwnd, tdCell->GetThemeName());

				DrawThemeBackground(hThemeCell, hdc, partID, stateID, pRect, pClipRect);
			}

			HRESULT hr = DrawThemeBackground(themeHandle, hdc, partID, stateID, pRect, pClipRect);
			success = SUCCEEDED(hr);

			if (!useCache)
			{
				CloseThemeData(themeHandle);
			}
		}
	}

	return success;

}
Example #10
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);
}
Example #11
0
LRESULT AeroControlBase::ButtonWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_SETTEXT:
    case WM_ENABLE:
    case WM_STYLECHANGED:
        {
            LRESULT res = DefSubclassProc(hWnd, uMsg, wParam, lParam);
            InvalidateRgn(hWnd, NULL, FALSE);
            return res;
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            if(hdc)
            {
                LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
                LONG_PTR dwButtonStyle = LOWORD(dwStyle);
                LONG_PTR dwButtonType = dwButtonStyle&0xF;
                RECT rcClient;
                VERIFY(GetClientRect(hWnd, &rcClient));

                if((dwButtonType&BS_GROUPBOX)==BS_GROUPBOX)
                {
                    ///
                    /// it must be a group box
                    ///
                    HTHEME hTheme = OpenThemeData(hWnd, L"Button");
                    if(hTheme)
                    {
                        BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) };
                        params.dwFlags        = BPPF_ERASE;

                        RECT rcExclusion = rcClient;
                        params.prcExclude = &rcExclusion;

                        ///
                        /// We have to calculate the exclusion rect and therefore
                        /// calculate the font height. We select the control's font
                        /// into the DC and fake a drawing operation:
                        ///
                        HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL);
                        if(hFontOld)
                            hFontOld = (HFONT) SelectObject(hdc, hFontOld);

                        RECT rcDraw = rcClient;
                        DWORD dwFlags = DT_SINGLELINE;

                        ///
                        /// we use uppercase A to determine the height of text, so we
                        /// can draw the upper line of the groupbox:
                        ///
                        DrawTextW(hdc, L"A", -1,  &rcDraw, dwFlags|DT_CALCRECT);

                        if (hFontOld)
                        {
                            SelectObject(hdc, hFontOld);
                            hFontOld    = NULL;
                        }

                        VERIFY(InflateRect(&rcExclusion, -1, -1*RECTHEIGHT(rcDraw)));

                        HDC hdcPaint = NULL;
                        HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB,
                            &params, &hdcPaint);
                        if (hdcPaint)
                        {
                            ///
                            /// now we again retrieve the font, but this time we select it into
                            /// the buffered DC:
                            ///
                            hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL);
                            if(hFontOld)
                                hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld);


                            VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS));

                            VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00));
                            int iPartId = BP_GROUPBOX;

                            int iState = GetStateFromBtnState(dwStyle, FALSE, FALSE, 0L, iPartId, FALSE);

                            DTTOPTS DttOpts = {sizeof(DTTOPTS)};
                            DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
                            DttOpts.crText   = RGB(255, 255, 255);
                            DttOpts.iGlowSize = 12; // Default value

                            VERIFY(DetermineGlowSize(&DttOpts.iGlowSize));

                            COLORREF cr = RGB(0x00, 0x00, 0x00);
                            VERIFY(GetEditBorderColor(hWnd, &cr));
                            ///
                            /// add the alpha value:
                            ///
                            cr |= 0xff000000;

                            std::unique_ptr<Pen> myPen( new Pen(Color(cr), 1) );
                            std::unique_ptr<Graphics> myGraphics( new Graphics(hdcPaint) );
                            int iY = RECTHEIGHT(rcDraw)/2;
                            Rect rr = Rect(rcClient.left, rcClient.top+iY,
                                RECTWIDTH(rcClient), RECTHEIGHT(rcClient)-iY-1);
                            GraphicsPath path;
                            GetRoundRectPath(&path, rr, 10);
                            myGraphics->DrawPath(myPen.get(), &path);
                            //myGraphics->DrawRectangle(myPen, rcClient.left, rcClient.top + iY,
                            //  RECTWIDTH(rcClient)-1, RECTHEIGHT(rcClient) - iY-1);
                            myGraphics.reset();
                            myPen.reset();

                            int iLen = GetWindowTextLength(hWnd);

                            if(iLen)
                            {
                                iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING
                                LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen);
                                if(szText)
                                {
                                    iLen = GetWindowTextW(hWnd, szText, iLen);
                                    if(iLen)
                                    {
                                        int iX = RECTWIDTH(rcDraw);
                                        rcDraw = rcClient;
                                        rcDraw.left += iX;
                                        DrawTextW(hdcPaint, szText, -1,  &rcDraw, dwFlags|DT_CALCRECT);
                                        VERIFY(PatBlt(hdcPaint, rcDraw.left, rcDraw.top , RECTWIDTH(rcDraw) + 3, RECTHEIGHT(rcDraw), BLACKNESS));
                                        rcDraw.left++;
                                        rcDraw.right++;
                                        VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1,
                                            dwFlags, &rcDraw, &DttOpts));

                                    }

                                    VERIFY(!LocalFree(szText));
                                }
                            }

                            if (hFontOld)
                            {
                                SelectObject(hdcPaint, hFontOld);
                                hFontOld    = NULL;
                            }

                            VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE));

                        }

                        VERIFY(S_OK==CloseThemeData(hTheme));
                    }
                }

                else if(dwButtonType==BS_CHECKBOX || dwButtonType==BS_AUTOCHECKBOX ||
                    dwButtonType==BS_3STATE || dwButtonType==BS_AUTO3STATE || dwButtonType==BS_RADIOBUTTON || dwButtonType==BS_AUTORADIOBUTTON)
                {
                    HTHEME hTheme = OpenThemeData(hWnd, L"Button");
                    if(hTheme)
                    {
                        HDC hdcPaint = NULL;
                        BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) };
                        params.dwFlags        = BPPF_ERASE;
                        HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, &params, &hdcPaint);
                        if (hdcPaint)
                        {
                            VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS));

                            VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00));

                            LRESULT dwCheckState = SendMessage(hWnd, BM_GETCHECK, 0, NULL);
                            POINT pt;
                            RECT rc;
                            GetWindowRect(hWnd, &rc);
                            GetCursorPos(&pt);
                            BOOL bHot = PtInRect(&rc, pt);
                            BOOL bFocus = GetFocus()==hWnd;

                            int iPartId = BP_CHECKBOX;
                            if(dwButtonType==BS_RADIOBUTTON || dwButtonType==BS_AUTORADIOBUTTON)
                                iPartId = BP_RADIOBUTTON;

                            int iState = GetStateFromBtnState(dwStyle, bHot, bFocus, dwCheckState, iPartId, FALSE);

                            int bmWidth = int(ceil(13.0 * GetDeviceCaps(hdcPaint, LOGPIXELSX) / 96.0));

                            UINT uiHalfWidth = (RECTWIDTH(rcClient) - bmWidth)/2;

                            ///
                            /// we have to use the whole client area, otherwise we get only partially
                            /// drawn areas:
                            ///
                            RECT rcPaint = rcClient;

                            if(dwButtonStyle & BS_LEFTTEXT)
                            {
                                rcPaint.left += uiHalfWidth;
                                rcPaint.right += uiHalfWidth;
                            }
                            else
                            {
                                rcPaint.left -= uiHalfWidth;
                                rcPaint.right -= uiHalfWidth;
                            }


                            ///
                            /// we assume that bmWidth is both the horizontal and the vertical
                            /// dimension of the control bitmap and that it is square. bm.bmHeight
                            /// seems to be the height of a striped bitmap because it is an absurdly
                            /// high dimension value
                            ///
                            if((dwButtonStyle&BS_VCENTER)==BS_VCENTER) /// BS_VCENTER is BS_TOP|BS_BOTTOM
                            {
                                int h = RECTHEIGHT(rcPaint);
                                rcPaint.top = (h - bmWidth) / 2;
                                rcPaint.bottom = rcPaint.top + bmWidth;
                            }
                            else if(dwButtonStyle&BS_TOP)
                            {
                                rcPaint.bottom = rcPaint.top + bmWidth;
                            }
                            else if(dwButtonStyle&BS_BOTTOM)
                            {
                                rcPaint.top =  rcPaint.bottom - bmWidth;
                            }
                            else // default: center the checkbox/radiobutton vertically
                            {
                                int h = RECTHEIGHT(rcPaint);
                                rcPaint.top = (h - bmWidth) / 2;
                                rcPaint.bottom = rcPaint.top + bmWidth;
                            }


                            VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL));
                            rcPaint = rcClient;


                            VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc));

                            if(dwButtonStyle & BS_LEFTTEXT)
                                rc.right -= bmWidth + 2 * GetSystemMetrics(SM_CXEDGE);
                            else
                                rc.left += bmWidth + 2 * GetSystemMetrics(SM_CXEDGE);

                            DTTOPTS DttOpts = {sizeof(DTTOPTS)};
                            DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
                            DttOpts.crText   = RGB(255, 255, 255);
                            DttOpts.iGlowSize = 12; // Default value

                            VERIFY(DetermineGlowSize(&DttOpts.iGlowSize));


                            HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL);
                            if(hFontOld)
                                hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld);
                            int iLen = GetWindowTextLength(hWnd);

                            if(iLen)
                            {
                                iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING
                                LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen);
                                if(szText)
                                {
                                    iLen = GetWindowTextW(hWnd, szText, iLen);
                                    if(iLen)
                                    {
                                        DWORD dwFlags = DT_SINGLELINE /*|DT_VCENTER*/;
                                        if(dwButtonStyle&BS_MULTILINE)
                                        {
                                            dwFlags|=DT_WORDBREAK;
                                            dwFlags&= ~(DT_SINGLELINE |DT_VCENTER);
                                        }

                                        if((dwButtonStyle&BS_CENTER)==BS_CENTER) /// BS_CENTER is BS_LEFT|BS_RIGHT
                                            dwFlags|=DT_CENTER;
                                        else if(dwButtonStyle&BS_LEFT)
                                            dwFlags|=DT_LEFT;
                                        else if(dwButtonStyle&BS_RIGHT)
                                            dwFlags|=DT_RIGHT;


                                        if((dwButtonStyle&BS_VCENTER)==BS_VCENTER) /// BS_VCENTER is BS_TOP|BS_BOTTOM
                                            dwFlags|=DT_VCENTER;
                                        else if(dwButtonStyle&BS_TOP)
                                            dwFlags|=DT_TOP;
                                        else if(dwButtonStyle&BS_BOTTOM)
                                            dwFlags|=DT_BOTTOM;
                                        else
                                            dwFlags|=DT_VCENTER;

                                        VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId,
                                            iState, szText, -1, dwFlags, &rc, &DttOpts));

                                        ///
                                        /// if our control has the focus, we also have to draw the focus rectangle:
                                        ///
                                        if(bFocus)
                                        {
                                            ///
                                            /// now calculate the text size:
                                            ///
                                            RECT rcDraw = rc;

                                            ///
                                            /// we use GDI's good old DrawText, because it returns much more
                                            /// accurate data than DrawThemeTextEx, which takes the glow
                                            /// into account which we don't want:
                                            ///
                                            VERIFY(DrawTextW(hdcPaint, szText, -1,  &rcDraw, dwFlags|DT_CALCRECT));
                                            if(dwFlags&DT_SINGLELINE)
                                            {
                                                dwFlags &= ~DT_VCENTER;
                                                RECT rcDrawTop;
                                                DrawTextW(hdcPaint, szText, -1,  &rcDrawTop, dwFlags|DT_CALCRECT);
                                                rcDraw.top = rcDraw.bottom - RECTHEIGHT(rcDrawTop);
                                            }

                                            if(dwFlags & DT_RIGHT)
                                            {
                                                int iWidth = RECTWIDTH(rcDraw);
                                                rcDraw.right = rc.right;
                                                rcDraw.left = rcDraw.right - iWidth;
                                            }

                                            RECT rcFocus;
                                            VERIFY(IntersectRect(&rcFocus, &rc, &rcDraw));

                                            DrawFocusRect(&rcFocus, hdcPaint);
                                        }
                                    }

                                    VERIFY(!LocalFree(szText));
                                }
                            }

                            if (hFontOld)
                            {
                                SelectObject(hdcPaint, hFontOld);
                                hFontOld    = NULL;
                            }

                            VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE));
                        }
                        VERIFY(S_OK==CloseThemeData(hTheme));
                    }


                }
                else if(BS_PUSHBUTTON==dwButtonType || BS_DEFPUSHBUTTON==dwButtonType)
                {
                    ///
                    /// it is a push button
                    ///
                    HTHEME hTheme = OpenThemeData(hWnd, L"Button");
                    if(hTheme)
                    {
                        HDC hdcPaint = NULL;
                        BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) };
                        params.dwFlags        = BPPF_ERASE;
                        HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, &params, &hdcPaint);
                        if (hdcPaint)
                        {
                            VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS));

                            VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00));

                            LRESULT dwCheckState = SendMessage(hWnd, BM_GETCHECK, 0, NULL);
                            POINT pt;
                            RECT rc;
                            GetWindowRect(hWnd, &rc);
                            GetCursorPos(&pt);
                            BOOL bHot = PtInRect(&rc, pt);
                            BOOL bFocus = GetFocus()==hWnd;
                            int iPartId = BP_PUSHBUTTON;

                            if(dwButtonStyle==BS_RADIOBUTTON || dwButtonStyle==BS_AUTORADIOBUTTON)
                                iPartId = BP_RADIOBUTTON;


                            int iState = GetStateFromBtnState(dwStyle, bHot, bFocus, dwCheckState, iPartId, GetCapture()==hWnd);

                            ///
                            /// we have to use the whole client area, otherwise we get only partially
                            /// drawn areas:
                            ///
                            RECT rcPaint = rcClient;
                            VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL));


                            VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc));


                            DTTOPTS DttOpts = {sizeof(DTTOPTS)};
                            DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
                            DttOpts.crText   = RGB(255, 255, 255);
                            DttOpts.iGlowSize = 12; // Default value

                            VERIFY(DetermineGlowSize(&DttOpts.iGlowSize));


                            HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL);
                            if(hFontOld)
                                hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld);
                            int iLen = GetWindowTextLength(hWnd);

                            if(iLen)
                            {
                                iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING
                                LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen);
                                if(szText)
                                {
                                    iLen = GetWindowTextW(hWnd, szText, iLen);
                                    if(iLen)
                                    {
                                        DWORD dwFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER;
                                        VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint,
                                            iPartId, iState, szText, -1, dwFlags, &rc, &DttOpts));

                                        ///
                                        /// if our control has the focus, we also have to draw the focus rectangle:
                                        ///
                                        if(bFocus)
                                        {
                                            RECT rcDraw = rcClient;
                                            VERIFY(InflateRect(&rcDraw, -3, -3));
                                            DrawFocusRect(&rcDraw, hdcPaint);
                                        }

                                    }

                                    VERIFY(!LocalFree(szText));
                                }
                            }

                            if (hFontOld)
                            {
                                SelectObject(hdcPaint, hFontOld);
                                hFontOld    = NULL;
                            }

                            VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE));
                        }
                        VERIFY(S_OK==CloseThemeData(hTheme));
                    }
                }
                else
                    //PaintControl(hWnd, hdc, &ps.rcPaint, (m_dwFlags & WD_DRAW_BORDER)!=0);
                    PaintControl(hWnd, hdc, &ps.rcPaint, false);
            }

            EndPaint(hWnd, &ps);
            return 0;
        }
        break;
    case WM_DESTROY:
    case WM_NCDESTROY:
        RemoveWindowSubclass(hWnd, SubclassProc, Button);
        subclassedControls.erase(hWnd);
        break;
    }

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
Example #12
0
LRESULT AeroControlBase::StaticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SETTEXT:
    case WM_ENABLE:
    case WM_STYLECHANGED:
        {
            LRESULT res = DefSubclassProc(hWnd, uMsg, wParam, lParam);
            InvalidateRgn(hWnd, NULL, FALSE);
            return res;
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            if(hdc)
            {
                HDC hdcPaint = NULL;
                RECT rcClient;
                VERIFY(GetClientRect(hWnd, &rcClient));

                LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
                LONG_PTR dwStyleEx = GetWindowLongPtr(hWnd, GWL_EXSTYLE);

                HTHEME hTheme = OpenThemeData(NULL, L"ControlPanelStyle");
                if(hTheme)
                {
                    HPAINTBUFFER hBufferedPaint = NULL;
                    if (dwStyleEx & WS_EX_TRANSPARENT)
                    {
                        BP_PAINTPARAMS paintParams = {0};
                        paintParams.cbSize = sizeof(paintParams);
                        paintParams.dwFlags = BPPF_ERASE;
                        BLENDFUNCTION blendf = {0};
                        blendf.BlendOp = AC_SRC_OVER;
                        blendf.AlphaFormat = AC_SRC_ALPHA;
                        blendf.SourceConstantAlpha = 255;
                        paintParams.pBlendFunction = &blendf;
                        hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, &paintParams, &hdcPaint);
                    }
                    else
                        hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, NULL, &hdcPaint);

                    if (hdcPaint)
                    {
                        VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS));
                        VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00));
                        LONG_PTR dwStaticStyle = dwStyle&0x1F;


                        if(dwStaticStyle==SS_ICON || dwStaticStyle==SS_BITMAP)
                        {
                            bool bIcon = dwStaticStyle==SS_ICON;
                            HANDLE hBmpIco = (HANDLE)SendMessage(hWnd, STM_GETIMAGE, bIcon ? IMAGE_ICON:IMAGE_BITMAP, NULL);
                            if(hBmpIco)
                            {
                                std::unique_ptr<Bitmap> pBmp( bIcon ? new Bitmap((HICON)hBmpIco) : new Bitmap((HBITMAP)hBmpIco, NULL) );
                                std::unique_ptr<Graphics> myGraphics( new Graphics(hdcPaint) );
                                std::unique_ptr<CachedBitmap> pcbmp( new CachedBitmap(pBmp.get(), myGraphics.get()) );
                                VERIFY(Ok==myGraphics->DrawCachedBitmap(pcbmp.get(), 0,0));
                            }
                        }
                        else if(SS_BLACKRECT==dwStaticStyle || SS_GRAYRECT==dwStaticStyle || SS_WHITERECT==dwStaticStyle)
                        {
                            ARGB argb = 0L;
                            switch (dwStaticStyle)
                            {
                            case SS_BLACKRECT:
                                argb = 0xFF000000;
                                break;
                            case SS_GRAYRECT:
                                argb = 0xFF808080;
                                break;
                            case SS_WHITERECT:
                                argb = 0xFFFFFFFF;
                                break;
                            default:
                                ASSERT(0);
                                break;
                            }
                            Color clr(argb);

                            FillRect(&rcClient, hdcPaint, clr);
                        }
                        else if(SS_BLACKFRAME==dwStaticStyle || SS_GRAYFRAME==dwStaticStyle || SS_WHITEFRAME==dwStaticStyle)
                        {
                            ARGB argb = 0L;
                            switch (dwStaticStyle)
                            {
                            case SS_BLACKFRAME:
                                argb = 0xFF000000;
                                break;
                            case SS_GRAYFRAME:
                                argb = 0xFF808080;
                                break;
                            case SS_WHITEFRAME:
                                argb = 0xFFFFFFFF;
                                break;
                            }
                            Color clr(argb);

                            DrawRect(&rcClient, hdcPaint, DashStyleSolid, clr, 1.0);
                        }
                        else
                        {
                            DTTOPTS DttOpts = {sizeof(DTTOPTS)};
                            DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
                            DttOpts.crText   = RGB(255, 255, 255);
                            DttOpts.iGlowSize = 12; // Default value

                            VERIFY(DetermineGlowSize(&DttOpts.iGlowSize));

                            HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL);
                            if(hFontOld)
                                hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld);
                            int iLen = GetWindowTextLength(hWnd);

                            if(iLen)
                            {
                                iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING
                                LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen);
                                if(szText)
                                {
                                    iLen = GetWindowTextW(hWnd, szText, iLen);
                                    if(iLen)
                                    {
                                        DWORD dwFlags = DT_WORDBREAK;

                                        switch (dwStaticStyle)
                                        {
                                        case SS_CENTER:
                                            dwFlags |= DT_CENTER;
                                            break;
                                        case SS_RIGHT:
                                            dwFlags |= DT_RIGHT;
                                            break;
                                        case SS_LEFTNOWORDWRAP:
                                            dwFlags &= ~DT_WORDBREAK;
                                            break;
                                        }

                                        if(dwStyle & SS_CENTERIMAGE)
                                        {
                                            dwFlags |= DT_VCENTER;
                                            dwFlags &= ~DT_WORDBREAK;
                                        }

                                        if(dwStyle & SS_ENDELLIPSIS)
                                            dwFlags |= DT_END_ELLIPSIS|DT_MODIFYSTRING;
                                        else if(dwStyle & SS_PATHELLIPSIS)
                                            dwFlags |= DT_PATH_ELLIPSIS|DT_MODIFYSTRING;
                                        else if(dwStyle & SS_WORDELLIPSIS)
                                            dwFlags |= DT_WORD_ELLIPSIS|DT_MODIFYSTRING;

                                        if (dwStyleEx&WS_EX_RIGHT)
                                            dwFlags |= DT_RIGHT;

                                        if(dwStyle & SS_NOPREFIX)
                                            dwFlags |= DT_NOPREFIX;

                                        VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, 0, 0,
                                            szText, -1, dwFlags, &rcClient, &DttOpts));

                                        if(dwStyle&SS_SUNKEN || dwStyle&WS_BORDER)
                                            DrawRect(&rcClient, hdcPaint, DashStyleSolid, Color(0xFF, 0,0,0), 1.0);
                                    }
                                    VERIFY(!LocalFree(szText));
                                }
                            }

                            if (hFontOld)
                            {
                                SelectObject(hdcPaint, hFontOld);
                                hFontOld    = NULL;
                            }
                        }

                        VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE));
                    }

                    VERIFY(S_OK==CloseThemeData(hTheme));
                }
            }

            EndPaint(hWnd, &ps);
            return 0;
        }
        break;
    case WM_NCDESTROY:
    case WM_DESTROY:
        RemoveWindowSubclass(hWnd, SubclassProc, Static);
        subclassedControls.erase(hWnd);
        break;
    }

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
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);
}
Example #14
0
void PaintClc(HWND hwnd, struct ClcData *dat, HDC hdc, RECT * rcPaint)
{
	RECT clRect;
	int indent, index, fontHeight;
	struct ClcGroup *group;
	HFONT hOldFont;
	LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
	int status = GetGeneralisedStatus();
	int grey = 0, groupCountsFontTopShift;
	HBRUSH hBrushAlternateGrey = NULL;
	// yes I know about GetSysColorBrush()
	COLORREF tmpbkcolour = style & CLS_CONTACTLIST ? (dat->useWindowsColours ? GetSysColor(COLOR_3DFACE) : dat->bkColour) : dat->bkColour;

	if (dat->greyoutFlags & pcli->pfnClcStatusToPf2(status) || style & WS_DISABLED)
		grey = 1;
	else if (GetFocus() != hwnd && dat->greyoutFlags & GREYF_UNFOCUS)
		grey = 1;
	GetClientRect(hwnd, &clRect);
	if (rcPaint == NULL)
		rcPaint = &clRect;
	if (IsRectEmpty(rcPaint))
		return;

	HDC hdcMem = CreateCompatibleDC(hdc);
	HBITMAP hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
	HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBmpOsb);
	{
		TEXTMETRIC tm;
		hOldFont = (HFONT)SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPS].hFont);
		GetTextMetrics(hdcMem, &tm);
		groupCountsFontTopShift = tm.tmAscent;
		SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPCOUNTS].hFont);
		GetTextMetrics(hdcMem, &tm);
		groupCountsFontTopShift -= tm.tmAscent;
	}
	if (style & CLS_GREYALTERNATE)
		hBrushAlternateGrey =
		CreateSolidBrush(GetNearestColor(hdcMem, RGB(GetRValue(tmpbkcolour) - 10, GetGValue(tmpbkcolour) - 10, GetBValue(tmpbkcolour) - 10)));

	ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
	SetBkMode(hdcMem, TRANSPARENT);
	{
		HBRUSH hBrush = CreateSolidBrush(tmpbkcolour);
		FillRect(hdcMem, rcPaint, hBrush);
		DeleteObject(hBrush);
		if (dat->hBmpBackground) {
			// XXX: Halftone isnt supported on 9x, however the scretch problems dont happen on 98.
			SetStretchBltMode(hdcMem, HALFTONE);

			BITMAP bmp;
			GetObject(dat->hBmpBackground, sizeof(bmp), &bmp);
			HDC hdcBmp = CreateCompatibleDC(hdcMem);
			SelectObject(hdcBmp, dat->hBmpBackground);
			int y = dat->backgroundBmpUse & CLBF_SCROLL ? -dat->yScroll : 0;
			int maxx = dat->backgroundBmpUse & CLBF_TILEH ? clRect.right : 1;
			int maxy = dat->backgroundBmpUse & CLBF_TILEV ? rcPaint->bottom : y + 1;
			int destw, desth;
			switch (dat->backgroundBmpUse & CLBM_TYPE) {
			case CLB_STRETCH:
				if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
					if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) {
						desth = clRect.bottom;
						destw = desth * bmp.bmWidth / bmp.bmHeight;
					}
					else {
						destw = clRect.right;
						desth = destw * bmp.bmHeight / bmp.bmWidth;
					}
				}
				else {
					destw = clRect.right;
					desth = clRect.bottom;
				}
				break;
			case CLB_STRETCHH:
				if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
					destw = clRect.right;
					desth = destw * bmp.bmHeight / bmp.bmWidth;
				}
				else {
					destw = clRect.right;
					desth = bmp.bmHeight;
				}
				break;
			case CLB_STRETCHV:
				if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
					desth = clRect.bottom;
					destw = desth * bmp.bmWidth / bmp.bmHeight;
				}
				else {
					destw = bmp.bmWidth;
					desth = clRect.bottom;
				}
				break;
			default:       //clb_topleft
				destw = bmp.bmWidth;
				desth = bmp.bmHeight;
				break;
			}
			for (; y < maxy; y += desth) {
				if (y < rcPaint->top - desth)
					continue;
				for (int x = 0; x < maxx; x += destw)
					StretchBlt(hdcMem, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
			}
			DeleteDC(hdcBmp);
		}
	}

	int y = -dat->yScroll;
	group = &dat->list;
	group->scanIndex = 0;
	indent = 0;
	for (index = 0; y < rcPaint->bottom;) {
		if (group->scanIndex == group->cl.count) {
			group = group->parent;
			indent--;
			if (group == NULL)
				break;
			group->scanIndex++;
			continue;
		}

		ClcContact *cc = group->cl.items[group->scanIndex];
		if (y > rcPaint->top - dat->rowHeight) {
			int iImage = -1;
			int selected = index == dat->selection && (dat->showSelAlways || dat->exStyle & CLS_EX_SHOWSELALWAYS || GetFocus() == hwnd) && cc->type != CLCIT_DIVIDER;
			int hottrack = dat->exStyle & CLS_EX_TRACKSELECT && cc->type != CLCIT_DIVIDER && dat->iHotTrack == index;
			SIZE textSize, countsSize = { 0 }, spaceSize = { 0 };
			int width, checkboxWidth;
			TCHAR *szCounts = NULL;

			// alternating grey
			if (style & CLS_GREYALTERNATE && index & 1) {
				RECT rc;
				rc.top = y;
				rc.bottom = rc.top + dat->rowHeight;
				rc.left = 0;
				rc.right = clRect.right;
				FillRect(hdcMem, &rc, hBrushAlternateGrey);
			}

			// setup
			if (cc->type == CLCIT_GROUP)
				ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
			else if (cc->type == CLCIT_INFO) {
				if (cc->flags & CLCIIF_GROUPFONT)
					ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
				else
					ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
			}
			else if (cc->type == CLCIT_DIVIDER)
				ChangeToFont(hdcMem, dat, FONTID_DIVIDERS, &fontHeight);
			else if (cc->type == CLCIT_CONTACT && cc->flags & CONTACTF_NOTONLIST)
				ChangeToFont(hdcMem, dat, FONTID_NOTONLIST, &fontHeight);
			else if (cc->type == CLCIT_CONTACT &&
				((cc->flags & CONTACTF_INVISTO && GetRealStatus(cc, status) != ID_STATUS_INVISIBLE) || (cc->flags & CONTACTF_VISTO && GetRealStatus(cc, status) == ID_STATUS_INVISIBLE))) {
				// the contact is in the always visible list and the proto is invisible
				// the contact is in the always invisible and the proto is in any other mode
				ChangeToFont(hdcMem, dat, cc->flags & CONTACTF_ONLINE ? FONTID_INVIS : FONTID_OFFINVIS, &fontHeight);
			}
			else if (cc->type == CLCIT_CONTACT && !(cc->flags & CONTACTF_ONLINE))
				ChangeToFont(hdcMem, dat, FONTID_OFFLINE, &fontHeight);
			else
				ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
			GetTextExtentPoint32(hdcMem, cc->szText, (int)mir_tstrlen(cc->szText), &textSize);
			width = textSize.cx;
			if (cc->type == CLCIT_GROUP) {
				szCounts = pcli->pfnGetGroupCountsText(dat, cc);
				if (szCounts[0]) {
					GetTextExtentPoint32(hdcMem, _T(" "), 1, &spaceSize);
					ChangeToFont(hdcMem, dat, FONTID_GROUPCOUNTS, &fontHeight);
					GetTextExtentPoint32(hdcMem, szCounts, (int)mir_tstrlen(szCounts), &countsSize);
					width += spaceSize.cx + countsSize.cx;
				}
			}

			if ((style & CLS_CHECKBOXES && cc->type == CLCIT_CONTACT) || (style & CLS_GROUPCHECKBOXES && cc->type == CLCIT_GROUP) || (cc->type == CLCIT_INFO && cc->flags & CLCIIF_CHECKBOX))
				checkboxWidth = dat->checkboxSize + 2;
			else
				checkboxWidth = 0;

			// background
			if (selected) {
				int x = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace - 2;
				ImageList_DrawEx(dat->himlHighlight, 0, hdcMem, x, y, min(width + 5, clRect.right - x), dat->rowHeight, CLR_NONE, CLR_NONE,
					dat->exStyle & CLS_EX_NOTRANSLUCENTSEL ? ILD_NORMAL : ILD_BLEND25);
				SetTextColor(hdcMem, dat->selTextColour);
			}
			else if (hottrack)
				SetHotTrackColour(hdcMem, dat);

			// checkboxes
			if (checkboxWidth) {
				RECT rc;
				HANDLE hTheme = OpenThemeData(hwnd, L"BUTTON");
				rc.left = dat->leftMargin + indent * dat->groupIndent;
				rc.right = rc.left + dat->checkboxSize;
				rc.top = y + ((dat->rowHeight - dat->checkboxSize) >> 1);
				rc.bottom = rc.top + dat->checkboxSize;
				DrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, cc->flags & CONTACTF_CHECKED ? (hottrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : (hottrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL), &rc, &rc);
				CloseThemeData(hTheme);
			}

			// icon
			if (cc->type == CLCIT_GROUP)
				iImage = cc->group->expanded ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT;
			else if (cc->type == CLCIT_CONTACT)
				iImage = cc->iImage;
			if (iImage != -1) {
				// this doesnt use CLS_CONTACTLIST since the colour prolly wont match anyway
				COLORREF colourFg = dat->selBkColour;
				int mode = ILD_NORMAL;
				if (hottrack) {
					colourFg = dat->hotTextColour;
				}
				else if (cc->type == CLCIT_CONTACT && cc->flags & CONTACTF_NOTONLIST) {
					colourFg = dat->fontInfo[FONTID_NOTONLIST].colour;
					mode = ILD_BLEND50;
				}
				if (cc->type == CLCIT_CONTACT && dat->showIdle
					&& (cc->flags & CONTACTF_IDLE)
					&& GetRealStatus(cc, ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
					mode = ILD_SELECTED;
				ImageList_DrawEx(himlCListClc, iImage, hdcMem, dat->leftMargin + indent * dat->groupIndent + checkboxWidth,
					y + ((dat->rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode);
			}

			// text
			if (cc->type == CLCIT_DIVIDER) {
				RECT rc;
				rc.top = y + (dat->rowHeight >> 1);
				rc.bottom = rc.top + 2;
				rc.left = dat->leftMargin + indent * dat->groupIndent;
				rc.right = rc.left + ((clRect.right - rc.left - textSize.cx) >> 1) - 3;
				DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
				TextOut(hdcMem, rc.right + 3, y + ((dat->rowHeight - fontHeight) >> 1), cc->szText,
					(int)mir_tstrlen(cc->szText));
				rc.left = rc.right + 6 + textSize.cx;
				rc.right = clRect.right;
				DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
			}
Example #15
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);
}
Example #16
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);
}
Example #17
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);
}
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId;
    int wmEvent;
    
    switch (message) 
    {
        case WM_COMMAND:
            wmId    = LOWORD(wParam); 
            wmEvent = HIWORD(wParam); 
            // Parse the menu selections:
            switch (wmId)
            {
                case IDM_ABOUT:
                    DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                    break;
                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;

        case WM_ERASEBKGND:
            return 1;

        case WM_PAINT:
            // Let's open some theme data, and using BufferedPainting draw different fonts on glass background
            {
                RECT rcClient;
                GetClientRect(hWnd, &rcClient);

                MARGINS marGlassInset = {-1, -1, -1, -1}; // -1 means the whole window
                DwmExtendFrameIntoClientArea(hWnd, &marGlassInset);

                PAINTSTRUCT ps;
                HDC    hdc    = BeginPaint(hWnd, &ps);
                // ControlPanelStyle is declared in AeroStyle.xml
                HTHEME hTheme = OpenThemeData(NULL, L"ControlPanelStyle"); 

                if (hTheme)
                {
                    HDC hdcPaint = NULL;

                    BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) };
                    params.dwFlags        = BPPF_ERASE;

                    HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, &params, &hdcPaint);
                    if (hdcPaint)
                    {
                        // Let's start with the simplest GDI default font
                        DTTOPTS DttOpts = {sizeof(DTTOPTS)};
                        DttOpts.dwFlags = DTT_COMPOSITED;
                        DrawText(hdcPaint, L"This is some GDI text in the default font", -1, &rcClient, 0);

                        // Let's look at the same text in the default theme
                        rcClient.top += RECT_INCREMENT;
                        DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text in the default font", -1, 0, &rcClient, &DttOpts);

                        // Let's add some text color to add to theming attributes and draw again
                        rcClient.top    += RECT_INCREMENT;
                        DttOpts.dwFlags |= DTT_TEXTCOLOR;
                        DttOpts.crText   = RGB(255, 255, 255);
                        // CPANEL_TASKLINK is declared in VSStyle.h
                        DrawThemeTextEx(hTheme, hdcPaint, CPANEL_TASKLINK, 0, L"This is some text in a themed font", -1, 0, &rcClient, &DttOpts);

                        // Draw text on glass in a selected font
                        DttOpts.dwFlags &= ~DTT_TEXTCOLOR;
                        LOGFONT lgFont;
                        HFONT hFontOld = NULL;
                        if (SUCCEEDED(GetThemeSysFont(hTheme, TMT_CAPTIONFONT, &lgFont)))
                        {
                            HFONT hFont = CreateFontIndirect(&lgFont);
                            hFontOld    = (HFONT) SelectObject(hdcPaint, hFont);
                        }

                        rcClient.top += RECT_INCREMENT;
                        DrawText(hdcPaint, L"This is some GDI text in the selected font", -1, &rcClient, 0);

                        // The same selected font in themed text
                        rcClient.top += RECT_INCREMENT;
                        DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text in the selected font", -1, 0, &rcClient, &DttOpts);

                        SelectObject(hdcPaint, hFontOld);
                        rcClient.top += RECT_INCREMENT;
                        DrawText(hdcPaint, L"This is some GDI text in the default font", -1, &rcClient, 0);

                        // Let's add glow to our text attributes
                        DttOpts.dwFlags |= DTT_GLOWSIZE;
                        DttOpts.iGlowSize = 12; // Default value
                        // CompositedWindow::Window is declared in AeroStyle.xml
                        HTHEME hThemeWindow = OpenThemeData(NULL, L"CompositedWindow::Window");
                        if (hThemeWindow != NULL)
                        {
                            GetThemeInt(hThemeWindow, 0, 0, TMT_TEXTGLOWSIZE, &DttOpts.iGlowSize);
                            CloseThemeData(hThemeWindow);
                        }

                        rcClient.top += RECT_INCREMENT;
                        DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text with glow in the default font", -1, 0, &rcClient, &DttOpts);

                        // Now some color(theme) and glow
                        DttOpts.dwFlags |= DTT_TEXTCOLOR;
                        DttOpts.crText   = RGB(255, 255, 255);

                        rcClient.top += RECT_INCREMENT;
                        // CPANEL_TASKLINK is declared in VSStyle.h
                        DrawThemeTextEx(hTheme, hdcPaint, CPANEL_TASKLINK, 0, L"This is some text with glow in a themed font", -1, 0, &rcClient, &DttOpts);

                        DttOpts.dwFlags &= ~DTT_TEXTCOLOR;

                        // Find a particular font and draw using this
                        if (SUCCEEDED(GetThemeSysFont(hTheme, TMT_CAPTIONFONT, &lgFont)))
                        {
                            HFONT hFont = CreateFontIndirect(&lgFont);
                            hFontOld    = (HFONT) SelectObject(hdcPaint, hFont);
                        }
                        
                        rcClient.top += RECT_INCREMENT;
                        DrawText(hdcPaint, L"This is some GDI text in the selected font", -1, &rcClient, 0);
                        
                        rcClient.top += RECT_INCREMENT;
                        DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text with glow in the selected font", -1, 0, &rcClient, &DttOpts);
                        
                        if (hFontOld)
                        {                        
                            SelectObject(hdcPaint, hFontOld);
                        }
                        EndBufferedPaint(hBufferedPaint, TRUE);
                    }
                    CloseThemeData(hTheme);
                }
                EndPaint(hWnd, &ps);
            }
            break;
        
        case WM_DESTROY:
            PostQuitMessage(0);
            BufferedPaintUnInit();
            break;
        
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
Example #19
0
static HRESULT drawButtonPart(HRESULT hr, struct drawState *s)
{
	uiTableValue *value;
	WCHAR *wstr;
	bool enabled;
	HTHEME theme;
	RECT r;
	TEXTMETRICW tm;

	if (hr != S_OK)
		return hr;
	if (s->p->buttonModelColumn == -1)
		return S_OK;

	value = uiprivTableModelCellValue(s->model, s->iItem, s->p->buttonModelColumn);
	wstr = toUTF16(uiTableValueString(value));
	uiFreeTableValue(value);
	enabled = uiprivTableModelCellEditable(s->model, s->iItem, s->p->buttonClickableModelColumn);

	theme = OpenThemeData(s->t->hwnd, L"button");

	if (GetTextMetricsW(s->dc, &tm) == 0) {
		logLastError(L"GetTextMetricsW()");
		hr = E_FAIL;
		goto fail;
	}
	r = s->m->subitemBounds;

	if (theme != NULL) {
		int state;

		state = PBS_NORMAL;
		if (!enabled)
			state = PBS_DISABLED;
		hr = DrawThemeBackground(theme, s->dc,
			BP_PUSHBUTTON, state,
			&r, NULL);
		if (hr != S_OK) {
			logHRESULT(L"DrawThemeBackground()", hr);
			goto fail;
		}
		// TODO DT_EDITCONTROL?
		// TODO DT_PATH_ELLIPSIS DT_WORD_ELLIPSIS instead of DT_END_ELLIPSIS? a middle-ellipsis option would be ideal here
		// TODO is there a theme property we can get instead of hardcoding these flags? if not, make these flags a macro
		hr = DrawThemeText(theme, s->dc,
			BP_PUSHBUTTON, state,
			wstr, -1,
			DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX, 0,
			&r);
		if (hr != S_OK) {
			logHRESULT(L"DrawThemeText()", hr);
			goto fail;
		}
	} else {
		UINT state;
		HBRUSH color, prevColor;
		int prevBkMode;

		// TODO check errors
		// TODO explain why we're not doing this in the themed case (it has to do with extra transparent pixels)
		InflateRect(&r, -1, -1);
		state = DFCS_BUTTONPUSH;
		if (!enabled)
			state |= DFCS_INACTIVE;
		if (DrawFrameControl(s->dc, &r, DFC_BUTTON, state) == 0) {
			logLastError(L"DrawFrameControl()");
			hr = E_FAIL;
			goto fail;
		}
		color = GetSysColorBrush(COLOR_BTNTEXT);
		// TODO check errors for these two
		prevColor = (HBRUSH) SelectObject(s->dc, color);
		prevBkMode = SetBkMode(s->dc, TRANSPARENT);
		// TODO DT_EDITCONTROL?
		// TODO DT_PATH_ELLIPSIS DT_WORD_ELLIPSIS instead of DT_END_ELLIPSIS? a middle-ellipsis option would be ideal here
		if (DrawTextW(s->dc, wstr, -1, &r, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX) == 0) {
			logLastError(L"DrawTextW()");
			hr = E_FAIL;
			goto fail;
		}
		// TODO check errors for these two
		SetBkMode(s->dc, prevBkMode);
		SelectObject(s->dc, prevColor);
	}

	hr = S_OK;
fail:
	// TODO check errors
	if (theme != NULL)
		CloseThemeData(theme);
	uiprivFree(wstr);
	return hr;
}
Example #20
0
static void _sttXptReloadThemeData(XPTObject * xptObject)
{
    CloseThemeData(xptObject->hThemeHandle);
    xptObject->hThemeHandle = OpenThemeData(xptObject->hOwnerWindow, xptObject->lpcwClassObject);
}
Example #21
0
static LRESULT IPADDRESS_Draw (const IPADDRESS_INFO *infoPtr, HDC hdc)
{
    static const WCHAR dotW[] = { '.', 0 };
    RECT rect, rcPart;
    COLORREF bgCol, fgCol;
    HTHEME theme;
    int i, state = ETS_NORMAL;

    TRACE("\n");

    GetClientRect (infoPtr->Self, &rect);

    theme = OpenThemeData(infoPtr->Self, WC_EDITW);

    if (theme) {
        DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);

        if (!infoPtr->Enabled)
            state = ETS_DISABLED;
        else if (dwStyle & ES_READONLY)
            state = ETS_READONLY;
        else if (GetFocus() == infoPtr->Self)
            state = ETS_FOCUSED;

        GetThemeColor(theme, EP_EDITTEXT, state, TMT_FILLCOLOR, &bgCol);
        GetThemeColor(theme, EP_EDITTEXT, state, TMT_TEXTCOLOR, &fgCol);

        if (IsThemeBackgroundPartiallyTransparent (theme, EP_EDITTEXT, state))
            DrawThemeParentBackground(infoPtr->Self, hdc, &rect);
        DrawThemeBackground (theme, hdc, EP_EDITTEXT, state, &rect, 0);
    } else {
        if (infoPtr->Enabled) {
            bgCol = comctl32_color.clrWindow;
            fgCol = comctl32_color.clrWindowText;
        } else {
            bgCol = comctl32_color.clr3dFace;
            fgCol = comctl32_color.clrGrayText;
        }

        FillRect (hdc, &rect, (HBRUSH)(DWORD_PTR)(bgCol+1));
        DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
    }
    
    SetBkColor  (hdc, bgCol);
    SetTextColor(hdc, fgCol);

    for (i = 0; i < 3; i++) {
        GetWindowRect (infoPtr->Part[i].EditHwnd, &rcPart);
        MapWindowPoints( 0, infoPtr->Self, (POINT *)&rcPart, 2 );
        rect.left = rcPart.right;
        GetWindowRect (infoPtr->Part[i+1].EditHwnd, &rcPart);
        MapWindowPoints( 0, infoPtr->Self, (POINT *)&rcPart, 2 );
        rect.right = rcPart.left;

        if (theme)
            DrawThemeText(theme, hdc, EP_EDITTEXT, state, dotW, 1, DT_SINGLELINE | DT_CENTER | DT_BOTTOM, 0, &rect);
        else
            DrawTextW(hdc, dotW, 1, &rect, DT_SINGLELINE | DT_CENTER | DT_BOTTOM);
    }

    if (theme)
        CloseThemeData(theme);

    return 0;
}
Example #22
0
static void on_draw_item(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
    static HBRUSH black_brush = 0;
    LPDRAWITEMSTRUCT draw_info = (LPDRAWITEMSTRUCT)lParam;

    if (!black_brush) black_brush = CreateSolidBrush(0);

    if (draw_info->CtlID == IDC_SYSPARAM_COLOR)
    {
        UINT state;
        HTHEME theme;
        RECT buttonrect;

        theme = OpenThemeData(NULL, WC_BUTTONW);

        if (theme) {
            MARGINS margins;

            if (draw_info->itemState & ODS_DISABLED)
                state = PBS_DISABLED;
            else if (draw_info->itemState & ODS_SELECTED)
                state = PBS_PRESSED;
            else
                state = PBS_NORMAL;

            if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state))
                DrawThemeParentBackground(draw_info->hwndItem, draw_info->hDC, NULL);

            DrawThemeBackground(theme, draw_info->hDC, BP_PUSHBUTTON, state, &draw_info->rcItem, NULL);

            buttonrect = draw_info->rcItem;

            GetThemeMargins(theme, draw_info->hDC, BP_PUSHBUTTON, state, TMT_CONTENTMARGINS, &draw_info->rcItem, &margins);

            buttonrect.left += margins.cxLeftWidth;
            buttonrect.top += margins.cyTopHeight;
            buttonrect.right -= margins.cxRightWidth;
            buttonrect.bottom -= margins.cyBottomHeight;

            if (draw_info->itemState & ODS_FOCUS)
                DrawFocusRect(draw_info->hDC, &buttonrect);

            CloseThemeData(theme);
        } else {
            state = DFCS_ADJUSTRECT | DFCS_BUTTONPUSH;

            if (draw_info->itemState & ODS_DISABLED)
                state |= DFCS_INACTIVE;
            else
                state |= draw_info->itemState & ODS_SELECTED ? DFCS_PUSHED : 0;

            DrawFrameControl(draw_info->hDC, &draw_info->rcItem, DFC_BUTTON, state);

            buttonrect = draw_info->rcItem;
        }

        if (!(draw_info->itemState & ODS_DISABLED))
        {
            HBRUSH brush;
            int index = SendDlgItemMessageW(hDlg, IDC_SYSPARAM_COMBO, CB_GETCURSEL, 0, 0);

            index = SendDlgItemMessageW(hDlg, IDC_SYSPARAM_COMBO, CB_GETITEMDATA, index, 0);
            brush = CreateSolidBrush(metrics[index].color);

            InflateRect(&buttonrect, -1, -1);
            FrameRect(draw_info->hDC, &buttonrect, black_brush);
            InflateRect(&buttonrect, -1, -1);
            FillRect(draw_info->hDC, &buttonrect, brush);
            DeleteObject(brush);
        }
    }
}
Example #23
0
static LRESULT CALLBACK OptionsFilterSubclassProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message != WM_PAINT && message != WM_PRINT)
		return mir_callNextSubclass(hWnd, OptionsFilterSubclassProc, message, wParam, lParam);

	if (GetFocus() == hWnd || GetWindowTextLength(hWnd))
		return mir_callNextSubclass(hWnd, OptionsFilterSubclassProc, message, wParam, lParam);

	RECT rc;
	GetClientRect(hWnd, &rc);
	HDC hdc;
	PAINTSTRUCT paint;

	if (message == WM_PAINT)
		hdc = BeginPaint(hWnd, &paint);
	else
		hdc = (HDC)wParam;

	TCHAR buf[255];
	if (bSearchState == 1 && FilterLoadProgress < 100 && FilterLoadProgress > 0)
		mir_sntprintf(buf, SIZEOF(buf), TranslateT("Loading... %d%%"), FilterLoadProgress);
	else
		mir_sntprintf(buf, SIZEOF(buf), TranslateT("Search"));

	BOOL bDrawnByTheme = FALSE;

	int oldMode = SetBkMode(hdc, TRANSPARENT);

	HTHEME hTheme = OpenThemeData(hWnd, L"EDIT");
	if (hTheme) {
		if (IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
			DrawThemeParentBackground(hWnd, hdc, &rc);

		RECT rc2;
		GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &rc, &rc2);
		rc2.top = 2 * rc.top - rc2.top;
		rc2.left = 2 * rc.left - rc2.left;
		rc2.bottom = 2 * rc.bottom - rc2.bottom;
		rc2.right = 2 * rc.right - rc2.right;

		DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &rc2, &rc);
		HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
		HFONT oldFont = (HFONT)SelectObject(hdc, hFont);

		wchar_t *bufW = mir_t2u(buf);
		DrawThemeText(hTheme, hdc, EP_EDITTEXT, ETS_DISABLED, bufW, -1, 0, 0, &rc);
		mir_free(bufW);

		SelectObject(hdc, oldFont);
		CloseThemeData(hTheme);
		bDrawnByTheme = TRUE;
	}

	SetBkMode(hdc, oldMode);

	if (!bDrawnByTheme) {
		HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
		HFONT oldFont = (HFONT)SelectObject(hdc, hFont);
		SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
		FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
		int oldMode = SetBkMode(hdc, TRANSPARENT);
		DrawText(hdc, buf, -1, &rc, 0);
		SetBkMode(hdc, oldMode);
		SelectObject(hdc, oldFont);
	}

	if (message == WM_PAINT)
		EndPaint(hWnd, &paint);

	return 0;
}
Example #24
0
static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	TRichUtil *ru = NULL, tru;
	int idx;
	LRESULT ret;

	tru.hwnd = hwnd;
	{
		mir_cslock lck(csRich);
		if (List_GetIndex(&sListInt, &tru, &idx))
			ru = (TRichUtil *)sListInt.items[idx];
	}

	switch (msg) {
	case WM_THEMECHANGED:
	case WM_STYLECHANGED:
		RichUtil_ClearUglyBorder(ru);
		break;

	case WM_NCPAINT:
		ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
		if (ru->hasUglyBorder && IsThemeActive())
		{
			HANDLE hTheme = OpenThemeData(ru->hwnd, L"EDIT");

			if (hTheme) {
				RECT rcBorder;
				RECT rcClient;
				int nState;
				HDC hdc = GetWindowDC(ru->hwnd);

				GetWindowRect(hwnd, &rcBorder);
				rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top;
				rcBorder.left = rcBorder.top = 0;
				CopyRect(&rcClient, &rcBorder);
				rcClient.left += ru->rect.left;
				rcClient.top += ru->rect.top;
				rcClient.right -= ru->rect.right;
				rcClient.bottom -= ru->rect.bottom;
				ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);

				if (IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
					DrawThemeParentBackground(hwnd, hdc, &rcBorder);

				if (!IsWindowEnabled(hwnd))
					nState = ETS_DISABLED;
				else if (SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY)
					nState = ETS_READONLY;
				else nState = ETS_NORMAL;

				DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL);
				CloseThemeData(hTheme);
				ReleaseDC(hwnd, hdc);
				return 0;
			}
		}
		return ret;

	case WM_NCCALCSIZE:
		{
			ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
			NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS *)lParam;

			if (ru->hasUglyBorder && IsThemeActive()) {
				HANDLE hTheme = OpenThemeData(hwnd, L"EDIT");
				if (hTheme) {
					RECT rcClient = {0};
					HDC hdc = GetDC(GetParent(hwnd));

					if (GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) {
						ru->rect.left = rcClient.left - ncsParam->rgrc[0].left;
						ru->rect.top = rcClient.top - ncsParam->rgrc[0].top;
						ru->rect.right = ncsParam->rgrc[0].right - rcClient.right;
						ru->rect.bottom = ncsParam->rgrc[0].bottom - rcClient.bottom;
						ncsParam->rgrc[0] = rcClient;

						CloseThemeData(hTheme);
						ReleaseDC(GetParent(hwnd), hdc);
						return WVR_REDRAW;
					}
					ReleaseDC(GetParent(hwnd), hdc);
					CloseThemeData(hTheme);
				}
			}
		}
		return ret;

	case WM_ENABLE:
		RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME);
		break;

	case WM_GETDLGCODE:
		return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam) & ~DLGC_HASSETSEL;

	case WM_NCDESTROY:
		ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
		{
			mir_cslock lck(csRich);
			List_Remove(&sListInt, idx);
		}
		mir_free(ru);
		return ret;
	}
	return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
}
Example #25
0
static void _sttXptCloseThemeData(XPTObject * xptObject)
{
    CloseThemeData(xptObject->hThemeHandle);
    xptObject->hThemeHandle = NULL;
}
Example #26
0
static int CALLBACK CheckboxWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	CCheckboxData *dat = (CCheckboxData*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (!dat)
		return 0;

	switch (Msg) {
	case UM_INITCHECKBOX:
		{
			HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
			if (!hFont)
				hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);

			LOGFONT lf;
			GetObject(hFont, sizeof(lf), &lf);
			lf.lfWeight = FW_BOLD;
			dat->hFont = CreateFontIndirect(&lf);
			SendMessage(hWnd, UM_AUTOSIZE, 0, 0);
		}
		return 0;

	case UM_AUTOSIZE:
		{
			HTHEME hTheme = OpenThemeData(hWnd, L"BUTTON");
			int Len = GetWindowTextLength(hWnd) + 1;
			HDC hdc = GetDC(hWnd);
			HFONT hOldFont = (HFONT)SelectObject(hdc, dat->hFont);
			RECT rcText = { 0 };
			if (hTheme) {
				WCHAR *szText = (WCHAR*)_alloca(Len * sizeof(WCHAR));
				GetWindowTextW(hWnd, szText, Len);
				GetThemeTextExtent(hTheme, hdc, BP_GROUPBOX, IsWindowEnabled(hWnd) ? GBS_NORMAL : GBS_DISABLED, szText, -1, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE, nullptr, &rcText);
			}
			else {
				SIZE size;
				wchar_t *szText = (wchar_t*)_alloca(Len * sizeof(wchar_t));
				GetWindowText(hWnd, szText, Len);
				GetTextExtentPoint32(hdc, szText, (int)mir_wstrlen(szText), &size);
				rcText.right = size.cx;
				rcText.bottom = size.cy;
			}

			SelectObject(hdc, hOldFont);
			ReleaseDC(hWnd, hdc);
			if (hTheme)
				CloseThemeData(hTheme);

			OffsetRect(&rcText, CG_CHECKBOX_INDENT + CG_CHECKBOX_WIDTH + CG_TEXT_INDENT, 0);
			RECT rc;
			GetClientRect(hWnd, &rc);
			SetWindowPos(hWnd, nullptr, 0, 0, rcText.right + CG_ADDITIONAL_WIDTH, rc.bottom, SWP_NOMOVE | SWP_NOZORDER);
		}
		break;

	case BM_CLICK:
		SendMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
		SendMessage(hWnd, WM_LBUTTONUP, 0, 0);
		return 0;

	case BM_GETCHECK:
		return dat->State & CGSM_ISCHECKED;

	case BM_SETCHECK:
		if ((wParam != BST_UNCHECKED && wParam != BST_CHECKED && wParam != BST_INDETERMINATE) || (wParam == BST_INDETERMINATE && dat->Style != BS_3STATE && dat->Style != BS_AUTO3STATE))
			wParam = BST_CHECKED;
		dat->State &= ~CGSM_ISCHECKED;
		dat->State |= wParam;
		InvalidateRect(hWnd, nullptr, false);
		SendMessage(GetParent(hWnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hWnd), BN_CLICKED), (LPARAM)hWnd);
		return 0;

	case BM_SETSTATE:
		if (wParam)
			dat->State |= CGS_PRESSED;
		else
			dat->State &= ~CGS_PRESSED;
		InvalidateRect(hWnd, nullptr, false);
		return 0;

	case BM_GETSTATE:
		return (dat->State & CGSM_GETSTATE) | ((GetFocus() == hWnd) ? BST_FOCUS : 0);

	case WM_GETDLGCODE:
		return DLGC_BUTTON;

	case WM_THEMECHANGED:
	case WM_ENABLE:
		InvalidateRect(hWnd, nullptr, false);
		return 0;

	case WM_SETTEXT:
		if (CallWindowProc(dat->OldWndProc, hWnd, Msg, wParam, lParam))
			SendMessage(hWnd, UM_AUTOSIZE, 0, 0);
		return 0;

	case WM_KEYDOWN:
		if (wParam == VK_SPACE)
			SendMessage(hWnd, BM_SETSTATE, true, 0);
		return 0;

	case WM_KEYUP:
		if (wParam == VK_SPACE) {
			SendMessage(hWnd, BM_SETCHECK, (SendMessage(hWnd, BM_GETCHECK, 0, 0) + 1) % ((dat->Style == BS_AUTO3STATE) ? 3 : 2), 0);
			SendMessage(hWnd, BM_SETSTATE, false, 0);
		}
		return 0;

	case WM_CAPTURECHANGED:
		SendMessage(hWnd, BM_SETSTATE, false, 0);
		return 0;

	case WM_ERASEBKGND:
		return true;

	case WM_LBUTTONDOWN:
	case WM_LBUTTONDBLCLK:
		SetFocus(hWnd);
		SendMessage(hWnd, BM_SETSTATE, true, 0);
		SetCapture(hWnd);
		return 0;

	case WM_LBUTTONUP:
		if (GetCapture() == hWnd)
			ReleaseCapture();

		SendMessage(hWnd, BM_SETSTATE, false, 0);
		if (dat->State & CGS_HOVERED && (dat->Style == BS_AUTOCHECKBOX || dat->Style == BS_AUTO3STATE))
			SendMessage(hWnd, BM_SETCHECK, (SendMessage(hWnd, BM_GETCHECK, 0, 0) + 1) % ((dat->Style == BS_AUTO3STATE) ? 3 : 2), 0);
		return 0;

	case WM_MOUSEMOVE:
		{
			TRACKMOUSEEVENT tme = { 0 };
			tme.cbSize = sizeof(tme);
			tme.dwFlags = TME_LEAVE;
			tme.dwHoverTime = HOVER_DEFAULT;
			tme.hwndTrack = hWnd;
			_TrackMouseEvent(&tme);
		}

		POINT pt;
		GetCursorPos(&pt);
		if ((WindowFromPoint(pt) == hWnd) ^ ((dat->State & CGS_HOVERED) != 0)) {
			dat->State ^= CGS_HOVERED;
			InvalidateRect(hWnd, nullptr, false);
		}
		return 0;

	case WM_MOUSELEAVE:
		if (dat->State & CGS_HOVERED) {
			dat->State &= ~CGS_HOVERED;
			InvalidateRect(hWnd, nullptr, false);
		}
		return 0;

	case WM_SETFOCUS:
	case WM_KILLFOCUS:
	case WM_SYSCOLORCHANGE:
		InvalidateRect(hWnd, nullptr, false);
		return 0;

	case WM_PAINT:
		{
			HDC hdc;
			PAINTSTRUCT ps;
			hdc = BeginPaint(hWnd, &ps);
			RECT rc;
			GetClientRect(hWnd, &rc);
			HDC hdcMem = CreateCompatibleDC(hdc);
			HBITMAP hbmMem = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
			HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
			HTHEME hTheme = OpenThemeData(hWnd, L"BUTTON");
			if (hTheme)
				DrawThemeParentBackground(hWnd, hdcMem, nullptr);
			else
				FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE));

			int StateID = 0;
			switch (SendMessage(hWnd, BM_GETCHECK, 0, 0)) {
			case BST_CHECKED:
				StateID += CBSCHECK_CHECKED;
				break;
			case BST_UNCHECKED:
				StateID += CBSCHECK_UNCHECKED;
				break;
			case BST_INDETERMINATE:
				StateID += CBSCHECK_MIXED;
				break;
			}
			if (!IsWindowEnabled(hWnd))
				StateID += CBSSTATE_DISABLED;
			else if (dat->State & CGS_PRESSED && (GetCapture() != hWnd || dat->State & CGS_HOVERED))
				StateID += CBSSTATE_PRESSED;
			else if (dat->State & CGS_PRESSED || dat->State & CGS_HOVERED)
				StateID += CBSSTATE_HOT;

			rc.left += CG_CHECKBOX_INDENT;
			rc.right = rc.left + CG_CHECKBOX_WIDTH; // left-align the image in the client area
			rc.top += CG_CHECKBOX_VERTINDENT;
			rc.bottom = rc.top + CG_CHECKBOX_WIDTH; // exact rc dimensions are necessary for DrawFrameControl to draw correctly
			if (hTheme)
				DrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, StateID, &rc, &rc);
			else {
				int dfcStates[] =
				{ 0, 0, DFCS_PUSHED, DFCS_INACTIVE,
				DFCS_CHECKED, DFCS_CHECKED, DFCS_CHECKED | DFCS_PUSHED, DFCS_CHECKED | DFCS_INACTIVE,
				DFCS_BUTTON3STATE | DFCS_CHECKED, DFCS_BUTTON3STATE | DFCS_CHECKED, DFCS_BUTTON3STATE | DFCS_INACTIVE | DFCS_CHECKED | DFCS_PUSHED, DFCS_BUTTON3STATE | DFCS_INACTIVE | DFCS_CHECKED | DFCS_PUSHED };
				_ASSERT(StateID >= 1 && StateID <= _countof(dfcStates));
				DrawFrameControl(hdcMem, &rc, DFC_BUTTON, dfcStates[StateID - 1]);
			}

			GetClientRect(hWnd, &rc);
			rc.left += CG_CHECKBOX_INDENT + CG_CHECKBOX_WIDTH + CG_TEXT_INDENT;

			int Len = GetWindowTextLength(hWnd) + 1;
			wchar_t *szTextT = (wchar_t*)_alloca(Len * sizeof(wchar_t));
			GetWindowText(hWnd, szTextT, Len);

			HFONT hOldFont = (HFONT)SelectObject(hdcMem, dat->hFont);
			SetBkMode(hdcMem, TRANSPARENT);
			if (hTheme)
				DrawThemeText(hTheme, hdcMem, BP_GROUPBOX, IsWindowEnabled(hWnd) ? GBS_NORMAL : GBS_DISABLED, szTextT, -1, DT_LEFT | DT_VCENTER | DT_SINGLELINE, 0, &rc);
			else
				DrawText(hdcMem, szTextT, -1, &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE);

			if (GetFocus() == hWnd) {
				RECT rcText = { 0 };
				if (hTheme)
					GetThemeTextExtent(hTheme, hdcMem, BP_GROUPBOX, IsWindowEnabled(hWnd) ? GBS_NORMAL : GBS_DISABLED, szTextT, -1, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE, nullptr, &rcText);
				else {
					SIZE size;
					GetTextExtentPoint32(hdcMem, szTextT, (int)mir_wstrlen(szTextT), &size);
					rcText.right = size.cx;
					rcText.bottom = size.cy;
				}
				rcText.bottom = rc.bottom;
				OffsetRect(&rcText, rc.left, 0);
				InflateRect(&rcText, 1, -1);
				DrawFocusRect(hdcMem, &rcText);
			}
			SelectObject(hdcMem, hOldFont);
			if (hTheme)
				CloseThemeData(hTheme);

			BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY);
			SelectObject(hdcMem, hbmOld);
			DeleteObject(hbmMem);
			DeleteDC(hdcMem);
			EndPaint(hWnd, &ps);
		}
		return 0;

	case WM_DESTROY:
		if (dat->hFont)
			DeleteObject(dat->hFont);

		SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
		CallWindowProc(dat->OldWndProc, hWnd, Msg, wParam, lParam);
		delete dat;
		return 0;
	}
	return CallWindowProc(dat->OldWndProc, hWnd, Msg, wParam, lParam);
}
Example #27
0
File: updown.c Project: devyn/wine
/***********************************************************************
 *           UpDownWndProc
 */
static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr (hwnd);
    static const WCHAR themeClass[] = {'S','p','i','n',0};
    HTHEME theme;

    TRACE("hwnd=%p msg=%04x wparam=%08lx lparam=%08lx\n", hwnd, message, wParam, lParam);

    if (!infoPtr && (message != WM_CREATE))
        return DefWindowProcW (hwnd, message, wParam, lParam);

    switch(message)
    {
        case WM_CREATE:
            infoPtr = Alloc (sizeof(UPDOWN_INFO));
	    SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

	    /* initialize the info struct */
	    infoPtr->Self = hwnd;
	    infoPtr->Notify = ((LPCREATESTRUCTW)lParam)->hwndParent;
            infoPtr->dwStyle = ((LPCREATESTRUCTW)lParam)->style;
	    infoPtr->AccelCount = 0;
	    infoPtr->AccelVect = 0;
	    infoPtr->AccelIndex = -1;
	    infoPtr->CurVal = 0;
	    infoPtr->MinVal = 100;
	    infoPtr->MaxVal = 0;
	    infoPtr->Base  = 10; /* Default to base 10  */
	    infoPtr->Buddy = 0;  /* No buddy window yet */
	    infoPtr->Flags = 0;  /* And no flags        */

            SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle & ~WS_BORDER);

            /* Do we pick the buddy win ourselves? */
	    if (infoPtr->dwStyle & UDS_AUTOBUDDY)
		UPDOWN_SetBuddy (infoPtr, GetWindow (hwnd, GW_HWNDPREV));

            OpenThemeData (hwnd, themeClass);

	    TRACE("UpDown Ctrl creation, hwnd=%p\n", hwnd);
	    break;

	case WM_DESTROY:
	    Free (infoPtr->AccelVect);

	    if(infoPtr->Buddy) RemovePropW(infoPtr->Buddy, BUDDY_UPDOWN_HWND);

	    Free (infoPtr);
	    SetWindowLongPtrW (hwnd, 0, 0);
            theme = GetWindowTheme (hwnd);
            CloseThemeData (theme);
	    TRACE("UpDown Ctrl destruction, hwnd=%p\n", hwnd);
	    break;

	case WM_ENABLE:
	    if (wParam) {
		infoPtr->dwStyle &= ~WS_DISABLED;
	    } else {
		infoPtr->dwStyle |= WS_DISABLED;
	    	UPDOWN_CancelMode (infoPtr);
	    }
	    InvalidateRect (infoPtr->Self, NULL, FALSE);
	    break;

        case WM_STYLECHANGED:
            if (wParam == GWL_STYLE) {
                infoPtr->dwStyle = ((LPSTYLESTRUCT)lParam)->styleNew;
	        InvalidateRect (infoPtr->Self, NULL, FALSE);
            }
            break;

        case WM_THEMECHANGED:
            theme = GetWindowTheme (hwnd);
            CloseThemeData (theme);
            OpenThemeData (hwnd, themeClass);
            InvalidateRect (hwnd, NULL, FALSE);
            break;

	case WM_TIMER:
	   /* is this the auto-press timer? */
	   if(wParam == TIMER_AUTOPRESS) {
		KillTimer(hwnd, TIMER_AUTOPRESS);
		infoPtr->Flags &= ~(FLAG_PRESSED | FLAG_ARROW);
		InvalidateRect(infoPtr->Self, NULL, FALSE);
	   }

	   /* if initial timer, kill it and start the repeat timer */
  	   if(wParam == TIMER_AUTOREPEAT) {
		int temp;

		KillTimer(hwnd, TIMER_AUTOREPEAT);
		/* if no accel info given, used default timer */
		if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0) {
		    infoPtr->AccelIndex = -1;
		    temp = REPEAT_DELAY;
		} else {
		    infoPtr->AccelIndex = 0; /* otherwise, use it */
		    temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
		}
		SetTimer(hwnd, TIMER_ACCEL, temp, 0);
      	    }

	    /* now, if the mouse is above us, do the thing...*/
	    if(infoPtr->Flags & FLAG_MOUSEIN) {
		int temp;

		temp = infoPtr->AccelIndex == -1 ? 1 : infoPtr->AccelVect[infoPtr->AccelIndex].nInc;
		UPDOWN_DoAction(infoPtr, temp, infoPtr->Flags & FLAG_ARROW);

		if(infoPtr->AccelIndex != -1 && infoPtr->AccelIndex < infoPtr->AccelCount-1) {
		    KillTimer(hwnd, TIMER_ACCEL);
		    infoPtr->AccelIndex++; /* move to the next accel info */
		    temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
	  	    /* make sure we have at least 1ms intervals */
		    SetTimer(hwnd, TIMER_ACCEL, temp, 0);
		}
	    }
	    break;

	case WM_CANCELMODE:
	  return UPDOWN_CancelMode (infoPtr);

	case WM_LBUTTONUP:
	    if (GetCapture() != infoPtr->Self) break;

	    if ( (infoPtr->Flags & FLAG_MOUSEIN) &&
		 (infoPtr->Flags & FLAG_ARROW) ) {

	    	SendMessageW( infoPtr->Notify,
			      (infoPtr->dwStyle & UDS_HORZ) ? WM_HSCROLL : WM_VSCROLL,
                  	      MAKELONG(SB_ENDSCROLL, infoPtr->CurVal),
			      (LPARAM)hwnd);
		if (UPDOWN_IsBuddyEdit(infoPtr))
		    SendMessageW(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
	    }
	    UPDOWN_CancelMode(infoPtr);
	    break;

	case WM_LBUTTONDOWN:
	case WM_MOUSEMOVE:
        case WM_MOUSELEAVE:
	    if(UPDOWN_IsEnabled(infoPtr))
		UPDOWN_HandleMouseEvent (infoPtr, message, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
	    break;

        case WM_MOUSEWHEEL:
            UPDOWN_MouseWheel(infoPtr, wParam);
            break;

	case WM_KEYDOWN:
	    if((infoPtr->dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(infoPtr))
		return UPDOWN_KeyPressed(infoPtr, (int)wParam);
	    break;

	case WM_PRINTCLIENT:
	case WM_PAINT:
	    return UPDOWN_Paint (infoPtr, (HDC)wParam);

	case UDM_GETACCEL:
	    if (wParam==0 && lParam==0) return infoPtr->AccelCount;
	    if (wParam && lParam) {
		int temp = min(infoPtr->AccelCount, wParam);
	        memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
	        return temp;
      	    }
	    return 0;

	case UDM_SETACCEL:
	{
	    unsigned temp;

	    TRACE("UDM_SETACCEL\n");

	    if(infoPtr->AccelVect) {
		Free (infoPtr->AccelVect);
		infoPtr->AccelCount = 0;
		infoPtr->AccelVect  = 0;
      	    }
	    if(wParam==0) return TRUE;
	    infoPtr->AccelVect = Alloc (wParam*sizeof(UDACCEL));
	    if(infoPtr->AccelVect == 0) return FALSE;
	    memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
            infoPtr->AccelCount = wParam;

            for (temp = 0; temp < wParam; temp++)
                TRACE("%d: nSec %u nInc %u\n", temp, infoPtr->AccelVect[temp].nSec, infoPtr->AccelVect[temp].nInc);

    	    return TRUE;
	}
	case UDM_GETBASE:
	    return infoPtr->Base;

	case UDM_SETBASE:
	    TRACE("UpDown Ctrl new base(%ld), hwnd=%p\n", wParam, hwnd);
	    if (wParam==10 || wParam==16) {
		WPARAM temp = infoPtr->Base;
		infoPtr->Base = wParam;
		return temp;
	    }
	    break;

	case UDM_GETBUDDY:
	    return (LRESULT)infoPtr->Buddy;

	case UDM_SETBUDDY:
	    return (LRESULT)UPDOWN_SetBuddy (infoPtr, (HWND)wParam);

	case UDM_GETPOS:
	{
	    int temp = UPDOWN_GetBuddyInt (infoPtr);
	    return MAKELONG(infoPtr->CurVal, temp ? 0 : 1);
	}
	case UDM_SETPOS:
	{
	    int temp = (short)LOWORD(lParam);

	    TRACE("UpDown Ctrl new value(%d), hwnd=%p\n", temp, hwnd);
	    if(!UPDOWN_InBounds(infoPtr, temp)) {
		if(temp < infoPtr->MinVal) temp = infoPtr->MinVal;
		if(temp > infoPtr->MaxVal) temp = infoPtr->MaxVal;
	    }
	    wParam = infoPtr->CurVal;
	    infoPtr->CurVal = temp;
	    UPDOWN_SetBuddyInt (infoPtr);
	    return wParam;            /* return prev value */
	}
	case UDM_GETRANGE:
	    return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);

	case UDM_SETRANGE:
                                                     /* we must have:     */
	    infoPtr->MaxVal = (short)(lParam);       /* UD_MINVAL <= Max <= UD_MAXVAL */
	    infoPtr->MinVal = (short)HIWORD(lParam); /* UD_MINVAL <= Min <= UD_MAXVAL */
                                                     /* |Max-Min| <= UD_MAXVAL        */
	    TRACE("UpDown Ctrl new range(%d to %d), hwnd=%p\n",
		  infoPtr->MinVal, infoPtr->MaxVal, hwnd);
	    break;

	case UDM_GETRANGE32:
	    if (wParam) *(LPINT)wParam = infoPtr->MinVal;
	    if (lParam) *(LPINT)lParam = infoPtr->MaxVal;
	    break;

	case UDM_SETRANGE32:
	    infoPtr->MinVal = (INT)wParam;
	    infoPtr->MaxVal = (INT)lParam;
	    if (infoPtr->MaxVal <= infoPtr->MinVal)
		infoPtr->MaxVal = infoPtr->MinVal + 1;
	    TRACE("UpDown Ctrl new range(%d to %d), hwnd=%p\n",
		  infoPtr->MinVal, infoPtr->MaxVal, hwnd);
	    break;

	case UDM_GETPOS32:
	    if ((LPBOOL)lParam != NULL) *((LPBOOL)lParam) = TRUE;
	    return infoPtr->CurVal;

	case UDM_SETPOS32:
	{
	    int temp;

	    if(!UPDOWN_InBounds(infoPtr, (int)lParam)) {
		if((int)lParam < infoPtr->MinVal) lParam = infoPtr->MinVal;
		if((int)lParam > infoPtr->MaxVal) lParam = infoPtr->MaxVal;
	    }
	    temp = infoPtr->CurVal;         /* save prev value   */
	    infoPtr->CurVal = (int)lParam;  /* set the new value */
	    UPDOWN_SetBuddyInt (infoPtr);
	    return temp;                    /* return prev value */
	}
	case UDM_GETUNICODEFORMAT:
	    /* we lie a bit here, we're always using Unicode internally */
	    return infoPtr->UnicodeFormat;

	case UDM_SETUNICODEFORMAT:
	{
	    /* do we really need to honour this flag? */
	    int temp = infoPtr->UnicodeFormat;
	    infoPtr->UnicodeFormat = (BOOL)wParam;
	    return temp;
	}
	default:
	    if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message))
		ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam);
	    return DefWindowProcW (hwnd, message, wParam, lParam);
    }

    return 0;
}
Example #28
0
static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	TRichUtil *ru;

	EnterCriticalSection(&csRich);
	ru = rlist_find(slist, hwnd);
	LeaveCriticalSection(&csRich);
	switch(msg) {
	case WM_THEMECHANGED:
	case WM_STYLECHANGED:
		RichUtil_ClearUglyBorder(ru);
		break;

	case WM_NCPAINT:
		{
			LRESULT ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
			if (ru->hasUglyBorder && IsThemeActive()) {
				HANDLE hTheme = OpenThemeData(ru->hwnd, L"EDIT");

				if (hTheme) {
					RECT rcBorder;
					RECT rcClient;
					int nState;
					HDC hdc = GetWindowDC(ru->hwnd);

					GetWindowRect(hwnd, &rcBorder);
					rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top;
					rcBorder.left = rcBorder.top = 0;
					CopyRect(&rcClient, &rcBorder);
					rcClient.left += ru->rect.left;
					rcClient.top += ru->rect.top;
					rcClient.right -= ru->rect.right;
					rcClient.bottom -= ru->rect.bottom;
					ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
					if(IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
						DrawThemeParentBackground(hwnd, hdc, &rcBorder);
					if (!IsWindowEnabled(hwnd))
						nState = ETS_DISABLED;
					else if(SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY)
						nState = ETS_READONLY;
					else nState = ETS_NORMAL;
					DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL);
					CloseThemeData(hTheme);
					ReleaseDC(hwnd, hdc);
					return 0;
				}
			}
			return ret;
		}
	case WM_NCCALCSIZE:
		{
			LRESULT ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
			NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam;

			if (ru->hasUglyBorder && IsThemeActive()) {
				HANDLE hTheme = OpenThemeData(hwnd, L"EDIT");

				if (hTheme) {
					RECT rcClient; 
					HDC hdc = GetDC(GetParent(hwnd));

					ZeroMemory(&rcClient, sizeof(RECT));
					if(GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) {
						ru->rect.left = rcClient.left-ncsParam->rgrc[0].left;
						ru->rect.top = rcClient.top-ncsParam->rgrc[0].top;
						ru->rect.right = ncsParam->rgrc[0].right-rcClient.right;
						ru->rect.bottom = ncsParam->rgrc[0].bottom-rcClient.bottom;
						CopyRect(&ncsParam->rgrc[0], &rcClient);
						CloseThemeData(hTheme);
						ReleaseDC(GetParent(hwnd), hdc);
						return WVR_REDRAW;
					}
					ReleaseDC(GetParent(hwnd), hdc);
					CloseThemeData(hTheme);
				}
			}
			return ret;
		}

	case WM_ENABLE:
		RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_UPDATENOW|RDW_FRAME);
		break;

	case WM_DESTROY:
		{
			LRESULT ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
			EnterCriticalSection(&csRich);
			slist = rlist_remove(slist, ru);
			LeaveCriticalSection(&csRich);
			if (ru) free(ru);
			return ret;
		}
	}
	return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
}
Example #29
0
/**********************************************************************
 * The dialog subclass window proc.
 */
LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, 
                                             WPARAM wParam, LPARAM lParam, 
                                             ULONG_PTR dwRefData)
{
    HTHEME theme = GetWindowTheme ( hWnd );
    static const WCHAR themeClass[] = { 'W','i','n','d','o','w',0 };
    BOOL themingActive = IsThemeDialogTextureEnabled (hWnd);
    BOOL doTheming = themingActive && (theme != NULL);
    LRESULT result;
      
    switch (msg)
    {
    case WM_CREATE:
	result = THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
	theme = OpenThemeData( hWnd, themeClass );
	return result;
    
    case WM_DESTROY:
        CloseThemeData ( theme );
        SetWindowTheme( hWnd, NULL, NULL );
        OpenThemeData( hWnd, NULL );
        return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);

    case WM_THEMECHANGED:
        CloseThemeData ( theme );
	OpenThemeData( hWnd, themeClass );
	InvalidateRect( hWnd, NULL, TRUE );
	return 0;
	
    case WM_SYSCOLORCHANGE:
	if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
        /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
   	 * which will do the repaint. */
        break;
        
    case WM_ERASEBKGND:
	if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
        {
            RECT rc;
            WNDPROC dlgp = (WNDPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC);
            if (!CallWindowProcW(dlgp, hWnd, msg, wParam, lParam))
            {
                /* Draw background*/
                GetClientRect (hWnd, &rc);
                if (IsThemePartDefined (theme, WP_DIALOG, 0))
                    /* Although there is a theme for the WINDOW class/DIALOG part, 
                     * but I[res] haven't seen Windows using it yet... Even when
                     * dialog theming is activated, the good ol' BTNFACE 
                     * background seems to be used. */
#if 0
                    DrawThemeBackground (theme, (HDC)wParam, WP_DIALOG, 0, &rc, 
                        NULL);
#endif
                    return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
                else 
                /* We might have gotten a TAB theme class, so check if we can 
                 * draw as a tab page. */
                if (IsThemePartDefined (theme, TABP_BODY, 0))
                    DrawThemeBackground (theme, (HDC)wParam, TABP_BODY, 0, &rc, 
                        NULL);
                else
                    return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
            }
            return 1;
        }
Example #30
0
void CButtonExtn::DrawButton(HWND hWnd, HDC hDC, RECT *pRect, BOOL fChecked, BOOL fHot, BOOL fFocus)
{
  // Code originally by Nikita Leontiev in answer to "Change checkBox text color Win32"
  // in MS's Forum: "Visual Studio Developer Center > Visual Studio vNext Forums > Visual C++ General"
  // Modified for MFC, Checkbox and Radio buttons by DK

  int nWidth = pRect -> right - pRect -> left;
  int nHeight = pRect -> bottom - pRect -> top;

  HDC hMemDC = CreateCompatibleDC(hDC);
  HBITMAP hBitmap = CreateCompatibleBitmap(hDC, nWidth, nHeight);
  SelectObject(hMemDC, hBitmap);

  RECT rFillRect = {0, 0, nWidth, nHeight};

  HTHEME hTheme = OpenThemeData(hWnd, L"BUTTON");
  int nStateID(0);

  if (m_type == BS_AUTOCHECKBOX) {
    nStateID = (fChecked) ? CBS_CHECKEDNORMAL : CBS_UNCHECKEDNORMAL;
    if (fHot)
      nStateID = (fChecked) ? CBS_CHECKEDHOT : CBS_UNCHECKEDHOT;
  } else {
    nStateID = (fChecked) ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL;
    if (fHot)
      nStateID = (fChecked) ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT;
  }

  //If bg color isn't set, try get backgroung color from current theme
  if (m_bUseBkgColour) {
    FillRect(hMemDC, &rFillRect, CreateSolidBrush(GetSysColor(m_icolour)));
  }
  else { 
    // Don't check IsThemeBackgroundPartiallyTransparent because it return false for BP_CHECKBOX
    DrawThemeParentBackground(hWnd, hMemDC, &rFillRect);
  }

  RECT rIconRect = {0, 0, 13, nHeight};
  DrawThemeBackground(hTheme, hMemDC, m_type == BS_AUTOCHECKBOX ? BP_CHECKBOX : BP_RADIOBUTTON,
                      nStateID, &rIconRect, NULL);
  CloseThemeData(hTheme);

  RECT rTextRect = {16, 0, nWidth - 16, nHeight};
  SetBkMode(hMemDC, TRANSPARENT);
  if (m_bUseTextColour)
    SetTextColor(hMemDC, m_crfText);

  SelectObject(hMemDC, (HFONT)GetStockObject(DEFAULT_GUI_FONT));

  if (m_caption.IsEmpty()) {
    GetWindowText(m_caption);
    SetWindowText(L"");
  }

  DrawText(hMemDC, m_caption, m_caption.GetLength(), &rTextRect, DT_SINGLELINE | DT_VCENTER);

  if (fFocus){
    DrawText(hMemDC, m_caption, m_caption.GetLength(), &rTextRect, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT);
    rTextRect.left--;
    rTextRect.right++;
    DrawFocusRect(hMemDC, &rTextRect);
  }

  BitBlt(hDC, 0, 0, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY);

  DeleteObject(hBitmap);
  DeleteDC(hMemDC);
}