674 lines
11 KiB
C++
Raw Normal View History

/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//
// XLStuff.cpp
//
//
#include "stdAfx.h"
#include "Babylon.h"
#include "resource.h"
#include <stdio.h>
#include "xlstuff.h"
#include <assert.h>
#include <comdef.h>
static const int xlWorkbookNormal = -4143;
static const int xlNoChange = 1;
static const int xlLocalSessionChanges = 2;
static const int xlWBATWorksheet = -4167;
static _Workbook *workbook = NULL;
static _Application *xl = NULL;
static Workbooks *wbs = NULL;
static Range *range = NULL;
static _Worksheet *ws = NULL;
static OLECHAR buffer[100*1024];
static VARIANT no, yes, dummy, dummy0, nullstring, empty;
static VARIANT continuous, automatic, medium, thin, none;
static VARIANT yellow, solid;
static VARIANT GetCell ( int row, int column )
{
VARIANT cell;
VARIANT result;
LPDISPATCH dispatch;
OLECHAR cellname[20];
V_VT ( &cell ) = VT_EMPTY;
assert ( column > 0 );
swprintf ( cellname, L"%c%d", 'A'+column -1 , row );
V_VT ( &cell ) = VT_BSTR;
V_BSTR ( &cell ) = SysAllocString (cellname);
V_VT ( &result ) = VT_BOOL;
V_BOOL ( &result ) = FALSE;
if ( !ws )
{
goto error;
}
if ( ! (dispatch = ws->GetRange (cell, cell )))
{
goto error;
}
range->AttachDispatch ( dispatch );
result = range->GetValue ();
range->ReleaseDispatch ( );
error:
VariantClear ( &cell );
return result;
}
int PutCell ( int row, int column, OLECHAR *string, int val )
{
VARIANT cell;
VARIANT newValue;
int ok = FALSE;
LPDISPATCH dispatch;
OLECHAR cellname[20];
V_VT ( &newValue ) = VT_EMPTY;
V_VT ( &cell ) = VT_EMPTY;
assert ( column > 0 );
swprintf ( cellname, L"%c%d", 'A'+column-1, row );
V_VT ( &cell ) = VT_BSTR;
V_BSTR ( &cell ) = SysAllocString (cellname);
if ( !ws )
{
goto error;
}
if ( ! (dispatch = ws->GetRange (cell, cell )))
{
goto error;
}
range->AttachDispatch ( dispatch );
if ( string )
{
V_VT ( &newValue ) = VT_BSTR;
if ( string[0] == '\'')
{
buffer[0] = '\\';
wcscpy ( &buffer[1], string );
V_BSTR ( &newValue ) = SysAllocString ( buffer );
}
else
{
V_BSTR ( &newValue ) = SysAllocString ( string );
}
}
else
{
V_VT ( &newValue ) = VT_I4;
V_I4 ( &newValue ) = val;
}
range->SetValue ( newValue );
range->ReleaseDispatch ( );
ok = TRUE;
error:
VariantClear ( &cell );
VariantClear ( &newValue );
return ok;
}
int PutSeparator ( int row )
{
// Rows(row).Select
// Selection.Borders(xlDiagonalDown).LineStyle = xlNone
// Selection.Borders(xlDiagonalUp).LineStyle = xlNone
// Selection.Borders(xlEdgeLeft).LineStyle = xlNone
// Selection.Borders(xlEdgeTop).LineStyle = xlNone
// With Selection.Borders(xlEdgeBottom)
// .LineStyle = xlContinuous
// .Weight = xlMedium
// .ColorIndex = xlAutomatic
// End With
// With Selection.Borders(xlEdgeRight)
// .LineStyle = xlContinuous
// .Weight = xlThin
// .ColorIndex = xlAutomatic
// End With
int ok = FALSE;
Border *border = NULL;
Borders *borders = NULL;
LPDISPATCH dispatch;
OLECHAR cellname1[20];
OLECHAR cellname2[20];
VARIANT cell1,cell2;
if ( !ws )
{
goto error;
}
assert ( row > 0 );
swprintf ( cellname1, L"A%d", row );
swprintf ( cellname2, L"%c%d", 'A'+CELL_LAST-1-1, row );
V_VT ( &cell1 ) = VT_BSTR;
V_BSTR ( &cell1 ) = SysAllocString (cellname1);
V_VT ( &cell2 ) = VT_BSTR;
V_BSTR ( &cell2 ) = SysAllocString (cellname2);
if ( ! (dispatch = ws->GetRange (cell1, cell2 )))
{
goto error;
}
range->AttachDispatch ( dispatch );
dispatch = range->GetBorders ();
borders = new Borders ( dispatch );
if ( !borders )
{
goto error;
}
dispatch = borders->GetItem ( xlEdgeBottom );
border = new Border ( dispatch );
if ( !border )
{
goto error;
}
border->SetLineStyle ( continuous );
border->SetColorIndex ( automatic );
border->SetWeight ( thin );
ok = TRUE;
error:
range->ReleaseDispatch ( );
if ( borders )
{
delete borders ;
}
if ( border )
{
delete border ;
}
VariantClear ( &cell1 );
VariantClear ( &cell2 );
return ok;
}
int PutSection ( int row, OLECHAR *title )
{
int ok = FALSE;
Range *range = NULL;
Border *border = NULL;
Borders *borders = NULL;
Interior *interior = NULL;
LPDISPATCH dispatch;
OLECHAR cellname1[20];
OLECHAR cellname2[20];
VARIANT cell1,cell2;
_Worksheet *ws = NULL;
if ( !ws )
{
goto error;
}
assert ( row > 0 );
swprintf ( cellname1, L"A%d", row );
swprintf ( cellname2, L"%c%d", 'A'+CELL_LAST-1-1, row );
V_VT ( &cell1 ) = VT_BSTR;
V_BSTR ( &cell1 ) = SysAllocString (cellname1);
V_VT ( &cell2 ) = VT_BSTR;
V_BSTR ( &cell2 ) = SysAllocString (cellname2);
if ( ! (dispatch = ws->GetRange (cell1, cell2 )))
{
goto error;
}
range->AttachDispatch ( dispatch );
dispatch = range->GetBorders ();
borders = new Borders ( dispatch );
if ( !borders )
{
goto error;
}
dispatch = borders->GetItem ( xlEdgeBottom );
border = new Border ( dispatch );
if ( !border )
{
goto error;
}
border->SetLineStyle ( continuous );
border->SetColorIndex ( automatic );
border->SetWeight ( thin );
delete border;
border = NULL;
dispatch = borders->GetItem ( xlEdgeTop );
border = new Border ( dispatch );
if ( !border )
{
goto error;
}
border->SetLineStyle ( continuous );
border->SetColorIndex ( automatic );
border->SetWeight ( medium );
delete border;
border = NULL;
dispatch = borders->GetItem ( xlEdgeRight );
border = new Border ( dispatch );
if ( !border )
{
goto error;
}
border->SetLineStyle ( none );
delete border;
border = NULL;
dispatch = borders->GetItem ( xlEdgeLeft );
border = new Border ( dispatch );
if ( !border )
{
goto error;
}
border->SetLineStyle ( none );
dispatch = range->GetInterior ( );
interior = new Interior ( dispatch );
if ( !interior )
{
goto error;
}
interior->SetColorIndex ( yellow );
interior->SetPattern ( solid );
PutCell ( row, 1, L"Section", 0 );
PutCell ( row, 2, title, 0 );
ok = TRUE;
error:
range->ReleaseDispatch ( );
if ( borders )
{
delete borders ;
}
if ( border )
{
delete border ;
}
VariantClear ( &cell1 );
VariantClear ( &cell2 );
return ok;
}
int OpenExcel ( void )
{
LPDISPATCH dispatch;
if ( xl )
{
return TRUE;
}
#if 0
while ( ExcelRunning ())
{
if ( AfxMessageBox ( "Excel is running!\n\nClose or kill all instances of Excel and retry\n\nNOTE: Check task tray (CTRL-ALT-DELETE) for instances of Excel", MB_OKCANCEL ) == IDCANCEL )
{
return FALSE;
}
}
#endif
xl = new _Application();
if ( !xl )
{
return FALSE;
}
if ( !xl->CreateDispatch ("Excel.Application"))
{
goto error_access;
}
dispatch = xl->GetWorkbooks ( );
if ( dispatch )
{
wbs = new Workbooks( dispatch );
}
if ( !wbs )
{
return FALSE;
}
if ( ! (ws = new _Worksheet ()))
{
return FALSE;
}
if ( ! (range = new Range ()))
{
return FALSE;
}
V_VT ( &no ) = VT_BOOL;
V_VT ( &yes ) = VT_BOOL;
V_VT ( &dummy ) = VT_I4;
V_VT ( &dummy0 ) = VT_I4;
V_VT ( &nullstring ) = VT_BSTR ;
V_VT ( &empty ) = VT_EMPTY;
V_VT ( &continuous ) = VT_I4;
V_VT ( &automatic ) = VT_I4;
V_VT ( &medium ) = VT_I4;
V_VT ( &thin ) = VT_I4;
V_VT ( &none ) = VT_I4;
V_VT ( &solid ) = VT_I4;
V_VT ( &yellow ) = VT_I4;
V_BOOL ( &no ) = FALSE;
V_BOOL ( &yes ) = TRUE;
V_I4 ( &dummy ) = 1;
V_I4 ( &dummy0 ) = 0;
V_BSTR ( &nullstring ) = SysAllocString ( OLESTR ("") );
V_I4 ( &continuous ) = xlContinuous;
V_I4 ( &automatic ) = xlAutomatic;
V_I4 ( &medium ) = xlMedium;
V_I4 ( &thin ) = xlThin;
V_I4 ( &none ) = xlThin;
V_I4 ( &solid ) = xlSolid;
V_I4 ( &yellow ) = 6;
return TRUE;
error_access:
AfxMessageBox ("Could not access Excel!\n\nMake sure Excel is installed on this system.");
return FALSE;
}
void CloseExcel ( void )
{
CloseWorkBook ();
if ( range )
{
delete range;
range = NULL;
}
if ( ws )
{
delete ws;
ws = NULL;
}
if ( wbs )
{
wbs->Close();
delete wbs;
wbs = NULL;
}
if ( xl )
{
xl->Quit();
xl->ReleaseDispatch ();
delete xl;
xl = NULL;
}
VariantClear ( &nullstring );
}
int OpenWorkBook ( const char *filename )
{
LPDISPATCH dispatch;
dispatch = wbs->Open ((LPCTSTR) filename, dummy0, yes, dummy, nullstring, nullstring, yes, dummy, dummy, no, no, dummy, no );
if ( dispatch )
{
workbook = new _Workbook ( dispatch );
}
if ( !workbook )
{
return FALSE;
}
SelectActiveSheet ( );
return TRUE;
}
int NewWorkBook ( const char *path )
{
LPDISPATCH dispatch;
VARIANT temp;
char tfile[200];
char *p;
WIN32_FIND_DATA finfo;
HANDLE handle;
V_VT ( &temp ) = VT_I4;
V_I4 ( &temp ) = xlWBATWorksheet;
if ( path )
{
strcpy ( tfile, path );
if ( (p = strchr ( tfile, '.' )))
{
*p = 0;
}
strcpy ( p, ".xlt" );
if ( (handle = FindFirstFile ( tfile, &finfo)) != INVALID_HANDLE_VALUE )
{
if ( !(finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
swprintf ( buffer, L"%S", tfile );
V_VT ( &temp ) = VT_BSTR;
V_BSTR ( &temp ) = SysAllocString ( buffer );
}
FindClose ( handle );
}
}
dispatch = wbs->Add ( temp );
VariantClear ( &temp );
if ( dispatch )
{
workbook = new _Workbook ( dispatch );
}
if ( !workbook )
{
return FALSE;
}
SelectActiveSheet ( );
return TRUE;
}
int SaveWorkBook ( const char *filename, int protect )
{
VARIANT name, fileformat, rc;
V_VT ( &name ) = VT_BSTR;
swprintf ( buffer, L"%S", filename );
V_BSTR ( &name ) = SysAllocString ( buffer );
V_VT ( &fileformat ) = VT_I4;
V_I4 ( &fileformat ) = xlWorkbookNormal;
V_VT ( &rc ) = VT_I4;
V_I4 ( &rc ) = xlLocalSessionChanges;
if ( protect )
{
VARIANT password;
V_VT ( &password ) = VT_BSTR;
V_BSTR ( &password ) = SysAllocString ( L"" );
ws->Protect ( password, yes, yes, yes, no );
VariantClear ( &password );
}
workbook->SaveAs ( name, fileformat, nullstring, nullstring, no, no,
xlNoChange, rc, no, empty, empty );
VariantClear ( &name );
return TRUE;
}
void CloseWorkBook ( void )
{
if ( workbook )
{
workbook->SetSaved ( TRUE );
workbook->Close ( no, nullstring, no );
delete workbook;
workbook = NULL;
}
}
void SelectActiveSheet ( void )
{
LPDISPATCH dispatch;
if ( ! (dispatch = xl->GetActiveSheet ()))
{
return;
}
ws->ReleaseDispatch ( );
ws->AttachDispatch ( dispatch );
}
int GetInt ( int row, int cell )
{
long value;
VARIANT var;
_variant_t v;
var = GetCell ( row, cell );
v.Attach ( var );
value = v;
return (int) value;
}
int GetString ( int row, int cell, OLECHAR *string )
{
VARIANT var;
string[0] =0;
var = GetCell ( row, cell );
if ( V_VT ( &var ) == VT_BSTR )
{
wcscpy ( string, V_BSTR ( &var ));
}
VariantClear ( &var );
return 1;
}