Add a background image using Cximage in CTreeCtrl and add a background image to the word

Source: Internet
Author: User
Tags drawtext

Loading background images in the CTreeCtrl, there are many examples on the internet, some feasible, some can not, the two days while looking at the data on the side of the collation, wrote a cximage loading pictures with the method, we may refer to the next. Some places are not perfect, but the basic functions can be implemented, and the screen does not blink after adding pictures. I've tried it already.

SetRedraw (): Ensure that it does not redraw when a child node pops up, but redraw after the child node has expanded

In doing the program, encountered a very stupid problem, is that I want to implement the mouse scrolling message, after writing the debugging code into not go, after I view, put On_wm_mousewhell in front of it can be

(a) Use Cximage to add any image

1. Add a static library in. h

#include "ximage.h" #pragma comment (lib, "Cximage.lib") #pragma comment (lib, "Jpeg.lib") #pragma comment (lib, "Png.lib") #pragma comment (lib, "Zlib.lib")

2, and declare two variables about Cximage, used to store the background image

Cximage *m_treebkimage; background image of//treectrl

Cximage *m_textbkimage; //The background picture of the word

3. Define messages to prevent screen flicker

afx_msg BOOL OnEraseBkgnd (CDC *PDC);

afx_msg void Onitemexpanding (nmhdr* pnmhdr, lresult* pResult);
afx_msg void onitemexpanded (nmhdr* pnmhdr, lresult* pResult);

(ii) Initialization of defined variables in. cpp

M_treebkimage = new Cximage (); //Picture background

M_textbkimage = new Cximage (); //The background of the word


On_wm_erasebkgnd ()

On_notify_reflect (tvn_itemexpanding,onitemexpanding)
On_notify_reflect (tvn_itemexpanded,onitemexpanded)


1, in OnPaint () call the whole picture, font, etc.

void Uitreectrl::onpaint () {CPAINTDC DC (this),//device context for Paintinggetclientrect (&m_clientrect); CBitmap bitmap; CDC Memedc; Memedc.createcompatibledc (&DC); bitmap. CreateCompatibleBitmap (&DC, M_clientrect.width (), M_clientrect.height ()); CBitmap *poldbitmap = Memedc.selectobject (&bitmap);D rawback (&MEMEDC);D Rawitem (&MEMEDC);
2. Picture background

void Uitreectrl::D rawback (cdc* PDC) {if (M_isdrawback = = TRUE) {M_loaddc.createcompatibledc (NULL);//Create compatible DCM_ Loaddc.selectobject (&M_BITMAP);//The compatible bitmap is selected in compatible Dc,m_loaddc.fillsolidrect (&m_clientrect,rgb (255,255,255));// First, the Bakebitmap (Customer area) is filled with a background color, which is white. Paintimage (PDC,&M_CLIENTRECT,&M_LOADDC); M_loaddc.deletedc ();} Elsepdc->fillsolidrect (&m_clientrect,m_treebkcolor);} dc. BitBlt (M_clientrect.left, M_clientrect.top, M_clientrect.width (), M_clientrect.height (), &memedc, 0, 0,SRCCOPY); Memedc.selectobject (POLDBITMAP); Memedc.deletedc ();}

3. Redraw each item

void Uitreectrl::D rawitem (cdc* pDc) {Htreeitem currentitem,parentitem;//the current handle, and a handle to its parent node DWORD    treestyle;// The type of the number CRect    itemrect;//each item's zone int      itemstate;//The state of an item CurrentItem = GetFirstVisibleItem ();//Gets the item visible in the first lesson do {if ( GetItemRect (currentitem,itemrect,true)) {itemrect.left=itemrect.left-15; CRect   FillRect (0,itemrect.top,m_clientrect.right,itemrect.bottom); itemState = GetItemState (currentitem,tvif_ State), if (itemrect.top>m_clientrect.bottom)  //Description This item has exceeded the bounds of the window, so do not draw Break;drawitemtext (Pdc,currentitem, Itemrect);}} while ((Currentitem=getnextvisibleitem (currentitem)) = NULL);}

4. Redraw fonts and "+" "-" lines

void Uitreectrl::D rawitemtext (CDC * Pdc,htreeitem hitem,crect prect) {int itemstate;//the state of an item DWORD dwstyle = GetStyle (); CRect rcitem,rctemp,selrect;//text position cpoint pttemp; UINT indent = GetIndent (); Selrect = prect; Selrect.left + = 15;pdc->selectobject (&m_font);//the size of the word itemstate = GetItemState (hitem,cdis_selected); if (itemState &tvis_selected)//Select the background color and font color change {pdc->settextcolor (M_stextcolor); Drawtextimage (Pdc,&selrect); } elsepdc->settextcolor (M_textcolor); CString Itemtext = GetItemText (HItem); CSize fontsize;fontsize= pdc->gettextextent (itemtext); rctemp = Prect;rctemp.left + = 18;rctemp.top + = 2;pDc-> SetBkMode (TRANSPARENT);pD C->drawtext (itemtext,rctemp,dt_left| Dt_top);//Display item text GetItemRect (hitem,&rcitem,true);//Get the text of the item rectangle range//2, if you want to draw line if (Dwstyle & Tvs_haslines) {//Create a  True dot-line brushes logbrush logbrush;  Logbrush.lbcolor = M_textcolor;  Logbrush.lbstyle = Bs_solid; CPen Pen (ps_cosmetic |  Ps_alternate, 1, &logbrush); cpen* Oldpen = Pdc->selectoBject (&pen);  Rctemp = RcItem;  Rctemp.left-= indent;//moves one indent from the current to the left rctemp.right = rctemp.left + indent;  Pttemp = Rctemp.centerpoint (); If item has a parent item, draw an ' L ' line in front of itself, and the inflection point is the center of the indent rectangle if (GetParentItem (hItem)! = NULL) {///if item has a brother node (upper brother Row), draw a bar in front of yourself  Vertical line, otherwise draw half Pdc->moveto (pttemp.x-1,rctemp.top-1);  if (GetNextSiblingItem (hItem) = NULL) Pdc->lineto (pttemp.x-1, Rctemp.bottom);  else Pdc->lineto (pttemp.x-1, pttemp.y-1);  Pdc->moveto (Rctemp.right, pttemp.y-1);  Pdc->lineto (Pttemp.x-1, pttemp.y-1);  }//Draw the link between the parent node of each Item and the open part of the Uncle node Htreeitem hitemtemp = HItem;  while (hitemtemp = GetParentItem (hitemtemp)) {rctemp.offsetrect (-indent, 0);  Pttemp = Rctemp.centerpoint ();  if (GetNextSiblingItem (hitemtemp)) {Pdc->moveto (pttemp.x-1, rctemp.top);  Pdc->lineto (Pttemp.x-1, Rctemp.bottom);  }}//Display delete MFC GDI object, because the previous version of MFC seems to have a bug, if you do not show delete it will not help you delete, this bug seems to exist Pdc->selectobject (Oldpen); Pen. DeleteObject (); Pen.  DeleteTempMap ();  }//3, Draw small ' + ' box if (Dwstyle & tvs_hasbuttons) {rcitem.left-= indent;  Rcitem.right = rcitem.left + indent;  Determine the drawing range rctemp.setrect (0, 0, 9, 9);  Rctemp.offsetrect (Rcitem.centerpoint ());  Rctemp.offsetrect (-5,-5); Draw, because the use of MFC10.0, so the actual drawing work can be handed to CMFCVisualManager to complete, in fact ... The difficulty of drawing oneself is also not big if (Itemhaschildren (HItem)) cmfcvisualmanager::getinstance ()->ondrawexpandingbox (PDc, Rctemp, ( GetItemState (HItem, tvis_expanded) & tvis_expanded?  True:false), RGB (0, 0, 0)); }  }

5, load the picture from the local need to know the path of the picture, define the function to load the path of the picture
CString uitreectrl::returnpicload () {//define path CString path;//get system Parameters GetModuleFileName (Null,path. GetBufferSetLength (max_path+1), MAX_PATH);p Ath. ReleaseBuffer (); int pos = path. Reversefind (' \ \ '); m_exepath = path. Left (pos+1); return m_exepath;}

6, know the path of the picture to load the picture, if the path is not correct, then no picture appears

void Uitreectrl::addloadpicture (CString pSrc) {if (ppic = = PSRC) Return;elsem_isdrawback = true;ppic    = psrc;m_ Treebkimage->load (M_exepath+ppic,findtype (ppic)); M_treebkimage->draw (Pdc->getsafehdc (), PRect->left , Prect->top,prect->width (), Prect->height (), 0,true);pD C->bitblt (prect->left,prect->top,prect- >width (), Prect->height (), psrc,0,0,srccopy);}

7, in the process of operation will appear flashing problems, although there are many ways to solve the network is similar, but still want to write, so the comparison code is more perfect

void Uitreectrl::onitemexpanding (nmhdr* pnmhdr, lresult* pResult) {nm_treeview* Pnmtreeview = (nm_treeview*) PNMHDR; SetRedraw (FALSE); *presult = 0;} void uitreectrl::onitemexpanded (nmhdr* pnmhdr, lresult* pResult) {nm_treeview* Pnmtreeview = (nm_treeview*) PNMHDR;I Nvalidate (); SetRedraw (TRUE); *presult = 0;}

8, a lot of friends see above that findtype this function is not defined, this is mainly based on the loaded picture can find the suffix type of the picture

int Uitreectrl::findtype (CString filename) {//The suffix type of the picture found according to the picture CString ext = filename. Right (filename. GetLength ()-filename. Reversefind ('. ')  -1) int type = 0;IF (ext = = _t ("BMP")) type = cximage_format_bmp; #if cximage_support_jpgelse if (ext = = _t ("jpg") | | ext = = _t ("JPEG"))  type = cximage_format_jpg; #endif # if Cximage_support_gifelse if (ext = = _t ("gif")) type = Cximage_format_ GIF; #endif #if cximage_support_png else if (ext = = _t ("PNG"))    type = cximage_format_png; #endifelse type = Cximage_for MAT_MNG;
<span style= "WHITE-SPACE:PRE;" ></span>return type;<span style= "WHITE-SPACE:PRE;" ></span>
}
BOOL uitreectrl::onerasebkgnd (CDC *PDC) {return true;}
The core of the content is the above.

I'll show you a way to redraw treectrl in both ways I've tried. Feasible.

void Uitreectrl::onnmcustomdraw (NMHDR *pnmhdr, LRESULT *presult) {Lpnmcustomdraw PNMCD = reinterpret_cast< Lpnmcustomdraw> (PNMHDR);      Lpnmtvcustomdraw Pcustomdraw = (lpnmtvcustomdraw) pnmcd; nmlvcustomdraw* PLVCD = reinterpret_cast<nmlvcustomdraw*> (PNMHDR); Htreeitem HItem = (htreeitem) plvcd->nmcd.dwitemspec;*presult  =  cdrf_dodefault;  CDC     *PDC = Cdc::fromhandle (PLVCD->NMCD.HDC); switch   (plvcd-> nmcd.dwdrawstage) {  case   Cdds_ Prepaint:    //Before drawing the control {*presult = Cdrf_notifyitemdraw;break;} Case   cdds_itemprepaint://An item is drawn before {CRect rcItem (PNMCD->RC);   Rcclient = RcItem; CPoint Ptitem (rcitem.left + 1, rcitem.top + 1); if (!hitem) return;//draw text, line, "+" sign DrawItem (hitem,pcustomdraw); *presult = cdrf_skipdefault;//tells the system to skip the default processing return;} break;} }

void Uitreectrl::D rawitem (Htreeitem hitem,lpnmtvcustomdraw lpnmtvcd) {DWORD dwstyle = GetStyle (); CRect rcitem,rctemp; CPoint pttemp;  UINT indent = GetIndent ();//Gets the Item text rectangle range GetItemRect (HItem, &rcitem, TRUE);  CDC DC; dc. Attach (LPNMTVCD-&GT;NMCD.HDC); if (Lpnmtvcd->nmcd.uitemstate & cdis_selected) {//If Item is selected DC. SetTextColor (RGB (0,0,255));d C. Fillsolidrect (&rcitem,m_stextcolor);} else {DC.  SetTextColor (M_textcolor); }DC.  SetBkMode (TRANSPARENT); rctemp = RcItem;  Rctemp.left + = 2;  Rctemp.top + = 2; 1. Draw the text DC. DrawText (GetItemText (HItem), &rctemp, Dt_left | Dt_singleline |  Dt_vcenter);  2. If you want to draw a line if (Dwstyle & Tvs_haslines) {//Create a true dot-line brush logbrush Logbrush;  Logbrush.lbcolor = M_textcolor;  Logbrush.lbstyle = Bs_solid; CPen Pen (ps_cosmetic |  Ps_alternate, 1, &logbrush); cpen* Oldpen = DC.  SelectObject (&pen);  Rctemp = RcItem;  Rctemp.left-= indent;//moves one indent from the current to the left rctemp.right = rctemp.left + indent;  Pttemp = Rctemp.centerpoint (); If IteM has the parent item to draw an ' L ' type line in front of itself, and the inflection point is the center of the indent rectangle if (GetParentItem (hItem)! = NULL) {///if Item has a brother node (above the elder brother Row), draw a vertical bar in front of you, otherwise draw half DC.  MoveTo (pttemp.x-1,rctemp.top-1); if (GetNextSiblingItem (hItem) = NULL) DC.  LineTo (Pttemp.x-1, Rctemp.bottom); Else DC.  LineTo (Pttemp.x-1, pttemp.y-1); dc.  MoveTo (Rctemp.right, pttemp.y-1); dc.  LineTo (Pttemp.x-1, pttemp.y-1);  }//Draw the link between the parent node of each Item and the open part of the Uncle node Htreeitem hitemtemp = HItem;  while (hitemtemp = GetParentItem (hitemtemp)) {rctemp.offsetrect (-indent, 0);  Pttemp = Rctemp.centerpoint (); if (GetNextSiblingItem (hitemtemp)) {DC.  MoveTo (Pttemp.x-1, rctemp.top); dc.  LineTo (Pttemp.x-1, Rctemp.bottom); }}//Display delete MFC GDI object, because the previous version of MFC seems to have a bug, if you do not show delete it will not help you delete, this bug seems to exist DC.  SelectObject (Oldpen); Pen.  DeleteObject (); Pen.  DeleteTempMap ();  }//3, Draw small ' + ' box if (Dwstyle & tvs_hasbuttons) {rcitem.left-= indent;  Rcitem.right = rcitem.left + indent;  Determine the drawing range rctemp.setrect (0, 0, 9, 9); Rctemp.offsetrect (Rcitem.centerpoint ());  Rctemp.offsetrect (-5,-5); Draw, because the use of MFC10.0, so the actual drawing work can be handed to CMFCVisualManager to complete, in fact ... The difficulty of drawing oneself is also not big if (Itemhaschildren (HItem)) cmfcvisualmanager::getinstance ()->ondrawexpandingbox (&AMP;DC, RcTemp, ( GetItemState (HItem, tvis_expanded) & tvis_expanded?  True:false), RGB (0, 0, 0)); }//Complete DC. Detach ();}




Add a background image using Cximage in CTreeCtrl and add a background image to the word

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.