|
|
1.1 root 1: /****************************************************************************\
2: *
3: * MODULE: anicmd.c
4: *
5: * PURPOSE: Processes WM_COMMANDs for the Animated Cursor Editor
6: *
7: * Copyright 1993, Microsoft Corp.
8: *
9: *
10: * History:
11: * 21-Apr-1993 JonPa Wrote it.
12: *
13: \****************************************************************************/
14:
15: #include <windows.h>
16: #include <commdlg.h>
17: #include <search.h>
18: #include "anidefs.h"
19:
20: static DWORD WINAPI ProcWaitThread( LPVOID lpv );
21: static BOOL CALLBACK ETWProc( HWND hwnd, LPARAM lParam );
22:
23: BOOL gfEditFrame = FALSE;
24: TCHAR gszTempFile[MAX_PATH];
25:
26: /****************************************************************************\
27: *
28: * FUNCTION: DoCommand(HWND, unsigned, WORD, LONG)
29: *
30: * PURPOSE: Processes commands for the main dialog box
31: *
32: * MESSAGES:
33: *
34: * WM_INITDIALOG - initialize dialog box
35: * WM_COMMAND - Input received
36: *
37: * COMMENTS:
38: *
39: *
40: * History:
41: * 21-Apr-1993 JonPa Created it
42: *
43: \****************************************************************************/
44: BOOL DoCommand( HWND hWnd, UINT wParam, LONG lParam )
45: {
46: int cmd = LOWORD(wParam);
47:
48: switch(cmd){
49:
50:
51: case MENU_FILE_NEW:
52: case DLG_MAIN_BTNNEW:
53: /* If dirty, then prompt for save */
54: if(!CheckDirty(hWnd))
55: break;
56:
57: /* free used memory and init structures and dlg */
58: NewAniCursor(hWnd);
59: ResumePreview(hWnd, DLG_MAIN_PREVIEW);
60: break;
61:
62: case DLG_MAIN_BTNOPEN:
63: case MENU_FILE_OPEN: {
64: HANDLE hfCursor;
65: TCHAR szFileTitle[MAX_PATH];
66: TCHAR szFile[MAX_PATH];
67:
68:
69: szFile[0] = TEXT('\0');
70:
71: /* check for dirty file */
72: if(!CheckDirty(hWnd))
73: break;
74:
75: /* Put up the open file dialog and get the open handle back */
76: hfCursor = PromptAndOpenFile(hWnd, MAX_PATH, szFileTitle,
77: COUNTOF(ganiAcon.szFile), szFile, gpszAniFilter);
78:
79: if (hfCursor == INVALID_HANDLE_VALUE)
80: break;
81:
82: /* delete any existing ani file */
83: NewAniCursor( hWnd );
84:
85: /* read in the file */
86: if (!ReadAniFile( hWnd, hfCursor )) {
87: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP, TRUE,
88: MSG_INVALIDCURSORFILE, szFileTitle );
89: } else {
90: /*
91: * Put the filename in the title.
92: */
93: lstrcpy(ganiAcon.szFile, szFile);
94: SetWindowFileTitle(hWnd, szFileTitle);
95: SetDlgItemInt( hWnd, DLG_MAIN_RATE, ganiAcon.anih.jifRate, FALSE);
96: }
97:
98: ResumePreview(hWnd, DLG_MAIN_PREVIEW);
99: break;
100: }
101:
102: case DLG_MAIN_BTNSAVE:
103: case MENU_FILE_SAVE:
104: case MENU_FILE_SAVEAS:
105: SaveFile(hWnd, cmd == MENU_FILE_SAVEAS);
106: break;
107:
108: case MENU_FILE_INSERT: {
109: TCHAR szFile[MAX_PATH];
110:
111: szFile[0] = TEXT('\0');
112:
113: /* Put up the open file dialog and get the open handle back */
114: if (PromptForFile(hWnd, 0, NULL,
115: MAX_PATH, szFile, gpszCurFilter, gpszImport, FALSE)) {
116:
117: /*
118: * If we got a file, open it and read the icon data, linking
119: * it into the frame list and maintaining the steps as well.
120: */
121: ganiAcon.fDirty = TRUE;
122: CreateFrameFromCursorFile(hWnd, szFile, FALSE);
123: }
124: break;
125: }
126:
127: case MENU_FILE_EXPORT: {
128: #if 0
129: TCHAR szFile[MAX_PATH];
130: szFile[0] = TEXT('\0');
131:
132: /* Put up the open file dialog and get the open handle back */
133: if (PromptForFile(hWnd, 0, NULL,
134: MAX_PATH, szFile, NULL, gpszExport, TRUE)) {
135:
136: /*
137: * If we got a file, open it and read the icon data, linking
138: * it into the frame list and maintaining the steps as well.
139: */
140: ????
141: }
142: #else
143: WRITEME(hWnd);
144: #endif
145: break;
146: }
147:
148: case MENU_FILE_EXIT:
149: ExitCommand(hWnd);
150: break;
151:
152: case DLG_MAIN_BTNCUT:
153: case MENU_EDIT_CUT:
154: ganiAcon.fDirty = TRUE;
155:
156: FALLTHRU(MENU_EDIT_COPY);
157:
158: case DLG_MAIN_BTNCOPY:
159: case MENU_EDIT_COPY: {
160: int *piSel;
161: int cSel;
162:
163: cSel = GetSelStepCount(hWnd);
164:
165: if( cSel > 0 && (piSel = AllocMem(cSel * sizeof(int))) != NULL) {
166: PCLPBRDDAT pcbd, pcbdNext, *ppcbd;
167:
168: int i;
169:
170: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, piSel, cSel, &cSel);
171:
172: /* Clear clipboard */
173: for( pcbd = gpbdClipBoard; pcbd != NULL; pcbd = pcbdNext ) {
174: pcbdNext = pcbd->pcbdNext;
175:
176: DestroyClpBrdDat(pcbd);
177: }
178:
179: /*
180: * Get the steps and put them in the clipboard in the correct order
181: */
182: ppcbd = &gpbdClipBoard;
183:
184: for( i = 0; i < cSel; i++ ) {
185: PSTEP ps;
186:
187: ps = GetStep(hWnd, piSel[i]);
188:
189: if( IsValidPS(ps) && (pcbd = NewClpBrdDat()) != NULL) {
190: CopyStep(&(pcbd->stp), ps);
191: *ppcbd = pcbd;
192: ppcbd = &(pcbd->pcbdNext);
193: }
194: }
195:
196: *ppcbd = NULL;
197:
198: /*
199: * If this is a cut, then yank them out of the listbox
200: */
201: if (cmd == MENU_EDIT_CUT || cmd == DLG_MAIN_BTNCUT) {
202: qsort( piSel, cSel, sizeof(piSel[0]), RevCompInts );
203: for( i = 0; i < cSel; i++ ) {
204: SendDlgItemMessage(hWnd, DLG_MAIN_FRAMELIST,
205: LB_DELETESTRING, piSel[i], 0);
206: }
207:
208: FreeMem(piSel);
209:
210: ClearStepSel(hWnd);
211: }
212: }
213:
214: break;
215: }
216:
217: case DLG_MAIN_BTNPASTE:
218: case MENU_EDIT_PASTE: {
219: PCLPBRDDAT pcbd;
220: int iSel, cSel;
221:
222: cSel = GetSelStepCount(hWnd);
223:
224: if (cSel > 1) {
225: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
226: TRUE, MSG_LESSEQONEFRAME);
227: break;
228: }
229:
230: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, &iSel, 1, &cSel);
231:
232: if (cSel == 0)
233: iSel = GetStepCount(hWnd) - 1;
234:
235: cSel = iSel;
236: ganiAcon.fDirty = TRUE;
237:
238: for( pcbd = gpbdClipBoard; pcbd != NULL; pcbd = pcbd->pcbdNext ) {
239: PSTEP ps = NewStep();
240:
241: if (IsValidPS(ps)) {
242: CopyStep(ps, &(pcbd->stp));
243:
244: SendDlgItemMessage(hWnd, DLG_MAIN_FRAMELIST, LB_INSERTSTRING,
245: ++cSel, (LPARAM)ps);
246: } else {
247: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OKCANCEL |
248: MB_ICONEXCLAMATION, TRUE, MSG_PASTEERR );
249: }
250: }
251:
252: /* in this case, cSel is actually an index */
253: iSel += 1;
254: ClearStepSel(hWnd);
255: SetStepSel(hWnd, iSel, cSel);
256:
257: break;
258: }
259:
260: case DLG_MAIN_DELFRAME:
261: case MENU_EDIT_CLEAR: {
262: int *piSel;
263: int cSteps = GetSelStepCount(hWnd);
264: int i;
265:
266: if (cSteps <= 0)
267: //BUGBUG - should we put a message box up here?
268: break;
269:
270: ganiAcon.fDirty = TRUE;
271:
272: piSel = AllocMem(cSteps * sizeof(int));
273: if (piSel == NULL)
274: break;
275:
276: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, piSel, cSteps, &cSteps);
277:
278: qsort( piSel, cSteps, sizeof(piSel[0]), RevCompInts );
279: for( i = 0; i < cSteps; i++ ) {
280: SendDlgItemMessage(hWnd, DLG_MAIN_FRAMELIST, LB_DELETESTRING,
281: piSel[i], 0);
282: }
283:
284: FreeMem(piSel);
285: ClearStepSel(hWnd);
286:
287: break;
288: }
289:
290: case DLG_MAIN_DUPFRAME:
291: case MENU_EDIT_DUP:
292: /* copy */
293: /* paste */
294: ganiAcon.fDirty = TRUE;
295: WRITEME(hWnd);
296: break;
297:
298: case DLG_MAIN_EDITFRAME:
299: case MENU_EDIT_EDITFRAME:
300: case DLG_MAIN_ADDFRAME:
301: case MENU_EDIT_ADDFRAME: {
302: BOOL fEditFrame;
303:
304: ganiAcon.fDirty = TRUE;
305:
306: fEditFrame = (cmd == MENU_EDIT_EDITFRAME ||
307: cmd == DLG_MAIN_EDITFRAME);
308:
309:
310: EditFrame(hWnd, fEditFrame);
311:
312: break;
313: }
314:
315: case DLG_MAIN_STOP:
316: PausePreview(hWnd, DLG_MAIN_PREVIEW);
317: break;
318:
319: case DLG_MAIN_PLAY:
320: ResumePreview(hWnd, DLG_MAIN_PREVIEW);
321: break;
322:
323: case MENU_HELP_ABOUT:
324: DialogBox(hInst, MAKEINTRESOURCE(DLG_ABOUT), hWnd, About);
325: break;
326:
327: case MENU_EDIT_OPTIONS:
328: if (DialogBox(hInst, MAKEINTRESOURCE(DLG_OPTIONS), hWnd, OptionsProc)){
329: InvalidateRect( GetDlgItem(hWnd, DLG_MAIN_PREVIEW), NULL, TRUE);
330: }
331: break;
332:
333: case DLG_MAIN_FRAMELIST: {
334: HWND hwndLB = (HWND)lParam;
335:
336: switch(HIWORD(wParam)) {
337:
338: case LBN_SELCHANGE: {
339: PSTEP ps;
340: int cSel;
341: LPTSTR pszText;
342:
343: cSel = SendMessage(hwndLB, LB_GETSELCOUNT, 0, 0);
344:
345: if (cSel > 1) {
346: int *piSel;
347: int i;
348:
349: pszText = FmtSprintf( cSel == GetStepCount(hWnd) ?
350: MSG_ALLFRAMES : MSG_FRAMESSELECTED, cSel );
351: SetDlgItemText(hWnd, DLG_MAIN_FRAMEGRP, pszText);
352: FmtFree( pszText );
353:
354: piSel = AllocMem( cSel * sizeof(int) );
355: if( piSel == NULL )
356: break;
357:
358: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, piSel, cSel, &cSel);
359: for( i = 0; i < cSel; i++ ) {
360: ps = GetStep(hWnd, piSel[i]);
361:
362: if( IsValidPS(ps) ) {
363: if (i == 0) {
364: ganiAcon.anih.jifRate = ps->jif;
365: } else if(ganiAcon.anih.jifRate != ps->jif) {
366: break;
367: }
368: }
369: }
370:
371: if (i < cSel) {
372: /* rates differ, wipe out jiffy edit control */
373: SetDlgItemText(hWnd, DLG_MAIN_RATE, "");
374: } else {
375: SetDlgItemInt(hWnd, DLG_MAIN_RATE,
376: ganiAcon.anih.jifRate, FALSE);
377: }
378:
379: FreeMem(piSel);
380:
381: } else if (cSel == 1) {
382: int iLBSel;
383:
384: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, &iLBSel, 1, &cSel);
385:
386: SetPreviewStep(hWnd, DLG_MAIN_PREVIEW, iLBSel);
387:
388: pszText = FmtSprintf( MSG_FRAMEOFSEL, iLBSel + 1,
389: GetStepCount(hWnd) );
390: SetDlgItemText(hWnd, DLG_MAIN_FRAMEGRP, pszText);
391: FmtFree( pszText );
392:
393: ps = (PSTEP)SendMessage(hwndLB, LB_GETITEMDATA, iLBSel, 0);
394:
395: if (IsValidPS(ps)) {
396: SetDlgItemInt( hWnd, DLG_MAIN_RATE, ps->jif, FALSE);
397: }
398: } else {
399: pszText = FmtSprintf( MSG_NOFRAMESSEL );
400: SetDlgItemText(hWnd, DLG_MAIN_FRAMEGRP, pszText);
401: FmtFree( pszText );
402: SetPreviewStep(hWnd, DLG_MAIN_PREVIEW, 0);
403: }
404: break;
405:
406: case LBN_DBLCLK:
407: ganiAcon.fDirty = TRUE;
408: EditFrame(hWnd, TRUE);
409: break;
410: }
411: }
412: break;
413:
414: }
415:
416: case DLG_MAIN_RATE: {
417: static BOOL fEditCtlHasFocus = FALSE;
418: static BOOL fEditCtlHasChanged = FALSE;
419: int *piSel;
420: int cSteps;
421: int i;
422:
423: switch(HIWORD(wParam)) {
424: case EN_SETFOCUS:
425: fEditCtlHasFocus = TRUE;
426: break;
427:
428: case EN_KILLFOCUS:
429: fEditCtlHasFocus = FALSE;
430: break;
431:
432: case EN_CHANGE:
433:
434: cSteps = GetSelStepCount(hWnd);
435:
436: if (fEditCtlHasFocus && cSteps >=1 &&
437: GetWindowTextLength(GetDlgItem(hWnd, DLG_MAIN_RATE)) > 0) {
438: JIF jif;
439: BOOL fOK;
440:
441: ganiAcon.fDirty = TRUE;
442: piSel = AllocMem( cSteps * sizeof(int) );
443: if (piSel == NULL) {
444: SetFocus((HWND)lParam);
445: break;
446: }
447:
448:
449: jif = GetDlgItemInt(hWnd, DLG_MAIN_RATE, &fOK, FALSE);
450:
451: if (jif == 0 || !fOK) {
452: FmtMessageBox(hWnd, MSG_LITERAL, gszWindowTitle,
453: MB_OK | MB_ICONEXCLAMATION, TRUE,
454: MSG_RATERANGE);
455: SetFocus((HWND)lParam);
456: break;
457: }
458:
459: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, piSel, cSteps,
460: &cSteps);
461:
462: for( i = 0; i < cSteps; i++ ) {
463: PSTEP ps = GetStep(hWnd, piSel[i]);
464:
465: if (IsValidPS(ps)) {
466: ps->jif = jif;
467: }
468: }
469: InvalidateRect(GetDlgItem(hWnd,DLG_MAIN_FRAMELIST), NULL,TRUE);
470:
471: FreeMem( piSel );
472: }
473: break;
474: }
475: break;
476: }
477:
478: default:
479: return FALSE;
480: }
481:
482: return TRUE;
483: }
484:
485: /****************************************************************************\
486: *
487: * FUNCTION: About(HWND, unsigned, WORD, LONG)
488: *
489: * PURPOSE: Processes messages for "About" dialog box
490: *
491: * MESSAGES:
492: *
493: * WM_INITDIALOG - initialize dialog box
494: * WM_COMMAND - Input received
495: *
496: * COMMENTS:
497: *
498: * No initialization is needed for this particular dialog box, but TRUE
499: * must be returned to Windows.
500: *
501: * Wait for user to click on "Ok" button, then close the dialog box.
502: *
503: \****************************************************************************/
504:
505: BOOL APIENTRY About(
506: HWND hDlg, /* window handle of the dialog box */
507: UINT message, /* type of message */
508: UINT wParam, /* message-specific information */
509: LONG lParam)
510: {
511: switch (message) {
512: case WM_INITDIALOG: /* message: initialize dialog box */
513: return (TRUE);
514:
515: case WM_COMMAND: /* message: received a command */
516: if (LOWORD(wParam) == IDOK /* "OK" box selected? */
517: || LOWORD(wParam) == IDCANCEL) { /*System menu close command?*/
518: EndDialog(hDlg, TRUE); /* Exits the dialog box */
519: return (TRUE);
520: }
521: break;
522: }
523: return (FALSE); /* Didn't process a message */
524: UNREFERENCED_PARAMETER(lParam);
525: }
526:
527:
528: /****************************************************************************\
529: *
530: * FUNCTION: OptionsProc(HWND, unsigned, WORD, LONG)
531: *
532: * PURPOSE: Processes messages for "Options" dialog box
533: *
534: * MESSAGES:
535: *
536: * WM_INITDIALOG - initialize dialog box
537: * WM_COMMAND - Input received
538: *
539: \****************************************************************************/
540:
541: BOOL APIENTRY OptionsProc(
542: HWND hDlg, /* window handle of the dialog box */
543: UINT message, /* type of message */
544: UINT wParam, /* message-specific information */
545: LONG lParam)
546: {
547: int i;
548: int fRepaint = FALSE;
549:
550: switch (message) {
551: case WM_INITDIALOG: /* message: initialize dialog box */
552: SendDlgItemMessage(hDlg, DLG_OPTIONS_EDITOR, EM_LIMITTEXT, MAX_PATH, 0);
553: SetDlgItemText(hDlg, DLG_OPTIONS_EDITOR, gszCursorEditor);
554: CheckRadioButton( hDlg,
555: DLG_OPTIONS_RADIO_DESKCOL,
556: DLG_OPTIONS_RADIO_WINCOL,
557: garadColor[giradColor].id );
558: return (TRUE);
559:
560: case WM_COMMAND: /* message: received a command */
561: switch(LOWORD(wParam)) {
562: case IDOK:
563:
564: /*
565: * Get the new desk color
566: */
567: for( i = 0; garadColor[i].id != 0; i++ ) {
568: if( IsDlgButtonChecked(hDlg, garadColor[i].id) ) {
569: break;
570: }
571: }
572:
573: if (i != giradColor ) {
574: /* new color, make new brush and repaint */
575: if (ghbrPrevBackgnd != NULL)
576: DeleteObject(ghbrPrevBackgnd);
577:
578: ghbrPrevBackgnd =
579: CreateSolidBrush(GetSysColor(garadColor[i].idSys));
580: giradColor = i;
581: fRepaint = TRUE;
582: }
583:
584: /*
585: * Get new editor
586: */
587: GetDlgItemText(hDlg,DLG_OPTIONS_EDITOR,
588: gszCursorEditor,COUNTOF(gszCursorEditor));
589:
590: for( i = 0; i < COUNTOF(gszCursorEditor); i++ ) {
591:
592: if (gszCursorEditor[i] == TEXT('\0'))
593: break;
594:
595: if (gszCursorEditor[i] == TEXT('%') &&
596: ++i < COUNTOF(gszCursorEditor) &&
597: gszCursorEditor[i] == TEXT('1')) {
598: break;
599: }
600: }
601:
602:
603: if (i >= COUNTOF(gszCursorEditor) ||
604: gszCursorEditor[i] != TEXT('1')) {
605:
606: if (i >= (COUNTOF(gszCursorEditor) - 4)) {
607: i = COUNTOF(gszCursorEditor) - 4;
608: }
609:
610: lstrcpy(&gszCursorEditor[i], TEXT(" %1"));
611: }
612:
613: case IDCANCEL:
614: EndDialog(hDlg, fRepaint); /* Exits the dialog box */
615: return (TRUE);
616:
617: default:
618: break;
619: }
620: break;
621: }
622: return (FALSE); /* Didn't process a message */
623: UNREFERENCED_PARAMETER(lParam);
624: }
625:
626:
627: /****************************************************************************\
628: *
629: * FUNCTION: ExitCommand(HWND)
630: *
631: * PURPOSE: Exit the program chekcing for dirty files etc.
632: *
633: *
634: \****************************************************************************/
635: VOID ExitCommand(HWND hWnd) {
636:
637: /* if file is dirty then prompt for save */
638: if(CheckDirty(hWnd))
639: EndDialog(hWnd, TRUE);
640: }
641:
642: /****************************************************************************\
643: *
644: * FUNCTION: CheckDirty(HWND)
645: *
646: * PURPOSE: check for dirty files and return TRUE if it is OK to continue.
647: *
648: *
649: \****************************************************************************/
650: BOOL CheckDirty(HWND hWnd) {
651: int idRet;
652:
653: /* if file is dirty then prompt for save */
654: if (ganiAcon.fDirty) {
655: idRet = FmtMessageBox( hWnd, MSG_LITERAL, gszWindowTitle,
656: MB_YESNOCANCEL | MB_ICONEXCLAMATION, TRUE, MSG_SAVEFILEQUEST,
657: ganiAcon.szFile);
658:
659: switch( idRet ) {
660: case IDYES:
661: SaveFile(hWnd, FALSE);
662: break;
663:
664: case IDNO:
665: break;
666:
667: case IDCANCEL:
668: return FALSE;
669: }
670: }
671:
672: return TRUE;
673: }
674:
675:
676: /****************************************************************************\
677: *
678: * FUNCTION: HWND ExecProgram( HWND hwndCaller, LPTSTR pszCmdLine )
679: *
680: * PURPOSE: Creates a process and returns the new processes main window
681: *
682: * RETURNS: NULL if the process could not be created, otherwise the
683: * processes main window handle.
684: *
685: * SIDEEFFECT: This function will also start a thread that will block
686: * on the process handle until the process terminates. At that
687: * time, the thread will post a message back to the calliers
688: * window.
689: *
690: *
691: * History:
692: * 22-Apr-1993 JonPa Created it
693: *
694: \****************************************************************************/
695: BOOL ExecProgram( HWND hwndCaller, LPTSTR pszCmdLine ) {
696: STARTUPINFO si;
697: PROCESS_INFORMATION pi;
698: HWND hwnd;
699: PTHDDATA pthd;
700: DWORD tid;
701: HANDLE hthrd;
702:
703: /*
704: * Create the monitor thread (suspened)
705: */
706: pthd = AllocMem(sizeof(THDDATA));
707:
708: if (pthd == NULL)
709: return FALSE;
710:
711: /* set thread data to be invalid incase we have to abort */
712: pthd->hprocMonitor = NULL;
713: pthd->hwndCaller = hwndCaller;
714:
715: if ((hthrd = CreateThread( NULL, 0, ProcWaitThread, pthd, CREATE_SUSPENDED,
716: &tid )) == NULL) {
717: /* could not create the monitor thread, return error */
718: FreeMem(pthd);
719: return FALSE;
720: }
721:
722: /*
723: * Create the process
724: */
725: ZeroMemory( &si, sizeof(si) );
726: si.cb = sizeof(si);
727: si.wShowWindow = SW_SHOW;
728: si.dwFlags = STARTF_USESHOWWINDOW;
729:
730: if (!CreateProcess( NULL, pszCmdLine, NULL, NULL, FALSE, 0, NULL, NULL,
731: &si, &pi)) {
732: ResumeThread(hthrd); // make thread localfree the data and exit
733: return FALSE;
734: }
735:
736: DPRINT(("MT:Child IDs proc/thd: 0x%lx / 0x%lx\n", pi.dwProcessId, pi.dwThreadId));
737: DPRINT(("MT:Child Hnd proc/thd: 0x%lx / 0x%lx\n", pi.hProcess, pi.hThread));
738:
739: /*
740: * Wait for the main window to be created
741: */
742: if( WaitForInputIdle( pi.hProcess, CMS_WAIT_FOR_PROCESS ) != 0 ) {
743: ResumeThread(hthrd); // make thread localfree the data and exit
744: return FALSE;
745: }
746:
747: DPRINT(("MT:Child is idle\n"));
748:
749: /*
750: * Enumerate the new processes main thread's windows and
751: * return the main one.
752: */
753: hwnd = NULL;
754: EnumThreadWindows( pi.dwThreadId, ETWProc, (LPARAM)&hwnd );
755:
756: #if 0
757: if (hwnd != NULL) {
758: pthd->hprocMonitor = pi.hProcess;
759: pthd->hwndMonitor = hwnd;
760:
761: SendMessage(hwndCaller, AIM_SETCHILDAPP, 0, hwnd);
762: }
763: #else
764: pthd->hprocMonitor = pi.hProcess;
765: pthd->hwndMonitor = hwnd;
766:
767: if (pthd->hprocMonitor != NULL)
768: SendMessage(hwndCaller, AIM_SETCHILDAPP, 0, hwnd);
769: #endif
770:
771: ResumeThread(hthrd);
772: CloseHandle(hthrd);
773: CloseHandle(pi.hThread);
774: return TRUE;
775: }
776:
777:
778: /****************************************************************************\
779: *
780: * FUNCTION: BOOL CALLBACK ETWProc( HWND hwnd, LPARAM lParam )
781: *
782: * PURPOSE: Enumeration proc for ExecProgram. It looks for the thread's
783: * top level window.
784: *
785: * History:
786: * 22-Apr-1993 JonPa Created it
787: *
788: \****************************************************************************/
789: BOOL CALLBACK ETWProc( HWND hwnd, LPARAM lParam ) {
790: DWORD *pdw = (DWORD *)lParam;
791:
792: /*
793: * If this window has no parent, then it is a toplevel
794: * window for the thread. Remember the last one we find since it
795: * is probably the main window.
796: */
797:
798: if (GetParent(hwnd) == NULL) {
799: DPRINT(("MT:EnumThdWin found 0x%lx\n", (DWORD)hwnd));
800: *pdw = (DWORD)hwnd;
801: }
802:
803: return TRUE;
804: }
805:
806: /****************************************************************************\
807: *
808: * FUNCTION: DWORD ProcWaitThread( LPDWORD lpdw )
809: *
810: * PURPOSE: Thread to wait on a process and then post a message
811: *
812: *
813: * History:
814: * 22-Apr-1993 JonPa Created it
815: *
816: \****************************************************************************/
817: DWORD WINAPI ProcWaitThread( LPVOID lpv ) {
818: LPDWORD lpdw = lpv;
819: PTHDDATA pthd = (PTHDDATA)lpdw;
820: DWORD dwRet;
821:
822: if (pthd->hprocMonitor == NULL) {
823: /* something went wrong, just exit now */
824: DPRINT(("wt:Aborting\n"));
825: FreeMem( lpdw );
826: ExitThread(0);
827: }
828:
829: DPRINT(("wt:Waiting\n"));
830: dwRet = WaitForSingleObject( pthd->hprocMonitor, INFINITE );
831:
832: DPRINT(("wt:Send AIM_PROCESSTERM\n"));
833: SendMessage(pthd->hwndCaller, AIM_PROCESSTERM, (dwRet == WAIT_OBJECT_0),
834: (LPARAM)pthd->hwndMonitor);
835:
836: CloseHandle( pthd->hprocMonitor );
837: FreeMem( lpdw );
838: ExitThread(0);
839:
840: return 0;
841: }
842:
843:
844: /****************************************************************************\
845: *
846: * FUNCTION: void NewAniCursor( HWND hwnd )
847: *
848: * PURPOSE: erase any used memory and init to a clean slate
849: *
850: *
851: * History:
852: * 22-Apr-1993 JonPa Created it
853: *
854: \****************************************************************************/
855: void NewAniCursor( HWND hwnd ) {
856: int i, cSteps;
857: LPTSTR psz;
858:
859: PausePreview(hwnd, DLG_MAIN_PREVIEW);
860:
861: /* Step through the list box, deleting all the lb entryies and everything
862: * that they point to (except the icons).
863: */
864: cSteps = GetStepCount(hwnd);
865:
866: if (cSteps != LB_ERR) {
867: for( i = 0; i < cSteps; i++ ) {
868: /*
869: * Delete the top item of the list. Note that once that item
870: * (current index 0) is deleted, then the next item will move
871: * up and become index 0.
872: */
873: SendDlgItemMessage( hwnd, DLG_MAIN_FRAMELIST, LB_DELETESTRING,0,0);
874: }
875: }
876:
877:
878: /*
879: * Step through the icon list deleting them. We don't need to call
880: * DestroyFrame since we are trashing the whole chain.
881: */
882:
883: #if 0
884: pf = gpfrmFrames;
885: gpfrmFrames = NULL;
886:
887: DON'T DO THIS!!! it will wipe out the clip board accidentally!
888:
889: for(; pf != NULL; pf = pfrmNext ) {
890: pfrmNext = pf->pfrmNext;
891:
892: DestroyIcon( pf->hcur );
893: FreeMem(pf);
894: }
895: #endif
896:
897: /*
898: * Init Ani header
899: */
900: ZeroMemory( &ganiAcon, sizeof(ganiAcon) );
901: ganiAcon.anih.cbSizeof = sizeof(ganiAcon);
902: ganiAcon.anih.cbSizeof = AF_ICON;
903: ganiAcon.anih.jifRate = 10;
904:
905: SetDlgItemTextA(hwnd, DLG_MAIN_TITLE, ganiAcon.azTitle);
906: SetDlgItemTextA(hwnd, DLG_MAIN_AUTHOR, ganiAcon.azCreator);
907:
908: SetDlgItemInt( hwnd, DLG_MAIN_RATE, ganiAcon.anih.jifRate, FALSE);
909:
910: PreviewCursor(hwnd, DLG_MAIN_PREVIEW);
911:
912: SetWindowFileTitle(hwnd, gpszUntitled );
913:
914: psz = FmtSprintf(MSG_NOFRAMESSEL);
915: SetDlgItemText(hwnd, DLG_MAIN_FRAMEGRP, psz);
916: FmtFree( psz );
917: }
918:
919: /****************************************************************************\
920: *
921: * FUNCTION: BOOL GetCurrentSel( HWND hwnd, int id, int * paiSel,
922: * int ciSel, int *pcSel );
923: *
924: * PURPOSE: Gets the selections and returns it's index
925: *
926: *
927: * History:
928: * 22-Apr-1993 JonPa Created it
929: *
930: \****************************************************************************/
931: BOOL GetCurrentSel( HWND hwnd, int id, int * paiSel, int ciSel, int *pcSel ) {
932:
933: #ifdef MULTISEL
934: *pcSel = SendDlgItemMessage(hwnd,id, LB_GETSELITEMS, ciSel,(LPARAM)paiSel);
935:
936: if (*pcSel == LB_ERR) {
937: *pcSel = 0;
938: }
939: #else
940:
941: *paiSel = SendDlgItemMessage(hwnd, id, LB_GETCURSEL, 0, 0);
942: *pcSel = 1;
943:
944: if (*paiSel == LB_ERR)
945: *pcSel = 0;
946: #endif
947:
948: return TRUE;
949: }
950:
951: /****************************************************************************\
952: *
953: * FUNCTION: VOID SetCurrentSel( HWND hwnd, int id, BOOL fExtend, int iSel);
954: *
955: * PURPOSE: Sets the selections and returns it's index
956: *
957: *
958: * History:
959: * 29-Apr-1993 JonPa Created it
960: *
961: \****************************************************************************/
962: VOID SetCurrentSel( HWND hwnd, int id, BOOL fExtend, int iSel) {
963: #ifdef MULTISEL
964: if (!fExtend) {
965: SendDlgItemMessage(hwnd, id, LB_SETSEL, FALSE, -1);
966: }
967:
968: SendDlgItemMessage(hwnd, id, LB_SETSEL, TRUE, iSel);
969: #else
970: SendDlgItemMessage(hwnd, id, LB_SETCURSEL, iSel, 0);
971: #endif
972:
973: UpdateStepSel( hwnd );
974: }
975:
976:
977: /****************************************************************************\
978: *
979: * FUNCTION: VOID EditFrame(HWND hwnd, int iSel);
980: *
981: * PURPOSE: Runs ImagEdit on the frame indexed by iSel
982: *
983: *
984: * History:
985: * 27-Apr-1993 JonPa
986: *
987: \****************************************************************************/
988: VOID EditFrame(HWND hWnd, BOOL fEditFrame) {
989: LPTSTR pszCmdLine = NULL;
990: int cchCmdLine;
991: HANDLE hf;
992: DWORD cb;
993: PBYTE pbIcon;
994: DWORD cbIcon;
995: int iSel;
996: int cSel;
997: BOOL fExeced;
998:
999: /* create a temp .cur file name */
1000: if( !GetTempCursorFileName( gszTempFile ) ) {
1001: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
1002: TRUE, MSG_OUTOFRESOUCES );
1003: return;
1004: }
1005:
1006:
1007: cSel = GetSelStepCount(hWnd);
1008:
1009: if ( (fEditFrame && (cSel != 1)) || cSel > 1 ) {
1010:
1011: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
1012: TRUE, fEditFrame ? MSG_MUSTEQONEFAME : MSG_LESSEQONEFRAME);
1013: return;
1014: }
1015:
1016: /* cache the currently selected item (Singluar) */
1017: GetCurrentSel( hWnd, DLG_MAIN_FRAMELIST, &iSel, 1, &cSel );
1018:
1019: /*
1020: * If edit, then write the frame to the file and save checksum
1021: * otherwise write the blank cursor to the file.
1022: */
1023:
1024: hf = CreateFile( gszTempFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1025: FILE_ATTRIBUTE_NORMAL, NULL );
1026:
1027:
1028: if (hf == INVALID_HANDLE_VALUE) {
1029: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP, TRUE,
1030: MSG_CANTCREATEFILE, gszTempFile );
1031: return;
1032: }
1033:
1034: if (fEditFrame || cSel != 0) {
1035: PSTEP ps = GetStep(hWnd, iSel);
1036:
1037: if( !IsValidPS(ps) ) {
1038: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
1039: TRUE, MSG_OUTOFRESOUCES );
1040: CloseHandle(hf);
1041: return;
1042: }
1043:
1044:
1045: pbIcon = ps->pfrmFrame->abIcon;
1046: cbIcon = ps->pfrmFrame->rtag.ckSize;
1047:
1048: } else {
1049:
1050: HRSRC hr = FindResource(hInst, MAKEINTRESOURCE(ID_BLANKCUR),
1051: MAKEINTRESOURCE(RCT_RAWDATA));
1052:
1053: if (hr == NULL || (pbIcon =LockResource(LoadResource(hInst, hr))) ==
1054: NULL) {
1055: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
1056: TRUE, MSG_OUTOFRESOUCES );
1057: CloseHandle(hf);
1058: return;
1059: }
1060:
1061: cbIcon = SizeofResource(hInst, hr);
1062: }
1063:
1064: WriteFile(hf, pbIcon, cbIcon, &cb, NULL);
1065:
1066: CloseHandle(hf);
1067:
1068: /*
1069: * change .tmp to .cur
1070: */
1071: { TCHAR szOldName[MAX_PATH];
1072:
1073: cchCmdLine = lstrlen(gszTempFile);
1074:
1075: lstrcpy( szOldName, gszTempFile );
1076: lstrcpy( &gszTempFile[cchCmdLine - 3], gpszCUR );
1077:
1078: if(!MoveFile(szOldName, gszTempFile))
1079: lstrcpy( gszTempFile, szOldName );
1080:
1081: cchCmdLine = (cchCmdLine + lstrlen(gszCursorEditor) + 1 + 1) *
1082: sizeof(TCHAR);
1083:
1084: pszCmdLine = AllocMem(cchCmdLine);
1085: }
1086:
1087: if (pszCmdLine == NULL)
1088: return;
1089:
1090: {
1091: LPTSTR pszTempFile = gszTempFile;
1092:
1093: FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
1094: gszCursorEditor, 0, 0, pszCmdLine, cchCmdLine, &pszTempFile);
1095: }
1096:
1097: /* spawn imagedit on the file */
1098: fExeced = ExecProgram( hWnd, pszCmdLine );
1099: DPRINT(("MT:Begin Defer to child\n"));
1100:
1101: FreeMem(pszCmdLine);
1102:
1103: if ( fExeced ) {
1104: gfEditFrame = fEditFrame;
1105: } else {
1106: FmtMessageBox( hWnd, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
1107: TRUE, MSG_NOIMAGEDIT, gszCursorEditor );
1108: }
1109: }
1110:
1111:
1112:
1113:
1114: /****************************************************************************\
1115: *
1116: * FUNCTION: PSTEP NewStep( void );
1117: *
1118: *
1119: * PURPOSE: Creates a new step and set's its pfrmFrame to NULL;
1120: *
1121: *
1122: * History:
1123: * 29-Apr-1993 JonPa Created it
1124: *
1125: \****************************************************************************/
1126: PSTEP NewStep( void ) {
1127: PSTEP ps;
1128:
1129: ps = AllocMem(sizeof(STEP));
1130:
1131: if (IsValidPS(ps))
1132: ps->pfrmFrame = NULL;
1133:
1134: return ps;
1135: }
1136:
1137: /****************************************************************************\
1138: *
1139: * FUNCTION: VOID DestroyStep( PSTEP ps );
1140: *
1141: *
1142: * PURPOSE: Deletes a step, and derefernces its frame, deleting it if
1143: * necessary.
1144: *
1145: * History:
1146: * 29-Apr-1993 JonPa Created it
1147: *
1148: \****************************************************************************/
1149: VOID DestroyStep( PSTEP ps ) {
1150: LinkStepFrame(ps, NULL);
1151:
1152: FreeMem(ps);
1153: }
1154:
1155:
1156: /****************************************************************************\
1157: *
1158: * FUNCTION: VOID CopyStep( PSTEP psDst, PSTEP psSrc );
1159: *
1160: *
1161: * PURPOSE: Copyies a step, bumping the ref count of the frame if it
1162: * needs it.
1163: *
1164: * History:
1165: * 07-May-1993 JonPa Created it
1166: *
1167: \****************************************************************************/
1168: VOID CopyStep( PSTEP psDst, PSTEP psSrc ) {
1169: *psDst = *psSrc;
1170:
1171: if( psDst->pfrmFrame != NULL ) {
1172: psDst->pfrmFrame->cRef += 1;
1173: }
1174: }
1175:
1176:
1177: /****************************************************************************\
1178: *
1179: * FUNCTION: VOID LinkStepFrame( PSTEP ps, PFRAME pf );
1180: *
1181: *
1182: * PURPOSE: Unlinks a step from its frame and then links the new
1183: * frame in its place. If the old frame is an orphan, it
1184: * gets destroyed.
1185: *
1186: *
1187: * History:
1188: * 29-Apr-1993 JonPa Created it
1189: *
1190: \****************************************************************************/
1191: VOID LinkStepFrame(PSTEP ps, PFRAME pf ) {
1192: PFRAME pfOld = ps->pfrmFrame;
1193:
1194: if (pf != NULL)
1195: pf->cRef++;
1196:
1197: if (pfOld != NULL && --(pfOld->cRef) == 0)
1198: DestroyFrame(pfOld);
1199:
1200: ps->pfrmFrame = pf;
1201: }
1202:
1203: /****************************************************************************\
1204: *
1205: * FUNCTION: VOID DestroyFrame( PFRAME pf );
1206: *
1207: *
1208: * PURPOSE: Unlinks a frame from the list, deletes its hcur, and
1209: * Frees its memory.
1210: *
1211: *
1212: * History:
1213: * 28-Apr-1993 JonPa Created it
1214: *
1215: \****************************************************************************/
1216: VOID DestroyFrame( PFRAME pf ) {
1217: PFRAME pfList;
1218:
1219: if (pf == gpfrmFrames) {
1220: gpfrmFrames = pf->pfrmNext;
1221: } else {
1222:
1223: for( pfList = gpfrmFrames; pfList != NULL;
1224: pfList = pfList->pfrmNext ) {
1225:
1226: if (pfList->pfrmNext == pf) {
1227: break;
1228: }
1229: }
1230:
1231: if (pfList != NULL) {
1232: pfList->pfrmNext = pf->pfrmNext;
1233: }
1234: }
1235:
1236: DestroyIcon( pf->hcur );
1237: FreeMem(pf);
1238: }
1239:
1240: /****************************************************************************\
1241: *
1242: * FUNCTION: PCLPBRDDAT NewClpBrdDat( void )
1243: *
1244: *
1245: * PURPOSE: Creates a new clip board data struct
1246: *
1247: *
1248: * History:
1249: * 29-Apr-1993 JonPa Created it
1250: *
1251: \****************************************************************************/
1252: PCLPBRDDAT NewClpBrdDat( void ) {
1253: PCLPBRDDAT pcbd = AllocMem( sizeof(CLPBRDDAT) );
1254:
1255: if (pcbd != NULL)
1256: pcbd->stp.pfrmFrame = NULL;
1257:
1258: return pcbd;
1259: }
1260:
1261: /****************************************************************************\
1262: *
1263: * FUNCTION: VOID DestroyClpBrdDat(PCLPBRDDAT pcbd)
1264: *
1265: *
1266: * PURPOSE: Creates a new clip board data struct
1267: *
1268: *
1269: * History:
1270: * 29-Apr-1993 JonPa Created it
1271: *
1272: \****************************************************************************/
1273: VOID DestroyClpBrdDat(PCLPBRDDAT pcbd) {
1274: LinkStepFrame(&(pcbd->stp), NULL);
1275:
1276: FreeMem(pcbd);
1277: }
1278:
1279: /****************************************************************************\
1280: *
1281: * FUNCTION: VOID SetWindowFileTitle(HWND hWnd, LPTSTR szFileTitle)
1282: *
1283: *
1284: * PURPOSE: Sets the file title
1285: *
1286: *
1287: * History:
1288: * 30-Apr-1993 JonPa Created it
1289: *
1290: \****************************************************************************/
1291: VOID SetWindowFileTitle(HWND hWnd, LPTSTR szFileTitle) {
1292:
1293: /*
1294: * We use LocalAlloc here instead of AllocMem because we don't really
1295: * char if it fails
1296: */
1297: int cch = lstrlen( gszWindowTitle ) + lstrlen(szFileTitle);
1298: LPTSTR pszTitle = LocalAlloc(LPTR, (cch+4) * sizeof(TCHAR) );
1299:
1300: if (pszTitle != NULL) {
1301: wsprintf( pszTitle, "%s - %s", gszWindowTitle, szFileTitle );
1302: SetWindowText(hWnd, pszTitle);
1303:
1304: LocalFree(pszTitle);
1305: } else {
1306: SetWindowText(hWnd, gszWindowTitle);
1307: }
1308: }
1309:
1310: int __cdecl RevCompInts(const void *elm1, const void *elm2) {
1311: return *((int *)elm2) - *((int *)elm1);
1312: }
1313:
1314: /****************************************************************************\
1315: *
1316: * FUNCTION: ClearStepSel
1317: *
1318: *
1319: * PURPOSE: Clears all selections from the frame list
1320: *
1321: *
1322: * History:
1323: * 02-Jul-1993 JonPa Created it
1324: *
1325: \****************************************************************************/
1326: VOID ClearStepSel( HWND hWnd ) {
1327: int cItems = GetStepCount(hWnd);
1328:
1329: if (cItems != 0) {
1330: SendDlgItemMessage(hWnd, DLG_MAIN_FRAMELIST,
1331: LB_SELITEMRANGE, (WPARAM)FALSE, MAKELPARAM(0, cItems - 1));
1332: }
1333:
1334: UpdateStepSel(hWnd);
1335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.