home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / icm20 / icmview / dialogs.c < prev    next >
C/C++ Source or Header  |  1997-09-07  |  42KB  |  1,202 lines

  1. //THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. //ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright  1994-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  FILE:
  9. //    DIALOGS.C
  10. //
  11. //  DESCRIPTION:
  12. //
  13. //
  14. //  PLATFORMS:
  15. //    Windows 95, Windows NT
  16. //
  17. //  SPECIAL INSTRUCTIONS:
  18. //
  19.  
  20. //
  21. // Pre-processor directives
  22. //
  23.  
  24. #define REGISTRY_CURRENT_DISPLAY "System\\CurrentControlSet\\Services\\Class\\DISPLAY\\0000"
  25. #define TOGGLE_BOOLEAN(b) b=!b
  26.  
  27. // Windows Header Files:
  28. #pragma warning(disable:4001)   // Single-line comment warnings
  29. #pragma warning(disable:4115)   // Named type definition in parentheses
  30. #pragma warning(disable:4201)   // Nameless struct/union warning
  31. #pragma warning(disable:4214)   // Bit field types other than int warnings
  32. #pragma warning(disable:4514)   // Unreferenced inline function has been removed
  33.  
  34. // Windows Header Files:
  35. #include <Windows.h>
  36. #include <WindowsX.h>
  37. #include <commdlg.h>
  38. #include <commctrl.h>
  39. #include "icm.h"
  40.  
  41. // Restore the warnings--leave the single-line comment warning OFF
  42. #pragma warning(default:4115)   // Named type definition in parentheses
  43. #pragma warning(default:4201)   // Nameless struct/union warning
  44. #pragma warning(default:4214)   // Bit field types other than int warnings
  45. #pragma warning(default:4514)   // Unreferenced inline function has been removed
  46.  
  47. // C-runtime header files
  48. #include <TCHAR.H>
  49. #include <stdlib.h>
  50.  
  51. // Local header files
  52. #include "icmview.h"
  53. #include "resource.h"
  54. #include "DibInfo.H"
  55. #include "Dialogs.h"
  56. #include "CDErr.h"
  57. #include "print.h"
  58. #include "child.h"
  59. #include "Dibs.H"
  60. #include "AppInit.h"
  61. #include "Debug.h"
  62.  
  63. // Private structures/typedefs
  64. typedef struct tagDIBPROPSHEETINFO
  65. {
  66.     UINT            uiPageNum;          // Page number of propsheet
  67.     HGLOBAL         hDIBInfo;           // Handle to DIBINFO structure
  68. } DIBPROPSHEETINFO, *LPDIBPROPSHEETINFO;
  69.  
  70. // Private function prototypes
  71. void            ProcessCDError(DWORD dwErrorCode, HWND hWnd);
  72. int CALLBACK    EnumICMProfileCallback(LPCTSTR lpszFileName, LPARAM lParam);
  73. LPTSTR          GetOpenImageName(HWND hWnd , PBOOL pbUserCancel);
  74. void            DlgDIBInfoPaint(HWND  hDlg, LPDIBINFO lpDIBInfo);
  75. BOOL            SaveDIBInfoDlgPage(HWND hDlg, LPDIBINFO lpDIBInfo, UINT uiPageNum);
  76. LPTSTR          GetDlgItemString(HWND hDlg, int iControlId, LPTSTR lpszCurrentString);
  77. DWORD           SetColorMatchUIFlags(DWORD dwDIFlags);
  78. BOOL WINAPI     ColorSetupApply(PCOLORMATCHSETUP pcmSetup, LPARAM lParam);
  79. VOID            ApplyColorSettings(LPDIBINFO lpDIBInfo, PCOLORMATCHSETUP pCMSetup);
  80. BOOL CALLBACK PrintDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  81.  
  82. // Global external variables
  83.  
  84. // Global private variables
  85. //UINT  guiNumProfiles = 0;
  86. BOOL  gbOpenCanceled;
  87.  
  88.  
  89. /////////////////////////////////////////////////////////////////////////////
  90. //
  91. //   FUNCTION: ProcessCDError(DWORD)
  92. //
  93. //   PURPOSE:  Processes errors from the common dialog functions.
  94. //
  95. //   COMMENTS:
  96. //
  97. //       This function is called whenever a common dialog function
  98. //       fails.  The CommonDialogExtendedError() value is passed to
  99. //       the function which maps the error value to a string table.
  100. //       The string is loaded and displayed for the user.
  101. //
  102. //   RETURN VALUES:
  103. //       void.
  104. //
  105. /////////////////////////////////////////////////////////////////////////////
  106. void ProcessCDError(DWORD dwErrorCode, HWND hWnd)
  107. {
  108.     WORD  wStringID;
  109.     TCHAR  buf[256];
  110.  
  111.     switch (dwErrorCode)
  112.     {
  113.         case CDERR_DIALOGFAILURE:   wStringID=IDS_DIALOGFAILURE;   break;
  114.         case CDERR_STRUCTSIZE:      wStringID=IDS_STRUCTSIZE;      break;
  115.         case CDERR_INITIALIZATION:  wStringID=IDS_INITIALIZATION;  break;
  116.         case CDERR_NOTEMPLATE:      wStringID=IDS_NOTEMPLATE;      break;
  117.         case CDERR_NOHINSTANCE:     wStringID=IDS_NOHINSTANCE;     break;
  118.         case CDERR_LOADSTRFAILURE:  wStringID=IDS_LOADSTRFAILURE;  break;
  119.         case CDERR_FINDRESFAILURE:  wStringID=IDS_FINDRESFAILURE;  break;
  120.         case CDERR_LOADRESFAILURE:  wStringID=IDS_LOADRESFAILURE;  break;
  121.         case CDERR_LOCKRESFAILURE:  wStringID=IDS_LOCKRESFAILURE;  break;
  122.         case CDERR_MEMALLOCFAILURE: wStringID=IDS_MEMALLOCFAILURE; break;
  123.         case CDERR_MEMLOCKFAILURE:  wStringID=IDS_MEMLOCKFAILURE;  break;
  124.         case CDERR_NOHOOK:          wStringID=IDS_NOHOOK;          break;
  125.         case PDERR_SETUPFAILURE:    wStringID=IDS_SETUPFAILURE;    break;
  126.         case PDERR_PARSEFAILURE:    wStringID=IDS_PARSEFAILURE;    break;
  127.         case PDERR_RETDEFFAILURE:   wStringID=IDS_RETDEFFAILURE;   break;
  128.         case PDERR_LOADDRVFAILURE:  wStringID=IDS_LOADDRVFAILURE;  break;
  129.         case PDERR_GETDEVMODEFAIL:  wStringID=IDS_GETDEVMODEFAIL;  break;
  130.         case PDERR_INITFAILURE:     wStringID=IDS_INITFAILURE;     break;
  131.         case PDERR_NODEVICES:       wStringID=IDS_NODEVICES;       break;
  132.         case PDERR_NODEFAULTPRN:    wStringID=IDS_NODEFAULTPRN;    break;
  133.         case PDERR_DNDMMISMATCH:    wStringID=IDS_DNDMMISMATCH;    break;
  134.         case PDERR_CREATEICFAILURE: wStringID=IDS_CREATEICFAILURE; break;
  135.         case PDERR_PRINTERNOTFOUND: wStringID=IDS_PRINTERNOTFOUND; break;
  136.         case CFERR_NOFONTS:         wStringID=IDS_NOFONTS;         break;
  137.         case FNERR_SUBCLASSFAILURE: wStringID=IDS_SUBCLASSFAILURE; break;
  138.         case FNERR_INVALIDFILENAME: wStringID=IDS_INVALIDFILENAME; break;
  139.         case FNERR_BUFFERTOOSMALL:  wStringID=IDS_BUFFERTOOSMALL;  break;
  140.  
  141.         case 0:   //User may have hit CANCEL or we got a *very* random error
  142.             return;
  143.  
  144.         default:
  145.             wStringID=IDS_UNKNOWNERROR;
  146.     }
  147.  
  148.     LoadString(NULL, wStringID, buf, sizeof(buf));
  149.     MessageBox(hWnd, buf, NULL, MB_OK);
  150.     return;
  151. }
  152.  
  153.  
  154. //////////////////////////////////////////////////////////////////////////
  155. //  Function:  GetOpenImageName
  156. //
  157. //  Description:
  158. //    Invokes common dialog function to open a file and opens it, returning
  159. //    the LPHANDLE to the opened file (NULL if failure) and setting the
  160. //    LPTSTR parameter to the FULLY QUALIFIED name of the file which was opened.
  161. //    If the user cancels out of the dialog, the bUserCancelled variable is
  162. //    set to TRUE, allowing the calling function to discriminate between this
  163. //    action and an actual failure of the open dialog calls.
  164. //
  165. //  Parameters:
  166. //    HWND      Handle to the associated window
  167. //    *BOOL     Indicates if user cancelled out of dialog.
  168. //
  169. //  Returns:
  170. //    LPTSTR     Pointer to the buffer to hold the filename.
  171. //
  172. //  Comments:
  173. //
  174. //////////////////////////////////////////////////////////////////////////
  175.  
  176. LPTSTR GetOpenImageName(HWND hWnd , PBOOL pbUserCancel)
  177. {
  178.     // Local variables
  179.     OPENFILENAME    OpenFileName;   // Structure for common dialog File/Open
  180.     TCHAR           szFilter[]=__TEXT("Images(*.BMP,*.DIB)\0*.BMP;*.DIB\0All Files(*.*)\0*.*\0\0");
  181.     TCHAR           szFile[MAX_PATH];
  182.     LPTSTR          lpszFileName;
  183.  
  184.     // Initialize variables
  185.     szFile[0] = __TEXT('\0');
  186.     OpenFileName.lStructSize       = sizeof(OPENFILENAME);
  187.     OpenFileName.hwndOwner         = hWnd;
  188.     OpenFileName.hInstance         = (HANDLE) ghInst;
  189.     OpenFileName.lpstrFilter       = szFilter;
  190.     OpenFileName.lpstrCustomFilter = (LPTSTR) NULL;
  191.     OpenFileName.nMaxCustFilter    = 0L;
  192.     OpenFileName.nFilterIndex      = 1L;
  193.     OpenFileName.lpstrFile         = szFile;
  194.     OpenFileName.nMaxFile          = sizeof(szFile);
  195.     OpenFileName.lpstrFileTitle    = NULL;
  196.     OpenFileName.nMaxFileTitle     = 0;
  197.     OpenFileName.lpstrInitialDir   = NULL;
  198.     OpenFileName.lpstrTitle        = __TEXT("ICMVIEW:  Open Image");
  199.     OpenFileName.nFileOffset       = 0;
  200.     OpenFileName.nFileExtension    = 0;
  201.     OpenFileName.lpstrDefExt       = NULL;  // No default extension
  202.     OpenFileName.lCustData         = 0;
  203.  
  204.     OpenFileName.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
  205.                          OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
  206.                          OFN_EXPLORER | OFN_LONGNAMES;
  207.  
  208.     if (GetOpenFileName(&OpenFileName))
  209.     {
  210.         *pbUserCancel = FALSE;
  211.         // We have a valid filename, let's copy it into the buffer
  212.         lpszFileName = GlobalAlloc(GPTR, (lstrlen(OpenFileName.lpstrFile)+1));
  213.         if (NULL == lpszFileName)
  214.         {
  215.             return(NULL);
  216.         }
  217.         _tcscpy(lpszFileName,OpenFileName.lpstrFile);
  218.     }
  219.     else // User didn't select a file
  220.     {
  221.         *pbUserCancel = TRUE;
  222.         ProcessCDError(CommDlgExtendedError(), hWnd );
  223.         return (NULL);
  224.     }
  225.     return(lpszFileName);
  226. }   // End of GetOpenImageName
  227.  
  228.  
  229. //////////////////////////////////////////////////////////////////////////
  230. //  Function:  fOpenNewImage
  231. //
  232. //  Description:
  233. //    Performs all tasks associated with opening a new file.  This includes
  234. //    creating the File Open common dialog, and if a file was successfully
  235. //    opened, creating a new thread and window to handle the selected image.
  236. //
  237. //  Parameters:
  238. //    HWND    Handle to associated window.
  239. //
  240. //  Returns:
  241. //    BOOL    Indicates if a file was successfully opened.
  242. //
  243. //  Comments:
  244. //
  245. //////////////////////////////////////////////////////////////////////////
  246.  
  247. BOOL fOpenNewImage(HWND hWnd, LPTSTR lpszFileName)
  248. {
  249.     // Local variables
  250.     BOOL        bUserCancelled;   // TRUE if user cancels open dialog
  251.     HGLOBAL     hDIBInfo, hMem;
  252.     BOOL        bRC;
  253.     HCURSOR     hCur;
  254.  
  255.     // If lpszFileName is NULL, get file name from user.
  256.     if (NULL == lpszFileName)
  257.     {
  258.         lpszFileName = GetOpenImageName(hWnd, &bUserCancelled);
  259.         if (lpszFileName == NULL)
  260.         {
  261.             if (!bUserCancelled)
  262.             {
  263.                 ErrMsg(hWnd, __TEXT("fOpenNewImage:  lpszFileName == NULL"));
  264.             }
  265.             return(FALSE);
  266.         }
  267.     }
  268.  
  269.     START_WAIT_CURSOR(hCur);
  270.     hDIBInfo = ReadDIBFile(lpszFileName);
  271.     END_WAIT_CURSOR(hCur);
  272.     if (hDIBInfo)
  273.     {
  274.         LPDIBINFO lpDIBInfo, lpGlobalDIBInfo;
  275.  
  276.         // Add file to recent files list.
  277.         AddRecentFile(hWnd, lpszFileName);
  278.  
  279.         // Copy ICM information from global LPDIBINFO
  280.         lpDIBInfo = GlobalLock(hDIBInfo);
  281.         lpGlobalDIBInfo = GetDIBInfoPtr(ghAppWnd);
  282.         fDuplicateICMInfo(lpDIBInfo, lpGlobalDIBInfo);
  283.  
  284.         // Now copy default options
  285.         lpDIBInfo->bStretch          = lpGlobalDIBInfo->bStretch;
  286.         lpDIBInfo->dwStretchBltMode  = lpGlobalDIBInfo->dwStretchBltMode;
  287.         lpDIBInfo->dwPrintOption     = lpGlobalDIBInfo->dwPrintOption;
  288.  
  289.         CreateNewImageWindow(hDIBInfo);
  290.         GlobalUnlock(GlobalHandle(lpGlobalDIBInfo));
  291.         GlobalUnlock(GlobalHandle(lpDIBInfo));
  292.         bRC = TRUE;
  293.     }
  294.     else
  295.     {
  296.         ErrMsg(hWnd, __TEXT("Unable to open file %s"), lpszFileName);
  297.         bRC = (FALSE);
  298.     }
  299.     hMem = GlobalHandle(lpszFileName);
  300.     GlobalFree(hMem);
  301.     return(bRC);
  302. }   // End of fOpenNewImage
  303.  
  304.  
  305. //////////////////////////////////////////////////////////////////////////
  306. //  Function:  CreateDIBPropSheet
  307. //
  308. //  Description:
  309. //    Creates the property sheet used to describe a DIB.
  310. //
  311. //  Parameters:
  312. //    HWND        Handle to the window which owns the property sheet
  313. //    HINSTANCE   Instance handle
  314. //
  315. //  Returns:
  316. //    int   Return value from the call to Win32 API PropertySheet
  317. //
  318. //  Comments:
  319. //
  320. //////////////////////////////////////////////////////////////////////////
  321. int CreateDIBPropSheet(HWND hwndOwner, HINSTANCE hInst, int nStartPage, LPTSTR lpszCaption)
  322. {
  323.     // Local variables
  324.     PROPSHEETPAGE     PropSheetPage[(DIB_PROPSHEET_MAX+1)];
  325.     PROPSHEETHEADER   PropSheetHdr;
  326.     DIBPROPSHEETINFO  DIBPropSheetInfo[(DIB_PROPSHEET_MAX+1)];
  327.     int               iPropSheet;  // Return code for PropertySheet call
  328.  
  329.     // Initialize vars
  330.     SetLastError(0);
  331.     ASSERT((DIB_PROPSHEET_MIN <= nStartPage) && (DIB_PROPSHEET_MAX >= nStartPage));
  332.     if ((DIB_PROPSHEET_MIN > nStartPage) && (DIB_PROPSHEET_MAX < nStartPage))
  333.     {
  334.         nStartPage = DIB_PROPSHEET_DEFAULT;
  335.     }
  336.  
  337.     // Initialize PROPERTYSHEETHEADER
  338.     PropSheetHdr.dwSize = sizeof(PROPSHEETHEADER);
  339.     PropSheetHdr.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
  340.     PropSheetHdr.hwndParent = hwndOwner;
  341.     PropSheetHdr.hInstance = hInst;
  342.     PropSheetHdr.pszIcon = NULL;
  343.     PropSheetHdr.pszCaption = lpszCaption;
  344.     PropSheetHdr.nPages = sizeof(PropSheetPage) / sizeof(PROPSHEETPAGE);
  345.     PropSheetHdr.ppsp = (LPCPROPSHEETPAGE)&PropSheetPage;
  346.     PropSheetHdr.nStartPage = nStartPage;
  347.  
  348.     // Initialize DIB Display Property Sheet
  349.     PropSheetPage[0].dwSize = sizeof(PROPSHEETPAGE);
  350.     PropSheetPage[0].dwFlags = PSP_USETITLE;
  351.     PropSheetPage[0].hInstance = hInst;
  352.     PropSheetPage[0].pszTemplate = MAKEINTRESOURCE(IDD_DISPLAY);
  353.     PropSheetPage[0].pszIcon = NULL;
  354.     PropSheetPage[0].pfnDlgProc = DlgDIBPropSheet;
  355.     PropSheetPage[0].pszTitle = __TEXT("Display");
  356.     DIBPropSheetInfo[0].uiPageNum = DIB_PROPSHEET_DISPLAY;
  357.     DIBPropSheetInfo[0].hDIBInfo = GetDIBInfoHandle(hwndOwner);
  358.     PropSheetPage[0].lParam = (LPARAM)(LPDIBPROPSHEETINFO)&DIBPropSheetInfo[0];
  359.  
  360.     // Initialize DIB Print Property Sheet
  361.     PropSheetPage[1].dwSize = sizeof(PROPSHEETPAGE);
  362.     PropSheetPage[1].dwFlags = PSP_USETITLE;
  363.     PropSheetPage[1].hInstance = hInst;
  364.     PropSheetPage[1].pszTemplate = MAKEINTRESOURCE(IDD_PRINT);
  365.     PropSheetPage[1].pszIcon = NULL;
  366.     PropSheetPage[1].pfnDlgProc = DlgDIBPropSheet;
  367.     PropSheetPage[1].pszTitle = __TEXT("Printer");
  368.     DIBPropSheetInfo[1].uiPageNum = DIB_PROPSHEET_PRINT;
  369.     DIBPropSheetInfo[1].hDIBInfo = GetDIBInfoHandle(hwndOwner);
  370.     PropSheetPage[1].lParam = (LPARAM)(LPDIBPROPSHEETINFO)&DIBPropSheetInfo[1];
  371.  
  372.     // Create the property sheet and return
  373.     iPropSheet = PropertySheet(&PropSheetHdr);
  374.     return(iPropSheet);
  375. } // End of function CreateDIBPropSheet
  376.  
  377.  
  378. //////////////////////////////////////////////////////////////////////////
  379. //  Function:  DlgDIBPropSheet
  380. //
  381. //  Description:
  382. //    Routine to handle the DIB Display properties property sheet.
  383. //
  384. //  Parameters:
  385. //    @@@
  386. //
  387. //  Returns:
  388. //    @@@
  389. //
  390. //  Comments:
  391. //
  392. //////////////////////////////////////////////////////////////////////////
  393. BOOL APIENTRY DlgDIBPropSheet(HWND hwndPSPage, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  394. {
  395.     // Local variables
  396.     HGLOBAL           hDIBInfo;
  397.     LPDIBINFO         lpDIBInfo;
  398.     static  UINT      uiPageNum = (UINT)UNINIT_DWORD;
  399.     static  LPDIBINFO lpTempDIBInfo = NULL;
  400.     static  HWND      hwndOwner = NULL;
  401.     static  HWND      hwndPSPagePropSheet = NULL;
  402.     HDC     hDC;
  403.     LPTSTR   lpszInitialProfile;
  404.     LPDIBPROPSHEETINFO  lpDIBPropSheetInfo;
  405.  
  406.     // Init variables
  407.     hDC = NULL;
  408.     lpszInitialProfile = NULL;
  409.     switch (uiMsg)
  410.     {
  411.         case WM_INITDIALOG:
  412.             // Save the page number associated w/this page
  413.             lpDIBPropSheetInfo = (LPDIBPROPSHEETINFO) ((LPPROPSHEETPAGE)lParam)->lParam;
  414.             uiPageNum = lpDIBPropSheetInfo->uiPageNum;
  415.             ASSERT(uiPageNum >= DIB_PROPSHEET_MIN && uiPageNum <= DIB_PROPSHEET_MAX);
  416.             SetWindowLong(hwndPSPage, GWL_ID, uiPageNum);
  417.             hDIBInfo = lpDIBPropSheetInfo->hDIBInfo;
  418.             lpDIBInfo = GlobalLock(hDIBInfo);
  419.             hwndOwner = lpDIBInfo->hWndOwner;
  420.             lpTempDIBInfo = fDuplicateDIBInfo(lpTempDIBInfo, lpDIBInfo);
  421.  
  422.             if (uiPageNum == DIB_PROPSHEET_DISPLAY)
  423.             {
  424.                 ASSERT(lpDIBInfo);
  425.  
  426.                 // Copy the DIBINFO structure for the image to a temporary DIBINFO
  427.                 // structure.  If the user presses "OK" or "Accept" to close the
  428.                 // property sheet, the temporary DIBINFO will be copied back into the
  429.                 // image's DIBINFO to reflect any possible changes.
  430.                 ASSERT(lpTempDIBInfo);
  431.                 lpszInitialProfile = lpTempDIBInfo->lpszMonitorProfile;
  432.             }
  433.             else if (uiPageNum == DIB_PROPSHEET_PRINT)
  434.             {
  435.                 lpszInitialProfile = lpTempDIBInfo->lpszPrinterProfile;
  436.             }
  437.  
  438.             GlobalUnlock(hDIBInfo);
  439.             break;
  440.  
  441.         case WM_DESTROY:
  442.             ASSERT(NULL != hwndOwner);
  443.             if (NULL != hwndOwner)
  444.             {
  445.                 InvalidateRect(      hwndOwner,       NULL,       FALSE);
  446.             }
  447.             if (lpTempDIBInfo)
  448.             {
  449.                 fFreeDIBInfo(GlobalHandle(lpTempDIBInfo), FALSE);
  450.             }
  451.             lpTempDIBInfo = NULL;
  452.             break;
  453.  
  454.         case WM_NOTIFY:
  455.             switch (((LPNMHDR)lParam)->code)  // type of notification message
  456.             {
  457.                 case PSN_SETACTIVE:
  458.                     // Initialize the controls
  459.                     uiPageNum = GetWindowLong(hwndPSPage,GWL_ID);
  460.                     if (uiPageNum == DIB_PROPSHEET_PRINT)
  461.                     {
  462.                         PopulatePrinterCombobox(hwndPSPage, IDC_PRINT_PRINTERLIST, lpTempDIBInfo->lpszPrinterName);
  463.                     }
  464.  
  465.                     // Update the dialog based upon the contents of lpDIBInfo
  466.                     DlgDIBInfoPaint(hwndPSPage, lpTempDIBInfo);
  467.                     SetDlgMsgResult(hwndPSPage, uiMsg, FALSE);
  468.                     break;
  469.  
  470.                 case PSN_KILLACTIVE:
  471.                     SaveDIBInfoDlgPage(hwndPSPage, lpTempDIBInfo, uiPageNum);
  472.                     SetDlgMsgResult(hwndPSPage, uiMsg, FALSE);
  473.                     break;
  474.  
  475.                 case PSN_APPLY:
  476.                     lpDIBInfo = GetDIBInfoPtr(hwndOwner);
  477.                     if (NULL == fDuplicateDIBInfo(lpDIBInfo, lpTempDIBInfo ))
  478.                     {
  479.                         ErrMsg(hwndPSPage, __TEXT("fDuplicateDIBInfo:  Failed to copy DIBINFO"));
  480.                     }
  481.                     ASSERT(lpDIBInfo != NULL);
  482.                     GlobalUnlock(GlobalHandle(lpDIBInfo));
  483.                     SetDlgMsgResult(hwndPSPage, uiMsg, PSNRET_NOERROR);
  484.                     break;
  485.  
  486.                 case PSN_RESET:
  487.                     fFreeDIBInfo(lpTempDIBInfo, FALSE);
  488.                     lpTempDIBInfo = NULL;
  489.                     SetDlgMsgResult(hwndPSPage, uiMsg, FALSE);
  490.                     break;
  491.  
  492.                 default:
  493.                     break;
  494.             }
  495.  
  496.         case WM_COMMAND:
  497.             {
  498.                 switch (LOWORD(wParam))
  499.                 {
  500.                     case IDC_DISPLAY_STRETCH:
  501.                         {
  502.                             BOOL  bChecked;
  503.  
  504.                             bChecked = IsDlgButtonChecked(hwndPSPage, IDC_DISPLAY_STRETCH);
  505.                             EnableWindow(GetDlgItem(hwndPSPage, IDC_DISPLAY_ANDSCAN), bChecked);
  506.                             EnableWindow(GetDlgItem(hwndPSPage, IDC_DISPLAY_DELETESCAN), bChecked);
  507.                             EnableWindow(GetDlgItem(hwndPSPage, IDC_DISPLAY_ORSCAN), bChecked);
  508.                         }
  509.                         break;
  510.  
  511.                     case IDC_PRINT_IMAGE:
  512.                         {
  513.                             HCURSOR hCur;
  514.                             HGLOBAL hDIBInfo, hTempDIBInfo;
  515.  
  516.                             START_WAIT_CURSOR(hCur);
  517.                             hDIBInfo = GetDIBInfoHandle(hwndOwner);
  518.                             SaveDIBInfoDlgPage(hwndPSPage, lpTempDIBInfo, uiPageNum);
  519.  
  520.                             // Use current settings
  521.                             hTempDIBInfo = GlobalHandle(lpTempDIBInfo);
  522.                             SetWindowLong(hwndOwner, GWL_DIBINFO, (LONG)hTempDIBInfo);
  523.  
  524.                             PrintImage(hwndOwner);
  525.  
  526.                             //Restore settings
  527.                             SetWindowLong(hwndOwner, GWL_DIBINFO, (LONG)hDIBInfo);
  528.                             END_WAIT_CURSOR(hCur);
  529.                         }
  530.                         break;
  531.  
  532.                     default:
  533.                         break;
  534.                 }
  535.  
  536.             }
  537.         default:
  538.             break;
  539.     }
  540.     return(FALSE);  // FALSE means let the system property sheet code take over
  541. } // End of function DlgDIBPropSheet
  542.  
  543.  
  544. //////////////////////////////////////////////////////////////////////////
  545. //  Function:  DlgDIBInfoPaint
  546. //
  547. //  Description:
  548. //    Update the dialog based upon the contents of lpDIBInfo.  This includes
  549. //    determining which property sheet page is visible, and using this
  550. //    information to populate the device profile ComboBox for the proper
  551. //    device type.
  552. //
  553. //  Parameters:
  554. //    HWND      Handle to the dialog.
  555. //    LPDIBINFO Pointer to DIBINFO structure.
  556. //    LPICMINFO Pointer to ICMINFO structure.
  557. //
  558. //  Returns:
  559. //    void
  560. //
  561. //  Comments:
  562. //
  563. //////////////////////////////////////////////////////////////////////////
  564. void DlgDIBInfoPaint(HWND  hDlg, LPDIBINFO lpDIBInfo)
  565. {
  566.     // Local variables
  567.     UINT    uiPageNum;        // ID's which property sheet page is visible
  568.  
  569.  
  570.     // Initialize variables
  571.     ASSERT(lpDIBInfo != NULL);
  572.     uiPageNum = GetWindowLong(hDlg, GWL_ID);
  573.     ASSERT(uiPageNum <= DIB_PROPSHEET_MAX);
  574.  
  575.     // Update the page-specific elements first
  576.     switch (uiPageNum)
  577.     {
  578.         case DIB_PROPSHEET_DISPLAY:
  579.  
  580.             // Display the display method information
  581.             CheckDlgButton(hDlg, IDC_DISPLAY_STRETCH, lpDIBInfo->bStretch);
  582.  
  583.             // Enable/Disable stretch mode buttons
  584.             EnableWindow(GetDlgItem(hDlg, IDC_DISPLAY_ANDSCAN), lpDIBInfo->bStretch);
  585.             EnableWindow(GetDlgItem(hDlg, IDC_DISPLAY_DELETESCAN), lpDIBInfo->bStretch);
  586.             EnableWindow(GetDlgItem(hDlg, IDC_DISPLAY_ORSCAN), lpDIBInfo->bStretch);
  587.  
  588.             // Select stretch mode if necessary
  589.             ASSERT(lpDIBInfo->dwStretchBltMode >= STRETCH_ANDSCANS);
  590.             ASSERT(lpDIBInfo->dwStretchBltMode <= STRETCH_DELETESCANS);
  591.             switch ((int)(lpDIBInfo->dwStretchBltMode))
  592.             {
  593.                 case STRETCH_ANDSCANS:
  594.                     CheckRadioButton(hDlg, IDC_DISPLAY_ANDSCAN, IDC_DISPLAY_ORSCAN, IDC_DISPLAY_ANDSCAN);
  595.                     break;
  596.                 case STRETCH_DELETESCANS:
  597.                     CheckRadioButton(hDlg, IDC_DISPLAY_ANDSCAN, IDC_DISPLAY_ORSCAN, IDC_DISPLAY_DELETESCAN);
  598.                     break;
  599.                 case STRETCH_ORSCANS:
  600.                     CheckRadioButton(hDlg, IDC_DISPLAY_ANDSCAN, IDC_DISPLAY_ORSCAN, IDC_DISPLAY_ORSCAN);
  601.                     break;
  602.                 default:
  603.                     CheckRadioButton(hDlg, IDC_DISPLAY_ANDSCAN, IDC_DISPLAY_ORSCAN, IDC_DISPLAY_ANDSCAN);
  604.             }
  605.             break;
  606.  
  607.  
  608.         case DIB_PROPSHEET_PRINT:
  609.             // Select print size
  610.             {
  611.                 int iPrintSize = IDC_PRINT_BESTFIT;
  612.  
  613.                 if (lpDIBInfo->dwPrintOption == ICMV_PRINT_ACTUALSIZE)
  614.                 {
  615.                     iPrintSize = IDC_PRINT_ACTUALSIZE;
  616.                 }
  617.                 CheckRadioButton(hDlg, IDC_PRINT_ACTUALSIZE, IDC_PRINT_BESTFIT, iPrintSize);
  618.             }
  619.             break;
  620.  
  621.         default:
  622.             break;
  623.     }
  624.  
  625. } // End of function DlgDIBInfoPaint
  626.  
  627.  
  628. //////////////////////////////////////////////////////////////////////////
  629. //  Function:  SaveDIBInfoDlgPage
  630. //
  631. //  Description:
  632. //    Saves the current page of the property sheet to the specified DIBINFO structure.
  633. //
  634. //  Parameters:
  635. //    @@@
  636. //
  637. //  Returns:
  638. //    BOOL  TRUE upon success, FALSE otherwise
  639. //
  640. //  Comments:
  641. //
  642. //
  643. //////////////////////////////////////////////////////////////////////////
  644. BOOL SaveDIBInfoDlgPage(HWND hDlg, LPDIBINFO lpDIBInfo, UINT uiPageNum)
  645. {
  646.     switch (uiPageNum)
  647.     {
  648.         case DIB_PROPSHEET_DISPLAY:
  649.             lpDIBInfo->bStretch = IsDlgButtonChecked(hDlg, IDC_DISPLAY_STRETCH);
  650.             if (IsDlgButtonChecked(hDlg, IDC_DISPLAY_ANDSCAN))
  651.                 lpDIBInfo->dwStretchBltMode = STRETCH_ANDSCANS;
  652.             else if (IsDlgButtonChecked(hDlg, IDC_DISPLAY_DELETESCAN))
  653.                 lpDIBInfo->dwStretchBltMode = STRETCH_DELETESCANS;
  654.             else if (IsDlgButtonChecked(hDlg, IDC_DISPLAY_ORSCAN))
  655.                 lpDIBInfo->dwStretchBltMode = STRETCH_ORSCANS;
  656.  
  657.             if (CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_ICM20))
  658.             {
  659.                 SetDWFlags((LPDWORD)&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, TRUE);
  660.             }
  661.             break;
  662.  
  663.         case DIB_PROPSHEET_PRINT:
  664.             {
  665.                 LPTSTR  pszTemp;
  666.  
  667.  
  668.                 pszTemp = GetDlgItemString(hDlg, IDC_PRINT_PRINTERLIST, NULL);
  669.                 if ( (NULL != pszTemp)
  670.                      &&
  671.                      (_tcscmp(pszTemp, __TEXT("No printers installed")))
  672.                    )
  673.                 {
  674.                     if (lstrcmpi(pszTemp, lpDIBInfo->lpszPrinterName))
  675.                     {
  676.                         HDC     hPrinterDC;
  677.                         TCHAR   szProfile[MAX_PATH];
  678.                         DWORD   dwSize = MAX_PATH;
  679.  
  680.  
  681.                         GlobalFree(lpDIBInfo->lpszPrinterName);
  682.                         lpDIBInfo->lpszPrinterName = pszTemp;
  683.                         if (NULL != lpDIBInfo->pDevMode)
  684.                             GlobalFree(GlobalHandle(lpDIBInfo->pDevMode));
  685.                         lpDIBInfo->pDevMode = GetDefaultPrinterDevMode(lpDIBInfo->lpszPrinterName);
  686.  
  687.                         hPrinterDC = CreateDC(NULL, lpDIBInfo->lpszPrinterName, NULL, lpDIBInfo->pDevMode);
  688.                         if (NULL != hPrinterDC)
  689.                         {
  690.                             if (GetICMProfile(hPrinterDC, &dwSize, szProfile))
  691.                                 UpdateString(&lpDIBInfo->lpszPrinterProfile, szProfile);
  692.                             DeleteDC(hPrinterDC);
  693.                         }
  694.                     }
  695.                 }
  696.                 else
  697.                 {
  698.                     if (NULL != lpDIBInfo->lpszPrinterName)
  699.                     {
  700.                         GlobalFree(lpDIBInfo->lpszPrinterName);
  701.                         lpDIBInfo->lpszPrinterName = NULL;
  702.                     }
  703.  
  704.                     if (NULL != pszTemp)
  705.                     {
  706.                         GlobalFree(pszTemp);
  707.                     }
  708.                 }
  709.  
  710.                 if (IsDlgButtonChecked(hDlg, IDC_PRINT_ACTUALSIZE))
  711.                 {
  712.                     lpDIBInfo->dwPrintOption = ICMV_PRINT_ACTUALSIZE;
  713.                 }
  714.                 else
  715.                 {
  716.                     lpDIBInfo->dwPrintOption = ICMV_PRINT_BESTFIT;
  717.                 }
  718.             }
  719.             break;
  720.  
  721.         default:
  722.             DebugMsg(__TEXT("DIALOGS.C : SaveDIBInfoDlgPage : Invalid uiPageNum\r\n"));
  723.             return(FALSE);
  724.             break;
  725.     }
  726.     return(TRUE);
  727. }   // End of function SaveDIBInfoDlgPage
  728.  
  729.  
  730. //////////////////////////////////////////////////////////////////////////
  731. //  Function:  GetDlgItemString
  732. //
  733. //  Description:
  734. //    If the specified control identifier text differs from the string
  735. //    passed in, the string will be reallocated to the proper size and
  736. //    the currently displayed item will be copied into the string.
  737. //
  738. //  Parameters:
  739. //    @@@
  740. //
  741. //  Returns:
  742. //    LPTSTR
  743. //
  744. //  Comments:
  745. //
  746. //
  747. //////////////////////////////////////////////////////////////////////////
  748. LPTSTR GetDlgItemString(HWND hDlg, int iControlId, LPTSTR lpszCurrentString)
  749. {
  750.     // Local variables
  751.     TCHAR    szEditString[MAX_PATH + 1];
  752.  
  753.     //  Initialize variables
  754.     if (lpszCurrentString == NULL)
  755.     {
  756.         lpszCurrentString = GlobalAlloc(GPTR, sizeof(TCHAR));
  757.         _tcscpy(lpszCurrentString, __TEXT(""));
  758.     }
  759.  
  760.     GetDlgItemText(hDlg, iControlId, szEditString, MAX_PATH);
  761.     {
  762.         if (_tcscmp(szEditString, lpszCurrentString) != 0)
  763.         {
  764.             // Edit control differs from current string
  765.             HGLOBAL hNewString, hCurrentString;
  766.  
  767.             hCurrentString = GlobalHandle(lpszCurrentString);
  768.             GlobalUnlock(hCurrentString);
  769.             hNewString = GlobalReAlloc(hCurrentString, (lstrlen(szEditString)+1) *sizeof(TCHAR), GMEM_MOVEABLE);
  770.             lpszCurrentString = GlobalLock(hNewString);
  771.  
  772.             _tcscpy(lpszCurrentString, szEditString);
  773.         }
  774.     }
  775.     return(lpszCurrentString);
  776. }   // End of function GetDlgItemString
  777.  
  778.  
  779. //////////////////////////////////////////////////////////////////////////
  780. //  Function:  ColorMatchUI
  781. //
  782. //  Description:
  783. //    Fills in COLORMATCHSETUP structure and calls SetupColorMatching, the new ICM 2.0 UI.
  784. //
  785. //  Parameters:
  786. //    HWND  Owner window; NULL if dialog to have no owner.
  787. //
  788. //  Returns:
  789. //    BOOL
  790. //
  791. //  Comments:
  792. //
  793. //
  794. //////////////////////////////////////////////////////////////////////////
  795.  
  796. BOOL ColorMatchUI(HWND hwndOwner, LPVOID lpvDIBInfo)
  797. {
  798.     // Local variables
  799.     COLORMATCHSETUP     CMSetup;
  800.     BOOL                bSetup;
  801.     TCHAR               stPrinterProfile[MAX_PATH];
  802.     TCHAR               stMonitorProfile[MAX_PATH];
  803.     TCHAR               stTargetProfile[MAX_PATH];
  804.     LPDIBINFO           lpDIBInfo;
  805.     DWORD               dwICMFlags;
  806.     LPBITMAPV5HEADER    lpbi;
  807.  
  808.     //  ASSERTs and parameter validations
  809.     ASSERT((NULL != hwndOwner) && (NULL != lpvDIBInfo));
  810.     if ((NULL == hwndOwner) || (NULL == lpvDIBInfo))
  811.     {
  812.         SetLastError(ERROR_INVALID_PARAMETER);
  813.         return(FALSE);
  814.     }
  815.  
  816.     //  Initialize variables
  817. #ifdef _DEBUG
  818.     memset((PBYTE)&CMSetup, UNINIT_BYTE, sizeof(COLORMATCHSETUP));
  819. #endif
  820.  
  821.     lpDIBInfo = (LPDIBINFO)lpvDIBInfo;
  822.     dwICMFlags = lpDIBInfo->dwICMFlags;
  823.  
  824.     // Fill in required information
  825.     // HACK for differnect versions of ICMUI.
  826.     CMSetup.dwSize    = sizeof(COLORMATCHSETUP);
  827.     CMSetup.dwVersion = COLOR_MATCH_VERSION;
  828.  
  829.     // Set ICM Flags
  830.     CMSetup.dwFlags   = SetColorMatchUIFlags(lpDIBInfo->dwICMFlags) | CMS_USEAPPLYCALLBACK;
  831.     CMSetup.hwndOwner = hwndOwner;
  832.  
  833.     // Fill in source name
  834.     CMSetup.pSourceName   =  NULL;
  835.     lpbi = (LPBITMAPV5HEADER)GlobalLock(lpDIBInfo->hDIB);
  836.     if (IS_BITMAPV5HEADER(lpbi))
  837.     {
  838.         switch (lpbi->bV5CSType)
  839.         {
  840.             case PROFILE_LINKED:
  841.                 CMSetup.pSourceName = (LPCTSTR)GETPROFILEDATA(lpbi);
  842.                 break;
  843.  
  844.             case PROFILE_EMBEDDED:
  845.                 CMSetup.pSourceName = &(__TEXT("Embedded Profile"));
  846.                 break;
  847.  
  848.             default:
  849.                 break;
  850.         }
  851.  
  852.     }
  853.     GlobalUnlock(lpDIBInfo->hDIB);
  854.  
  855.     // Fill in device names
  856.     CMSetup.pDisplayName  =  lpDIBInfo->lpszMonitorName;
  857.     CMSetup.pPrinterName  =  lpDIBInfo->lpszPrinterName;
  858.  
  859.     // Fill in profile names.  Make local copies of the values within
  860.     // the DIBINFO structure, as they may have been allocated to the
  861.     // size of the actual strings.
  862.  
  863.     stPrinterProfile[0] = (TCHAR)'\0';
  864.     if (lpDIBInfo->lpszPrinterProfile)
  865.     {
  866.         _tcscpy((LPTSTR)stPrinterProfile, lpDIBInfo->lpszPrinterProfile);
  867.     }
  868.     CMSetup.pPrinterProfile = (LPTSTR)&stPrinterProfile;
  869.     CMSetup.ccPrinterProfile = MAX_PATH;
  870.  
  871.     stMonitorProfile[0] = (TCHAR)'\0';
  872.     if (lpDIBInfo->lpszMonitorProfile)
  873.     {
  874.         _tcscpy((LPTSTR)stMonitorProfile, lpDIBInfo->lpszMonitorProfile);
  875.     }
  876.     CMSetup.pMonitorProfile = (LPTSTR)&stMonitorProfile;
  877.     CMSetup.ccMonitorProfile = MAX_PATH;
  878.  
  879.     stTargetProfile[0] = (TCHAR)'\0';
  880.     if (lpDIBInfo->lpszTargetProfile)
  881.     {
  882.         _tcscpy((LPTSTR)stTargetProfile, lpDIBInfo->lpszTargetProfile);
  883.     }
  884.     CMSetup.pTargetProfile = (LPTSTR)&stTargetProfile;
  885.     CMSetup.ccTargetProfile = MAX_PATH;
  886.  
  887.     // Set up rendering intents
  888.     CMSetup.dwRenderIntent = lpDIBInfo->dwRenderIntent;
  889.     CMSetup.dwProofingIntent = lpDIBInfo->dwProofingIntent;
  890.  
  891.     // Set up for apply callback.
  892.     CMSetup.lpfnApplyCallback = ColorSetupApply;
  893.     CMSetup.lParamApplyCallback = (LPARAM) lpDIBInfo;
  894.  
  895.     // Clear unused items
  896.     CMSetup.lpfnHook = NULL;
  897.     CMSetup.lParam = (LPARAM)NULL;
  898.  
  899.     // Save ICM state before call
  900.     dwICMFlags = lpDIBInfo->dwICMFlags;
  901.  
  902.  
  903.     // Call the function to create the actual dialog
  904.     SetLastError(0);
  905.     bSetup = SetupColorMatching(&CMSetup);
  906.  
  907.     // Save information from dialog
  908.     if (!bSetup)
  909.     {
  910.         if (ERROR_SUCCESS == GetLastError()) // User cancelled the dialog
  911.         {
  912.             return(TRUE);
  913.         }
  914.         else  // Something unexpected happened
  915.         {
  916.             DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
  917.         }
  918.     }
  919.  
  920.     ApplyColorSettings(lpDIBInfo, &CMSetup);
  921.  
  922.     return(bSetup);
  923. } // End of function ColorMatchUI
  924.  
  925. //////////////////////////////////////////////////////////////////////////
  926. //  Function:  SetColorMatchUIFlags
  927. //
  928. //  Description:
  929. //    Function which converts a DIBINFO's dwFlags to a COLORMATCHSETUP flag.
  930. //
  931. //  Parameters:
  932. //    @@@
  933. //
  934. //  Returns:
  935. //    BOOL
  936. //
  937. //  Comments:
  938. //
  939. //
  940. //////////////////////////////////////////////////////////////////////////
  941. DWORD SetColorMatchUIFlags(DWORD dwDIFlags)
  942. {
  943.     // Local variables
  944.     DWORD       dwCMFlags;      // COLORMATCHSETUP flags
  945.  
  946.     //  ASSERTs and parameter validations
  947.  
  948.     //  Initialize variables
  949.     dwCMFlags = CMS_SETRENDERINTENT | CMS_SETPROOFINTENT | CMS_SETTARGETPROFILE
  950.                 | CMS_SETMONITORPROFILE | CMS_SETPRINTERPROFILE;
  951.  
  952.     if (!CHECK_DWFLAG(dwDIFlags, ICMVFLAGS_ENABLE_ICM))
  953.     {
  954.         dwCMFlags |= CMS_DISABLEICM;
  955.     }
  956.  
  957.     if (CHECK_DWFLAG(dwDIFlags, ICMVFLAGS_PROOFING))
  958.     {
  959.         dwCMFlags |= CMS_ENABLEPROOFING;
  960.     }
  961.     return(dwCMFlags);
  962. } // End of function SetColorMatchUIFlags
  963.  
  964.  
  965. ///////////////////////////////////////////////////////////////////////
  966. //
  967. // Function:   SaveDIBToFileDialog
  968. //
  969. // Purpose:    Gets file name and saves DIB to file.
  970. //
  971. // Parms:
  972. //
  973. ///////////////////////////////////////////////////////////////////////
  974.  
  975. void SaveDIBToFileDialog(HWND hWnd, LPDIBINFO lpDIBInfo)
  976. {
  977.     TCHAR           szFileName[MAX_PATH];
  978.     DWORD           dwSaveAs[3] = {LCS_sRGB, LCS_sRGB, LCS_sRGB};
  979.     OPENFILENAME    OpenFileName;
  980.     PBITMAPV5HEADER pBitmap;
  981.  
  982.  
  983.     // Validate parameters.
  984.     if (NULL == lpDIBInfo)
  985.         return;
  986.  
  987.     // Save bitmap.
  988.     pBitmap = (PBITMAPV5HEADER) GlobalLock(lpDIBInfo->hDIB);
  989.     if (NULL != pBitmap)
  990.     {
  991.         // Initialize OPENFILENAME structure for getting save as file name.
  992.         lstrcpy(szFileName, lpDIBInfo->lpszImageFileName);
  993.         memset(&OpenFileName, 0, sizeof(OPENFILENAME));
  994.         OpenFileName.lStructSize = sizeof(OPENFILENAME);
  995.         OpenFileName.hwndOwner = hWnd;
  996.         OpenFileName.lpstrFile = szFileName;
  997.         OpenFileName.nMaxFile = MAX_PATH;
  998.         OpenFileName.lpstrTitle = __TEXT("Save Bitmap As");
  999.         OpenFileName.Flags = OFN_CREATEPROMPT | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
  1000.         OpenFileName.lpstrDefExt = __TEXT("bmp");
  1001.  
  1002.         if ( (sizeof(BITMAPINFOHEADER) < pBitmap->bV5Size)
  1003.              &&
  1004.              (LCS_CALIBRATED_RGB == pBitmap->bV5CSType)
  1005.            )
  1006.         {
  1007.             // INVARIANT:  Bitmap is a calibrated RGB bitmap.
  1008.  
  1009.             // Can save as sRGB or calibrated bitmap.
  1010.             OpenFileName.lpstrFilter = __TEXT("sRGB Bitmap (*.bmp)\0*.bmp\0Calibrated RGB Bitmap\0 (*.bmp)\0*.bmp\0");
  1011.             dwSaveAs[1] = LCS_CALIBRATED_RGB;
  1012.         }
  1013.         else if ( (sizeof(BITMAPINFOHEADER) < pBitmap->bV5Size)
  1014.                   &&
  1015.                   ( (PROFILE_LINKED == pBitmap->bV5CSType)
  1016.                     ||
  1017.                     (PROFILE_EMBEDDED == pBitmap->bV5CSType)
  1018.                   )
  1019.                 )
  1020.         {
  1021.             // INVARIANT:  Bitmap is either a LINKed or MBEDed bitmap.
  1022.  
  1023.             // Can save as sRGB, linked or embeded,
  1024.             OpenFileName.lpstrFilter = __TEXT("sRGB Bitmap (*.bmp)\0*.bmp\0Linked Bitmap (*.bmp)\0*.bmp\0Embedded Bitmap (*.bmp)\0*.bmp\0\0");
  1025.             dwSaveAs[1] = PROFILE_LINKED;
  1026.             dwSaveAs[2] = PROFILE_EMBEDDED;
  1027.         }
  1028.         else
  1029.         {
  1030.             // Can only save as sRGB bitmap.
  1031.             OpenFileName.lpstrFilter = __TEXT("sRGB Bitmap (*.bmp)\0*.bmp\0\0");
  1032.         }
  1033.  
  1034.         // No longer need hDIB in this routine.
  1035.         GlobalUnlock(lpDIBInfo->hDIB);
  1036.  
  1037.         if (GetSaveFileName(&OpenFileName))
  1038.         {
  1039.             // INVARIANT:  User specified file and choice OK.
  1040.  
  1041.             // Save DIB.
  1042.             SaveDIBToFile(hWnd, OpenFileName.lpstrFile, lpDIBInfo, dwSaveAs[OpenFileName.nFilterIndex -1]);
  1043.         }
  1044.  
  1045.     }
  1046. } // End of function SaveDIBToFileDialog
  1047.  
  1048.  
  1049. ///////////////////////////////////////////////////////////////////////
  1050. //
  1051. // Function:   GetProfileSaveName
  1052. //
  1053. // Purpose:    Gets file name to save profile to.
  1054. //
  1055. // Parms:
  1056. //
  1057. ///////////////////////////////////////////////////////////////////////
  1058.  
  1059. BOOL GetProfileSaveName(HWND hWnd, LPSTR* ppszFileName, DWORD dwSize)
  1060. {
  1061.     OPENFILENAMEA   OpenFileName;
  1062.  
  1063.  
  1064.     // Initialize OPENFILENAME structure for getting save as file name.
  1065.     memset(&OpenFileName, 0, sizeof(OPENFILENAME));
  1066.     OpenFileName.lStructSize = sizeof(OPENFILENAME);
  1067.     OpenFileName.hwndOwner = hWnd;
  1068.     OpenFileName.lpstrFile = *ppszFileName;
  1069.     OpenFileName.nMaxFile = dwSize;
  1070.     OpenFileName.lpstrTitle = "Save Profile As";
  1071.     OpenFileName.Flags = OFN_CREATEPROMPT | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
  1072.     OpenFileName.lpstrFilter = "ICC Color Profile (*.icm, *.icc)\0*.icm;*.icc\0\0";
  1073.     OpenFileName.lpstrDefExt = "icm";
  1074.  
  1075.     return GetSaveFileNameA(&OpenFileName);
  1076. }
  1077.  
  1078.  
  1079. ///////////////////////////////////////////////////////////////////////
  1080. //
  1081. // Function:   ColorSetupApply
  1082. //
  1083. // Purpose:    Applies current color setup dialog values.
  1084. //
  1085. // Parms:
  1086. //
  1087. ///////////////////////////////////////////////////////////////////////
  1088.  
  1089. BOOL WINAPI ColorSetupApply(PCOLORMATCHSETUP pcmSetup, LPARAM lParam)
  1090. {
  1091.     ApplyColorSettings((LPDIBINFO)lParam, pcmSetup);
  1092.     return TRUE;
  1093. }
  1094.  
  1095.  
  1096. ///////////////////////////////////////////////////////////////////////
  1097. //
  1098. // Function:   ApplyColorSettings
  1099. //
  1100. // Purpose:    Applies color settings to dib info.
  1101. //
  1102. // Parms:
  1103. //
  1104. ///////////////////////////////////////////////////////////////////////
  1105.  
  1106. VOID ApplyColorSettings(LPDIBINFO lpDIBInfo, PCOLORMATCHSETUP pCMSetup)
  1107. {
  1108.     DWORD   dwICMFlags = lpDIBInfo->dwICMFlags;
  1109.  
  1110.  
  1111.     // Check if ICM and/or proofing is enabled
  1112.     SetDWFlags(&(lpDIBInfo->dwICMFlags), ICMVFLAGS_PROOFING, CHECK_DWFLAG(pCMSetup->dwFlags, CMS_ENABLEPROOFING));
  1113.     SetDWFlags(&(lpDIBInfo->dwICMFlags), ICMVFLAGS_ENABLE_ICM, (!CHECK_DWFLAG(pCMSetup->dwFlags, CMS_DISABLEICM)));
  1114.     if ((dwICMFlags != lpDIBInfo->dwICMFlags) && (CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_ICM20)))
  1115.     {
  1116.         SetDWFlags(&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, TRUE);
  1117.     }
  1118.  
  1119.     // Update Intents
  1120.     if ((lpDIBInfo->dwRenderIntent != pCMSetup->dwRenderIntent) || (lpDIBInfo->dwProofingIntent != pCMSetup->dwProofingIntent))
  1121.     {
  1122.         SetDWFlags(&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, TRUE);
  1123.     }
  1124.     lpDIBInfo->dwRenderIntent = pCMSetup->dwRenderIntent;
  1125.     lpDIBInfo->dwProofingIntent = pCMSetup->dwProofingIntent;
  1126.  
  1127.     // Update DIBINFO profile strings if CMSetup strings have changed
  1128.     if (0 != _tcscmp(__TEXT(""), pCMSetup->pMonitorProfile))
  1129.     {
  1130.         UpdateString(&(lpDIBInfo->lpszMonitorProfile), pCMSetup->pMonitorProfile);
  1131.         SetDWFlags(&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, TRUE);
  1132.     }
  1133.  
  1134.     if (0 != _tcscmp(__TEXT(""), pCMSetup->pPrinterProfile))
  1135.     {
  1136.         UpdateString(&(lpDIBInfo->lpszPrinterProfile), pCMSetup->pPrinterProfile);
  1137.     }
  1138.  
  1139.     if (0 != _tcscmp(__TEXT(""), pCMSetup->pTargetProfile))
  1140.     {
  1141.         UpdateString(&(lpDIBInfo->lpszTargetProfile),  pCMSetup->pTargetProfile);
  1142.         SetDWFlags(&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, TRUE);
  1143.     }
  1144.  
  1145.     InvalidateRect(lpDIBInfo->hWndOwner, NULL, FALSE);
  1146. }
  1147.  
  1148.  
  1149.  
  1150. //////////////////////////////////////////////////////////////////////////
  1151. //  Function:  PrintDialog
  1152. //
  1153. //  Description:
  1154. //    Displays printing dialog box.
  1155. //
  1156. //  Parameters:
  1157. //    @@@
  1158. //
  1159. //  Returns:
  1160. //    BOOL
  1161. //
  1162. //  Comments:
  1163. //
  1164. //
  1165. //////////////////////////////////////////////////////////////////////////
  1166. BOOL PrintDialog(HWND hWnd, HINSTANCE hInst, LPDIBINFO lpDIBInfo)
  1167. {
  1168.     PRINTDLG    Print;
  1169.  
  1170.  
  1171.     memset(&Print, 0, sizeof(PRINTDLG));
  1172.     Print.lStructSize = sizeof(PRINTDLG);
  1173.     Print.hwndOwner = hWnd;
  1174.     Print.hDevMode = GlobalHandle(lpDIBInfo->pDevMode);
  1175.  
  1176.     if (PrintDlg(&Print))
  1177.     {
  1178.         lpDIBInfo->pDevMode = (PDEVMODE) GlobalLock(Print.hDevMode);
  1179.         if (lstrcmpi(lpDIBInfo->lpszPrinterName, lpDIBInfo->pDevMode->dmDeviceName))
  1180.         {
  1181.             HDC     hPrinterDC;
  1182.             TCHAR   szProfile[MAX_PATH];
  1183.             DWORD   dwSize = MAX_PATH;
  1184.  
  1185.  
  1186.             UpdateString(&lpDIBInfo->lpszPrinterName, lpDIBInfo->pDevMode->dmDeviceName);
  1187.             hPrinterDC = CreateDC(NULL, lpDIBInfo->lpszPrinterName, NULL, lpDIBInfo->pDevMode);
  1188.             if (NULL != hPrinterDC)
  1189.             {
  1190.                 if (GetICMProfile(hPrinterDC, &dwSize, szProfile))
  1191.                     UpdateString(&lpDIBInfo->lpszPrinterProfile, szProfile);
  1192.                 DeleteDC(hPrinterDC);
  1193.             }
  1194.         }
  1195.         PrintImage(hWnd);
  1196.     }
  1197.  
  1198.     return TRUE;
  1199. }
  1200.  
  1201.  
  1202.