|
|
1.1 root 1: /****************************************************************************\
2: *
3: * PROGRAM: AniEdit.c
4: *
5: * PURPOSE: Animated Cursor Editor for Windows NT
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 "anidefs.h"
17:
18: HANDLE hInst;
19: HWND ghwndMain;
20: HWND ghwndRateScroll = NULL;
21:
22: ANICUR ganiAcon;
23:
24: int gcyCursor, gcxCursor;
25:
26: HBRUSH ghbrPrevBackgnd, ghbrWindow, ghbrHighlight;
27: COLORREF gcrHighlightText;
28:
29: TCHAR gszModPath[MAX_PATH]; /* name for above font module */
30: TCHAR gszWindowTitle[MAX_PATH] = TEXT("AniEdit");
31: TCHAR gszDots[] = TEXT("...");
32: PFRAME gpfrmFrames = NULL;
33: PCLPBRDDAT gpbdClipBoard = NULL;
34: TCHAR gszCursorEditor[MAX_PATH];
35:
36: //HACCEL haccel;
37: int giradColor = 0; /* Default to desktop color */
38: RADIOCOLOR garadColor[] = {
39: {DLG_OPTIONS_RADIO_DESKCOL, COLOR_BACKGROUND},
40: {DLG_OPTIONS_RADIO_WINCOL, COLOR_WINDOW},
41: {0, 0}
42: };
43:
44: #if DLG_OPTIONS_RADIO_DESKCOL == 0 || DLG_OPTIONS_RADIO_WINCOL == 0
45: # error("Dialog IDs must not equal zero!")
46: #endif
47:
48:
49: /*
50: * Registry Strings
51: * (Since the registry is not localized, these don't have to be read in
52: * from the strings RC)
53: */
54: TCHAR gszAppKey[] = "Software\\Microsoft\\AniEdit";
55: TCHAR gszKeyCurEditor[] = "Editor";
56: TCHAR gszKeyPrevColor[] = "Preview Color";
57:
58:
59: /****************************************************************************
60: *
61: * FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
62: *
63: * PURPOSE: calls initialization function, processes message loop
64: *
65: * COMMENTS:
66: *
67: * Windows recognizes this function by name as the initial entry point
68: * for the program. This function calls the application initialization
69: * routine, if no other instance of the program is running, and always
70: * calls the instance initialization routine. It then executes a message
71: * retrieval and dispatch loop that is the top-level control structure
72: * for the remainder of execution. The loop is terminated when a WM_QUIT
73: * message is received, at which time this function exits the application
74: * instance by returning the value passed by PostQuitMessage().
75: *
76: * If this function must abort before entering the message loop, it
77: * returns the conventional value NULL.
78: *
79: * History:
80: * 21-Apr-1993 JonPa Created it
81: *
82: \****************************************************************************/
83:
84: int APIENTRY WinMain(
85: HINSTANCE hInstance,
86: HINSTANCE hPrevInstance,
87: LPSTR lpCmdLine,
88: int nCmdShow
89: )
90: {
91:
92: MSG msg; /* message */
93:
94: UNREFERENCED_PARAMETER( lpCmdLine );
95:
96: if (!hPrevInstance) /* Other instances of app running? */
97: if (!InitApplication(hInstance)) /* Initialize shared things */
98: return (FALSE); /* Exits if unable to initialize */
99:
100: /* Perform initializations that apply to a specific instance */
101: if (!InitInstance(hInstance, nCmdShow))
102: return (FALSE);
103:
104:
105: DialogBox( hInstance, MAKEINTRESOURCE(DLG_MAIN), GetDesktopWindow(),
106: MainWndProc );
107:
108:
109: /* Write user profile */
110: WriteRegistry();
111:
112: //BUGBUG - unregister preview class
113:
114: if (gszModPath[0] != TEXT('\0')) {
115: RemoveFontResource(gszModPath);
116: PostMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
117: }
118:
119:
120: DeleteObject(ghbrPrevBackgnd);
121:
122: /* Return the value from PostQuitMessage */
123: return (msg.wParam);
124: }
125:
126:
127: /****************************************************************************
128: *
129: * FUNCTION: InitApplication(HANDLE)
130: *
131: * PURPOSE: Initializes window data and registers window class
132: *
133: * COMMENTS:
134: *
135: * This function is called at initialization time only if no other
136: * instances of the application are running. This function performs
137: * initialization tasks that can be done once for any number of running
138: * instances.
139: *
140: * In this case, we initialize a window class by filling out a data
141: * structure of type WNDCLASS and calling the Windows RegisterClass()
142: * function. Since all instances of this application use the same window
143: * class, we only need to do this when the first instance is initialized.
144: *
145: *
146: \****************************************************************************/
147:
148: BOOL InitApplication(HANDLE hInstance) /* current instance */
149: {
150: WNDCLASS cls;
151:
152: /*
153: * Register a new window class to handle the cursor preview.
154: */
155: cls.style = 0;
156: cls.lpfnWndProc = PreviewWndProc;
157: cls.cbClsExtra = 0;
158: cls.cbWndExtra = 0;
159: cls.hInstance = hInstance;
160: cls.hIcon = NULL;
161: cls.hCursor = NULL;
162: cls.hbrBackground = NULL;
163: cls.lpszMenuName = NULL;
164: cls.lpszClassName = szPREVIEW;
165: RegisterClass(&cls);
166:
167: AniAddFontModule(hInstance);
168:
169: return TRUE;
170: }
171:
172:
173: void AniAddFontModule(HINSTANCE hInst) {
174:
175:
176: if (GetModuleFileName(hInst, gszModPath, MAX_PATH))
177: AddFontResource(gszModPath);
178: else
179: gszModPath[0] = TEXT('\0');
180: }
181:
182:
183: /****************************************************************************
184: *
185: * FUNCTION: InitInstance(HANDLE, int)
186: *
187: * PURPOSE: Saves instance handle and creates main window
188: *
189: * COMMENTS:
190: *
191: * This function is called at initialization time for every instance of
192: * this application. This function performs initialization tasks that
193: * cannot be shared by multiple instances.
194: *
195: * In this case, we save the instance handle in a static variable and
196: * create and display the main program window.
197: *
198: \****************************************************************************/
199:
200: BOOL InitInstance(
201: HANDLE hInstance,
202: int nCmdShow)
203: {
204:
205: /* Save the instance handle in static variable, which will be used in */
206: /* many subsequence calls from this application to Windows. */
207:
208: hInst = hInstance;
209:
210: gcyCursor = GetSystemMetrics(SM_CYCURSOR);
211: gcxCursor = GetSystemMetrics(SM_CXCURSOR);
212:
213:
214: /* Load user profile */
215: ReadRegistry();
216:
217: #if 0
218: /* Load the accel table */
219: if (!(haccel = LoadAccelerators(hInstance, "AniEditAccel")))
220: return FALSE;
221: #endif
222:
223: return (TRUE); /* Returns the value from PostQuitMessage */
224:
225: }
226:
227: /* Copied from winfile:
228: */
229: INT APIENTRY GetHeightFromPoints( int pts)
230: {
231: HDC hdc;
232: INT height;
233:
234: hdc = GetDC (NULL);
235: height = MulDiv(-pts, GetDeviceCaps (hdc, LOGPIXELSY), 72);
236: ReleaseDC (NULL, hdc);
237:
238: return height;
239: }
240:
241:
242:
243: /****************************************************************************
244: *
245: * FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
246: *
247: * PURPOSE: Processes messages
248: *
249: * MESSAGES:
250: *
251: * WM_COMMAND - application menu (About dialog box)
252: * WM_DESTROY - destroy window
253: *
254: * COMMENTS:
255: *
256: * To process the IDM_ABOUT message, call MakeProcInstance() to get the
257: * current instance address of the About() function. Then call Dialog
258: * box which will create the box according to the information in your
259: * aniedit.rc file and turn control over to the About() function. When
260: * it returns, free the intance address.
261: *
262: * History:
263: * 21-Apr-1993 JonPa Created it
264: *
265: \****************************************************************************/
266:
267: BOOL APIENTRY MainWndProc(
268: HWND hWnd, /* window handle */
269: UINT message, /* type of message */
270: UINT wParam, /* additional information */
271: LONG lParam) /* additional information */
272: {
273: static HWND hwndChildApp = NULL;
274: static HBRUSH hbrBtnBar;
275: static HFONT hfontButton;
276:
277: switch (message) {
278: case WM_INITDIALOG:
279: ghwndMain = hWnd;
280:
281: gcrHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
282: ghbrHighlight = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
283: ghbrWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
284: hbrBtnBar = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
285:
286: hfontButton = CreateFont (GetHeightFromPoints(8), 0, 0, 0, 400,
287: 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
288: CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
289: DEFAULT_PITCH | FF_SWISS,
290: TEXT("AniEdit Button"));
291:
292: SendDlgItemMessage (hWnd, DLG_MAIN_BTNNEW, WM_SETFONT, (WPARAM)hfontButton, 0L);
293: SendDlgItemMessage (hWnd, DLG_MAIN_BTNOPEN, WM_SETFONT, (WPARAM)hfontButton, 0L);
294: SendDlgItemMessage (hWnd, DLG_MAIN_BTNSAVE, WM_SETFONT, (WPARAM)hfontButton, 0L);
295:
296: SendDlgItemMessage (hWnd, DLG_MAIN_BTNCUT, WM_SETFONT, (WPARAM)hfontButton, 0L);
297: SendDlgItemMessage (hWnd, DLG_MAIN_BTNCOPY, WM_SETFONT, (WPARAM)hfontButton, 0L);
298: SendDlgItemMessage (hWnd, DLG_MAIN_BTNPASTE, WM_SETFONT, (WPARAM)hfontButton, 0L);
299:
300: SendDlgItemMessage (hWnd, DLG_MAIN_DELFRAME, WM_SETFONT, (WPARAM)hfontButton, 0L);
301:
302: SendDlgItemMessage (hWnd, DLG_MAIN_ADDFRAME, WM_SETFONT, (WPARAM)hfontButton, 0L);
303: SendDlgItemMessage (hWnd, DLG_MAIN_EDITFRAME, WM_SETFONT, (WPARAM)hfontButton, 0L);
304:
305: SendDlgItemMessage (hWnd, DLG_MAIN_PLAY, WM_SETFONT, (WPARAM)hfontButton, 0L);
306: SendDlgItemMessage (hWnd, DLG_MAIN_STOP, WM_SETFONT, (WPARAM)hfontButton, 0L);
307:
308: SendDlgItemMessage (hWnd, DLG_MAIN_FRAMETXT, WM_SETFONT, (WPARAM)hfontButton, 0L);
309:
310:
311:
312: GetWindowText(hWnd, gszWindowTitle, COUNTOF(gszWindowTitle));
313:
314: /* cache scroll bar window handle */
315: ghwndRateScroll = GetDlgItem(hWnd, DLG_MAIN_RATESPIN);
316:
317: /* limit title and author string lengths */
318:
319: SendDlgItemMessage(hWnd, DLG_MAIN_TITLE, EM_LIMITTEXT,
320: COUNTOF(ganiAcon.azTitle), 0);
321:
322: SendDlgItemMessage(hWnd, DLG_MAIN_AUTHOR, EM_LIMITTEXT,
323: COUNTOF(ganiAcon.azCreator), 0);
324:
325: NewAniCursor(hWnd);
326: return (TRUE);
327:
328: case WM_COMMAND: /* message: command from application menu */
329: return DoCommand( hWnd, wParam, lParam );
330:
331:
332: case AIM_SETCHILDAPP:
333: /*
334: * A child app has just been started. Remeber its hwnd and defer
335: * all activation to it.
336: */
337: DPRINT(("MT:Child HWND = 0x%lx\n", lParam));
338: hwndChildApp = (HWND)lParam;
339:
340: if (hwndChildApp == NULL)
341: EnableWindow(hWnd, FALSE);
342:
343: break;
344:
345: case AIM_PROCESSTERM:
346: /*
347: * The copy of ImagEdit that we spanwed off has just ended.
348: * Time to read in the cursor file and put it back into the list.
349: */
350:
351: /* "enable" our window */
352: DPRINT(("MT:got AIM_PROCESSTERM\n"));
353:
354: hwndChildApp = NULL;
355:
356: EnableWindow(hWnd, TRUE);
357:
358: SetForegroundWindow(hWnd);
359:
360: /* call CreateFrameFromCursorFile to reload the modified cursor */
361: if(CreateFrameFromCursorFile(hWnd, gszTempFile, gfEditFrame))
362: DeleteFile(gszTempFile);
363:
364: break;
365:
366: case WM_ACTIVATE:
367: /*
368: * Convert WM_ACTIVATE to WM_NCACTIVATE
369: */
370: switch (LOWORD(wParam)) {
371:
372: case WA_CLICKACTIVE:
373: /*
374: * Simulate disabled window's beep
375: */
376: if (IsWindow( hwndChildApp ))
377: MessageBeep(MB_OK);
378:
379: wParam = TRUE;
380: break;
381:
382: case WA_ACTIVE:
383: wParam = TRUE;
384: break;
385:
386: default:
387: wParam = FALSE;
388: break;
389: }
390:
391: FALLTHRU(WM_NCACTIVATE);
392:
393: case WM_NCACTIVATE:
394: case WM_ACTIVATEAPP:
395: DPRINT(("MT:got Activate (%04x) %c %08x\n", message, wParam ? 'T' : 'F', lParam));
396:
397: if (wParam == TRUE && IsWindow( hwndChildApp )) {
398: /*
399: * We have a 'modal' child app upp, defer the activation to it.
400: */
401: DPRINT(("MT:Defering Now\n"));
402: return SetForegroundWindow(hwndChildApp);
403: }
404:
405: /*
406: * Let DefWndProc process this message
407: */
408: return FALSE;
409:
410: case WM_MEASUREITEM:
411: ((MEASUREITEMSTRUCT *)lParam)->itemHeight = gcyCursor + 2;
412: break;
413:
414: case WM_DRAWITEM:
415: DrawCursorListItem((DRAWITEMSTRUCT *)lParam);
416: break;
417:
418:
419: case WM_DELETEITEM: {
420: PSTEP ps;
421:
422: if (wParam != DLG_MAIN_FRAMELIST)
423: return FALSE;
424:
425: ps = (PSTEP)((LPDELETEITEMSTRUCT)lParam)->itemData;
426:
427: if (IsValidPS(ps)) {
428: DestroyStep(ps);
429: }
430: break;
431: }
432:
433:
434: case WM_VSCROLL:
435: if( (HWND)lParam == ghwndRateScroll ) {
436: LONG iDelta;
437:
438: switch( LOWORD(wParam) ) {
439: case SB_LINEUP:
440: case SB_PAGEUP:
441: iDelta = 1;
442: break;
443:
444: case SB_LINEDOWN:
445: case SB_PAGEDOWN:
446: iDelta = -1;
447: break;
448:
449: default:
450: iDelta = 0;
451: }
452:
453: if (iDelta != 0) {
454: BOOL fOK;
455: JIF jifRate = GetDlgItemInt(hWnd, DLG_MAIN_RATE, &fOK, FALSE);
456:
457: if( fOK ) {
458: if ((jifRate += iDelta) != 0) {
459: int *piSel, cSel;
460:
461: SetDlgItemInt(hWnd, DLG_MAIN_RATE, jifRate, FALSE);
462:
463: cSel = GetSelStepCount(hWnd);
464:
465: if (cSel > 0 && (piSel = AllocMem(cSel * sizeof(int))) !=
466: NULL) {
467: int i;
468:
469: ganiAcon.fDirty = TRUE;
470: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, piSel, cSel,
471: &cSel);
472:
473: for( i = 0; i < cSel; i++ ) {
474: PSTEP ps = GetStep(hWnd, piSel[i]);
475: if (IsValidPS(ps)) {
476: ps->jif = jifRate;
477: }
478: }
479:
480: InvalidateRect(GetDlgItem(hWnd, DLG_MAIN_FRAMELIST),
481: NULL, TRUE);
482: FreeMem(piSel);
483: }
484: }
485: } else {
486: int *piSel, cSel, i;
487: JIF jifMin, jifTmp;
488:
489: cSel = GetSelStepCount(hWnd);
490:
491: if (cSel > 0 && (piSel = AllocMem(cSel * sizeof(int))) !=
492: NULL) {
493:
494: ganiAcon.fDirty = TRUE;
495: GetCurrentSel(hWnd, DLG_MAIN_FRAMELIST, piSel, cSel,
496: &cSel);
497:
498: jifMin = MAXLONG;
499:
500: for( i = 0; i < cSel; i++ ) {
501: PSTEP ps = GetStep(hWnd, piSel[i]);
502: if (IsValidPS(ps)) {
503: jifMin = min(jifMin, ps->jif);
504: }
505: }
506:
507: for( i = 0; i < cSel; i++ ) {
508: PSTEP ps = GetStep(hWnd, piSel[i]);
509: if (IsValidPS(ps)) {
510:
511: jifTmp = ps->jif;
512:
513: if (iDelta == 1) {
514: ps->jif += (ps->jif / jifMin);
515: } else {
516: ps->jif -= (ps->jif / jifMin);
517: }
518:
519: /* check for over/under-flow */
520: if (ps->jif == 0) {
521: ps->jif = jifTmp;
522: }
523: }
524: }
525:
526: InvalidateRect(GetDlgItem(hWnd, DLG_MAIN_FRAMELIST),
527: NULL, TRUE);
528: FreeMem(piSel);
529: }
530: }
531: }
532: }
533: break;
534:
535: case WM_SYSCOMMAND:
536: if (wParam == SC_CLOSE) {
537: ExitCommand(hWnd);
538: } else {
539: return FALSE;
540: }
541:
542: break;
543:
544: case WM_SYSCOLORCHANGE:
545: DeleteObject(ghbrPrevBackgnd);
546: DeleteObject(ghbrWindow);
547: DeleteObject(ghbrHighlight);
548: DeleteObject(hbrBtnBar);
549:
550: ghbrHighlight = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
551: gcrHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
552: ghbrWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
553: ghbrPrevBackgnd = CreateSolidBrush(GetSysColor(
554: garadColor[giradColor].idSys));
555:
556: hbrBtnBar = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
557: break;
558:
559: case WM_ERASEBKGND: {
560: RECT rc;
561: GetClientRect(hWnd, &rc);
562: FillRect((HDC)wParam, &rc, ghbrWindow);
563:
564: GetWindowRect(GetDlgItem(hWnd, DLG_MAIN_BTNBAR), &rc);
565: ScreenToClient(hWnd, (LPPOINT)&(rc.left));
566: ScreenToClient(hWnd, (LPPOINT)&(rc.right));
567: FillRect((HDC)wParam, &rc, hbrBtnBar);
568:
569: break;
570: }
571:
572: case WM_DESTROY:
573: DeleteObject(ghbrPrevBackgnd);
574: DeleteObject(ghbrWindow);
575: DeleteObject(ghbrHighlight);
576: DeleteObject(hbrBtnBar);
577: DeleteObject(hfontButton );
578: return FALSE;
579:
580:
581: default:
582: return FALSE;
583: }
584:
585: return TRUE;
586: }
587:
588:
589: /***************************************************************************\
590: *
591: * DrawCursorListItem
592: *
593: *
594: * History:
595: * 22-Dec-1991 DarrinM Created in the Cursors cpa.
596: * 22-Apr-1993 JonPa copied into this app and tweeked it.
597: \***************************************************************************/
598:
599: void DrawCursorListItem(
600: DRAWITEMSTRUCT *pdis)
601: {
602: COLORREF crPrev;
603: static LONG cxAvgChar = 0;
604: TEXTMETRIC tm;
605: PSTEP ps;
606: TCHAR szJif[CCH_JIF];
607:
608: /*
609: * LATER: Deal with focus rect.
610: */
611: if (pdis->itemAction == ODA_FOCUS)
612: return;
613:
614:
615: /* find the average char width for this listbox and cache it */
616: if (cxAvgChar == 0) {
617: if (GetTextMetrics( pdis->hDC, &tm)) {
618: cxAvgChar = tm.tmAveCharWidth;
619: }
620: }
621:
622: ps = (PSTEP)(pdis->itemData);
623:
624: SetBkMode(pdis->hDC, TRANSPARENT);
625:
626: if (pdis->itemState & ODS_SELECTED) {
627: FillRect(pdis->hDC, &pdis->rcItem, ghbrHighlight);
628: crPrev = SetTextColor(pdis->hDC, gcrHighlightText);
629: } else {
630: FillRect(pdis->hDC, &pdis->rcItem, ghbrWindow);
631: }
632:
633:
634: /* Draw the frame */
635: DrawIcon(pdis->hDC, pdis->rcItem.left + 2, pdis->rcItem.top + 1,
636: ps->pfrmFrame->hcur);
637:
638:
639: pdis->rcItem.left += gcxCursor + 2 + ((cxAvgChar != 0) ? cxAvgChar : 8);
640:
641:
642: /* write the rate text */
643: wsprintf( szJif, "%d", (int)ps->jif );
644:
645: DrawText(pdis->hDC, szJif, strlen(szJif), &pdis->rcItem,
646: DT_SINGLELINE | DT_LEFT | DT_VCENTER);
647:
648:
649: if (pdis->itemState & ODS_SELECTED) {
650: SetTextColor(pdis->hDC, crPrev);
651: }
652: }
653:
654:
655:
656:
657:
658: /***************************************************************************\
659: *
660: * FUNCTION: FmtMessageBox( HWND hwnd, DWORD dwTitleID, UINT fuStyle,
661: * BOOL fSound, DWORD dwTextID, ... );
662: *
663: * PURPOSE: Formats messages with FormatMessage and then displays them
664: * in a message box
665: *
666: *
667: *
668: *
669: * History:
670: * 22-Apr-1993 JonPa Created it.
671: \***************************************************************************/
672: int FmtMessageBox( HWND hwnd, DWORD dwTitleID, LPTSTR pszTitleStr,
673: UINT fuStyle, BOOL fSound, DWORD dwTextID, ... ) {
674: LPTSTR pszMsg;
675: LPTSTR pszTitle;
676: int idRet;
677:
678: va_list marker;
679:
680: va_start( marker, dwTextID );
681:
682: if(!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
683: FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK, hInst,
684: dwTextID, 0, (LPTSTR)&pszMsg, 1, &marker))
685: pszMsg = gpszUnknownError;
686:
687: va_end( marker );
688:
689: GetLastError();
690:
691: pszTitle = NULL;
692:
693: if (dwTitleID == (DWORD)-1 ||
694: FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
695: FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK |
696: FORMAT_MESSAGE_ARGUMENT_ARRAY,
697: hInst, dwTitleID, 0, (LPTSTR)&pszTitle, 1, &pszTitleStr)) {
698: }
699:
700: GetLastError();
701:
702: if (fSound) {
703: MessageBeep( fuStyle & (MB_ICONASTERISK | MB_ICONEXCLAMATION |
704: MB_ICONHAND | MB_ICONQUESTION | MB_OK) );
705: }
706:
707: idRet = MessageBox(hwnd, pszMsg, pszTitle, fuStyle);
708:
709: if (pszTitle != NULL)
710: LocalFree( pszTitle );
711:
712: if (pszMsg != gpszUnknownError)
713: LocalFree( pszMsg );
714:
715: return idRet;
716: }
717:
718: /***************************************************************************\
719: *
720: * FUNCTION: FmtSprintf( DWORD id, ... );
721: *
722: * PURPOSE: sprintf but it gets the pattern string from the message rc.
723: *
724: * History:
725: * 03-May-1993 JonPa Created it.
726: \***************************************************************************/
727: LPTSTR FmtSprintf( DWORD id, ... ) {
728: LPTSTR pszMsg;
729: va_list marker;
730:
731: va_start( marker, id );
732:
733: if(!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
734: FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK, hInst,
735: id, 0, (LPTSTR)&pszMsg, 1, &marker)) {
736: GetLastError();
737: pszMsg = gszDots;
738: }
739: va_end( marker );
740:
741: return pszMsg;
742: }
743:
744: /***************************************************************************\
745: *
746: * FUNCTION: PVOID AllocMem( DWORD cb );
747: *
748: * PURPOSE: allocates memory, checking for errors
749: *
750: * History:
751: * 22-Apr-1993 JonPa Wrote it.
752: \***************************************************************************/
753: PVOID AllocMem( DWORD cb ) {
754: PVOID pv = (PVOID)LocalAlloc(LPTR, cb);
755:
756: if (pv == NULL) {
757: FmtMessageBox( ghwndMain, TITL_ERROR, NULL, MB_OK | MB_ICONSTOP,
758: TRUE, MSG_OUTOFMEM );
759: }
760:
761: return pv;
762: }
763:
764:
765: /***************************************************************************\
766: * PreviewWndProc
767: *
768: *
769: * History:
770: * 08-07-92 DarrinM Created in CURSORS.CPL.
771: * 24-Apr-1993 JonPa Copied here and tweeked.
772: \***************************************************************************/
773:
774: LRESULT CALLBACK
775: PreviewWndProc(
776: HWND hwnd,
777: UINT msg,
778: WPARAM wParam,
779: LPARAM lParam
780: )
781: {
782: HDC hdc;
783: RECT rc;
784: PAINTSTRUCT ps;
785: PPREVIEWDATA ppd;
786: static int cxBM, cyBM;
787: static int cxCenter, cyCenter;
788:
789: switch (msg) {
790: case WM_CREATE:
791: if (!(ppd = (PPREVIEWDATA)LocalAlloc(LPTR, sizeof(PREVIEWDATA))))
792: return -1;
793:
794: SetWindowLong(hwnd, GWL_USERDATA, (LONG)ppd);
795:
796: /*
797: * Create a temp DC and bitmap to be used for buffering the
798: * preview rendering.
799: */
800: cxCenter = gcxCursor;
801: cyCenter = gcyCursor;
802:
803: cxBM = cxCenter * 2;
804: cyBM = cyCenter * 2;
805:
806: hdc = GetDC(hwnd);
807: ppd->hdcMem = CreateCompatibleDC(hdc);
808: ppd->hbmMem = CreateCompatibleBitmap(hdc, cxBM, cyBM);
809: ppd->hbmOld = SelectObject(ppd->hdcMem, ppd->hbmMem);
810: ppd->iFrame = 0;
811: ppd->hcur = NULL;
812: ppd->xHot = ppd->yHot = 0;
813: ReleaseDC(hwnd, hdc);
814: break;
815:
816: case WM_SIZE:
817: ppd = (PPREVIEWDATA)GetWindowLong(hwnd, GWL_USERDATA);
818:
819: SelectObject(ppd->hdcMem, ppd->hbmOld);
820: DeleteObject(ppd->hbmMem);
821:
822: cxBM = LOWORD(lParam);
823: cyBM = HIWORD(lParam);
824: cxCenter = cxBM / 2;
825: cyCenter = cyBM / 2;
826:
827: hdc = GetDC(hwnd);
828: ppd->hbmMem = CreateCompatibleBitmap(hdc, cxBM, cyBM);
829: ppd->hbmOld = SelectObject(ppd->hdcMem, ppd->hbmMem);
830: ReleaseDC(hwnd, hdc);
831: break;
832:
833: case WM_DESTROY:
834: ppd = (PPREVIEWDATA)GetWindowLong(hwnd, GWL_USERDATA);
835: SelectObject(ppd->hdcMem, ppd->hbmOld);
836: DeleteObject(ppd->hbmMem);
837: DeleteDC(ppd->hdcMem);
838: LocalFree(ppd);
839: break;
840:
841: case PM_PAUSEANIMATION:
842: KillTimer(hwnd, ID_PREVIEWTIMER);
843: break;
844:
845: case PM_UNPAUSEANIMATION:
846: NextFrame(hwnd, TRUE);
847: break;
848:
849: case PM_NEWCURSOR:
850: wParam = 0;
851: FALLTHRU(PM_SETSTEP);
852:
853: case PM_SETSTEP: {
854: BOOL fRun = KillTimer(hwnd, ID_PREVIEWTIMER);
855:
856: ppd = (PPREVIEWDATA)GetWindowLong(hwnd, GWL_USERDATA);
857:
858: ppd->iFrame = wParam;
859:
860: NextFrame(hwnd, fRun);
861: InvalidateRect(hwnd, NULL, FALSE);
862: break;
863: }
864:
865: case WM_TIMER:
866: if (wParam != ID_PREVIEWTIMER)
867: break;
868:
869: NextFrame(hwnd, TRUE);
870: break;
871:
872: case WM_PAINT:
873: BeginPaint(hwnd, &ps);
874:
875: ppd = (PPREVIEWDATA)GetWindowLong(hwnd, GWL_USERDATA);
876:
877: if (ppd->hcur != NULL)
878: {
879: rc.left = rc.top = 0;
880: rc.right = cxBM;
881: rc.bottom = cyBM;
882: FillRect(ppd->hdcMem, &rc, ghbrPrevBackgnd);
883:
884:
885: DrawIcon(ppd->hdcMem, cxCenter - ppd->xHot, cyCenter - ppd->yHot,
886: ppd->hcur);
887:
888: BitBlt(ps.hdc, 0, 0, cxBM, cyBM, ppd->hdcMem, 0, 0, SRCCOPY);
889: }
890: else
891: {
892: FillRect(ps.hdc, &ps.rcPaint, ghbrPrevBackgnd);
893: }
894:
895: EndPaint(hwnd, &ps);
896: break;
897:
898: case WM_ERASEBKGND:
899: break;
900:
901: default:
902: return DefWindowProc(hwnd, msg, wParam, lParam);
903: }
904:
905: return 0;
906: }
907:
908: /*****************************************************************************\
909: * NextFrame
910: *
911: * Sets up for the next frame in the preview window.
912: *
913: * Arguments:
914: * HWND hwnd - Dialog window handle.
915: *
916: \*****************************************************************************/
917:
918: VOID
919: NextFrame(
920: HWND hwnd, BOOL fRun
921: )
922: {
923: PPREVIEWDATA ppd;
924: HWND hwndLB;
925: DWORD cFrame;
926: PSTEP ps;
927:
928: ppd = (PPREVIEWDATA)GetWindowLong(hwnd, GWL_USERDATA);
929:
930: //
931: // Be sure there is a cursor specified. If not, or it is
932: // not an animated cursor, we are done.
933: //
934: hwndLB = GetDlgItem(GetParent(hwnd), DLG_MAIN_FRAMELIST);
935: cFrame = SendMessage(hwndLB, LB_GETCOUNT, 0, 0);
936: if (cFrame == LB_ERR || cFrame == 0) {
937: ppd->hcur = NULL;
938: InvalidateRect(hwnd, NULL, FALSE);
939: return;
940: }
941:
942: if (ppd->iFrame >= cFrame)
943: ppd->iFrame = 0;
944:
945: /*
946: * Find how long this frame should be displayed (i.e. get jifRate)
947: */
948: ps = (PSTEP)SendMessage(hwndLB, LB_GETITEMDATA, ppd->iFrame, 0);
949:
950: if (IsValidPS(ps)) {
951: ppd->xHot = ps->pfrmFrame->xHotSpot;
952: ppd->yHot = ps->pfrmFrame->yHotSpot;
953:
954: ppd->hcur = ps->pfrmFrame->hcur;
955:
956: if (fRun)
957: SetTimer(hwnd, ID_PREVIEWTIMER, ps->jif * 16, NULL);
958:
959: ppd->iFrame += 1;
960: } else {
961: ppd->hcur = NULL;
962: }
963:
964: /*
965: * Redraw this frame of the cursor.
966: */
967: InvalidateRect(hwnd, NULL, FALSE);
968: }
969:
970: /*****************************************************************************\
971: * ReadRegistry
972: *
973: * Opens (creates if necessary) the registry key for preferences and then
974: * reads the last saved values.
975: *
976: * 03-Jul-1993 JonPa Copied from Spy, but changed greatly
977: *
978: \*****************************************************************************/
979:
980: VOID ReadRegistry( VOID ) {
981: DWORD dw;
982: DWORD cbData;
983: HKEY hkey;
984:
985: if (RegOpenKeyEx(HKEY_CURRENT_USER, gszAppKey, 0, KEY_QUERY_VALUE, &hkey)){
986:
987: lstrcpy( gszCursorEditor, gpszImagEdit );
988:
989: } else {
990:
991: cbData = sizeof(gszCursorEditor);
992: if (RegQueryValueEx(hkey, gszKeyCurEditor, NULL, NULL,
993: gszCursorEditor, &cbData) != ERROR_SUCCESS) {
994:
995: lstrcpy( gszCursorEditor, gpszImagEdit );
996:
997: }
998:
999: cbData = sizeof(dw);
1000: if (RegQueryValueEx(hkey, gszKeyPrevColor, NULL, NULL, (LPBYTE)&dw,
1001: &cbData) == ERROR_SUCCESS) {
1002:
1003: giradColor = (int)dw;
1004: }
1005:
1006: RegCloseKey(hkey);
1007: }
1008:
1009: ghbrPrevBackgnd = CreateSolidBrush(GetSysColor(garadColor[giradColor].idSys));
1010: }
1011:
1012:
1013:
1014: /*****************************************************************************\
1015: * WriteRegistry
1016: *
1017: * Writes out preference data to the registry when the app exits, then
1018: * closes the registry key.
1019: *
1020: * 03-Jul-1993 JonPa Copied from Spy, but changed greatly
1021: \*****************************************************************************/
1022:
1023: VOID WriteRegistry( VOID ) {
1024: HKEY hkey;
1025: DWORD dw;
1026:
1027: if (RegCreateKeyEx(HKEY_CURRENT_USER, gszAppKey, 0, NULL,
1028: REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dw))
1029: return;
1030:
1031: RegSetValueEx(hkey, gszKeyCurEditor, 0, REG_SZ, gszCursorEditor,
1032: lstrlen(gszCursorEditor)+1);
1033:
1034: dw = giradColor;
1035: RegSetValueEx(hkey, gszKeyPrevColor, 0, REG_DWORD, (LPBYTE)&dw, sizeof(dw));
1036:
1037: RegCloseKey(hkey);
1038:
1039: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.