Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

465 lines
10 KiB

#include "ctlspriv.h"
#include "rlefile.h"
#define RectWid(_rc) ((_rc).right-(_rc).left)
#define RectHgt(_rc) ((_rc).bottom-(_rc).top)
typedef struct {
HWND hwnd; // my window
int id; // my id
HWND hwndP; // my owner (get notify messages)
HINSTANCE hInstance; // my hInstance
BOOL fFirstPaint; // TRUE until first paint.
RLEFILE *prle;
#ifdef WIN32
CRITICAL_SECTION crit;
#endif
RECT rc;
int NumFrames;
int Rate;
int iFrame;
int PlayCount;
int PlayFrom;
int PlayTo;
HANDLE PaintThread;
} ANIMATE;
#ifdef WIN32
#define Enter(p) EnterCriticalSection(&p->crit)
#define Leave(p) LeaveCriticalSection(&p->crit)
#else
#define Enter(p)
#define Leave(p)
#endif
#define OPEN_WINDOW_TEXT 42
LRESULT CALLBACK AnimateWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL HandleOpen(ANIMATE *p, LPCTSTR pszName, UINT flags);
BOOL HandleStop(ANIMATE *p);
BOOL HandlePlay(ANIMATE *p, int from, int to, int count);
void HandlePaint(ANIMATE *p, HDC hdc);
BOOL HandleTick(ANIMATE *p);
#pragma code_seg(CODESEG_INIT)
TCHAR c_szAnimateClass[] = ANIMATE_CLASS;
BOOL FAR PASCAL InitAnimateClass(HINSTANCE hInstance)
{
WNDCLASS wc;
if (!GetClassInfo(hInstance, c_szAnimateClass, &wc)) {
#ifndef WIN32
extern LRESULT CALLBACK _AnimateWndProc(HWND, UINT, WPARAM, LPARAM);
wc.lpfnWndProc = _AnimateWndProc;
#else
wc.lpfnWndProc = (WNDPROC)AnimateWndProc;
#endif
wc.lpszClassName = c_szAnimateClass;
wc.style = CS_DBLCLKS | CS_GLOBALCLASS;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(DWORD);
wc.hInstance = hInstance; // use DLL instance if in DLL
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wc.lpszMenuName = NULL;
if (!RegisterClass(&wc))
return FALSE;
}
return TRUE;
}
#pragma code_seg()
BOOL HandleOpen(ANIMATE *p, LPCTSTR pszName, UINT flags)
{
TCHAR ach[MAX_PATH];
//
// use window text as file name
//
if (flags == OPEN_WINDOW_TEXT)
{
GetWindowText(p->hwnd, ach, ARRAYSIZE(ach));
pszName = ach;
}
HandleStop(p); // stop a play first
if (p->prle)
{
RleFile_Free(p->prle);
p->prle = NULL;
}
p->iFrame = 0;
p->NumFrames = 0;
if (pszName == NULL || (HIWORD(pszName) && *pszName == 0))
return FALSE;
//
// now open the file/resource we got.
//
p->prle = RleFile_New();
if (p->prle == NULL)
return FALSE;
if (!RleFile_OpenFromResource(p->prle, p->hInstance, pszName, TEXT("AVI")) &&
!RleFile_OpenFromFile(p->prle, pszName))
{
RleFile_Free(p->prle);
p->prle = NULL;
return FALSE;
}
else
{
p->NumFrames = RleFile_NumFrames(p->prle);
p->Rate = (int)RleFile_Rate(p->prle);
SetRect(&p->rc, 0, 0, RleFile_Width(p->prle), RleFile_Height(p->prle));
}
//
// handle a transparent color
//
if ((GetWindowLong(p->hwnd, GWL_STYLE) & ACS_TRANSPARENT) && p->hwndP)
{
HDC hdc;
HDC hdcM;
HBITMAP hbm;
COLORREF rgbS, rgbD;
hdc = GetDC(p->hwnd);
//
// create a bitmap and draw image into it.
// get upper left pixel and make that transparent.
//
hdcM= CreateCompatibleDC(hdc);
hbm = CreateCompatibleBitmap(hdc, 1, 1);
SelectObject(hdcM, hbm);
HandlePaint(p, hdcM);
rgbS = GetPixel(hdcM, 0, 0);
DeleteDC(hdcM);
DeleteObject(hbm);
SendMessage(p->hwndP, GET_WM_CTLCOLOR_MSG(CTLCOLOR_STATIC),
GET_WM_CTLCOLOR_MPS(hdc, p->hwnd, CTLCOLOR_STATIC));
rgbD = GetBkColor(hdc);
ReleaseDC(p->hwnd, hdc);
//
// now replace the color
//
RleFile_ChangeColor(p->prle, rgbS, rgbD);
}
//
// ok it worked, resize window.
//
if (GetWindowLong(p->hwnd, GWL_STYLE) & ACS_CENTER)
{
RECT rc;
GetClientRect(p->hwnd, &rc);
OffsetRect(&p->rc, (rc.right-p->rc.right)/2,(rc.bottom-p->rc.bottom)/2);
}
else
{
RECT rc;
rc = p->rc;
AdjustWindowRectEx(&rc, GetWindowStyle(p->hwnd), FALSE, GetWindowExStyle(p->hwnd));
SetWindowPos(p->hwnd, NULL, 0, 0, RectWid(rc), RectHgt(rc),
SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
}
if (GetWindowLong(p->hwnd, GWL_STYLE) & ACS_AUTOPLAY)
{
PostMessage(p->hwnd, ACM_PLAY, (UINT)-1, MAKELONG(0, -1));
}
else
{
InvalidateRect(p->hwnd, NULL, TRUE);
}
return TRUE;
}
void DoNotify(ANIMATE *p, int cmd)
{
if (p->hwndP)
PostMessage(p->hwndP, WM_COMMAND, GET_WM_COMMAND_MPS(p->id, p->hwnd, cmd));
}
BOOL HandleStop(ANIMATE *p)
{
if (p == NULL || !p->PaintThread)
return FALSE;
#ifdef WIN32
// set thread up to terminate between frames
Enter( p );
p->PlayCount = 0;
Leave( p );
WaitForSingleObject(p->PaintThread, INFINITE);
CloseHandle(p->PaintThread);
p->PaintThread = NULL;
#else
KillTimer(p->hwnd, (int)p->PaintThread);
p->PaintThread = 0;
DoNotify(p, ACN_STOP);
#endif
return TRUE;
}
#ifdef WIN32
int PlayThread(ANIMATE *p)
{
DoNotify(p, ACN_START);
while (HandleTick(p))
Sleep(p->Rate);
DoNotify(p, ACN_STOP);
return 0;
}
#endif
BOOL HandlePlay(ANIMATE *p, int from, int to, int count)
{
if (p == NULL || p->prle == NULL)
return FALSE;
HandleStop(p);
if (from >= p->NumFrames)
from = p->NumFrames-1;
if (to == -1)
to = p->NumFrames-1;
if (to < 0)
to = 0;
if (to >= p->NumFrames)
to = p->NumFrames-1;
p->PlayCount = count;
p->PlayTo = to;
if (from >= 0) {
p->iFrame = from;
p->PlayFrom = from;
} else
from = p->PlayFrom;
if ( (from == to) || !count )
{
InvalidateRect(p->hwnd, NULL, TRUE);
return TRUE;
}
InvalidateRect(p->hwnd, NULL, FALSE);
UpdateWindow(p->hwnd);
#ifdef WIN32
{
DWORD dw;
p->PaintThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlayThread, (void*)p, 0, &dw);
}
#else
DoNotify(p, ACN_START);
p->PaintThread = (HANDLE)SetTimer(p->hwnd, 42, (UINT)p->Rate, NULL);
#endif
return TRUE;
}
void HandlePaint(ANIMATE *p, HDC hdc)
{
if( p && p->prle )
{
Enter( p );
RleFile_Paint( p->prle, hdc, p->iFrame, p->rc.left, p->rc.top );
Leave( p );
}
}
void HandleErase(ANIMATE * p, HDC hdc)
{
HBRUSH hbr;
RECT rc;
hbr = (HBRUSH)SendMessage(p->hwndP, GET_WM_CTLCOLOR_MSG(CTLCOLOR_STATIC),
GET_WM_CTLCOLOR_MPS(hdc, p->hwnd, CTLCOLOR_STATIC));
GetClientRect(p->hwnd, &rc);
FillRect(hdc, &rc, hbr);
}
BOOL HandleTick(ANIMATE *p)
{
BOOL result = FALSE;
if( p && p->prle )
{
HDC hdc;
RECT dummy;
Enter( p );
hdc = GetDC( p->hwnd );
if( GetClipBox( hdc, &dummy ) != NULLREGION )
{
// do a full repaint on first frame
if( p->iFrame == p->PlayFrom )
HandlePaint( p, hdc );
else
RleFile_Draw( p->prle, hdc, p->iFrame, p->rc.left, p->rc.top );
if( p->iFrame >= p->PlayTo )
{
if( p->PlayCount > 0 )
p->PlayCount--;
if( p->PlayCount != 0 )
p->iFrame = p->PlayFrom;
}
else
p->iFrame++;
}
else
p->iFrame = p->PlayFrom;
ReleaseDC( p->hwnd, hdc );
result = ( p->PlayCount != 0 );
Leave( p );
}
return result;
}
LRESULT CALLBACK AnimateWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
ANIMATE *p = (ANIMATE *)(UINT)GetWindowLong(hwnd, 0);
HDC hdc;
PAINTSTRUCT ps;
switch (msg) {
case WM_NCCREATE:
#define lpcs ((LPCREATESTRUCT)lParam)
p = (ANIMATE *)LocalAlloc(LPTR, sizeof(ANIMATE));
if (!p)
return 0; // WM_NCCREATE failure is 0
// note, zero init memory from above
p->hwnd = hwnd;
p->hwndP = lpcs->hwndParent;
p->hInstance = lpcs->hInstance;
p->id = (int)lpcs->hMenu;
p->fFirstPaint = TRUE;
#ifdef WIN32
InitializeCriticalSection(&p->crit);
#endif
SetWindowLong(hwnd, 0, (LONG)(UINT)p);
break;
case WM_CLOSE:
Animate_Stop(hwnd);
break;
case WM_DESTROY:
if (p)
{
Animate_Close(hwnd);
if( p )
{
DeleteCriticalSection(&p->crit);
LocalFree((HLOCAL)p);
SetWindowLong(hwnd, 0, 0);
}
}
break;
case WM_NCHITTEST:
return HTTRANSPARENT;
case WM_ERASEBKGND:
HandleErase(p, (HDC)wParam);
return(1);
case WM_PAINT:
if (p->fFirstPaint)
{
p->fFirstPaint = FALSE;
if (p->NumFrames == 0 &&
(GetWindowLong(p->hwnd, GWL_STYLE) & WS_CHILD))
{
HandleOpen(p, NULL, OPEN_WINDOW_TEXT);
}
}
hdc = BeginPaint(hwnd, &ps);
HandlePaint(p, hdc);
EndPaint(hwnd, &ps);
return 0;
case WM_SIZE:
if (GetWindowLong(hwnd, GWL_STYLE) & ACS_CENTER)
{
OffsetRect(&p->rc, (LOWORD(lParam)-RectWid(p->rc))/2-p->rc.left,
(HIWORD(lParam)-RectHgt(p->rc))/2-p->rc.top);
InvalidateRect(hwnd, NULL, TRUE);
}
break;
#ifndef WIN32
case WM_TIMER:
if (!HandleTick(p))
HandleStop(p);
break;
#endif
#ifdef UNICODE
case ACM_OPENA:
{
WCHAR szFileNameW[MAX_PATH];
LPTSTR lpFileName = szFileNameW;
if (HIWORD(lParam)) {
MultiByteToWideChar (CP_ACP, 0, (LPCSTR)lParam, -1,
szFileNameW, MAX_PATH);
} else {
lpFileName = (LPTSTR) lParam;
}
return HandleOpen(p, lpFileName, (UINT)wParam);
}
#endif
case ACM_OPEN:
return HandleOpen(p, (LPCTSTR)lParam, (UINT)wParam);
case ACM_STOP:
return HandleStop(p);
case ACM_PLAY:
return HandlePlay(p, (int)(SHORT)LOWORD(lParam), (int)(SHORT)HIWORD(lParam), (int)wParam);
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}