home *** CD-ROM | disk | FTP | other *** search
/ Windows Shareware GOLD / NuclearComputingVol3No1.cdr / _bbs4 / f1164.zip / DESKSAVE.C < prev    next >
Text File  |  1990-07-21  |  14KB  |  563 lines

  1. /*
  2.  *  DeskSave.c    v2.0  15 Sep 1988
  3.  *                v2.0a 20 Jul 1990
  4.  *
  5.  *  Windows 3.0 Desk Saving Utility
  6.  *
  7.  *  Written by Jari Salminen, OH2BYQ
  8.  *    UUCP: mcvax!tut!kolvi!jsa
  9.  *    Internet: jsa@kolvi.hut.FI
  10.  *
  11.  *  Usage:
  12.  *    To save desk:
  13.  *    - run DESKSAVE
  14.  *    - select command "Save Desk" from System menu
  15.  *
  16.  *    To arrange desk:
  17.  *    - run DESKSAVE and select command "Arrange Desk"
  18.  *    or
  19.  *    - run DESKSAVE with command line option "-l"
  20.  *    or
  21.  *    - add DESKLOAD.EXE to "Load"-list in WIN.INI as the last name in list
  22.  *      ( done by DESKSAVE with "Save Desk" command )
  23.  *
  24.  *  This file creates both DESKSAVE.OBJ and DESKLOAD.OBJ
  25.  *  For DESKLOAD.OBJ compile with option /DDESKLOAD
  26.  *
  27.  */
  28.  
  29. #define NOMINMAX
  30. #include <windows.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "desksave.h"
  34.  
  35. #define MAXINT        32767
  36. #define MAX_WIN        64        /* Max. number of windows that */
  37.                     /* can be arranged */
  38. #define MAX_LIST_SIZE    1024
  39.  
  40. /* Menu command definitions */
  41.  
  42. #define CMD_SAVEDESK    1
  43. #define CMD_ARRDESK    2
  44. #define CMD_CLEAR    3
  45. #define CMD_ABOUT    4
  46.  
  47.  
  48. HANDLE    hInstance;        /* Our instance handle */
  49. HWND    hWndDeskSave;        /* hWnd of our icon */
  50.  
  51. FARPROC    lpEnumWndProc;        /* Enumerate windows */
  52.  
  53. char    szLoadList[MAX_LIST_SIZE];    /* List of files to load */
  54. char    szRunList[MAX_LIST_SIZE];    /* List of files to run */
  55. char    szFileName[_MAX_FNAME + _MAX_EXT];    /* Name of file */
  56. char    szFileNameKey[_MAX_FNAME + _MAX_EXT + 1];
  57. char    szKeyList[MAX_LIST_SIZE];    /* List of coordinates for file */
  58. char    szNameList[2 * MAX_LIST_SIZE];    /* List of file handeled */
  59.  
  60. BOOL    bSaveFlag;
  61. BOOL    bInitialMSDOS;
  62.  
  63. char    szClass[] =    "DeskSave";    /* Our window class name */
  64. char    szTitle[] =    "DeskSave";    /* Our window title */
  65. char    szSaveDesk[] =    "Save &Desk";
  66. char    szArrDesk[] =    "&Arrange Desk";
  67. char    szClrRun[] =    "C&lear \"Load\" and \"Run\"";
  68. char    szAbout[] =    "A&bout DeskSave...";
  69.  
  70. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  71.  
  72. BOOL        IsRunable( HWND );
  73. BOOL        IsLoadable( HWND );
  74. long FAR PASCAL    DeskSaveWndProc( HWND, unsigned, WORD, LONG );
  75. BOOL        ArrangeWindow( HWND );
  76. int PASCAL    WinMain( HANDLE, HANDLE, LPSTR, int );
  77. BOOL        Initialize( void );
  78. BOOL FAR PASCAL    AboutBox( HWND, unsigned, WORD, LONG );
  79.  
  80. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  81.  
  82. /*  DeskSave's window function.
  83.  */
  84.  
  85. long FAR PASCAL DeskSaveWndProc( hWnd, wMsg, wParam, lParam )
  86. HWND    hWnd;            /* Window handle */
  87. unsigned wMsg;            /* Message number */
  88. WORD    wParam;         /* Word parameter for the message */
  89. LONG    lParam;         /* Long parameter for the message */
  90. {
  91.     FARPROC    lpProc;         /* ProcInstance for AboutBox */
  92.  
  93.     switch( wMsg ) {
  94.  
  95.     /* Destroy-window message - time to quit the application */
  96.     case WM_DESTROY:
  97.         PostQuitMessage( 0 );
  98.         return(0L);
  99.  
  100.     /* Query open icon message - don't allow icon to be opened! */
  101.     case WM_QUERYOPEN:
  102.         return(0L);
  103.  
  104.     /* System menu command message - process the command if ours */
  105.     case WM_SYSCOMMAND:
  106.         switch( wParam ) {
  107.         case CMD_SAVEDESK:
  108.             SaveDesk();
  109.             return(0L);
  110.  
  111.         case CMD_ARRDESK:
  112.             ArrangeDesk();
  113.             return(0L);
  114.  
  115.         case CMD_CLEAR:
  116.             WriteProfileString((LPSTR)"windows",(LPSTR)"Run",
  117.                     (LPSTR)"" );
  118.             WriteProfileString((LPSTR)"windows",(LPSTR)"Load",
  119.                     (LPSTR)"" );
  120.             return(0L);
  121.  
  122.         case CMD_ABOUT:
  123.             lpProc = MakeProcInstance( (FARPROC)AboutBox, hInstance );
  124.             if( ! lpProc )
  125.                 return(0L);
  126.             DialogBox( hInstance, MAKEINTRESOURCE(ABOUTBOX),
  127.                 hWnd, lpProc );
  128.             FreeProcInstance( lpProc );
  129.             return(0L);
  130.         }
  131.         break;
  132.     }
  133.  
  134.     /* For all other messages, we pass them on to DefWindowProc */
  135.     return( DefWindowProc( hWnd, wMsg, wParam, lParam ));
  136. }
  137.  
  138. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  139. BOOL FAR PASCAL EnumWndProc( hWnd, lParam )
  140. HWND hWnd;
  141. LONG lParam;
  142. {
  143.     MSG    Msg;
  144.  
  145.     if ( bSaveFlag ) {
  146.         SaveWindow( hWnd );
  147.     } else {
  148.         ArrangeWindow( hWnd );
  149.     }
  150.  
  151. #ifdef DESKLOAD
  152.     /* Yield control to other applications !!!
  153.      * It slows this applications down so that MS-WINDOWS
  154.      * initial MSDOS.EXE is shown up and DeskLoad can destroy it !
  155.      */
  156.     PeekMessage( (LPMSG)&Msg, hWndDeskSave, 0, 0, PM_NOREMOVE );
  157. #endif
  158.     return(TRUE);
  159. }
  160.  
  161. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  162.  
  163.  
  164. ArrangeDesk()
  165. {
  166.     strcpy( szNameList, "" );
  167.     bInitialMSDOS = FALSE;
  168.     bSaveFlag = FALSE;
  169.     EnumWindows( lpEnumWndProc, 0L );
  170. }
  171.  
  172. ArrangeWindow( hWnd )
  173. HWND hWnd;
  174. {
  175.     RECT    r;
  176.     char    s[40], *sp;
  177.     int    i, nc;
  178.  
  179.     if ( !IsRunable( hWnd ) && !IsIconic( hWnd )) return(FALSE);
  180.  
  181.     GetFileName( hWnd );
  182.  
  183.     /* Check DESKSAVE and WIN*.OVL */
  184.     switch ( NameOK() ) {
  185.     case 0:        /* OK */
  186.         break;
  187.     case 1:        /* DESKSAVE */
  188.         return(1);
  189.     case 2:        /* WIN*.OVL == MSDOS.EXE */
  190.         strcpy( szFileName, "MSDOS.EXE" );
  191.  
  192. #ifdef DESKLOAD
  193.         /* Is this first iconic MSDOS.EXE ? If so, kill that window */
  194.         if ( !bInitialMSDOS && IsIconic( hWnd ) ) {
  195.             bInitialMSDOS = TRUE;
  196.             PostMessage( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L );
  197.             return(1);
  198.         }
  199. #endif
  200.         break;
  201.     }
  202.  
  203.     /* Keyname for iconic applications begins with 'i' */
  204.     if ( IsIconic( hWnd ) ) {
  205.         strcpy( szFileNameKey, "i" );
  206.         strcat( szFileNameKey, szFileName );
  207.     } else {
  208.         strcpy( szFileNameKey, szFileName );
  209.     }
  210.  
  211.     if ( GetProfileString( (LPSTR)szTitle, (LPSTR)szFileNameKey,
  212.             (LPSTR)"", (LPSTR)szKeyList, MAX_LIST_SIZE ) == 0 )
  213.         return(NULL);
  214.  
  215.     /* Has this file been placed before ? */
  216.     nc = GetNameCount( szFileNameKey );
  217.     sp = szKeyList;
  218.     for( i=0 ; i < nc; i++ ) {    /* Search right coordinates */
  219.         char *sp2;
  220.         if ((sp2=strchr( sp, ';' )) == NULL) return(NULL);
  221.         sp = ++sp2;
  222.     }
  223.  
  224.     if (sscanf( sp, "%d %d %d %d",    &r.left, &r.top,
  225.                     &r.right, &r.bottom ) != 4)
  226.         return(NULL);
  227.  
  228.     /* Name and coordinates found. Add name to list */
  229.     strcat( szNameList, szFileNameKey );
  230.     strcat( szNameList, " " );
  231.  
  232.     /* Move window to its position */
  233.     SetWindowPos( hWnd, (HWND)NULL,
  234.             r.left, r.top,
  235.             r.right - r.left,
  236.             r.bottom - r.top,
  237.             SWP_NOACTIVATE | SWP_NOZORDER );
  238.     return(NULL);
  239. }
  240.  
  241.  
  242. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  243.  
  244. /*  These functions save the positions of the windows.
  245.  */
  246.  
  247. SaveDesk()
  248. {
  249.     HWND    hWnd = NULL;
  250.  
  251.     strcpy( szLoadList, "" );
  252.     strcpy( szRunList, "" );
  253.  
  254.     bSaveFlag = TRUE;
  255.     EnumWindows( lpEnumWndProc, 0L );
  256.  
  257.     /* Add loader program to the last of the LOADLIST !*/
  258.     strcat( szLoadList, "DESKLOAD.EXE" );
  259.  
  260.     WriteProfileString((LPSTR)"windows",(LPSTR)"Run", (LPSTR)szRunList );
  261.     WriteProfileString((LPSTR)"windows",(LPSTR)"Load",(LPSTR)szLoadList );
  262. }
  263.  
  264. SaveWindow( hWnd )
  265. HWND hWnd;
  266. {
  267.     if( IsRunable( hWnd ) ) {
  268.         AddRunList( hWnd );
  269.         return(NULL);
  270.     }
  271.  
  272.     if( IsLoadable( hWnd ) ) {
  273.         AddLoadList( hWnd );
  274.         return(NULL);
  275.     }
  276. }
  277.  
  278. AddRunList( hWnd )
  279. HWND hWnd;
  280. {
  281.     RECT    rc;
  282.     char    s[40];
  283.  
  284.     GetFileName( hWnd );
  285.  
  286.     /* Check DESKSAVE and WIN*.OVL */
  287.     switch ( NameOK() ) {
  288.     case 0:        /* OK */
  289.         break;
  290.     case 1:        /* DESKSAVE */
  291.         return(NULL);
  292.     case 2:        /* WIN*.OVL == MSDOS.EXE */
  293.         strcpy( szFileName, "MSDOS.EXE" );
  294.         break;
  295.     }
  296.  
  297.     GetWindowRect( hWnd, (LPRECT)&rc );
  298.     if (strstr( szRunList, szFileName ) != NULL) {
  299.         if ( GetProfileString( (LPSTR)szTitle, (LPSTR)szFileName,
  300.                 (LPSTR)"", (LPSTR)szKeyList,
  301.                 MAX_LIST_SIZE - 30 ) == 0 ) {
  302.             return(FALSE);
  303.         }
  304.         sprintf( s, ";%d %d %d %d",
  305.             rc.left, rc.top, rc.right, rc.bottom);
  306.         strcat( szKeyList, s );
  307.     } else {
  308.         sprintf( szKeyList, "%d %d %d %d",
  309.             rc.left, rc.top, rc.right, rc.bottom);
  310.     }
  311.  
  312.     WriteProfileString( (LPSTR)szTitle, (LPSTR)szFileName, (LPSTR)szKeyList );
  313.  
  314.     strcat( szRunList, szFileName );
  315.     strcat( szRunList, " " );
  316. }
  317.  
  318. AddLoadList( hWnd )
  319. HWND hWnd;
  320. {
  321.     RECT    rc;
  322.     char    s[40];
  323.  
  324.     GetFileName( hWnd );
  325.     strcpy( szFileNameKey, "i" );
  326.     strcat( szFileNameKey, szFileName );
  327.  
  328.     /* Check DESKSAVE and WIN*.OVL */
  329.     switch ( NameOK() ) {
  330.     case 0:        /* OK */
  331.         break;
  332.     case 1:        /* DESKSAVE */
  333.         return(NULL);
  334.     case 2:        /* WIN*.OVL == MSDOS.EXE */
  335.         strcpy( szFileNameKey, "iMSDOS.EXE" );
  336.         strcpy( szFileName, "MSDOS.EXE" );
  337.         break;
  338.     }
  339.  
  340.     GetWindowRect( hWnd, (LPRECT)&rc );
  341.     if (strstr( szLoadList, szFileName ) != NULL) {
  342.         if ( GetProfileString( (LPSTR)szTitle, (LPSTR)szFileNameKey,
  343.                 (LPSTR)"", (LPSTR)szKeyList,
  344.                 MAX_LIST_SIZE - 30 ) == 0 ) {
  345.             return(FALSE);
  346.         }
  347.         sprintf( s, ";%d %d %d %d",
  348.             rc.left, rc.top, rc.right, rc.bottom);
  349.         strcat( szKeyList, s );
  350.     } else {
  351.         sprintf( szKeyList, "%d %d %d %d",
  352.             rc.left, rc.top, rc.right, rc.bottom);
  353.     }
  354.  
  355.     WriteProfileString( (LPSTR)szTitle, (LPSTR)szFileNameKey,
  356.             (LPSTR)szKeyList );
  357.  
  358.     strcat( szLoadList, szFileName );
  359.     strcat( szLoadList, " " );
  360. }
  361.  
  362.  
  363. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  364.  
  365. /*  Tells whether a window can be run, returns TRUE if so.
  366.  *  We will run only top level, resizable windows that are not
  367.  *  minimized and not maximized.
  368.  */
  369.  
  370. BOOL IsRunable( hWnd )
  371. HWND hWnd;
  372. {
  373.     DWORD    dwStyle;
  374.  
  375.     dwStyle = GetWindowLong( hWnd, GWL_STYLE );
  376.     return(
  377.         ! ( dwStyle & ( WS_POPUP | WS_MINIMIZE | WS_MAXIMIZE ) )  &&
  378.           ( dwStyle & WS_VISIBLE )
  379.     );
  380. }
  381.  
  382. /*  Tells whether a window can be load, returns TRUE if so.
  383.  *  We will load only minimized windows.
  384.  */
  385.  
  386. BOOL IsLoadable( hWnd )
  387. HWND hWnd;
  388. {
  389.     DWORD    dwStyle;
  390.  
  391.     dwStyle = GetWindowLong( hWnd, GWL_STYLE );
  392.     return(    ( dwStyle & WS_MINIMIZE )  &&
  393.         ( dwStyle & WS_VISIBLE ) );
  394. }
  395.  
  396. GetFileName( hWnd )
  397. HWND hWnd;
  398. {
  399.     HANDLE    hInst;
  400.     char    s[_MAX_PATH];
  401.     static    char    drive[_MAX_DRIVE],
  402.             dir[_MAX_DIR],
  403.             fname[_MAX_FNAME],
  404.             ext[_MAX_EXT];
  405.  
  406.     hInst = GetWindowWord( hWnd, GWW_HINSTANCE );
  407.     GetModuleFileName( hInst, (LPSTR)s, _MAX_PATH );
  408.     _splitpath( s, drive, dir, fname, ext );
  409.     strcpy( szFileName, fname );
  410.     strcat( szFileName, ext );
  411. }
  412.  
  413. NameOK()
  414. {
  415.     /* Don't save DESKSAVE to list */
  416.     if ( strnicmp( szFileName, szTitle, strlen(szTitle) ) == 0 )
  417.         return 1;
  418.  
  419.     /* Don't save WIN*.OVL */
  420.     if ( strnicmp( szFileName, "WIN", 3 ) == 0 &&
  421.          strnicmp( &szFileName[ strlen(szFileName) - 3], "OVL", 3) == 0 )
  422.         return 2;
  423.  
  424.     return 0;
  425. }
  426.  
  427.  
  428. /* Count occurrences of string s in szNamelist */
  429. GetNameCount( s )
  430. char *s;
  431. {
  432.     int i;
  433.     char *spNames, *sp;
  434.  
  435.     i = 0;
  436.     spNames = szNameList;
  437.     while( (sp=strstr( spNames, s )) != NULL ) {
  438.         spNames = ( sp + strlen( s ) );
  439.         i++;
  440.     }
  441.     return i;
  442. }
  443.  
  444. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  445.  
  446. /*  Application main program.
  447.  */
  448.  
  449. int PASCAL WinMain( hInst, hPrevInst, lpszCmdLine, nCmdShow )
  450. HANDLE    hInst;            /* Our instance handle */
  451. HANDLE    hPrevInst;        /* Previous instance of this application */
  452. LPSTR    lpszCmdLine;        /* Pointer to any command line params */
  453. int     nCmdShow;        /* Parameter to use for first ShowWindow */
  454. {
  455.     MSG     msg;            /* Message structure */
  456.  
  457.     /* Allow only a single instance */
  458.     if( hPrevInst ) {
  459.         MessageBeep( 0 );
  460.         return 0;
  461.     }
  462.  
  463.     /* Save our instance handle in static variable */
  464.     hInstance = hInst;
  465.  
  466.     /* Initialize application, quit if any errors */
  467.     if( ! Initialize() )
  468.         return FALSE;
  469.  
  470. #ifdef DESKLOAD
  471.     ArrangeDesk();
  472.     return 0;
  473. #else
  474.     /* If parameter "-l" arrange desk */
  475.     if (lpszCmdLine[0] == '-' && lpszCmdLine[1] == 'l') {
  476.         ArrangeDesk();
  477.     }
  478.  
  479.     /* Main message processing loop */
  480.     while( GetMessage( &msg, NULL, 0, 0 ) ) {
  481.         TranslateMessage( &msg );
  482.         DispatchMessage( &msg );
  483.     }
  484.  
  485.     return msg.wParam;
  486. #endif
  487. }
  488.  
  489. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  490.  
  491. /*  Initialize DESKSAVE.  Assumes a single instance.
  492.  *  Returns TRUE if initialization succeeded, FALSE if failed.
  493.  */
  494.  
  495. BOOL Initialize()
  496. {
  497.     WNDCLASS Class;            /* Class structure for RegisterClass */
  498.     HMENU    hMenu;            /* Menu handle of system menu */
  499.  
  500.     /* Register our window class */
  501.     Class.style        = 0;
  502.     Class.cbClsExtra    = 0;
  503.     Class.cbWndExtra    = 0;
  504.     Class.lpfnWndProc    = DeskSaveWndProc;
  505.     Class.hInstance        = hInstance;
  506.     Class.hIcon         = LoadIcon( hInstance, szClass );
  507.     Class.hCursor        = LoadCursor( NULL, IDC_ARROW );
  508.     Class.hbrBackground    = COLOR_WINDOW + 1;
  509.     Class.lpszMenuName    = NULL;
  510.     Class.lpszClassName    = szClass;
  511.  
  512.     if( ! RegisterClass( &Class ) )
  513.         return FALSE;
  514.  
  515.     /* Create our window but don't iconize it yet */
  516.     hWndDeskSave = CreateWindow(
  517.             szClass, szTitle,
  518.             WS_OVERLAPPED | WS_SYSMENU,
  519.             CW_USEDEFAULT, 0,
  520.             CW_USEDEFAULT, 0,
  521.             NULL, NULL, hInstance, NULL );
  522.     if( ! hWndDeskSave )
  523.         return FALSE;
  524.  
  525.     lpEnumWndProc = MakeProcInstance( (FARPROC)EnumWndProc, hInstance );
  526.  
  527. #ifndef DESKLOAD
  528.     /* Add our menu items to the System (Control) menu, at the top of
  529.      * the menu, so "Tile Columns" becomes the default choice */
  530.     hMenu = GetSystemMenu( hWndDeskSave, FALSE );
  531.     ChangeMenu( hMenu, 0, NULL, MAXINT, MF_APPEND | MF_SEPARATOR );
  532.     ChangeMenu( hMenu, 0, szSaveDesk, CMD_SAVEDESK, MF_APPEND );
  533.     ChangeMenu( hMenu, 0, szArrDesk, CMD_ARRDESK, MF_APPEND );
  534.     ChangeMenu( hMenu, 0, szClrRun, CMD_CLEAR, MF_APPEND );
  535.     ChangeMenu( hMenu, 0, NULL, MAXINT, MF_APPEND | MF_SEPARATOR );
  536.     ChangeMenu( hMenu, 0, szAbout, CMD_ABOUT, MF_APPEND );
  537.  
  538.     /* Now display our window as an icon */
  539.     ShowWindow( hWndDeskSave, SW_SHOWMINIMIZED );
  540. #endif
  541.     return TRUE;
  542. }
  543.  
  544. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  545. /*  Dialog function for the About box.
  546.  *  Since this is a simple box with only one button, WM_COMMAND is assumed
  547.  *  to be a click on that button (the command number is not checked).
  548.  */
  549.  
  550. BOOL FAR PASCAL AboutBox( hDlg, wMsg, wParam, lParam )
  551. HWND    hDlg;            /* Window handle */
  552. unsigned    wMsg;        /* Message number */
  553. WORD    wParam;         /* Word parameter for the message */
  554. LONG    lParam;         /* Long parameter for the message */
  555. {
  556.     switch( wMsg ) {
  557.     case WM_COMMAND:
  558.         EndDialog( hDlg, TRUE );
  559.         return TRUE;
  560.     }
  561.     return FALSE;
  562. }
  563.