Exemple #1
0
void PrintRichEdit(HWND hwnd, Gdiplus::Graphics* graphics, Gdiplus::Bitmap* background, Gdiplus::Rect layoutArea) {
	using namespace Gdiplus;
	//Calculate the area to render.
	HDC hdc1 = ::GetDC(hwnd);

	double anInchX = 1440 / GetDeviceCaps(hdc1, LOGPIXELSX);
	double anInchY = 1440 / GetDeviceCaps(hdc1, LOGPIXELSY);
			ReleaseDC(hwnd,hdc1);

	//double anInch = 1440.0  /  GetDeviceCaps(hdc1, LOGPIXELSX);

	RECT rectLayoutArea;
	rectLayoutArea.top = (int)(layoutArea.GetTop() * anInchY);
	rectLayoutArea.bottom = (int)(layoutArea.GetBottom() * anInchY);
	rectLayoutArea.left = (int)(layoutArea.GetLeft() *anInchX  );
	rectLayoutArea.right = (int)(layoutArea.GetRight() * anInchX);

	HDC hdc = graphics->GetHDC();
	Gdiplus::Graphics gr2(hdc);
	SolidBrush br(Color(255,255,255));

	// We need to draw background on new HDC, otherwise the text will look ugly
	Status st = gr2.DrawImage(background,layoutArea.GetLeft(),layoutArea.GetTop(),layoutArea.GetLeft(), layoutArea.GetTop(), layoutArea.Width, layoutArea.Height,Gdiplus::UnitPixel/*gr2.GetPageUnit()*/);

	FORMATRANGE fmtRange;
	fmtRange.chrg.cpMax = -1;                    //Indicate character from to character to 
	fmtRange.chrg.cpMin = 0;
	fmtRange.hdc = hdc;                                //Use the same DC for measuring and rendering
	fmtRange.hdcTarget = hdc;                    //Point at printer hDC
	fmtRange.rc = rectLayoutArea;            //Indicate the area on page to print
	fmtRange.rcPage = rectLayoutArea;    //Indicate size of page


	int characterCount = ::SendMessage(hwnd, EM_FORMATRANGE, 1, (LPARAM)&fmtRange);

	//Release the device context handle obtained by a previous call
	graphics->ReleaseHDC(hdc);
}
            HRESULT Action(
                const P* pts,
                size_t count,
                const Gdiplus::Rect& clip,
                ScanConvertCallback callback,
                INT_PTR hint)
            {
                if(count <= 0) return E_INVALIDARG;
                if(pts == NULL) return E_INVALIDARG;
                if(callback == NULL) return E_INVALIDARG;

                n = (INT) count;
                pt = pts;

                /// initialize index array as natrual order
                std::vector<INT> idx(n);
                active.resize(n);
                for(INT i = 0; i < n; i ++)
                {
                    idx[i] =  i;
                }

                /// Sort idx by the order of pt[idx[k]].Y
                std::sort(&idx[0], &idx[0] + n, CompareIndex(pt));

                nact = 0;       /// number of active edges, init as empty
                INT k = 0;      /// idx[k] is the next vertex to precess
                INT y0 = max(clip.GetTop(), xtl::FloorCast<INT>(pt[idx[0]].Y));     /// the topmost scanline
                INT y1 = min(clip.GetBottom(), xtl::CeilCast<INT>(pt[idx[n-1]].Y)); /// the bottom  scanline

                /// step through scanlines
                /// scanline y is at y+.5 in continuous coordinates
                for(INT y = y0; y < y1; y ++)
                {
		            /// check vertices between previous scanline and current one, if any
                    for (; (k < n) && (pt[idx[k]].Y <= y); k++)
                    {
			            /// to simplify, if pt.y = y+.5, pretend it's above
                        /// invariant: y-.5 < pt[i].y <= y+.5
			            INT i = idx[k];

			            ///  insert or delete edges before and after vertex i 
                        ///  (i-1 to i, and i to i+1) from active list if they cross scanline y
                        INT j = i > 0 ? i-1 : n-1;	/// vertex previous to i
			            if (pt[j].Y <= y)	        /// old edge, remove from active list
                        {
                            DeleteActiveEdge(j);
                        }
                        else if (pt[j].Y > y)       ///  new edge, add to active list
                        {
                            InsertActiveEdge(j, y);
                        }

			            j = i < (n - 1) ? i+1 : 0;	/// vertex next after i
			            if (pt[j].Y <= y)	        /// old edge, remove from active list
				        {
				            DeleteActiveEdge(i);
				        }
			            else if (pt[j].Y > y)	    /// new edge, add to active list
				        {
				            InsertActiveEdge(i, y);
				        }
                    }

		            /// sort active edge list by active[j].x
                    std::sort(&active[0], &active[0] + nact, CompareEdge());

		            /// draw horizontal segments for scanline y
                    for (INT j=0; j < nact; j += 2)	/// draw horizontal segments
                    {
                        /// span 'tween j & j+1 is inside, span tween j+1 & j+2 is outside
                        INT xl = xtl::CeilCast<INT>(active[j].x);		/// left end of span
                        if (xl < clip.GetLeft()) xl = clip.GetLeft();
                        if (xl > clip.GetRight()) xl = clip.GetRight();

                        INT xr = xtl::CeilCast<INT>(active[j+1].x);	 /// right end of span
                        if (xr < clip.GetLeft()) xr = clip.GetLeft();
                        if (xr > clip.GetRight()) xr = clip.GetRight();

                        if (xl < xr)
                        {
                            /// Invoke call back in span
                            if(!callback(y, xl, xr, hint))
                            {
                                /// if call back returns false
                                /// return prematurely
                                return S_OK;
                            }
                        }

                        active[j].x += active[j].dx;	    /// increment edge coords
                        active[j+1].x += active[j+1].dx;
                    }
                }

                return S_OK;
            }
void TrackListCtrl::DrawItem(Gdiplus::Graphics& g, INT nItem, Gdiplus::Rect& itemRC)
{
	HDC hdc = g.GetHDC();
	if (hdc == 0)
	{
		TRACE(_T("@1 TrackListCtrl::DrawItem. Cant get HDC\r\n"));
		return;		
	}
	CDC* pDC = CDC::FromHandle(hdc);
	PrgAPI* pAPI = PRGAPI();
	//Calculate Colors
	BOOL bSelected = IsItemSelected(nItem);
	COLORREF clrText = m_colors[COL_Text];
	COLORREF clrBk = m_colors[COL_Bk];
	if (bSelected)
	{
		clrText =  m_colors[COL_TextSel];
		clrBk = m_colors[COL_TextSelBk];
	}

	CRect rcSubItem(itemRC.X, itemRC.Y, itemRC.GetRight(), itemRC.GetBottom());
	pDC->SetTextColor(clrText);
	pDC->FillSolidRect(rcSubItem, clrBk);

	const INT cMargin = 2;

	FullTrackRecordSP& rec = (*m_pCollection)[nItem];

	pDC->SetBkMode(TRANSPARENT);

	INT curx = cMargin;


	CRect rcFirstLine(rcSubItem);
	rcFirstLine.bottom = rcFirstLine.top + 20;
	rcFirstLine.left = cMargin;
	rcFirstLine.right -= cMargin;
	CRect rcSecondLine(rcSubItem);
	rcSecondLine.top = rcFirstLine.bottom;
	rcSecondLine.left = cMargin;
	rcSecondLine.right -= cMargin;


	if (m_bDrawPictures)
	{
		INT imgHeight = 32;//rcSubItem.Height() - 2 * cMargin;
		INT cury = rcSubItem.top + cMargin;
		LocalPictureManager* pLM = PRGAPI()->GetLocalPictureManager();
		Gdiplus::Rect rcImage(curx, cury, imgHeight, imgHeight);
		Graphics g2(hdc);
		BOOL bRet = pLM->DrawAlbumThumbnail(rec->artist.name.c_str(), rec->album.name.c_str(), g2, rcImage);
		if (!bRet)
			bRet = pLM->DrawArtistThumbnail(rec->artist.name.c_str(), g2, rcImage);
		if (!bRet)
			bRet = pLM->DrawDefaultThumbnail(IIT_AlbumPicture, g2, rcImage);

		curx += 32 + cMargin ;

	}

	rcSecondLine.left = curx;
	//=== Draw the icon
	INT cury = rcFirstLine.top + (rcFirstLine.Height() - 16) / 2;
	pDC->SetTextColor(clrText);
	DrawIconEx(pDC->m_hDC, curx, cury, pAPI->GetIconForTrackType(rec->track.trackType), 16, 16, 0, 0, DI_NORMAL);
	curx += 16 + cMargin;


	//=== Draw the title
	CRect rcTitle(rcFirstLine);
	rcTitle.left = curx;
	CFont* pOldFont = pDC->SelectObject(m_pBoldFont);
	pDC->DrawText(rec->track.name.c_str(), rec->track.name.size(), &rcTitle, DT_END_ELLIPSIS | DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
	pDC->DrawText(rec->track.name.c_str(), rec->track.name.size(), &rcTitle, DT_END_ELLIPSIS | DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_CALCRECT);

	//=== Draw the artist
	CRect rcArtist(rcFirstLine);
	rcArtist.left = rcTitle.right + cMargin;
	pDC->DrawText(rec->artist.name.c_str(), rec->artist.name.size(), &rcArtist, DT_END_ELLIPSIS | DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);

	pDC->SelectObject(m_pNormalFont);

	//=== Next line
	//=== Draw the rating (if exists)
	if (rec->track.rating > 0 && rec->track.rating < 256)
	{
		FLOAT fStars = Rating2Stars(rec->track.rating);
		if (fStars > 0.0f && fStars <=1.0f)
		{
			DrawIconEx(hdc, rcSecondLine.left, rcSecondLine.top, pAPI->GetIcon(ICO_StarBad16), 16, 16, 0, 0, DI_NORMAL);
			rcSecondLine.left += 17;
		}
		while (fStars > 1.0f)
		{
			DrawIconEx(hdc, rcSecondLine.left, rcSecondLine.top, pAPI->GetIcon(ICO_StarGold16), 16, 16, 0, 0, DI_NORMAL);
			fStars -= 1.0f;
			rcSecondLine.left += 17;
		}
	}

	TCHAR time[500];
	UINT len = _sntprintf(time, 500, _T("%d:%02d | %s: %s | %s: %s"), 
		INT (rec->track.duration / 60), INT(rec->track.duration) % 60,
		pAPI->GetString(IDS_ALBUM), rec->album.name.c_str(),
		pAPI->GetString(IDS_LOCATION), rec->track.location.c_str()
		);
	pDC->DrawText(time, len, &rcSecondLine, DT_END_ELLIPSIS | DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);

	pDC->SelectObject(pOldFont);

	g.ReleaseHDC(pDC->m_hDC);
}