/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2003 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "commonheaders.h" #include "m_clc.h" #include "clc.h" //#include extern HIMAGELIST himlCListClc; static BYTE divide3[765]={255}; int MetaIgnoreEmptyExtra; static void ChangeToFont(HDC hdc,struct ClcData *dat,int id,int *fontHeight) { SelectObject(hdc,dat->fontInfo[id].hFont); SetTextColor(hdc,dat->fontInfo[id].colour); if(fontHeight) *fontHeight=dat->fontInfo[id].fontHeight; } static void __inline SetHotTrackColour(HDC hdc,struct ClcData *dat) { if(dat->gammaCorrection) { COLORREF oldCol,newCol; int oldLum,newLum; oldCol=GetTextColor(hdc); oldLum=(GetRValue(oldCol)*30+GetGValue(oldCol)*59+GetBValue(oldCol)*11)/100; newLum=(GetRValue(dat->hotTextColour)*30+GetGValue(dat->hotTextColour)*59+GetBValue(dat->hotTextColour)*11)/100; if(newLum==0) { SetTextColor(hdc,dat->hotTextColour); return; } if(newLum>=oldLum+20) { oldLum+=20; newCol=RGB(GetRValue(dat->hotTextColour)*oldLum/newLum,GetGValue(dat->hotTextColour)*oldLum/newLum,GetBValue(dat->hotTextColour)*oldLum/newLum); } else if(newLum<=oldLum) { int r,g,b; r=GetRValue(dat->hotTextColour)*oldLum/newLum; g=GetGValue(dat->hotTextColour)*oldLum/newLum; b=GetBValue(dat->hotTextColour)*oldLum/newLum; if(r>255) { g+=(r-255)*3/7; b+=(r-255)*3/7; r=255; } if(g>255) { r+=(g-255)*59/41; if(r>255) r=255; b+=(g-255)*59/41; g=255; } if(b>255) { r+=(b-255)*11/89; if(r>255) r=255; g+=(b-255)*11/89; if(g>255) g=255; b=255; } newCol=RGB(r,g,b); } else newCol=dat->hotTextColour; SetTextColor(hdc,newCol); } else SetTextColor(hdc,dat->hotTextColour); } static int GetStatusOnlineness(int status) { switch(status) { case ID_STATUS_FREECHAT: return 110; case ID_STATUS_ONLINE: return 100; case ID_STATUS_OCCUPIED: return 60; case ID_STATUS_ONTHEPHONE: return 50; case ID_STATUS_DND: return 40; case ID_STATUS_AWAY: return 30; case ID_STATUS_OUTTOLUNCH: return 20; case ID_STATUS_NA: return 10; case ID_STATUS_INVISIBLE: return 5; } return 0; } static int GetGeneralisedStatus(void) { int i,status,thisStatus,statusOnlineness,thisOnlineness; status=ID_STATUS_OFFLINE; statusOnlineness=0; for (i=0;ihClcProtoCount;i++) { thisStatus = pcli->clcProto[i].dwStatus; if(thisStatus==ID_STATUS_INVISIBLE) return ID_STATUS_INVISIBLE; thisOnlineness=GetStatusOnlineness(thisStatus); if(thisOnlineness>statusOnlineness) { status=thisStatus; statusOnlineness=thisOnlineness; } } return status; } static int GetRealStatus(struct ClcContact * contact, int status) { int i; char *szProto=contact->proto; if (!szProto) return status; for (i=0;ihClcProtoCount;i++) { if (!lstrcmpA(pcli->clcProto[i].szProto,szProto)) { return pcli->clcProto[i].dwStatus; } } return status; } static HMODULE themeAPIHandle = NULL; // handle to uxtheme.dll static HANDLE (WINAPI *MyOpenThemeData)(HWND,LPCWSTR); static HRESULT (WINAPI *MyCloseThemeData)(HANDLE); static HRESULT (WINAPI *MyDrawThemeBackground)(HANDLE,HDC,int,int,const RECT *,const RECT *); #define MGPROC(x) GetProcAddress(themeAPIHandle,x) void InternalPaintClc(HWND hwnd,struct ClcData *dat,HDC hdc,RECT *rcPaint) { HDC hdcMem; HBITMAP oldbmp; HBITMAP oldbm; HFONT oldfont; RECT clRect; int y,indent,index,fontHeight, subindex, subident; struct ClcContact *Drawing; struct ClcGroup *group; HBITMAP hBmpOsb; DWORD style=GetWindowLong(hwnd,GWL_STYLE); int status=GetGeneralisedStatus(); int grey=0,groupCountsFontTopShift; HBRUSH hBrushAlternateGrey=NULL; POINT pt; RECT testrc; // 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; //rcPaint=&clRect; if(IsRectEmpty(rcPaint)) return; GetCursorPos(&pt); ScreenToClient(hwnd,&pt); y=-dat->yScroll; hdcMem=CreateCompatibleDC(hdc); hBmpOsb=CreateBitmap(clRect.right,clRect.bottom,1,GetDeviceCaps(hdc,BITSPIXEL),NULL); oldbmp=(HBITMAP)SelectObject(hdcMem,hBmpOsb); { TEXTMETRIC tm; oldfont=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; SelectObject(hdcMem,oldfont); } 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,hoBrush; hBrush=CreateSolidBrush(tmpbkcolour); hoBrush=(HBRUSH)SelectObject(hdcMem,hBrush); FillRect(hdcMem,rcPaint,hBrush); SelectObject(hdcMem,hoBrush); DeleteObject(hBrush); if(dat->hBmpBackground) { BITMAP bmp; HDC hdcBmp; int x,y; int maxx,maxy; int destw,desth; // XXX: Halftone isnt supported on 9x, however the scretch problems dont happen on 98. SetStretchBltMode(hdcMem, HALFTONE); GetObject(dat->hBmpBackground,sizeof(bmp),&bmp); hdcBmp=CreateCompatibleDC(hdcMem); oldbm=SelectObject(hdcBmp,dat->hBmpBackground); y=dat->backgroundBmpUse&CLBF_SCROLL?-dat->yScroll:0; maxx=dat->backgroundBmpUse&CLBF_TILEH?clRect.right:1; maxy=dat->backgroundBmpUse&CLBF_TILEV?maxy=rcPaint->bottom:y+1; switch(dat->backgroundBmpUse&CLBM_TYPE) { case CLB_STRETCH: if(dat->backgroundBmpUse&CLBF_PROPORTIONAL) { if(clRect.right*bmp.bmHeightbackgroundBmpUse&CLBF_PROPORTIONAL) { destw=clRect.right; desth=destw*bmp.bmHeight/bmp.bmWidth; } else { destw=clRect.right; desth=bmp.bmHeight; if (dat->backgroundBmpUse&CLBF_TILEVTOROWHEIGHT) { desth=dat->rowHeight; } } 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; if (dat->backgroundBmpUse&CLBF_TILEVTOROWHEIGHT) { desth=dat->rowHeight; } break; } for (;ytop-desth) continue; for(x=0;xlist; group->scanIndex=0; indent=0; subindex=-1; for(index=0;ybottom;) { if (subindex==-1) if (group->scanIndex==group->cl.count) { group=group->parent; indent--; if(group==NULL) break; group->scanIndex++; continue; } //if(group==NULL) break; if(y>rcPaint->top-dat->rowHeight ) { int iImage=-1; int selected; int hottrack; SIZE textSize,countsSize,spaceSize; int width,checkboxWidth; char *szCounts; if (subindex==-1) { Drawing=group->cl.items[group->scanIndex]; subident=0; } else { Drawing=&(group->cl.items[group->scanIndex]->subcontacts[subindex]); subident=dat->rowHeight/2; } //alternating grey selected=index==dat->selection && (dat->showSelAlways || dat->exStyle&CLS_EX_SHOWSELALWAYS || GetFocus()==hwnd) && Drawing->type!=CLCIT_DIVIDER; hottrack=dat->exStyle&CLS_EX_TRACKSELECT && Drawing->type!=CLCIT_DIVIDER && dat->iHotTrack==index; 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(Drawing->type==CLCIT_GROUP) { if (Drawing->group->expanded) { ChangeToFont(hdcMem,dat,FONTID_GROUPS,&fontHeight); } else { ChangeToFont(hdcMem,dat,FONTID_GROUPSCLOSED,&fontHeight); } } else if(Drawing->type==CLCIT_INFO) { if(Drawing->flags&CLCIIF_GROUPFONT) ChangeToFont(hdcMem,dat,FONTID_GROUPS,&fontHeight); else ChangeToFont(hdcMem,dat,FONTID_CONTACTS,&fontHeight); } else if(Drawing->type==CLCIT_DIVIDER) ChangeToFont(hdcMem,dat,FONTID_DIVIDERS,&fontHeight); else if(Drawing->type==CLCIT_CONTACT && (Drawing->flags&CONTACTF_NOTONLIST) && (!Drawing->isSubcontact) ) ChangeToFont(hdcMem,dat,FONTID_NOTONLIST,&fontHeight); else if ( Drawing->type==CLCIT_CONTACT && ( (Drawing->flags&CONTACTF_INVISTO && (!Drawing->isSubcontact) && GetRealStatus(group->cl.items[group->scanIndex], status) != ID_STATUS_INVISIBLE ) || (Drawing->flags&CONTACTF_VISTO && (!Drawing->isSubcontact) && GetRealStatus(group->cl.items[group->scanIndex], 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, Drawing->flags&CONTACTF_ONLINE ? FONTID_INVIS:FONTID_OFFINVIS ,&fontHeight); } else if(Drawing->type==CLCIT_CONTACT && (!(Drawing->flags&CONTACTF_ONLINE) && (!Drawing->isSubcontact))) ChangeToFont(hdcMem,dat,FONTID_OFFLINE,&fontHeight); else ChangeToFont(hdcMem,dat,FONTID_CONTACTS,&fontHeight); GetTextExtentPoint32(hdcMem,Drawing->szText,lstrlen(Drawing->szText),&textSize); width=textSize.cx; if(Drawing->type==CLCIT_GROUP) { szCounts = pcli->pfnGetGroupCountsText(dat,group->cl.items[group->scanIndex]); if(szCounts[0]) { GetTextExtentPoint32A(hdcMem," ",1,&spaceSize); ChangeToFont(hdcMem,dat,FONTID_GROUPCOUNTS,&fontHeight); GetTextExtentPoint32A(hdcMem,szCounts,lstrlenA(szCounts),&countsSize); width+=spaceSize.cx+countsSize.cx; } } if ((style&CLS_CHECKBOXES && Drawing->type==CLCIT_CONTACT) || (style&CLS_GROUPCHECKBOXES && Drawing->type==CLCIT_GROUP) || (Drawing->type==CLCIT_INFO && Drawing->flags&CLCIIF_CHECKBOX)) checkboxWidth=dat->checkboxSize+2; else checkboxWidth=0; //background if(selected) { switch (dat->HiLightMode) { case 0: { int x=dat->leftMargin+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace-2+subident; 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); break; } case 1: { ImageList_DrawEx(dat->himlHighlight,0,hdcMem,0,y,clRect.right, dat->rowHeight,CLR_NONE,CLR_NONE, dat->exStyle&CLS_EX_NOTRANSLUCENTSEL?ILD_NORMAL:ILD_BLEND25); SetTextColor(hdcMem,dat->selTextColour); break; } case 2: { ImageList_DrawEx(dat->himlHighlight,0,hdcMem,1,y+1,clRect.right-2, dat->rowHeight-1,CLR_NONE,CLR_NONE, dat->exStyle&CLS_EX_NOTRANSLUCENTSEL?ILD_NORMAL:ILD_BLEND25); SetTextColor(hdcMem,dat->selTextColour); break; } case 3: { SetTextColor(hdcMem,dat->selTextColour); break; } } } else if(hottrack) SetHotTrackColour(hdcMem,dat); //checkboxes if(checkboxWidth && (subindex==-1 ||1)) { RECT rc; HANDLE hTheme = NULL; // THEME if (IsWinVerXPPlus()) { if (!themeAPIHandle) { themeAPIHandle = GetModuleHandleA("uxtheme"); if (themeAPIHandle) { MyOpenThemeData = (HANDLE (WINAPI *)(HWND,LPCWSTR))MGPROC("OpenThemeData"); MyCloseThemeData = (HRESULT (WINAPI *)(HANDLE))MGPROC("CloseThemeData"); MyDrawThemeBackground = (HRESULT (WINAPI *)(HANDLE,HDC,int,int,const RECT *,const RECT *))MGPROC("DrawThemeBackground"); } } // Make sure all of these methods are valid (i would hope either all or none work) if (MyOpenThemeData &&MyCloseThemeData &&MyDrawThemeBackground) { hTheme = MyOpenThemeData(hwnd,L"BUTTON"); } } rc.left=dat->leftMargin+indent*dat->groupIndent+subident; rc.right=rc.left+dat->checkboxSize; rc.top=y+((dat->rowHeight-dat->checkboxSize)>>1); rc.bottom=rc.top+dat->checkboxSize; if (hTheme) { MyDrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, Drawing->flags&CONTACTF_CHECKED?(hottrack?CBS_CHECKEDHOT:CBS_CHECKEDNORMAL):(hottrack?CBS_UNCHECKEDHOT:CBS_UNCHECKEDNORMAL), &rc, &rc); } else DrawFrameControl(hdcMem,&rc,DFC_BUTTON,DFCS_BUTTONCHECK|DFCS_FLAT|(Drawing->flags&CONTACTF_CHECKED?DFCS_CHECKED:0)|(hottrack?DFCS_HOT:0)); if (hTheme&&MyCloseThemeData) { MyCloseThemeData(hTheme); hTheme = NULL; } } //icon if(Drawing->type==CLCIT_GROUP) iImage=Drawing->group->expanded?IMAGE_GROUPOPEN:IMAGE_GROUPSHUT; else if(Drawing->type==CLCIT_CONTACT) iImage=Drawing->iImage; if(iImage!=-1) { /*COLORREF colourFg=dat->selBkColour; int mode=ILD_NORMAL; if(selected) mode=ILD_SELECTED; else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;} else if(Drawing->type==CLCIT_CONTACT && Drawing->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;} ImageList_DrawEx(himlCListClc,iImage,hdcMem,dat->leftMargin+indent*dat->groupIndent+checkboxWidth,y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode); */ COLORREF colourFg=dat->selBkColour; int mode=ILD_NORMAL; if(hottrack) {colourFg=dat->hotTextColour;} else if(Drawing->type==CLCIT_CONTACT && Drawing->flags&CONTACTF_NOTONLIST && (!Drawing->isSubcontact)) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;} if (Drawing->type==CLCIT_CONTACT && dat->showIdle && (Drawing->flags&CONTACTF_IDLE)&& (!Drawing->isSubcontact) && GetRealStatus(group->cl.items[group->scanIndex],ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) mode=ILD_SELECTED; ImageList_DrawEx(himlCListClc,iImage,hdcMem,dat->leftMargin+subident+indent*dat->groupIndent+checkboxWidth,y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode); } //text if(Drawing->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),Drawing->szText,lstrlen(Drawing->szText)); rc.left=rc.right+6+textSize.cx; rc.right=clRect.right; DrawEdge(hdcMem,&rc,BDR_SUNKENOUTER,BF_RECT); } else if(Drawing->type==CLCIT_GROUP) { RECT rc; if(szCounts[0]) { struct ClcGroup *clcg; clcg=(struct ClcGroup *)Drawing; fontHeight=dat->fontInfo[FONTID_GROUPS].fontHeight; rc.left=dat->leftMargin+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace; rc.right=min(clRect.right-countsSize.cx,rc.left+textSize.cx+spaceSize.cx); rc.top=y+((dat->rowHeight-fontHeight)>>1); rc.bottom=rc.top+textSize.cy; if(rc.rightgroup->expanded) { ChangeToFont(hdcMem,dat,FONTID_GROUPS,&fontHeight); } else { ChangeToFont(hdcMem,dat,FONTID_GROUPSCLOSED,&fontHeight); } if(selected) SetTextColor(hdcMem,dat->selTextColour); else if(hottrack) SetHotTrackColour(hdcMem,dat); rc.right--; ExtTextOut(hdcMem,rc.left,rc.top,ETO_CLIPPED,&rc,Drawing->szText,lstrlen(Drawing->szText),NULL); } else TextOut(hdcMem,dat->leftMargin+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace,y+((dat->rowHeight-fontHeight)>>1),Drawing->szText,lstrlen(Drawing->szText)); if(dat->exStyle&CLS_EX_LINEWITHGROUPS) { //calc if extra icons present int enabledextraicons=0; for(iImage=0;iImageextraColumnsCount;iImage++) { if(Drawing->iExtraImage[iImage]==0xFF) continue; enabledextraicons++; } rc.top=y+(dat->rowHeight>>1); rc.bottom=rc.top+2; rc.left=dat->leftMargin+subident+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace+width+3; rc.right=clRect.right-1-dat->extraColumnSpacing*enabledextraicons; if(rc.right-rc.left>1) DrawEdge(hdcMem,&rc,BDR_SUNKENOUTER,BF_RECT); } } else { RECT rc; rc.left=dat->leftMargin+subident+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace; rc.top=y+((dat->rowHeight-fontHeight)>>1); rc.bottom=rc.top+dat->rowHeight; rc.right=clRect.right; if (Drawing->type=CLCIT_CONTACT) { if (hottrack/*PtInRect(&rc,pt)*/) { ChangeToFont(hdcMem,dat,FONTID_CONTACTSHOVER,&fontHeight); } } DrawText(hdcMem,Drawing->szText,lstrlen(Drawing->szText),&rc,DT_END_ELLIPSIS); } if(selected) { if(Drawing->type!=CLCIT_DIVIDER) { SetTextColor(hdcMem,dat->quickSearchColour); TextOut(hdcMem,dat->leftMargin+subident+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace,y+((dat->rowHeight-fontHeight)>>1),Drawing->szText,lstrlen(dat->szQuickSearch)); } } if (dat->style&CLS_SHOWSTATUSMESSAGES) { // status message if (group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_STATUSMSG) { TCHAR * szText = group->cl.items[group->scanIndex]->szStatusMsg; RECT rc; rc.left=dat->leftMargin+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace; rc.top=y+dat->rowHeight+((dat->rowHeight-fontHeight)>>1); rc.right=(clRect.right - clRect.left); rc.bottom=rc.top+dat->rowHeight; ChangeToFont(hdcMem,dat,FONTID_STATUSMSG,&fontHeight); //ExtTextOut(hdcMem,rc.left,rc.top,ETO_CLIPPED,&rc,szText,lstrlen(szText),NULL); DrawText(hdcMem, szText, lstrlen(szText), &rc, DT_SINGLELINE | DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS); } } if (!Drawing->isSubcontact || (DBGetContactSettingByte(NULL,"CLC","MetaHideExtra",0)==0)) { //extra icons if (!(style&CLS_EX_MULTICOLUMNALIGNLEFT)) { int c=dat->extraColumnsCount; for(iImage=dat->extraColumnsCount-1;iImage>=0;iImage--) { COLORREF colourFg=dat->selBkColour; int mode=ILD_NORMAL; if(Drawing->iExtraImage[iImage]==0xFF) continue; if(selected) mode=ILD_SELECTED; else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;} else if(Drawing->type==CLCIT_CONTACT && Drawing->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;} { } if (dat->MetaIgnoreEmptyExtra) c--; else c=iImage; testrc.left=clRect.right-dat->extraColumnSpacing*(dat->extraColumnsCount-c); testrc.top=(y+((dat->rowHeight-16)>>1)); testrc.right=testrc.left+16; testrc.bottom=testrc.top+16; if (!PtInRect(&testrc,pt)) { mode=ILD_NORMAL; } ImageList_DrawEx(dat->himlExtraColumns,Drawing->iExtraImage[iImage],hdcMem,clRect.right-dat->extraColumnSpacing*(dat->extraColumnsCount-c),y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode); } } else { int ic=0; for(iImage=0;iImageextraColumnsCount;iImage++) { COLORREF colourFg=dat->selBkColour; int mode=ILD_NORMAL; int x; //if(group->cl.items[group->scanIndex].iExtraImage[iImage]==0xFF) continue; /* if(selected) mode=ILD_SELECTED; else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;} else if(group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;} x=(dat->leftMargin+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace-2+width); x+=16; x=x+dat->extraColumnSpacing*(ic); if (iImage==dat->extraColumnsCount-1) {x=clRect.right-18;} ImageList_DrawEx(dat->himlExtraColumns,group->cl.items[group->scanIndex].iExtraImage[iImage],hdcMem, x, y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode); */ if(Drawing->iExtraImage[iImage]==0xFF) continue; //if(selected) mode=ILD_SELECTED; else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;} else if(Drawing->type==CLCIT_CONTACT && Drawing->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;} x=(dat->leftMargin+indent*dat->groupIndent+checkboxWidth+dat->iconXSpace-2+width); x+=16; x=x+dat->extraColumnSpacing*(ic); if (iImage==dat->extraColumnsCount-1) {x=clRect.right-18;} ImageList_DrawEx(dat->himlExtraColumns,Drawing->iExtraImage[iImage],hdcMem, x, y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode); ic++; } } } } index++; y+=dat->rowHeight; if (group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_STATUSMSG) { y+=dat->rowHeight; index++; } //increment by subcontacts if (group->cl.items[group->scanIndex]->subcontacts!=NULL && group->cl.items[group->scanIndex]->type!=CLCIT_GROUP) if (group->cl.items[group->scanIndex]->SubExpanded) if (subindexcl.items[group->scanIndex]->SubAllocated-1) subindex++; else subindex=-1; if(subindex==-1) { if(group->cl.items[group->scanIndex]->type==CLCIT_GROUP && group->cl.items[group->scanIndex]->group->expanded) { group=group->cl.items[group->scanIndex]->group; indent++; group->scanIndex=0; subindex=-1; continue; } group->scanIndex++; } } if(dat->iInsertionMark!=-1) { //insertion mark HBRUSH hBrush,hoBrush; POINT pts[8]; HRGN hRgn; pts[0].x=dat->leftMargin; pts[0].y=dat->iInsertionMark*dat->rowHeight-dat->yScroll-4; pts[1].x=pts[0].x+2; pts[1].y=pts[0].y+3; pts[2].x=clRect.right-4; pts[2].y=pts[1].y; pts[3].x=clRect.right-1; pts[3].y=pts[0].y-1; pts[4].x=pts[3].x; pts[4].y=pts[0].y+7; pts[5].x=pts[2].x+1; pts[5].y=pts[1].y+2; pts[6].x=pts[1].x; pts[6].y=pts[5].y; pts[7].x=pts[0].x; pts[7].y=pts[4].y; hRgn=CreatePolygonRgn(pts,SIZEOF(pts),ALTERNATE); hBrush=CreateSolidBrush(dat->fontInfo[FONTID_CONTACTS].colour); hoBrush=(HBRUSH)SelectObject(hdcMem,hBrush); FillRgn(hdcMem,hRgn,hBrush); SelectObject(hdcMem,hoBrush); DeleteObject(hBrush); } if (!grey) BitBlt(hdc,rcPaint->left,rcPaint->top,rcPaint->right-rcPaint->left,rcPaint->bottom-rcPaint->top,hdcMem,rcPaint->left,rcPaint->top,SRCCOPY); //DeleteDC(hdcMem); if(hBrushAlternateGrey) DeleteObject(hBrushAlternateGrey); if(grey) { PBYTE bits; BITMAPINFOHEADER bmih={0}; int i; int greyRed,greyGreen,greyBlue; COLORREF greyColour; bmih.biBitCount=32; bmih.biSize=sizeof(bmih); bmih.biCompression=BI_RGB; bmih.biHeight=-clRect.bottom; bmih.biPlanes=1; bmih.biWidth=clRect.right; bits=(PBYTE)mir_alloc(4*bmih.biWidth*-bmih.biHeight); GetDIBits(hdc,hBmpOsb,0,clRect.bottom,bits,(BITMAPINFO*)&bmih,DIB_RGB_COLORS); greyColour=GetSysColor(COLOR_3DFACE); greyRed=GetRValue(greyColour)*2; greyGreen=GetGValue(greyColour)*2; greyBlue=GetBValue(greyColour)*2; if(divide3[0]==255) { for(i=0; i < SIZEOF(divide3); i++) divide3[i]=(i+1)/3; } for(i=4*clRect.right*clRect.bottom-4;i>=0;i-=4) { bits[i]=divide3[bits[i]+greyBlue]; bits[i+1]=divide3[bits[i+1]+greyGreen]; bits[i+2]=divide3[bits[i+2]+greyRed]; } SetDIBitsToDevice(hdc,0,0,clRect.right,clRect.bottom,0,0,0,clRect.bottom,bits,(BITMAPINFO*)&bmih,DIB_RGB_COLORS); mir_free(bits); } SelectObject(hdcMem,oldfont); SelectObject(hdcMem,oldbmp); DeleteObject(hBmpOsb); DeleteDC(hdcMem); } void PaintClc(HWND hwnd,struct ClcData *dat,HDC hdc,RECT *rcPaint) { if (SED.cbSize==sizeof(SED)&&SED.PaintClc!=NULL) { SED.PaintClc(hwnd,dat,hdc,rcPaint,pcli->hClcProtoCount,pcli->clcProto,himlCListClc); return; } InternalPaintClc(hwnd,dat,hdc,rcPaint); }