home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / MSWSRC35 / SETUP / SETUPDLG.CPP < prev    next >
C/C++ Source or Header  |  1993-08-20  |  20KB  |  648 lines

  1. /*****************************************************************
  2. Module name: SetupDlg.C
  3. Programmer : Jeffrey M. Richter.
  4. *****************************************************************/
  5.  
  6. #include <windows.h>
  7. #include <windowsx.h>
  8. #include <Ver.h>
  9. #include <StdLib.h>
  10. #include "Meter.H"
  11. #include "Setup.h"
  12. #include "SetupInf.h"
  13.  
  14. void PrepareDialogBox (HWND hWnd, BOOL fBeep) {
  15.    RECT rc; char szBuf[MAXAPPNAME];
  16.    GetWindowRect(hWnd, &rc);
  17.    SetWindowPos(hWnd, NULL,
  18.       (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
  19.       (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
  20.       0, 0, SWP_NOSIZE | SWP_NOZORDER);
  21.  
  22.    // Place the correct title in the dialog box caption
  23.    _SetupInfo.GetAppName(szBuf);
  24.    SetWindowText(hWnd, szBuf);
  25.    if (fBeep) MessageBeep(0);
  26. }
  27.  
  28.  
  29. WORD WINAPI GetCheckedRadioBtn (HWND hDlg, WORD wStartId,
  30.    WORD wEndId) {
  31.    for (; wStartId <= wEndId; wStartId++) {
  32.       if (IsDlgButtonChecked(hDlg, wStartId)) return(wStartId);
  33.    }
  34.    return(-1);
  35. }
  36.  
  37. // ***************************************************************
  38. // Setup's initializing screen.
  39. #pragma argsused
  40. BOOL CALLBACK InitDlgProc (HWND hDlg, UINT uMsg,
  41.    WPARAM wParam, LPARAM lParam) {
  42.  
  43.    BOOL fProcessed = TRUE;
  44.  
  45.    switch (uMsg) {
  46.       case WM_INITDIALOG:
  47.          PrepareDialogBox(hDlg, FALSE);
  48.          UpdateWindow(hDlg);
  49.          break;
  50.  
  51.       default:
  52.          fProcessed = FALSE;
  53.          break;
  54.    }
  55.    return(fProcessed);
  56. }
  57.  
  58.  
  59. // ***************************************************************
  60. // Initial sign on screen.  Asks user for destination directory.
  61. BOOL CALLBACK WelcomeDlgProc (HWND hDlg, UINT uMsg,
  62.    WPARAM wParam, LPARAM lParam) {
  63.  
  64.    BOOL fProcessed = TRUE;
  65.    char szBuf[MAXDIR];
  66.    OFSTRUCT ofStruct;
  67.  
  68.    switch (uMsg) {
  69.       case WM_INITDIALOG:
  70.          PrepareDialogBox(hDlg, FALSE);
  71.  
  72.          _SetupInfo.GetDefaultDstDir(szBuf);
  73.          SetDlgItemText(hDlg, ID_DESTPATH, szBuf);
  74.          Edit_LimitText(GetDlgItem(hDlg, ID_DESTPATH),
  75.             sizeof(szBuf));
  76.          break;
  77.  
  78.       case WM_COMMAND:
  79.          switch (wParam) {
  80.             case ID_DESTPATH:
  81.                EnableWindow(GetDlgItem(hDlg, IDOK),
  82.                   Edit_LineLength(LOWORD(lParam), 0) > 0);
  83.                break;
  84.  
  85.             case IDOK:
  86.                GetDlgItemText(hDlg, ID_DESTPATH,
  87.                   szBuf, sizeof(szBuf));
  88.                OpenFile(szBuf, &ofStruct, OF_PARSE);
  89.                lstrcpy(_szDstDir, (LPSTR) ofStruct.szPathName);
  90.                // Do IDCANCEL case
  91.  
  92.             case IDCANCEL:
  93.                EndDialog(hDlg, wParam);
  94.                break;
  95.          }
  96.          break;
  97.  
  98.       default:
  99.          fProcessed = FALSE;
  100.          break;
  101.    }
  102.    return(fProcessed);
  103. }
  104.  
  105.  
  106. // ***************************************************************
  107. // Displays copying status.  Allows user to cancel Setup.
  108. #pragma argsused
  109. BOOL CALLBACK StatusDlgProc (HWND hDlg, UINT uMsg,
  110.    WPARAM wParam, LPARAM lParam) {
  111.  
  112.    BOOL fProcessed = TRUE;
  113.    int nResult;
  114.  
  115.    switch (uMsg) {
  116.       case WM_INITDIALOG:
  117.          PrepareDialogBox(hDlg, FALSE);
  118.          break;
  119.  
  120.       case WM_SHOWWINDOW:
  121.          fProcessed = FALSE;
  122.          if (!wParam) break;
  123.          EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
  124.          SetDlgItemText(hDlg, ID_STATLINE1, "");
  125.          SetDlgItemText(hDlg, ID_STATLINE2, "");
  126.          SendDlgItemMessage(hDlg, ID_METER,
  127.             MM_SETPARTSCOMPLETE, 0, 0);
  128.          SendDlgItemMessage(hDlg, ID_METER,
  129.             MM_SETPARTSINJOB, 0, 0);
  130.          break;
  131.  
  132.       case WM_COMMAND:
  133.          switch (wParam) {
  134.             case IDOK:
  135.                // User presses ENTER.  DO IDCANCEL case.
  136.  
  137.             case IDCANCEL:
  138.                nResult = MsgBox(_hInstance, hDlg, IDS_QUERYABORT,
  139.                   _szAppName, MB_ICONQUESTION | MB_YESNO);
  140.                if (nResult == IDYES)
  141.                   EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
  142.                break;
  143.          }
  144.          break;
  145.  
  146.       default:
  147.          fProcessed = FALSE;
  148.          break;
  149.    }
  150.    return(fProcessed);
  151. }
  152.  
  153. // ***************************************************************
  154. // Prompt's user to insert a different diskette.
  155. BOOL CALLBACK InsertDiskDlgProc (HWND hDlg, UINT uMsg,
  156.    WPARAM wParam, LPARAM lParam) {
  157.  
  158.    BOOL fProcessed = TRUE;
  159.    int nResult;
  160.  
  161.    switch (uMsg) {
  162.       case WM_INITDIALOG:
  163.          PrepareDialogBox(hDlg, TRUE);
  164.  
  165.          // lParam is address of diskette description.
  166.          // Throw away the data segment and use the new one.
  167.          // This is in case the data segment has moved.
  168.          SetDlgItemText(hDlg, ID_DISKNAME, (LPSTR) lParam);
  169.          SetDlgItemText(hDlg, ID_SRCPATH, _szSrcDir);
  170.          Edit_LimitText(GetDlgItem(hDlg, ID_SRCPATH),
  171.             sizeof(_szSrcDir));
  172.          break;
  173.  
  174.       case WM_COMMAND:
  175.          switch (wParam) {
  176.             case ID_SRCPATH:
  177.                EnableWindow(GetDlgItem(hDlg, IDOK),
  178.                   Edit_LineLength(LOWORD(lParam), 0) > 0);
  179.                break;
  180.  
  181.             case IDOK:
  182.                GetDlgItemText(hDlg, ID_SRCPATH,
  183.                   _szSrcDir, sizeof(_szSrcDir));
  184.                EndDialog(hDlg, wParam);
  185.                break;
  186.  
  187.             case IDCANCEL:
  188.                nResult = MsgBox(_hInstance, hDlg, IDS_QUERYABORT,
  189.                   _szAppName, MB_ICONQUESTION | MB_YESNO);
  190.                if (nResult == IDNO) break;
  191.                EndDialog(hDlg, wParam);
  192.                break;
  193.          }
  194.          break;
  195.  
  196.       default:
  197.          fProcessed = FALSE;
  198.          break;
  199.    }
  200.    return(fProcessed);
  201. }
  202.  
  203.  
  204. // ***************************************************************
  205. BOOL CALLBACK CurNEDestDlgProc (HWND hDlg, UINT uMsg,
  206.    WPARAM wParam, LPARAM lParam) {
  207.  
  208.    BOOL fProcessed = TRUE;
  209.    LPCURNEDESTSTRUCT lpCurNEDestStruct;
  210.    UINT x;
  211.    int nResult;
  212.  
  213.    switch (uMsg) {
  214.       case WM_INITDIALOG:
  215.          PrepareDialogBox(hDlg, TRUE);
  216.  
  217.          lpCurNEDestStruct = (LPCURNEDESTSTRUCT) lParam;
  218.          SetDlgItemText(hDlg, ID_DSTFILENAME,
  219.             lpCurNEDestStruct->szDstFileName);
  220.          SetDlgItemText(hDlg, ID_DSTDIR,
  221.             lpCurNEDestStruct->szDstDir);
  222.          SetDlgItemText(hDlg, ID_CURDIR,
  223.             lpCurNEDestStruct->szCurDir);
  224.          CheckRadioButton(hDlg, ID_INSTALLANDDELETE,
  225.             ID_ABORTINSTALL, ID_INSTALLANDDELETE);
  226.          break;
  227.  
  228.       case WM_COMMAND:
  229.          if (wParam != IDOK) break;
  230.          x = GetCheckedRadioBtn(hDlg,
  231.             ID_INSTALLANDDELETE, ID_ABORTINSTALL);
  232.          if (x == ID_ABORTINSTALL) {
  233.             nResult = MsgBox(_hInstance, hDlg, IDS_QUERYABORT,
  234.                _szAppName, MB_ICONQUESTION | MB_YESNO);
  235.             if (nResult == IDNO) break;
  236.          }
  237.          EndDialog(hDlg, x);
  238.          break;
  239.  
  240.       default: fProcessed = FALSE; break;
  241.    }
  242.    return(fProcessed);
  243. }
  244.  
  245.  
  246. // ***************************************************************
  247. BOOL CALLBACK FileInUseDlgProc (HWND hDlg, UINT uMsg,
  248.    WPARAM wParam, LPARAM lParam) {
  249.  
  250.    BOOL fProcessed = TRUE;
  251.    UINT x;
  252.    int nResult;
  253.  
  254.    switch (uMsg) {
  255.       case WM_INITDIALOG:
  256.          PrepareDialogBox(hDlg, TRUE);
  257.          SetDlgItemText(hDlg, ID_FILENAMEINUSE, (LPSTR) lParam);
  258.          CheckRadioButton(hDlg, IDABORT, IDIGNORE, IDRETRY);
  259.          break;
  260.  
  261.       case WM_COMMAND:
  262.          if (wParam != IDOK) break;
  263.          x = GetCheckedRadioBtn(hDlg, IDABORT, IDIGNORE);
  264.          if (x == IDABORT) {
  265.             nResult = MsgBox(_hInstance, hDlg, IDS_QUERYABORT,
  266.                _szAppName, MB_ICONQUESTION | MB_YESNO);
  267.             if (nResult == IDNO) break;
  268.          }
  269.          EndDialog(hDlg, x);
  270.          break;
  271.  
  272.       default: fProcessed = FALSE; break;
  273.    }
  274.    return(fProcessed);
  275. }
  276.  
  277.  
  278.  
  279. // ***************************************************************
  280. char _szUnknown[] = "Unknown";
  281.  
  282. enum VERFILEFIXFIELD {
  283.    VF_FF_FILEVER, VF_FF_PRODVER, VF_FF_FILEFLAGS,
  284.    VF_FF_OPSYS, VF_FF_FILETYPE
  285. };
  286.  
  287. char *szVerFileFixedField[] = {
  288.    "File version",
  289.    "Product version",
  290.    "File flags",
  291.    "Operating sys",
  292.    "File type"
  293. };
  294.  
  295.  
  296.  
  297. enum VERFILEVARFIELD {
  298.    VF_VF_COMMENTS, VF_VF_COMPANY, VF_VF_DESC, VF_VF_FILEVER,
  299.    VF_VF_INTERNALNAME, VF_VF_COPYRIGHT, VF_VF_TRADEMARKS,
  300.    VF_VF_ORIGNAME, VF_VF_PRVTBLD, VF_VF_PRODNAME, VF_VF_PRODVER,
  301.    VF_VF_SPECIALBLD
  302. };
  303.  
  304. char *szVerFileVarField[][2] = {
  305.    { "Comments",        "Comments"           },
  306.    { "Company",         "CompanyName"        },
  307.    { "Description",     "FileDescription"    },
  308.    { "File version",    "FileVersion"        },
  309.    { "Internal name",   "InternalName"       },
  310.    { "Copyright",       "LegalCopyright"     },
  311.    { "Trademarks",      "LegalTrademarks"    },
  312.    { "Original name",   "OriginalFilename"   },
  313.    { "Private build",   "PrivateBuild"       },
  314.    { "Product name",    "ProductName"        },
  315.    { "Product version", "ProductVersion"     },
  316.    { "Special build",   "SpecialBuild"       }
  317. };
  318.  
  319.  
  320. static BOOL NEAR GetVerInfo (LPCSTR szPathname, HWND hwndLB) {
  321.    LPSTR szFileType, szFileSubtype, p, q;
  322.    void FAR *lpVerInfo;
  323.    VS_FIXEDFILEINFO FAR *lpVSFixedFileInfo;
  324.    UINT uLen, x, uMaxFieldLen = 0;
  325.    DWORD dwVerInfoSize, dwHandle;
  326.    HGLOBAL hGlbl;
  327.    char szBuf[100], szVXDID[10];
  328.    HDC hDC;
  329.    HFONT hFont;
  330.  
  331.    ListBox_ResetContent(hwndLB);
  332.    dwVerInfoSize = _GetFileVersionInfoSize(szPathname, &dwHandle);
  333.    if (dwVerInfoSize == 0) // No version info exists
  334.       return(FALSE);
  335.  
  336.    hGlbl = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  337.    if (hGlbl == NULL)
  338.       return(FALSE);
  339.  
  340.    lpVerInfo = GlobalLock(hGlbl);
  341.    x = _GetFileVersionInfo(szPathname, dwHandle,
  342.       dwVerInfoSize, lpVerInfo);
  343.    if (x == 0) {
  344.       // Couldn't get the version info for some reason.
  345.       GlobalUnlock(hGlbl);
  346.       GlobalFree(hGlbl);
  347.       return(FALSE);
  348.    }
  349.  
  350.    // Find the address of the VS_FIXEDFILEINFO structure
  351.    if (!_VerQueryValue(lpVerInfo, "\\",
  352.        (void FAR * FAR *) &lpVSFixedFileInfo, &uLen) ||
  353.        (uLen == 0)) {
  354.       // VS_FIXEDFILEINFO structure is not available
  355.       ListBox_AddString(hwndLB,
  356.          "Version information is not available.");
  357.       GlobalUnlock(hGlbl);
  358.       GlobalFree(hGlbl);
  359.       return(FALSE);
  360.    }
  361.  
  362.    SetWindowRedraw(hwndLB, FALSE);
  363.    hDC = GetDC(hwndLB);
  364.    hFont = GetWindowFont(hwndLB);
  365.    if (hFont != NULL)
  366.       SelectObject(hDC, hFont);
  367.  
  368.    // Cycle through all of the members in VS_FIXEDFILEINFO
  369.    for (x = 0; x < ARRAY_LEN(szVerFileFixedField); x++) {
  370.       p = szBuf +
  371.          wsprintf(szBuf, "%s:\t", szVerFileFixedField[x]);
  372.  
  373.       uMaxFieldLen = max(uMaxFieldLen, LOWORD(
  374.          GetTextExtent(hDC, szBuf, (int) (p - szBuf) - 1)));
  375.  
  376.       switch (x) {
  377.       case VF_FF_FILEVER:
  378.          wsprintf(p, "%d.%d.%d.%d",
  379.             HIWORD(lpVSFixedFileInfo->dwFileVersionMS),
  380.             LOWORD(lpVSFixedFileInfo->dwFileVersionMS),
  381.             HIWORD(lpVSFixedFileInfo->dwFileVersionLS),
  382.             LOWORD(lpVSFixedFileInfo->dwFileVersionLS));
  383.          break;
  384.  
  385.       case VF_FF_PRODVER:
  386.          wsprintf(p, "%d.%d.%d.%d",
  387.             HIWORD(lpVSFixedFileInfo->dwProductVersionMS),
  388.             LOWORD(lpVSFixedFileInfo->dwProductVersionMS),
  389.             HIWORD(lpVSFixedFileInfo->dwProductVersionLS),
  390.             LOWORD(lpVSFixedFileInfo->dwProductVersionLS));
  391.          break;
  392.  
  393.       case VF_FF_FILEFLAGS:
  394.          DWORD dwNum = lpVSFixedFileInfo->dwFileFlags;
  395.          if (dwNum & VS_FF_DEBUG)
  396.             lstrcat(p, "Debug ");
  397.          if (dwNum & VS_FF_PRERELEASE)
  398.             lstrcat(p, "Pre-release ");
  399.          if (dwNum & VS_FF_PATCHED)
  400.             lstrcat(p, "Patched ");
  401.          if (dwNum & VS_FF_PRIVATEBUILD)
  402.             lstrcat(p, "Private ");
  403.          if (dwNum & VS_FF_INFOINFERRED)
  404.             lstrcat(p, "Info ");
  405.          if (dwNum & VS_FF_SPECIALBUILD)
  406.             lstrcat(p, "Special ");
  407.          if (dwNum == 0)
  408.             lstrcat(p, "No flags");
  409.          break;
  410.  
  411.       case VF_FF_OPSYS:
  412.          switch (lpVSFixedFileInfo->dwFileOS) {
  413.             case VOS_DOS:
  414.                q = "DOS"; break;
  415.             case VOS_DOS_WINDOWS16:
  416.                q = "Windows 3.0 or later under DOS"; break;
  417.             case VOS_DOS_WINDOWS32:
  418.                q = "Windows-32 under DOS"; break;
  419.             case VOS_OS216:
  420.                q = "OS/2-16"; break;
  421.             case VOS_OS216_PM16:
  422.                q = "OS/2-16 PM-16"; break;
  423.             case VOS_OS232:
  424.                q = "OS/2-32"; break;
  425.             case VOS_OS232_PM32:
  426.                q = "OS/2-32 PM-32"; break;
  427.             case VOS_NT:
  428.                q = "Windows NT"; break;
  429.             case VOS_NT_WINDOWS32:
  430.                q = "Windows-32 under Windows-NT"; break;
  431.             case VOS_UNKNOWN:
  432.                default: q = _szUnknown; break;
  433.          }
  434.          lstrcat(p, q); break;
  435.  
  436.       case VF_FF_FILETYPE:
  437.          szFileSubtype = NULL;
  438.          switch (lpVSFixedFileInfo->dwFileType) {
  439.          case VFT_UNKNOWN: default:
  440.             szFileType = _szUnknown; break;
  441.          case VFT_APP:
  442.             szFileType = "Application"; break;
  443.          case VFT_DLL:
  444.             szFileType = "Dynamic-link library"; break;
  445.          case VFT_DRV:
  446.             szFileType = "Device driver";
  447.             switch (lpVSFixedFileInfo->dwFileSubtype) {
  448.             case VFT2_UNKNOWN:
  449.                default: szFileSubtype = _szUnknown; break;
  450.             case VFT2_DRV_PRINTER:
  451.                szFileSubtype = "Printer"; break;
  452.             case VFT2_DRV_KEYBOARD:
  453.                szFileSubtype = "Keyboard"; break;
  454.             case VFT2_DRV_LANGUAGE:
  455.                szFileSubtype = "Language"; break;
  456.             case VFT2_DRV_DISPLAY:
  457.                szFileSubtype = "Display"; break;
  458.             case VFT2_DRV_MOUSE:
  459.                szFileSubtype = "Mouse"; break;
  460.             case VFT2_DRV_NETWORK:
  461.                szFileSubtype = "Network"; break;
  462.             case VFT2_DRV_SYSTEM:
  463.                szFileSubtype = "System"; break;
  464.             case VFT2_DRV_INSTALLABLE:
  465.                szFileSubtype = "Installable"; break;
  466.             case VFT2_DRV_SOUND:
  467.                szFileSubtype = "Sound"; break;
  468.             case VFT2_DRV_COMM:
  469.                szFileSubtype = "Communication"; break;
  470.             }
  471.             break;
  472.  
  473.          case VFT_FONT:
  474.             szFileType = "Font";
  475.             switch (lpVSFixedFileInfo->dwFileSubtype) {
  476.             case VFT2_UNKNOWN: default:
  477.                szFileSubtype = _szUnknown; break;
  478.             case VFT2_FONT_RASTER:
  479.                szFileSubtype = "Raster"; break;
  480.             case VFT2_FONT_VECTOR:
  481.                szFileSubtype = "Vector"; break;
  482.             case VFT2_FONT_TRUETYPE:
  483.                szFileSubtype = "TrueType"; break;
  484.             }
  485.             break;
  486.  
  487.          case VFT_VXD:
  488.             szFileType = "Virtual device";
  489.             ltoa(lpVSFixedFileInfo->dwFileSubtype,
  490.                szFileSubtype = szVXDID, 10);
  491.             break;
  492.  
  493.          case VFT_STATIC_LIB:
  494.             szFileType = "Static-link library"; break;
  495.          }  // switch (lpVSFixedFileInfo->dwFileType)
  496.  
  497.          wsprintf(p, "%s%s%s%s", szFileType,
  498.             ((szFileSubtype == NULL) ? "" : " ("),
  499.             ((szFileSubtype == NULL) ? "" : szFileSubtype),
  500.             ((szFileSubtype == NULL) ? "" : ")"));
  501.       }  // switch
  502.       ListBox_AddString(hwndLB, szBuf);
  503.    }  // for
  504.  
  505.  
  506.  
  507.    // Variable file Version information
  508.  
  509.    // Use the first translation Langauge-CharSet pair
  510.  
  511.    _VerQueryValue(lpVerInfo, "\\VarFileInfo\\Translation",
  512.       (VOID FAR * FAR *) &p, &x);
  513.  
  514.    char szStringName[50];
  515.    DWORD dwTranslation = * ((DWORD FAR *) p);
  516.    WORD wRootLen = wsprintf(szStringName,
  517.       "\\StringFileInfo\\%04x%04x\\",
  518.       LOWORD(dwTranslation), HIWORD(dwTranslation));
  519.  
  520.    p = szBuf + wsprintf(szBuf, "Language:\t");
  521.    _VerLanguageName(LOWORD(dwTranslation), p,
  522.       (UINT) (sizeof(szBuf) - (p - szBuf)));
  523.    ListBox_AddString(hwndLB, szBuf);
  524.  
  525.    // Cycle through all of the StringNames
  526.    for (x = 0; x < ARRAY_LEN(szVerFileVarField); x++) {
  527.       p = szBuf +
  528.          wsprintf(szBuf, "%s:\t", szVerFileVarField[x][0]);
  529.  
  530.       uMaxFieldLen = max(uMaxFieldLen, LOWORD(
  531.          GetTextExtent(hDC, szBuf, (int) (p - szBuf) - 1)));
  532.  
  533.       lstrcat(szStringName, szVerFileVarField[x][1]);
  534.       WORD wStringLen;
  535.       if (!_VerQueryValue(lpVerInfo, szStringName,
  536.           (VOID FAR * FAR *) &p, (UINT FAR *) &wStringLen) ||
  537.           (wStringLen == 0))
  538.          lstrcat(szBuf, _szUnknown);
  539.       else lstrcat(szBuf, p);
  540.       ListBox_AddString(hwndLB, szBuf);
  541.  
  542.       // Be sure to reset to 0 so that we can concat
  543.       szStringName[wRootLen] = 0;
  544.    }
  545.    ReleaseDC(hwndLB, hDC);
  546.  
  547.    RECT rc;
  548.    SetRect(&rc, 4, 8, 0, 0);
  549.    MapDialogRect(GetParent(hwndLB), &rc);
  550.    x = 6 + ((uMaxFieldLen * 4) / rc.left);
  551.    ListBox_SetTabStops(hwndLB, 1, &x);
  552.  
  553.    ListBox_SetHorizontalExtent(hwndLB,
  554.       2 * GetSystemMetrics(SM_CXSCREEN));
  555.    SetWindowRedraw(hwndLB, TRUE);
  556.    InvalidateRect(hwndLB, NULL, TRUE);
  557.  
  558.    GlobalUnlock(hGlbl);
  559.    GlobalFree(hGlbl);
  560.    return(TRUE);
  561. }
  562.  
  563. static LRESULT ListBoxSubclass (HWND hWnd, UINT uMsg,
  564.    WPARAM wParam, LPARAM lParam) {
  565.  
  566.    if ((uMsg == WM_HSCROLL) || (uMsg == WM_VSCROLL))
  567.       FORWARD_WM_COMMAND(GetParent(hWnd), GetWindowID(hWnd),
  568.          hWnd, LBN_SELCHANGE, PostMessage);
  569.  
  570.    return(CallWindowProc((FARPROC)
  571.       GetClassLong(hWnd, GCL_WNDPROC), hWnd, uMsg,
  572.       wParam, lParam));
  573. }
  574.  
  575. BOOL CALLBACK MismatchDlgProc (HWND hDlg, UINT uMsg,
  576.    WPARAM wParam, LPARAM lParam) {
  577.  
  578.    BOOL fProcessed = TRUE;
  579.    LPMISMATCHSTRUCT lpMismatchStruct;
  580.    char szBuf[100];
  581.    WORD x;
  582.    int nResult;
  583.  
  584.    switch (uMsg) {
  585.       case WM_INITDIALOG:
  586.          PrepareDialogBox(hDlg, TRUE);
  587.  
  588.          lpMismatchStruct = (LPMISMATCHSTRUCT) lParam;
  589.  
  590.          // Tell the user why there is a file conflict
  591.          DWORD dwVIFResult = lpMismatchStruct->dwVIFResult;
  592.          x = 0;
  593.          if (dwVIFResult & VIF_MISMATCH)   x = IDS_MISMATCH;
  594.          if (dwVIFResult & VIF_SRCOLD)     x = IDS_SRCOLD;
  595.          if (dwVIFResult & VIF_DIFFLANG)   x = IDS_DIFFLANG;
  596.          if (dwVIFResult & VIF_DIFFCODEPG) x = IDS_DIFFCODEPG;
  597.          if (dwVIFResult & VIF_DIFFTYPE)   x = IDS_DIFFTYPE;
  598.          LoadString(_hInstance, x, szBuf, sizeof(szBuf));
  599.          SetDlgItemText(hDlg, ID_VERMISMATCHTEXT, szBuf);
  600.  
  601.          GetVerInfo(lpMismatchStruct->szExistingPath,
  602.             GetDlgItem(hDlg, ID_VERINFOEXISTING));
  603.  
  604.          GetVerInfo(lpMismatchStruct->szTmpPath,
  605.             GetDlgItem(hDlg, ID_VERINFONEW));
  606.  
  607.          SubclassWindow(GetDlgItem(hDlg, ID_VERINFOEXISTING),
  608.             ListBoxSubclass);
  609.          SubclassWindow(GetDlgItem(hDlg, ID_VERINFONEW),
  610.             ListBoxSubclass);
  611.          break;
  612.  
  613.       case WM_COMMAND:
  614.          switch (wParam) {
  615.             case IDABORT:
  616.                nResult = MsgBox(_hInstance, hDlg, IDS_QUERYABORT,
  617.                   _szAppName, MB_ICONQUESTION | MB_YESNO);
  618.                if (nResult == IDNO) break;
  619.                EndDialog(hDlg, wParam); 
  620.                break;
  621.  
  622.             case IDYES: case IDNO: 
  623.                EndDialog(hDlg, wParam); 
  624.                break;
  625.  
  626.             case ID_VERINFOEXISTING:
  627.             case ID_VERINFONEW:
  628.                if (HIWORD(lParam) != LBN_SELCHANGE) break;
  629.                HWND hWndOtherLB = GetDlgItem(hDlg, 
  630.                   ((wParam == ID_VERINFONEW)
  631.                   ? ID_VERINFOEXISTING : ID_VERINFONEW));
  632.  
  633.                x = ListBox_GetCurSel(LOWORD(lParam));
  634.                if (x != ListBox_GetCurSel(hWndOtherLB))
  635.                   ListBox_SetCurSel(hWndOtherLB, x);
  636.  
  637.                x = ListBox_GetTopIndex(LOWORD(lParam));
  638.                if (x != ListBox_GetTopIndex(hWndOtherLB))
  639.                   ListBox_SetTopIndex(hWndOtherLB, x);
  640.                break;
  641.          }
  642.          break;
  643.  
  644.       default: fProcessed = FALSE; break;
  645.    }
  646.    return(fProcessed);
  647. }
  648.