📄 global.cpp
字号:
//
// global.cpp -- Global functions and main app event loop
//
// $Id: global.cpp 2.4 1995/10/31 02:20:37 tsurace Beta $
// $Log: global.cpp $// Revision 2.4 1995/10/31 02:20:37 tsurace// Modified startup code to take command line.//
// Revision 2.3 1995/10/31 00:43:03 tsurace
// Added code to specify startup file on command line, default to
// "C:/VT/MAIN.VTC".
//
// Revision 2.2 1995/10/27 20:06:46 tsurace
// Added Getch function to allow retrieving single keystroke.
// Added accelerator loading/translation code.
//
// Revision 2.1 1995/10/24 15:52:51 tsurace
// Roll.
//
// Revision 1.5 1995/10/18 23:53:59 tsurace
// Added version string
//
// Revision 1.4 1995/10/18 22:46:59 tsurace
// Added BlockingHook to handle blocking calls correctly (connect()).
//
// Revision 1.3 1995/10/11 21:02:31 tsurace
// Added out-of-memory handling (xalloc).
//
// Revision 1.2 1995/10/08 23:28:47 tsurace
// Change the order of calls on exiting.
//
// (end of log)
#define STRICT
#include <windows.h>
#pragma hdrstop
#include <except.h>
#include "global.hpp"
#include "resids.hpp"
#include "vt102em.hpp"
#ifndef __FLAT__
#error hey, we only deal with 32-bit code, buddy!
#endif
extern "C" {
extern void main_init_all (int argc, char ** argv); /* in ../main.c */
};
VT102Emulator * main_window = NULL;
HINSTANCE Global::_hInstance = 0;
HINSTANCE Global::_hPrevInstance = 0;
HACCEL Global::_accelerators = 0;
// The version string -- this will be displayed in an ABOUT dialog
// some day...
const char * Global::VersionInfo =
"<insert name here> Version 1.0.0 $State: Beta $";
// This cannot be loaded from a resource file
static const char * _out_of_memory_message =
"You seem to be out of memory, :( and it is probable\n\
that this program will soon die. :< On the bright side,\n\
the crash could free up some memory.";
// ----------------------------------------------------------------------
// GetPointer, SetPointer -- Functions to get/set the Window pointer
// from the "extra" field in a window.
// ----------------------------------------------------------------------
inline VT102Emulator * GetPointer (HWND hWnd)
{
return (VT102Emulator *) GetWindowLong(hWnd, 0);
}
inline void SetPointer(HWND hWnd, VT102Emulator * pWindow)
{
SetWindowLong(hWnd, 0, (LONG) pWindow);
}
// -----------------------------------------------------------------
// BlockingHook - called while WinSock is in a blocking call (connect)
//
// We must not call any WinSock interface functions during this--which
// is to say we must not process keyboard input except for BREAK, and
// of course we must not retrieve socket messages (DUH).
//
BOOL CALLBACK Global::BlockingHook(void)
{
MSG msg;
BOOL ret;
// Get a keystroke if available, yield to other processes
ret = PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE);
if (ret)
{
// Ignore keystrokes, but if break key is hit, cancel!
if (WM_KEYDOWN == msg.message && VK_CANCEL == msg.wParam)
WSACancelBlockingCall();
}
else
{
// Check for expose and destroy events (don't yield)
ret = (PeekMessage(&msg,NULL,WM_PAINT,WM_PAINT,PM_REMOVE|PM_NOYIELD)
|| PeekMessage(&msg,NULL,WM_DESTROY,WM_DESTROY,PM_REMOVE|PM_NOYIELD));
if (ret)
{
TranslateMessage(&msg); // Don't bother with accelerators
DispatchMessage(&msg);
};
};
return ret; // TRUE if we got a message and handled it
}
// ----------------------------------------------------------------------
// GetchLoop - simulated getch!
//
// This ignores most everything except keystrokes, paint events, and
// related things (maybe minimize/restore?)
//
// Returns:
// the got character
//
int Global::GetchLoop()
{
MSG msg;
int got_ch;
int done = 0;
while (!done) // Several continue statements in this loop...
{
// Get a keystroke if available, yield to other processes
if (PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE))
{
// Turn into a char, if possible
if (0 == TranslateMessage(&msg) // Not translatable
&& WM_CHAR == msg.message) // keystroke message?
{
got_ch = (int)msg.wParam; // Got a keystroke!
done = 1;
}
}
else if (PeekMessage(&msg,NULL,WM_PAINT,WM_PAINT,PM_REMOVE|PM_NOYIELD)
|| PeekMessage(&msg,NULL,WM_DESTROY,WM_DESTROY,PM_REMOVE|PM_NOYIELD))
{
TranslateMessage(&msg); // Don't bother with accelerators
DispatchMessage(&msg);
};
};
return got_ch; // Return the char we got
}
// ----------------------------------------------------------------------
// Init - to be called from WinMain to save the instance variables
// ----------------------------------------------------------------------
void Global::Init(HINSTANCE inst, HINSTANCE prev)
{
_hInstance = inst;
_hPrevInstance = prev;
_accelerators = LoadAccelerators(inst,
MAKEINTRESOURCE(ACC_MyAccelerators));
};
// ----------------------------------------------------------------------
// PostOutOfMemoryMessage - tell the user we're out
// ----------------------------------------------------------------------
void Global::PostOutOfMemoryMessage()
{
MessageBox(NULL,
_out_of_memory_message,
"Terribly sorry to bother you...",
MB_SYSTEMMODAL | MB_ICONHAND | MB_OK);
}
// ----------------------------------------------------------------------
// WndProc - Main window proc where all (window) messages are recieved
// ----------------------------------------------------------------------
LRESULT CALLBACK _export Global::WndProc(HWND hWnd,
UINT iMessage,
WPARAM wParam,
LPARAM lParam)
{
LRESULT return_value;
try // Handle exceptions
{
// The pointer pWindow will have an invalid value if the WM_CREATE
// message has not yet been processed. At a call to WM_CREATE,
// of course, we set that value.
// This code will break if windows fails to set extra bytes to
// zero at some future rev.
// Get window's "this" pointer
VT102Emulator *pWindow = GetPointer(hWnd);
if (pWindow == 0) // Pointer not set?
{
if (iMessage == WM_CREATE) // Create message is special
{
// Retrieve the window's "this" pointer
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
pWindow = (VT102Emulator *) lpcs->lpCreateParams;
// Store the "This" pointer in the window's extra bytes
SetPointer(hWnd, pWindow);
// Now let the object perform whatever
// initialization it needs for WM_CREATE in its own
// WndProc.
return_value = pWindow->WndProc( iMessage, wParam, lParam );
}
else
{
// Not our message, pass it on.
return_value = DefWindowProc( hWnd, iMessage, wParam, lParam );
};
}
else
{
// Call the window's proc
return_value = pWindow->WndProc( iMessage, wParam, lParam );
};
}
catch (xalloc &)
{
PostOutOfMemoryMessage();
return_value = DefWindowProc(hWnd, iMessage, wParam, lParam);
};
return return_value;
}
// ----------------------------------------------------------------------
// _MessageLoop - main program loop of the emulator.
//
// Loops until program exit.
// ----------------------------------------------------------------------
int Global::MessageLoop()
{
MSG msg; // Windows event message
while (GetMessage(&msg, NULL, 0, 0))
{
// Accelerators get first dibs on the keystrokes
if (0 == TranslateAccelerator(msg.hwnd, _accelerators, &msg))
TranslateMessage(&msg);
// Shouldn't we be doing something special for dialogs here?
DispatchMessage(&msg);
};
return msg.wParam; // Hopefully the return value of the exit dialog
}
//
// >>>>> WinMain <<<<< //
//
// ----------------------------------------------------------------------
// WinMain - called by Windoze at program startup
// ----------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
(void) lpszCmdLine; // Silence 'not used' warning
extern int _argc;
extern char **_argv;
int ret_val = EXIT_FAILURE;
try
{
// Require path to startup file as command-line option
if (2 != _argc)
scream_and_die(EC_FatalError, ERR_CommandLine);
Global::Init(hInstance, hPrevInstance); // Init globals
// Initialize the winsock interface
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD (1, 1);
if (WSAStartup(wVersionRequested, &wsaData) != 0)
scream_and_die(EC_WinSock, ERR_WinSockMissing);
if (NULL == WSASetBlockingHook(Global::BlockingHook))
scream_and_die(EC_WinSock, ERR_BlockingHook);
main_window = new VT102Emulator(nCmdShow); // Create main window
main_init_all(_argc, _argv); // Initialize VT
ret_val = Global::MessageLoop(); // Go!
}
catch (xalloc &)
{
Global::PostOutOfMemoryMessage();
}
catch (...)
{
WSACleanup(); // At least take care of the sockets
throw;
};
delete main_window; // Free memory
WSACleanup (); // clean up Winsock stuff
return ret_val;
}
// ----------------------------------------------------------------------
// These are called by VaporTalk
//
extern "C" {
/* Returns non-null on error */
const char * NewSocket(SOCKET s, long evt)
{
if (main_window)
return main_window->NewSocket(s, evt);
return "Main program not initialized";
};
void WriteString(char * str, int len)
{
if (main_window)
main_window->Output(str, len);
}
}
// EOF //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -