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 / child.c < prev    next >
C/C++ Source or Header  |  1997-09-07  |  31KB  |  960 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. //    CHILD.C
  10. //
  11. //  PURPOSE:
  12. //    Routines for child windows.
  13. //
  14. //  PLATFORMS:
  15. //    Windows 95, Windows NT
  16. //
  17. //  SPECIAL INSTRUCTIONS: N/A
  18. //
  19.  
  20. // These pragmas allow for the maximum warning level to be set
  21. // without getting bombarded by warnings from the Windows SDK
  22. // include files.
  23. #pragma warning(disable:4001)   // Single-line comment warnings
  24. #pragma warning(disable:4115)   // Named type definition in parentheses
  25. #pragma warning(disable:4201)   // Nameless struct/union warning
  26. #pragma warning(disable:4214)   // Bit field types other than int warnings
  27. #pragma warning(disable:4514)   // Unreferenced inline function has been removed
  28.  
  29. // Windows Header Files:
  30. #include <Windows.h>
  31. #include <WindowsX.h>
  32. #include <CommCtrl.h>
  33. #include <STDLIB.H>
  34. #include "icm.h"
  35.  
  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.  
  41. // C RunTime Header Files
  42.  
  43. // Local Header Files
  44. #include "icmview.h"
  45. #include "resource.h"
  46. #include "child.h"
  47. #include "DibInfo.H"
  48. #include "dialogs.h"
  49. #include "Dibs.h"
  50. #include "print.h"
  51. #include "debug.h"
  52.  
  53. // Pre-processor definitions and macros
  54.  
  55. // Typedefs and structs
  56.  
  57. typedef struct TAG_PROGRESSPARAM
  58. {
  59.     BOOL    bCancel;
  60.     HWND    hWnd;
  61.     HWND    hDialog;
  62.     DWORD   dwStartTick;
  63. } PROGRESSPARAM, *PPROGRESSPARAM;
  64.  
  65.  
  66. // External global data
  67.  
  68. // Private Global DataPrivate data
  69.  
  70. // Function prototypes
  71. void ChildWndPaint (HWND hWnd);
  72. BOOL ChildWndQueryNewPalette (HWND hWnd, HWND hWndFrame);
  73. BOOL WINAPI TransformProgress(ULONG ulMax, ULONG ulCurrent, ULONG ulCallbackData);
  74. BOOL CALLBACK TransformProgressProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  75. void SizeScrollBars(HWND hWnd, LPDIBINFO lpDIBInfo, UINT uiWindowHeight, UINT uiWindowWidth);
  76. void InitializeScrollBars(HWND hWnd, LPDIBINFO lpDIBInfo);
  77. BOOL ScrollChildWindow(HWND hWnd, int nScrollBar, WORD wScrollCode);
  78.  
  79.  
  80.  
  81. //////////////////////////////////////////////////////////////////////////
  82. //  Function:  ChildWndProc
  83. //
  84. //  Description:
  85. //    Child window procedure.
  86. //
  87. //  Parameters:
  88. //    HWND    handle of window
  89. //    UINT    message identifier
  90. //    WPARAM  first message parameter
  91. //    LPARAM  second message parameter
  92. //
  93. //  Returns:
  94. //
  95. //  Comments:
  96. //
  97. //////////////////////////////////////////////////////////////////////////
  98.  
  99. LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  100. {
  101.     LPDIBINFO   lpDIBInfo;
  102.     int wmId, wmEvent;
  103.  
  104.     // Initialize variables
  105.     lpDIBInfo = GetDIBInfoPtr(hWnd);
  106.     switch (uiMsg)
  107.     {
  108.         case WM_COMMAND:
  109.             wmId    = LOWORD(wParam);
  110.             wmEvent = HIWORD(wParam);
  111.  
  112.             switch (wmId)
  113.             {
  114.                 case ID_FILE_SAVEAS:
  115.                     SaveDIBToFileDialog(hWnd, lpDIBInfo);
  116.                     break;
  117.  
  118.                 case IDM_FILE_PRINT_SETUP:
  119.                     CreateDIBPropSheet(hWnd, ghInst, DIB_PROPSHEET_PRINT, lpDIBInfo->lpszImageFileName);
  120.                     SetFocus(ghAppWnd);
  121.                     break;
  122.  
  123.                 case IDM_FILE_PRINT:
  124.                     PrintDialog(hWnd, ghInst, lpDIBInfo);
  125.                     break;
  126.  
  127.                 case IDM_FILE_DISPLAY:
  128.                     CreateDIBPropSheet(hWnd, ghInst, DIB_PROPSHEET_DISPLAY, lpDIBInfo->lpszImageFileName);
  129.                     InvalidateRect(hWnd, NULL, FALSE);
  130.                     break;
  131.  
  132.                 case IDM_FILE_CLOSE:
  133.                     SendMessage(hWnd, WM_CLOSE, 0, 0);
  134.                     break;
  135.  
  136.                 case IDM_FILE_ICM20:
  137.                 case IDM_FILE_ICM10:
  138.                 case IDM_FILE_CONFIGURE_ICM:
  139.                     {
  140.                         HGLOBAL     hDIBInfo;
  141.                         BOOL        bFreed;
  142.  
  143.                         switch (wmId)
  144.                         {
  145.                             case IDM_FILE_ICM20:
  146.                                 if (!CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_ICM20))  // Don't redundantly transform DIB
  147.                                 {
  148.                                     SetDWFlags((LPDWORD)&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, TRUE);
  149.                                     SetDWFlags((LPDWORD)&(lpDIBInfo->dwICMFlags), (ICMVFLAGS_ICM20), TRUE);
  150.                                 }
  151.                                 break;
  152.  
  153.                             case IDM_FILE_ICM10:
  154.                                 SetDWFlags((LPDWORD)&(lpDIBInfo->dwICMFlags), ICMVFLAGS_ICM20, FALSE);
  155.                                 break;
  156.  
  157.                             case IDM_FILE_CONFIGURE_ICM:
  158.                                 ColorMatchUI(hWnd, lpDIBInfo);
  159.                                 break;
  160.  
  161.                             default:
  162.                                 break;
  163.                         }
  164.                         hDIBInfo = GlobalHandle(lpDIBInfo);
  165.                         bFreed = GlobalUnlock(hDIBInfo);
  166.                         InvalidateRect(hWnd, NULL, FALSE);
  167.                     }
  168.                     break;
  169.  
  170.                 default:
  171.                     return(DefMDIChildProc(hWnd, uiMsg, wParam, lParam));
  172.                     break;
  173.             }
  174.             break;
  175.  
  176.         case WM_CONTEXTMENU:
  177.             {
  178.                 HMENU hMenu;
  179.                 hMenu = InitImageMenu(hWnd);
  180.                 if (hMenu)
  181.                 {
  182.                     TrackPopupMenu (hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
  183.                     DestroyMenu(hMenu);
  184.                 }
  185.                 return(0);
  186.             }
  187.             break;
  188.  
  189.         case WM_PAINT:
  190.             ChildWndPaint(hWnd);
  191.             return(0); // We have processed the message
  192.             break;
  193.  
  194.         case WM_CLOSE:
  195.             SendMessage(ghWndMDIClient, WM_MDIDESTROY, (WPARAM)(HWND)hWnd, 0);
  196.             DestroyWindow(hWnd);
  197.             SetFocus(ghAppWnd);
  198.             return(1L);
  199.  
  200.         case WM_DESTROY:
  201.             fFreeDIBInfo(GetDIBInfoHandle(hWnd), TRUE);
  202.             SetWindowLong(hWnd, GWL_DIBINFO, (LONG)NULL);
  203.             break;
  204.  
  205.         case WM_MDIACTIVATE:
  206.             if (0 != wParam)
  207.             {
  208.                 SendMessage (hWnd, MYWM_QUERYNEWPALETTE, (WPARAM) GetParent(ghWndMDIClient), 0L);
  209.             }
  210.             break;
  211.  
  212.         case WM_SIZE:
  213.             // May need to show or hide scroll bars.
  214.             SizeScrollBars(hWnd, lpDIBInfo, HIWORD(lParam), LOWORD(lParam));
  215.  
  216.             // This makes sure that we redraw
  217.             // all the window if we are stretching to window
  218.             // and the size changes.
  219.             InvalidateRect(hWnd, NULL, FALSE);
  220.             break;
  221.  
  222.         case WM_VSCROLL:
  223.             ScrollChildWindow(hWnd, SB_VERT, LOWORD(wParam));
  224.             return FALSE;
  225.  
  226.         case WM_HSCROLL:
  227.             ScrollChildWindow(hWnd, SB_HORZ, LOWORD(wParam));
  228.             return FALSE;
  229.  
  230.         case MYWM_QUERYNEWPALETTE:
  231.             return ChildWndQueryNewPalette (hWnd, (HWND) wParam);
  232.     }
  233.     return DefMDIChildProc(hWnd, uiMsg, wParam, lParam);
  234. }
  235.  
  236. //////////////////////////////////////////////////////////////////////////
  237. //  Function:  CreateNewImageWindow
  238. //
  239. //  Description:
  240. //    Creates a new window for a new image.  As this function is the
  241. //    startup function for a new thread, some administrative duties
  242. //    are required.  The following actions are taken when the new
  243. //    thread is created:
  244. //      -A new window is created.
  245. //                      -A DIBINFO structure is created and associated with the
  246. //       window via a SetWindowLong call.
  247. //                      -The contents of the DIBINFO structure associated with the
  248. //       main application window are copied into the new window's
  249. //       DIBINFO structure.
  250. //
  251. //  Parameters:
  252. //    DWORD   Actually an LPTSTR to the file name of the image.
  253. //
  254. //  Returns:
  255. //    DWORD to be returned by implicit CloseThread call
  256. //
  257. //  Comments:
  258. //
  259. //////////////////////////////////////////////////////////////////////////
  260.  
  261. DWORD CreateNewImageWindow(HANDLE hDIBInfo)
  262. {
  263.     // Local variables
  264.     int             nWidth;
  265.     int             nHeight;
  266.     HWND            hwndImage;
  267.     HANDLE          hAccel;
  268.     RECT            rcWindow;
  269.     RECT            rcClient;
  270.     LPDIBINFO       lpDIBInfo;
  271.  
  272.  
  273.     //  Initialize variables
  274.     ASSERT(ghWndMDIClient != NULL);  // If it's NULL, won't get a window for thread
  275.     ASSERT(NULL != hDIBInfo);
  276.     if (NULL == hDIBInfo)
  277.     {
  278.         return(FALSE);
  279.     }
  280.     lpDIBInfo = GlobalLock(hDIBInfo);
  281.  
  282.     // Determine the necessary window size to hold the DIB.
  283.     rcWindow.left   = 0;
  284.     rcWindow.top    = 0;
  285.     rcWindow.right  = (int) lpDIBInfo->uiDIBWidth;
  286.     rcWindow.bottom = (int) lpDIBInfo->uiDIBHeight;
  287.  
  288.     if (!AdjustWindowRectEx (&rcWindow,
  289.                              MDIS_ALLCHILDSTYLES|WS_CHILD|WS_SYSMENU|WS_CAPTION|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
  290.                              FALSE, WS_EX_MDICHILD))
  291.     {
  292.         DebugMsg(__TEXT("CreateNewImageWindow:  AdjustWindowRectEx failed, LastError = %lu\r\n"), GetLastError());
  293.         return(ERROR_INVALID_PARAMETER);
  294.     }
  295.  
  296.     // Make sure child window is not larger than parent's client area.
  297.     GetClientRect(ghWndMDIClient, &rcClient);
  298.     nWidth  = __min(rcClient.right, rcWindow.right - rcWindow.left);
  299.     nHeight = __min(rcClient.bottom, rcWindow.bottom - rcWindow.top);
  300.  
  301.     // Create child window; class declaration leaves room for pointer to DIBINFO.
  302.     hwndImage = CreateWindowEx(WS_EX_MDICHILD, CHILD_CLASSNAME,
  303.                                lpDIBInfo->lpszImageFileName,
  304.                                MDIS_ALLCHILDSTYLES | WS_CHILD|WS_SYSMENU|WS_CAPTION|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
  305.                                0, 0, nWidth, nHeight, ghWndMDIClient, NULL, ghInst, 0);
  306.  
  307.     if (hwndImage != NULL)
  308.     {
  309.         // Obtain handle to main window's ICMINFO
  310.         lpDIBInfo->hWndOwner = hwndImage;  // Establish ownership of DIBINFO structure
  311.         SetWindowLong(hwndImage, GWL_DIBINFO, (LONG)hDIBInfo);
  312.  
  313.         // Initial scroll information.
  314.         InitializeScrollBars(hwndImage, lpDIBInfo);
  315.  
  316.         ShowWindow(hwndImage, SW_NORMAL);
  317.         UpdateWindow(hwndImage);
  318.  
  319.         SendMessage(hwndImage, MYWM_QUERYNEWPALETTE, (WPARAM) ghAppWnd, 0L);
  320.     }
  321.     else
  322.     {
  323.         DebugMsg(__TEXT("CreateNewImageWindow:  hwndImage = NULL, LastError = %lu\r\n"), GetLastError);
  324.         return(ERROR_INVALID_PARAMETER);
  325.     }
  326.  
  327.     // Unlock handle
  328.     GlobalUnlock(hDIBInfo);
  329.     lpDIBInfo = NULL;
  330.  
  331.     hAccel = LoadAccelerators(ghInst, __TEXT("ICMVIEW"));
  332.     ASSERT(hAccel);
  333.     return(ERROR_SUCCESS);
  334. }   // End of CreateNewImageWindow
  335.  
  336.  
  337. ///////////////////////////////////////////////////////////////////////
  338. //
  339. // Function:   ChildWndPaint
  340. //
  341. // Purpose:    Called by ChildWndProc() on WM_PAINT.  Does all paints
  342. //             for this MDI child window.
  343. //
  344. //             Reads position of scroll bars to find out what part
  345. //             of the DIB to display.
  346. //
  347. //             Checks the stretching flag in the DIBINFO structure for
  348. //             this window to see if we are stretching to the window
  349. //             (if we're iconic, we always stretch to a tiny bitmap).
  350. //
  351. //             Selects/Realizes the palette as a background palette.
  352. //             The palette was realized as the foreground palette in
  353. //             ChildWndQueryNewPalette() if this is the active window.
  354. //
  355. //
  356. // Parms:      hWnd == Handle to window being painted.
  357. //
  358. ///////////////////////////////////////////////////////////////////////
  359.  
  360. void ChildWndPaint(HWND hWnd)
  361. {
  362.     HDC                 hDC;
  363.     RECT                rectClient;
  364.     RECT                rectDDB;
  365.     BOOL                bStretch;
  366.     HGLOBAL             hDIBInfo;
  367.     LPDIBINFO           lpDIBInfo;
  368.     HANDLE              hDIB;
  369.     LPTSTR              lpszTargetProfile;
  370.     DWORD               dwLCSIntent;
  371.     HCURSOR             hCur;
  372.     PAINTSTRUCT         ps;
  373.     PROGRESSPARAM       ProgressParam;
  374.     LPBITMAPINFOHEADER  lpBi;
  375.  
  376.     // Initialize variables
  377.     lpDIBInfo = NULL;
  378.     lpBi = NULL;
  379.     hDIBInfo = NULL;
  380.     hDIB = NULL;
  381.     lpszTargetProfile = NULL;
  382.  
  383.     START_WAIT_CURSOR(hCur);
  384.     hDC = BeginPaint (hWnd, &ps);
  385.     hDIBInfo = GetDIBInfoHandle(hWnd);
  386.  
  387.     if ( (NULL != hDC)
  388.          &&
  389.          (NULL != hDIBInfo)
  390.          &&
  391.          (RECTWIDTH(&ps.rcPaint) != 0)
  392.          &&
  393.          (RECTHEIGHT(&ps.rcPaint) !=0)
  394.        )
  395.     {
  396.         lpDIBInfo = (LPDIBINFO)GlobalLock(hDIBInfo);
  397.  
  398.         //Check if we're using ICM outside of the DC. If so, it might be necessary to
  399.         // create a color transform.
  400.         if ( CHECK_DWFLAG(lpDIBInfo->dwICMFlags,ICMVFLAGS_ICM20) && CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_ENABLE_ICM))
  401.         {
  402.             // Outside DC selected
  403.             hDIB = lpDIBInfo->hDIBTransformed;
  404.             if (CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_CREATE_TRANSFORM) || (hDIB == NULL))
  405.             {
  406.                 if (NULL != lpDIBInfo->hDIBTransformed)  // Free old transformed bits
  407.                 {
  408.                     GlobalFree(lpDIBInfo->hDIBTransformed);
  409.                 }
  410.                 // Set up for transform
  411.                 if (CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_PROOFING))
  412.                 {
  413.                     lpszTargetProfile = lpDIBInfo->lpszTargetProfile;
  414.                 }
  415.                 // Initialize Progress Param structure.
  416.                 ProgressParam.bCancel = FALSE;
  417.                 ProgressParam.hWnd = hWnd;
  418.                 ProgressParam.hDialog = NULL;
  419.                 ProgressParam.dwStartTick = GetTickCount();
  420.  
  421.                 ConvertIntent(lpDIBInfo->dwRenderIntent, ICC_TO_LCS, &dwLCSIntent);
  422.                 lpDIBInfo->hDIBTransformed = TransformDIBOutsideDC(lpDIBInfo->hDIB,
  423.                                                                    lpDIBInfo->bmFormat,
  424.                                                                    lpDIBInfo->lpszMonitorProfile,
  425.                                                                    lpszTargetProfile,
  426.                                                                    USE_BITMAP_INTENT, NULL, //TransformProgress,
  427.                                                                    (ULONG) &ProgressParam);
  428.                 // May need to destroy progress dialog.
  429.                 if (IsWindow(ProgressParam.hDialog))
  430.                     DestroyWindow(ProgressParam.hDialog);
  431.  
  432.                 if (NULL == lpDIBInfo->hDIBTransformed)
  433.                 {
  434.                     ErrMsg(hWnd, __TEXT("DIB Transform failed.  Disabling ICM"));
  435.                     hDIB = lpDIBInfo->hDIB;
  436.                     SetDWFlags((LPDWORD)&(lpDIBInfo->dwICMFlags), ICMVFLAGS_ENABLE_ICM, FALSE);
  437.                 }
  438.                 else
  439.                 {
  440.                     SetDWFlags((LPDWORD)&(lpDIBInfo->dwICMFlags), ICMVFLAGS_CREATE_TRANSFORM, FALSE);
  441.                     hDIB = lpDIBInfo->hDIBTransformed;
  442.                 }
  443.             }
  444.         }
  445.         else  // Inside DC selected
  446.         {
  447.             hDIB = lpDIBInfo->hDIB;
  448.         }
  449.  
  450.         if (NULL != hDIB)
  451.         {
  452.             lpBi = GlobalLock(hDIB);
  453.         }
  454.         if (NULL == lpBi)
  455.         {
  456.             DebugMsg(__TEXT("CHILD.C : ChildWndPaint : NULL lpBi\r\n"));
  457.             goto ABORTPAINT;
  458.         }
  459.         bStretch = lpDIBInfo->bStretch;
  460.  
  461.         // Set up the necessary rectangles -- i.e. the rectangle
  462.         //  we're rendering into, and the rectangle in the DIB.
  463.         if (bStretch)
  464.         {
  465.             GetClientRect(hWnd, &rectClient);
  466.             rectDDB.left   = 0;
  467.             rectDDB.top    = 0;
  468.             rectDDB.right  = BITMAPWIDTH(lpBi);
  469.             rectDDB.bottom = abs(BITMAPHEIGHT(lpBi));
  470.         }
  471.         else
  472.         {
  473.             int xScroll;
  474.             int yScroll;
  475.  
  476.  
  477.             xScroll  = GetScrollPos(hWnd, SB_HORZ);
  478.             yScroll  = GetScrollPos(hWnd, SB_VERT);
  479.             CopyRect(&rectClient, &ps.rcPaint);
  480.  
  481.             rectDDB.left   = xScroll + rectClient.left;
  482.             rectDDB.top    = yScroll + rectClient.top;
  483.             rectDDB.right  = rectDDB.left + RECTWIDTH(&rectClient);
  484.             rectDDB.bottom = rectDDB.top + RECTHEIGHT(&rectClient);
  485.  
  486.             if (rectDDB.right > BITMAPWIDTH(lpBi))
  487.             {
  488.                 int dx;
  489.  
  490.                 dx = BITMAPWIDTH(lpBi) - rectDDB.right;
  491.                 rectDDB.right     += dx;
  492.                 rectClient.right  += dx;
  493.             }
  494.  
  495.             if (rectDDB.bottom > abs(BITMAPHEIGHT(lpBi)))
  496.             {
  497.                 int dy;
  498.  
  499.                 dy = abs(BITMAPHEIGHT(lpBi)) - rectDDB.bottom;
  500.                 rectDDB.bottom    += dy;
  501.                 rectClient.bottom += dy;
  502.             }
  503.         }
  504.         DIBPaint (hDC, &rectClient, hDIB, &rectDDB, lpDIBInfo);
  505.  
  506.         // Draw the clipboard selection rubber-band.
  507.         SetWindowOrgEx (hDC, GetScrollPos(hWnd, SB_HORZ), GetScrollPos (hWnd, SB_VERT), NULL);
  508.     }
  509.     else
  510.     {
  511.         if (NULL == hDC)
  512.         {
  513.             END_WAIT_CURSOR(hCur);
  514.             DebugMsg(__TEXT("ChildWndPaint : NULL hDC\r\n"));
  515.             return;
  516.         }
  517.     }
  518.  
  519.     ABORTPAINT:
  520.     EndPaint (hWnd, &ps);
  521.     END_WAIT_CURSOR(hCur);
  522.  
  523.     if (hDIB && lpBi)
  524.     {
  525.         GlobalUnlock(hDIB);
  526.     }
  527.     if (lpDIBInfo)
  528.     {
  529.         GlobalUnlock(hDIBInfo);
  530.     }
  531. }
  532.  
  533. ///////////////////////////////////////////////////////////////////////
  534. //
  535. // Function:   ChildWndQueryNewPalette
  536. //
  537. // Purpose:    Called by ChildWndProc() on WM_QUERYNEWPALETTE.
  538. //
  539. //             We get this message when an MDI child is getting
  540. //             focus (by hocus pocus in FRAME.C, and by passing
  541. //             this message when we get WM_MDIACTIVATE).  Normally
  542. //             this message is passed only to the top level window(s)
  543. //             of an application.
  544. //
  545. //             We want this window to have the foreground palette when this
  546. //             happens, so we select and realize the palette as
  547. //             a foreground palette (of the frame Window).  Then make
  548. //             sure the window repaints, if necessary.
  549. //
  550. // Parms:      hWnd      == Handle to window getting WM_QUERYNEWPALETTE.
  551. //             hWndFrame == Handle to the frame window (i.e. the top-level
  552. //                            window of this app.
  553. //
  554. ///////////////////////////////////////////////////////////////////////
  555.  
  556. BOOL ChildWndQueryNewPalette (HWND hWnd, HWND hWndFrame)
  557. {
  558.     HPALETTE  hOldPal;
  559.     HDC       hDC;
  560.     HGLOBAL   hDIBInfo;
  561.     LPDIBINFO lpDIBInfo;
  562.     int       nColorsChanged;
  563.  
  564.     hDIBInfo = GetDIBInfoHandle (hWnd);
  565.  
  566.     if (!hDIBInfo)
  567.         return FALSE;
  568.  
  569.     lpDIBInfo = (LPDIBINFO) GlobalLock (hDIBInfo);
  570.  
  571.     if (!lpDIBInfo->hPal)
  572.     {
  573.         GlobalUnlock (hDIBInfo);
  574.         return FALSE;
  575.     }
  576.  
  577.  
  578.     // We're going to make our palette the foreground palette for
  579.     //  this application.  Window's palette manager expects the
  580.     //  top-level window of the application to have the palette,
  581.     //  so, we get a DC for the frame here!
  582.  
  583.     hDC     = GetDC (hWndFrame);
  584.     hOldPal = SelectPalette (hDC, lpDIBInfo->hPal, FALSE);
  585.  
  586.     nColorsChanged = RealizePalette (hDC);
  587.     InvalidateRect (hWnd, NULL, FALSE);
  588.  
  589.     if (hOldPal)
  590.         SelectPalette (hDC, hOldPal, FALSE);
  591.  
  592.     ReleaseDC (hWndFrame, hDC);
  593.  
  594.     GlobalUnlock (hDIBInfo);
  595.  
  596.     return (nColorsChanged != 0);
  597. }
  598.  
  599.  
  600. //////////////////////////////////////////////////////////////////////////
  601. //  Function:  TransformProgress
  602. //
  603. //  Description:
  604. //
  605. //
  606. //  Parameters:
  607. //    @@@
  608. //
  609. //  Returns:
  610. //    BOOL
  611. //
  612. //  Comments:
  613. //
  614. //
  615. //////////////////////////////////////////////////////////////////////////
  616. BOOL WINAPI TransformProgress(ULONG ulMax, ULONG ulCurrent, ULONG ulCallbackData)
  617. {
  618.     PPROGRESSPARAM  pProgressParam = (PPROGRESSPARAM) ulCallbackData;
  619.  
  620.  
  621.     DebugMsg(__TEXT("TransformProgress:  ulCurrent = %d, ulMax = %d\r\n"), ulCurrent, ulMax);
  622.  
  623.     if (!IsWindow(pProgressParam->hDialog))
  624.     {
  625.         DWORD   dwTick = GetTickCount();
  626.  
  627.         // May need to create progress dialog for translate bitmap bits.
  628.         // Create dialog only if translation takes awhile to do.
  629.         if ( (dwTick - pProgressParam->dwStartTick > 1000L) && ((double)ulCurrent/ulMax < 0.33))
  630.         {
  631.             // Created dialog must be destroyed by TranslateBitmapBits caller.
  632.             pProgressParam->hDialog = CreateDialogParam(NULL, MAKEINTRESOURCE(IDD_TRANSLATE),
  633.                                                         pProgressParam->hWnd, TransformProgressProc,
  634.                                                         (LPARAM) ulCallbackData);
  635.             ShowWindow(pProgressParam->hDialog, SW_SHOWNORMAL);
  636.             UpdateWindow(pProgressParam->hDialog);
  637.             SendDlgItemMessage(pProgressParam->hDialog, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELONG(0, ulMax));
  638.             SendDlgItemMessage(pProgressParam->hDialog, IDC_PROGRESS, PBM_SETPOS, ulCurrent, 0);
  639.         }
  640.     }
  641.     else
  642.     {
  643.         // Update dialog's progress bar.
  644.         SendDlgItemMessage(pProgressParam->hDialog, IDC_PROGRESS, PBM_SETPOS, ulCurrent, 0);
  645.     }
  646.  
  647.     return !pProgressParam->bCancel;
  648. }
  649.  
  650.  
  651.  
  652. //////////////////////////////////////////////////////////////////////////
  653. //  Function:  TransformProgressProc
  654. //
  655. //  Description:
  656. //
  657. //
  658. //  Parameters:
  659. //    @@@
  660. //
  661. //  Returns:
  662. //    BOOL
  663. //
  664. //  Comments:
  665. //
  666. //
  667. //////////////////////////////////////////////////////////////////////////
  668. BOOL CALLBACK TransformProgressProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  669. {
  670.  
  671.     switch (uMsg)
  672.     {
  673.         case WM_INITDIALOG:
  674.             ASSERT(lParam != 0);
  675.             SetWindowLong(hDlg, GWL_USERDATA, lParam);
  676.             return TRUE;
  677.  
  678.         case WM_COMMAND:
  679.             switch (LOWORD(wParam))
  680.             {
  681.                 case IDCANCEL:
  682.                     {
  683.                         PPROGRESSPARAM  pProgressParam = (PPROGRESSPARAM) GetWindowLong(hDlg, GWL_USERDATA);
  684.  
  685.                         pProgressParam->bCancel = TRUE;
  686.                     }
  687.                     break;
  688.             }
  689.             break;
  690.     }
  691.  
  692.     return FALSE;
  693. }
  694.  
  695.  
  696. //////////////////////////////////////////////////////////////////////////
  697. //  Function:  SizeScrollBars
  698. //
  699. //  Description:
  700. //
  701. //
  702. //  Parameters:
  703. //    @@@
  704. //
  705. //  Returns:
  706. //    BOOL
  707. //
  708. //  Comments:
  709. //
  710. //
  711. //////////////////////////////////////////////////////////////////////////
  712. void SizeScrollBars(HWND hWnd, LPDIBINFO lpDIBInfo, UINT uiWindowHeight, UINT uiWindowWidth)
  713. {
  714.     static BOOL    bAdjusting = FALSE;
  715.  
  716.  
  717.     // Only size for validte windows and dib info.
  718.     // Don't SizeScrollBars if in process of adjusting them.
  719.     if ( IsWindow(hWnd)
  720.          &&
  721.          (NULL != lpDIBInfo)
  722.          &&
  723.          !bAdjusting
  724.        )
  725.     {
  726.         int         nScrollHeight = GetSystemMetrics (SM_CXVSCROLL);
  727.         int         nScrollWidth = GetSystemMetrics (SM_CYHSCROLL);
  728.         SCROLLINFO  VertScrollInfo;
  729.         SCROLLINFO  HorzScrollInfo;
  730.  
  731.         // Make sure that we don't get into an infinite loop when updating scroll bars.
  732.         bAdjusting = TRUE;
  733.  
  734.         // Get current vertical scroll info.
  735.         VertScrollInfo.cbSize = sizeof(SCROLLINFO);
  736.         VertScrollInfo.fMask = SIF_ALL;
  737.         GetScrollInfo(hWnd, SB_VERT, &VertScrollInfo);
  738.  
  739.         // Get current horizontal scroll info.
  740.         HorzScrollInfo.cbSize = sizeof(SCROLLINFO);
  741.         HorzScrollInfo.fMask = SIF_ALL;
  742.         GetScrollInfo(hWnd, SB_HORZ, &HorzScrollInfo);
  743.  
  744.         // Only adjust if not stretching to fit.
  745.         // Turn off scroll bars if stretching to fit.
  746.         if (!lpDIBInfo->bStretch)
  747.         {
  748.             // Adjust window width and height to account for current scroll bars.
  749.             if ((int) VertScrollInfo.nPage <= VertScrollInfo.nMax)
  750.             {
  751.                 // INVARIANT:  Vertical scroll bar exists.
  752.  
  753.                 // modify width to account for scroll bars width.
  754.                 uiWindowWidth += nScrollWidth;
  755.             }
  756.             if ((int) HorzScrollInfo.nPage <= HorzScrollInfo.nMax)
  757.             {
  758.                 // INVARIANT:   Horizantal scroll bar exists.
  759.  
  760.                 // Modify height to account for scroll bars height.
  761.                 uiWindowHeight += nScrollHeight;
  762.             }
  763.  
  764.             // Adjust width and height based on what will happen.
  765.             if ((int) uiWindowHeight < VertScrollInfo.nMax)
  766.             {
  767.                 uiWindowWidth -= nScrollWidth;
  768.                 if ((int) uiWindowWidth < HorzScrollInfo.nMax)
  769.                 {
  770.                     uiWindowHeight -= nScrollHeight;
  771.                 }
  772.             }
  773.             else if ((int) uiWindowWidth < HorzScrollInfo.nMax)
  774.             {
  775.                 uiWindowHeight -= nScrollHeight;
  776.                 if ((int) uiWindowHeight < VertScrollInfo.nMax)
  777.                 {
  778.                     uiWindowWidth -= nScrollWidth;
  779.                 }
  780.             }
  781.  
  782.             // If width or height equals bitmap, need to make it larger
  783.             // so that scroll bars will not appear.
  784.             if ((int) uiWindowWidth == HorzScrollInfo.nMax)
  785.             {
  786.                 ++uiWindowWidth;
  787.             }
  788.             if ((int) uiWindowHeight == VertScrollInfo.nMax)
  789.             {
  790.                 ++uiWindowHeight;
  791.             }
  792.         }
  793.         else
  794.         {
  795.             uiWindowHeight = VertScrollInfo.nMax + 1;
  796.             uiWindowWidth = HorzScrollInfo.nMax + 1;
  797.         }
  798.  
  799.         // Update vertical scroll info.
  800.         VertScrollInfo.fMask = SIF_PAGE;
  801.         VertScrollInfo.nPage = uiWindowHeight;
  802.         SetScrollInfo(hWnd, SB_VERT, &VertScrollInfo, FALSE);
  803.  
  804.         // Update horizontal scroll info.
  805.         HorzScrollInfo.fMask = SIF_PAGE;
  806.         HorzScrollInfo.nPage = uiWindowWidth;
  807.         SetScrollInfo(hWnd, SB_HORZ, &HorzScrollInfo, FALSE);
  808.  
  809.         bAdjusting = FALSE;
  810.     }
  811. }
  812.  
  813.  
  814. //////////////////////////////////////////////////////////////////////////
  815. //  Function:  InitializeScrollBars
  816. //
  817. //  Description:
  818. //
  819. //
  820. //  Parameters:
  821. //    @@@
  822. //
  823. //  Returns:
  824. //    BOOL
  825. //
  826. //  Comments:
  827. //
  828. //
  829. //////////////////////////////////////////////////////////////////////////
  830. void InitializeScrollBars(HWND hWnd, LPDIBINFO lpDIBInfo)
  831. {
  832.     RECT        rClient;
  833.     SCROLLINFO  ScrollInfo;
  834.  
  835.  
  836.     // Get windows client size.
  837.     GetClientRect(hWnd, &rClient);
  838.  
  839.     // If client size is equel to dib size, then add one to client size
  840.     // so that we don't show scroll bars.
  841.     // However, if client size is less than dib size, subtract scroll bar
  842.     // size form client size so that page size will be correct when
  843.     // scroll bars are shown.
  844.     if ((UINT) rClient.bottom == lpDIBInfo->uiDIBHeight)
  845.         ++rClient.bottom;
  846.     else if ((UINT) rClient.bottom < lpDIBInfo->uiDIBHeight)
  847.         rClient.bottom -= GetSystemMetrics (SM_CYHSCROLL);
  848.     if ((UINT) rClient.right == lpDIBInfo->uiDIBWidth)
  849.         ++rClient.right;
  850.     else if ((UINT) rClient.right < lpDIBInfo->uiDIBWidth)
  851.         rClient.right -= GetSystemMetrics (SM_CXVSCROLL);
  852.  
  853.     // Initialize vertical scroll bar.
  854.     ScrollInfo.cbSize = sizeof(SCROLLINFO);
  855.     ScrollInfo.fMask = SIF_ALL;
  856.     ScrollInfo.nMin = 0;
  857.     ScrollInfo.nMax = lpDIBInfo->uiDIBHeight;
  858.     ScrollInfo.nPage = rClient.bottom;
  859.     ScrollInfo.nPos = 0;
  860.     SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, TRUE);
  861.  
  862.     // Initialize vertical scroll bar.
  863.     ScrollInfo.nMax = lpDIBInfo->uiDIBWidth;
  864.     ScrollInfo.nPage = rClient.right;
  865.     SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, TRUE);
  866. }
  867.  
  868.  
  869. //////////////////////////////////////////////////////////////////////////
  870. //  Function:  ScrollChildWindow
  871. //
  872. //  Description:
  873. //
  874. //
  875. //  Parameters:
  876. //    @@@
  877. //
  878. //  Returns:
  879. //    BOOL
  880. //
  881. //  Comments:
  882. //
  883. //
  884. //////////////////////////////////////////////////////////////////////////
  885. BOOL ScrollChildWindow(HWND hWnd, int nScrollBar, WORD wScrollCode)
  886. {
  887.     int         nPosition;
  888.     int         nHorzScroll = 0;
  889.     int         nVertScroll = 0;
  890.     SCROLLINFO  ScrollInfo;
  891.  
  892.  
  893.     // Get current scroll information.
  894.     ScrollInfo.cbSize = sizeof(SCROLLINFO);
  895.     ScrollInfo.fMask = SIF_ALL;
  896.     GetScrollInfo(hWnd, nScrollBar, &ScrollInfo);
  897.     nPosition = ScrollInfo.nPos;
  898.  
  899.     // Modify scroll information based on requested
  900.     // scroll action.
  901.     switch (wScrollCode)
  902.     {
  903.         case SB_LINEDOWN:
  904.             ScrollInfo.nPos++;
  905.             break;
  906.  
  907.         case SB_LINEUP:
  908.             ScrollInfo.nPos--;
  909.             break;
  910.  
  911.         case SB_PAGEDOWN:
  912.             ScrollInfo.nPos += ScrollInfo.nPage;
  913.             break;
  914.  
  915.         case SB_PAGEUP:
  916.             ScrollInfo.nPos -= ScrollInfo.nPage;
  917.             break;
  918.  
  919.         case SB_TOP:
  920.             ScrollInfo.nPos = ScrollInfo.nMin;
  921.             break;
  922.  
  923.         case SB_BOTTOM:
  924.             ScrollInfo.nPos = ScrollInfo.nMax;
  925.             break;
  926.  
  927.             // Don't do anything.
  928.         case SB_THUMBPOSITION:
  929.         case SB_THUMBTRACK:
  930.             ScrollInfo.nPos = ScrollInfo.nTrackPos;
  931.             break;
  932.  
  933.         case SB_ENDSCROLL:
  934.             default:
  935.             return FALSE;
  936.     }
  937.  
  938.     // Make sure that scroll position is in range.
  939.     if (0 > ScrollInfo.nPos)
  940.         ScrollInfo.nPos = 0;
  941.     else if (ScrollInfo.nMax - (int) ScrollInfo.nPage + 1 < ScrollInfo.nPos)
  942.         ScrollInfo.nPos = ScrollInfo.nMax  - ScrollInfo.nPage + 1;
  943.  
  944.     // Set new scroll position.
  945.     ScrollInfo.fMask = SIF_POS;
  946.     SetScrollInfo(hWnd, nScrollBar, &ScrollInfo, TRUE);
  947.  
  948.     // Scroll window.
  949.     if (SB_VERT == nScrollBar)
  950.         nVertScroll = nPosition - ScrollInfo.nPos;
  951.     else
  952.         nHorzScroll = nPosition - ScrollInfo.nPos;
  953.  
  954.     ScrollWindowEx(hWnd, nHorzScroll, nVertScroll, NULL, NULL,
  955.                    NULL, NULL, SW_INVALIDATE);
  956.  
  957.     return TRUE;
  958. }
  959.  
  960.