home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / INSTALL.ZIP / EXAMPLE.C next >
Text File  |  1989-11-30  |  18KB  |  587 lines

  1.  
  2. #include  "example.h"                               /* Local definitions      */
  3.  
  4.  
  5.  
  6.  
  7. /*
  8.  *              Start of Main function
  9.  */
  10.  
  11.  
  12. int cdecl main(VOID){
  13.  
  14.     HMQ   hmq;                        /* Message queue handle   */
  15.     QMSG  qmsg;                     /* Message data structure */
  16.     ULONG lCreate;                    /* Frame creation flags   */
  17.     SHORT cxScreen, cyScreen;                /* Screen size variables  */
  18.  
  19.     DosError(0);
  20.  
  21.     vhab  =  WinInitialize(NULL);            /* Create anchor handle   */
  22.  
  23.     hmq  =  WinCreateMsgQueue(vhab, 0);         /* Create message queue   */
  24.  
  25.     /* Register window class and procedure   */
  26.     WinRegisterClass(vhab,
  27.              vszClass,
  28.              StatusWndProc,
  29.              CS_SYNCPAINT,
  30.              0);
  31.  
  32.     lCreate = FCF_TITLEBAR |  FCF_BORDER;        /* Frame creation flags   */
  33.  
  34.     /* Create a standard main window with a title bar and border.  */
  35.     vhwndFrame = WinCreateStdWindow( HWND_DESKTOP,
  36.                     0L,
  37.                     &lCreate,        /* Pointer to flags       */
  38.                     vszClass,        /* Class name          */
  39.                     vszTitle,        /* Window's Title         */
  40.                     0L,
  41.                     NULL,
  42.                     0L,
  43.                     &vhwndClient    /* Client handle pointer  */
  44.                     );
  45.  
  46.     /* Query the vertical and horizontal screen size */
  47.     cxScreen = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  48.     cyScreen = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  49.  
  50.     /* Size and position the status information window     */
  51.     WinSetWindowPos(
  52.             (HWND)vhwndFrame,
  53.             (HWND)HWND_TOP,
  54.             cxScreen / 4,
  55.             cyScreen / 2,
  56.             cxScreen / 2,
  57.             cyScreen / 4,
  58.             SWP_ACTIVATE | SWP_SIZE |
  59.             SWP_MOVE | SWP_HIDE
  60.             );
  61.  
  62.     /* Start of main message loop */
  63.     while (WinGetMsg(vhab, &qmsg, NULL, 0, 0))
  64.               WinDispatchMsg(vhab, &qmsg);
  65.  
  66.     /* Termination and clean up */
  67.     WinDestroyWindow(vhwndFrame);
  68.     WinDestroyMsgQueue(hmq);
  69.     WinTerminate(vhab);
  70.     return 0;
  71. }
  72.  
  73.  
  74. /*
  75.  *    Start of status information window procedure.
  76.  */
  77.  
  78.  
  79. MRESULT EXPENTRY StatusWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2){
  80.  
  81.     static SHORT  cyDspPos,              /* Status display variable  */
  82.           cxCharWidth;              /* Character width variable */
  83.     FONTMETRICS   fm;                  /* Font metrics structure   */
  84.     HPS       hps;                  /* Presentation space handle*/
  85.     POINTL      ptl;                  /* Point structure          */
  86.  
  87.     switch(msg){
  88.  
  89.        case WM_SIZE:
  90.         cyDspPos = SHORT2FROMMP(mp2) / 4;      /* Get client window size.  */
  91.         return 0;
  92.  
  93.  
  94.        case WM_CREATE:
  95.         hps = WinGetPS(hwnd);
  96.  
  97.         /* Query current font information.    */
  98.         GpiQueryFontMetrics(hps, (LONG)sizeof(fm), &fm);
  99.  
  100.         /* Determine the average charactor width for this font. */
  101.         cxCharWidth = (SHORT)fm.lAveCharWidth;
  102.         WinReleasePS(hps);
  103.  
  104.         /* Start the installation */
  105.         WinPostMsg(hwnd, WM_INSTALL, NULL, NULL);
  106.         return 0;
  107.  
  108.  
  109.  
  110.        case WM_PAINT:
  111.         hps = WinBeginPaint(hwnd, NULL, NULL);
  112.  
  113.         GpiErase(hps);              /* Clear the client window. */
  114.         ptl.y = cyDspPos * 3;          /* Point at display position*/
  115.         ptl.x = cxCharWidth * 10;          /* Set line starting point. */
  116.  
  117.         /* Display type of operation  line. */
  118.         GpiCharStringAt(hps, &ptl,28L , "Installing Program and Files");
  119.  
  120.         ptl.y = cyDspPos * 2;          /* Point at display position*/
  121.         ptl.x = cxCharWidth * 3;          /* Set line starting point. */
  122.  
  123.         /* Display the first status line. */
  124.         GpiCharStringAt(hps, &ptl, 5L , "From:");
  125.  
  126.         ptl.x = cxCharWidth * 12;          /* Set new line position.   */
  127.         GpiCharStringAt(hps, &ptl, (LONG)strlen(vszCopyFrom),
  128.                                 vszCopyFrom);
  129.  
  130.         ptl.y = cyDspPos ;             /* Point at display position.*/
  131.         ptl.x = cxCharWidth * 3;         /* Set line starting point.  */
  132.  
  133.         /* Display the second status line. */
  134.         GpiCharStringAt(hps, &ptl, 3L, "To:");
  135.  
  136.         ptl.x = cxCharWidth * 12;         /* Set new line position.    */
  137.         GpiCharStringAt(hps, &ptl, (LONG)strlen(vszCopyTo), vszCopyTo);
  138.         WinEndPaint(hps);
  139.         return 0;
  140.  
  141.        case WM_INSTALL:
  142.  
  143.         /* Start installation by creating a Directory    */
  144.         WinDlgBox( HWND_DESKTOP  ,
  145.                vhwndFrame    ,
  146.                CrtDirDlgProc ,
  147.                NULL         ,
  148.                IDDLG_CRTDIR  ,
  149.                NULL);
  150.         return 0;
  151.  
  152.        default:
  153.         return WinDefWindowProc(hwnd, msg, mp1, mp2);
  154.     }
  155. }
  156.  
  157.  
  158.  
  159. /*
  160.  *   ControlThread function runs as an independant thread. By running on it's
  161.  *   own thread of execution, long copy operations may then be started without
  162.  *   violation of the 1/10 second rule.
  163.  */
  164.  
  165.  
  166. VOID ControlThread(VOID){
  167.  
  168.     HPROGRAM hGroup;                    /* Group handle          */
  169.     SHORT    i = 0;                    /* Array index variable   */
  170.     SHORT    rc;                    /* Return code variable   */
  171.     HAB      hab;                    /* Anchor bar handle      */
  172.     HMQ      hmq;                    /* Message queue handle   */
  173.  
  174.  
  175.     hab  =  WinInitialize(NULL);            /* Create anchor handle   */
  176.     hmq = WinCreateMsgQueue(hab, 0);            /* Create message queue   */
  177.  
  178.  
  179.  
  180.  
  181.     /* Start of the copy loop. */
  182.  
  183.        do{
  184.  
  185.       /* Update the copy status line information for display   */
  186.       /* in the status window's client area.                   */
  187.  
  188.          strcpy(vszCopyFrom,vszCmdData[i]);     /* Copy from information  */
  189.          strcpy(vszCopyTo,vszProgInfo[4]);
  190.          strcat(vszCopyTo,vszCmdData[i+1]);     /* Copy to information    */
  191.  
  192.       /* Generate a WM_PAINT message to update the copy status.*/
  193.          WinInvalidateRect(vhwndClient, NULL,FALSE);
  194.  
  195. #ifdef PMREL1_1                     /* Using OS/2 1.1 toolkit */
  196.  
  197.       /* Call a local function to handle the copying of the    */
  198.       /* program and files.                    */
  199.  
  200.          rc = CopyFile(vszCopyFrom,vszCopyTo);
  201. #else
  202.       /* When using the OS/2 1.2 toolkit call the DosCopy       */
  203.       /* OS/2 function.  The DCPY_EXISTING parameter means       */
  204.       /* if target exists replace it               */
  205.  
  206.          rc = DosCopy(vszCopyFrom,vszCopyTo, DCPY_EXISTING, 0L);
  207.  
  208. #endif /* PMREL1_1 */
  209.  
  210.       /* In this example, we are only checking for diskette    */
  211.       /* not ready. On a not ready condition we will display   */
  212.       /* a message with retry. All other copy errors will       */
  213.       /* display a generic message with cancel only option.    */
  214.  
  215.          if (rc)
  216.           if(rc == ERROR_NOT_READY)
  217.             rc = DisplayMsg( MSG005, MB_RETRYCANCEL | MB_ICONHAND);
  218.           else
  219.             rc = DisplayMsg( MSG002, MB_CANCEL | MB_ICONHAND);
  220.           else
  221.           i+=2;
  222.  
  223.        }while((i < BUFFSIZE) && (rc == 0 || rc == MBID_RETRY));
  224.  
  225.        /* Continue the installation if program and files were  */
  226.        /* copied without error.                   */
  227.  
  228.        if(!rc){
  229.  
  230.        /* Create the "Example" group.   WinCreateGroup will    */
  231.        /* return an existing group handle or create a new one  */
  232.        /* if it doesn't exist.                                 */
  233.  
  234.          hGroup = WinCreateGroup(vhab,  vszProgInfo[0],
  235.                               SHE_VISIBLE, 0L, 0L);
  236.  
  237.          if (hGroup){
  238.  
  239.        /* Calling  a local function "AddProgram"  to add       */
  240.        /* programinformation to our new group.           */
  241.  
  242.          rc = AddProgram( vszProgInfo[1], vszCopyTo,
  243.                       vszProgInfo[3] , vszProgInfo[4], hGroup);
  244.  
  245.        /* In this example, we are only checking for duplicate  */
  246.        /* program titles in the group. Any other error return  */
  247.        /* code will display a generic message.           */
  248.  
  249.          if(rc)
  250.              if(rc == PMERR_DUPLICATE_TITLE)
  251.               DisplayMsg(  MSG006, MB_CANCEL | MB_ICONHAND);
  252.              else
  253.               DisplayMsg(  MSG004, MB_CANCEL | MB_ICONHAND);
  254.  
  255.          else{
  256.  
  257.              /* Hide the status window */
  258.              WinShowWindow(vhwndFrame, FALSE);
  259.  
  260.              /* If we are here, the installation completed  */
  261.              /* without error. Display a message to tell    */
  262.              /* the user.                    */
  263.  
  264.              DisplayMsg(  MSG007, MB_OK | MB_ICONASTERISK);
  265.          }
  266.  
  267.          }else
  268.          /* Group creation error message. */
  269.          DisplayMsg(  MSG003, MB_CANCEL | MB_ICONHAND);
  270.  
  271.        }
  272.  
  273.     /* Post a WM_QUIT message to the message queue to end the  */
  274.     /* installation program.                       */
  275.     WinPostMsg( vhwndClient, WM_QUIT, NULL, NULL );
  276.  
  277.  
  278.     /* Termination and clean up */
  279.     WinDestroyMsgQueue( hmq );                /* Destroy message queue  */
  280.     WinTerminate(hab);                    /* Destroy handle          */
  281.     DosExit( EXIT_THREAD, 0 );                /* End thread execution.  */
  282. }
  283.  
  284.  
  285. /*
  286.  *   CopyFile function is only needed if using OS/2 release 1.1 toolkit. Since
  287.  *   OS/2 has provided the DosCopy function for release 1.2, this function will
  288.  *   no longer be needed.
  289.  */
  290.  
  291.  
  292. BOOL CopyFile(PSZ pszSrc, PSZ pszTarget){
  293.  
  294.     #define WORKBUFFER    4096              /* Copy data buffer          */
  295.  
  296.     HFILE   hSrcfile ;                  /* Source file handle       */
  297.     HFILE   hTargetfile ;              /* Target file handle       */
  298.     USHORT  uAction ;                  /* Open action information  */
  299.     USHORT  rc ;                  /* Return code          */
  300.     USHORT  cbytesRead ;              /* Count of bytes read      */
  301.     USHORT  cbWritten ;               /* Count of bytes written   */
  302.     FILESTATUS fStatus ;              /* File Status buffer       */
  303.     SEL selAddress ;                  /* Alloc. segment selector  */
  304.  
  305.     /* Opening the source file, read only, none share.        */
  306.     if(!(rc = DosOpen(pszSrc, &hSrcfile, &uAction, 0L, 0,
  307.                             0x0001, 0x20A0, 0L))){
  308.  
  309.        /* Get source file information creation date, time, etc...  */
  310.        DosQFileInfo(hSrcfile, 1, (PBYTE)&fStatus, sizeof(FILESTATUS));
  311.  
  312.        /* Opening target file replace or create mode none share.   */
  313.        if (!(rc = DosOpen(pszTarget, &hTargetfile, &uAction,
  314.              fStatus.cbFile, fStatus.attrFile, 0x0012, 0x2091, 0L))){
  315.  
  316.       /* Allocate copy buffer space.               */
  317.       if (!(rc = DosAllocSeg(WORKBUFFER, &selAddress, 0))){
  318.  
  319.          /* Start copy file to file loop.               */
  320.          do{
  321.  
  322.         /* Reading a buffer of data from source file.        */
  323.         rc = DosRead(hSrcfile, MAKEP(selAddress,0),
  324.                                WORKBUFFER, &cbytesRead);
  325.  
  326.         /* Write the buffer to the target file.         */
  327.         if(!rc)
  328.            rc = DosWrite(hTargetfile, MAKEP(selAddress,0),
  329.                                cbytesRead, &cbWritten);
  330.  
  331.  
  332.          }while (cbytesRead && rc == 0);
  333.  
  334.          /* Check if any error occured during the copy operation.*/
  335.  
  336.          if (rc)
  337.  
  338.          /* The copy operation failed. Remove the incomplete    */
  339.          /* target file.                        */
  340.  
  341.         DosDelete(pszTarget, 0L);
  342.          else
  343.  
  344.          /* The copy operation was successful. Change the target */
  345.          /* file's status information, creation date, time, to   */
  346.          /* match the source file's.                             */
  347.  
  348.         DosSetFileInfo(hTargetfile, 1, (PBYTE)&fStatus,
  349.                                sizeof(FILESTATUS)) ;
  350.  
  351.          DosClose(hTargetfile);          /* Close the target file    */
  352.          DosFreeSeg(selAddress);          /* Free copy buffer space   */
  353.       }
  354.        }
  355.        DosClose(hSrcfile);              /* Close the source file    */
  356.     }
  357.  
  358.     /* Return a completion code to the calling function.       */
  359.     return(rc);
  360. }
  361.  
  362.  
  363. /*
  364.  *   AddProgram function adds program information to a group. The
  365.  *   function adds a title, program name and path, any parameters,
  366.  *   and working directory information.
  367.  */
  368.  
  369.  
  370. SHORT AddProgram( PSZ pszTitle, PSZ pszNamePath, PCH pszParameters,
  371.                    PSZ pszWorkDir, HPROGRAM hGroup){
  372.  
  373.     PIBSTRUCT  pib;                  /* Program information block*/
  374.     HPROGRAM   hprog;                  /* Program handle          */
  375.  
  376.     pib.pchProgramParameter = pszParameters;      /* Program's parameters     */
  377.     pib.cchProgramParameter = strlen(pszParameters)+1;
  378.  
  379.     pib.pchEnvironmentVars = NULL;          /* No environment string    */
  380.     pib.cchEnvironmentVars = 0;
  381.     pib.progt.progc = PROG_PM;              /* Installing a PM program. */
  382.     pib.progt.fbVisible = SHE_VISIBLE;          /* Make entry visible.      */
  383.     pib.szIconFileName[0] = NULL;          /* Use default program icon.*/
  384.     pib.xywinInitial.x = 0;              /* Default window position  */
  385.     pib.xywinInitial.y = 0;              /* and size.              */
  386.     pib.xywinInitial.cx = 0;
  387.     pib.xywinInitial.cy = 0;
  388.     pib.xywinInitial.fsWindow = XYF_NORMAL;      /* Normal visible window.   */
  389.     pib.res1 = 0;                  /* Reserved must be zero.   */
  390.     pib.res2 = 0;                  /* Reserved must be zero.   */
  391.  
  392.     strcpy(pib.szTitle, pszTitle);          /* Program title.          */
  393.     strcpy(pib.szExecutable, pszNamePath);      /* Executable's name/path.  */
  394.     strcpy(pib.szStartupDir, pszWorkDir);      /* Current directory.       */
  395.  
  396.     /* Add the new program entry. */
  397.     hprog = WinAddProgram(vhab, (PPIBSTRUCT)&pib, hGroup);
  398.  
  399.     if (hprog == NULL)
  400.  
  401.        /* On an error, return the error code. */
  402.        return ((SHORT)WinGetLastError(vhab));
  403.     else
  404.        return 0;                  /* Completed without error. */
  405. }
  406.  
  407.  
  408. /*
  409.  *    DisplayMsg controls all message display. The function uses the
  410.  *    passed message ID to find and display the requested message.
  411.  *    DisplayMsg returns the user's message response to the calling
  412.  *    procedure.
  413.  */
  414.  
  415.  
  416. USHORT    DisplayMsg(  USHORT msgid, SHORT style){
  417.  
  418.     CHAR     szMsgStr[MAXMSGSIZE];         /* Message string buffer.    */
  419.  
  420.     /* Load message buffer with message text.  */
  421.     WinLoadString(vhab, NULL, msgid, sizeof szMsgStr, szMsgStr) ;
  422.  
  423.  
  424.     /* Display message and return response to calling procedure. */
  425.     return(WinMessageBox(HWND_DESKTOP, vhwndClient, szMsgStr,
  426.             (PSZ)vszTitle, NULL, style | MB_HELP |
  427.                           MB_MOVEABLE ));
  428.  
  429. }
  430.  
  431.  
  432. /*
  433.  *   CrtDirDlgProc is the window procedure for the create directory dialog
  434.  *   box. This is a example of using a dialog box to give experienced users
  435.  *   the option to change the installation defaults.
  436.  */
  437.  
  438.  
  439. MRESULT APIENTRY CrtDirDlgProc(HWND hdlg, USHORT msg,
  440.                       MPARAM MParam1, MPARAM MParam2){
  441.  
  442.     SHORT    cch;                   /*  String char. count     */
  443.     SHORT    rc;                   /*  Return code variable   */
  444.     SHORT   idThread;                   /*  Thread ID variable     */
  445.  
  446.     switch (msg) {
  447.  
  448.     case WM_INITDLG:
  449.  
  450.     /* Remove greyed System menu items */
  451.     RemoveSysItems(hdlg);
  452.  
  453.     /* Set the dialog box input field size limit. */
  454.     WinSendDlgItemMsg(hdlg, IDC_DIRPATH, EM_SETTEXTLIMIT,
  455.               MPFROMSHORT(MAXSTRSIZE), 0L);
  456.  
  457.     /* Display default directory path in input field. */
  458.     WinSetWindowText(WinWindowFromID(hdlg, IDC_DIRPATH), vszProgInfo[4]);
  459.  
  460.     break;    /* End WM_INITDLG */
  461.  
  462.     case WM_COMMAND:
  463.     switch (LOUSHORT(MParam1)) {
  464.  
  465.     case IDC_OK:
  466.  
  467.         /* Query the input field for the size of the path string. */
  468.         cch = WinQueryWindowTextLength( WinWindowFromID( hdlg
  469.                       , IDC_DIRPATH));
  470.  
  471.         /* Read the new path string */
  472.         WinQueryWindowText( WinWindowFromID( hdlg, IDC_DIRPATH)
  473.                   , cch + 1, vszProgInfo[4] );
  474.  
  475.         /* Convert path string to upper case */
  476.         strupr(vszProgInfo[4]);
  477.  
  478.              /* Create directory  */
  479.         rc = DosMkDir((PSZ)vszProgInfo[4], (ULONG)0);
  480.  
  481.  
  482.      /* Check if directory creation completed without error.  If the */
  483.      /* directory already existed before the call, OS/2 will return  */
  484.      /* an ERROR_ACCESS_DENIED code.   In this case we aren't        */
  485.      /* considering this as an error.                 */
  486.  
  487.         if ( (rc == 0) || (rc == ERROR_ACCESS_DENIED ) ){
  488.  
  489.            /* Start the installation copy thread running. */
  490.         DosCreateThread( ControlThread, &idThread,
  491.                        (PBYTE)&vStack[STACK_SIZE-2] );
  492.  
  493.         /* Show the status window */
  494.         WinShowWindow(vhwndFrame, TRUE);
  495.  
  496.         /* Remove the dialog window. */
  497.         WinDismissDlg( hdlg, TRUE );
  498.         }else{
  499.  
  500.            /* We got an error creating the directory.  */
  501.            /* Display a message to tell the user.       */
  502.         if(rc == ERROR_PATH_NOT_FOUND)
  503.  
  504.            rc = DisplayMsg(  MSG009, MB_RETRYCANCEL | MB_ICONHAND);
  505.         else
  506.            rc = DisplayMsg(  MSG001, MB_CANCEL | MB_ICONHAND);
  507.  
  508.  
  509.         if(rc == MBID_CANCEL){
  510.  
  511.            /* Post a WM_QUIT message to the message queue to end the  */
  512.            /* installation program.                      */
  513.             WinPostMsg( vhwndClient, WM_QUIT, NULL, NULL );
  514.  
  515.            /* Remove the dialog window. */
  516.             WinDismissDlg( hdlg, FALSE );
  517.  
  518.          }else
  519.  
  520.             /* Set focus on input field and let the user try again.*/
  521.              WinSetFocus(HWND_DESKTOP, WinWindowFromID(hdlg,
  522.                                  IDC_DIRPATH));
  523.         }
  524.         break;   /* End IDC_OK Case */
  525.  
  526.     case IDC_CANCEL:
  527.  
  528.         /* The user has clicked on the cancel button. Display a  */
  529.         /* terminate confirmation message.                 */
  530.  
  531.         switch( DisplayMsg( MSG008, MB_YESNO | MB_ICONQUESTION )){
  532.  
  533.           case MBID_YES:
  534.  
  535.              /* Remove dialog box and terminate the program. */
  536.               WinDismissDlg( hdlg, FALSE );
  537.               WinPostMsg( vhwndClient, WM_QUIT, NULL, NULL );
  538.               break;
  539.  
  540.           case MBID_NO:
  541.  
  542.             /* Set focus on input field and let the user try again.*/
  543.           WinSetFocus(HWND_DESKTOP, WinWindowFromID(hdlg,
  544.                                  IDC_DIRPATH));
  545.         }
  546.         break;  /* End IDC_CANCEL Case */
  547.  
  548.     }
  549.     break; /* End WM_COMMAND Case */
  550.  
  551.     default:
  552.     return WinDefDlgProc(hdlg, msg, MParam1, MParam2);
  553.     break;
  554.     }
  555.  
  556.     return 0L;
  557. }
  558.  
  559. /*
  560.  *   Since our dialog box can't be resized, minimized, maximized, or restored,
  561.  *   RemoveSysItems deletes these greyed items from the System menu. This is
  562.  *   in conformation with CUA.
  563.  */
  564.  
  565.  
  566. VOID RemoveSysItems(HWND hdlg){
  567.  
  568. #define ITEMS 4
  569. SHORT i;
  570. HWND  hSysMenu;                    /* System menu's handle    */
  571. static SHORT items[] =                   /* Items to remove          */
  572.                {
  573.               SC_RESTORE  ,
  574.               SC_SIZE     ,
  575.               SC_MINIMIZE ,
  576.               SC_MAXIMIZE
  577.             };
  578.  
  579.     /* Get the handle of the dialog's system menu. */
  580.     hSysMenu = WinWindowFromID(hdlg, FID_SYSMENU);
  581.  
  582.     /* Send messages to system menu to delete the items. */
  583.     for(i = 0; i < ITEMS; ++i)
  584.     WinSendMsg(hSysMenu, MM_DELETEITEM, MPFROM2SHORT(items[i],
  585.                                 TRUE), NULL);
  586. }
  587.