home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / aniedit / aniedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-07  |  36.8 KB  |  1,302 lines

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