home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
swCHIP 1991 January
/
swCHIP_95-1.bin
/
ikony
/
animart
/
child.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-09
|
18KB
|
691 lines
#include "animator.h"
static char szAllPurpose [MAX_FILE_SIZE];
#ifdef __cplusplus
extern "C" {
#endif
BOOL NEAR PASCAL Child_OnCreate (HWND, LPCREATESTRUCT);
VOID NEAR PASCAL Child_OnSize (HWND, UINT, short, short);
VOID NEAR PASCAL Child_OnSetFocus (HWND, HWND);
VOID NEAR PASCAL Child_OnMDIActivate (HWND, BOOL, HWND, HWND);
VOID NEAR PASCAL Child_OnCommand (HWND, UINT, HWND, UINT);
VOID NEAR PASCAL Child_OnDestroy (HWND);
VOID NEAR PASCAL Child_OnClose(HWND);
BOOL NEAR PASCAL Child_OnQueryEndSession (HWND);
LONG NEAR PASCAL Child_OnDrawItem (HWND, const DRAWITEMSTRUCT FAR *);
LONG NEAR PASCAL Child_OnMeasureItem (HWND, LPMEASUREITEMSTRUCT);
VOID NEAR PASCAL Child_OnDropFiles (HWND, HDROP);
short NEAR PASCAL FigureOutWhereToInsert (HWND, LPPOINT);
BOOL NEAR PASCAL InsertIconImage (short, HWND, short, LPSTR);
BOOL NEAR PASCAL AddIconImage (short, HWND, LPSTR);
VOID NEAR PASCAL HandleSelectionState (const DRAWITEMSTRUCT FAR *);
VOID NEAR PASCAL HandleFocusState (const DRAWITEMSTRUCT FAR *);
#ifdef __cplusplus
}
#endif
//////////////////////////////////////////////////////////////////////////
// ChildProc - Handles all of the messages for the Child animation
// window which shows all of the icons and their file names.
// The window procedure makes use of Message Crackers, a new
// idea introduced in the header file WINDOWSX.H. Using this file
// is a good way to preserve your code for changes in upcoming versions
// of Windows, where types and parameters change.
//////////////////////////////////////////////////////////////////////////
LRESULT _export CALLBACK ChildProc(WNDPROC_PARAMS)
{
switch (uMsg)
{
HANDLE_MSG (hWnd, WM_CREATE, Child_OnCreate);
HANDLE_MSG (hWnd, WM_SIZE, Child_OnSize);
HANDLE_MSG (hWnd, WM_SETFOCUS, Child_OnSetFocus);
HANDLE_MSG (hWnd, WM_MDIACTIVATE, Child_OnMDIActivate);
HANDLE_MSG (hWnd, WM_COMMAND, Child_OnCommand);
HANDLE_MSG (hWnd, WM_DRAWITEM, Child_OnDrawItem);
HANDLE_MSG (hWnd, WM_MEASUREITEM, Child_OnMeasureItem);
HANDLE_MSG (hWnd, WM_DESTROY, Child_OnDestroy);
HANDLE_MSG (hWnd, WM_CLOSE, Child_OnClose);
HANDLE_MSG (hWnd, WM_QUERYENDSESSION, Child_OnQueryEndSession);
HANDLE_MSG (hWnd, WM_DROPFILES, Child_OnDropFiles);
}
return DefMDIChildProc(hWnd, uMsg, wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////
// Child_OnCreate() - Creates the listbox and initializes the data
// structure and window words for this window.
//////////////////////////////////////////////////////////////////////////
BOOL NEAR PASCAL Child_OnCreate (HWND hwnd, LPCREATESTRUCT lpCS)
{
short i,j;
HWND hwndList = CreateWindow ("LISTBOX","",
WS_CHILD|WS_VISIBLE|
LBS_NOINTEGRALHEIGHT|
LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|
LBS_NOTIFY|WS_VSCROLL|WS_BORDER,
0,0,0,0,hwnd,
IDD_LISTBOX, _hInst, NULL);
if (!IsWindow (hwndList))
{
return FALSE;
}
SendMessage (hwndList, WM_SETFONT, GetStockFont(ANSI_VAR_FONT),0L);
DragAcceptFiles (hwnd, TRUE);
i = (short)((LPMDICREATESTRUCT)lpCS->lpCreateParams)->lParam;
SET_HWNDLIST (hwnd, hwndList); // next three are window words.
SET_WINDOWNUM (hwnd, i);
SET_ISDIRTY (hwnd, FALSE);
SET_EXELOADED (i, FALSE); // rest are in data structure.
SET_AUTOANIMATE (i, FALSE);
SZFILENAME(i)[0] = '\0';
SZEXELINK(i)[0] = '\0';
SET_HWNDANIM(i, hwnd);
SET_INDEX (i, 0);
SET_NUMICONS (i, 0);
SET_TIMEINT (i, 100);
for (j=0; j<(short)MAXICONS ; j++)
{
HICONS(i)[j] = NULL;
}
UPDATE_STATBAR;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// Child_OnSize() - Moves listbox accordingly, and sets column width.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL Child_OnSize (HWND hwnd, UINT wSizeType, short cx, short cy)
{
if (LB_ERR==(WORD)SendMessage(HWNDLIST(hwnd),LB_SETCOLUMNWIDTH,cx-2,0L))
{
MESSAGE (IDS_ListBoxSize);
}
MoveWindow(HWNDLIST(hwnd), 0, 0, cx, cy, TRUE);
DefMDIChildProc(hwnd, WM_SIZE, (WPARAM)wSizeType, MAKELPARAM(cx,cy));
}
//////////////////////////////////////////////////////////////////////////
// Child_OnDropFiles() - Handles the Drag-n-Drop protocol that File
// Manager in Windows 3.1 makes available to us.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL Child_OnDropFiles (HWND hwnd, HDROP hDrop)
{
short sChild = WINDOWNUM (hwnd);
HWND hwndList = HWNDLIST (hwnd);
short sNumDrop = (short)DragQueryFile (hDrop,(WORD)-1,NULL,0);
if (ISANIMATING(sChild))
{
MESSAGE (IDS_NoDropOnWhileAnimate);
return;
}
if (sNumDrop > 0)
{
short i;
short sInsert;
POINT pt;
char szDropFile [MAX_FILE_SIZE];
// get the point of up-click. If up-click over an existing
// listbox entry, insert the files there. Else, append.
DragQueryPoint (hDrop, (LPPOINT)&pt);
sInsert = FigureOutWhereToInsert (hwndList, (LPPOINT)&pt);
for (i=0 ; i<(short)sNumDrop ; i++)
{
DragQueryFile (hDrop, i, (LPSTR)szDropFile, MAX_FILE_SIZE);
if (sInsert < 0)
{
AddIconImage (sChild, hwndList, (LPSTR)szDropFile);
}
else
{
InsertIconImage (sChild, hwndList, sInsert, (LPSTR)szDropFile);
}
SET_ISDIRTY (hwnd, TRUE);
}
}
}
//////////////////////////////////////////////////////////////////////////
// Child_OnSetFocus() - Sets focus to the listbox.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL Child_OnSetFocus (HWND hwnd, HWND hwndPrev)
{
SetFocus(HWNDLIST(hwnd));
}
//////////////////////////////////////////////////////////////////////////
// Child_OnMDIActivate() - Sets up the menu accordingly, and updates
// the status bar, since the new active child may have a totally
// different state.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL Child_OnMDIActivate (HWND hwnd, BOOL bActive,
HWND hwndActive, HWND hwndDeActive)
{
SendMessage(_hwndClient, WM_MDISETMENU, (WPARAM)0,
bActive ? MAKELPARAM(_hmenuChild, _hmenuChildWindow)
: MAKELPARAM(_hmenuMain, _hmenuMainWindow));
DrawMenuBar(_hwndFrame);
UPDATE_STATBAR;
if (bActive)
{
SetFocus (hwnd);
}
DefMDIChildProc(hwnd, WM_MDIACTIVATE, (WPARAM)bActive,
MAKELPARAM(hwndActive,hwndDeActive));
}
//////////////////////////////////////////////////////////////////////////
// Child_OnCommand() - Handles all of the command processing specific
// to an animation.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL Child_OnCommand (HWND hwnd, UINT uMsg,
HWND hChild, UINT uExtra)
{
short sChild = WINDOWNUM(hwnd);
switch (uMsg)
{
case IDM_SETTINGS:
{
if (DialogBox (_hInst, SETTINGSDLG, hwnd, _lpfnSettings))
{
UPDATE_STATBAR;
SET_ISDIRTY (hwnd, TRUE);
if (AUTOANIMATE (sChild))
{
PostMessage (hwnd, WM_COMMAND, IDM_GO, 0L);
}
}
break;
}
case IDM_GO:
{
if (!NUMICONS(sChild))
{
MESSAGE (IDS_NoIcons);
break;
}
if (!TIMEINT(sChild) || !SZEXELINK(sChild)[0])
{
SendMessage (_hwndFrame, WM_COMMAND, IDM_SETTINGS, 0L);
}
if (SZEXELINK(sChild) && TIMEINT(sChild))
{
// Free old icon handles before creating new ones.
//
DeletePreviousHandles (hwnd);
SetupIconHandles (hwnd);
SET_INDEX (sChild, 0);
SET_ISANIMATING (sChild, TRUE);
}
break;
}
case IDM_STOP:
{
SET_ISANIMATING (sChild, FALSE);
if (IsWindow (HWNDTARGET(sChild)))
{
SetClassWord (HWNDTARGET(sChild), GCW_HICON,
HPREVICON(sChild));
InvalidateAll (HWNDTARGET(sChild),HPREVICON(sChild));
}
break ;
}
case IDM_SAVE:
case IDM_SAVEAS:
{
SaveIconsToFile (hwnd, uMsg);
SET_ISDIRTY (hwnd, FALSE);
break;
}
case IDM_ADDICON:
case IDM_INSERTICON:
{
char szAddFile [MAX_FILE_SIZE];
getcwd (szAddFile, MAX_FILE_SIZE);
if (ShowCommonDialog(hwnd,_lpszIconFilter,
(LPSTR)szAddFile, (LPSTR)"Add or Insert Icon...\0",
(LPSTR)"*.ICO", FALSE))
{
HWND hwndList = HWNDLIST (hwnd);
if (!IsWindow (hwndList))
{
break;
}
if (uMsg == IDM_INSERTICON)
{
short sSel = (short)ListBox_GetCurSel (hwndList);
if (sSel == LB_ERR)
{
MESSAGE (IDS_PleaseSelect);
}
else
{
InsertIconImage (sChild, hwndList, sSel,
(LPSTR)szAddFile);
}
}
else
{
AddIconImage (sChild, hwndList, (LPSTR)szAddFile);
}
SET_ISDIRTY (hwnd, TRUE);
}
break;
}
case IDM_DELETEICON:
{
DeleteCurSel (hwnd);
SET_ISDIRTY (hwnd, TRUE);
break;
}
default:
return;
}
UPDATE_STATBAR;
}
//////////////////////////////////////////////////////////////////////////
// Child_OnDestroy() - frees all memory handles used for icons, and
// resets the animStruct for this window to all zeros.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL Child_OnDestroy (HWND hWnd)
{
int i;
short sChild = WINDOWNUM(hWnd);
if (ISANIMATING(sChild))
{
SET_ISANIMATING (sChild, FALSE);
if (IsWindow (HWNDTARGET(sChild)))
{
SetClassWord (HWNDTARGET(sChild), GCW_HICON, HPREVICON(sChild));
InvalidateAll (HWNDTARGET(sChild),HPREVICON(sChild));
}
}
DestroyWindow(HWNDLIST(hWnd));
for (i=0; i<(short)NUMICONS(sChild) ; i++)
{
GlobalFree (HICONS(sChild)[i]);
HICONS(sChild)[i] = NULL; // reset the structure to all nulls
}
_fmemset ((LPANIMSTRUCT)&_animStruct[sChild], 0x00, sizeof(ANIMSTRUCT));
_lPageFlags &= 0xFFFFFFFFL ^ (1 << sChild);
DefMDIChildProc(hWnd, WM_DESTROY, (WPARAM)0, (LPARAM)0L);
}
//////////////////////////////////////////////////////////////////////////
// Child_OnClose() - Checks with QueryEndSession to see if it is ok
// with the user to close, then closes, by calling Destroy.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL
Child_OnClose (HWND hwnd)
{
if (SendMessage(hwnd, WM_QUERYENDSESSION, 0, 0L))
{
MDI_Destroy (_hwndClient, hwnd);
}
}
//////////////////////////////////////////////////////////////////////////
// Asks whether or not to save changes, if changes need to be saved.
// If everything is cool, or the user presses NO, we say its OK to
// close, as FrameProc()'s BroadcastProc() is the one calling this.
// This child also calls it when a WM_CLOSE message comes its way.
//////////////////////////////////////////////////////////////////////////
BOOL NEAR PASCAL Child_OnQueryEndSession (HWND hWnd)
{
char szBigString [192];
char szWindowText [MAX_FILE_SIZE];
char szFmtString [36];
if (ISDIRTY(hWnd))
{
short sChild = WINDOWNUM(hWnd);
UINT uReply;
GetWindowText (hWnd, (LPSTR)szWindowText, MAX_FILE_SIZE);
LoadStr(IDS_QueryEnd, szFmtString);
wsprintf ((LPSTR)szBigString,
(LPSTR)szFmtString,
(LPSTR)szWindowText);
uReply = MessageBox (hWnd, szBigString, _szAppName, MB_YESNOCANCEL);
if (uReply == IDYES)
{
SendMessage (hWnd, WM_COMMAND, (WPARAM)(SZFILENAME(sChild)[0] ?
IDM_SAVE : IDM_SAVEAS), (LPARAM)0L);
return TRUE;
}
else if (uReply == IDCANCEL)
{
return FALSE;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// Child_OnDrawItem() - Does the meat of the drawing for each item
// in the listbox, and calls the HandleFocusState() and HandleSelection()
// functions as necessary.
//////////////////////////////////////////////////////////////////////////
LONG NEAR PASCAL Child_OnDrawItem (HWND hwnd, const DRAWITEMSTRUCT FAR * lp)
{
short sChild = WINDOWNUM(hwnd);
if ((lp->CtlType == ODT_LISTBOX) && (lp->CtlID == IDD_LISTBOX))
{
if (NUMICONS(sChild) == 0)
{
return 0L;
}
if (lp->itemAction & ODA_DRAWENTIRE)
{
DrawIcon (lp->hDC,
(lp->rcItem.right - lp->rcItem.left - ICON_DX)/2,
lp->rcItem.top+(PADDING/2),
HICONS(sChild)[lp->itemID]);
HandleSelectionState(lp);
}
// If a list box item was just selected or unselected,
// call function (which could check if ODS_SELECTED bit is set)
// and draw item in selected or unselected state.
if (lp->itemAction & ODA_SELECT)
{
HandleSelectionState(lp);
}
return 1L;
}
return 0L;
}
//////////////////////////////////////////////////////////////////////////
// Child_OnMeasureItem() - tells Windows how to size the listbox.
//////////////////////////////////////////////////////////////////////////
LONG NEAR PASCAL Child_OnMeasureItem (HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
{
lpmis->itemHeight = GetANSITextHeight()+ICON_DY+PADDING;
return 0L;
}
//////////////////////////////////////////////////////////////////////////
// HandleSelectionState() - Handles the drawing of the listbox with
// current selection, and draws an un-selected one. The item being
// selected and the one being un-selected are dealt with here.
//////////////////////////////////////////////////////////////////////////
VOID NEAR PASCAL HandleSelectionState(const DRAWITEMSTRUCT FAR * lp)
{
BOOL fOn = lp->itemState & ODS_SELECTED;
short sIndent;
short sDownSpace;
UINT oldBkMode;
COLORREF oldTextColor;
DWORD dwExtent;
RECT rc;
HBRUSH hBrush;
CopyRect (&rc, &lp->rcItem);
ListBox_GetText (lp->hwndItem, lp->itemID, (LPSTR)szAllPurpose);
dwExtent = GetTextExtent (lp->hDC, (LPSTR)szAllPurpose,
lstrlen((LPSTR)szAllPurpose));
sIndent = ((short)(rc.right-rc.left-LOWORD(dwExtent)) / 2);
sDownSpace = (short)(rc.bottom-rc.top-HIWORD(dwExtent));
/* Setup formatting rectangle */
rc.left += sIndent;
rc.right -= sIndent;
rc.top += sDownSpace;
/* Use the title bar colors for highlighting, so we
set the text color and bk color to those colors,
draw the text, then reset the colors back to original
values */
oldBkMode = SetBkMode (lp->hDC, TRANSPARENT);
oldTextColor = SetTextColor (lp->hDC,
Color(fOn ? COLOR_CAPTIONTEXT : COLOR_WINDOWTEXT));
hBrush = CreateSolidBrush(Color (fOn ? COLOR_ACTIVECAPTION :
COLOR_WINDOW));
FillRect (lp->hDC, &rc, hBrush);
DeleteBrush (hBrush);
ExtTextOut (lp->hDC, rc.left, rc.top,
ETO_CLIPPED,
(LPRECT)&rc,
(LPSTR)szAllPurpose,
lstrlen ((LPSTR)szAllPurpose),
NULL);
SetBkMode (lp->hDC, oldBkMode);
SetTextColor (lp->hDC, oldTextColor);
}
//////////////////////////////////////////////////////////////////////////
// FigureOutWhereToInsert() - Given the listbox and a point somewhere
// in the listbox when the user up-clicked the LBUTTON, we find out
// where, then return an index if they up-clicked over an item. If not,
// we return telling them to append to end of list.
//////////////////////////////////////////////////////////////////////////
short NEAR PASCAL FigureOutWhereToInsert (HWND hwndList, LPPOINT lppt)
{
short sCount = (short)ListBox_GetCount (hwndList);
short i;
RECT rc;
for (i=0 ; i<sCount ; i++)
{
ListBox_GetItemRect (hwndList, i, (LPRECT)&rc);
if (!PtInRect ((LPRECT)&rc, *lppt)) continue;
return i;
}
return (short)(-1);
}
//////////////////////////////////////////////////////////////////////////
// InsertIconImage() - inserts an icon into a specific position in the
// list.
//////////////////////////////////////////////////////////////////////////
BOOL NEAR PASCAL InsertIconImage (short sChild, HWND hwndList,
short sInsert, LPSTR lpszFile)
{
short sNumIcons = NUMICONS (sChild);
HICON hNewIcon;
short i;
if (sNumIcons >= MAXICONS)
{
MESSAGE (IDS_TooManyIcons);
return FALSE;
}
hNewIcon = ExtractIcon (_hInst, lpszFile, 0);
if (hNewIcon == NULL) return FALSE;
if (sNumIcons == 0)
{
HICONS(sChild)[sNumIcons] = hNewIcon;
}
else
{
for (i=sNumIcons ; i>=0 ; i--)
{
HICONS(sChild)[i] = HICONS(sChild)[i-1];
if ( (i-1) == sInsert)
{
HICONS(sChild)[i-1] = hNewIcon;
break;
}
}
}
sNumIcons++;
SET_NUMICONS (sChild, sNumIcons);
if (LB_ERR == ListBox_InsertString(hwndList,sInsert,lpszFile))
{
MESSAGE(IDS_AddFileError);
return FALSE;
}
ListBox_SetCurSel (hwndList, sInsert);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// AddIconImage() - Adds an icon to the end of the list.
//////////////////////////////////////////////////////////////////////////
BOOL NEAR PASCAL AddIconImage (short sChild, HWND hwndList,
LPSTR lpszFile)
{
HICON hNewIcon;
short sNumIcons = NUMICONS(sChild);
if (sNumIcons >= MAXICONS)
{
MESSAGE (IDS_TooManyIcons);
return FALSE;
}
hNewIcon = ExtractIcon (_hInst, lpszFile, 0);
if (hNewIcon == NULL) return FALSE;
HICONS(sChild)[sNumIcons] = hNewIcon;
sNumIcons++;
SET_NUMICONS (sChild, sNumIcons);
if (LB_ERR == ListBox_AddString(hwndList,lpszFile))
{
MESSAGE(IDS_AddFileError);
return FALSE;
}
ListBox_SetCurSel (hwndList, ListBox_GetCount(hwndList)-1);
return TRUE;
}