Ejemplo n.º 1
0
void DestroyAnimation(HWND hwnd, ACCData* data)
{
	DestroyFlash(hwnd, data);
	DestroyAnimatedGif(hwnd, data);
}
Ejemplo n.º 2
0
static LRESULT CALLBACK ACCWndProc(HWND hwnd, UINT msg,  WPARAM wParam, LPARAM lParam) {
	ACCData* data =  (ACCData *) GetWindowLong(hwnd, 0);
	switch(msg) 
	{
		case WM_NCCREATE:
		{
			SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | BS_OWNERDRAW);
			SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT);

			data = (ACCData*) mir_alloc(sizeof(ACCData));
			if (data == NULL) 
				return FALSE;
			SetWindowLong(hwnd, 0, (LONG)data);

			ZeroMemory(data, sizeof(ACCData));
            data->hHook = HookEventMessage(ME_AV_AVATARCHANGED, hwnd, DM_AVATARCHANGED);
            data->hHookMy = HookEventMessage(ME_AV_MYAVATARCHANGED, hwnd, DM_MYAVATARCHANGED);
			data->hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
			data->borderColor = -1;
			data->bkgColor = -1;
			data->avatarBorderColor = -1;
			data->respectHidden = TRUE;
			data->showingFlash = FALSE;
			data->resizeIfSmaller = TRUE;

			return TRUE;
		}
        case WM_NCDESTROY:
        {
			DestroyFlash(hwnd, data);
			if (data) 
			{
                UnhookEvent(data->hHook);
                UnhookEvent(data->hHookMy);
				mir_free(data);
			}
			SetWindowLong(hwnd, 0, (LONG)NULL);
			break;
		}
		case WM_SETFONT:
		{
			data->hFont = (HFONT)wParam;
			Invalidate(hwnd);
			break;
		}
		case AVATAR_SETCONTACT:
		{
			if (data->showingFlash)
			{
				DestroyFlash(hwnd, data);
				data->showingFlash = FALSE;
			}

			data->hContact = (HANDLE) lParam;
			lstrcpynA(data->proto, (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)data->hContact, 0), sizeof(data->proto));

			if (DBGetContactSettingWord(data->hContact, "ContactPhoto", "Format", 0) == PA_FORMAT_XML)
			{
				data->showingFlash = StartFlash(hwnd, data);
			}

			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETPROTOCOL:
		{
			if (data->showingFlash)
			{
				DestroyFlash(hwnd, data);
				data->showingFlash = FALSE;
			}

			data->hContact = NULL;
			if (lParam == NULL)
				data->proto[0] = '\0';
			else
				lstrcpynA(data->proto, (char *) lParam, sizeof(data->proto));

			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETBKGCOLOR:
		{
			data->bkgColor = (COLORREF) lParam;
			if (data->showingFlash)
				SetBkgFlash(hwnd, data);
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETBORDERCOLOR:
		{
			data->borderColor = (COLORREF) lParam;
			if (data->showingFlash)
				ResizeFlash(hwnd, data);
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETAVATARBORDERCOLOR:
		{
			data->avatarBorderColor = (COLORREF) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETAVATARROUNDCORNERRADIUS:
		{
			data->avatarRoundCornerRadius = (int) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETNOAVATARTEXT:
		{
			lstrcpynA(data->noAvatarText, Translate((char*) lParam), sizeof(data->noAvatarText));
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_RESPECTHIDDEN:
		{
			data->respectHidden = (BOOL) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETRESIZEIFSMALLER:
		{
			data->resizeIfSmaller = (BOOL) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_GETUSEDSPACE:
		{
			int *width = (int *)wParam;
			int *height = (int *)lParam;

			if (data->hContact == NULL && data->proto[0] == '\0')
			{
				*width = 0;
				*height = 0;
				return TRUE;
			}

			RECT rc;
			GetClientRect(hwnd, &rc);

			// Get avatar
			if (data->showingFlash && ServiceExists(MS_FAVATAR_GETINFO))
			{
				FLASHAVATAR fa = {0}; 
                fa.hContact = data->hContact;
				fa.cProto = data->proto;
				fa.hParentWindow = hwnd;
                fa.id = 1675;
				CallService(MS_FAVATAR_GETINFO, (WPARAM)&fa, 0);
				if (fa.hWindow != NULL)
				{
					*width = rc.right - rc.left;
					*height = rc.bottom - rc.top;
					return TRUE;
				}
			}

			avatarCacheEntry *ace;
			if (data->hContact == NULL)
				ace = (avatarCacheEntry *) CallService(MS_AV_GETMYAVATAR, 0, (LPARAM) data->proto);
			else
				ace = (avatarCacheEntry *) CallService(MS_AV_GETAVATARBITMAP, 0, (LPARAM) data->hContact);

			if (ace == NULL || ace->bmHeight == 0 || ace->bmWidth == 0 
				|| (data->respectHidden && (ace->dwFlags & AVS_HIDEONCLIST)))
			{
				*width = 0;
				*height = 0;
				return TRUE;
			}

			// Get its size
			int targetWidth = rc.right - rc.left;
			int targetHeight = rc.bottom - rc.top;

			if (!data->resizeIfSmaller && ace->bmHeight <= targetHeight && ace->bmWidth <= targetWidth)
			{
				*height = ace->bmHeight;
				*width = ace->bmWidth;
			} 
			else if (ace->bmHeight > ace->bmWidth)
			{
				float dScale = targetHeight / (float)ace->bmHeight;
				*height = targetHeight;
				*width = (int) (ace->bmWidth * dScale);
			}
			else 
			{
				float dScale = targetWidth / (float)ace->bmWidth;
				*height = (int) (ace->bmHeight * dScale);
				*width = targetWidth;
			}

			return TRUE;
		}
        case DM_AVATARCHANGED:
		{
			if (data->hContact == (HANDLE) wParam)
			{
				if (data->showingFlash)
				{
					DestroyFlash(hwnd, data);
					data->showingFlash = FALSE;
				}

				if (DBGetContactSettingWord(data->hContact, "ContactPhoto", "Format", 0) == PA_FORMAT_XML)
					data->showingFlash = StartFlash(hwnd, data);

				NotifyAvatarChange(hwnd);
				Invalidate(hwnd);
			}
            break;
		}
        case DM_MYAVATARCHANGED:
		{
			if (data->hContact == NULL && strcmp(data->proto, (char*) wParam) == 0)
			{
				if (data->showingFlash)
				{
					DestroyFlash(hwnd, data);
					data->showingFlash = FALSE;
				}

				NotifyAvatarChange(hwnd);
				Invalidate(hwnd);
			}
            break;
		}
		case WM_NCPAINT:
		case WM_PAINT:
		{
			if (data->hContact == NULL && data->proto[0] == '\0')
				break;

			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);
			if (hdc == NULL) 
				break;

			int oldBkMode = SetBkMode(hdc, TRANSPARENT);
			SetStretchBltMode(hdc, HALFTONE);

			RECT rc;
			GetClientRect(hwnd, &rc);

			// Draw background
			if (data->bkgColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->bkgColor);
				FillRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			// If has a flash avatar, don't draw it
			if (data->showingFlash && ServiceExists(MS_FAVATAR_GETINFO))
			{
				FLASHAVATAR fa = {0}; 
                fa.hContact = data->hContact;
				fa.cProto = data->proto;
				fa.hParentWindow = hwnd;
                fa.id = 1675;
				CallService(MS_FAVATAR_GETINFO, (WPARAM)&fa, 0);
				if (fa.hWindow != NULL)
				{
					// Draw control border
					if (data->borderColor != -1)
					{
						HBRUSH hbrush = CreateSolidBrush(data->borderColor);
						FrameRect(hdc, &rc, hbrush);
						DeleteObject(hbrush);
					}
					return TRUE;
				}
			}

			// Draw avatar
            AVATARDRAWREQUEST avdrq = {0};
            avdrq.cbSize = sizeof(avdrq);
			avdrq.rcDraw = rc;
            avdrq.hContact = data->hContact;
			avdrq.szProto = data->proto;
            avdrq.hTargetDC = hdc;
            avdrq.dwFlags = AVDRQ_HIDEBORDERONTRANSPARENCY
				| (data->respectHidden ? AVDRQ_RESPECTHIDDEN : 0) 
				| (data->hContact != NULL ? 0 : AVDRQ_OWNPIC)
				| (data->avatarBorderColor == -1 ? 0 : AVDRQ_DRAWBORDER)
				| (data->avatarRoundCornerRadius <= 0 ? 0 : AVDRQ_ROUNDEDCORNER)
				| (data->resizeIfSmaller ? 0 : AVDRQ_DONTRESIZEIFSMALLER);
            avdrq.clrBorder = data->avatarBorderColor;
            avdrq.radius = data->avatarRoundCornerRadius;
			if (!CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&avdrq)) 
			{
				HGDIOBJ oldFont = SelectObject(hdc, data->hFont);

				// Get text rectangle
				RECT tr = avdrq.rcDraw;
				tr.top += 10;
				tr.bottom -= 10;
				tr.left += 10;
				tr.right -= 10;

				// Calc text size
				RECT tr_ret = tr;
				DrawTextA(hdc, data->noAvatarText, -1, &tr_ret, 
						DT_WORDBREAK | DT_NOPREFIX | DT_CENTER | DT_CALCRECT);
				
				// Calc needed size
				tr.top += ((tr.bottom - tr.top) - (tr_ret.bottom - tr_ret.top)) / 2;
				tr.bottom = tr.top + (tr_ret.bottom - tr_ret.top);
				DrawTextA(hdc, data->noAvatarText, -1, &tr, 
						DT_WORDBREAK | DT_NOPREFIX | DT_CENTER);

				SelectObject(hdc, oldFont);
			}

			// Draw control border
			if (data->borderColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->borderColor);
				FrameRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			SetBkMode(hdc, oldBkMode);

			EndPaint(hwnd, &ps);
			return TRUE;
		}
		case WM_ERASEBKGND:
		{
			HDC hdc = (HDC) wParam;
			RECT rc;
			GetClientRect(hwnd, &rc);

			// Draw background
			if (data->bkgColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->bkgColor);
				FillRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			// Draw control border
			if (data->borderColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->borderColor);
				FrameRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			return TRUE;
		}
		case WM_SIZE:
		{
			if (data->showingFlash)
				ResizeFlash(hwnd, data);
			InvalidateRect(hwnd, NULL, TRUE);
			break;
		}
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}