ICMVIEW.C
//THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
//ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
//THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
// PARTICULAR PURPOSE. 
// 
// Copyright  1994-1997  Microsoft Corporation.  All Rights Reserved. 
// 
//  FILE: 
//    ICMVIEW.C 
// 
//  PURPOSE: 
// 
// 
//  PLATFORMS: 
//    Windows 95, Windows NT 
// 
//  SPECIAL INSTRUCTIONS: N/A 
// 
 
// Windows Header Files: 
#pragma warning(disable:4001)   // Single-line comment warnings 
#pragma warning(disable:4115)   // Named type definition in parentheses 
#pragma warning(disable:4201)   // Nameless struct/union warning 
#pragma warning(disable:4214)   // Bit field types other than int warnings 
#pragma warning(disable:4514)   // Unreferenced inline function has been removed 
 
// Windows Header Files: 
#include <Windows.h> 
#include <WindowsX.h> 
#include "icm.h" 
 
// Restore the warnings--leave the single-line comment warning OFF 
#pragma warning(default:4115)   // Named type definition in parentheses 
#pragma warning(default:4201)   // Nameless struct/union warning 
#pragma warning(default:4214)   // Bit field types other than int warnings 
 
// C RunTime Header Files 
#include <stdlib.h> 
#include <stdio.h> 
#include <malloc.h> 
#include <memory.h> 
#include <tchar.h> 
 
// Local Header Files 
#include "Resource.h" 
 
#define   ICMVIEW_INTERNAL 
#include "ICMView.h" 
#undef    ICMVIEW_INTERNAL 
 
#include "Print.H" 
#include "DibInfo.H" 
#include "Dialogs.H" 
#include "AppInit.H" 
#include "child.h" 
#include "Debug.h" 
 
 
// Global Variables: 
HINSTANCE   ghInst;                         // Global instance handle 
TCHAR       gstTitle[MAX_STRING];           // The title bar text 
HWND        ghAppWnd;                       // Handle to application window 
HWND        ghWndMDIClient; 
DWORD       gdwLastError;                   // Used to track last error value 
TCHAR       gstProfilesDir[MAX_PATH];       // System directory for ICM profiles 
 
// Foward declarations of functions included in this code module: 
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); 
 
// 
//  FUNCTION: WinMain(HANDLE, HANDLE, LPTSTR, int) 
// 
//  PURPOSE: Entry point for the application. 
// 
//  COMMENTS: 
// 
//      This function initializes the application and processes the 
//      message loop. 
// 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    MSG msg; 
    HANDLE hAccelTable; 
 
    if (!hPrevInstance) 
    { 
        // Perform instance initialization: 
        if (!InitApplication(hInstance)) 
        { 
            return (FALSE); 
        } 
    } 
 
    // Perform application initialization: 
    if (!InitInstance(hInstance, nCmdShow)) 
    { 
        return (FALSE); 
    } 
 
    hAccelTable = LoadAccelerators (hInstance, APPNAME); 
    ASSERT(hAccelTable); 
 
    // Main message loop: 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
        if ((!TranslateMDISysAccel (ghWndMDIClient, &msg)) 
            && (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg))) 
        { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
    } 
    return (msg.wParam); 
    lpCmdLine; // This will prevent 'unused formal parameter' warnings 
} 
 
// 
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG) 
// 
//  PURPOSE:  Processes messages for the main window. 
// 
//  MESSAGES: 
// 
//      WM_COMMAND - process the application menu 
//      WM_PAINT - Paint the main window 
//      WM_DESTROY - post a quit message and return 
//      WM_DISPLAYCHANGE - message sent to Plug & Play systems when the display changes 
//      WM_RBUTTONDOWN - Right mouse click -- put up context menu here if appropriate 
//      WM_NCRBUTTONUP - User has clicked the right button on the application's system menu 
// 
// 
LRESULT CALLBACK WndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) 
{ 
    int         wmId, wmEvent; 
    POINT       pnt; 
    HMENU       hMenu; 
    int         iDlg; 
 
    // Init variables 
    iDlg = 0; 
 
    switch (uiMsg) 
    { 
 
        case WM_INITMENUPOPUP: 
            InitImageMenu(hwnd); 
            break; 
 
        case WM_CREATE: 
            { 
                CLIENTCREATESTRUCT ccs; 
 
                // Find window menu where children will be listed 
                ccs.hWindowMenu  = GetSubMenu (GetMenu (hwnd), WINDOWMENU_POS); 
                ccs.idFirstChild = FIRSTCHILD; 
 
                // Create the MDI client window, which will fill the client area 
                ghWndMDIClient = CreateWindow ( 
                                              __TEXT("MDICLIENT"), 
                                              NULL, 
                                              WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL, 
                                              0, 
                                              0, 
                                              0, 
                                              0, 
                                              hwnd, 
                                              (HMENU) 0xCAC, 
                                              ghInst, 
                                              (LPTSTR)&ccs); 
 
                ShowWindow (ghWndMDIClient, SW_SHOW); 
                break; 
            } 
 
        case WM_COMMAND: 
            wmId    = LOWORD(wParam); // Remember, these are... 
            wmEvent = HIWORD(wParam); // ...different for Win32! 
 
            //Parse the menu selections: 
            switch (wmId) 
            { 
                case IDM_HELP_ABOUT: 
                    DialogBox(ghInst, __TEXT("AboutBox"), hwnd, (DLGPROC)About); 
                    break; 
 
                case IDM_FILE_EXIT: 
                    DestroyWindow (hwnd); 
                    break; 
 
                case IDM_FILE_OPEN: 
                    fOpenNewImage(hwnd, NULL); 
                    break; 
 
                case IDM_WINDOW_CASCADE: 
                    SendMessage(ghWndMDIClient, WM_MDICASCADE, 0, 0);; 
                    break; 
 
                case IDM_WINDOW_TILE_HORIZONTAL: 
                    SendMessage(ghWndMDIClient, WM_MDITILE, (WPARAM)MDITILE_HORIZONTAL, 0);; 
                    break; 
 
                case IDM_WINDOW_TILE_VERTICAL: 
                    SendMessage(ghWndMDIClient, WM_MDITILE, (WPARAM)MDITILE_VERTICAL, 0);; 
                    break; 
 
                case IDM_WINDOW_ARRANGE: 
                    SendMessage(ghWndMDIClient, WM_MDIICONARRANGE, 0, 0); 
                    break; 
 
                case IDM_FILE_RECENT: 
                case IDM_FILE_RECENT1: 
                case IDM_FILE_RECENT2: 
                case IDM_FILE_RECENT3: 
                    { 
                        HANDLE  hRecent; 
                        LPTSTR  *ppszRecent; 
                        LPTSTR  lpszFileName; 
 
                        // Get handle to recent file list table. 
                        hRecent = GetProp(hwnd, APP_RECENT); 
                        if (NULL != hRecent) 
                        { 
                            // Get pointer to recent file array. 
                            ppszRecent = (LPTSTR*) GlobalLock(hRecent); 
                            ASSERT(NULL != ppszRecent); 
 
                            // Copy file name into buffer. 
                            lpszFileName = GlobalAlloc(GPTR,(lstrlen(ppszRecent[ wmId - IDM_FILE_RECENT]) +1) * sizeof(TCHAR)); 
 
                            // Open the file. 
                            if (lpszFileName != NULL) 
                            { 
                                // Copy recent file name to file name buffer. 
                                _tcscpy(lpszFileName, ppszRecent[ wmId - IDM_FILE_RECENT]); 
                                GlobalUnlock(hRecent); 
 
                                // Open new image of recent file. 
                                fOpenNewImage(hwnd, lpszFileName); 
                            } 
                        } 
                    } 
                    break; 
 
                default: 
                    { 
                        HWND  hwndActiveChild; 
 
                        hwndActiveChild = GetCurrentMDIWnd(); 
                        ASSERT(hwndActiveChild != NULL); 
                        if (hwndActiveChild) 
                        { 
                            PostMessage(hwndActiveChild, uiMsg, wmId, wmEvent); 
                        } 
                        break; 
                    } 
            } 
            break; 
 
        case WM_RBUTTONDOWN: // RightClick in windows client area... 
            pnt.x = LOWORD(lParam); 
            pnt.y = HIWORD(lParam); 
            ClientToScreen(hwnd, (LPPOINT) &pnt); 
            hMenu = GetSubMenu (GetMenu (hwnd), 2); 
            if (hMenu) 
            { 
                TrackPopupMenu (hMenu, 0, pnt.x, pnt.y, 0, hwnd, NULL); 
            } 
            else  // Couldn't find the menu... 
            { 
                MessageBeep(0); 
            } 
            break; 
 
        case WM_DISPLAYCHANGE: // Only comes through on plug'n'play systems 
            { 
                SIZE szScreen; 
                BOOL fChanged = (BOOL)wParam; 
 
                szScreen.cx = LOWORD(lParam); 
                szScreen.cy = HIWORD(lParam); 
            } 
            break; 
 
        case WM_CLOSE: 
            DestroyWindow(hwnd); 
            return 1L; 
 
        case WM_DESTROY: 
            { 
                DWORD             dwFlags = 0L; 
                HANDLE            hRecent; 
                WINDOWPLACEMENT   WndPlacement; 
 
                // Store application settings. 
                dwFlags |= IsZoomed(hwnd) ? IVF_MAXIMIZED : 0L; 
                WndPlacement.length = sizeof(WINDOWPLACEMENT); 
                GetWindowPlacement(hwnd, &WndPlacement); 
                hRecent = GetProp(hwnd, APP_RECENT); 
                SetSettings(&WndPlacement.rcNormalPosition, dwFlags, hRecent); 
 
                // Remove recent file attachment and free memory. 
                RemoveProp(hwnd, APP_RECENT); 
                GlobalFree(hRecent); 
            } 
            PostQuitMessage(0); 
            break; 
 
        case WM_QUERYNEWPALETTE: 
            { 
                HWND hwndActive; 
 
                hwndActive = GetCurrentMDIWnd(); 
                if (NULL != hwndActive) 
                { 
                    return SendMessage(hwndActive, MYWM_QUERYNEWPALETTE, (WPARAM) hwnd, 0L); 
                } 
                return FALSE; 
            } 
 
        case WM_SIZE: 
            InvalidateRect(hwnd, NULL, TRUE); 
            break; 
    } 
    return DefFrameProc(hwnd,ghWndMDIClient, uiMsg, wParam, lParam); 
} 
 
// 
//  FUNCTION: About(HWND, unsigned, WORD, LONG) 
// 
//  PURPOSE:  Processes messages for "About" dialog box 
//              This version allows greater flexibility over the contents of the 'About' box, 
//              by pulling out values from the 'Version' resource. 
// 
//  MESSAGES: 
// 
//      WM_INITDIALOG - initialize dialog box 
//      WM_COMMAND    - Input received 
// 
// 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    static  HFONT hfontDlg;         // Font for dialog text 
    static  HFONT hFinePrint;       // Font for 'fine print' in dialog 
    DWORD   dwVerInfoSize;          // Size of version information block 
    LPTSTR   lpVersion;              // String pointer to 'version' text 
    DWORD   dwVerHnd=0;             // An 'ignored' parameter, always '0' 
    UINT    uVersionLen; 
    int     iRootLen; 
    BOOL    bRetCode; 
    int     i; 
    TCHAR   szFullPath[256]; 
    TCHAR   szResult[256]; 
    TCHAR   szGetName[256]; 
    DWORD   dwVersion; 
    TCHAR   szVersion[40]; 
    DWORD   dwResult; 
 
    wParam = wParam; //Eliminate 'unused formal parameter' warning 
    lParam = lParam; //Eliminate 'unused formal parameter' warning 
 
    switch (message) 
    { 
        case WM_INITDIALOG: 
            ShowWindow (hDlg, SW_HIDE); 
            hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, __TEXT("")); 
            hFinePrint = CreateFont(11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, __TEXT("")); 
            CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); 
            GetModuleFileName (ghInst, szFullPath, sizeof(szFullPath)); 
 
            // Now let's dive in and pull out the version information: 
            dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd); 
            if (dwVerInfoSize) 
            { 
                LPTSTR   lpstrVffInfo; 
                HANDLE  hMem; 
                hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize); 
                lpstrVffInfo  = GlobalLock(hMem); 
                GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo); 
 
                // The below 'hex' value looks a little confusing, but 
                // essentially what it is, is the hexidecimal representation 
                // of a couple different values that represent the language 
                // and character set that we are wanting string values for. 
                // 040904E4 is a very common one, because it means: 
                //   US English, Windows MultiLingual characterset 
                // Or to pull it all apart: 
                // 04//////        = SUBLANG_ENGLISH_USA 
                // --09////        = LANG_ENGLISH 
                // ////04E4 = 1252 = Codepage for Windows:Multilingual 
                _tcscpy(szGetName, __TEXT("\\StringFileInfo\\040904E4\\")); 
                iRootLen = lstrlen(szGetName); // Save this position 
 
                // Set the title of the dialog: 
                lstrcat (szGetName, __TEXT("ProductName")); 
                bRetCode = VerQueryValue((LPVOID)lpstrVffInfo, (LPTSTR)szGetName, (LPVOID)&lpVersion, (UINT *)&uVersionLen); 
                _tcscpy(szResult, __TEXT("About ")); 
                lstrcat(szResult, lpVersion); 
                SetWindowText (hDlg, szResult); 
 
                // Walk through the dialog items that we want to replace: 
                for (i = DLG_VERFIRST; i <= DLG_VERLAST; i++) 
                { 
                    GetDlgItemText(hDlg, i, szResult, sizeof(szResult)); 
                    szGetName[iRootLen] = __TEXT('\0'); 
                    lstrcat (szGetName, szResult); 
                    uVersionLen   = 0; 
                    lpVersion     = NULL; 
                    bRetCode      =  VerQueryValue((LPVOID)lpstrVffInfo, (LPTSTR)szGetName, (LPVOID)&lpVersion, (UINT *)&uVersionLen); 
 
                    if ( bRetCode && uVersionLen && lpVersion) 
                    { 
                        // Replace dialog item text with version info 
                        _tcscpy(szResult, lpVersion); 
                        SetDlgItemText(hDlg, i, szResult); 
                    } 
                    else 
                    { 
                        dwResult = GetLastError(); 
                        wsprintf (szResult,__TEXT("Error %lu"), dwResult); 
                        SetDlgItemText (hDlg, i, szResult); 
                    } 
                    SendMessage (GetDlgItem (hDlg, i), WM_SETFONT, (UINT)((i==DLG_VERLAST)?hFinePrint:hfontDlg), TRUE); 
                } // for (i = DLG_VERFIRST; i <= DLG_VERLAST; i++) 
                GlobalUnlock(hMem); 
                GlobalFree(hMem); 
            } 
            else 
            { 
                // No version information available. 
            } // if (dwVerInfoSize) 
 
            SendMessage (GetDlgItem (hDlg, IDC_LABEL), WM_SETFONT, (WPARAM)hfontDlg,(LPARAM)TRUE); 
 
            // We are  using GetVersion rather then GetVersionEx 
            // because earlier versions of Windows NT and Win32s 
            // didn't include GetVersionEx: 
            dwVersion = GetVersion(); 
            if (dwVersion < 0x80000000) 
            { 
                // Windows NT 
                wsprintf (szVersion,__TEXT("Microsoft Windows NT %u.%u (Build: %u)"), (DWORD)(LOBYTE(LOWORD(dwVersion))), (DWORD)(HIBYTE(LOWORD(dwVersion))),(DWORD)(HIWORD(dwVersion)) ); 
            } 
            else 
            { 
                if (LOBYTE(LOWORD(dwVersion)) < 4) 
                { 
                    // Win32s 
                    wsprintf (szVersion, __TEXT("Microsoft Win32s %u.%u (Build: %u)"), (DWORD)(LOBYTE(LOWORD(dwVersion))), (DWORD)(HIBYTE(LOWORD(dwVersion))),(DWORD)(HIWORD(dwVersion) & ~0x8000) ); 
                } 
                else 
                { 
                    // Windows 95 
                    wsprintf (szVersion, __TEXT("Microsoft Windows 95 %u.%u"), (DWORD)(LOBYTE(LOWORD(dwVersion))), (DWORD)(HIBYTE(LOWORD(dwVersion))) ); 
                } 
            } 
            SetWindowText (GetDlgItem(hDlg, IDC_OSVERSION), szVersion); 
            ShowWindow (hDlg, SW_SHOW); 
            return (TRUE); 
 
        case WM_COMMAND: 
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
            { 
                EndDialog(hDlg, TRUE); 
                DeleteObject (hfontDlg); 
                DeleteObject (hFinePrint); 
                return (TRUE); 
            } 
            break; 
    } 
    return FALSE; 
} 
 
// 
//   FUNCTION: CenterWindow(HWND, HWND) 
// 
//   PURPOSE: Centers one window over another. 
// 
//   COMMENTS: 
// 
//        In this function, we save the instance handle in a global variable and 
//        create and display the main program window. 
// 
//              This function will center one window over another ensuring that 
//              the placement of the window is within the 'working area', meaning 
//              that it is both within the display limits of the screen, and not 
//              obscured by the tray or other framing elements of the desktop. 
BOOL CenterWindow (HWND hwndChild, HWND hwndParent) 
{ 
    RECT    rChild, rParent, rWorkArea; 
    int     wChild, hChild, wParent, hParent; 
    int     xNew, yNew; 
    BOOL    bResult; 
 
    // Get the Height and Width of the child window 
    GetWindowRect (hwndChild, &rChild); 
    wChild = rChild.right - rChild.left; 
    hChild = rChild.bottom - rChild.top; 
 
    // Get the Height and Width of the parent window 
    GetWindowRect (hwndParent, &rParent); 
    wParent = rParent.right - rParent.left; 
    hParent = rParent.bottom - rParent.top; 
 
    // Get the limits of the 'workarea' 
    bResult = SystemParametersInfo( 
                                  SPI_GETWORKAREA, 
                                  sizeof(RECT), 
                                  &rWorkArea, 
                                  0); 
    if (!bResult) 
    { 
        rWorkArea.left = rWorkArea.top = 0; 
        rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); 
        rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); 
    } 
    // Calculate new X position, then adjust for workarea 
    xNew = rParent.left + ((wParent - wChild) / 2); 
    if (xNew < rWorkArea.left) 
    { 
        xNew = rWorkArea.left; 
    } 
    else if ((xNew + wChild) > rWorkArea.right) 
    { 
        xNew = rWorkArea.right - wChild; 
    } 
    // Calcualte new Y position, then adjust for workarea 
    yNew = rParent.top + ((hParent - hChild) /2); 
    if (yNew < rWorkArea.top) 
    { 
        yNew = rWorkArea.top; 
    } 
    else if ((yNew + hChild) > rWorkArea.bottom) 
    { 
        yNew = rWorkArea.bottom - hChild; 
    } 
 
    //Set it and return 
    return(SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER)); 
} 
 
////////////////////////////////////////////////////////////////////////// 
//  Function:  CopyString 
// 
//  Description: 
//    Allocates space and copies one LPTSTR into a new one.  Allocates 
//    exactly as much memory as necessary. 
// 
//  Parameters: 
//    LPTSTR    Source string to be copied. 
// 
//  Returns: 
//    LPTSTR  Pointer to copy of string; NULL if failure. 
// 
//  Comments: 
// 
// 
////////////////////////////////////////////////////////////////////////// 
LPTSTR CopyString(LPTSTR  lpszSrc) 
{ 
    // Local variables 
    LPTSTR    lpszDest; 
    int       iStrLen; 
 
    //  Initialize variables 
    lpszDest = NULL; 
 
    if (lpszSrc == NULL) 
    { 
        DebugMsg(__TEXT("ICMVIEW.C : CopyString : lpszSrc == NULL\r\n")); 
        return(NULL); 
    } 
    iStrLen = ((int)(lstrlen(lpszSrc) +1) * sizeof(TCHAR)); 
    lpszDest = GlobalAlloc(GPTR, iStrLen); 
    _tcscpy(lpszDest, lpszSrc); 
    return(lpszDest); 
}   // End of function CopyString 
 
 
////////////////////////////////////////////////////////////////////////// 
//  Function:  UpdateString 
// 
//  Description: 
//    Replaces target string with source string.  Frees target first 
//    if necessary. 
// 
//  Parameters: 
//    LPTSTR    Destination string 
//    LPTSTR    Source string 
// 
//  Returns: 
//    LPTSTR    Destination string. 
// 
//  Comments: 
// 
// 
////////////////////////////////////////////////////////////////////////// 
BOOL UpdateString(LPTSTR *lpszDest, LPTSTR lpszSrc) 
{ 
    // Local variables 
    HGLOBAL hMem, hDest; 
    LPTSTR  lpszNew; 
 
    //  Initialize variables 
    if (NULL == lpszSrc) 
    { 
        DebugMsg(__TEXT("ICMVIEW.C : UpdateString : NULL source\r\n")); 
        *lpszDest = NULL; 
        return(FALSE); 
    } 
 
    if (NULL != *lpszDest) 
    { 
        hDest = GlobalHandle(*lpszDest); 
        GlobalUnlock(hDest); 
        GlobalFree(hDest); 
    } 
    hMem = GlobalAlloc(GPTR, (1 + lstrlen(lpszSrc))* sizeof(TCHAR)); 
    if (NULL == hMem) 
    { 
        DebugMsg(__TEXT("UpdateString : GlobalAlloc failed\r\n")); 
        return(FALSE); 
    } 
    lpszNew = GlobalLock(hMem); 
    _tcscpy(lpszNew, lpszSrc); 
    *lpszDest = lpszNew; 
    return(TRUE); 
}   // End of function UpdateString 
 
 
 
BOOL ConvertIntent(DWORD dwOrig, DWORD dwDirection, LPDWORD lpdwXlate) 
{ 
    DWORD   adwIntents[MAX_ICC_INTENT + 1] = { LCS_GM_IMAGES, LCS_GM_GRAPHICS, LCS_GM_BUSINESS, LCS_GM_GRAPHICS}; 
    int     idx; 
 
    ASSERT((ICC_TO_LCS == dwDirection) || (LCS_TO_ICC == dwDirection)); 
    *lpdwXlate = (DWORD)-1; 
 
    switch (dwDirection) 
    { 
        case LCS_TO_ICC: 
            for (idx = MAX_ICC_INTENT+1; idx >0; idx--) 
            { 
                if (adwIntents[idx] == dwOrig) 
                { 
                    *lpdwXlate = idx; 
                    return(TRUE); 
                } 
            } 
            break; 
 
        case ICC_TO_LCS: 
            if (dwOrig <= MAX_ICC_INTENT) 
            { 
                *lpdwXlate = adwIntents[dwOrig]; 
                return(TRUE); 
            } 
        default: 
            SetLastError(ERROR_INVALID_PARAMETER); 
            return(FALSE); 
            break; 
    } 
    return(FALSE); 
} 
 
////////////////////////////////////////////////////////////////////////// 
//  Function:  SetDWFlags 
// 
//  Description: 
//    Sets flag values in a DWORD flag. 
// 
//  Parameters: 
//    LPDWORD Pointer to flag variable to be changed. 
//    DWORD   Value to be set/cleared. 
//    BOOL    Indicates if value is to be set or cleared. 
// 
//  Returns: 
//    DWORD   Value of flag variable prior to call. 
// 
//  Comments: 
// 
////////////////////////////////////////////////////////////////////////// 
DWORD SetDWFlags(LPDWORD lpdwFlag, DWORD dwBitValue, BOOL bSet) 
{ 
    // Initialize variables 
    if (bSet) 
    { 
        (*lpdwFlag) |= dwBitValue; 
    } 
    else 
    { 
        (*lpdwFlag) &= (~dwBitValue); 
    } 
    return(*lpdwFlag); 
} // End of function SetDWFlags 
 
 
////////////////////////////////////////////////////////////////////////// 
//  Function:  InitImageMenu 
// 
//  Description: 
//    Handles the WM_CONTEXTMENU message 
// 
//  Parameters: 
//    @@@ 
// 
//  Returns: 
//    LRESULT 
// 
//  Comments: 
// 
// 
////////////////////////////////////////////////////////////////////////// 
HMENU InitImageMenu(HWND hwnd) 
{ 
    // Local variables 
    HMENU       hMenu, hActiveMenu; 
    UINT        uiMenuFlag; 
    LPDIBINFO   lpDIBInfo; 
    HWND        hwndImage; 
 
    //  Initialize variables 
    lpDIBInfo = NULL; 
 
    hwndImage = GetCurrentMDIWnd(); 
    if (hwndImage)  // we have an active child window 
    { 
        lpDIBInfo = GetDIBInfoPtr(hwndImage); 
        if (!lpDIBInfo) 
        { 
            return(NULL); 
        } 
    } 
 
    if (hwnd == ghAppWnd) // dealing with main app window 
    { 
        hMenu = GetMenu(hwnd); 
        hActiveMenu = GetSubMenu(hMenu, IsZoomed(hwndImage) ? 1 : 0); 
        uiMenuFlag = (hwndImage != NULL) ? MF_ENABLED : MF_GRAYED; 
        EnableMenuItem(hActiveMenu, IDM_FILE_CLOSE, uiMenuFlag); 
        EnableMenuItem(hActiveMenu, IDM_FILE_PRINT_SETUP, uiMenuFlag); 
        EnableMenuItem(hActiveMenu, IDM_FILE_PRINT, uiMenuFlag); 
        EnableMenuItem(hActiveMenu, IDM_FILE_DISPLAY, uiMenuFlag); 
        EnableMenuItem(hActiveMenu, IDM_FILE_CONFIGURE_ICM, uiMenuFlag); 
        EnableMenuItem(hActiveMenu, ID_FILE_SAVEAS, uiMenuFlag); 
    } 
    else  // dealing with child window--must init context menu 
    { 
        hMenu = LoadMenu(ghInst, __TEXT("ImageContext")); 
        hActiveMenu = GetSubMenu(hMenu, 0); 
    } 
 
    // Check EITHER ICM 2.0 or ICM 1.0 (Inside DC or Outside DC) 
    if (hActiveMenu && lpDIBInfo) 
    { 
        uiMenuFlag = (CHECK_DWFLAG(lpDIBInfo->dwICMFlags, ICMVFLAGS_ICM20) ? MF_CHECKED : MF_UNCHECKED); 
        CheckMenuItem(hActiveMenu, IDM_FILE_ICM20, uiMenuFlag); 
        CheckMenuItem(hActiveMenu, IDM_FILE_ICM10, uiMenuFlag == MF_CHECKED ? MF_UNCHECKED : MF_CHECKED); 
    } 
 
    if (lpDIBInfo) 
        GlobalUnlock(GlobalHandle(lpDIBInfo)); 
 
    return(hActiveMenu); 
}   // End of function InitImageMenu 
 
////////////////////////////////////////////////////////////////////////// 
//  Function:  GetBaseFilename 
// 
//  Description: 
// 
// 
//  Parameters: 
//      @@@ 
// 
//  Returns: 
//      BOOL 
// 
//  Comments: 
// 
// 
////////////////////////////////////////////////////////////////////////// 
BOOL GetBaseFilename(LPTSTR lpszFilename, LPTSTR *lpszBaseFilename) 
{ 
    // Local variables 
    TCHAR   stFile[MAX_PATH], stExt[MAX_PATH]; 
 
    //  ASSERTs and parameter validations 
    ASSERT(NULL != lpszFilename); 
    if (NULL == lpszFilename) 
    { 
        SetLastError(ERROR_INVALID_PARAMETER); 
        return(FALSE); 
    } 
 
    //  Initialize variables 
    _tsplitpath(lpszFilename, NULL, NULL, stFile, stExt); 
    (*lpszBaseFilename) = (LPTSTR)GlobalAlloc(GPTR, ((_tcslen(stFile) + _tcslen(stExt) + 1 ) * sizeof(TCHAR))); 
    if (NULL != *lpszBaseFilename) 
    { 
        _stprintf(*lpszBaseFilename, __TEXT("%s%s"), stFile, stExt); 
    } 
    //  Cleanup any allocated resources 
    return(NULL != *(lpszBaseFilename)); 
} // End of function GetBaseFilename