home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
swCHIP 1991 January
/
swCHIP_95-1.bin
/
ikony
/
animart
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-09
|
16KB
|
606 lines
#include "animator.h"
#include <string.h>
VOID NEAR PASCAL ParseCmdLine (LPSTR);
//////////////////////////////////////////////////////////////////////////
// WinMain - Obviously sets up the Window class, loads string
// and menu resources, creates the frame window,
// sets the timer function pointer, toolhelp notify,
// and allows the non-preemted loop to start.
//////////////////////////////////////////////////////////////////////////
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR lpszCmdLine, int nCmdShow)
{
HACCEL hAccel;
WNDCLASS wndclass;
MSG msg;
if ((short)GetVersion() < 0x0310)
{
MESSAGE (IDS_WinVer);
return 0;
}
_hInst = hInst;
// Load all application strings... (defined in .RC file)
LoadStr (IDS_AppName, _szAppName);
LoadStr (IDS_AppTitle, _szTitleBar);
LoadStr (IDS_ChildClassName, _szChildClass);
LoadStr (IDS_StatBarClassName, _szStatBarClass);
LoadStr (IDS_Extension, _szExtension);
LoadStr (IDS_Untitled, _szUntitled);
LoadStr (IDS_TimerIntervalKey, _szTimeInt);
LoadStr (IDS_InfoSection, _szInfo);
LoadStr (IDS_NumIconsKey, _szNumIcons);
LoadStr (IDS_LinkFileKey, _szLinkFile);
LoadStr (IDS_IconsSection, _szIconSection);
LoadStr (IDS_IconFrameKey, _szIcon);
LoadStr (IDS_AutoAnimateKey, _szAutoAnimateKey);
if (hPrevInst)
{
HWND hwnd = FindWindow (_szAppName,NULL);
BringWindowToTop (hwnd);
return 0;
}
_hmenuMain = LoadMenu(_hInst, MAINMENU);
_hmenuChild = LoadMenu(_hInst, CHILDMENU);
_hmenuMainWindow =
_hmenuChildWindow = GetSubMenu(_hmenuChild, WNDMENUPOS);
_hpnBlack = CreatePen (PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
_hpnGray = CreatePen (PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
_hpnWhite = CreatePen (PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
if (!hPrevInst)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = FrameProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = _hInst;
wndclass.hIcon = LoadIcon(_hInst, MAINICON);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = COLOR_APPWORKSPACE + 1;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = _szAppName;
if (!RegisterClass(&wndclass)) return 0;
wndclass.lpfnWndProc = ChildProc;
wndclass.cbWndExtra = WW_ENDOFWORDS;
wndclass.hIcon = LoadIcon(_hInst, CHILDICON);
wndclass.hbrBackground = COLOR_WINDOW + 1;
wndclass.lpszClassName = _szChildClass;
if (!RegisterClass(&wndclass)) return 0;
wndclass.lpfnWndProc = StatusBarProc;
wndclass.cbWndExtra = 0;
wndclass.hIcon = NULL;
wndclass.hbrBackground = COLOR_BTNFACE + 1;
wndclass.lpszClassName = _szStatBarClass;
if (!RegisterClass (&wndclass)) return 0;
}
_lpfnTimer = MakeProcInstance ((FARPROC)TimerCallback, _hInst);
if (_lpfnTimer == NULL) goto MErr0;
_lpfnNotify = MakeProcInstance ((FARPROC)NotifyProc, _hInst);
if (_lpfnNotify == NULL) goto MErr1;
_lpfnSettings = MakeProcInstance ((FARPROC)SettingsDlg, _hInst);
if (_lpfnSettings == NULL) goto MErr2;
_lpfnAbout = MakeProcInstance ((FARPROC)About, _hInst);
if (_lpfnAbout == NULL) goto MErr3;
_lpfnBroadcast = MakeProcInstance ((FARPROC)BroadcastProc, _hInst);
if (_lpfnBroadcast == NULL) goto MErr4;
_hwndFrame = CreateWindow(_szAppName, _szTitleBar,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
0, 0, FRAME_X, FRAME_Y,
NULL, _hmenuMain, _hInst, NULL);
if (!IsWindow(_hwndFrame)) goto MErr5;
if (!RestorePosition (_hwndFrame, nCmdShow))
{
CenterWindow (_hwndFrame);
}
if (lpszCmdLine)
{
ParseCmdLine (lpszCmdLine);
RefreshAnimations ();
}
ShowWindow(_hwndFrame, SW_SHOW);
UpdateWindow(_hwndFrame);
hAccel = LoadAccelerators(_hInst, ACCELTABLE);
if (hAccel == NULL) goto MErr5;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateMDISysAccel(_hwndClient, &msg) &&
!TranslateAccelerator(_hwndFrame, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
MErr5:
FreeProcInstance (_lpfnBroadcast);
MErr4:
FreeProcInstance (_lpfnAbout);
MErr3:
FreeProcInstance (_lpfnSettings);
MErr2:
FreeProcInstance (_lpfnNotify);
MErr1:
FreeProcInstance (_lpfnTimer);
MErr0:
DeletePen (_hpnBlack);
DeletePen (_hpnWhite);
DeletePen (_hpnGray);
return msg.wParam;
}
//////////////////////////////////////////////////////////////////////////
// CenterWindow - takes any window (more especially dialog boxes) and
// centers it on the display.
//////////////////////////////////////////////////////////////////////////
VOID WINAPI CenterWindow (HWND hDlg)
{
RECT rc;
GetWindowRect(hDlg,&rc);
SetWindowPos(hDlg,NULL,
(GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
(GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
}
//////////////////////////////////////////////////////////////////////////
// RestorePosition() - Gets the formated information for the
// WINDOWPLACEMENT structure from the WIN.INI file, parses it by
// calling IntFromString(), and then calls SetWindowPlacement().
//////////////////////////////////////////////////////////////////////////
BOOL WINAPI RestorePosition (HWND hwnd, short nCmdShow)
{
char szFmt[80];
LPSTR lpszCur = (LPSTR)szFmt;
WINDOWPLACEMENT wpl;
GetProfileString ((LPSTR)_szTitleBar, (LPSTR)"Position\0", (LPSTR)"\0",
(LPSTR)szFmt, sizeof(szFmt));
if (szFmt[0] == '\0' || IntFromString((LPSTR FAR *)&lpszCur) != 9)
{
return FALSE;
}
else
{
// Format in the WIN.INI file for the position restoration is:
// [Animator]
// Position = 9 showcmd minX minY maxX maxY normX normY normDX normDY
//
wpl.length = sizeof(wpl);
wpl.showCmd = (UINT)IntFromString((LPSTR FAR *)&lpszCur);
wpl.showCmd = (UINT)nCmdShow;
wpl.ptMinPosition.x = IntFromString((LPSTR FAR *)&lpszCur);
wpl.ptMinPosition.y = IntFromString((LPSTR FAR *)&lpszCur);
wpl.ptMaxPosition.x = IntFromString((LPSTR FAR *)&lpszCur);
wpl.ptMaxPosition.y = IntFromString((LPSTR FAR *)&lpszCur);
wpl.rcNormalPosition.left = IntFromString((LPSTR FAR *)&lpszCur);
wpl.rcNormalPosition.top = IntFromString((LPSTR FAR *)&lpszCur);
wpl.rcNormalPosition.right = IntFromString((LPSTR FAR *)&lpszCur);
wpl.rcNormalPosition.bottom = IntFromString((LPSTR FAR *)&lpszCur);
return SetWindowPlacement(hwnd, &wpl);
}
}
//////////////////////////////////////////////////////////////////////////
// RecordPosition() - Gets the window placement and show state, by
// using the GetWindowPlacement function. the length member MUST
// be filled or it will fail. We then write the information to
// the WIN.INI with the info separated by spaces.
//////////////////////////////////////////////////////////////////////////
VOID WINAPI RecordPosition(HWND hwnd)
{
WINDOWPLACEMENT wpl;
char szFmt[80];
wpl.length = sizeof(wpl); // necessary...
GetWindowPlacement(hwnd, &wpl);
wsprintf((LPSTR)szFmt, "%d %d %d %d %d %d %d %d %d %d",
9,
wpl.showCmd,
wpl.ptMinPosition.x,
wpl.ptMinPosition.y,
wpl.ptMaxPosition.x,
wpl.ptMaxPosition.y,
wpl.rcNormalPosition.left,
wpl.rcNormalPosition.top,
wpl.rcNormalPosition.right,
wpl.rcNormalPosition.bottom
);
WriteProfileString((LPSTR)_szTitleBar, (LPSTR)"Position", (LPSTR)szFmt);
}
//////////////////////////////////////////////////////////////////////////
// IntFromString() - Our version of the C function itoa, with a little
// more flexibility given our situation: a string of ints separated by
// spaces.
//////////////////////////////////////////////////////////////////////////
short WINAPI IntFromString(LPSTR FAR * lplpsz)
{
LPSTR lpsz = *lplpsz;
short i = 0;
char ch;
BOOL fNeg;
while (*lpsz == ' ')
lpsz++;
fNeg = FALSE;
while (ch = *lpsz++)
{
if (ch == '-')
{
fNeg = !fNeg;
continue;
}
if (ch < '0' || ch > '9')
break;
i = (i * 10) + (ch - '0');
}
*lplpsz = lpsz;
return (fNeg ? -i : i);
}
//////////////////////////////////////////////////////////////////////////
// DeletePreviousHandles - Frees the memory occupied by the icons
// in the list, if any in the list.
//////////////////////////////////////////////////////////////////////////
VOID WINAPI DeletePreviousHandles (HWND hwnd)
{
short sChild = WINDOWNUM(hwnd);
short sLimit = NUMICONS (sChild);
short i;
if (sLimit)
{
for (i=0; i<sLimit ;i++)
{
if (HICONS(sChild)[i] != NULL)
{
GlobalFree (HICONS(sChild)[i]);
HICONS(sChild)[i] = NULL;
}
}
SET_NUMICONS (sChild, 0);
}
}
//////////////////////////////////////////////////////////////////////////
// SetupIconHandles - takes the active window, gets the icon filenames
// from the listbox, loads those icons into memory in an array kept
// in the animStruct.
//////////////////////////////////////////////////////////////////////////
VOID WINAPI SetupIconHandles (HWND hwnd)
{
short sChild, sLimit, i;
HWND hwndList;
HICON * phIcons;
char szlistbox[MAX_FILE_SIZE];
if (!IsWindow(hwnd)) return;
sChild = WINDOWNUM(hwnd);
hwndList = HWNDLIST(hwnd);
SET_NUMICONS (sChild, (short)ListBox_GetCount(hwndList));
sLimit = NUMICONS(sChild);
phIcons = HICONS(sChild);
for (i=0 ; i<sLimit ; i++)
{
ListBox_GetText (hwndList,i,(LPSTR)szlistbox);
// If the user manually entered the filename in the
// .ANM file, and did not include a path, this condition
// takes care of it:
if (strrchr (szlistbox, '\\') == NULL)
{
char szDir[MAX_FILE_SIZE];
getcwd (szDir, MAX_FILE_SIZE);
if (szDir[strlen(szDir)-1] != '\\')
{
strcat (szDir, "\\");
}
strcat (szDir, szlistbox);
phIcons[i] = ExtractIcon(_hInst, (LPSTR)szDir, 0);
}
else
{
phIcons[i] = ExtractIcon(_hInst, (LPSTR)szlistbox, 0);
}
}
phIcons[sLimit] = NULL;
}
//////////////////////////////////////////////////////////////////////////
// DeleteCurSel - takes the selected files in the listbox, and
// deletes them.
//////////////////////////////////////////////////////////////////////////
BOOL WINAPI DeleteCurSel (HWND hwnd)
{
short sSel;
short sChild;
short sNumIcons;
HWND hwndList;
short i;
if (!IsWindow(hwnd)) return FALSE;
sChild = WINDOWNUM (hwnd);
hwndList = HWNDLIST (hwnd);
sNumIcons = NUMICONS (sChild);
sSel = (short)ListBox_GetCurSel (hwndList);
if (sSel == LB_ERR)
{
return FALSE;
}
for (i=sSel ; i<sNumIcons ; i++)
{
if (i == sSel)
{
GlobalFree (HICONS(sChild)[i]);
}
HICONS(sChild)[i] = HICONS(sChild)[i+1];
}
SET_NUMICONS (sChild, --sNumIcons);
ListBox_DeleteString (hwndList, sSel);
ListBox_SetCurSel (hwndList, sSel);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// GetWindowListbox - gets the active window, then looks to its first
// extra window word for the handle to its listbox, and returns it.
//////////////////////////////////////////////////////////////////////////
HWND WINAPI GetWindowListbox(VOID)
{
return (HWND)(IsWindow(_hwndClient) ?
HWNDLIST(MDI_GetActive(_hwndClient))
: NULL);
}
//////////////////////////////////////////////////////////////////////////
// GetWindowNumber - looks to the second extra window word in the
// window data structure, and finds the number of the window, and
// returns it. The number is kept for data structure access purposes.
//////////////////////////////////////////////////////////////////////////
short WINAPI GetWindowNumber(VOID)
{
return (short)(IsWindow(_hwndClient) ?
WINDOWNUM(MDI_GetActive(_hwndClient))
: -1);
}
//////////////////////////////////////////////////////////////////////////
// CheckForDoubles - Just ensures that nobody tries to set up two
// animations on one running application.
//////////////////////////////////////////////////////////////////////////
BOOL WINAPI CheckForDoubles (HWND hwnd)
{
int i;
BOOL result = FALSE;
for (i=0 ; i<MAXANIMATIONS ; i++)
{
if (HWNDANIM(i)!=NULL)
{
if (HWNDTARGET(i) == hwnd)
{
result = TRUE;
}
}
}
return result;
}
//////////////////////////////////////////////////////////////////////////
// MESSAGE - just loads the appropriate string via the string ID value,
// and displays it in the form of an error message box.
//////////////////////////////////////////////////////////////////////////
VOID WINAPI MESSAGE (WORD wStringID)
{
char szString[96];
LoadStr (wStringID,szString);
MessageBox (NULL, (LPSTR)szString, (LPSTR)_szAppName,
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
}
//////////////////////////////////////////////////////////////////////////
// GetTextWidth() - Gets the height of the string in the DC which
// already has the font selected into it.
//////////////////////////////////////////////////////////////////////////
UINT WINAPI GetTextWidth (HDC hdc, LPSTR lp)
{
return (UINT)LOWORD(GetTextExtent (hdc, lp, lstrlen(lp)));
}
//////////////////////////////////////////////////////////////////////////
// GetTextHeight() - Gets the height of the string in the DC which
// already has the font selected into it.
//////////////////////////////////////////////////////////////////////////
UINT WINAPI GetTextHeight (HDC hdc, LPSTR lp)
{
return (UINT)HIWORD(GetTextExtent (hdc, lp, lstrlen(lp)));
}
//////////////////////////////////////////////////////////////////////////
// GetANSITextHeight() - returns the height including leading to the
// caller.
//////////////////////////////////////////////////////////////////////////
UINT WINAPI GetANSITextHeight(VOID)
{
TEXTMETRIC tm;
HDC hdc = GetDC (NULL);
HFONT hold = SelectFont (hdc, GetStockFont(ANSI_VAR_FONT));
if (!hold) return 0;
GetTextMetrics (hdc, &tm);
SelectFont (hdc, hold);
ReleaseDC (NULL, hdc);
return (UINT)(tm.tmHeight + tm.tmExternalLeading);
}
//////////////////////////////////////////////////////////////////////////
// NotifyProc() - Everytime TOOLHELP figures out that a task is
// exiting or starting, it notifies us via this callback function.
// We immediately post the message to get the condition into the queue
// of a window.
//////////////////////////////////////////////////////////////////////////
BOOL _export CALLBACK NotifyProc (WORD wID, DWORD dwData)
{
switch (wID)
{
case NFY_EXITTASK:
{
PostMessage (_hwndFrame, WM_COMMAND, IDN_EXITTASK, 0L);
break;
}
case NFY_STARTTASK:
{
PostMessage (_hwndFrame, WM_COMMAND, IDN_NEWTASK, 0L);
break;
}
default:
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////
// ParseCmdLine() takes the command line for animator and parses
// it to find which files to initially open, and opens them.
///////////////////////////////////////////////////////////////////
VOID NEAR PASCAL ParseCmdLine (LPSTR lpszCmdLine)
{
LPSTR lpszCur = lpszCmdLine;
char szFileName[MAX_FILE_SIZE];
short i = 0;
AnsiUpper (lpszCmdLine);
while (*lpszCur)
{
while (*lpszCur && *lpszCur != ' ')
{
szFileName[i++] = *lpszCur++;
}
szFileName[i] = '\0';
if (!GetPathIfNoPath ((LPSTR)szFileName))
{
MESSAGE (IDS_InvalidScript);
}
else
{
OpenIconsInFile (szFileName);
}
if (*lpszCur)
{
lpszCur++; // kill leading blank character.
}
i = 0;
}
}