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

Windows编程

开发平台:

Visual C++

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