Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

644 lines
15 KiB

/*
* FVINIT.CPP
*
* All initialization functions and some miscellany for the
* CFileViewer implementation.
*
* Copyright (c)1994 Microsoft Corporation, All Rights Reserved
* with SCC Changes for SCC QuickView - SDN
*/
#include "fileview.h"
/*
* CFileViewer::Init
*
* Purpose:
* Performs any intiailization of a CFileViewer that's prone to
* failure that we also use internally before exposing the object
* outside.
*
* Parameters:
* None
*
* Return Value:
* HRESULT NOERROR if successful, error code otherwise.
*
*/
HRESULT CFileViewer::Init(void)
{
LPUNKNOWN pIUnknown=(LPUNKNOWN)this;
WNDCLASS wc;
HRESULT hr;
HDC hDC;
char locLibPath[MAX_PATH];
char * pszLibPath;
//Default error code
hr=ResultFromScode(E_OUTOFMEMORY);
/*
* Make pIUnknown point to outer unknown if we get one.
* The interfaces allocated below are always given an IUnknown
* to which they delegate at all times. This will be either
* the CFileViewer object's IUnknown itself or the outer
* unknown if this object is aggregated. The interfaces
* need not know which case is being used.
*/
if (NULL!=m_pUnkOuter)
pIUnknown=m_pUnkOuter;
//Allocate contained interfaces.
m_pIPersistFile=new CImpIPersistFile(this, pIUnknown);
if (NULL==m_pIPersistFile)
return hr;
m_pIFileViewer=new CImpIFileViewer(this, pIUnknown);
if (NULL==m_pIFileViewer)
return hr;
m_pST=new CStringTable(m_hInst);
if (NULL==m_pST)
return hr;
/*
* Go load the strings we need in CFileViewer::String. Note:
* the String function is implemented inline (see FVTEXT.H)
*/
if (!m_pST->FInit(IDS_MIN, IDS_MAX, CCHSTATUSMSGMAX /*CCHSTRINGMAX*/))
return hr;
//Register window classes that we'll need to display the file
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = FileViewerFrameProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = CBWNDEXTRAFRAME;
wc.hInstance = m_hInst;
wc.hIcon = LoadIcon(m_hInst, "Icon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = String(IDS_CLASSFRAME);
if (!RegisterClass(&wc))
return hr;
// Also load the the other two main libraries. These should be
// located in the same directory as we were loaded from.
GetModuleFileName(m_hInst, locLibPath, sizeof(locLibPath));
pszLibPath = locLibPath;
while (*pszLibPath != 0x00)
pszLibPath++;
while (*pszLibPath != '\\' && *pszLibPath != ':')
pszLibPath--;
pszLibPath++;
// lstrcpy(pszLibPath, "SCCVW.DLL");
lstrcpy (pszLibPath, "MSVIEWUT.DLL");
m_hSCCVWDLL = LoadLibrary ( locLibPath );
m_hSCCPageDLL = m_hSCCVWDLL;
// lstrcpy(pszLibPath, "SCCPG.DLL");
// m_hSCCPageDLL = LoadLibrary ( locLibPath );
// CHECK - Work on the handling of load failures
m_fClassReg=TRUE;
/*
* Create a default fixed pitch font for the Viewport. We
* use Courier New here instead of say, SYSTEM_FIXED_FONT
* because we want the font sizing buttons to work normally
* when this window appears, and the system fonts do not
* scale, but Courier New does. Default is 10 point calculated
* from 10*PIXELSPERINCH/72.
*/
hDC=GetDC(NULL);
m_cyPPI=GetDeviceCaps(hDC, LOGPIXELSY);
ReleaseDC(NULL, hDC);
m_hFont=CreateFont(MulDiv(-10, m_cyPPI, 72)
, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE
, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY, FF_DONTCARE, "Arial");
if (m_hFont)
GetObject ( m_hFont, sizeof(LOGFONT), &m_LogFont);
return NOERROR;
}
BOOL CFileViewer::FInitToolbar(void)
{
BOOL fRet=TRUE;
RECT rc;
TBBUTTON rgtb[CTBBUTTONS];
HICON hIcon=NULL;
HDC hDC=NULL;
HDC hCompDC=NULL;
HBITMAP hBitmap=NULL;
HBITMAP hOldBitmap=NULL;
/*
* Initialize the toolbar button array. This uses the TOOLS.BMP
* resource which has four buttons and two separators. The
* buttons are tied to File/Open As, Increase/Decrease Font
* size and Replace Window.
*/
rgtb[0].iBitmap=IDBT_OPENAS;
rgtb[0].idCommand=IDM_FILEOPENAS;
rgtb[0].fsState=TBSTATE_ENABLED;
rgtb[0].fsStyle=TBSTYLE_BUTTON;
rgtb[0].dwData=0L;
rgtb[0].iString=0;
rgtb[1].iBitmap=0;
rgtb[1].idCommand=0;
rgtb[1].fsState=TBSTATE_ENABLED;
rgtb[1].fsStyle=TBSTYLE_SEP;
rgtb[1].dwData=0L;
rgtb[1].iString=0;
rgtb[2].iBitmap=IDBT_FONTSIZEINCREASE;
rgtb[2].idCommand=IDM_VIEWFONTINCREASE;
rgtb[2].fsState=TBSTATE_ENABLED;
rgtb[2].fsStyle=TBSTYLE_BUTTON;
rgtb[2].dwData=0L;
rgtb[2].iString=0;
rgtb[3].iBitmap=IDBT_FONTSIZEDECREASE;
rgtb[3].idCommand=IDM_VIEWFONTDECREASE;
rgtb[3].fsState=TBSTATE_ENABLED;
rgtb[3].fsStyle=TBSTYLE_BUTTON;
rgtb[3].dwData=0L;
rgtb[3].iString=0;
rgtb[4].iBitmap=0;
rgtb[4].idCommand=0;
rgtb[4].fsState=TBSTATE_ENABLED;
rgtb[4].fsStyle=TBSTYLE_SEP;
rgtb[4].dwData=0L;
rgtb[4].iString=0;
rgtb[5].iBitmap=IDBT_FVMULTIWINDOW;
rgtb[5].idCommand=IDM_VIEWREPLACE;
rgtb[5].fsState=TBSTATE_ENABLED;
rgtb[5].fsStyle=TBSTYLE_CHECK;
rgtb[5].dwData=0L;
rgtb[5].iString=0;
/*
* Open as button: call SHGetIconOfFile to retrieve
* the image, then overwrite it in the toolbar bitmap we send
* to CreateToolbarEx. If SHGetIconOfFile fails, then just
* use the one in the toolbar bitmap already.
*
*/
{
HICON hIcon;
HBITMAP hBitmap;
SHFILEINFO locShellFileInfo;
hBitmap = CreateMappedBitmap (m_hInst, IDB_TOOLS, CMB_MASKED, NULL,0);
if (m_hTBitmap != NULL)
DeleteObject(m_hTBitmap);
m_hTBitmap = hBitmap;
// hIcon = SHGetFileIcon (m_hInst, m_pszPath, FILE_ATTRIBUTE_NORMAL,
// SHGFI_SMALLICON );
// SHGFI_SHELLICONSIZE );
// As of build 310 the SDK now reflects the switch to
// SHGetFileInfo from SHGetFileIcon!!!!
MemSet ( (char *) &locShellFileInfo, 0, sizeof(SHFILEINFO) );
SHGetFileInfo (m_pszPath, 0,
(SHFILEINFO *) &locShellFileInfo,
sizeof (locShellFileInfo),
SHGFI_ICON | SHGFI_SMALLICON);
hIcon = locShellFileInfo.hIcon;
if ( NULL != hIcon )
{
// Wipe the bitmap area clean, then draw the shell's
// small icon for the application.
HDC hDC = GetDC (m_hWnd);
HDC hCompDC = CreateCompatibleDC (hDC);
HBITMAP hOldBitmap = (HBITMAP)SelectObject ( hCompDC, hBitmap );
UINT cxSmIcon = GetSystemMetrics(SM_CXSMICON);
UINT cySmIcon = GetSystemMetrics(SM_CYSMICON);
// Temporary fix
cxSmIcon = 16;
cySmIcon = 16;
HBRUSH hBrush = CreateSolidBrush (GetSysColor(COLOR_BTNFACE));
RECT locRect;
locRect.top = locRect.left = 0;
locRect.bottom = cySmIcon;
locRect.right = cxSmIcon;
FillRect (hCompDC, &locRect, hBrush);
DrawIconEx(hCompDC, 0, 0, hIcon, cxSmIcon, cySmIcon, 0, 0, DI_NORMAL );
SelectObject ( hCompDC, hOldBitmap);
DeleteObject ( hBrush );
ReleaseDC (m_hWnd, hDC);
DeleteDC (hCompDC);
m_hWndToolbar=CreateToolbarEx(m_hWnd, TBSTYLE_TOOLTIPS
| WS_CHILD | WS_CLIPSIBLINGS, ID_TOOLBAR
, CTBBITMAPS, NULL, (unsigned int) hBitmap, rgtb, CTBBUTTONS
, 0, 0, 0, 0, sizeof(TBBUTTON));
}
else
m_hWndToolbar=CreateToolbarEx(m_hWnd, TBSTYLE_TOOLTIPS
| WS_CHILD | WS_CLIPSIBLINGS, ID_TOOLBAR
, CTBBITMAPS, m_hInst, IDB_TOOLS, rgtb, CTBBUTTONS
, 0, 0, 0, 0, sizeof(TBBUTTON));
}
/*
* Remember the height for resizing this and the viewport.
* Use window rectangles for toolbars.
*/
GetWindowRect(m_hWndToolbar, &rc);
m_cyTools=rc.bottom-rc.top;
return fRet;
}
/*
* CFileViewer::FInitFrameControls
*
* Purpose:
* Creates and initializes the toolbar and status bar for
* the frame window.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the function worked, FALSE otherwise.
*/
BOOL CFileViewer::FInitFrameControls(void)
{
BOOL fRet;
RECT rc;
/*
* Status line
*/
// Make sure that Common Controls library is initialized
InitCommonControls();
// Create and initialize the toolbar and tooltips
FInitToolbar();
/*
| Create size grip
*/
m_hWndSizeGrip = CreateWindow("SCROLLBAR","",
WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN,
0,0,30,30,
m_hWnd,
(HMENU)ID_SIZEGRIP,
m_hInst,
0);
m_hWndStatus=CreateStatusWindow(WS_CHILD | WS_CLIPSIBLINGS | SBARS_SIZEGRIP
, String(IDS_MSGREADY), m_hWnd, ID_STATUSBAR);
if (NULL==m_hWndStatus)
{
ODS("CFileViewer::FInitFrameTools failed to create status bar");
return FALSE;
}
/*
* Remember the height for resizing this and the viewport.
* Use client rectangle for status lines.
*/
GetClientRect(m_hWndStatus, &rc);
m_cyStatus=rc.bottom-rc.top;
/*
* Create a status bar helper and tell it what messages
* to use. This object will be called from WM_MENUSELECT
* in FileViewerFrameProc in FVPROC.CPP.
*/
m_pSH=new CStatusHelper(m_hWndStatus, m_hInst);
if (NULL==m_pSH)
return FALSE;
fRet=m_pSH->MessageMap(m_hWnd, IDR_STATMESSAGEMAP, IDS_STATUSMSGMIN
, IDS_STATUSMSGMAX, CCHSTATUSMSGMAX, ID_MENUFILE, ID_MENUHELP
, ID_MSGREADY, ID_MSGEMPTY, ID_MENUSYS);
return fRet;
}
/**
** Uninteresting functions that need little or no modification
**/
/*
* CFileViewer::String
*
* Purpose:
* Inline string lookup function for access to stringtable.
*/
LPSTR inline CFileViewer::String(UINT uID)
{
return (*m_pST)[uID];
}
/*
* CFileViewer::MemAlloc
*
* Purpose:
* Central allocation function using IMalloc.
*/
LPVOID CFileViewer::MemAlloc(ULONG cb)
{
LPVOID pv;
#ifdef SCC_OLE2_CALLS
LPMALLOC pIMalloc;
if (FAILED(CoGetMalloc(MEMCTX_SHARED, &pIMalloc)))
{
ODS("CFileViewer::MemAlloc CoGetMalloc failed");
return NULL;
}
pv=pIMalloc->Alloc(cb);
pIMalloc->Release();
#else
pv=LocalAlloc(LPTR, cb);
#endif
return pv;
}
/*
* CFileViewer::MemFree
*
* Purpose:
* Central free function using IMalloc.
*/
void CFileViewer::MemFree(LPVOID pv)
{
#ifdef SCC_OLE2_CALLS
LPMALLOC pIMalloc;
#endif
if (NULL==pv)
{
ODS("CFileViewer::MemFree passed NULL pointer");
return;
}
#ifdef SCC_OLE2_CALLS
if (FAILED(CoGetMalloc(MEMCTX_SHARED, &pIMalloc)))
{
ODS("CFileViewer::MemFree CoGetMalloc failed");
return;
}
pIMalloc->Free(pv);
pIMalloc->Release();
#else
LocalFree(pv);
#endif
return;
}
/*
* CFileViewer::QueryInterface
* CFileViewer::AddRef
* CFileViewer::Release
*
* Purpose:
* IUnknown members for CFileViewer object.
*/
STDMETHODIMP CFileViewer::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
/*
* The only calls for IUnknown are either in a nonaggregated
* case or when created in an aggregation, so in either case
* always return our IUnknown for IID_IUnknown.
*/
if (IsEqualIID(riid, IID_IUnknown))
*ppv=(LPVOID)this;
//IPersist is base of IPersistFile
if (IsEqualIID(riid, IID_IPersist)
|| IsEqualIID(riid, IID_IPersistFile))
*ppv=(LPVOID)m_pIPersistFile;
if (IsEqualIID(riid, IID_IFileViewer))
*ppv=(LPVOID)m_pIFileViewer;
//AddRef any interface we'll return.
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CFileViewer::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CFileViewer::Release(void)
{
ULONG cRefT;
cRefT=--m_cRef;
if (0L==m_cRef)
{
/*
* Tell the server that an object is going away
* so it can shut down if appropriate. (See FILEVIEW.CPP
* for the ObjectDestroyed function).
*/
if (NULL!=m_pfnDestroy)
(*m_pfnDestroy)();
delete this;
}
return cRefT;
}
#ifndef SCC_OLE2_CALLS
// ????{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}
#define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
// converts GUID into (...) form without leading identifier; returns
// amount of data copied to lpsz if successful; 0 if buffer too small.
STDAPI_(int) QV_StringFromCLSID(REFGUID rguid, LPSTR lpsz, int cbMax)
{
if (cbMax < GUIDSTR_MAX)
return 0;
wsprintf(lpsz, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
rguid.Data1, rguid.Data2, rguid.Data3,
rguid.Data4[0], rguid.Data4[1],
rguid.Data4[2], rguid.Data4[3],
rguid.Data4[4], rguid.Data4[5],
rguid.Data4[6], rguid.Data4[7]);
// Assert(lstrlen(lpsz) + 1 == GUIDSTR_MAX);
return GUIDSTR_MAX;
}
#endif
// for application title and other stuff
#define APPBUFFER 80
/*
* CFileViewer::FSetWindowTitle
*/
void CFileViewer::FSetWindowTitle(void)
{
char locPath[MAX_PATH + APPBUFFER];
char *pLocPath, *pStart, *pEnd;
int i;
HINSTANCE hShellInst;
LPFNSHGETFILEINFO lpfnSHGetFileInfo;
SHFILEINFO locSHFileInfo;
// Parse the file name, add the separator and application name
lpfnSHGetFileInfo = NULL;
hShellInst = (HINSTANCE) LoadLibrary ("SHELL32");
if (hShellInst < (HINSTANCE)32)
{
// SetWindowText ( m_hWnd, String (IDS_APPNAME) );
// return;
hShellInst = NULL;
}
else
{
lpfnSHGetFileInfo = (LPFNSHGETFILEINFO) GetProcAddress (
(HMODULE) hShellInst,
(LPSTR) "SHGetFileInfo" ); // in 197
}
// Strip Path
if (NULL != lpfnSHGetFileInfo)
{
// Per JP request 10/4/94
// Again let the shell handle retrieving the display name
MemSet ( (char *) &locSHFileInfo, 0, sizeof(SHFILEINFO) );
if ( (*lpfnSHGetFileInfo)(m_pszPath, 0, &locSHFileInfo,
sizeof(SHFILEINFO), SHGFI_DISPLAYNAME) )
strcpy ( locPath, locSHFileInfo.szDisplayName );
}
else
{
// Manual approach if the SHell wasn't available>>>>
// Strip Extension (only if .3 or less) and Path -Shell isn't exporting
locPath[0] = '\0';
pLocPath = m_pszPath;
pStart= pEnd = pLocPath;
while (*pLocPath != '\0')
{
switch (*pLocPath)
{
case '\\':
pStart=AnsiNext(pLocPath); // Delimeter for directory
break;
case ':':
pStart=AnsiNext(pLocPath); // Potential drive delimeter
break;
case '/':
pStart=AnsiNext(pLocPath); // Another directory delimiter
break;
case '.':
pEnd=pLocPath; // A Possible extension
break;
}
pLocPath = AnsiNext(pLocPath);
}
if (pEnd <= pStart)
pEnd = pStart+ strlen(pStart);
for (i=0; pStart < pEnd && i < MAX_PATH; pStart++,i++)
locPath[i] = *pStart;
locPath[i] = '\0';
}
// Add Separator and Application Name
strcat ( locPath, String(IDS_TITLESEPARATOR) );
strcat ( locPath, String(IDS_APPNAME) );
SetWindowText ( m_hWnd, (LPSTR) locPath );
if (hShellInst)
FreeLibrary ( hShellInst );
return;
}