windows-nt/Source/XPSP1/NT/com/ole32/stg/async/layoutui/layoutui.cxx
2020-09-26 16:20:57 +08:00

1515 lines
40 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: layoutui.cxx
//
// Contents: UI implementation on Docfile Layout Tool
//
// Classes: CLayoutApp
//
// Functions:
//
// History: 23-Mar-96 SusiA Created
//
//----------------------------------------------------------------------------
#include "layoutui.hxx"
// Constants for File Addition dialogs
#define MAX_FILES_BUFFER 2048
#define MAX_TITLE_LEN 256
#define MAX_FILTER_LEN 256
#define MAX_PREFIX_LEN 5
#define WIDTH 500
#define HEIGHT 300
#define NULL_TERM TEXT('\0')
#define BACKSLASH TEXT("\\")
#define SPACE TEXT(' ')
#define MALLOC(x) LocalAlloc( LMEM_FIXED , x );
#define FREE(x) LocalFree( x );
#define JumpOnFail(sc) if( FAILED(sc) ) goto Err;
#ifdef UNICODE
#define STRING_LEN(x) Laylstrlen(x)
#define CopyString(dst, src) Laylstrcpy(dst, src)
#define CatString(dst, src) Laylstrcat(dst, src)
#else
#define STRING_LEN(x) lstrlen(x)
#define CopyString(dst, src) lstrcpy(dst, src)
#define CatString(dst, src) lstrcat(dst, src)
#endif
// Since the LayoutDlgProc must be static for the Callback,
// we need a way to reference the member variables inside of
// LayoutDlgProc
static CLayoutApp *pStaticThis;
#ifdef STRICT
static WNDPROC lpfnwpListBoxProc = NULL;
static WNDPROC lpfnwpButtonProc = NULL;
#define SUBCLASS_WNDPROC WNDPROC
#else
static FARPROC lpfnwpListBoxProc = NULL;
static FARPROC lpfnwpButtonProc = NULL;
#define SUBCLASS_WNDPROC FARPROC
#endif
// currently supported version of NT
#define NT_MAJOR_VER 3
#define NT_MINOR_VER 51
// currently supported version of Win95
#define WIN95_MAJOR_VER 4
BOOL g_fIsNT351 = FALSE;
//+---------------------------------------------------------------------------
//
// Function IsOperatingSystemOK
//
// Synopsis: Checks to see if thid OS version is compatible
// with this application.
// NT40 Win95 and NT3.51 are supprted.
// Sets g_fIsNT351
//
// History: 27-July-96 SusiA Created
//
//----------------------------------------------------------------------------
BOOL IsOperatingSystemOK(void)
{
OSVERSIONINFO osversioninfo = {0};
// get operating system info
osversioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osversioninfo))
{
return FALSE;
}
// if NT, check version
if (osversioninfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if ( osversioninfo.dwMajorVersion < NT_MAJOR_VER )
{
return FALSE;
}
if ( osversioninfo.dwMajorVersion == NT_MAJOR_VER )
if ( osversioninfo.dwMinorVersion < NT_MINOR_VER )
{
return FALSE;
}
if ( osversioninfo.dwMajorVersion == NT_MAJOR_VER )
if ( osversioninfo.dwMinorVersion == NT_MINOR_VER )
{
g_fIsNT351 = TRUE;
return TRUE;
}
return TRUE;
}
// else if Win95 check version
else if (osversioninfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
if ( osversioninfo.dwMajorVersion < WIN95_MAJOR_VER )
{
return FALSE;
}
else
{
return TRUE;
}
}
// else unrecognized OS (should never make it here)
else
{
return FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::CLayoutApp public
//
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
CLayoutApp::CLayoutApp(HINSTANCE hInst)
{
m_hInst = hInst;
m_hwndMain = hwndNil;
pStaticThis = this;
m_bOptimizing = FALSE;
m_bCancelled = FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::InitApp public
//
// Synopsis: Initialize the application
//
// Returns: TRUE is sucessful, FALSE is FAILED
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
BOOL CLayoutApp::InitApp(void)
{
if (!IsOperatingSystemOK())
{
return FALSE;
}
if( !InitWindow() )
{
DisplayMessage(NULL,
IDS_MAIN_WINDOW_FAIL,
IDS_MAIN_WINDOW_FAIL_TITLE,
MB_ICONSTOP);
return FALSE;
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::DoAppMessageLoop public
//
// Synopsis: Main window message loop
//
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
INT CLayoutApp::DoAppMessageLoop(void)
{
MSG msg;
HACCEL hAccel;
hAccel = LoadAccelerators( m_hInst, MAKEINTRESOURCE(IDR_ACCELERATOR1) );
while (GetMessage (&msg, NULL, 0, 0))
{
if (m_hwndMain == 0 || !IsDialogMessage (m_hwndMain, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return (INT) msg.wParam;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::InitWindow public
//
// Synopsis: Initialize the main window
//
// Returns: TRUE is sucessful, FALSE is FAILED
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
BOOL CLayoutApp::InitWindow (void)
{
m_hwndMain = CreateDialog( m_hInst,
MAKEINTRESOURCE(IDD_MAIN),
NULL,
(DLGPROC)LayoutDlgProc);
if( m_hwndMain == NULL )
return FALSE;
EnableButtons();
DragAcceptFiles(m_hwndMain, TRUE);
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::InitApp public
//
// Synopsis: Application Callback function
//
// Returns: TRUE is message was handled. FALSE otherwise
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
LONG CALLBACK CLayoutApp::ListBoxWndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_SETCURSOR:
if( (HWND)wParam == pStaticThis->m_hwndMain )
SetCursor(LoadCursor(NULL, (pStaticThis->m_bCancelled ? IDC_WAIT : IDC_ARROW)));
return bMsgHandled;
}
return (LONG) CallWindowProc(lpfnwpListBoxProc, hWnd, uMsg, wParam, lParam);
}
LONG CALLBACK CLayoutApp::ButtonWndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_SETCURSOR:
if( (HWND)wParam == pStaticThis->m_hwndMain )
SetCursor(LoadCursor(NULL, (pStaticThis->m_bCancelled ? IDC_WAIT : IDC_ARROW)));
return bMsgHandled;
}
return (LONG) CallWindowProc(lpfnwpButtonProc, hWnd, uMsg, wParam, lParam);
}
BOOL CALLBACK CLayoutApp::LayoutDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
SCODE sc = S_OK;
WORD wId = LOWORD((DWORD)wParam);
WORD wNotifyCode = HIWORD((DWORD)wParam);
DWORD thrdid;
static HANDLE hthread;
switch (uMsg)
{
case WM_INITDIALOG:
pStaticThis->m_hwndBtnAdd = GetDlgItem( hDlg, IDC_BTN_ADD );
pStaticThis->m_hwndBtnRemove = GetDlgItem( hDlg, IDC_BTN_REMOVE );
pStaticThis->m_hwndBtnOptimize = GetDlgItem( hDlg, IDC_BTN_OPTIMIZE );
pStaticThis->m_hwndListFiles = GetDlgItem( hDlg, IDC_LIST_FILES );
pStaticThis->m_hwndStaticFiles = GetDlgItem( hDlg, IDC_STATIC_FILES );
#ifdef _WIN64
lpfnwpListBoxProc = (SUBCLASS_WNDPROC)SetWindowLongPtr(
pStaticThis->m_hwndListFiles,
GWLP_WNDPROC,
(ULONG_PTR)MakeProcInstance(
(FARPROC)ListBoxWndProc,
pStaticThis->m_hInst
)
);
lpfnwpButtonProc = (SUBCLASS_WNDPROC)SetWindowLongPtr(
pStaticThis->m_hwndBtnAdd,
GWLP_WNDPROC,
(ULONG_PTR)MakeProcInstance(
(FARPROC)ButtonWndProc,
pStaticThis->m_hInst
)
);
lpfnwpButtonProc = (SUBCLASS_WNDPROC)SetWindowLongPtr(
pStaticThis->m_hwndBtnRemove,
GWLP_WNDPROC,
(ULONG_PTR)MakeProcInstance(
(FARPROC)ButtonWndProc,
pStaticThis->m_hInst
)
);
lpfnwpButtonProc = (SUBCLASS_WNDPROC)SetWindowLongPtr(
pStaticThis->m_hwndBtnOptimize,
GWLP_WNDPROC,
(ULONG_PTR)MakeProcInstance(
(FARPROC)ButtonWndProc,
pStaticThis->m_hInst
)
);
#else
lpfnwpListBoxProc = (SUBCLASS_WNDPROC)SetWindowLong(
pStaticThis->m_hwndListFiles,
GWL_WNDPROC,
(LONG)(WNDPROC)MakeProcInstance(
(FARPROC)ListBoxWndProc,
pStaticThis->m_hInst
)
);
lpfnwpButtonProc = (SUBCLASS_WNDPROC)SetWindowLong(
pStaticThis->m_hwndBtnAdd,
GWL_WNDPROC,
(LONG)(WNDPROC)MakeProcInstance(
(FARPROC)ButtonWndProc,
pStaticThis->m_hInst
)
);
lpfnwpButtonProc = (SUBCLASS_WNDPROC)SetWindowLong(
pStaticThis->m_hwndBtnRemove,
GWL_WNDPROC,
(LONG)(WNDPROC)MakeProcInstance(
(FARPROC)ButtonWndProc,
pStaticThis->m_hInst
)
);
lpfnwpButtonProc = (SUBCLASS_WNDPROC)SetWindowLong(
pStaticThis->m_hwndBtnOptimize,
GWL_WNDPROC,
(LONG)(WNDPROC)MakeProcInstance(
(FARPROC)ButtonWndProc,
pStaticThis->m_hInst
)
);
#endif // _WIN64
// resize dialog and center it on the screen
{
RECT rcScreen;
GetWindowRect(GetDesktopWindow(), &rcScreen);
SetWindowPos(
hDlg,
HWND_TOP,
(rcScreen.right - rcScreen.left - WIDTH) / 2,
(rcScreen.bottom - rcScreen.top - HEIGHT) / 2,
WIDTH,
HEIGHT,
SWP_SHOWWINDOW);
}
return TRUE;
case WM_SIZE:
pStaticThis->ReSizeWindow(lParam);
return bMsgHandled;
case WM_GETMINMAXINFO:
{
LPMINMAXINFO lpminmax = (LPMINMAXINFO) lParam;
lpminmax->ptMinTrackSize.x = gdxWndMin;
lpminmax->ptMinTrackSize.y = gdyWndMin;
}
return bMsgHandled;
case WM_CLOSE:
DestroyWindow(hDlg);
PostQuitMessage(0);
return bMsgHandled;
case WM_DROPFILES:
{
TCHAR atcFileName[MAX_PATH];
HDROP hdrop = (HDROP)wParam;
INT nFiles = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
INT i;
for( i=0; i < nFiles; i++ )
{
if( DragQueryFile(hdrop, i, atcFileName, MAX_PATH) != 0 )
pStaticThis->AddFileToListBox(atcFileName);
}
DragFinish(hdrop);
pStaticThis->EnableButtons();
}
return bMsgHandled;
case WM_SETCURSOR:
if( (HWND)wParam == pStaticThis->m_hwndMain )
SetCursor(LoadCursor(NULL, (pStaticThis->m_bCancelled ? IDC_WAIT : IDC_ARROW)));
return bMsgHandled;
case WM_COMMAND:
switch( wId )
{
case IDC_BTN_ADD:
pStaticThis->AddFiles();
return bMsgHandled;
case IDC_BTN_REMOVE:
pStaticThis->RemoveFiles();
return bMsgHandled;
case IDC_BTN_OPTIMIZE:
if (pStaticThis->m_bOptimizing) //Cancel Button click
{
pStaticThis->m_bCancelled = TRUE;
//SetCursor(LoadCursor(NULL, IDC_WAIT));
return bMsgHandled;
}
else //Optimize Button Click
{
pStaticThis->m_bOptimizing = TRUE;
pStaticThis->SetActionButton( IDS_CANCEL );
hthread = CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE) &(pStaticThis->OptimizeFiles),
NULL, 0, &thrdid);
return bMsgHandled;
}
case IDC_LIST_FILES:
switch( wNotifyCode )
{
case LBN_SELCHANGE:
pStaticThis->EnableButtons();
return bMsgHandled;
default:
break;
}
default:
break;
}
break;
}
return bMsgNotHandled;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::ReSizeWindow public
//
// Synopsis: Handle resizing the main dialog
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::ReSizeWindow (LPARAM lParam)
{
int nW = LOWORD(lParam);
int nH = HIWORD(lParam);
int nBorder = 10;
int nButtonH = 25;
int nButtonW = 100;
int nStaticH = 15;
int nListY = nBorder + nStaticH;
int nListW = nW - 3 * nBorder - nButtonW;
int nListH = nH - nListY - nBorder;
int nButtonX = 2 * nBorder + nListW;
MoveWindow(m_hwndStaticFiles, nBorder, nBorder, nListW, nStaticH, TRUE);
MoveWindow(m_hwndListFiles , nBorder, nListY, nListW, nH - nButtonH - nBorder, TRUE);
MoveWindow(m_hwndBtnAdd , nButtonX, nListY, nButtonW, nButtonH, TRUE);
MoveWindow(m_hwndBtnRemove , nButtonX, nListY + 3 * nBorder, nButtonW, nButtonH, TRUE);
MoveWindow(m_hwndBtnOptimize, nButtonX, nListY + nListH - nButtonH, nButtonW, nButtonH, TRUE);
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::AddFiles public
//
// Synopsis: Add and display selected files to the dialog window
//
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::AddFiles (void)
{
//We add 1 to atcFile so that we can double null terminate
//the string they give us in the 3.51 case
TCHAR atcFile[MAX_FILES_BUFFER +1 ];
TCHAR atcTitle[MAX_TITLE_LEN];
TCHAR atcFilter[MAX_FILTER_LEN];
OPENFILENAME ofn;
FillMemory( (LPVOID)&ofn, sizeof(ofn), 0 );
ofn.lStructSize = sizeof( ofn );
ofn.hwndOwner = m_hwndMain;
ofn.hInstance = m_hInst;
FormFilterString( atcFilter, MAX_FILTER_LEN );
ofn.lpstrFilter = atcFilter;
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 0;
*atcFile = NULL_TERM;
ofn.lpstrFile = atcFile;
ofn.nMaxFile = MAX_FILES_BUFFER;
ofn.lpstrFileTitle = NULL;
ofn.lpstrInitialDir = NULL;
LoadString( m_hInst, IDS_ADDFILES_TITLE, atcTitle, MAX_TITLE_LEN );
ofn.lpstrTitle = atcTitle;
if (g_fIsNT351) //NT 3.51 doesn't support OFN_EXPLORER
{
ofn.Flags = OFN_ALLOWMULTISELECT |
OFN_HIDEREADONLY |
OFN_FILEMUSTEXIST |
OFN_PATHMUSTEXIST;
}
else
{
ofn.Flags = OFN_ALLOWMULTISELECT |
OFN_HIDEREADONLY |
OFN_EXPLORER |
OFN_FILEMUSTEXIST |
OFN_PATHMUSTEXIST;
}
if( !GetOpenFileName( &ofn ) )
{
DWORD dw = CommDlgExtendedError();
if( dw == FNERR_BUFFERTOOSMALL )
DisplayMessage( m_hwndMain,
IDS_ADDFILES_BUFFERTOOSMALL,
IDS_ADDFILES_BUFFERTOOSMALL_TITLE,
0);
return;
}
WriteFilesToList( atcFile );
EnableButtons();
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::FormFilterString public
//
// Synopsis: Specifies which files (with which extension are to be displayed
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::FormFilterString( TCHAR *patcFilter, INT nMaxLen )
{
int nLen;
UINT uStrID;
//NOTE: the string resources must be in sequence
uStrID = IDS_FILTER_BEGIN+1;
// this is an internal function and so we aren't checking for
// enough room in the string buffer, patcFilter
while( uStrID != IDS_FILTER_END )
{
LoadString( m_hInst, uStrID++, patcFilter, nMaxLen );
nLen = STRING_LEN( patcFilter );
nMaxLen -= nLen + 1;
patcFilter += nLen;
*patcFilter++ = NULL_TERM;
}
*patcFilter = NULL_TERM;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::WriteFilesToList public
//
// Synopsis: For NT4.0 and Win95
// Gets and writes the files, complete with path, to the File List
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::WriteFilesToList( TCHAR *patcFilesList )
{
TCHAR *patcDir;
TCHAR atcFile[MAX_PATH];
BOOL bOneFile = TRUE;
patcDir = patcFilesList;
if (g_fIsNT351)
{
// NT 3.51 stores SPACES instead of NULLs
// between multiple file names
// so we need some preprocessing here
while ( *patcFilesList != NULL_TERM )
{
if (*patcFilesList == SPACE)
{
*patcFilesList = NULL_TERM;
}
patcFilesList++;
}
// and we need to double NULL terminate
*(++patcFilesList) = NULL_TERM;
//reset the pointer to the start
patcFilesList = patcDir;
}
while( *patcFilesList++ != NULL_TERM )
;
while( *patcFilesList != NULL_TERM )
{
bOneFile = FALSE;
CopyString( atcFile, patcDir );
CatString( atcFile, BACKSLASH );
CatString( atcFile, patcFilesList );
AddFileToListBox( atcFile );
while( *patcFilesList++ != NULL_TERM )
;
}
// if only one file was selected,
// the filename isn't separated by it's path,
// but is one complete filename
if( bOneFile )
{
AddFileToListBox( patcDir );
}
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::AddFileToListBox public
//
// Synopsis: displays the file to the dialog list box
//
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::AddFileToListBox( TCHAR *patcFile )
{
// add the file iff the file is not already displayed
if (LB_ERR == SendMessage(m_hwndListFiles,
LB_FINDSTRING,
(WPARAM)0,
(LPARAM)(LPCTSTR)patcFile))
{
SendMessage(m_hwndListFiles,
LB_ADDSTRING,
(WPARAM)0,
(LPARAM)(LPCTSTR)patcFile);
}
SetListBoxExtent();
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::RemoveFileFromListBox public
//
// Synopsis: remove the displayed the file from the dialog list box
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::RemoveFileFromListBox( INT nIndex )
{
SendMessage(m_hwndListFiles,
LB_DELETESTRING,
(WPARAM)nIndex,
(LPARAM)0);
SetListBoxExtent();
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::SetListBoxExtent public
//
// Synopsis: Handles making a horizontal scroll bar if necessary
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::SetListBoxExtent( void )
{
INT i;
INT nExtent = 0;
LPARAM nItems = SendMessage( m_hwndListFiles,
LB_GETCOUNT,
(WPARAM)0,
(LPARAM)0);
TCHAR atcFile[MAX_PATH];
HDC hdc = NULL;
SIZE size;
if( nItems == 0 )
goto lSetListBoxExtent_Exit;
if( (hdc = GetDC(m_hwndMain)) == NULL)
goto lSetListBoxExtent_Exit;
for( i=0; i < (INT) nItems; i++ )
{
SendMessage(m_hwndListFiles,
LB_GETTEXT,
(WPARAM)i,
(LPARAM)(LPCTSTR)atcFile);
GetTextExtentPoint32(
hdc,
atcFile,
STRING_LEN(atcFile),
&size);
nExtent = max(nExtent, (INT)size.cx);
}
lSetListBoxExtent_Exit:
if( hdc )
ReleaseDC( m_hwndMain, hdc );
SendMessage(m_hwndListFiles,
LB_SETHORIZONTALEXTENT,
(WPARAM)nExtent,
(LPARAM)0);
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::RemoveFiles public
//
// Synopsis: remove one or more files from displayed list
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::RemoveFiles (void)
{
INT i;
INT *pnSelItems;;
LPARAM nSelItems = SendMessage( m_hwndListFiles,
LB_GETSELCOUNT,
(WPARAM)0,
(LPARAM)0);
if( nSelItems == 0 )
return;
pnSelItems = (LPINT) MALLOC( sizeof(INT)* (INT)nSelItems );
if( !pnSelItems )
return;
SendMessage(m_hwndListFiles,
LB_GETSELITEMS,
(WPARAM)nSelItems,
(LPARAM)(LPINT)pnSelItems);
// start from bottom of list to keep the indices correct
for( i= (INT)nSelItems; --i >= 0; )
RemoveFileFromListBox( pnSelItems[i] );
FREE( pnSelItems );
EnableButtons();
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::DisplayMessage public
//
// Synopsis: message box general routine with no file names
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
INT CLayoutApp::DisplayMessage(HWND hWnd,
UINT uMessageID,
UINT uTitleID,
UINT uFlags)
{
TCHAR atcMessage[MAX_PATH];
TCHAR atcTitle[MAX_PATH];
LoadString(m_hInst, uMessageID, atcMessage, MAX_PATH);
LoadString(m_hInst, uTitleID, atcTitle, MAX_PATH);
if( hWnd )
SetForegroundWindow(hWnd);
return MessageBox(hWnd, atcMessage, atcTitle, uFlags);
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::DisplayMessageWithFileName public
//
// Synopsis: message box general routine with 1 file name
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
INT CLayoutApp::DisplayMessageWithFileName(HWND hWnd,
UINT uMessageIDBefore,
UINT uMessageIDAfter,
UINT uTitleID,
UINT uFlags,
TCHAR *patcFileName)
{
TCHAR atcMessageBefore[MAX_PATH];
TCHAR atcMessageAfter[MAX_PATH];
TCHAR atcTitle[MAX_PATH];
TCHAR atcFileErrorMsg[MAX_PATH*2];
LoadString(m_hInst, uMessageIDBefore, atcMessageBefore, MAX_PATH);
LoadString(m_hInst, uMessageIDAfter, atcMessageAfter, MAX_PATH);
LoadString(m_hInst, uTitleID, atcTitle, MAX_PATH);
CopyString(atcFileErrorMsg, atcMessageBefore);
CatString(atcFileErrorMsg, patcFileName);
CatString(atcFileErrorMsg, atcMessageAfter);
if( hWnd )
SetForegroundWindow(hWnd);
return MessageBox(hWnd, atcFileErrorMsg, atcTitle, uFlags);
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::DisplayMessageWithTwoFileNames public
//
// Synopsis: message box general routine with 2 file names
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
INT CLayoutApp::DisplayMessageWithTwoFileNames(HWND hWnd,
UINT uMessageID,
UINT uTitleID,
UINT uFlags,
TCHAR *patcFirstFileName,
TCHAR *patcLastFileName)
{
TCHAR atcMessage[MAX_PATH];
TCHAR atcTitle[MAX_PATH];
TCHAR atcFileErrorMsg[MAX_PATH*2];
LoadString(m_hInst, uMessageID, atcMessage, MAX_PATH);
LoadString(m_hInst, uTitleID, atcTitle, MAX_PATH);
CopyString(atcFileErrorMsg, patcFirstFileName);
CatString(atcFileErrorMsg, atcMessage);
CatString(atcFileErrorMsg, patcLastFileName);
if( hWnd )
SetForegroundWindow(hWnd);
return MessageBox(hWnd, atcFileErrorMsg, atcTitle, uFlags);
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::EnableButtons public
//
// Synopsis: Updates the buttons. Optimize turns to Cancel
// during optimize function.
// Remove is greyed if no files are displayed
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::EnableButtons( BOOL bShowOptimizeBtn )
{
LPARAM nItems = SendMessage( m_hwndListFiles,
LB_GETCOUNT,
(WPARAM)0,
(LPARAM)0);
LPARAM nSelItems = SendMessage( m_hwndListFiles,
LB_GETSELCOUNT,
(WPARAM)0,
(LPARAM)0);
EnableWindow( m_hwndBtnAdd, TRUE );
EnableWindow( m_hwndBtnRemove, nSelItems > 0 );
EnableWindow( m_hwndBtnOptimize, nItems > 0 && bShowOptimizeBtn );
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::OptimizeFiles public
//
// Synopsis: Static function to call the optimizeFiles worker routine
//
// Returns: Appropriate status code
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
DWORD CLayoutApp::OptimizeFiles (void *args)
{
SCODE sc;
sc = CoInitialize(NULL);
sc = pStaticThis->OptimizeFilesWorker();
CoUninitialize();
pStaticThis->HandleOptimizeReturnCode(sc);
pStaticThis->m_bCancelled = FALSE;
pStaticThis->SetActionButton( IDS_OPTIMIZE );
pStaticThis->m_bOptimizing = FALSE;
//SetCursor(LoadCursor(NULL, IDC_ARROW));
return 0;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::OptimizeFilesWorker public
//
// Synopsis: Optimize all the displayed files. Make temp files,
// optimize to temp file, then rename temp back to original file.
//
// Returns: Appropriate status code
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
SCODE CLayoutApp::OptimizeFilesWorker (void)
{
INT i, j;
SCODE sc = S_OK;
HRESULT hr;
TCHAR atcFileName[MAX_PATH];
TCHAR atcTempPath[MAX_PATH];
TCHAR atcTempFile[MAX_PATH];
TCHAR atcPrefix[MAX_PREFIX_LEN];
TCHAR **ppatcTempFiles = NULL;
INT *pintErrorFlag = NULL;
INT nItems = (INT) SendMessage( m_hwndListFiles,
LB_GETCOUNT,
(WPARAM)0,
(LPARAM)0 );
if( nItems == 0 )
return S_OK;
ppatcTempFiles = (TCHAR **) MALLOC( sizeof(TCHAR *) * nItems );
if( !ppatcTempFiles )
return STG_E_INSUFFICIENTMEMORY;
FillMemory( (LPVOID)ppatcTempFiles, sizeof(TCHAR *) * nItems, 0 );
pintErrorFlag = (INT *) MALLOC( sizeof(INT) * nItems );
if( !pintErrorFlag )
{
sc = STG_E_INSUFFICIENTMEMORY;
JumpOnFail(sc);
}
FillMemory( (LPVOID)pintErrorFlag, sizeof(INT) * nItems, 0 );
if( GetTempPath( MAX_PATH, atcTempPath ) == 0 )
{
sc = GetLastError();
JumpOnFail(sc);
}
LoadString( m_hInst, IDS_TEMPFILE_PREFIX, atcPrefix, MAX_PREFIX_LEN );
for( i=0; i < nItems; i++ )
{
// handle Cancel pressed and cleanup
if (m_bCancelled)
{
m_bCancelled = FALSE;
for( j=0; j < i ; j++ )
DeleteFile(ppatcTempFiles[j]);
sc = STG_E_NONEOPTIMIZED;
JumpOnFail(sc);
}
if( GetTempFileName( atcTempPath, atcPrefix, (UINT)0, atcTempFile ) == 0 )
{
sc = GetLastError();
JumpOnFail(sc);
}
ppatcTempFiles[i] =
(TCHAR *) MALLOC( (STRING_LEN(atcTempFile) + 1) * sizeof(TCHAR) );
if( !ppatcTempFiles[i] )
{
sc = STG_E_INSUFFICIENTMEMORY;
JumpOnFail(sc);
}
CopyString( ppatcTempFiles[i], atcTempFile );
}
for( i=0; i < nItems; i++ )
{
// handle Cancel pressed and cleanup
if (m_bCancelled)
{
m_bCancelled = FALSE;
for( j=i; j < nItems ; j++ )
{
DeleteFile(ppatcTempFiles[j]);
pintErrorFlag[j] = 1;
}
sc = STG_E_NONEOPTIMIZED;
for( j=nItems; --j >= 0; )
{
if (pintErrorFlag[j])
{
RemoveFileFromListBox(j);
}
else
{
sc = S_OK;
}
}
EnableButtons();
goto Err;
}
SendMessage( m_hwndListFiles,
LB_GETTEXT,
(WPARAM)i,
(LPARAM)(LPINT)atcFileName );
sc = DoOptimizeFile( atcFileName, ppatcTempFiles[i] );
#if DBG==1
//check that files are identical here.
if ((SUCCEEDED(sc)) && (!IdenticalFiles( atcFileName, ppatcTempFiles[i])))
{
sc = STG_E_DOCFILECORRUPT;
}
#endif
if (!SUCCEEDED(sc))
{
// This file could not be optimized. Display Error message
switch( sc )
{
// the file is read only
case STG_E_ACCESSDENIED:
DisplayMessageWithFileName(m_hwndMain,
IDS_FILE_BEFORE,
IDS_FILE_AFTER_READ_ONLY,
IDS_OPTIMIZE_FAILED_TITLE,
0,
atcFileName);
break;
// the file is not in a legal docfile format.
case STG_E_FILEALREADYEXISTS:
DisplayMessageWithFileName(m_hwndMain,
IDS_FILE_BEFORE,
IDS_FILE_AFTER_NOTDOCFILE,
IDS_OPTIMIZE_FAILED_TITLE,
0,
atcFileName);
break;
default:
DisplayMessageWithFileName(m_hwndMain,
IDS_FILE_BEFORE,
IDS_OPTIMIZE_ERROR,
IDS_OPTIMIZE_FAILED_TITLE,
0,
atcFileName);
break;
}
pintErrorFlag[i] = 1;
DeleteFile( ppatcTempFiles[i] );
continue;
}
//remove the (unoptimized) original file
hr = DeleteFile( atcFileName );
if (!hr)
{
sc = GetLastError();
DisplayMessageWithFileName(m_hwndMain,
IDS_FILE_BEFORE,
IDS_DELETE_ERROR,
IDS_OPTIMIZE_FAILED_TITLE,
0,
atcFileName);
DisplayMessageWithTwoFileNames(m_hwndMain,
IDS_RENAME_MESSAGE,
IDS_OPTIMIZE_FAILED_TITLE,
0,
atcFileName,
ppatcTempFiles[i]);
SendMessage( m_hwndListFiles,
LB_DELETESTRING,
(WPARAM)i,
(LPARAM)0);
SendMessage( m_hwndListFiles,
LB_INSERTSTRING,
(WPARAM)i,
(LPARAM)(LPINT)ppatcTempFiles[i] );
continue;
}
// rename the optimized file to the original file name
hr = MoveFile( ppatcTempFiles[i], atcFileName );
if (!hr)
{
sc = GetLastError();
DisplayMessageWithFileName(m_hwndMain,
IDS_FILE_BEFORE,
IDS_RENAME_ERROR,
IDS_OPTIMIZE_FAILED_TITLE,
0,
ppatcTempFiles[i]);
DisplayMessageWithTwoFileNames(m_hwndMain,
IDS_RENAME_MESSAGE,
IDS_OPTIMIZE_FAILED_TITLE,
0,
atcFileName,
ppatcTempFiles[i]);
SendMessage( m_hwndListFiles,
LB_DELETESTRING,
(WPARAM)i,
(LPARAM)0);
SendMessage( m_hwndListFiles,
LB_INSERTSTRING,
(WPARAM)i,
(LPARAM)(LPINT)ppatcTempFiles[i] );
continue;
}
DeleteFile( ppatcTempFiles[i] );
}
// remove files from list box that could not be optimized
//bSuccess is set if at least one file was sucessfully optimized.
sc = STG_E_NONEOPTIMIZED;
for( i=nItems; --i >= 0; )
{
if (pintErrorFlag[i])
{
RemoveFileFromListBox(i);
}
else
{
sc = S_OK;
}
}
EnableButtons();
Err:
if ( pintErrorFlag )
FREE( pintErrorFlag);
if( ppatcTempFiles )
{
for( i=0; i < nItems; i++ )
{
if( ppatcTempFiles[i] )
FREE( ppatcTempFiles[i] );
}
FREE( ppatcTempFiles );
}
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::DoOptimizeFile public
//
// Synopsis: Monitor and relayout docfile to temp file.
//
// Returns: Appropriate status code
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
SCODE CLayoutApp::DoOptimizeFile( TCHAR *patcFileName, TCHAR *patcTempFile )
{
IStorage *pStg = NULL;
ILayoutStorage *pLayoutStg = NULL;
IUnknown *punkApp = NULL;
IPersistStorage *pPersist = NULL;
IOleObject *pObj = NULL;
COleClientSite *pSite = NULL;
SCODE sc = S_OK;
STATSTG stat;
OLECHAR awcNewFileName[MAX_PATH];
sc = StgOpenLayoutDocfile
(TCharToOleChar(patcFileName, awcNewFileName, MAX_PATH),
STGM_DIRECT |
STGM_READWRITE |
STGM_SHARE_EXCLUSIVE,
NULL,
&pStg);
JumpOnFail(sc);
sc = pStg->QueryInterface( IID_ILayoutStorage, (void**) &pLayoutStg );
JumpOnFail(sc);
pStg->Release();
// begin monitoring
sc = pLayoutStg->BeginMonitor();
JumpOnFail(sc);
sc = pStg->Stat(&stat, STATFLAG_NONAME);
JumpOnFail(sc);
// open the application type of the input storage
sc = CoCreateInstance( stat.clsid,
NULL,
(CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD),
IID_IUnknown,
(void**) &punkApp );
JumpOnFail(sc);
// load the document through the IPersistStorage Interface
sc = punkApp->QueryInterface( IID_IPersistStorage, (void**) &pPersist );
JumpOnFail(sc);
punkApp->Release();
sc = pPersist->Load( pStg );
JumpOnFail(sc);
sc = punkApp->QueryInterface( IID_IOleObject, (void**) &pObj );
JumpOnFail(sc);
punkApp->Release();
// Open as a client
pSite = new COleClientSite;
pSite->m_patcFile = patcFileName;
sc = pObj->DoVerb(OLEIVERB_OPEN, NULL, (IOleClientSite*) pSite, 0, NULL, NULL);
JumpOnFail(sc);
pObj->Close( OLECLOSE_NOSAVE );
// end monitoring and relayout
if( pLayoutStg )
{
sc = pLayoutStg->EndMonitor();
JumpOnFail(sc);
sc = pLayoutStg->ReLayoutDocfile(
TCharToOleChar(patcTempFile, awcNewFileName, MAX_PATH) );
JumpOnFail(sc);
}
Err:
if( pStg )
pStg->Release();
if( punkApp )
punkApp->Release();
if( pSite )
pSite->Release();
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::HandleOptimizeReturnCode public
//
// Synopsis: message box general routine to display apprpriate message
// based on the Optimize returned SCODE
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::HandleOptimizeReturnCode( SCODE sc )
{
switch( sc )
{
case S_OK:
DisplayMessage(m_hwndMain, IDS_OPTIMIZE_SUCCESS, IDS_OPTIMIZE_SUCCESS_TITLE, 0);
break;
case STG_E_FILENOTFOUND:
case STG_E_INSUFFICIENTMEMORY:
DisplayMessage(m_hwndMain, IDS_OPTIMIZE_OUTOFMEM, IDS_OPTIMIZE_OUTOFMEM_TITLE, 0);
break;
case STG_E_PATHNOTFOUND:
DisplayMessage(m_hwndMain, IDS_OPTIMIZE_NOPATH, IDS_OPTIMIZE_NOPATH_TITLE, 0);
break;
case STG_E_NONEOPTIMIZED:
// already displayed errors for why each file could not be optimized.
break;
default:
DisplayMessage(m_hwndMain, IDS_OPTIMIZE_FAILED, IDS_OPTIMIZE_FAILED_TITLE, 0);
break;
}
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::TCharToOleChar public
//
// Synopsis: helper function for UNICODE/ANSI TCHAR to OLEchar conversion
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
OLECHAR *CLayoutApp::TCharToOleChar(TCHAR *patcSrc, OLECHAR *pawcDst, INT nDstLen)
{
#ifdef UNICODE
// this is already UNICODE
return patcSrc;
#else
UINT uCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
*pawcDst = NULL_TERM;
// convert to UNICODE
MultiByteToWideChar(
uCodePage,
0,
patcSrc,
-1,
pawcDst,
nDstLen-1 );
return pawcDst;
#endif
}
//+---------------------------------------------------------------------------
//
// Member: CLayoutApp::SetActionButton public
//
// Synopsis: change the text of the button
//
// History: 03-April-96 SusiA Created
//
//----------------------------------------------------------------------------
VOID CLayoutApp::SetActionButton( UINT uID )
{
TCHAR atcText[MAX_PATH];
LoadString( m_hInst, uID, atcText, MAX_PATH );
SetWindowText( m_hwndBtnOptimize, atcText );
UpdateWindow( m_hwndMain );
}