Pues visto lo visto he escrito una función que realiza el efecto. Despliega una ventana semitransparente con un texto en el systray, la muestra un tiempo y la repliega.
Hacer el efecto con la VCL es muy sencillo, pero nos ata a ella y a ejecutables muy pesados. Si queremos el efecto para mini ejecutables (estoy hablando de ejecutables de 5 a 10k) tenemos que bajar a la API. Eso es lo que muestro en este truco que además puede servir de ejemplo o punto de partida para modificaciones posteriores o mostrar ventanas mas complejas pasando su Handle.
Aquí muestro el código en C++
void TaskBarUpMessage(char *Msg, int cX, int cY, int cW, int cH, int cTime, HINSTANCE chInstance) { RECT RectArea; SystemParametersInfo(SPI_GETWORKAREA, 0, &RectArea, 0); static YMax = RectArea.bottom; static int X = cX; static int Y = cY; static int W = cW; static int H = cH; static int Time = cTime; static HINSTANCE hInstance = chInstance; int Margin = 10; SIZE Size; HDC hDC = GetDC(0); int nLines = 1; int Ancho = 0; for(char *C = Msg, *Ini = Msg; *C; C++) if(*C=='\n') { GetTextExtentPoint32(hDC, Ini, DWORD(C)-DWORD(Ini), &Size); if(Ancho < Size.cx) Ancho = Size.cx; Ini = C; nLines++; } if(!W) W = Ancho + Margin*2; if(!H) H = Size.cy*nLines + Margin*2.5; if(!X) X = RectArea.right - W; if(Y) YMax = H+Y; Y = YMax; ReleaseDC(0, hDC); struct Timer{ static VOID __stdcall OnTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime){ static Inc = 1; if(YMax-Y >= H && Inc>0){ Inc = -Inc; Sleep(Time); } if(YMax<=Y && Inc<0){ Inc = -Inc; SendMessage(hWnd, WM_CLOSE, 0, 0); ::UnregisterClass("UPMSG", hInstance); return; } Y-=Inc; // SetWindowPos(hWnd, HWND_TOPMOST, X, Y, W, YMax-Y, SWP_SHOWWINDOW); SetWindowPos(hWnd, HWND_TOP, X, Y, W, H, SWP_SHOWWINDOW); } }TI; WNDCLASS WinClass = {0,DefWindowProc,0,0,hInstance,0,0,(HBRUSH)COLOR_BTNSHADOW,"","UPMSG"}; ::RegisterClass(&WinClass); HANDLE hFrame = CreateWindowEx(WS_EX_LAYERED, "UPMSG", "",WS_VISIBLE | WS_POPUP |WS_THICKFRAME ,X, Y, W, 0, HWND_DESKTOP, (HMENU)0, hInstance, NULL); HANDLE hStatic = CreateWindow("STATIC", "", WS_VISIBLE | WS_CHILD ,Margin, Margin, W-Margin*2, H-Margin*2, hFrame, (HMENU)0, hInstance, NULL); SetWindowText(hStatic, Msg); SetLayeredWindowAttributes(hFrame, NULL, 200, LWA_ALPHA); SetTimer(hFrame, 0, 10, (TIMERPROC)TI.OnTimer); }
El uso es simple. Si damos los valores cero a las coordenadas de la ventana, la muestra en el systray y calcula el tamaño necesario para contener el texto según el número de líneas y tamaño.
Si damos tamaño a la ventana, el texto se tratará de ajustar a ella.
cTime es el tiempo durante el que mostrará la ventana una vez desplegada antes de comenzar a ocultarse.
Ejemplo de uso automático:
TaskBarUpMessage("Mensage secundario\nMicroondas\ncocedero", 0, 0, 0, 0, 1000, 0);
Saludos.