void Toolbar::onSysColorChange()
{
	// the following line is used to hack the toolbar background color for tradeshow
	return;
	int iconSize;
	ImageList_GetIconSize( disabledImageList_, &iconSize, &iconSize );
	disabledImageList_ = ImageList_Create( iconSize, iconSize, ILC_COLOR32, 1, 256 );
	hotImageList_ = ImageList_Create( iconSize, iconSize, ILC_COLOR32, 1, 256 );
	normalImageList_ = ImageList_Create( iconSize, iconSize, ILC_COLOR32, 1, 256 );

	// destroy it
	while( sendMessage( TB_BUTTONCOUNT, 0, 0 ) )
		sendMessage( TB_DELETEBUTTON , 0, 0 );

	HIMAGELIST imglist;
	imglist = (HIMAGELIST)sendMessage( TB_SETIMAGELIST, 0, (LPARAM)normalImageList_ );
	if( imglist )
		ImageList_Destroy( imglist );
	imglist = (HIMAGELIST)sendMessage( TB_SETHOTIMAGELIST, 0, (LPARAM)hotImageList_ );
	if( imglist )
		ImageList_Destroy( imglist );
	imglist = (HIMAGELIST)sendMessage( TB_SETDISABLEDIMAGELIST, 0, (LPARAM)disabledImageList_ );
	if( imglist )
		ImageList_Destroy( imglist );

	imageIndices_.clear();
	Manager::instance().bitmaps().clear();

	unsigned int index = 0;
	changed( index, rootItem() );
}
Ejemplo n.º 2
0
int Icon::add_to_imagelist(HIMAGELIST himl, HDC hdc_wnd, COLORREF bk_color, HBRUSH bk_brush) const
{
    int ret;

    if (_itype == IT_SYSCACHE) {
        HIMAGELIST himl = g_Globals._icon_cache.get_sys_imagelist();

        int cx, cy;
        ImageList_GetIconSize(himl, &cx, &cy);

        HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, cx, cy);
        HDC hdc = CreateCompatibleDC(hdc_wnd);
        HBITMAP hbmp_old = SelectBitmap(hdc, hbmp);
        ImageList_DrawEx(himl, _sys_idx, hdc, 0, 0, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL);
        SelectBitmap(hdc, hbmp_old);
        DeleteDC(hdc);

        ret = ImageList_Add(himl, hbmp, 0);

        DeleteObject(hbmp);
    } else
        ret = ImageList_AddAlphaIcon(himl, _hicon, bk_brush, hdc_wnd);

    return ret;
}
Ejemplo n.º 3
0
void CSharedDirsTreeCtrl::OnLvnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)pNMHDR;
	*pResult = 0;

	CDirectoryItem* pToDrag = (CDirectoryItem*)lpnmtv->itemNew.lParam;
	if (pToDrag == NULL || pToDrag->m_eItemType != SDI_UNSHAREDDIRECTORY || FileSystemTreeIsShared(pToDrag->m_strFullPath))
		return;

	ASSERT( m_pDraggingItem == NULL );
	delete m_pDraggingItem;
	m_pDraggingItem = pToDrag->CloneContent(); // to be safe we store a copy, as items can be deleted when collapsing the tree etc

	CImageList* piml = NULL;
	POINT ptOffset;
	RECT rcItem;
	if ((piml = CreateDragImage(lpnmtv->itemNew.hItem)) == NULL)
		return;

	/* get the bounding rectangle of the item being dragged (rel to top-left of control) */
	if (GetItemRect(lpnmtv->itemNew.hItem, &rcItem, TRUE))
	{
		CPoint ptDragBegin;
		int nX, nY;
		/* get offset into image that the mouse is at */
		/* item rect doesn't include the image */
		ptDragBegin = lpnmtv->ptDrag;
		ImageList_GetIconSize(piml->GetSafeHandle(), &nX, &nY);
		ptOffset.x = (ptDragBegin.x - rcItem.left) + (nX - (rcItem.right - rcItem.left));
		ptOffset.y = (ptDragBegin.y - rcItem.top) + (nY - (rcItem.bottom - rcItem.top));
		/* convert the item rect to screen co-ords, for use later */
		MapWindowPoints(NULL, &rcItem);
	}
	else
	{
		GetWindowRect(&rcItem);
		ptOffset.x = ptOffset.y = 8;
	}

	if (piml->BeginDrag(0, ptOffset))
	{
		CPoint ptDragEnter = lpnmtv->ptDrag;
		ClientToScreen(&ptDragEnter);
		piml->DragEnter(NULL, ptDragEnter);
	}
	delete piml;

	/* set the focus here, so we get a WM_CANCELMODE if needed */
	SetFocus();

	/* redraw item being dragged, otherwise it remains (looking) selected */
	InvalidateRect(&rcItem, TRUE);
	UpdateWindow();

	/* Hide the mouse cursor, and direct mouse input to this window */
	SetCapture(); 
}
Ejemplo n.º 4
0
void CEditView::DrawLeftMarginImages( HDC hDC, BOOL bBookmark, BYTE byImages, int x, int y ) const
{
	HIMAGELIST hil = m_pCtrl->GetImageList();
	if ( hil )
	{
		int cx, cy;
		if ( !ImageList_GetIconSize( hil, &cx, &cy ) )
			return;
		x = x + ( ( CM_CXLEFTMARGIN - cx ) / 2 );
		y = y + ( ( m_cyLine - cy ) / 2 );

		// draw the bookmark if enabled
		if ( bBookmark )
		{
			ImageList_Draw( hil, 0, hDC, x, y, ILD_TRANSPARENT );
		}

		// draw all custom margin images enabled by the caller
		if ( byImages )
		{
			for ( int i = 1; byImages && i <= 7; i++ )
			{
				BYTE byMask = ( BYTE ) ( 1 << i );
				if ( byImages & byMask )
				{
					byImages &= ~byMask;	// remove so we may shortcircuit from loop if done
					ImageList_Draw( hil, i, hDC, x, y, ILD_TRANSPARENT );
				}
			}
		}
	}
	else if ( bBookmark )
	{
		// no imagelist, so let's just draw the bookmark by hand as usual
		HBRUSH hbr = CreateSolidBrush( m_pCtrl->GetBookmarkColor() );
		HPEN hpen = CreatePen( PS_SOLID, 1, m_pCtrl->GetBookmarkBkColor() );
		HBRUSH hbrOld = ( HBRUSH ) SelectObject( hDC, hbr );
		HPEN hpenOld = ( HPEN ) SelectObject( hDC, hpen );

		POINT pt[ 3 ];
		pt[ 0 ].x = x + CM_CXLEFTMARGIN - 4;
		pt[ 0 ].y = y + m_cyLine / 2;
		pt[ 1 ].x = x + CM_CXLEFTMARGIN / 4;
		pt[ 1 ].y = pt[ 0 ].y - 6;
		pt[ 2 ].x = pt[ 1 ].x;
		pt[ 2 ].y = pt[ 0 ].y + 6;

		Polygon( hDC, pt, ARRAY_SIZE( pt ) );

		SelectObject( hDC, hbrOld );
		DeleteObject( hbr );
		SelectObject( hDC, hpenOld );
		DeleteObject( hpen );
	}
}
Ejemplo n.º 5
0
// Sets the image list to use in the list box.
//
// Parameters:
//		[IN]	pImageList
//				Pointer to an CImageList object containing the image list
//				to use in the list box. Pass NULL to remove any previous
//				associated image list.
//
void CListBoxST::SetImageList(CImageList* pImageList)
{
	m_pImageList = pImageList;
	// Get icons size
	if (m_pImageList)
		ImageList_GetIconSize(*m_pImageList, (LPINT)&m_szImage.cx, (LPINT)&m_szImage.cy);
	else
		::ZeroMemory(&m_szImage, sizeof(m_szImage));

	Invalidate();
} // End of SetImageList
Ejemplo n.º 6
0
// For the layout engine.
BOOL ClsFlatButton::OnGetMinSize( ClsSize& szMinSize )
{
	// Add room for the frame.
	szMinSize.CX() += ::GetSystemMetrics( SM_CXFRAME ) * 3;

	// For vista and up we use different numbers.
	if ( ClsGetApp()->GetMajorVersion() >= 6 )
	{
		szMinSize.CY() += ::GetSystemMetrics( SM_CYFRAME ) * 1 + 4;
	}
	else
	{
		szMinSize.CY() += ::GetSystemMetrics( SM_CYFRAME ) * 3;
	}

	// Images?
	int cxi = 0, cyi = 0;
	if ( m_hImages && ImageList_GetImageCount( m_hImages ))
	{
		// Get the image size.
		ImageList_GetIconSize( m_hImages, &cxi, &cyi );

		// Make room.
		cxi += 4;

		// Add sizes.
		szMinSize.CX() += cxi;
		szMinSize.CY() += cyi;
	}

	// Do we have a caption?
	ClsString str( GetSafeHWND());
	if ( str.GetStringLength())
	{
		// Setup the DC.
		ClsGetDC dc( this );
		ClsFont font;
		GetFont( font );
		ClsSelector sel( &dc, font );

		// Measure the caption.
		ClsRect rc;
		dc.DrawText( str, rc, DT_CALCRECT );

		// Add the width of the caption.
		szMinSize.CX() += rc.Width() + 4;

		// Adjust the height if necessary.
		if ( rc.Height() > cyi )
			szMinSize.CY() += rc.Height() - cyi;
	}
	return TRUE;
}
Ejemplo n.º 7
0
HBITMAP    Icon::create_bitmap(COLORREF bk_color, HBRUSH hbrBkgnd, HDC hdc_wnd) const
{
    if (_itype == IT_SYSCACHE) {
        HIMAGELIST himl = g_Globals._icon_cache.get_sys_imagelist();

        int cx, cy;
        ImageList_GetIconSize(himl, &cx, &cy);

        HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, cx, cy);
        HDC hdc = CreateCompatibleDC(hdc_wnd);
        HBITMAP hbmp_old = SelectBitmap(hdc, hbmp);
        ImageList_DrawEx(himl, _sys_idx, hdc, 0, 0, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL);
        SelectBitmap(hdc, hbmp_old);
        DeleteDC(hdc);

        return hbmp;
    } else
        return create_bitmap_from_icon(_hicon, hbrBkgnd, hdc_wnd);
}
Ejemplo n.º 8
0
HICON ImageList_GetIconFixed (HIMAGELIST himl, INT i, UINT fStyle)
{
	ICONINFO ii;
	HICON hIcon;
	HBITMAP hOldDstBitmap;
	HDC hdcDst;

	int cx, cy;
	ImageList_GetIconSize(himl, &cx, &cy);

	hdcDst = CreateCompatibleDC(NULL);

	ii.fIcon = TRUE;
	ii.xHotspot = 0;
	ii.yHotspot = 0;

	/* draw mask*/
	ii.hbmMask = CreateBitmap (cx, cy, 1, 1, NULL);
	hOldDstBitmap = (HBITMAP)SelectObject (hdcDst, ii.hbmMask);
	PatBlt(hdcDst, 0, 0, cx, cy, WHITENESS);
	ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_MASK);

	/* draw image*/
	ii.hbmColor = CreateBitmap (cx, cy, 1, 32, NULL);
	SelectObject (hdcDst, ii.hbmColor);
	PatBlt (hdcDst, 0, 0, cx, cy, BLACKNESS);
	ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_TRANSPARENT);

	/*
	* CreateIconIndirect requires us to deselect the bitmaps from
	* the DCs before calling
	*/
	SelectObject(hdcDst, hOldDstBitmap);

	hIcon = CreateIconIndirect (&ii);

	DeleteObject (ii.hbmMask);
	DeleteObject (ii.hbmColor);
	DeleteDC (hdcDst);

	return hIcon;
}
Ejemplo n.º 9
0
int HIDPI_ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon)
{
    int iRet;
    int cxIcon, cyIcon;
    HICON hiconStretched;

    ImageList_GetIconSize(himl, &cxIcon, &cyIcon);
    HIDPI_StretchIcon_Internal(hicon, &hiconStretched, cxIcon, cyIcon);
    if (hiconStretched != NULL)
    {
        iRet = ImageList_ReplaceIcon(himl, i, hiconStretched);
        DestroyIcon(hiconStretched);
    }
    else
    {
        iRet = ImageList_ReplaceIcon(himl, i, hicon);
    }

    return iRet;
}
Ejemplo n.º 10
0
CSysImageList::CSysImageList()
{
    SHFILEINFO ssfi;
    TCHAR windir[MAX_PATH] = { 0 };
    GetWindowsDirectory(windir, _countof(windir));  // MAX_PATH ok.
    hSystemImageList =
        (HIMAGELIST)SHGetFileInfo(windir,
                                  0,
                                  &ssfi, sizeof ssfi,
                                  SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

    int cx, cy;
    ImageList_GetIconSize(hSystemImageList, &cx, &cy);
    auto emptyImageList = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, ImageList_GetImageCount(hSystemImageList), 10);
    Attach(emptyImageList);

    m_dirIconIndex = GetFileIcon(L"Doesn't matter", FILE_ATTRIBUTE_DIRECTORY, 0);
    m_dirOpenIconIndex = GetFileIcon(L"Doesn't matter", FILE_ATTRIBUTE_DIRECTORY, SHGFI_OPENICON);
    m_defaultIconIndex = GetFileIcon(L"", FILE_ATTRIBUTE_NORMAL, 0);
}
Ejemplo n.º 11
0
int CMySuperGrid::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CSuperGridCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;
	/////////////////////
	//remember this	
	///////////////////
	//associate imagelist with listviewctrl	
	if(!m_image.Create(IDB_FOLDERS,16,1,RGB(0, 255, 255)))
		return -1;

	SetImageList(&m_image, LVSIL_SMALL);
	CImageList *pImageList = GetImageList(LVSIL_SMALL);
	if(pImageList)
		ImageList_GetIconSize(pImageList->m_hImageList, &m_cxImage, &m_cyImage);
	else
		return -1;
	
	return 0;
}
Ejemplo n.º 12
0
		virtual BOOL on_draw   (HELEMENT he, UINT draw_type, HDC hdc, const RECT& rc ) 
		{ 
			if( draw_type != DRAW_CONTENT )
				return FALSE; /*do default draw*/ 

			dom::element el = he;
			const wchar_t* filename = el.get_attribute("filename");
			if( !filename )
				return FALSE;  // no such attribute at all.

			// 先画图标
			SHFILEINFOW sfi;
			HIMAGELIST hlist = (HIMAGELIST) SHGetFileInfoW( filename,
				0, &sfi, sizeof(SHFILEINFO), 
				/*SHGFI_USEFILEATTRIBUTES |*/ SHGFI_SYSICONINDEX | SHGFI_SMALLICON );
			if(!hlist)
				return FALSE;
			int szx = 16;
			int szy = 16;
			ImageList_GetIconSize(hlist, &szx, &szy);
			int x = rc.left - 19; // 水平居左 // + (rc.right - rc.left - szx) / 2; 
			int y = rc.top + (rc.bottom - rc.top - szy) / 2; // 垂直居中

			//draw_file_icon(hdc, x, y, filename);
			ImageList_Draw(hlist, sfi.iIcon, hdc, x, y, ILD_TRANSPARENT);

			// 输出文字
			UINT pta = GetTextAlign(hdc);
			SetTextAlign(hdc, TA_LEFT | TA_TOP |TA_NOUPDATECP); 
			DrawTextW(hdc,  (is_fullpath(el) && (wcslen(filename) > 1)) ? filename : el.text(),
				-1,const_cast<RECT*>(&rc), 
				DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_PATH_ELLIPSIS | DT_NOPREFIX);
			SetTextAlign(hdc, pta); 

			return TRUE; /*skip default draw as we did it already*/ 
		}
Ejemplo n.º 13
0
RT_B RT_API RtDrawImageList(RT_H hImageList, RT_H hDc, RT_N nX, RT_N nY)
{
  RT_N32 nImagesCount;
  RT_N32 nWidth;
  RT_N32 nHeight;
  RT_N nI;
  RT_B bResult;

  nImagesCount = ImageList_GetImageCount(hImageList);
  bResult = ImageList_GetIconSize(hImageList, &nWidth, &nHeight);
  if (bResult)
  {
    for (nI = 0; nI < nImagesCount; nI++)
    {
      bResult = ImageList_Draw(hImageList, nI, hDc, nX + nI * nWidth, nY, ILD_TRANSPARENT);
      if (!bResult)
      {
        break;
      }
    }
  }

  return bResult;
}
Ejemplo n.º 14
0
// Returns the size (same for all images) of the images in the list
bool wxImageList::GetSize(int WXUNUSED(index), int &width, int &height) const
{
    wxASSERT_MSG( m_hImageList, wxT("invalid image list") );

    return ImageList_GetIconSize(GetHImageList(), &width, &height) != 0;
}
void CXTPSkinObjectToolBar::DrawButtonImage(CDC* pDC, int x, int y, int nIndex)
{
	CToolBarCtrl* pToolBar = (CToolBarCtrl*)this;

	TBBUTTON tbb;
	pToolBar->GetButton(nIndex, &tbb);

	int state = tbb.fsState;
	int nHot = (int)pToolBar->SendMessage(TB_GETHOTITEM);
	BOOL fHotTrack = nHot == nIndex;
	int iIndex = 0;
	int iImage = tbb.iBitmap;

	HIMAGELIST himl = 0;
	BOOL bMonoBitmap = FALSE;

	if (fHotTrack || (state & TBSTATE_CHECKED))
	{
		himl   = GetImageList(HIML_HOT, iIndex);
	}
	else if (!(state & TBSTATE_ENABLED))
	{
		himl = GetImageList(HIML_DISABLED, iIndex);
		bMonoBitmap = himl == NULL;
	}

	if (!himl)
	{
		himl = GetImageList(HIML_NORMAL, iIndex);
	}

	if (himl && (iImage != -1))
	{
		if (bMonoBitmap && IsAlphaImageList(himl))
		{
			XTP_IMAGELISTDRAWPARAMSEX imldp;

			imldp.himl = himl;
			imldp.cbSize = sizeof(imldp);
			imldp.i      = iImage;
			imldp.hdcDst = pDC->GetSafeHdc();
			imldp.x      = x;
			imldp.y      = y;
			imldp.cx     = 0;
			imldp.cy     = 0;
			imldp.xBitmap= 0;
			imldp.yBitmap= 0;
			imldp.rgbBk  = GetColor(COLOR_3DFACE);
			imldp.rgbFg  = CLR_DEFAULT;
			imldp.fStyle = ILD_TRANSPARENT;

			imldp.fState = ILS_SATURATE;
			imldp.Frame = 0;
			imldp.crEffect = 0;

			ImageList_DrawIndirect((IMAGELISTDRAWPARAMS*)&imldp);
		}
		else if (bMonoBitmap)
		{
			int iDxBitmap, iDyBitmap;
			ImageList_GetIconSize(himl, &iDxBitmap, &iDyBitmap);

			CDC dcMono;
			dcMono.CreateCompatibleDC(pDC);

			CBitmap bmp;
			bmp.Attach(CreateBitmap(iDxBitmap + 1, iDyBitmap + 1, 1, 1, 0));

			CBitmap* pOldBitmap = dcMono.SelectObject(&bmp);
			dcMono.SetTextColor(0L);

			XTP_IMAGELISTDRAWPARAMS imldp;

			PatBlt(dcMono, 0, 0, iDxBitmap + 1, iDyBitmap + 1, WHITENESS);

			imldp.cbSize = sizeof(imldp);
			imldp.himl   = himl;
			imldp.i      = iImage;
			imldp.hdcDst = dcMono.GetSafeHdc();
			imldp.x      = 0;
			imldp.y      = 0;
			imldp.cx     = 0;
			imldp.cy     = 0;
			imldp.xBitmap= 0;
			imldp.yBitmap= 0;
			imldp.rgbBk  = GetColor(COLOR_BTNFACE);
			imldp.rgbFg  = CLR_DEFAULT;
			imldp.fStyle = ILD_ROP | ILD_MASK;
			imldp.dwRop  = SRCCOPY;

			ImageList_DrawIndirect((IMAGELISTDRAWPARAMS*)&imldp);

			imldp.fStyle = ILD_ROP | ILD_IMAGE;
			imldp.rgbBk  = GetColor(COLOR_3DHILIGHT);
			imldp.dwRop  = SRCPAINT;


			ImageList_DrawIndirect((IMAGELISTDRAWPARAMS*)&imldp);


			pDC->SetTextColor(0L);
			pDC->SetBkColor(0x00FFFFFF);

			HBRUSH hbrOld = (HBRUSH)SelectObject(pDC->GetSafeHdc(), GetMetrics()->m_brTheme[COLOR_3DHILIGHT]);
			BitBlt(pDC->GetSafeHdc(), x + 1, y + 1, iDxBitmap, iDyBitmap, dcMono, 0, 0, PSDPxax);
			SelectObject(pDC->GetSafeHdc(), hbrOld);

			hbrOld = (HBRUSH)SelectObject(pDC->GetSafeHdc(), GetMetrics()->m_brTheme[COLOR_BTNSHADOW]);
			BitBlt(pDC->GetSafeHdc(), x, y, iDxBitmap, iDyBitmap, dcMono, 0, 0, PSDPxax);
			SelectObject(pDC->GetSafeHdc(), hbrOld);

			dcMono.SelectObject(pOldBitmap);
		}
		else
		{
			XTP_IMAGELISTDRAWPARAMS imldp;

			imldp.himl = himl;
			imldp.cbSize = sizeof(imldp);
			imldp.i      = iImage;
			imldp.hdcDst = pDC->GetSafeHdc();
			imldp.x      = x;
			imldp.y      = y;
			imldp.cx     = 0;
			imldp.cy     = 0;
			imldp.xBitmap= 0;
			imldp.yBitmap= 0;
			imldp.rgbBk  = GetColor(COLOR_3DFACE);
			imldp.rgbFg  = CLR_DEFAULT;
			imldp.fStyle = ILD_TRANSPARENT;

			ImageList_DrawIndirect((IMAGELISTDRAWPARAMS*)&imldp);
		}
	}
}
Ejemplo n.º 16
0
void CEnListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	CDC* pDC;
	CRect rText, rItem, rClient, rHeader;
	COLORREF crOldText, crOldBack;
	CSize sizeText;
	LV_COLUMN lvc = { 0 };
//	CPen* pOldPen;
	CImageList* pImageList;
	CImageList* pStateList;
	int nImage = -1;
	BOOL bItemFocused, bListFocused, bSelected, bDropHighlighted, bSelAlways;
	UINT uStyle, uState;
	CSize sizeState(0, 0), sizeImage(0, 0);
	int nIndent = 0;

	// get and prepare device context
	pDC = CDC::FromHandle(lpDrawItemStruct->hDC);//GetDC(); 
	pDC->SelectObject(GetFont());
	pDC->SetROP2(R2_COPYPEN);

	// init helper variables
	int nItem = lpDrawItemStruct->itemID;
	GetItemRect(nItem, rItem, LVIR_BOUNDS);//lpDrawItemStruct->rcItem;
	GetClientRect(&rClient);

	// some problems with drophiliting items during drag and drop
	// so we need to make sure drawing is clipped to client area
	// this fixes it admirably!
	if (GetHeader())
	{
		GetHeader()->GetWindowRect(rHeader);
		ScreenToClient(rHeader);
		rClient.top = max(0, rHeader.bottom);
		pDC->IntersectClipRect(rClient);
	}

	rText = rItem;

	uStyle = GetStyle();
	uState = GetItemState(nItem, LVIS_DROPHILITED | LVIS_SELECTED);
	bDropHighlighted = (uState & LVIS_DROPHILITED);
	bItemFocused = (GetFocusedItem() == nItem);
	bListFocused = (GetFocus() == this);
	bSelected = (uState & LVIS_SELECTED);
	bSelAlways = ((uStyle & LVS_SHOWSELALWAYS) == LVS_SHOWSELALWAYS);
	bSelected = bSelected && (bListFocused || bSelAlways);

	crOldText = pDC->SetTextColor(COLORREF(0)); // this will be overwritten on a per subitem basis
	crOldBack = pDC->SetBkColor(GetItemBackColor(nItem, bSelected, bDropHighlighted, bListFocused));

	// images and indentation
	pImageList = GetImageList(LVSIL_SMALL);

	if (pImageList)
	{
		nImage = GetImageIndex(nItem, 0); 
		ImageList_GetIconSize(pImageList->m_hImageList, (int*)&sizeImage.cx, (int*)&sizeImage.cy);

		nIndent = GetItemIndent(nItem) * sizeImage.cx;

		rText.left += nIndent;
		rItem.left += nIndent;

//		if (pImageList == &s_ilIndent)
//			pImageList = NULL;
	}

	// state
	pStateList = GetImageList(LVSIL_STATE);

	if (pStateList)
		ImageList_GetIconSize(pStateList->m_hImageList, (int*)&sizeState.cx, (int*)&sizeState.cy);

	if (lpDrawItemStruct->itemAction & (ODA_DRAWENTIRE | ODA_SELECT))
	{
		// setup colors and pens
		int nImageStyle = GetImageStyle(bSelected, bDropHighlighted, bListFocused);

		// draw item images if required
		int nImageWidth = 0;

		// make sure there is enough space
		lvc.mask = LVCF_WIDTH | LVCF_FMT;
		int nCol = 0;
		BOOL bRes = GetColumn(nCol, &lvc);
		
		// must paint the background of column 0 before the icons
		if (bRes && (pStateList || pImageList))
			pDC->ExtTextOut(0, rItem.top, ETO_CLIPPED | ETO_OPAQUE, CRect(0, rItem.top, lvc.cx, rItem.bottom), _T(""), NULL);

		// state
		if (pStateList && bRes)
		{
			int nState = (GetItemState(nItem, LVIS_STATEIMAGEMASK) & LVIS_STATEIMAGEMASK);
			nState = nState >> 12;

			if (lvc.cx > sizeState.cx)
				pStateList->Draw(pDC, nState, CPoint(rText.left + 1, rText.top), ILD_TRANSPARENT); 

			nImageWidth = sizeState.cx + 2; // 1 pixel border either side
		}
void CXTPSkinObjectToolBar::DrawButton(CDC* pDC, int nIndex)
{
	CToolBarCtrl* pToolBar = (CToolBarCtrl*)this;

	TBBUTTON tbb;
	pToolBar->GetButton(nIndex, &tbb);

	CRect rc;
	if (!pToolBar->GetItemRect(nIndex, rc))
		return;

	int dxText = rc.Width() - (2 * GetMetrics()->m_cxEdge);
	int dyText = rc.Height() - (2 * GetMetrics()->m_cyEdge);

	NMTBCUSTOMDRAW tbcd;
	ZeroMemory(&tbcd, sizeof(NMTBCUSTOMDRAW));
	tbcd.nmcd.hdc = pDC->GetSafeHdc();
	tbcd.nmcd.rc = rc;
	tbcd.nmcd.dwItemSpec = tbb.idCommand;
	tbcd.nmcd.lItemlParam = tbb.dwData;

	SetRect(&tbcd.rcText, 0, 0, dxText, dyText);

	int nHot = (int)pToolBar->SendMessage(TB_GETHOTITEM);
	BOOL fHotTrack = nHot == nIndex;
	BOOL bPressed = tbb.fsState & TBSTATE_PRESSED;
	BOOL bChecked = tbb.fsState & TBSTATE_CHECKED;
	BOOL bEnabled = tbb.fsState & TBSTATE_ENABLED;

	tbcd.nmcd.uItemState = (fHotTrack ? CDIS_HOT : 0)
		| (bPressed ? CDIS_SELECTED : 0)
		| (bChecked ? CDIS_CHECKED : 0)
		| (bEnabled ? 0 : CDIS_DISABLED);

	LRESULT dwCustom = CustomDrawNotify(CDDS_ITEMPREPAINT, &tbcd.nmcd);

	fHotTrack = tbcd.nmcd.uItemState & CDIS_HOT;
	bPressed = tbcd.nmcd.uItemState & CDIS_SELECTED;
	bChecked = tbcd.nmcd.uItemState & CDIS_CHECKED;
	bEnabled = (tbcd.nmcd.uItemState & CDIS_DISABLED) == 0;

	if (!(dwCustom & CDRF_SKIPDEFAULT))
	{
		int dxFace = rc.Width() - 2 * GetMetrics()->m_cxEdge;

		dxText = tbcd.rcText.right - tbcd.rcText.left;
		dyText = tbcd.rcText.bottom - tbcd.rcText.top;

		int x = rc.left + GetMetrics()->m_cxEdge;
		int y = rc.top + GetMetrics()->m_cyEdge;

		BOOL bSplit = HasSplitDropDown(&tbb);
		int cxMenuCheck = bSplit ? GetSystemMetrics(SM_CYMENUCHECK) : 0;

		if (HasDropDownArrow(&tbb))
		{
			dxFace -= 5;
			dxText -= bSplit ? cxMenuCheck : 5;
		}


		LRESULT lPad = SendMessage(TB_GETPADDING);
		int yPad = HIWORD(lPad);
		int xPad = LOWORD(lPad);

		int yOffset = (yPad - (2 * GetMetrics()->m_cyEdge)) / 2;
		if (yOffset < 0)
			yOffset = 0;

		HIMAGELIST himl = GetImageList(HIML_NORMAL, 0);

		int iDxBitmap = 16, iDyBitmap = 16;

		if (himl)
		{
			ImageList_GetIconSize(himl, &iDxBitmap, &iDyBitmap);
		}

		int xCenterOffset =  (dxFace - iDxBitmap) / 2;

		if (GetStyle() & TBSTYLE_LIST)
		{
			xCenterOffset = xPad / 2;
		}
		else if (bSplit)
		{
			xCenterOffset = (dxFace + GetMetrics()->m_cxEdge * 2 - (iDxBitmap + cxMenuCheck)) / 2;
		}

		if ((bPressed || bChecked) && (!(dwCustom & TBCDRF_NOOFFSET)))
		{
			xCenterOffset++;
			yOffset++;
		}

		CXTPSkinManagerClass* pClass = GetSkinClass();

		if (!(dwCustom & TBCDRF_NOEDGES))
		{
			if (bSplit)
			{

				CRect rcSplit(rc), rcSplitDropDown(rc);
				rcSplit.right -= cxMenuCheck;
				rcSplitDropDown.left = rcSplit.right;

				pClass->DrawThemeBackground(pDC, TP_SPLITBUTTON, !bEnabled ? TS_DISABLED :
					bPressed ? TS_PRESSED : bChecked ? TS_CHECKED : fHotTrack ? TS_HOT : TS_NORMAL, &rcSplit);
				pClass->DrawThemeBackground(pDC, TP_SPLITBUTTONDROPDOWN, !bEnabled ? TS_DISABLED :
					bPressed ? TS_PRESSED : bChecked ? TS_CHECKED : fHotTrack ? TS_HOT : TS_NORMAL, &rcSplitDropDown);
			}
			else
			{
				pClass->DrawThemeBackground(pDC, TP_BUTTON, !bEnabled ? TS_DISABLED :
					bPressed ? TS_PRESSED : bChecked ? TS_CHECKED : fHotTrack ? TS_HOT : TS_NORMAL, &rc);
			}
		}

		BOOL fImage = HasButtonImage(&tbb);

		if (fImage)
		{
			int yImage = y, xImage = x;

			if (GetStyle() & TBSTYLE_LIST)
			{
				if (iDyBitmap + yPad >= rc.Height())
					yImage -= GetMetrics()->m_cyEdge;

				if (iDxBitmap + xPad >= rc.Width())
					xImage -= GetMetrics()->m_cxEdge;
			}

			DrawButtonImage(pDC, xImage + xCenterOffset, yImage + yOffset, nIndex);
		}


		CString strText;

		SendMessage(TB_GETBUTTONTEXT, tbb.idCommand, (LPARAM)(LPTSTR)strText.GetBuffer(256));
		strText.ReleaseBuffer();

	#ifdef _UNICODE
		if (strText.IsEmpty() && (int)SendMessage(WM_NOTIFYFORMAT, 0, NF_QUERY) == NFR_ANSI)
		{
			char tText[256];
			tText[0] = 0;
			SendMessage(TB_GETBUTTONTEXTA, tbb.idCommand, (LPARAM)tText);
			strText = tText;
		}
	#endif

		if (!strText.IsEmpty())
		{
			if ((bPressed || bChecked) && (!(dwCustom & TBCDRF_NOOFFSET)))
			{
				x++;
				if (GetStyle() & TBSTYLE_LIST)
					y++;
			}


			if (GetStyle() & TBSTYLE_LIST)
			{
				int iListGap = (GetMetrics()->m_cxEdge * 2);

				if (fImage)
				{
					x += iDxBitmap + iListGap;
					dxText -= iDxBitmap + iListGap;
				}
			}
			else
			{
				y += yOffset + iDyBitmap;
				dyText -= yOffset + iDyBitmap;
			}

			DWORD uiStyle = DT_END_ELLIPSIS;

			int nTextRows = (int)SendMessage(TB_GETTEXTROWS);

			if (nTextRows > 1)
				uiStyle |= DT_WORDBREAK | DT_EDITCONTROL;
			else
				uiStyle |= DT_SINGLELINE;

			if (GetStyle() & TBSTYLE_LIST)
			{
				uiStyle |= DT_LEFT | DT_VCENTER | DT_SINGLELINE;
			}
			else
			{
				uiStyle |= DT_CENTER;
			}

			pDC->SetBkMode(TRANSPARENT);
			pDC->SetTextColor(bEnabled ? GetColor(COLOR_BTNTEXT) :
				GetColor(COLOR_BTNSHADOW));

			if (dxText > 0)
			{
				CRect rcText(x + 1, y + 1, x + 1 + dxText, y + 1 + dyText);
				pDC->DrawText(strText, rcText, uiStyle);
			}
		}


		if (!bSplit && HasDropDownArrow(&tbb))
		{
			CPoint pt(rc.right - 6, rc.CenterPoint().y);
			if (bPressed)
				pt.Offset(1, 1);

			CXTPDrawHelpers::Triangle(pDC, CPoint(pt.x - 2, pt.y - 1), CPoint(pt.x + 2, pt.y - 1), CPoint(pt.x, pt.y + 1), GetColor(COLOR_BTNTEXT));
		}
	}

	if (dwCustom & CDRF_NOTIFYPOSTPAINT)
		CustomDrawNotify(CDDS_ITEMPOSTPAINT, &tbcd.nmcd);
}
Ejemplo n.º 18
0
void _draw_listview(
		LPDRAWITEMSTRUCT itst
	)
{
	DRAWTEXTPARAMS dtp         = { sizeof(dtp) };
	LVCOLUMN       lvc         = { sizeof(lvc) };
	wchar_t        s_text[200] = { 0 };
	int            cx, cy, k   = 0;
	int            offset      = 0;
	int            icon;
	BOOL           is_root;
	int            col_cnt     = Header_GetItemCount( ListView_GetHeader( itst->hwndItem ) );
	LVITEM         lvitem      = { LVIF_TEXT | LVIF_PARAM, itst->itemID, 0, 0, 0, s_text, countof(s_text) };
	COLORREF       bgcolor     = ListView_GetBkColor( itst->hwndItem );

	ListView_GetItem( itst->hwndItem, &lvitem );
	is_root = _is_root_item( lvitem.lParam );

	{
		void *user_data = wnd_get_long( __lists[HMAIN_DRIVES], GWL_USERDATA );
		if (user_data != NULL)
		{
			MessageBox( __dlg, s_text, NULL, 0 );
		}
	}

	if ( ( itst->itemState & ODS_SELECTED ) && IsWindowEnabled( itst->hwndItem ) /*&& ( lvitem.lParam != NULL )*/ ) 
	{
		if ( GetFocus( ) == itst->hwndItem )
		{
			bgcolor = CL_WHITE;
		} else {
			bgcolor = _cl( COLOR_BTNFACE, 80 );
		}
	}
	if ( is_root ) 
	{
		bgcolor = _cl( COLOR_BTNSHADOW, 60 );
	}
	if ( _is_marked_item(lvitem.lParam) ) 
	{
		bgcolor = _cl( COLOR_BTNSHADOW, 35 );
	}
	
	_fill( itst->hDC, &itst->rcItem, bgcolor );

	for ( ; k < col_cnt; k++ )
	{
		lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_IMAGE;
		ListView_GetColumn( itst->hwndItem, k, &lvc );

		itst->rcItem.left  = k ? itst->rcItem.right : 0;
		itst->rcItem.right = itst->rcItem.left + lvc.cx;

		lvitem.iItem       = itst->itemID; 
		lvitem.iSubItem    = k;

		ListView_GetItem( itst->hwndItem, &lvitem );
		dtp.iLeftMargin = dtp.iRightMargin = 5;		

		if ( (!itst->rcItem.left) && _is_icon_show( itst->hwndItem, k ) )
		{
			ImageList_GetIconSize( __dsk_img, &cx, &cy );
			offset = lvitem.lParam && !is_root ? 25 : 3;

			itst->rcItem.left += offset + cy + ( lvitem.lParam && !is_root ? 8 : 4 );
			icon = 0;

			if (! is_root ) 
			{
				if ( _is_splited_item(lvitem.lParam) ) icon = 1;
				if ( _is_cdrom_item(lvitem.lParam) )   icon = 2;
			}

			ImageList_Draw(
				__dsk_img, icon, itst->hDC, offset, itst->rcItem.top + 3, ILD_TRANSPARENT
				);
		} else 
		{
			offset = 0;
		}
		if ( offset && is_root )
		{
			DrawState(
				itst->hDC, 0, NULL, (LPARAM)s_text, 0, 
				itst->rcItem.left+5, itst->rcItem.top, 0, 0, DST_PREFIXTEXT | DSS_MONO
				);
		} else 
		{
			if ( wcslen(s_text) != 0 ) 
			{
				COLORREF text_color = GetSysColor( COLOR_WINDOWTEXT );

				if ( !_is_active_item(lvitem.lParam) )
				{
					text_color = GetSysColor( COLOR_GRAYTEXT );
				}
				SetTextColor( itst->hDC, text_color );

				if ( k >= 4 )
				{
					SelectObject( itst->hDC, __font_bold );
				}
				if ( !IsWindowEnabled( itst->hwndItem ) )
				{
					SetTextColor( itst->hDC, GetSysColor(COLOR_GRAYTEXT) );

					DrawTextEx(
						itst->hDC, s_text, -1, &itst->rcItem,
						DT_END_ELLIPSIS | ((lvc.fmt & LVCFMT_RIGHT) ? DT_RIGHT : FALSE), &dtp
						);
				} else 
				{
					DrawTextEx(
						itst->hDC, s_text, -1, &itst->rcItem,
						DT_END_ELLIPSIS | ((lvc.fmt & LVCFMT_RIGHT) ? DT_RIGHT : FALSE), &dtp
						);
					/*
					if ( GetFocus( ) == itst->hwndItem )
					{
						DrawFocusRect( itst->hDC, &itst->rcItem );
					}
					*/
				}
			}
		}
	}							
}
Ejemplo n.º 19
0
void ImageListItemType::GetSize(SIZE& size)
{
	ImageList_GetIconSize(m_hImList, (int*)&size.cx, (int*)&size.cy);
}
void CXTPSkinObjectHeader::DrawItemEntry(CDC* pDC, int nIndex, CRect rcItem, int nState)
{
	CXTPSkinManagerClass* pClass = GetSkinClass();

	CHeaderCtrl* pHeaderCtrl = (CHeaderCtrl*)this;
	CImageList* pImageList = CImageList::FromHandle((HIMAGELIST)
		::SendMessage(pHeaderCtrl->m_hWnd, HDM_GETIMAGELIST, 0, 0L));

	// Set up the header item order array.
	HD_ITEM hdi;
	::ZeroMemory(&hdi, sizeof(HD_ITEM));

	hdi.fmt = HDF_STRING | HDF_IMAGE;
	hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_IMAGE | HDI_LPARAM;

	// Get the header item text and format
	CString strCaption;
	LPTSTR pszText = strCaption.GetBuffer(256);
	pszText[0] = 0;
	hdi.pszText = pszText;
	hdi.cchTextMax = 255;

	BOOL bResult = pHeaderCtrl->GetItem(nIndex, &hdi);

	strCaption.ReleaseBuffer();

#ifdef _UNICODE
	if (!bResult)
	{
		char tText[256];
		tText[0] = 0;

		HD_ITEMA hdia;
		::ZeroMemory(&hdia, sizeof(HD_ITEMA));

		hdia.fmt = HDF_STRING | HDF_IMAGE;
		hdia.mask = HDI_TEXT | HDI_FORMAT | HDI_IMAGE | HDI_LPARAM;

		// Get the header item text and format
		hdia.pszText = tText;
		hdia.cchTextMax = 255;

		::SendMessage(pHeaderCtrl->m_hWnd, HDM_GETITEMA, nIndex, (LPARAM)&hdia);

		strCaption = tText;
		hdi.fmt = hdia.fmt;
		hdi.iImage = hdia.iImage;
		hdi.lParam = hdia.lParam;
	}
#else
	bResult;
#endif

	if (hdi.fmt & HDF_OWNERDRAW)
	{
		DRAWITEMSTRUCT dis;

		dis.CtlType = ODT_HEADER;
		dis.CtlID = (UINT)GetDlgCtrlID();
		dis.itemID = nIndex;
		dis.itemAction = ODA_DRAWENTIRE;
		dis.itemState = (nState == HIS_PRESSED) ? ODS_SELECTED : 0;
		dis.hwndItem = m_hWnd;
		dis.hDC = pDC->GetSafeHdc();
		dis.rcItem = rcItem;
		dis.itemData = hdi.lParam;

		// Now send it off to my parent...
		if (GetParent()->SendMessage(WM_DRAWITEM, dis.CtlID,
			(LPARAM)(DRAWITEMSTRUCT*)&dis))
		{
			return;
		}
	}

	CRect rcText(rcItem);

	if (pImageList && (hdi.fmt & HDF_IMAGE) && hdi.iImage >= 0 && hdi.iImage < pImageList->GetImageCount())
	{
		int iBitmapMargin = (int)SendMessage(HDM_GETBITMAPMARGIN);
		if (iBitmapMargin == 0)
			iBitmapMargin = GetMetrics()->m_cxEdge * 3;
		int cxBitmap = 16, cyBitmap = 16;
		ImageList_GetIconSize(pImageList->GetSafeHandle(), &cxBitmap, &cyBitmap);

		CPoint pt(rcItem.left + iBitmapMargin, (rcItem.bottom + rcItem.top - cyBitmap) / 2);

		if (hdi.fmt & HDF_BITMAP_ON_RIGHT)
		{
			CSize sz = pDC->GetTextExtent(strCaption);

			pt.x += sz.cx + iBitmapMargin + 9;
			if (pt.x + cxBitmap > rcItem.right - 3)
				pt.x = max(rcItem.left + 6, rcItem.right - 3 - cxBitmap);
			if (nState == HIS_PRESSED)
				pt.x ++;

			pImageList->Draw(pDC, hdi.iImage, pt, ILD_TRANSPARENT);
			rcText.right = pt.x + 6;
		}
		else
		{
			if (nState == HIS_PRESSED)
				pt.x ++;
			pImageList->Draw(pDC, hdi.iImage, pt, ILD_TRANSPARENT);

			rcText.left += cxBitmap + iBitmapMargin;
		}
	}

	if (((hdi.fmt & HDF_IMAGE) == 0) && ((hdi.fmt & HDF_SORTUP) || (hdi.fmt & HDF_SORTDOWN)))
	{
		int iBitmapMargin = GetMetrics()->m_cxEdge * 3;
		CSize sz = pDC->GetTextExtent(strCaption);

		CPoint pt(rcItem.left + iBitmapMargin, (rcItem.bottom + rcItem.top - 2) / 2);

		pt.x += sz.cx + iBitmapMargin + 9;
		if (pt.x + 9 > rcItem.right - 3)
			pt.x = max(rcItem.left + 6, rcItem.right - 3 - 9);

		if (hdi.fmt & HDF_SORTUP)
		{
			XTPDrawHelpers()->Triangle(pDC, CPoint(pt.x - 4, pt.y + 2),
				CPoint(pt.x, pt.y - 2), CPoint(pt.x + 4, pt.y + 2), GetColor(COLOR_3DSHADOW));
		}
		else
		{
			XTPDrawHelpers()->Triangle(pDC, CPoint(pt.x - 4, pt.y - 2),
				CPoint(pt.x, pt.y + 2), CPoint(pt.x + 4, pt.y - 2), GetColor(COLOR_3DSHADOW));
		}
		rcText.right = pt.x;
	}

	UINT nFormat = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX;

	// determine justification for text.
	switch (hdi.fmt & HDF_JUSTIFYMASK)
	{
	case HDF_LEFT:
		nFormat |= DT_LEFT;
		rcText.DeflateRect(9, 0, 6, 0);
		break;

	case HDF_CENTER:
		nFormat |= DT_CENTER;
		rcText.DeflateRect(6, 0, 6, 0);
		break;

	case HDF_RIGHT:
		nFormat |= DT_RIGHT;
		rcText.DeflateRect(6, 0, 9, 0);
		break;
	}

	if (rcText.Width() > 0)
	{
		if (nState == HIS_PRESSED)
			rcText.OffsetRect(1, 1);

		// draw text.
		pDC->SetTextColor(GetColor(COLOR_BTNTEXT));
		pClass->DrawThemeText(pDC, HP_HEADERITEM, nState, strCaption, nFormat, &rcText);
	}
}
Ejemplo n.º 21
0
Archivo: main.c Proyecto: yhcflyy/ui
static LRESULT CALLBACK tableWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	struct table *t;
	HDC dc;
	PAINTSTRUCT ps;
	NMHDR *nmhdr = (NMHDR *) lParam;
	NMHEADERW *nm = (NMHEADERW *) lParam;

	t = (struct table *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
	if (t == NULL) {
		// we have to do things this way because creating the header control will fail mysteriously if we create it first thing
		// (which is fine; we can get the parent hInstance this way too)
		if (uMsg == WM_NCCREATE) {
			CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;

			t = (struct table *) malloc(sizeof (struct table));
			if (t == NULL)
				abort();
			ZeroMemory(t, sizeof (struct table));
			t->hwnd = hwnd;
			// TODO this should be a global
			t->defaultFont = (HFONT) GetStockObject(SYSTEM_FONT);
			if (t->defaultFont == NULL)
				abort();
			t->font = t->defaultFont;
t->selected = 5;t->count=100;//TODO
			t->header = CreateWindowExW(0,
				WC_HEADERW, L"",
				// TODO is HOTTRACK needed?
				WS_CHILD | HDS_FULLDRAG | HDS_HORZ | HDS_HOTTRACK,
				0, 0, 0, 0,
				t->hwnd, (HMENU) 100, cs->hInstance, NULL);
			if (t->header == NULL)
				abort();
{t->imagelist = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32, 1, 1);
if(t->imagelist==NULL)abort();
{
HICON icon;
int unused;
icon = LoadIconW(NULL, IDI_ERROR);
if(icon == NULL)abort();
if (ImageList_AddIcon(t->imagelist, icon) == -1)abort();
if (ImageList_GetIconSize(t->imagelist, &unused, &(t->imagelistHeight)) == 0)abort();
}
}
			t->checkboxes = makeCheckboxImageList(t->hwnd, &(t->theme), &(t->checkboxWidth), &(t->checkboxHeight));
			t->focusedColumn = -1;
			SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) t);
		}
		// even if we did the above, fall through
		return DefWindowProcW(hwnd, uMsg, wParam, lParam);
	}
	switch (uMsg) {
	case WM_PAINT:
		dc = BeginPaint(hwnd, &ps);
		if (dc == NULL)
			abort();
		drawItems(t, dc, ps.rcPaint);
		EndPaint(hwnd, &ps);
		return 0;
	case WM_SETFONT:
		t->font = (HFONT) wParam;
		if (t->font == NULL)
			t->font = t->defaultFont;
		// also set the header font
		SendMessageW(t->header, WM_SETFONT, wParam, lParam);
		if (LOWORD(lParam) != FALSE) {
			// the scrollbar page size will change so redraw that too
			// also recalculate the header height
			// TODO do that when this is FALSE too somehow
			resize(t);
			redrawAll(t);
		}
		return 0;
	case WM_GETFONT:
		return (LRESULT) t->font;
	case WM_VSCROLL:
		vscroll(t, wParam);
		return 0;
	case WM_MOUSEWHEEL:
		wheelscroll(t, wParam);
		return 0;
	case WM_HSCROLL:
		hscroll(t, wParam);
		return 0;
	case WM_SIZE:
		resize(t);
		return 0;
	case WM_LBUTTONDOWN:
		selectItem(t, wParam, lParam);
		return 0;
	case WM_SETFOCUS:
	case WM_KILLFOCUS:
		// all we need to do here is redraw the highlight
		// TODO ensure giving focus works right
		redrawRow(t, t->selected);
		return 0;
	case WM_KEYDOWN:
		keySelect(t, wParam, lParam);
		return 0;
	// TODO header double-click
	case WM_NOTIFY:
		if (nmhdr->hwndFrom == t->header)
			switch (nmhdr->code) {
			// I could use HDN_TRACK but wine doesn't emit that
			case HDN_ITEMCHANGING:
			case HDN_ITEMCHANGED:		// TODO needed?
				recomputeHScroll(t);
				redrawAll(t);
				return FALSE;
			}
		return DefWindowProcW(hwnd, uMsg, wParam, lParam);
	// TODO others?
	case WM_WININICHANGE:
	case WM_SYSCOLORCHANGE:
	case WM_THEMECHANGED:
		if (ImageList_Destroy(t->checkboxes) == 0)
			abort();
		t->checkboxes = makeCheckboxImageList(t->hwnd, &(t->theme), &(t->checkboxWidth), &(t->checkboxHeight));
		resize(t);		// TODO needed?
		redrawAll(t);
		// now defer back to DefWindowProc() in case other things are needed
		// TODO needed?
		return DefWindowProcW(hwnd, uMsg, wParam, lParam);
	case tableAddColumn:
		addColumn(t, wParam, lParam);
		return 0;
	case WM_GETOBJECT:		// accessibility
/*
		if (((DWORD) lParam) == OBJID_CLIENT) {
			TODO *server;
			LRESULT lResult;

			// TODO create the server object
			lResult = LresultFromObject(IID_IAccessible, wParam, server);
			if (/* TODO failure *|/)
				abort();
			// TODO release object
			return lResult;
		}
*/
		return DefWindowProcW(hwnd, uMsg, wParam, lParam);
	default:
		return DefWindowProcW(hwnd, uMsg, wParam, lParam);
	}
	abort();
	return 0;		// unreached
}
Ejemplo n.º 22
0
inline BOOL CBackgroundUpdater::RunningProc()
{
	BuDebugMessage1("BU RunningProc() BEGIN, running thread 0x%X",GetCurrentThreadId());

	// CLocatedItem::LoadThumbnail needs this
	CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
	
	for (;;)
	{
		InterlockedExchange(&m_lIsWaiting,TRUE);

		BuDebugMessage("BU: Going to sleep.");
		
		DWORD nRet=WaitForMultipleObjects(2,m_phEvents,FALSE,INFINITE);
		InterlockedExchange(&m_lIsWaiting,FALSE);
		InterlockedExchange(&m_lIgnoreItemsAndGoToSleep,FALSE);
		
		BuDebugMessage2("BU: nRet=%d, %d item to be updated",nRet,m_aUpdateList.GetSize());

		if (nRet==WAIT_TIMEOUT)
			continue;
		if (nRet==WAIT_OBJECT_0) // 0 = end event
			break;
		else if (nRet==WAIT_OBJECT_0+1)
		{
			// Resolve list style, list control size and icon size
			// Do this everytime because size of dialog or list style may be changed or 
			RECT rcViewRect;
			int nIconSizeX,nIconSizeY;

			DWORD nListStyle=m_pList->GetStyle()&LVS_TYPEMASK;
			m_pList->GetClientRect(&rcViewRect);
			ImageList_GetIconSize(
				m_pList->GetImageList(nListStyle==LVS_ICON?LVSIL_NORMAL:LVSIL_SMALL),
				&nIconSizeX,&nIconSizeY);

			

			for (;;)
			{
				// We use local variable for the array so that
				// other operations are not delayed
				
				EnterCriticalSection(&m_csUpdateList);
				
				CArrayFP<Item*> aLocalUpdateList;
				aLocalUpdateList.Swap(m_aUpdateList);

				LeaveCriticalSection(&m_csUpdateList);
                
				// No items in list, there is no need to do anything
				if (aLocalUpdateList.GetSize()==0)
					break;
			
				
				for (int i=0;i<aLocalUpdateList.GetSize() && !m_lIgnoreItemsAndGoToSleep;i++)
				{
					Item* pItem=aLocalUpdateList.GetAt(i);

					// At first, check that item is visible and threfore needs to be updated
					//BuDebugMessage1("Checking whether item %S needs to be updated ",pItem->m_pItem->GetName());

					POINT pt;
					if (m_pList->GetItemPosition(pItem->m_iItem,&pt))
					{
						// X axes does not need to be checked when report mode is on
						if (nListStyle==LVS_REPORT)
						{
							if (pt.y >= -nIconSizeY && pt.y<=rcViewRect.bottom)
							{
								BOOL bReDraw=FALSE;
								
								BuDebugMessage1("BU: Refreshing %s (1)",pItem->m_pItem->GetName());
								pItem->m_pItem->ReFresh(pItem->m_aDetails,bReDraw); // Item is visible

								if (bReDraw)
									m_pList->PostMessage(LVM_REDRAWITEMS,pItem->m_iItem,pItem->m_iItem);
							}
						}
						else
						{
							POINT ptOrigin;
							if (!m_pList->GetOrigin(&ptOrigin))
							{
								ptOrigin.x=0;
								ptOrigin.y=0;
							}

							if (pt.y >= ptOrigin.y-nIconSizeY && pt.y<=rcViewRect.bottom+ptOrigin.y &&
								pt.x >= ptOrigin.x-nIconSizeX && pt.x<=rcViewRect.right+ptOrigin.x)
							{
								BOOL bReDraw=FALSE;
								
								BuDebugMessage1("BU: Refreshing %S (2)",pItem->m_pItem->GetName());
								pItem->m_pItem->ReFresh(pItem->m_aDetails,bReDraw); // Item is visible

								if (bReDraw)
									m_pList->PostMessage(LVM_REDRAWITEMS,pItem->m_iItem,pItem->m_iItem);
							}
						}
					}
					
				}
				aLocalUpdateList.RemoveAll();
				
			}
			ResetEvent(m_phEvents[1]);
			
		}
	}
	delete this;
	
	BuDebugMessage("BU: RunningProc() END");

	CoUninitialize();
	return TRUE;
}
Ejemplo n.º 23
0
// Calculate the dimensions and draw the balloon header
CSize CBalloonHelp::DrawHeader(CDC* pDC, bool bDraw)
{
	CSize sizeHdr(0,0);
	CRect rectClient;
	GetClientRect(&rectClient);   // use this for positioning when drawing
	// else if content is wider than title, centering wouldn't work
	
	// calc & draw icon
	if ( NULL != m_ilIcon.m_hImageList )
	{
		int x = 0;
		int y = 0;
		ImageList_GetIconSize(m_ilIcon, &x, &y);
		sizeHdr.cx += x;
		sizeHdr.cy = max(sizeHdr.cy, y);
		m_ilIcon.SetBkColor(m_crBackground);
		if (bDraw)
			m_ilIcon.Draw(pDC, 0, CPoint(0,0), ILD_NORMAL);//ILD_TRANSPARENT);
		rectClient.left += x;
	}
	
	// calc & draw close button
	if ( m_unOptions & unSHOW_CLOSE_BUTTON )
	{
		// if something is already in the header (icon) leave space
		if ( sizeHdr.cx > 0 )
			sizeHdr.cx += nTIP_MARGIN;
		sizeHdr.cx += 16;
		sizeHdr.cy = max(sizeHdr.cy, 16);
		if (bDraw)
			pDC->DrawFrameControl(CRect(rectClient.right-16,0,rectClient.right,16), DFC_CAPTION, DFCS_CAPTIONCLOSE|DFCS_FLAT);
		rectClient.right -= 16;
	}
	
	// calc title size
	CString strTitle;
	GetWindowText(strTitle);
	if ( !strTitle.IsEmpty() )
	{
		CFont* pOldFont = pDC->SelectObject(m_pTitleFont);
		
		// if something is already in the header (icon or close button) leave space
		if ( sizeHdr.cx > 0 ) 
			sizeHdr.cx += nTIP_MARGIN;
		CRect rectTitle(0,0,0,0);
		pDC->DrawText(strTitle, &rectTitle, DT_CALCRECT | DT_NOPREFIX | DT_EXPANDTABS | DT_SINGLELINE);
		sizeHdr.cx += rectTitle.Width();
		sizeHdr.cy = max(sizeHdr.cy, rectTitle.Height());
		
		// draw title
		if ( bDraw )
		{
			pDC->SetBkMode(TRANSPARENT);
			pDC->SetTextColor(m_crForeground);
			pDC->DrawText(strTitle, &rectClient, DT_CENTER | DT_NOPREFIX  | DT_EXPANDTABS | DT_SINGLELINE);
		}
		
		// cleanup
		pDC->SelectObject(pOldFont);
	}
	
	return sizeHdr;
}
Ejemplo n.º 24
0
HIMAGELIST
SdkCreateGrayImageList(
	IN HIMAGELIST himlNormal
	)
{
	int Count, i;
	int Width, Height;
	HIMAGELIST himlGray;
	HDC hdcDesktop;
	HDC hdcMem;
	RECT rc;
	COLORREF crMask;
	HPALETTE hpal;
	UINT index;
	HGDIOBJ hbm;
	HGDIOBJ hbmOld;
	COLORREF rgb;
	BYTE gray;
	HWND hWnd;
	int x, y;

	Count = ImageList_GetImageCount(himlNormal);
	if (Count == 0) {
		return NULL;
	}

	ImageList_GetIconSize(himlNormal, &Width, &Height);
	himlGray = ImageList_Create(Width, Height, ILC_COLOR24 | ILC_MASK, Count, 0);

	hdcDesktop = GetDC(NULL);
	hdcMem = CreateCompatibleDC(NULL);
	
	rc.top = rc.left = 0;
	rc.bottom = Height;
	rc.right = Width;
	crMask = RGB(200, 199, 200);

	if (GetDeviceCaps(hdcDesktop, BITSPIXEL) < 24) {
		hpal = (HPALETTE)GetCurrentObject(hdcDesktop, OBJ_PAL);
		index = GetNearestPaletteIndex(hpal, crMask);
		if (index != CLR_INVALID) { 
			crMask = PALETTEINDEX(index);
		}
	}

	for (i = 0 ; i < Count; ++i) {

		hbm = CreateCompatibleBitmap(hdcDesktop, Width, Height);
		hbmOld = SelectObject(hdcMem, hbm);

		SdkFillSolidRect(hdcMem, crMask, &rc);

		ImageList_SetBkColor(himlNormal, crMask);
		ImageList_Draw(himlNormal, i, hdcMem, 0, 0, ILD_NORMAL);

		for (x = 0 ; x < Width; ++x) {
			for (y = 0; y < Height; ++y) {
				rgb = GetPixel(hdcMem, x, y);
				if (rgb != crMask) { 
					gray = (BYTE) (95 + (GetRValue(rgb) * 3 + GetGValue(rgb) * 6 + GetBValue(rgb)) / 20);
					SetPixel(hdcMem, x, y, RGB(gray, gray, gray));
				}
			}
		}

		hbm = SelectObject(hdcMem, hbmOld);
		ImageList_AddMasked(himlGray, (HBITMAP)hbm, crMask);
		DeleteObject(hbm);
	}

	DeleteDC(hdcMem);
	hWnd = WindowFromDC(hdcDesktop);
	ReleaseDC(hWnd, hdcDesktop);

	return himlGray; 
}
Ejemplo n.º 25
0
void AddMainToolbarButtons(PluginInfo *plugin)
{
	HDC	hDC;
	int	iNumBits;
	HIMAGELIST hilToolbar;
	HBITMAP hbmpPGPkeys;
	int nPGPkeysSTR;
	int nPGPkeysBMP;
	TBBUTTON tbb[1];
	char szText[255];
	HINSTANCE hInst;
	int nX;
	int nY;
	
	hInst = UIGetInstance();
	
	hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar, TB_GETIMAGELIST, 
								0, 0);
	
	hDC = GetDC (NULL);		// DC for desktop
	iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
	ReleaseDC (NULL, hDC);

	ImageList_GetIconSize(hilToolbar, &nX, &nY);
	if (nX < 20)
		plugin->bSmallIcons = TRUE;
	else
		plugin->bSmallIcons = FALSE;
	
	if (iNumBits <= 8) 
	{
		if (plugin->bSmallIcons)
			hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYSO4));
		else
			hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYSOFF4));
	}
	else
	{
		if (plugin->bSmallIcons)
			hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYSO));
		else
			hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYSOFF));
	}
	
	nPGPkeysBMP = ImageList_AddMasked(hilToolbar, hbmpPGPkeys, 
					TRANSPARENT_COLOR);
	DeleteObject(hbmpPGPkeys);
	plugin->nPGPKeysImage = nPGPkeysBMP;
	
	SendMessage(plugin->hToolbar, TB_SETIMAGELIST, 0, (LPARAM) hilToolbar);
	
	hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar, 
								TB_GETHOTIMAGELIST, 0, 0);
	
	if (iNumBits <= 8)
	{
		if (plugin->bSmallIcons)
			hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYS4));
		else
			hbmpPGPkeys = LoadBitmap(hInst, 
							MAKEINTRESOURCE(IDB_PGPKEYSLARGE4));
	}
	else
	{
		if (plugin->bSmallIcons)
			hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYS));
		else
			hbmpPGPkeys = LoadBitmap(hInst, 
							MAKEINTRESOURCE(IDB_PGPKEYSLARGE));
	}
	
	ImageList_AddMasked(hilToolbar, hbmpPGPkeys, TRANSPARENT_COLOR);
	DeleteObject(hbmpPGPkeys);
	
	SendMessage(plugin->hToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM) hilToolbar);
	
	UIGetString(szText, 254, IDS_TOOLTIP_PGPKEYS);
	nPGPkeysSTR = SendMessage(plugin->hToolbar, TB_ADDSTRING, 0,
					(LPARAM) szText);
	plugin->nPGPKeysString = nPGPkeysSTR;
	
	tbb[0].iBitmap = nPGPkeysBMP;
	tbb[0].idCommand = IDC_PGPKEYS;
	tbb[0].fsState = TBSTATE_ENABLED;
	tbb[0].fsStyle = TBSTYLE_BUTTON;
	tbb[0].dwData = 0;
	tbb[0].iString = nPGPkeysSTR;
	
	SendMessage(plugin->hToolbar, TB_ADDBUTTONS, 1, (LPARAM) &tbb);
	
	plugin->nPGPKeysButton = SendMessage(plugin->hToolbar, TB_COMMANDTOINDEX,
								IDC_PGPKEYS, 0);
	
	return;
}
Ejemplo n.º 26
0
static LRESULT CALLBACK ToolbarParentWndProc(HWND hDlg, 
											 UINT msg,
											 WPARAM wParam, 
											 LPARAM lParam)
{
	WNDPROC lpOldProc;
	PluginInfo *plugin;
	LPNMHDR lpnm;
	LPNMTOOLBAR lptb;

	lpOldProc = (WNDPROC)GetProp( hDlg, "oldproc" );
	plugin = GetPluginInfo(hDlg);

	lpnm = (LPNMHDR) lParam;
	lptb = (LPNMTOOLBAR) lParam;

	switch(msg)
	{
	case WM_NOTIFY:
		{
			int nIndex;

			if (lpnm->code == TBN_BEGINADJUST)
			{
				nIndex = SendMessage(plugin->hToolbar, TB_COMMANDTOINDEX,
							IDC_PGPKEYS, 0);

				SendMessage(plugin->hToolbar, TB_DELETEBUTTON, nIndex, 0);
				plugin->nPGPKeysButton = -1;
			}

			if (lpnm->code == TBN_ENDADJUST)
			{
				TBBUTTON tbb[1];
				HIMAGELIST hilToolbar;
				int nX;
				int nY;
				LRESULT lResult;
				
				lResult = CallWindowProc(lpOldProc, hDlg, msg, wParam, 
							lParam);

				hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar, 
											TB_GETIMAGELIST, 0, 0);

				ImageList_GetIconSize(hilToolbar, &nX, &nY);
				if ((nX < 20) && !(plugin->bSmallIcons))
					AddMainToolbarButtons(plugin);
				else if ((nX > 20) && plugin->bSmallIcons)
					AddMainToolbarButtons(plugin);
				else
				{
					tbb[0].iBitmap = plugin->nPGPKeysImage;
					tbb[0].idCommand = IDC_PGPKEYS;
					tbb[0].fsState = TBSTATE_ENABLED;
					tbb[0].fsStyle = TBSTYLE_BUTTON;
					tbb[0].dwData = 0;
					tbb[0].iString = plugin->nPGPKeysString;
					
					SendMessage(plugin->hToolbar, TB_ADDBUTTONS, 1, 
						(LPARAM) &tbb);
					
					plugin->nPGPKeysButton = SendMessage(plugin->hToolbar,
												TB_COMMANDTOINDEX,
												IDC_PGPKEYS,
												0);
				}

				return lResult;
			}

			break;
		}
	}

	return CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
}
Ejemplo n.º 27
0
void DrawStartPage(WindowInfo& win, HDC hdc, FileHistory& fileHistory, COLORREF colorRange[2])
{
    HPEN penBorder = CreatePen(PS_SOLID, DOCLIST_SEPARATOR_DY, WIN_COL_BLACK);
    HPEN penThumbBorder = CreatePen(PS_SOLID, DOCLIST_THUMBNAIL_BORDER_W, WIN_COL_BLACK);
    HPEN penLinkLine = CreatePen(PS_SOLID, 1, COL_BLUE_LINK);

    ScopedFont fontSumatraTxt(GetSimpleFont(hdc, L"MS Shell Dlg", 24));
    ScopedFont fontLeftTxt(GetSimpleFont(hdc, L"MS Shell Dlg", 14));

    HGDIOBJ origFont = SelectObject(hdc, fontSumatraTxt); /* Just to remember the orig font */

    ClientRect rc(win.hwndCanvas);
    FillRect(hdc, &rc.ToRECT(), gBrushLogoBg);

    SelectObject(hdc, gBrushLogoBg);
    SelectObject(hdc, penBorder);

    bool isRtl = IsUIRightToLeft();

    /* render title */
    RectI titleBox = RectI(PointI(0, 0), CalcSumatraVersionSize(hdc));
    titleBox.x = rc.dx - titleBox.dx - 3;
    DrawSumatraVersion(hdc, titleBox);
    PaintLine(hdc, RectI(0, titleBox.dy, rc.dx, 0));

    /* render recent files list */
    SelectObject(hdc, penThumbBorder);
    SetBkMode(hdc, TRANSPARENT);
    SetTextColor(hdc, WIN_COL_BLACK);

    rc.y += titleBox.dy;
    rc.dy -= titleBox.dy;
    FillRect(hdc, &rc.ToRECT(), gBrushAboutBg);
    rc.dy -= DOCLIST_BOTTOM_BOX_DY;

    Vec<DisplayState *> list;
    fileHistory.GetFrequencyOrder(list);

    int width = limitValue((rc.dx - DOCLIST_MARGIN_LEFT - DOCLIST_MARGIN_RIGHT + DOCLIST_MARGIN_BETWEEN_X) / (THUMBNAIL_DX + DOCLIST_MARGIN_BETWEEN_X), 1, DOCLIST_MAX_THUMBNAILS_X);
    int height = min((rc.dy - DOCLIST_MARGIN_TOP - DOCLIST_MARGIN_BOTTOM + DOCLIST_MARGIN_BETWEEN_Y) / (THUMBNAIL_DY + DOCLIST_MARGIN_BETWEEN_Y), FILE_HISTORY_MAX_FREQUENT / width);
    PointI offset(rc.x + DOCLIST_MARGIN_LEFT + (rc.dx - width * THUMBNAIL_DX - (width - 1) * DOCLIST_MARGIN_BETWEEN_X - DOCLIST_MARGIN_LEFT - DOCLIST_MARGIN_RIGHT) / 2, rc.y + DOCLIST_MARGIN_TOP);
    if (offset.x < ABOUT_INNER_PADDING)
        offset.x = ABOUT_INNER_PADDING;
    else if (list.Count() == 0)
        offset.x = DOCLIST_MARGIN_LEFT;

    SelectObject(hdc, fontSumatraTxt);
    SIZE txtSize;
    const WCHAR *txt = _TR("Frequently Read");
    GetTextExtentPoint32(hdc, txt, (int)str::Len(txt), &txtSize);
    RectI headerRect(offset.x, rc.y + (DOCLIST_MARGIN_TOP - txtSize.cy) / 2, txtSize.cx, txtSize.cy);
    if (isRtl)
        headerRect.x = rc.dx - offset.x - headerRect.dx;
    DrawText(hdc, txt, -1, &headerRect.ToRECT(), (isRtl ? DT_RTLREADING : DT_LEFT) | DT_NOPREFIX);

    SelectObject(hdc, fontLeftTxt);
    SelectObject(hdc, GetStockBrush(NULL_BRUSH));

    win.staticLinks.Reset();
    for (int h = 0; h < height; h++) {
        for (int w = 0; w < width; w++) {
            if (h * width + w >= (int)list.Count()) {
                // display the "Open a document" link right below the last row
                height = w > 0 ? h + 1 : h;
                break;
            }
            DisplayState *state = list.At(h * width + w);

            RectI page(offset.x + w * (int)(THUMBNAIL_DX + DOCLIST_MARGIN_BETWEEN_X * win.uiDPIFactor),
                       offset.y + h * (int)(THUMBNAIL_DY + DOCLIST_MARGIN_BETWEEN_Y * win.uiDPIFactor),
                       THUMBNAIL_DX, THUMBNAIL_DY);
            if (isRtl)
                page.x = rc.dx - page.x - page.dx;
            bool loadOk = true;
            if (!state->thumbnail)
                loadOk = LoadThumbnail(*state);
            if (loadOk && state->thumbnail) {
                SizeI thumbSize = state->thumbnail->Size();
                if (thumbSize.dx != THUMBNAIL_DX || thumbSize.dy != THUMBNAIL_DY) {
                    page.dy = thumbSize.dy * THUMBNAIL_DX / thumbSize.dx;
                    page.y += THUMBNAIL_DY - page.dy;
                }
                HRGN clip = CreateRoundRectRgn(page.x, page.y, page.x + page.dx, page.y + page.dy, 10, 10);
                SelectClipRgn(hdc, clip);
                RenderedBitmap *clone = state->thumbnail->Clone();
                UpdateBitmapColorRange(clone->GetBitmap(), colorRange);
                clone->StretchDIBits(hdc, page);
                SelectClipRgn(hdc, NULL);
                DeleteObject(clip);
                delete clone;
            }
            RoundRect(hdc, page.x, page.y, page.x + page.dx, page.y + page.dy, 10, 10);

            int iconSpace = (int)(20 * win.uiDPIFactor);
            RectI rect(page.x + iconSpace, page.y + page.dy + 3, page.dx - iconSpace, iconSpace);
            if (isRtl)
                rect.x -= iconSpace;
            DrawText(hdc, path::GetBaseName(state->filePath), -1, &rect.ToRECT(), DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX | (isRtl ? DT_RIGHT : DT_LEFT));

            SHFILEINFO sfi;
            HIMAGELIST himl = (HIMAGELIST)SHGetFileInfo(state->filePath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
            ImageList_Draw(himl, sfi.iIcon, hdc,
                           isRtl ? page.x + page.dx - (int)(16 * win.uiDPIFactor) : page.x,
                           rect.y, ILD_TRANSPARENT);

            win.staticLinks.Append(StaticLinkInfo(rect.Union(page), state->filePath, state->filePath));
        }
    }

    /* render bottom links */
    rc.y += DOCLIST_MARGIN_TOP + height * THUMBNAIL_DY + (height - 1) * DOCLIST_MARGIN_BETWEEN_Y + DOCLIST_MARGIN_BOTTOM;
    rc.dy = DOCLIST_BOTTOM_BOX_DY;

    SetTextColor(hdc, COL_BLUE_LINK);
    SelectObject(hdc, penLinkLine);

    HIMAGELIST himl = (HIMAGELIST)SendMessage(win.hwndToolbar, TB_GETIMAGELIST, 0, 0);
    RectI rectIcon(offset.x, rc.y, 0, 0);
    ImageList_GetIconSize(himl, &rectIcon.dx, &rectIcon.dy);
    rectIcon.y += (rc.dy - rectIcon.dy) / 2;
    if (isRtl)
        rectIcon.x = rc.dx - offset.x - rectIcon.dx;
    ImageList_Draw(himl, 0 /* index of Open icon */, hdc, rectIcon.x, rectIcon.y, ILD_NORMAL);

    txt = _TR("Open a document...");
    GetTextExtentPoint32(hdc, txt, (int)str::Len(txt), &txtSize);
    RectI rect(offset.x + rectIcon.dx + 3, rc.y + (rc.dy - txtSize.cy) / 2, txtSize.cx, txtSize.cy);
    if (isRtl)
        rect.x = rectIcon.x - rect.dx - 3;
    DrawText(hdc, txt, -1, &rect.ToRECT(), isRtl ? DT_RTLREADING : DT_LEFT);
    PaintLine(hdc, RectI(rect.x, rect.y + rect.dy, rect.dx, 0));
    // make the click target larger
    rect = rect.Union(rectIcon);
    rect.Inflate(10, 10);
    win.staticLinks.Append(StaticLinkInfo(rect, SLINK_OPEN_FILE));

    rect = DrawBottomRightLink(win.hwndCanvas, hdc, _TR("Hide frequently read"));
    win.staticLinks.Append(StaticLinkInfo(rect, SLINK_LIST_HIDE));

    SelectObject(hdc, origFont);

    DeleteObject(penBorder);
    DeleteObject(penThumbBorder);
    DeleteObject(penLinkLine);
}