DINSTALL.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:29k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995 Microsoft Corporation.  All Rights Reserved.
  4.  *
  5.  *  File:       dinstall.c
  6.  *  Content:    Game SDK sample setup program
  7.  ***************************************************************************/
  8. #include <stdio.h>      // for sprintf
  9. #include <windows.h>
  10. #include <shellapi.h>   // for SHFileOperation
  11. #include <shlobj.h>     // for SHBroweForFolder
  12. #include "dsetup.h"
  13. #include "dinstall.h"
  14. /*
  15.  * global constants and macros
  16.  */
  17. #define BUFFER_SIZE 512
  18. #define LoadStrFromRes(uID,lpBuffer) 
  19. LoadString (GetModuleHandle(NULL),
  20.             (uID),
  21.             (lpBuffer),
  22.             sizeof((lpBuffer)));
  23. /*
  24.  * list of files that will be copied from the source directory to
  25.  * to the directory the game is created in
  26.  */
  27. static char* copy_list [] =
  28. {
  29.         "ROCKEM3D.EXE",
  30.         "ARENA.X",
  31.         "BLOCK1.WAV",
  32.         "BLOCK2.WAV",
  33.         "BLOCK3.WAV",
  34.         "CBOO.WAV",
  35.         "CLOOP.WAV",
  36.         "CYEAH.WAV",
  37.         "DEBRIS_B.X",
  38.         "DEBRIS_R.X",
  39.         "DEFEND1.WAV",
  40.         "DEFEND2.WAV",
  41.         "DEMECH.X",
  42.         "DEMECHBK.PPM",
  43.         "DEMECHBT.PPM",
  44.         "DEMECHCH.PPM",
  45.         "DEMECHGR.PPM",
  46.         "DEMECHH1.PPM",
  47.         "DEMECHH2.PPM",
  48.         "DEMECHHD.PPM",
  49.         "DEMECHHN.PPM",
  50.         "DEMECHLA.PPM",
  51.         "DEMECHLL.PPM",
  52.         "DEMECHUA.PPM",
  53.         "DEMECHUL.PPM",
  54.         "GDK_FILL.PPM",
  55.         "HEAD.WAV",
  56.         "INTRO.WAV",
  57.         "PUNCH.WAV",
  58.         "PUNCH1.WAV",
  59.         "PUNCH2.WAV",
  60.         "PUNCH3.WAV",
  61.         "PUNCH4.WAV",
  62.         "REVDN1.WAV",
  63.         "REVDN2.WAV",
  64.         "REVDN3.WAV",
  65.         "REVUP1.WAV",
  66.         "REVUP2.WAV",
  67.         "REVUP3.WAV",
  68.         "RANDOM1.WAV",
  69.         "RANDOM2.WAV",
  70.         "RANDOM3.WAV",
  71.         "RANDOM4.WAV",
  72.         "RANDOM5.WAV",
  73.         "RANDOM6.WAV",
  74.         "ROCKEM3D.BIN",
  75.         "ROCKEM3D.MID",
  76.         "ROCKEM3D.PAL",
  77.         "SKMECH.X",
  78.         "SKMECHBK.PPM",
  79.         "SKMECHBT.PPM",
  80.         "SKMECHCH.PPM",
  81.         "SKMECHGR.PPM",
  82.         "SKMECHHN.PPM",
  83.         "SKMECHJD.PPM",
  84.         "SKMECHLA.PPM",
  85.         "SKMECHLL.PPM",
  86.         "SKMECHUA.PPM",
  87.         "SKMECHUL.PPM",
  88.         "SPLASH.PAL",
  89.         "WALK0.WAV",
  90.         "WALK1.WAV",
  91.         "WHOOSH1.WAV",
  92.         "WHOOSH2.WAV",
  93. };
  94. static char       szTitle[BUFFER_SIZE];
  95. /*
  96.  * prototypes
  97.  */
  98. BOOL FAR PASCAL masterDlgProc( HWND hdlg,DWORD message,DWORD wparam,DWORD lparam );
  99. /*
  100.  * globals
  101.  */
  102. static HANDLE   hinst;
  103. static char     GameDirectory[MAX_PATH];    // where the user wants the game
  104. static char     SetupDirectory[MAX_PATH];     // where the user ran setup from
  105. /*
  106.  * support functions
  107.  */
  108. void catpath(char *dst, char *src)
  109. {
  110.         int len = lstrlen(dst);
  111.         if (len > 0 && (dst[len-1] != '\' && dst[len-1] != '/'))
  112.                 lstrcat(dst,"\");
  113.         lstrcat(dst,src);
  114.         // SHFileOperation needs a double null string.
  115.         len = lstrlen(dst);
  116.         dst[len+1] = 0;
  117. }
  118. /*
  119.  * set a bitmap into a static control
  120.  */
  121. void SetBitmap(HWND hDlg, int id, char *szBitmap, int w, int h)
  122. {
  123.         HBITMAP hbm;
  124.         HWND hwnd;
  125.         hwnd = GetDlgItem(hDlg, id);
  126.         if (hwnd == NULL)
  127.                 return;
  128.         hbm = (HBITMAP)LoadImage(hinst, szBitmap, IMAGE_BITMAP, w, h,
  129.                 LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS | LR_CREATEDIBSECTION);
  130.         if (hbm)
  131.                 hbm = (HBITMAP)SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbm);
  132.         if (hbm)
  133.                 DeleteObject(hbm);
  134. }
  135. void SetInfoText(HWND hDlg, char *sz, ...)
  136. {
  137.         char ach[128];
  138.         va_list marker;
  139.         va_start (marker,sz);
  140.         wvsprintf(ach, sz, marker);
  141.         SetDlgItemText(hDlg, IDC_INFO, ach);
  142. }
  143. void _SHFree(void *p)
  144. {
  145.         IMalloc *pm;
  146.         SHGetMalloc(&pm);
  147.         if (pm)
  148.         {
  149.                 pm->lpVtbl->Free(pm,p);
  150.                 pm->lpVtbl->Release(pm);
  151.         }
  152. }
  153. /*
  154.  * build a shortcut in the start menu
  155.  */
  156. void MakeShortcut()
  157. {
  158.         char buf[512];
  159.         char szSetupIni[MAX_PATH];
  160.         char szExeFile[MAX_PATH];
  161.         int len;
  162.         int fh;
  163.         char szGroupName[BUFFER_SIZE];
  164.         char szLinkName[BUFFER_SIZE];
  165.         static char setup_ini[] =
  166.                 "[progman.groups]rn"
  167.                 "groupX=%srn"
  168.                 "[groupX]rn"
  169.                 ""%s","%s",,,,"%s"rn";
  170.         GetWindowsDirectory(szSetupIni, sizeof(szSetupIni));
  171.         catpath(szSetupIni, "SETUP.INI");
  172.         lstrcpy(buf, GameDirectory);
  173.         catpath(buf, copy_list[0]);
  174.         GetShortPathName(buf, szExeFile, sizeof(szExeFile));
  175. //  lstrcpy(buf, GameDirectory);
  176. //  GetShortPathName(buf, szWork, sizeof(szWork));
  177.         LoadStrFromRes( IDS_GROUP_NAME, szGroupName );
  178.         LoadStrFromRes( IDS_LINK_NAME, szLinkName );
  179.         len = wsprintf(buf, setup_ini, szGroupName, szLinkName,
  180.                 szExeFile, GameDirectory);
  181.         fh = _lcreat(szSetupIni, 0);
  182.         if (fh != -1)
  183.         {
  184.                 _lwrite(fh, buf, len);
  185.                 _lclose(fh);
  186.                 WinExec("grpconv -o", SW_HIDE);
  187.         }
  188. }
  189. /*
  190.  * dlg proc for wizard dialog box, the setup is controlled from here.
  191.  */
  192. BOOL FAR PASCAL masterDlgProc(HWND hDlg,DWORD dwMessage,DWORD wParam,DWORD lParam)
  193. {
  194.         int             result;
  195.         static int  system_restart;
  196.         static int      current_dialog;
  197.         static int  busy;
  198.         char        src[MAX_PATH];
  199.         char        dst[MAX_PATH];
  200.         SHFILEOPSTRUCT fileop;
  201.         char       szBuffer[BUFFER_SIZE];
  202.     switch(dwMessage)
  203.     {
  204.     case WM_INITDIALOG:
  205.                 busy = 0;
  206.                 current_dialog = 0;
  207.                 LoadStrFromRes( IDS_TITLE, szTitle );
  208.                 SetWindowText( hDlg, szTitle );
  209.                 EnableWindow( GetDlgItem(hDlg, IDC_B), FALSE );
  210.                 EnableWindow( GetDlgItem(hDlg, IDC_H), FALSE );
  211.                 /*
  212.                  * set the signon bitmap into our static control
  213.                  */
  214.                 LoadStrFromRes( IDS_SIGNON_BITMAP_NAME, szBuffer );
  215.                 SetBitmap( hDlg, IDC_STATIC, szBuffer, 175, 195 );
  216.                 /*
  217.                  * limit the size of the input of this text field to the length of a path
  218.                  * put the default directory to install the game into in it
  219.                  * select the whole thing to make it easy for people to replace it
  220.                  * set the focus to it
  221.                  */
  222.                 SendDlgItemMessage( hDlg, IDC_EDIT, EM_LIMITTEXT, MAX_PATH, 0L);
  223.                 LoadStrFromRes( IDS_DEFAULT_GAME_DIR, szBuffer );
  224.                         SetDlgItemText( hDlg, IDC_EDIT, szBuffer );
  225.                 SendDlgItemMessage( hDlg, IDC_EDIT, EM_SETSEL, 0, MAKELONG(256, 256) );
  226.                         SetFocus( GetDlgItem(hDlg, IDC_EDIT) );
  227.                 /*
  228.                  * return 0 here indicating we have set the focus for the dialog box
  229.                  * and it doesn't need to help us
  230.                  */
  231.                 return 0;
  232.     case WM_SETCURSOR:
  233.         if (busy)
  234.         {
  235.             SetCursor(LoadCursor(NULL, IDC_WAIT));
  236.             return TRUE;
  237.         }
  238.         break;
  239.     case WM_COMMAND:
  240.                 switch(wParam)
  241.                 {
  242.                 case IDOK:
  243.                         if( busy > 0 )
  244.                         {
  245.                                 /*
  246.                                  * busy bit keeps us from taking input while we are off doing
  247.                                  * things that can create other dialog boxes and end up causing
  248.                                  * us to be reentered.
  249.                                  */
  250.                                 break;
  251.                         }
  252.                         else if( current_dialog == 0 )
  253.                         {
  254.                                         int     i;
  255.                                         busy++;
  256.                                         EnableWindow(GetDlgItem(hDlg,IDOK), FALSE);
  257.                                         EnableWindow(GetDlgItem(hDlg,IDCANCEL), FALSE);
  258.                                         SetCursor(LoadCursor(NULL, IDC_WAIT));
  259.                                         /*
  260.                                          * get the directory the user typed
  261.                                          */
  262.                                         GetWindowText( GetDlgItem( hDlg,IDC_EDIT ), GameDirectory, sizeof(GameDirectory));
  263.                                         /*
  264.                                          * verify that the typed in directory is valid
  265.                                          * by having the SHELL copy WIN.INI to this directory
  266.                                          * it will also create the directory for us.
  267.                                          */
  268.                                         LoadStrFromRes( IDS_CREATE_MSG, szBuffer );
  269.                                         SetInfoText(hDlg, szBuffer);
  270.                                         GetWindowsDirectory(src, sizeof(src));
  271.                                         catpath(src,"WIN.INI");
  272.                                         lstrcpy(dst,GameDirectory);
  273.                                         catpath(dst,"SMAG.INI");
  274.                                         fileop.hwnd     = hDlg;
  275.                                         fileop.wFunc    = FO_COPY;
  276.                                         fileop.pFrom    = src;
  277.                                         fileop.pTo      = dst;
  278.                                         fileop.fFlags   = FOF_SILENT | FOF_NOCONFIRMATION;
  279.                                         if (SHFileOperation(&fileop) != 0)
  280.                                         {
  281.                                                 // failed, the shell gave the user a error.
  282.                                                 SetInfoText(hDlg, "");
  283.                                                 EnableWindow(GetDlgItem(hDlg,IDOK), TRUE);
  284.                                                 EnableWindow(GetDlgItem(hDlg,IDCANCEL), TRUE);
  285.                                                 busy--;
  286.                                                 break;
  287.                                         }
  288.                                         /*
  289.                                          * the directory is valid now delete the bogus file
  290.                                          */
  291.                                         fileop.hwnd     = hDlg;
  292.                                         fileop.wFunc    = FO_DELETE;
  293.                                         fileop.pFrom    = dst;
  294.                                         fileop.pTo      = NULL;
  295.                                         fileop.fFlags   = FOF_SILENT | FOF_NOCONFIRMATION;
  296.                                         SHFileOperation(&fileop);
  297.                                         SetInfoText(hDlg, "");
  298.                                         /*
  299.                                          * check if there is enough space to install the game
  300.                                          * NOTE: there is always enough space at the moment :-)
  301.                                          */
  302.                                         LoadStrFromRes( IDS_DISK_MSG, szBuffer );
  303.                                         SetInfoText(hDlg, szBuffer);
  304.                                         if( 0 )
  305.                                         {
  306.                                                 /* your code goes here */
  307.                                         }
  308.                                         SetInfoText(hDlg, "");
  309.                                         /*
  310.                                          * now setup DirectX
  311.                                          */
  312.                                         LoadStrFromRes( IDS_INSTALL_MSG, szBuffer );
  313.                                         SetInfoText(hDlg, szBuffer);
  314.                                         result = DirectXSetup( hDlg, NULL, DSETUP_DIRECTX );
  315.                                         SetInfoText(hDlg, "");
  316.                                         if( result < 0 )
  317.                                         {
  318.                                                 if (result == DSETUPERR_NOTPREINSTALLEDONNT)
  319.                                                 {
  320.                                                         /*
  321.                                                          *  DirectX comes preinstalled on NT, and can only
  322.                                                          *  be installed in an NT release or Service Pack.
  323.                                                          *  If this error code is returned, then the required
  324.                                                          *  version of DirectX is not preinstalled on this
  325.                                                          *  NT machine.  The user will have to go get
  326.                                                          *  the NT version or Service Pack required, or this
  327.                                                          *  game will not run.  Note that any application
  328.                                                          *  can redistribute an NT Service Pack as long as
  329.                                                          *  it is distributed in its entirety.  Check out
  330.                                                          *  ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes
  331.                                                          */
  332.                                                         LoadStrFromRes( IDS_NTFAILED_MSG, szBuffer );
  333.                                                         MessageBox( hDlg, szBuffer, szTitle, 0 );
  334.                                                 }
  335.                                                 else
  336.                                                 {
  337.                                                         LoadStrFromRes( IDS_FAILED_MSG, szBuffer );
  338.                                                         MessageBox( hDlg, szBuffer, szTitle, 0 );
  339.                                                 }
  340.                                                 EndDialog(hDlg, result);
  341.                                                 break;
  342.                                         }
  343.                                         else if( result == 0 )
  344.                                         {
  345.                                                 /*
  346.                                                  *  Check the post-install DirectX Version number,
  347.                                                  *  to check if the game will be able to run.
  348.                                                  *
  349.                                                  *  DirectXSetupGetVersion will get the version
  350.                                                  *  and revision info about the current installation.
  351.                                                  *  Note that since we're calling this after
  352.                                                  *  DirectXSetup, the "current" installation is the
  353.                                                  *  post-install version of DirectX.
  354.                                                  *
  355.                                                  *  Since we don't care about the revision number,
  356.                                                  *  we're leaving that parameter as NULL.
  357.                                                  */
  358.                                                 DWORD dwVersion;
  359.                                                 if( DirectXSetupGetVersion(&dwVersion, NULL) )
  360.                                                 {
  361.                                                         /*  we need DirectX 3.0 or better, so we're going
  362.                                                          *  to make sure that dwVersion is at least equal
  363.                                                          *  to 0x00040003.  If we needed DirectX 5.0
  364.                                                          *  functionality, we'd check for 0x00040005.
  365.                                                          *
  366.                                                          *  If your game needs specific DX functionality,
  367.                                                          *  this is a good place to check to ensure that
  368.                                                          *  the correct version of DirectX is available.
  369.                                                          *
  370.                                                          *  On Windows NT, DirectX is pre-installed, so
  371.                                                          *  this check will allow notification of NT users
  372.                                                          *  that they'll need to update through a service
  373.                                                          *  pack, or they won't be able to run the game.
  374.                                                          */
  375.                                                         if( dwVersion < (DWORD)0x00040003 )
  376.                                                         {
  377.                                                                 sprintf(szBuffer,
  378.                                                                         "Your system is preinstalled with version %d.%d "
  379.                                                                         "of DirectX.  This game requires DirectX version "
  380.                                                                         "4.3 or better to run.nn"
  381.                                                                         "Do you want to install the game anyway?",
  382.                                                                         HIWORD(dwVersion), LOWORD(dwVersion));
  383.                                                                 result = MessageBox( hDlg, szBuffer, szTitle, MB_YESNO);
  384.                                                                 if( result == IDNO )
  385.                                                                 {
  386.                                                                         MessageBox( hDlg,
  387.                                                                         "You've chosen not to install the game.nn"
  388.                                                                         "Click "OK" to end Setup.",
  389.                                                                         szTitle, MB_OK);
  390.                                                                         EndDialog( hDlg, 0 );
  391.                                                                         break;
  392.                                                                 }
  393.                                                         }
  394.                                                 }
  395.                                         }
  396.                                         /*
  397.                                          * check if there is enough space to install the game
  398.                                          * NOTE: there is always enough space at the moment :-)
  399.                                          */
  400.                                         LoadStrFromRes( IDS_DISK_MSG, szBuffer );
  401.                                         SetInfoText(hDlg, szBuffer);
  402.                                         if( 0 )
  403.                                         {
  404.                                                 /* your code goes here */
  405.                                         }
  406.                                         SetInfoText(hDlg, "");
  407.                                         /*
  408.                                          * now copy the files.
  409.                                          */
  410.                                         system_restart = result;
  411.                                         LoadStrFromRes( IDS_COPYING_MSG, szBuffer );
  412.                                         SetInfoText(hDlg, szBuffer);
  413.                                         for( i = 0; i < sizeof( copy_list )/sizeof( copy_list[0] ); i++ )
  414.                                         {
  415.                                                 lstrcpy( src, SetupDirectory );
  416.                                                 catpath( src, copy_list[i] );
  417.                                                 lstrcpy( dst, GameDirectory );
  418.                                                 catpath( dst, copy_list[i] );
  419.                                                 LoadStrFromRes( IDS_CURRENT_FILE_MSG, szBuffer );
  420.                                                 SetInfoText(hDlg, szBuffer, copy_list[i]);
  421.                                                 fileop.hwnd     = hDlg;
  422.                                                 fileop.wFunc    = FO_COPY;
  423.                                                 fileop.pFrom    = src;
  424.                                                 fileop.pTo      = dst;
  425.                                                 fileop.fFlags   = FOF_SILENT | FOF_NOCONFIRMATION;
  426.                                                 while (result = SHFileOperation(&fileop))
  427.                                                 {
  428.                                                         char errorText[MAX_PATH+BUFFER_SIZE];
  429.                                                         LoadStrFromRes( IDS_SETUP_FAILURE_MSG, szBuffer );
  430.                                                         wsprintf(errorText, szBuffer, copy_list[i] );
  431.                                                         result = MessageBox( hDlg, errorText, szTitle, MB_RETRYCANCEL );
  432.                                                         if( result == IDCANCEL )
  433.                                                         {
  434.                                                                 result = -1;
  435.                                                                 break;
  436.                                                         }
  437.                                                 }
  438.                                                 if( result == 0 )
  439.                                                 {
  440.                                                         SetFileAttributes( dst, FILE_ATTRIBUTE_NORMAL );
  441.                                                 }
  442.                                         }
  443.                                         SetInfoText(hDlg, "");
  444.                                         LoadStrFromRes( IDS_STARTUP_MSG, szBuffer );
  445.                                         SetInfoText(hDlg, szBuffer);
  446.                                         MakeShortcut();
  447.                                         SetInfoText(hDlg, "");
  448.                                         if( result >= 0 )
  449.                                         {
  450.                                                 /*
  451.                                                  * hide current controls
  452.                                                  */
  453.                                                 ShowWindow( GetDlgItem(hDlg, IDC_EDIT), SW_HIDE );
  454.                                                 ShowWindow( GetDlgItem(hDlg, IDC_DIRECTIONS1), SW_HIDE );
  455.                                                 ShowWindow( GetDlgItem(hDlg, IDC_DIRECTIONS2), SW_HIDE );
  456.                                                 ShowWindow( GetDlgItem(hDlg, IDC_EDITTEXT), SW_HIDE );
  457.                                                 ShowWindow( GetDlgItem(hDlg, IDC_INFO), SW_HIDE );
  458.                                                 ShowWindow( GetDlgItem(hDlg, IDC_BROWSE), SW_HIDE );
  459.                                                 if( system_restart )
  460.                                                 {
  461.                                                         /*
  462.                                                          * show new dialogs
  463.                                                          */
  464.                                                         ShowWindow( GetDlgItem(hDlg, IDC_REBOOT1), SW_SHOW );
  465.                                                         ShowWindow( GetDlgItem(hDlg, IDC_REBOOT2), SW_SHOW );
  466.                                                         LoadStrFromRes( IDS_REBOOT_BUTTON, szBuffer );
  467.                                                         SetWindowText( GetDlgItem(hDlg, IDOK), szBuffer );
  468.                                                         /*
  469.                                                          * set the reboot bitmap into our static control
  470.                                                          */
  471.                                                         LoadStrFromRes( IDS_REBOOT_BITMAP_NAME, szBuffer );
  472.                                                         SetBitmap(hDlg, IDC_STATIC, szBuffer, 270, 195);
  473.                                                         current_dialog++;
  474.                                                 }
  475.                                                 else
  476.                                                 {
  477.                                                         ShowWindow( GetDlgItem(hDlg, IDC_SUCCESS), SW_SHOW );
  478.                                                         LoadStrFromRes( IDS_FINISH_BUTTON, szBuffer );
  479.                                                         SetWindowText( GetDlgItem(hDlg, IDOK), szBuffer );
  480.                                                         current_dialog++;
  481.                                                         EnableWindow(GetDlgItem(hDlg,IDOK), TRUE);
  482.                                                         busy--;
  483.                                                         break;
  484.                                                 }
  485.                                         }
  486.                                         EnableWindow(GetDlgItem(hDlg,IDOK), TRUE);
  487.                                         EnableWindow(GetDlgItem(hDlg,IDCANCEL), TRUE);
  488.                                         busy--;
  489.                                         if( result < 0 )
  490.                                         {
  491.                                                 EndDialog( hDlg, result );
  492.                                         }
  493.                                 }
  494.                                 else if (current_dialog == 1)
  495.                                 {
  496.                                         /*
  497.                                          * restart windows, kill apps that aren't responding, reboot
  498.                                          */
  499.                                         if( system_restart )
  500.                                         {
  501.                                                 ExitWindowsEx( EWX_REBOOT, 0 );
  502.                                         }
  503.                                         else
  504.                                         {
  505.                                                 EndDialog( hDlg, 0 );
  506.                                         }
  507.                                 }
  508.                                 break;
  509.                         case IDCANCEL:
  510.                                 if( !busy )
  511.                                 {
  512.                                         /*
  513.                                          * only allow cancel if we aren't doing anything else
  514.                                          */
  515.                                         EndDialog( hDlg, -1 );
  516.                                 }
  517.                                 break;
  518.                         case IDC_BROWSE:
  519.                                 if( current_dialog == 0 )
  520.                                 {
  521.                                         BROWSEINFO bi;
  522.                                         LPITEMIDLIST pidl;
  523.                                         char ach[MAX_PATH];
  524.                                         bi.hwndOwner      = hDlg;
  525.                                         bi.pidlRoot       = NULL;
  526.                                         bi.pszDisplayName = ach;
  527.                                         bi.lpszTitle      = NULL;
  528.                                         bi.ulFlags        = BIF_RETURNONLYFSDIRS;
  529.                                         bi.lpfn           = NULL;
  530.                                         bi.lParam         = 0;
  531.                                         bi.iImage         = 0;
  532.                                         pidl = SHBrowseForFolder(&bi);
  533.                                         if (pidl)
  534.                                         {
  535.                                                 SHGetPathFromIDList(pidl, ach);
  536.                                                 SetDlgItemText(hDlg, IDC_EDIT, ach);
  537.                                                 _SHFree(pidl);
  538.                                         }
  539.                                 }
  540.                                 break;
  541.                 }
  542.     }
  543.     return 0;
  544. }
  545. /* **************************************************************** */
  546. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
  547. {
  548.         TCHAR * p;
  549.         TCHAR * x;
  550.         hinst = hInstance;
  551.         /*
  552.          * get our fullpath name and strip the file name
  553.          */
  554.         GetModuleFileName(hInstance, SetupDirectory, sizeof(SetupDirectory));
  555.         for (x=p=SetupDirectory; *p; p=AnsiNext(p))
  556.         {
  557.                 if ((*p == '\') || (*p == '/'))
  558.                         x = p;
  559.         }
  560.         *x = 0;
  561.         /*
  562.          * do the setup thing, it is all one big dialog box that you show
  563.          * and hide things from depending on the screen
  564.          * we just sign on, ask where to install, and install
  565.          */
  566.         DialogBox( hInstance, "DLG_MASTER", NULL, (DLGPROC)masterDlgProc );
  567.         return 0;
  568. } /* WinMain */