Пример #1
0
static void CreateThumbsFont()
{
	for (int nFontId = 0; nFontId < FLT_FONTIDS; nFontId++) {
		if (NULL != hFont[nFontId]) {
			DeleteObject(hFont[nFontId]);
			hFont[nFontId] = NULL;
		}

		LOGFONT lf;
		FontService_GetFont(LPGENT("Floating contacts"), s_fonts[nFontId], &tColor[nFontId], &lf);
		hFont[nFontId] = CreateFontIndirect(&lf);
	}
}
Пример #2
0
static void CreateThumbsFont()
{
	for (int nFontId = 0; nFontId < FLT_FONTIDS; nFontId++) {
		if (NULL != hFont[nFontId]) {
			DeleteObject(hFont[nFontId]);
			hFont[nFontId] = NULL;
		}

		LOGFONT lf;
		FontService_GetFont( LPGENT("Floating contacts"), s_fonts[nFontId], &tColor[nFontId], &lf);

		HDC hdc = GetDC(NULL);
		LONG height = lf.lfHeight;
		lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72);
		ReleaseDC(NULL, hdc);

		hFont[nFontId] = CreateFontIndirect(&lf);

		lf.lfHeight = height;
	}
}
Пример #3
0
static LRESULT CALLBACK FrameWndProc(HWND hwndFrame, UINT msg, WPARAM wParam, LPARAM lParam)
{
	CountdownFrameWndData *dat = (CountdownFrameWndData*)GetWindowLongPtr(hwndFrame, GWLP_USERDATA);

	switch (msg) {
	case WM_NCCREATE:  /* init window data */
		dat = (struct CountdownFrameWndData*)mir_calloc(sizeof(*dat));
		SetWindowLongPtr(hwndFrame, GWLP_USERDATA, (LONG_PTR)dat);
		if (dat == NULL) return FALSE; /* creation failed */
		dat->fTimeFlags = *(WORD*)((CREATESTRUCT*)lParam)->lpCreateParams;
		dat->flags = FWPDF_COUNTDOWNINVALID;
		break;

	case WM_CREATE:  /*  create childs */
		{
			CREATESTRUCT *params = (CREATESTRUCT*)lParam;
			dat->hwndIcon = CreateWindowEx(WS_EX_NOPARENTNOTIFY, _T("Static"), NULL, WS_CHILD | WS_VISIBLE | SS_ICON | SS_CENTERIMAGE | SS_NOTIFY,
				3, 0, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), hwndFrame, NULL, params->hInstance, NULL);
			dat->hwndProgress = CreateWindowEx(WS_EX_NOPARENTNOTIFY, PROGRESS_CLASS, (dat->fTimeFlags&SDWTF_ST_TIME) ? TranslateT("Shutdown at:") : TranslateT("Time left:"),
				WS_CHILD | WS_VISIBLE | PBS_SMOOTH, GetSystemMetrics(SM_CXICON) + 5, 5, 90, (GetSystemMetrics(SM_CXICON) / 2) - 5, hwndFrame, NULL, params->hInstance, NULL);
			if (dat->hwndProgress == NULL) return -1; /* creation failed, calls WM_DESTROY */
			SendMessage(dat->hwndProgress, PBM_SETSTEP, 1, 0);
			mir_subclassWindow(dat->hwndProgress, ProgressBarSubclassProc);
			dat->hwndDesc = CreateWindowEx(WS_EX_NOPARENTNOTIFY, _T("Static"), (dat->fTimeFlags&SDWTF_ST_TIME) ? TranslateT("Shutdown at:") : TranslateT("Time left:"),
				WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP | SS_NOTIFY, GetSystemMetrics(SM_CXICON) + 5, (GetSystemMetrics(SM_CXICON) / 2), 75,
				(GetSystemMetrics(SM_CXICON) / 2), hwndFrame, NULL, params->hInstance, NULL);
			dat->hwndTime = CreateWindowEx(WS_EX_NOPARENTNOTIFY, _T("Static"), NULL, WS_CHILD | WS_VISIBLE | SS_RIGHT | SS_NOTIFY | SS_ENDELLIPSIS,
				(GetSystemMetrics(SM_CXICON) + 80), (GetSystemMetrics(SM_CXICON) / 2), 35, (GetSystemMetrics(SM_CXICON) / 2), hwndFrame, NULL, params->hInstance, NULL);
			if (dat->hwndTime == NULL)
				return -1; /* creation failed, calls WM_DESTROY */

			// create tooltips
			TTTOOLINFO ti;
			dat->hwndToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP | TTS_NOPREFIX,
				CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndFrame, NULL, params->hInstance, NULL);
			if (dat->hwndToolTip != NULL) {
				SetWindowPos(dat->hwndToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
				memset(&ti, 0, sizeof(ti));
				ti.cbSize = sizeof(ti);
				ti.hwnd = hwndFrame;
				ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRANSPARENT;
				ti.lpszText = LPSTR_TEXTCALLBACK; /* commctl 4.70+ */
				ti.uId = (UINT_PTR)dat->hwndTime; /* in-place tooltip */
				SendMessage(dat->hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
				ti.uFlags &= ~TTF_TRANSPARENT;
				ti.uId = (UINT_PTR)dat->hwndProgress;
				SendMessage(dat->hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
				if (dat->hwndDesc != NULL) {
					ti.uId = (UINT_PTR)dat->hwndDesc;
					SendMessage(dat->hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
				}
				if (dat->hwndIcon != NULL) {
					ti.uId = (UINT_PTR)dat->hwndIcon;
					SendMessage(dat->hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
				}
			}
			/* init layout */
			dat->hHookColorsChanged = HookEventMessage(ME_COLOUR_RELOAD, hwndFrame, M_REFRESH_COLORS);
			dat->hHookFontsChanged = HookEventMessage(ME_FONT_RELOAD, hwndFrame, M_REFRESH_FONTS);
			dat->hHookIconsChanged = HookEventMessage(ME_SKIN2_ICONSCHANGED, hwndFrame, M_REFRESH_ICONS);
			SendMessage(hwndFrame, M_REFRESH_COLORS, 0, 0);
			SendMessage(hwndFrame, M_REFRESH_FONTS, 0, 0);
			SendMessage(hwndFrame, M_REFRESH_ICONS, 0, 0);
			SendMessage(hwndFrame, M_SET_COUNTDOWN, 0, 0);
			SendMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
			if (!SetTimer(hwndFrame, 1, 1000, NULL))
				return -1; /* creation failed, calls WM_DESTROY */
		}
		return 0;

	case WM_DESTROY:
		if (dat == NULL) return 0;

		UnhookEvent(dat->hHookColorsChanged);
		UnhookEvent(dat->hHookFontsChanged);
		UnhookEvent(dat->hHookIconsChanged);
		/* other childs are destroyed automatically */
		if (dat->hwndToolTip != NULL)
			DestroyWindow(dat->hwndToolTip);
		break;

	case WM_NCDESTROY:
		if (dat == NULL) return 0;
		if (dat->hFont != NULL) DeleteObject(dat->hFont);
		if (dat->hbrBackground != NULL) DeleteObject(dat->hbrBackground);
		mir_free(dat);
		SetWindowLongPtr(hwndFrame, GWLP_USERDATA, 0);
		break;

	case WM_SIZE:
		{
			RECT rc;
			UINT defflg = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE;
			SetRect(&rc, 0, 0, LOWORD(lParam), HIWORD(lParam)); /* width,height */
			/* workaround: reduce flickering of frame in clist */
			InvalidateRect(hwndFrame, &rc, FALSE);
			HDWP hdwp = BeginDeferWindowPos(3);
			/* progress */
			LONG width = rc.right - GetSystemMetrics(SM_CXICON) - 10;
			LONG height = rc.bottom - (GetSystemMetrics(SM_CYICON) / 2) - 5;
			if (NULL != dat->hwndProgress) /* Wine fix. */
				hdwp = DeferWindowPos(hdwp, dat->hwndProgress, NULL, 0, 0, width, height, SWP_NOMOVE | defflg);
			/* desc */
			if (dat->hwndDesc != NULL) /* Wine fix. */
				hdwp = DeferWindowPos(hdwp, dat->hwndDesc, NULL, GetSystemMetrics(SM_CXICON) + 5, 5 + height, 0, 0, SWP_NOSIZE | defflg);
			/* time */
			if (NULL != dat->hwndTime) /* Wine fix. */
				hdwp = DeferWindowPos(hdwp, dat->hwndTime, NULL, GetSystemMetrics(SM_CXICON) + 85, 5 + height, width - 80, (GetSystemMetrics(SM_CXICON) / 2), defflg);
			EndDeferWindowPos(hdwp);
		}
		PostMessage(hwndFrame, M_CHECK_CLIPPED, 0, 0);
		return 0;

	case M_REFRESH_COLORS:
		COLORREF clrBar;
		if (FontService_GetColor(_T("Automatic Shutdown"), _T("Progress Bar"), &clrBar))
			clrBar = GetDefaultColor(FRAMEELEMENT_BAR);
		if (FontService_GetColor(_T("Automatic Shutdown"), _T("Background"), &dat->clrBackground))
			dat->clrBackground = GetDefaultColor(FRAMEELEMENT_BKGRND);
		if (dat->hbrBackground != NULL) DeleteObject(dat->hbrBackground);
		dat->hbrBackground = CreateSolidBrush(dat->clrBackground);
		SendMessage(dat->hwndProgress, PBM_SETBARCOLOR, 0, (LPARAM)clrBar);
		SendMessage(dat->hwndProgress, PBM_SETBKCOLOR, 0, (LPARAM)dat->clrBackground);
		InvalidateRect(hwndFrame, NULL, TRUE);
		return 0;

	case M_REFRESH_ICONS:
		return 0;

	case M_REFRESH_FONTS:
		{
			LOGFONT lf;
			if (!FontService_GetFont(_T("Automatic Shutdown"), _T("Countdown on Frame"), &dat->clrText, &lf)) {
				if (dat->hFont != NULL) DeleteObject(dat->hFont);
				dat->hFont = CreateFontIndirect(&lf);
			}
			else {
				dat->clrText = GetDefaultColor(FRAMEELEMENT_TEXT);
				if (GetDefaultFont(&lf) != NULL) {
					if (dat->hFont != NULL) DeleteObject(dat->hFont);
					dat->hFont = CreateFontIndirect(&lf);
				}
			}
		}
		if (dat->hwndDesc != NULL)
			SendMessage(dat->hwndDesc, WM_SETFONT, (WPARAM)dat->hFont, FALSE);
		SendMessage(dat->hwndTime, WM_SETFONT, (WPARAM)dat->hFont, FALSE);
		InvalidateRect(hwndFrame, NULL, FALSE);
		return 0;

	case WM_SYSCOLORCHANGE:
		SendMessage(hwndFrame, M_REFRESH_COLORS, 0, 0);
		break;

	case WM_SETTINGCHANGE: /* colors depend on windows settings */
		SendMessage(hwndFrame, M_REFRESH_COLORS, 0, 0);
		SendMessage(hwndFrame, M_REFRESH_FONTS, 0, 0);
		SendMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
		RedrawWindow(hwndFrame, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE);
		break;

	case WM_TIMECHANGE: /* windows system clock changed */
		SendMessage(hwndFrame, M_SET_COUNTDOWN, 0, 0);
		PostMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
		break;

	case WM_CTLCOLORDLG:
	case WM_CTLCOLORSTATIC:
		SetTextColor((HDC)wParam, dat->clrText);
		SetBkColor((HDC)wParam, dat->clrBackground);
		return (INT_PTR)dat->hbrBackground;

	case WM_ERASEBKGND:
		{
			RECT rc;
			if (dat->hbrBackground != NULL && GetClientRect(hwndFrame, &rc)) {
				FillRect((HDC)wParam, &rc, dat->hbrBackground);
				return TRUE;
			}
			return FALSE;
		}
	case M_SET_COUNTDOWN:
		if (dat->fTimeFlags&SDWTF_ST_TIME) {
			dat->settingLastTime = (time_t)db_get_dw(NULL, "AutoShutdown", "TimeStamp", SETTING_TIMESTAMP_DEFAULT);
			dat->countdown = time(NULL);
			if (dat->settingLastTime > dat->countdown) dat->countdown = dat->settingLastTime - dat->countdown;
			else dat->countdown = 0;
		}
		else if (dat->flags&FWPDF_COUNTDOWNINVALID) {
			dat->countdown = (time_t)db_get_dw(NULL, "AutoShutdown", "Countdown", SETTING_COUNTDOWN_DEFAULT);
			dat->countdown *= (time_t)db_get_dw(NULL, "AutoShutdown", "CountdownUnit", SETTING_COUNTDOWNUNIT_DEFAULT);
		}
		dat->flags &= ~FWPDF_COUNTDOWNINVALID;
		/* commctl 4.70+, Win95: 1-100 will work fine (wrap around) */
		SendMessage(dat->hwndProgress, PBM_SETRANGE32, 0, (LPARAM)dat->countdown);
		return 0;
	case WM_TIMER:
		if (dat == NULL) return 0;
		if (dat->countdown != 0 && !(dat->flags&FWPDF_COUNTDOWNINVALID) && !(dat->flags&FWPDF_PAUSED)) {
			dat->countdown--;
			PostMessage(dat->hwndProgress, PBM_STEPIT, 0, 0);
		}
		if (IsWindowVisible(hwndFrame)) PostMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
		if (dat->countdown == 0) {
			SendMessage(hwndFrame, M_CLOSE_COUNTDOWN, 0, 0);
			ServiceShutdown(0, TRUE);
			ServiceStopWatcher(0, 0);
		}
		return 0;
	case WM_SHOWWINDOW:
		/* the text is kept unchanged while hidden */
		if ((BOOL)wParam) SendMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
		break;
	case M_UPDATE_COUNTDOWN:
		if (dat->flags&FWPDF_PAUSED && !(dat->flags&FWPDF_PAUSEDSHOWN)) {
			SetWindowText(dat->hwndTime, TranslateT("Paused"));
			dat->flags |= FWPDF_PAUSEDSHOWN;
		}
		else {
			TCHAR szOutput[256];
			if (dat->fTimeFlags&SDWTF_ST_TIME)
				GetFormatedDateTime(szOutput, _countof(szOutput), dat->settingLastTime, TRUE);
			else GetFormatedCountdown(szOutput, _countof(szOutput), dat->countdown);
			SetWindowText(dat->hwndTime, szOutput);
			PostMessage(hwndFrame, M_CHECK_CLIPPED, 0, 0);
			/* update tooltip text (if shown) */
			if (dat->hwndToolTip != NULL && !(dat->flags&FWPDF_PAUSED)) {
				TTTOOLINFO ti;
				ti.cbSize = sizeof(ti);
				if (SendMessage(dat->hwndToolTip, TTM_GETCURRENTTOOL, 0, (LPARAM)&ti) && (HWND)ti.uId != dat->hwndIcon)
					SendMessage(dat->hwndToolTip, TTM_UPDATE, 0, 0);
			}
			else dat->flags &= ~FWPDF_PAUSEDSHOWN;
		}
		return 0;
	case M_CLOSE_COUNTDOWN:
		KillTimer(hwndFrame, 1);
		dat->countdown = 0;
		dat->flags &= ~FWPDF_PAUSED;
		SendMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
		dat->flags |= FWPDF_COUNTDOWNINVALID;
		/* step up to upper range */
		SendMessage(dat->hwndProgress, PBM_SETPOS, SendMessage(dat->hwndProgress, PBM_GETRANGE, FALSE, 0), 0);
		SetWindowLongPtr(dat->hwndProgress, GWL_STYLE, GetWindowLongPtr(dat->hwndProgress, GWL_STYLE) | PBM_SETMARQUEE);
		SendMessage(dat->hwndProgress, PBM_SETMARQUEE, TRUE, 10); /* marquee for rest of time */
		return 0;
	case M_PAUSE_COUNTDOWN:
		if (dat->flags&FWPDF_PAUSED) {
			/* unpause */
			dat->flags &= ~(FWPDF_PAUSED | FWPDF_PAUSEDSHOWN);
			SendMessage(hwndFrame, M_SET_COUNTDOWN, 0, 0);
			SendMessage(dat->hwndProgress, PBM_SETSTATE, PBST_NORMAL, 0); /* WinVista+ */
		}
		else {
			/* pause */
			dat->flags |= FWPDF_PAUSED;
			SendMessage(dat->hwndProgress, PBM_SETSTATE, PBST_PAUSED, 0); /* WinVista+ */
		}
		SendMessage(hwndFrame, M_UPDATE_COUNTDOWN, 0, 0);
		return 0;
	case WM_CONTEXTMENU:
		{
			if (dat->flags & FWPDF_COUNTDOWNINVALID)
				return 0;

			POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
			if (pt.x == -1 && pt.y == -1) { /* invoked by keyboard */
				RECT rc;
				/* position in middle above rect */
				if (!GetWindowRect(hwndFrame, &rc)) return 0;
				pt.x = rc.left + ((int)(rc.right - rc.left) / 2);
				pt.y = rc.top + ((int)(rc.bottom - rc.top) / 2);
			}
			HMENU hContextMenu = CreatePopupMenu();
			if (hContextMenu != NULL) {
				AppendMenu(hContextMenu, MF_STRING, MENUITEM_PAUSECOUNTDOWN, (dat->flags&FWPDF_PAUSED) ? TranslateT("&Unpause Countdown") : TranslateT("&Pause Countdown"));
				SetMenuDefaultItem(hContextMenu, MENUITEM_PAUSECOUNTDOWN, FALSE);
				AppendMenu(hContextMenu, MF_STRING, MENUITEM_STOPCOUNTDOWN, TranslateT("&Cancel Countdown"));
				TrackPopupMenuEx(hContextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_HORPOSANIMATION | TPM_VERPOSANIMATION | TPM_RIGHTBUTTON, pt.x, pt.y, hwndFrame, NULL);
				DestroyMenu(hContextMenu);
			}
		}
		return 0;
	case WM_LBUTTONDBLCLK:
		if (!(dat->flags&FWPDF_COUNTDOWNINVALID))
			SendMessage(hwndFrame, M_PAUSE_COUNTDOWN, 0, 0);
		return 0;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case MENUITEM_STOPCOUNTDOWN:
			/* close only countdown window when other watcher types running */
			if (dat->fTimeFlags&~(SDWTF_SPECIFICTIME | SDWTF_ST_MASK))
				CloseCountdownFrame(); /* something else is running */
			else ServiceStopWatcher(0, 0); /* calls CloseCountdownFrame() */
			return 0;
		case MENUITEM_PAUSECOUNTDOWN:
			SendMessage(hwndFrame, M_PAUSE_COUNTDOWN, 0, 0);
			return 0;
		}
		break;
	case M_CHECK_CLIPPED: /* for in-place tooltip on dat->hwndTime */
		{
			RECT rc;
			HDC hdc;
			SIZE size;
			HFONT hFontPrev = NULL;
			TCHAR szOutput[256];
			dat->flags &= ~FWPDF_TIMEISCLIPPED;
			if (GetWindowText(dat->hwndTime, szOutput, _countof(szOutput)))
				if (GetClientRect(dat->hwndTime, &rc)) {
					hdc = GetDC(dat->hwndTime);
					if (hdc != NULL) {
						if (dat->hFont != NULL)
							hFontPrev = (HFONT)SelectObject(hdc, dat->hFont);
						if (GetTextExtentPoint32(hdc, szOutput, (int)mir_tstrlen(szOutput), &size))
							if (size.cx >= (rc.right - rc.left))
								dat->flags &= FWPDF_TIMEISCLIPPED;
						if (dat->hFont != NULL)
							SelectObject(hdc, hFontPrev);
						ReleaseDC(dat->hwndTime, hdc);
					}
				}
			return 0;
		}
	case WM_NOTIFY:
		if (((NMHDR*)lParam)->hwndFrom == dat->hwndToolTip)
			switch (((NMHDR*)lParam)->code) {
			case TTN_SHOW: /* 'in-place' tooltip on dat->hwndTime */
				if (dat->flags&FWPDF_TIMEISCLIPPED && (HWND)wParam == dat->hwndTime) {
					RECT rc;
					if (GetWindowRect(dat->hwndTime, &rc)) {
						SetWindowLongPtr(dat->hwndToolTip, GWL_STYLE, GetWindowLongPtr(dat->hwndToolTip, GWL_STYLE) | TTS_NOANIMATE);
						SetWindowLongPtr(dat->hwndToolTip, GWL_EXSTYLE, GetWindowLongPtr(dat->hwndToolTip, GWL_EXSTYLE) | WS_EX_TRANSPARENT);
						SendMessage(dat->hwndToolTip, TTM_ADJUSTRECT, TRUE, (LPARAM)&rc);
						SetWindowPos(dat->hwndToolTip, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
						return TRUE; /* self-defined position */
					}
				}
				SetWindowLongPtr(dat->hwndToolTip, GWL_STYLE, GetWindowLongPtr(dat->hwndToolTip, GWL_STYLE) & (~TTS_NOANIMATE));
				SetWindowLongPtr(dat->hwndToolTip, GWL_EXSTYLE, GetWindowLongPtr(dat->hwndToolTip, GWL_EXSTYLE) & (~WS_EX_TRANSPARENT));
				return 0;
			case TTN_POP:
				/* workaround #5: frame does not get redrawn after
				 * in-place tooltip	hidden on dat->hwndTime */
				RedrawWindow(hwndCountdownFrame, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE);
				return 0;
			case TTN_NEEDTEXT:
				{
					NMTTDISPINFO *ttdi = (NMTTDISPINFO*)lParam;
					if (dat->flags&FWPDF_TIMEISCLIPPED && (HWND)wParam == dat->hwndTime) {
						if (GetWindowText(dat->hwndTime, ttdi->szText, _countof(ttdi->szText)))
							ttdi->lpszText = ttdi->szText;
					}
					else if ((HWND)wParam == dat->hwndIcon)
						ttdi->lpszText = TranslateT("Automatic Shutdown");
					else {
						TCHAR szTime[_countof(ttdi->szText)];
						if (dat->fTimeFlags&SDWTF_ST_TIME)
							GetFormatedDateTime(szTime, _countof(szTime), dat->settingLastTime, FALSE);
						else GetFormatedCountdown(szTime, _countof(szTime), dat->countdown);
						mir_sntprintf(ttdi->szText, _T("%s %s"), (dat->fTimeFlags&SDWTF_ST_TIME) ? TranslateT("Shutdown at:") : TranslateT("Time left:"), szTime);
						ttdi->lpszText = ttdi->szText;
					}
					return 0;
				}
			}
		break;
	}
	return DefWindowProc(hwndFrame, msg, wParam, lParam);
}