LRESULT CALLBACK EditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static BOOL bHover; static BYTE dwAlphaEnd; static BYTE dwAlphaStart; static BYTE dwAlphaStep; switch (msg) { case WM_SYSCOMMAND: if ((wParam & 0xFFF0) == SC_CLOSE) return SendMessage(GetParent(hWnd), WM_SYSCOMMAND, wParam, lParam); break; case WM_MOUSEMOVE: if (!bHover) { if (hWnd != GetFocus()) SetFocus(hWnd); bHover = TRUE; TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hWnd, 0 }; TrackMouseEvent(&tme); InvalidateRect(hWnd, 0, TRUE); PostMessage(hWnd, WM_SETALPHA, SHOWEDITALPHA, 0); } break; case WM_MOUSELEAVE: bHover = FALSE; PostMessage(hWnd, WM_SETALPHA, HIDEDITALPHA, 0); break; case WM_SETALPHA: KillTimer(hWnd, 0x1234); GetLayeredWindowAttributes(hWnd, 0, &dwAlphaStart, 0); dwAlphaEnd = wParam; dwAlphaStep = 0; SetTimer(hWnd, 0x1234, 1, 0); return 0; case WM_TIMER: if (dwAlphaStep > ANIMATION_STEP || dwAlphaStart == dwAlphaEnd) { KillTimer(hWnd, 0x1234); SetLayeredWindowAttributes(hWnd, 0, dwAlphaEnd, LWA_ALPHA); } else { dwAlphaStep++; const BYTE bByte = (dwAlphaStart < dwAlphaEnd) ? easeOutExpo(dwAlphaStep, dwAlphaStart, dwAlphaEnd - dwAlphaStart, ANIMATION_STEP) : dwAlphaStart + dwAlphaEnd - easeOutExpo(dwAlphaStep, dwAlphaEnd, dwAlphaStart - dwAlphaEnd, ANIMATION_STEP); SetLayeredWindowAttributes(hWnd, 0, bByte, LWA_ALPHA); } break; case WM_DESTROY: KillTimer(hWnd, 0x1234); break; } return CallWindowProc(EditWndProc, hWnd, msg, wParam, lParam); }
/** * Easing equation function for an exponential (2^t) easing out/in: deceleration until halfway, then acceleration. * * @param t Current time (in frames or seconds). * @return The correct value. */ static qreal easeOutInExpo(qreal t) { if (t < 0.5) return easeOutExpo (2*t)/2; return easeInExpo(2*t - 1)/2 + 0.5; }