/* 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" extern HIMAGELIST himlCListClc; static BYTE divide3[765] = {255}; int MetaIgnoreEmptyExtra; ExternDrawer SED; 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; ClcGroup *group; HBITMAP hBmpOsb; DWORD style = GetWindowLongPtr(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); { oldfont = (HFONT)SelectObject(hdcMem,dat->fontInfo[FONTID_GROUPS].hFont); TEXTMETRIC tm; 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 = (HBITMAP)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 (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) { // default value - paint on text 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); } 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]) { ClcGroup *clcg; clcg = (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] == 0xFFFF) 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) 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] == 0xFFFF) 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 (Drawing->iExtraImage[iImage] == 0xFFFF) continue; 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); }