home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol07 / 06 / winlib / vershow.c < prev    next >
C/C++ Source or Header  |  1992-10-01  |  13KB  |  435 lines

  1. /*****************************************************************************
  2. Module name: VerShow.C
  3. Programmer : Jeffrey M. Richter.
  4. Description: Version Resource Viewer.
  5. *****************************************************************************/
  6.  
  7. #include <Windows.h>
  8. #include <Windowsx.h>
  9. #include <CommDlg.h>
  10. #include <Ver.h>
  11. #include <String.h>
  12. #include "VerShow.h"
  13.  
  14. #define ARRAY_LEN(Array)    (sizeof(Array) / sizeof(Array[0]))
  15.  
  16. // Application global variables.
  17. extern const HINSTANCE cdecl _hInstance;
  18. char _szAppName[]  = "VerShow";
  19. void VerShow_StringFileInfo (HWND hDlg, UINT uTranslationNum);
  20.  
  21. //****************************************************************************
  22. void VerShow_ClearFields (HWND hDlg, LPCSTR szFile) {
  23.     SetDlgItemText(hDlg, ID_PATHNAME,
  24.         (szFile == NULL) ? "No file selected" : szFile);
  25.     SetDlgItemText(hDlg, ID_FIXEDFILEINFODATA,
  26.         (szFile == NULL) ? "": "No version information exists");
  27.     (void) ComboBox_ResetContent(GetDlgItem(hDlg, ID_TRANSLATIONS));
  28.     (void) ListBox_ResetContent(GetDlgItem(hDlg, ID_STRINGS));
  29. }
  30.  
  31.  
  32. char _szUnknown[] = "Unknown";
  33.  
  34. char *_szFileTypes[] = {
  35.     _szUnknown,                        // 0-VFT_UNKNOWN
  36.     "Application",                    // 1-VFT_APP
  37.     "Dynamic-link library",        // 2-VFT_DLL
  38.     "Device driver",                // 3-VFT_DRV
  39.     "Font",                            // 4-VFT_FONT
  40.     "Virtual device",                // 5-VFT_VXD
  41.     _szUnknown,                        // 6-Unknown
  42.     "Static library"                // 7-VFT_STATIC_LIB
  43. };
  44.  
  45. char *_szDriverSubtypes[] = {
  46.     _szUnknown,                        // 0-VFT2_UNKNOWN
  47.     "Printer",                        // 1-VFT2_DRV_PRINTER
  48.     "Keyboard",                        // 2-VFT2_DRV_KEYBOARD
  49.     "Language",                        // 3-VFT2_DRV_LANGUAGE
  50.     "Display",                        // 4-VFT2_DRV_DISPLAY
  51.     "Mouse",                            // 5-VFT2_DRV_MOUSE
  52.     "Network",                        // 6-VFT2_DRV_NETWORK
  53.     "System",                        // 7-VFT2_DRV_SYSTEM
  54.     "Installable",                    // 8-VFT2_DRV_INSTALLABLE
  55.     "Sound",                            // 9-VFT2_DRV_SOUND
  56.     "Comm"                            // A-VFT2_DRV_COMM
  57. };
  58.  
  59. char *_szFontSubtypes[] = {
  60.     _szUnknown,                        // 0-VFT2_UNKNOWN
  61.     "Raster",                        // 1-VFT2_FONT_RASTER
  62.     "Vector",                        // 2-VFT2_FONT_VECTOR
  63.     "TrueType"                        // 3-VFT2_FONT_TRUETYPE
  64. };
  65.  
  66. void CreateFixedVerInfoString (LPSTR szBuf, 
  67.     VS_FIXEDFILEINFO FAR *lpVS_FixedFileInfo) {
  68.  
  69.     DWORD dwTemp;
  70.     LPSTR p;
  71.  
  72.     wsprintf(szBuf,
  73.         "0x%08lX\n"            // Signature
  74.         "0x%08lX\n"            // Structure version
  75.         "%d.%d.%d.%d\n"    // File version
  76.         "%d.%d.%d.%d\n"    // Product version
  77.         "0x%08lX\n",        // File flags mask
  78.         lpVS_FixedFileInfo->dwSignature,
  79.         lpVS_FixedFileInfo->dwStrucVersion,
  80.  
  81.         HIWORD(lpVS_FixedFileInfo->dwFileVersionMS),
  82.         LOWORD(lpVS_FixedFileInfo->dwFileVersionMS),
  83.         HIWORD(lpVS_FixedFileInfo->dwFileVersionLS),
  84.         LOWORD(lpVS_FixedFileInfo->dwFileVersionLS),
  85.         
  86.         HIWORD(lpVS_FixedFileInfo->dwProductVersionMS),
  87.         LOWORD(lpVS_FixedFileInfo->dwProductVersionMS),
  88.         HIWORD(lpVS_FixedFileInfo->dwProductVersionLS),
  89.         LOWORD(lpVS_FixedFileInfo->dwProductVersionLS),
  90.         lpVS_FixedFileInfo->dwFileFlagsMask);
  91.  
  92.     // Add the string equiavlent of the file flags.
  93.     dwTemp = lpVS_FixedFileInfo->dwFileFlags;
  94.     if (dwTemp == 0)                        lstrcat(szBuf, "No file flags");
  95.     if (dwTemp & VS_FF_DEBUG)            lstrcat(szBuf, "Debug ");
  96.     if (dwTemp & VS_FF_PRERELEASE)    lstrcat(szBuf, "Prerelease ");
  97.     if (dwTemp & VS_FF_PATCHED)        lstrcat(szBuf, "Patched ");
  98.     if (dwTemp & VS_FF_PRIVATEBUILD)    lstrcat(szBuf, "PrivateBuild ");
  99.     if (dwTemp & VS_FF_INFOINFERRED)    lstrcat(szBuf, "InfoInferred ");
  100.     if (dwTemp & VS_FF_SPECIALBUILD)    lstrcat(szBuf, "SpecialBuild ");
  101.     lstrcat(szBuf, "\n");
  102.  
  103.     // Add the string equiavlent of the file OS.
  104.     dwTemp = lpVS_FixedFileInfo->dwFileOS;
  105.     switch (LOWORD(dwTemp)) {
  106.         case VOS__WINDOWS16:    p = "Windows (16-bit)";    break;
  107.         case VOS__PM16:        p = "PM (16-bit)";        break;
  108.         case VOS__PM32:        p = "PM (32-bit)";        break;
  109.         case VOS__WINDOWS32:    p = "Windows (32-bit)";    break;
  110.         default:                    p = _szUnknown;                break;
  111.     }
  112.     lstrcat(szBuf, p); lstrcat(szBuf, " running under ");
  113.     switch (HIWORD(dwTemp)) {
  114.         case HIWORD(VOS_DOS):    p = "DOS";                break;
  115.         case HIWORD(VOS_OS216):    p = "OS/2 (16-bit)";    break;
  116.         case HIWORD(VOS_OS232):    p = "OS/2 (32-bit)";    break;
  117.         case HIWORD(VOS_NT):        p = "Windows-NT";        break;
  118.         default:                        p = _szUnknown;        break;
  119.     }
  120.     lstrcat(szBuf, p); lstrcat(szBuf, "\n");
  121.  
  122.  
  123.     // Add the string equiavlent of the file type.
  124.     lstrcat(szBuf, _szFileTypes[(UINT) lpVS_FixedFileInfo->dwFileType]);
  125.     lstrcat(szBuf, "\n");
  126.  
  127.     // Add the string equiavlent of the file subtype.
  128.     switch (lpVS_FixedFileInfo->dwFileType) {
  129.         case VFT_DRV:    
  130.             p = _szDriverSubtypes[(UINT) lpVS_FixedFileInfo->dwFileSubtype];
  131.             break;
  132.  
  133.         case VFT_FONT:
  134.             p = _szFontSubtypes[(UINT) lpVS_FixedFileInfo->dwFileSubtype];
  135.             break;
  136.  
  137.         case VFT_VXD:
  138.             wsprintf(_fstrchr(szBuf, 0), "%ld", 
  139.                 (LPSTR) lpVS_FixedFileInfo->dwFileSubtype);
  140.             p = NULL;
  141.             break;
  142.  
  143.         default:
  144.             p = NULL;
  145.             break;
  146.     }
  147.     if (p != NULL) lstrcat(szBuf, p);
  148.     lstrcat(szBuf, "\n");
  149. }
  150.  
  151.  
  152.  
  153.  
  154. void VerShow_FillFields (HWND hDlg, LPCSTR szFile) {
  155.     DWORD dwVerInfoSize, dwHandle, FAR *lpdwTranslation;
  156.     HGLOBAL hGlbl; 
  157.     VOID FAR *lpVerInfo; 
  158.     UINT uLen, x;
  159.     char szBuf[500];
  160.     VS_FIXEDFILEINFO FAR *lpVS_FixedFileInfo;
  161.  
  162.     // Clear all of the fields.
  163.     VerShow_ClearFields(hDlg, szFile);
  164.  
  165.     // Calculate the size of the version control resource information.
  166.     dwVerInfoSize = GetFileVersionInfoSize(szFile, &dwHandle);
  167.     if (dwVerInfoSize == 0)    // No resource information exists.
  168.         return;    
  169.  
  170.     // Allocate a memory block large enough to hold the version information.
  171.     hGlbl = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  172.     if (hGlbl == NULL) {
  173.         MessageBox(hDlg, _szAppName, "Insufficient memory.", MB_OK);
  174.         return;
  175.     }
  176.  
  177.     // Load the version information into memory.
  178.     lpVerInfo = GlobalLock(hGlbl);
  179.     GetFileVersionInfo(szFile, dwHandle, dwVerInfoSize, lpVerInfo);
  180.  
  181.     // Get the address to the VS_FIXEDFILEINFO structure data.
  182.     VerQueryValue(lpVerInfo, "\\",
  183.         (VOID FAR * FAR *) &lpVS_FixedFileInfo, &uLen);
  184.  
  185.     // Create the string containing the VS_FIXEDFILEINFO data information.
  186.     CreateFixedVerInfoString(szBuf, lpVS_FixedFileInfo);
  187.     
  188.     // Place the version info string in the dialog's STATIC control.
  189.     SetDlgItemText(hDlg, ID_FIXEDFILEINFODATA, szBuf);
  190.  
  191.     // ************************************************************************
  192.     // Load the "Translations" combo box.
  193.     VerQueryValue(lpVerInfo, "\\VarFileInfo\\Translation",
  194.         (VOID FAR * FAR *) &lpdwTranslation, &uLen);
  195.  
  196.     for (x = 0; x < uLen; x += 4, lpdwTranslation++) {
  197.         // Get the string name for the language number.
  198.         VerLanguageName(LOWORD(*lpdwTranslation), szBuf, sizeof(szBuf));
  199.         lstrcat(szBuf, " -- ");
  200.  
  201.         // Get the string name for the code page number.
  202.         LoadString(_hInstance, HIWORD(*lpdwTranslation), _fstrchr(szBuf, 0), 
  203.             (UINT) (sizeof(szBuf) - (_fstrchr(szBuf, 0) - szBuf)));
  204.  
  205.         // Add the string to the combo box.
  206.         (void) ComboBox_AddString(GetDlgItem(hDlg, ID_TRANSLATIONS), szBuf);
  207.     }
  208.  
  209.     // Select the first translation entry as the default.
  210.     (void) ComboBox_SetCurSel(GetDlgItem(hDlg, ID_TRANSLATIONS), 0);
  211.  
  212.     // Show the version info strings for the default translation entry.
  213.     VerShow_StringFileInfo(hDlg, 0);
  214.  
  215.     // Free the version information because it is no longer needed.
  216.     GlobalUnlock(hGlbl);
  217.     GlobalFree(hGlbl);
  218. }
  219.  
  220.  
  221.  
  222.  
  223. char *_szStringNames[] = {
  224.     "Comments",
  225.     "CompanyName",
  226.     "FileDescription",
  227.     "FileVersion",
  228.     "InternalName",
  229.     "LegalCopyright",
  230.     "LegalTrademarks",
  231.     "OriginalFilename",
  232.     "PrivateBuild",
  233.     "ProductName",
  234.     "ProductVersion",
  235.     "SpecialBuild"
  236. };
  237.  
  238. void VerShow_StringFileInfo (HWND hDlg, UINT uTranslationNum) {
  239.     char szFile[128], szBuf[200]; 
  240.     DWORD dwHandle, FAR *lpdwTranslation, dwVerInfoSize;
  241.     HGLOBAL hGlbl;
  242.     UINT uLen, uMaxFieldLen, x;
  243.     VOID FAR *lpVerInfo;
  244.     LPSTR szStringData;
  245.     HDC hDC;
  246.     HFONT hFont;
  247.     RECT rc;
  248.     HWND hWndLB = GetDlgItem(hDlg, ID_STRINGS);
  249.  
  250.     GetDlgItemText(hDlg, ID_PATHNAME, szFile, sizeof(szFile));
  251.  
  252.     dwVerInfoSize = GetFileVersionInfoSize(szFile, &dwHandle);
  253.     if (dwVerInfoSize == 0)        // No resource information exists.
  254.         return;
  255.  
  256.     // Allocate a memory block large enough to hold the version information.
  257.     hGlbl = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  258.     if (hGlbl == NULL) {
  259.         MessageBox(hDlg, _szAppName, "Insufficient memory.", MB_OK);
  260.         return;
  261.     }
  262.  
  263.     // Load the version information into memory.
  264.     lpVerInfo = GlobalLock(hGlbl);
  265.     GetFileVersionInfo(szFile, dwHandle, dwVerInfoSize, lpVerInfo);
  266.  
  267.     VerQueryValue(lpVerInfo, "\\VarFileInfo\\Translation",
  268.         (VOID FAR * FAR *) &lpdwTranslation, &uLen);
  269.     lpdwTranslation += uTranslationNum;
  270.  
  271.     hDC = GetDC(hDlg);
  272.     hFont = GetWindowFont(hDlg);
  273.     if (hFont != NULL) SelectObject(hDC, hFont);
  274.     uMaxFieldLen = 0;
  275.  
  276.     SetWindowRedraw(hWndLB, FALSE);
  277.     (void) ListBox_ResetContent(hWndLB);
  278.  
  279.     for (x = 0; x < ARRAY_LEN(_szStringNames); x++) {
  280.         uMaxFieldLen = max(uMaxFieldLen, LOWORD(
  281.             GetTextExtent(hDC, _szStringNames[x], lstrlen(_szStringNames[x]))));
  282.  
  283.         wsprintf(szBuf,
  284.             "\\StringFileInfo\\%04x%04x\\%s",
  285.             LOWORD(*lpdwTranslation), HIWORD(*lpdwTranslation),
  286.             (LPSTR) _szStringNames[x]);
  287.  
  288.         if (0 == VerQueryValue(lpVerInfo, szBuf,
  289.             (VOID FAR * FAR *) &szStringData, &uLen)) continue;
  290.  
  291.         if (uLen == 0) continue;    // This string doesn't exist.
  292.  
  293.         wsprintf(szBuf, "%s\t%s", (LPSTR) _szStringNames[x],
  294.             (LPSTR) szStringData);
  295.         (void) ListBox_AddString(hWndLB, szBuf);
  296.     }
  297.  
  298.     // Select the first string by default.
  299.     (void) ListBox_SetCurSel(hWndLB, 0);
  300.  
  301.    // Convert pixels into dialog box units.
  302.    SetRect(&rc, 4, 8, 4, 8);
  303.    MapDialogRect(hDlg, &rc);
  304.    x = 6 + ((uMaxFieldLen * 4) / rc.left);
  305.  
  306.    // Set tabstop position in listbox.  Note: listbox must
  307.    // have LBS_USETABSTOPS style in dialog box template.
  308.    (void) ListBox_SetTabStops(hWndLB, 1, &x);
  309.    ListBox_SetHorizontalExtent(hWndLB, GetSystemMetrics(SM_CXSCREEN) * 2);
  310.     ReleaseDC(hDlg, hDC);
  311.  
  312.     // Force the listbox to be repainted.
  313.     SetWindowRedraw(hWndLB, TRUE);
  314.     InvalidateRect(hWndLB, NULL, TRUE);
  315.  
  316.     // Free the version information because it is no longer needed.
  317.     GlobalUnlock(hGlbl);
  318.     GlobalFree(hGlbl);
  319. }
  320.  
  321.  
  322. #pragma argsused
  323. BOOL VerShow_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM lParam) {
  324.  
  325.     SetDlgItemText(hwnd, ID_FIXEDFILEINFOFIELDS,
  326.         "Signature:\n"
  327.         "Structure version:\n"
  328.         "File version:\n"
  329.         "Product version:\n"
  330.         "File flags mask:\n"
  331.         "File flags:\n"
  332.         "File OS:\n"
  333.         "File type:\n"
  334.         "File subtype:\n"
  335.         "File date:\n");
  336.  
  337.     VerShow_ClearFields(hwnd, NULL);
  338.     return(TRUE);
  339. }
  340.  
  341.  
  342.  
  343. void VerShow_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
  344.     OPENFILENAME ofn;
  345.     char szPathname[128];
  346.  
  347.     switch (id) {
  348.  
  349.       case ID_SELECTFILE:
  350.             _fmemset(&ofn, 0, sizeof(ofn));
  351.             ofn.lStructSize = sizeof(ofn);
  352.             ofn.hwndOwner = hwnd;
  353.             ofn.lpstrFilter =
  354.                 "Executables\0*.EXE\0"
  355.                 "DLLs\0*.DLL\0"
  356.                 "Device drivers\0*.DRV\0"
  357.                 "Fonts\0*.FON\0"
  358.                 "Virtual devices\0*.386\0"
  359.                 "Static libraries\0*.LIB\0";
  360.             ofn.lpstrFile = szPathname; ofn.lpstrFile[0] = 0;
  361.             ofn.nMaxFile = sizeof(szPathname);
  362.             ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  363.             if (GetOpenFileName(&ofn)) {
  364.                 VerShow_FillFields(hwnd, ofn.lpstrFile);
  365.             } else {
  366.                 VerShow_ClearFields(hwnd, NULL);
  367.             }
  368.             break;
  369.  
  370.         case ID_TRANSLATIONS:
  371.             if (codeNotify != CBN_SELCHANGE) 
  372.                 break;
  373.             VerShow_StringFileInfo(hwnd, ComboBox_GetCurSel(hwndCtl));
  374.             break;
  375.  
  376.       case IDCANCEL:
  377.          EndDialog(hwnd, 0);
  378.          break;
  379.     }
  380. }
  381.  
  382.  
  383. #pragma argsused
  384. BOOL VerShow_OnEraseBkgnd (HWND hwnd, HDC hdc) {
  385.     return(IsMinimized(hwnd) ? 1 : 0);
  386. }
  387.  
  388.  
  389. void VerShow_OnPaint (HWND hwnd) {
  390.     PAINTSTRUCT ps;
  391.     BeginPaint(hwnd, &ps);
  392.     if (IsMinimized(hwnd))
  393.         DrawIcon(ps.hdc, 0, 0,
  394.             LoadIcon(_hInstance, MAKEINTRESOURCE(ICON_VerShow)));
  395.     EndPaint(hwnd, &ps);
  396. }
  397.  
  398.  
  399. BOOL CALLBACK VerShowDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, 
  400.     LPARAM lParam) {
  401.     LRESULT lResult = 0;
  402.  
  403.    switch (uMsg) {
  404.  
  405.         case WM_INITDIALOG:
  406.             lResult = HANDLE_WM_INITDIALOG(hDlg, wParam, lParam,
  407.                 VerShow_OnInitDialog);
  408.             break;
  409.  
  410.         case WM_COMMAND:
  411.             lResult = HANDLE_WM_COMMAND(hDlg, wParam, lParam,
  412.                 VerShow_OnCommand);
  413.             break;
  414.  
  415.         case WM_ERASEBKGND:
  416.             lResult = HANDLE_WM_ERASEBKGND(hDlg, wParam, lParam,
  417.                 VerShow_OnEraseBkgnd);
  418.             break;
  419.  
  420.         case WM_PAINT:
  421.             (void) HANDLE_WM_PAINT(hDlg, wParam, lParam, VerShow_OnPaint);
  422.             break;
  423.    }
  424.    return((BOOL) lResult);
  425. }
  426.  
  427. #pragma argsused
  428. int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  429.     LPSTR lpszCmdLine, int nCmdShow) {
  430.  
  431.     DialogBox(hInstance, MAKEINTRESOURCE(DLG_VERSHOW),
  432.         NULL, (DLGPROC) VerShowDlgProc);
  433.     return(0);
  434. }
  435.