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.
836 lines
21 KiB
836 lines
21 KiB
/* File: D:\WACKER\tdll\tdll.c (Created: 26-Nov-1993)
|
|
*
|
|
* Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 22 $
|
|
* $Date: 4/23/02 8:31a $
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#pragma hdrstop
|
|
|
|
#include <commctrl.h>
|
|
|
|
#include "stdtyp.h"
|
|
#include <term\res.h>
|
|
#include "globals.h"
|
|
#include "session.h"
|
|
#include "assert.h"
|
|
#include "misc.h"
|
|
#include "tdll.h"
|
|
#include "tdll\htchar.h"
|
|
#include "vu_meter.h"
|
|
#include "banner.h"
|
|
#include "mc.h"
|
|
#include "open_msc.h"
|
|
#ifdef INCL_DEFAULT_TELNET_APP
|
|
#include "telnetck.h"
|
|
#endif
|
|
#ifdef INCL_NAG_SCREEN
|
|
#include "nagdlg.h"
|
|
#include "register.h"
|
|
#endif
|
|
#include "term.h"
|
|
|
|
#define SESSION_CLASS TEXT("SESSION_WINDOW")
|
|
|
|
|
|
static BOOL InitDll(const HINSTANCE hInstance);
|
|
static BOOL DetachDll(const HINSTANCE hInstance);
|
|
static int HTCheckInstance(TCHAR *pachCmdLine);
|
|
BOOL WINAPI TDllEntry(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved);
|
|
BOOL WINAPI _CRT_INIT(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved);
|
|
|
|
#if defined(INCL_PRIVATE_EDITION_BANNER)
|
|
static HINSTANCE gRTFInstanceHandle = NULL;
|
|
|
|
#if !defined(NT_EDITION)
|
|
BOOL RegisterBannerAboutClass(HANDLE hInstance); // see aboutdlg.c
|
|
BOOL UnregisterBannerAboutClass(HANDLE hInstance); // see aboutdlg.c
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* TDllEntry
|
|
*
|
|
* DESCRIPTION:
|
|
* Currently, just initializes the C-Runtime library but may be used
|
|
* for other things later.
|
|
*
|
|
* ARGUMENTS:
|
|
* hInstDll - Instance of this DLL
|
|
* fdwReason - Why this entry point is called
|
|
* lpReserved - reserved
|
|
*
|
|
* RETURNS:
|
|
* BOOL
|
|
*
|
|
*/
|
|
BOOL WINAPI TDllEntry(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved)
|
|
{
|
|
/* --- Docs say to call _CRT_INIT before any of our code - mrw --- */
|
|
|
|
if (_CRT_INIT(hInstDll, fdwReason, lpReserved) == FALSE)
|
|
return FALSE;
|
|
|
|
switch (fdwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
if (!InitDll(hInstDll))
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
if (!DetachDll(hInstDll))
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* InitDll
|
|
*
|
|
* DESCRIPTION:
|
|
* Intializes the application. Done only for the first instance.
|
|
*
|
|
*/
|
|
static BOOL InitDll(const HINSTANCE hInstance)
|
|
{
|
|
WNDCLASSEX wc;
|
|
|
|
// Documentation says this should be called once per application
|
|
// If we use any of the common controls which we do.
|
|
|
|
if(GetDllVersion(TEXT("comctl32.dll")) >= PACKVERSION(4,70))
|
|
{
|
|
INITCOMMONCONTROLSEX sInit;
|
|
sInit.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
sInit.dwICC = ICC_BAR_CLASSES | ICC_USEREX_CLASSES | ICC_WIN95_CLASSES;
|
|
|
|
InitCommonControlsEx(&sInit);
|
|
}
|
|
else
|
|
{
|
|
InitCommonControls();
|
|
}
|
|
|
|
memset(&wc, 0, sizeof(WNDCLASSEX));
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
|
|
if (GetClassInfoEx(hInstance, SESSION_CLASS, &wc) == FALSE)
|
|
{
|
|
glblSetDllHinst(hInstance);
|
|
|
|
// Read program's help file name from the resource file.
|
|
// REV: 3/26/2002 Moved here so the shell extension
|
|
// could use its context help.
|
|
//
|
|
glblSetHelpFileName();
|
|
|
|
// Session Class
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = SessProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = extLoadIcon(MAKEINTRESOURCE(IDI_PROG));
|
|
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
|
wc.hbrBackground = NULL;
|
|
wc.lpszMenuName = TEXT("MainMenu");
|
|
wc.lpszClassName = SESSION_CLASS;
|
|
wc.hIconSm = extLoadIcon(MAKEINTRESOURCE(IDI_PROG));
|
|
|
|
if (RegisterClassEx(&wc) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegisterTerminalClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegisterVuMeterClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegisterSidebarClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
#if !defined(NT_EDITION)
|
|
#if defined(INCL_PRIVATE_EDITION_BANNER)
|
|
if (RegisterBannerAboutClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
#if defined(INCL_PRIVATE_EDITION_BANNER)
|
|
gRTFInstanceHandle = LoadLibrary("RICHED32");
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* InitInstance
|
|
*
|
|
* DESCRIPTION:
|
|
* Creates the session window. Does instance specific stuff.
|
|
*
|
|
* ARGUMENTS:
|
|
* HINSTANCE hInstance - apps instance handle.
|
|
* LPTSTR lpCmdLine - copy of the command line.
|
|
* int nCmdShow - passed from WinMain arg list.
|
|
*
|
|
*/
|
|
BOOL InitInstance(const HINSTANCE hInstance,
|
|
const LPTSTR lpCmdLine,
|
|
const int nCmdShow)
|
|
{
|
|
HWND hwnd;
|
|
TCHAR ach[100];
|
|
HACCEL hAccel;
|
|
#if !defined(NT_EDITION)
|
|
HWND hwndBanner;
|
|
DWORD dwStart, dwNow;
|
|
#endif
|
|
|
|
#if !defined(NDEBUG)
|
|
#if !defined(NO_SMARTHEAP)
|
|
MemRegisterTask();
|
|
#endif
|
|
#endif
|
|
|
|
// Save program's instance handle
|
|
|
|
glblSetHinst(hInstance);
|
|
|
|
if (HTCheckInstance(lpCmdLine) == TRUE)
|
|
return FALSE;
|
|
|
|
// Get program title
|
|
|
|
LoadString(glblQueryDllHinst(),
|
|
IDS_GNRL_APPNAME,
|
|
ach,
|
|
sizeof(ach) / sizeof(TCHAR));
|
|
|
|
// Read program's help file name from the resource file.
|
|
// JMH 12/12/96 Moved up here so the default telnet dialog
|
|
// could use its context help.
|
|
//
|
|
// Now done in InitDLL() so that the help file is available
|
|
// to the shell extension. REV: 3/26/2002
|
|
//
|
|
// glblSetHelpFileName();
|
|
|
|
#ifdef INCL_NAG_SCREEN
|
|
// Do the nag screen stuff
|
|
//
|
|
if ( IsEval() && IsTimeToNag() )
|
|
{
|
|
DoDialog(glblQueryDllHinst(),
|
|
MAKEINTRESOURCE(IDD_NAG_SCREEN),
|
|
0,
|
|
DefaultNagDlgProc,
|
|
0);
|
|
}
|
|
|
|
#ifdef NDEBUG
|
|
// Display the registration reminder dialog if needed...
|
|
//
|
|
if (!IsRegisteredUser())
|
|
{
|
|
if (IsInitialRun())
|
|
{
|
|
DoRegister();
|
|
SetLastReminderDate();
|
|
}
|
|
|
|
else if (IsWillingToBeReminded())
|
|
{
|
|
if (IsTimeToRemind())
|
|
DoRegistrationReminderDlg(0);
|
|
}
|
|
}
|
|
|
|
#endif // NDEBUG
|
|
#endif // INCL_NAG_SCREEN
|
|
|
|
#ifdef INCL_DEFAULT_TELNET_APP
|
|
// Do the default telnet app stuff
|
|
//
|
|
if ( !IsHyperTerminalDefaultTelnetApp() && QueryTelnetCheckFlag() )
|
|
{
|
|
#ifndef NT_EDITION
|
|
//ask the user if they want HT to be the default telnet app
|
|
DoDialog(glblQueryDllHinst(), MAKEINTRESOURCE(IDD_DEFAULT_TELNET),
|
|
0, DefaultTelnetAppDlgProc, 0);
|
|
#else
|
|
//
|
|
// Change back to always prompt per MS request. REV: 12/04/2000.
|
|
//
|
|
|
|
#if 0
|
|
//mpt:8-9-97 MS asked us to make HT the default telnet app without asking - yippee!
|
|
SetTelnetCheckFlag(FALSE); //so we don't check again
|
|
SetDefaultTelnetApp(); //just do it without asking
|
|
#endif
|
|
|
|
//ask the user if they want HT to be the default telnet app
|
|
DoDialog(glblQueryDllHinst(), MAKEINTRESOURCE(IDD_DEFAULT_TELNET),
|
|
0, DefaultTelnetAppDlgProc, 0);
|
|
#endif // NT_EDITION
|
|
}
|
|
#endif // INCL_DEFAULT_TELNET_APP
|
|
|
|
// Setup and display the banner
|
|
|
|
#if !defined(NT_EDITION)
|
|
bannerRegisterClass(glblQueryDllHinst());
|
|
hwndBanner = bannerCreateBanner(glblQueryDllHinst(), ach);
|
|
|
|
UpdateWindow(hwndBanner);
|
|
glblSetHwndBanner(hwndBanner);
|
|
|
|
dwStart = GetTickCount();
|
|
#endif // !NT_EDITION
|
|
|
|
// Load accerator table for program.
|
|
|
|
hAccel = LoadAccelerators(glblQueryDllHinst(), MAKEINTRESOURCE(IDA_WACKER));
|
|
|
|
if (hAccel == 0)
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
glblSetAccelHdl(hAccel);
|
|
|
|
// mpt:07-30-97
|
|
if ( IsNT() )
|
|
CreateUserDirectory();
|
|
|
|
// Create a main window for this application instance. Pass command
|
|
// line string as user data to be stored and acted on later.
|
|
|
|
hwnd = CreateWindowEx(
|
|
WS_EX_WINDOWEDGE,
|
|
SESSION_CLASS,
|
|
ach,
|
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
0,
|
|
0,
|
|
glblQueryDllHinst(),
|
|
lpCmdLine
|
|
);
|
|
|
|
if (!IsWindow(hwnd))
|
|
{
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
// Needed in the message loop unfortunately
|
|
//
|
|
glblSetHwndFrame(hwnd);
|
|
|
|
#if !defined(NT_EDITION)
|
|
// Leave banner up at least BANNER_TIME
|
|
//
|
|
if (!glblQueryProgramStatus())
|
|
{
|
|
dwNow = GetTickCount();
|
|
|
|
if ( (dwNow - dwStart) < BANNER_TIME)
|
|
{
|
|
#ifdef USE_PRIVATE_EDITION_3_BANNER
|
|
// The HTPE 3.0 banner has a button on it. If we just sleep,
|
|
// no Windows messages will be processed, so you can't push
|
|
// the button. We need to sleep, but we also need to pump
|
|
// messages as well. - cab:11/29/96
|
|
//
|
|
Rest(BANNER_TIME - (dwNow - dwStart));
|
|
#else
|
|
Sleep(BANNER_TIME - (dwNow - dwStart));
|
|
#endif
|
|
}
|
|
}
|
|
#endif // !NT_EDITION
|
|
|
|
// Post a message to size and show the window.
|
|
//
|
|
PostMessage(hwnd, WM_SESS_SIZE_SHOW, (WPARAM)nCmdShow, 0);
|
|
|
|
// Posting this next messages kicks off the connection stuff
|
|
//
|
|
PostMessage(hwnd, WM_CMDLN_DIAL, (WPARAM)nCmdShow, 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* MessageLoop
|
|
*
|
|
* DESCRIPTION:
|
|
* Wackers main message loop
|
|
*
|
|
* ARGUMENTS:
|
|
* void
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*/
|
|
int MessageLoop(void)
|
|
{
|
|
MSG msg;
|
|
|
|
while (GetMessage(&msg, 0, 0, 0))
|
|
{
|
|
if (!CheckModelessMessage(&msg))
|
|
ProcessMessage(&msg);
|
|
}
|
|
|
|
return (int)msg.wParam;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* GetFileNameFromCmdLine
|
|
*
|
|
* DESCRIPTION:
|
|
* Extracts the file name, if any, from the command line and fully
|
|
* qualifies it.
|
|
*
|
|
* ARGUMENTS:
|
|
* pachCmdLine Copy of command line
|
|
* pachFileName Place to put the result
|
|
* nSize Size of buffer pointed to by pachFileName (in TCHARs)
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*
|
|
*/
|
|
int GetFileNameFromCmdLine(TCHAR *pachCmdLine, TCHAR *pachFileName, int nSize)
|
|
{
|
|
int nIdx = 0;
|
|
TCHAR * pszStr;
|
|
TCHAR acName[FNAME_LEN];
|
|
TCHAR acPath[FNAME_LEN];
|
|
TCHAR ach[_MAX_EXT];
|
|
TCHAR * pachFile;
|
|
TCHAR * pszTelnet = TEXT("telnet:"); //jmh 3/24/97
|
|
int fTelnetCmdLnDial = FALSE;
|
|
DWORD dwFile;
|
|
|
|
// Make sure all the filename buffers are nulled out. REV: 11/14/2000.
|
|
//
|
|
TCHAR_Fill(pachFileName, TEXT('\0'), nSize);
|
|
TCHAR_Fill(acName, TEXT('\0'), FNAME_LEN);
|
|
TCHAR_Fill(acPath, TEXT('\0'), FNAME_LEN);
|
|
|
|
nIdx = 0;
|
|
|
|
//Just in case there is no command line. This happened when one specified '/t'
|
|
//with no hostname on the command line - mpt 05/28/99
|
|
if ( pachCmdLine[0] == TEXT('\0') )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for (pszStr = pachCmdLine;
|
|
*pszStr != TEXT('\0') && nIdx < nSize;
|
|
pszStr = StrCharNext(pszStr))
|
|
{
|
|
/*
|
|
* This works because we only allow certain characters as switches
|
|
*/
|
|
if (*pszStr == TEXT('/'))
|
|
{
|
|
/* Process as a switch */
|
|
pszStr = StrCharNext(pszStr); // skip the switch char
|
|
//JMH 03-24-97 Test for special case here...
|
|
if (*pszStr == TEXT('\0'))
|
|
{
|
|
break;
|
|
}
|
|
else if (*pszStr == TEXT('T') || *pszStr == TEXT('t'))
|
|
{
|
|
fTelnetCmdLnDial = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Copy all non switch stuff to the buffer */
|
|
if (nIdx < (FNAME_LEN - 1))
|
|
{
|
|
// JFH:6/9/95 acName[nIdx++] = *pszStr;
|
|
if (IsDBCSLeadByte(*pszStr))
|
|
{
|
|
MemCopy(&acName[nIdx], pszStr, (size_t)2 * sizeof(TCHAR));
|
|
nIdx += 2;
|
|
}
|
|
else
|
|
{
|
|
acName[nIdx++] = *pszStr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (nIdx == nSize)
|
|
{
|
|
acName[nIdx - 1] = TEXT('\0');
|
|
}
|
|
else
|
|
{
|
|
acName[nIdx] = TEXT('\0');
|
|
}
|
|
|
|
/* Trim leading and trailing spaces */
|
|
pszStr = TCHAR_Trim(acName);
|
|
|
|
//jmh 3/24/97 Needed to copy this from sessCheckAndLoadCmdLn(), and modify it
|
|
// slightly. This needs to be here because it affects the filename, and we want
|
|
// to make sure we're comparing the same name as in other instances.
|
|
#if defined(INCL_WINSOCK)
|
|
// If this is a telnet address from the browser, it will usually be preceeded
|
|
// by the string telnet: If so, we must remove it or it will confuse some of
|
|
// the code to follow jkh, 03/22/1997
|
|
if (fTelnetCmdLnDial)
|
|
{
|
|
nIdx = StrCharGetStrLength(pszTelnet);
|
|
if (StrCharCmpiN(acName, pszTelnet, nIdx) == 0)
|
|
{
|
|
// Remove the telnet string from the front of acName
|
|
memmove(acName, &acName[nIdx], (StrCharGetStrLength(acName) - nIdx) + 1);
|
|
}
|
|
}
|
|
|
|
// See if URL contains a port number. This will take the form of
|
|
// addr:nnn where nnn is the port number i.e. culine.colorado.edu:860
|
|
// or there might be the name of an assigned port like hilgraeve.com:finger.
|
|
// We support numeric port right now, may add port names later. jkh, 3/22/1997
|
|
pszStr = StrCharFindFirst(acName, TEXT(':'));
|
|
if (pszStr && isdigit(pszStr[1]))
|
|
{
|
|
*pszStr = TEXT('\0');
|
|
}
|
|
#endif // defined(INCL_WINSOCK)
|
|
|
|
// Now that the parsing is done, open the session file if one
|
|
// was supplied. A session name that is not fully qualified may have
|
|
// been passed in on the command line. Fully qulaify that name, then
|
|
// carry on.
|
|
//
|
|
dwFile = GetFullPathName(acName, FNAME_LEN, acPath, &pachFile);
|
|
|
|
if (dwFile > 0 && dwFile <= FNAME_LEN)
|
|
{
|
|
StrCharCopyN(acName, acPath, FNAME_LEN);
|
|
}
|
|
#if !defined(NDEBUG)
|
|
else
|
|
{
|
|
DWORD dwLastError = GetLastError();
|
|
assert(FALSE);
|
|
}
|
|
#endif //!defined(NDEBUG)
|
|
|
|
// Get hypertrm extension
|
|
//
|
|
TCHAR_Fill(ach, TEXT('\0'), _MAX_EXT);
|
|
|
|
LoadString(glblQueryDllHinst(), IDS_GNRL_HAS, ach, _MAX_EXT);
|
|
|
|
// For now, lets assume all session files end in HT. If it
|
|
// doesn't append the .HT. John Hile and I have discussed
|
|
// this and feel it should be otherwise but don't want to
|
|
// make a change this late in the ball game. - mrw,3/2/95
|
|
//
|
|
if ((pszStr = StrCharFindLast(acName, '.')))
|
|
{
|
|
if (StrCharCmpi(pszStr, ach) != 0 && StrCharCmpi(pszStr, ".TRM") != 0)
|
|
{
|
|
nIdx = StrCharGetStrLength(acName) + StrCharGetStrLength(ach);
|
|
|
|
if(nIdx > nSize)
|
|
{
|
|
ach[nSize - StrCharGetStrLength(ach) - 1] = TEXT('\0');
|
|
}
|
|
|
|
StrCharCat(acName, ach);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nIdx = StrCharGetStrLength(acName) + StrCharGetStrLength(ach);
|
|
|
|
if(nIdx > nSize)
|
|
{
|
|
acName[nSize - StrCharGetStrLength(ach) - 1] = TEXT('\0');
|
|
}
|
|
|
|
StrCharCat(acName, ach);
|
|
}
|
|
|
|
if (acName[0] != TEXT('\0'))
|
|
{
|
|
// Convert the possible short file name (i.e., the 8.3 format)
|
|
// to the long file name and save it.
|
|
//
|
|
dwFile = GetFullPathName(acName, FNAME_LEN, acPath, &pachFile);
|
|
|
|
if (dwFile > 0 && dwFile <= FNAME_LEN)
|
|
{
|
|
StrCharCopyN(acName, acPath, FNAME_LEN);
|
|
}
|
|
#if !defined(NDEBUG)
|
|
else
|
|
{
|
|
DWORD dwLastError = GetLastError();
|
|
assert(FALSE);
|
|
}
|
|
#endif //!defined(NDEBUG)
|
|
}
|
|
|
|
StrCharCopyN(pachFileName, acName, nSize);
|
|
pachFileName[nSize - 1] = TEXT('\0');
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Used for CheckInstCallback and HTCheckInstance
|
|
//
|
|
static int fKillTheApp;
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* CheckInstCallback
|
|
*
|
|
* DESCRIPTION:
|
|
* Callback for EnumWindows
|
|
*
|
|
* ARGUMENTS:
|
|
* hwnd - window handle from EmuWindows
|
|
* lPar - optional data parameter (file name in this case)
|
|
*
|
|
* RETURNS:
|
|
* FALSE if it finds another instance using the same file name.
|
|
* TRUE if is doesn't
|
|
*
|
|
* AUTHOR: Mike Ward, 27-Jan-1995
|
|
*/
|
|
BOOL CALLBACK CheckInstCallback(HWND hwnd, LPARAM lPar)
|
|
{
|
|
BOOL fRet = TRUE;
|
|
TCHAR szClass[256];
|
|
GetClassName(hwnd, szClass, sizeof(szClass));
|
|
|
|
if (StrCharCmpi(szClass, SESSION_CLASS) == 0) // mrw, 2/12/95
|
|
{
|
|
ATOM aFile = GlobalAddAtom((TCHAR *)lPar);
|
|
|
|
if (SendMessage(hwnd, WM_HT_QUERYOPENFILE, 0, (LPARAM)aFile))
|
|
{
|
|
if (!IsZoomed(hwnd))
|
|
ShowWindow(hwnd, SW_RESTORE);
|
|
|
|
SetForegroundWindow(hwnd);
|
|
fKillTheApp = TRUE;
|
|
fRet = FALSE;
|
|
}
|
|
|
|
GlobalDeleteAtom(aFile);
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* CheckInstance
|
|
*
|
|
* DESCRIPTION:
|
|
* Checks if another instance of HyperTerminal is using this file.
|
|
*
|
|
* ARGUMENTS:
|
|
* pachFile - filename this guy is trying to open
|
|
*
|
|
* RETURNS:
|
|
* TRUE=yes, another HT using it.
|
|
* FALSE=nope
|
|
*
|
|
* AUTHOR: Mike Ward, 27-Jan-1995
|
|
*/
|
|
static int HTCheckInstance(TCHAR *pachCmdLine)
|
|
{
|
|
TCHAR achPath[FNAME_LEN];
|
|
|
|
// Make sure the filename buffer is nulled out. REV: 11/14/2000.
|
|
//
|
|
TCHAR_Fill(achPath, TEXT('\0'), FNAME_LEN);
|
|
|
|
// Get the filename
|
|
//
|
|
GetFileNameFromCmdLine(pachCmdLine, achPath, FNAME_LEN);
|
|
|
|
// If EnumWindows callback (CheckInstCallback) matches the given
|
|
// path, it will set the fKillApp guy to TRUE
|
|
//
|
|
fKillTheApp = FALSE;
|
|
|
|
// EnumWindows will give our callback toplevel windows one at a time
|
|
//
|
|
EnumWindows(CheckInstCallback, (LPARAM)achPath);
|
|
return fKillTheApp;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* Rest
|
|
*
|
|
* DESCRIPTION:
|
|
* This function causes the current thread to sleep for the given
|
|
* number of milliseconds. However, it will still process Windows
|
|
* messages.
|
|
*
|
|
* ARGUMENTS:
|
|
* dwMilliSecs - Number of milliseconds to sleep for.
|
|
*
|
|
* AUTHOR: C. Baumgartner, 11/29/96
|
|
*/
|
|
void Rest(DWORD dwMilliSecs)
|
|
{
|
|
|
|
MSG msg;
|
|
DWORD dwStart = GetTickCount();
|
|
DWORD dwStop = dwStart + dwMilliSecs;
|
|
|
|
while( dwStop > GetTickCount() )
|
|
{
|
|
if ( GetMessage(&msg, NULL, 0, 0) )
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* DetachDll
|
|
*
|
|
* DESCRIPTION:
|
|
* Intializes the application. Done only for the first instance.
|
|
*
|
|
*/
|
|
static BOOL DetachDll(const HINSTANCE hInstance)
|
|
{
|
|
BOOL lReturn = TRUE;
|
|
#if !defined(NDEBUG)
|
|
TCHAR acError[80];
|
|
#endif // !defined(NDEBUG)
|
|
|
|
// Release the RICHED32 library if it was loaded. REV: 11/09/2000.
|
|
//
|
|
#if defined(INCL_PRIVATE_EDITION_BANNER)
|
|
if (gRTFInstanceHandle)
|
|
{
|
|
FreeLibrary(gRTFInstanceHandle);
|
|
gRTFInstanceHandle = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (UnregisterClass(SESSION_CLASS, hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
lReturn = FALSE;
|
|
#if !defined(NDEBUG)
|
|
wsprintf(acError, TEXT("UnregisterClass returned error %d"),
|
|
GetLastError());
|
|
MessageBox(NULL, acError, NULL, MB_OK);
|
|
#endif // !defined(NDEBUG)
|
|
}
|
|
|
|
if (UnregisterTerminalClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
lReturn = FALSE;
|
|
#if !defined(NDEBUG)
|
|
wsprintf(acError, TEXT("UnregisterTerminalClass returned error %d"),
|
|
GetLastError());
|
|
MessageBox(NULL, acError, NULL, MB_OK);
|
|
#endif // !defined(NDEBUG)
|
|
}
|
|
|
|
if (UnregisterVuMeterClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
lReturn = FALSE;
|
|
#if !defined(NDEBUG)
|
|
wsprintf(acError, TEXT("UnregisterVuMeterClass returned error %d"),
|
|
GetLastError());
|
|
MessageBox(NULL, acError, NULL, MB_OK);
|
|
#endif // !defined(NDEBUG)
|
|
}
|
|
|
|
if (UnregisterSidebarClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
lReturn = FALSE;
|
|
#if !defined(NDEBUG)
|
|
wsprintf(acError, TEXT("UnregisterSidebarClass returned error %d"),
|
|
GetLastError());
|
|
MessageBox(NULL, acError, NULL, MB_OK);
|
|
#endif // !defined(NDEBUG)
|
|
}
|
|
|
|
#if !defined(NT_EDITION)
|
|
#if defined(INCL_PRIVATE_EDITION_BANNER)
|
|
if (UnregisterBannerAboutClass(hInstance) == FALSE)
|
|
{
|
|
assert(FALSE);
|
|
lReturn = FALSE;
|
|
#if !defined(NDEBUG)
|
|
wsprintf(acError, TEXT("UnregisterBannerAboutClass returned error %d"),
|
|
GetLastError());
|
|
MessageBox(NULL, acError, NULL, MB_OK);
|
|
#endif // !defined(NDEBUG)
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
return lReturn;
|
|
}
|
|
|