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