476 lines
11 KiB
C++
476 lines
11 KiB
C++
//
|
|
// MAIN.CPP
|
|
// Whiteboard Windows App Code
|
|
//
|
|
// Copyright Microsoft 1998-
|
|
//
|
|
|
|
|
|
// PRECOMP
|
|
#include "precomp.h"
|
|
|
|
|
|
WbMainWindow * g_pMain;
|
|
HINSTANCE g_hInstance;
|
|
IWbClient* g_pwbCore;
|
|
UINT g_uConfShutdown;
|
|
WbPrinter * g_pPrinter;
|
|
|
|
BOOL g_bPalettesInitialized;
|
|
BOOL g_bUsePalettes;
|
|
HPALETTE g_hRainbowPaletteDisplay;
|
|
|
|
HINSTANCE g_hImmLib;
|
|
IGC_PROC g_fnImmGetContext;
|
|
INI_PROC g_fnImmNotifyIME;
|
|
|
|
//
|
|
// Arrays
|
|
//
|
|
COLORREF g_ColorTable[NUM_COLOR_ENTRIES] =
|
|
{
|
|
RGB( 0, 255, 255), // Cyan
|
|
RGB(255, 255, 0), // Yellow
|
|
RGB(255, 0, 255), // Magenta
|
|
RGB( 0, 0, 255), // Blue
|
|
RGB(192, 192, 192), // Grey
|
|
RGB(255, 0, 0), // Red
|
|
RGB( 0, 0, 128), // Dark blue
|
|
RGB( 0, 128, 128), // Dark cyan
|
|
RGB( 0, 255, 0), // Green
|
|
RGB( 0, 128, 0), // Dark green
|
|
RGB(128, 0, 0), // Dark red
|
|
RGB(128, 0, 128), // Purple
|
|
RGB(128, 128, 0), // Olive
|
|
RGB(128, 128, 128), // Grey
|
|
RGB(255, 255, 255), // White
|
|
RGB( 0, 0, 0), // Black
|
|
RGB(255, 128, 0), // Orange
|
|
RGB(128, 255, 255), // Turquoise
|
|
RGB( 0, 128, 255), // Mid blue
|
|
RGB( 0, 255, 128), // Pale green
|
|
RGB(255, 0, 128) // Dark pink
|
|
};
|
|
|
|
|
|
int g_ClipboardFormats[CLIPBOARD_ACCEPTABLE_FORMATS] =
|
|
{
|
|
0, // CLIPBOARD_PRIVATE_SINGLE_OBJ - Reserved for the
|
|
// Whiteboard private format
|
|
0,
|
|
CF_DIB, // Standard formats
|
|
CF_ENHMETAFILE, // move metafiles to lower pri than bitmaps (bug NM4db:411)
|
|
CF_TEXT
|
|
};
|
|
|
|
|
|
|
|
// Default widths for all tools except for highlighters
|
|
UINT g_PenWidths[NUM_OF_WIDTHS] = { 2, 4, 8, 16 };
|
|
|
|
// Default widths for highlight tools
|
|
UINT g_HighlightWidths[NUM_OF_WIDTHS] = { 4, 8, 16, 32 };
|
|
|
|
//
|
|
// Objects
|
|
//
|
|
WbUserList * g_pUsers;
|
|
WbDrawingArea * g_pDraw;
|
|
DCWbColorToIconMap * g_pIcons;
|
|
|
|
#ifdef _DEBUG
|
|
HDBGZONE ghZoneWb;
|
|
|
|
PTCHAR g_rgZonesWb[] = // CHECK ZONE_WBxxx CONSTANTS IF THESE CHANGE
|
|
{
|
|
"OldWB",
|
|
DEFAULT_ZONES
|
|
"DEBUG",
|
|
"MSG",
|
|
"TIMER",
|
|
"EVENT"
|
|
};
|
|
#endif // _DEBUG
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/* D L L M A I N */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: DllMain
|
|
|
|
-------------------------------------------------------------------------*/
|
|
BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD fdwReason, LPVOID lpv)
|
|
{
|
|
switch (fdwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
#ifdef _DEBUG
|
|
MLZ_DbgInit((PSTR *) &g_rgZonesWb[0],
|
|
(sizeof(g_rgZonesWb) / sizeof(g_rgZonesWb[0])) - 1);
|
|
#endif
|
|
g_hInstance = hDllInst;
|
|
DisableThreadLibraryCalls(g_hInstance);
|
|
|
|
DBG_INIT_MEMORY_TRACKING(hDllInst);
|
|
break;
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
g_hInstance = NULL;
|
|
|
|
DBG_CHECK_MEMORY_TRACKING(hDllInst);
|
|
#ifdef _DEBUG
|
|
MLZ_DbgDeInit();
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Whiteboard's init routine
|
|
//
|
|
BOOL WINAPI InitWB(void)
|
|
{
|
|
BOOL fInited = FALSE;
|
|
|
|
ASSERT(!g_pMain);
|
|
ASSERT(!g_hImmLib);
|
|
ASSERT(!g_fnImmGetContext);
|
|
ASSERT(!g_fnImmNotifyIME);
|
|
|
|
//
|
|
// Load IMM32 if this is FE
|
|
//
|
|
if (GetSystemMetrics(SM_DBCSENABLED))
|
|
{
|
|
g_hImmLib = LoadLibrary("imm32.dll");
|
|
if (!g_hImmLib)
|
|
{
|
|
ERROR_OUT(("Failed to load imm32.dll"));
|
|
}
|
|
else
|
|
{
|
|
g_fnImmGetContext = (IGC_PROC)GetProcAddress(g_hImmLib, "ImmGetContext");
|
|
if (!g_fnImmGetContext)
|
|
{
|
|
ERROR_OUT(("Failed to get ImmGetContext pointer"));
|
|
}
|
|
g_fnImmNotifyIME = (INI_PROC)GetProcAddress(g_hImmLib, "ImmNotifyIME");
|
|
if (!g_fnImmNotifyIME)
|
|
{
|
|
ERROR_OUT(("Failed to get ImmNotifyIME pointer"));
|
|
}
|
|
}
|
|
}
|
|
|
|
g_pMain = new WbMainWindow();
|
|
if (!g_pMain)
|
|
{
|
|
ERROR_OUT(("Can't create WbMainWindow"));
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// OK, now we're ready to create our HWND
|
|
//
|
|
if (!g_pMain->Open(SW_SHOWDEFAULT))
|
|
{
|
|
ERROR_OUT(("Can't create WB windows"));
|
|
goto Done;
|
|
}
|
|
|
|
fInited = TRUE;
|
|
|
|
Done:
|
|
return(fInited);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Whiteboard's term routine
|
|
//
|
|
void WINAPI TermWB(void)
|
|
{
|
|
if (g_pMain != NULL)
|
|
{
|
|
delete g_pMain;
|
|
g_pMain = NULL;
|
|
}
|
|
|
|
g_fnImmNotifyIME = NULL;
|
|
g_fnImmGetContext = NULL;
|
|
|
|
if (g_hImmLib)
|
|
{
|
|
FreeLibrary(g_hImmLib);
|
|
g_hImmLib = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Whiteboard's thread handler
|
|
//
|
|
void WINAPI RunWB(void)
|
|
{
|
|
ASSERT(g_pMain != NULL);
|
|
|
|
//
|
|
// Try to join call
|
|
//
|
|
//
|
|
// Find out if we're in a call and join if so.
|
|
//
|
|
if (!g_pMain->JoinDomain())
|
|
{
|
|
ERROR_OUT(("WB couldn't start up and join call"));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// MESSAGE LOOP
|
|
//
|
|
MSG msg;
|
|
|
|
while (::GetMessage(&msg, NULL, NULL, NULL))
|
|
{
|
|
if (!g_pMain->FilterMessage(&msg))
|
|
{
|
|
::TranslateMessage(&msg);
|
|
::DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Mapping of internal return codes to string resources
|
|
//
|
|
typedef struct tagERROR_MAP
|
|
{
|
|
UINT uiFEReturnCode;
|
|
UINT uiDCGReturnCode;
|
|
UINT uiCaption;
|
|
UINT uiMessage;
|
|
}
|
|
ERROR_MAP;
|
|
|
|
|
|
ERROR_MAP g_ErrorStringID[] =
|
|
{
|
|
{ WBFE_RC_JOIN_CALL_FAILED, // Registration failed
|
|
0,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_JOIN_CALL_FAILED
|
|
},
|
|
|
|
{ WBFE_RC_WINDOWS, // A windows error has occurred
|
|
0,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_WINDOWS_RESOURCES
|
|
},
|
|
|
|
{ WBFE_RC_WB, // Page limit exceeded
|
|
WB_RC_TOO_MANY_PAGES,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_TOO_MANY_PAGES
|
|
},
|
|
|
|
{ WBFE_RC_WB, // Another user has the contents lock
|
|
WB_RC_LOCKED,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_LOCKED
|
|
},
|
|
|
|
{ WBFE_RC_WB, // Another user has the graphic locked
|
|
WB_RC_GRAPHIC_LOCKED,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_GRAPHIC_LOCKED,
|
|
},
|
|
|
|
{ WBFE_RC_WB, // The local user does not have the lock
|
|
WB_RC_NOT_LOCKED,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_NOT_LOCKED
|
|
},
|
|
|
|
{ WBFE_RC_WB, // File is not in expected format
|
|
WB_RC_BAD_FILE_FORMAT,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_BAD_FILE_FORMAT
|
|
},
|
|
|
|
{ WBFE_RC_WB, // Whiteboard busy (exhausted page cache)
|
|
WB_RC_BUSY,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_BUSY
|
|
},
|
|
|
|
{ WBFE_RC_CM, // Failed to access call manager
|
|
0,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_CM_ERROR
|
|
},
|
|
|
|
{ WBFE_RC_AL, // Failed to register with application loader
|
|
0,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_AL_ERROR
|
|
},
|
|
|
|
{ WBFE_RC_PRINTER, // Failed to register with application loader
|
|
0,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_PRINTER_ERROR
|
|
},
|
|
|
|
{ 0, // Catch-all default
|
|
0,
|
|
IDS_MSG_CAPTION,
|
|
IDS_MSG_DEFAULT
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// Function: Message
|
|
//
|
|
// Purpose: Display an error message box with string resources specified
|
|
// as parameters, with the WB main window as the modal window.
|
|
//
|
|
//
|
|
int Message
|
|
(
|
|
HWND hwnd,
|
|
UINT uiCaption,
|
|
UINT uiMessage,
|
|
UINT uiStyle
|
|
)
|
|
{
|
|
TCHAR message[256];
|
|
TCHAR caption[256];
|
|
|
|
//make sure we're on top
|
|
ASSERT(g_pMain);
|
|
if (!hwnd)
|
|
hwnd = g_pMain->m_hwnd;
|
|
|
|
if (hwnd != NULL)
|
|
{
|
|
::SetForegroundWindow(hwnd);
|
|
}
|
|
|
|
LoadString(g_hInstance, uiMessage, message, 256);
|
|
|
|
LoadString(g_hInstance, uiCaption, caption, 256);
|
|
|
|
//
|
|
// BOGUS LAURABU:
|
|
// Make use of MessageBoxEx() and just pass the string IDs along,
|
|
// rather than doing the LoadString() ourself.
|
|
//
|
|
|
|
// Display a message box with the relevant text
|
|
return(::MessageBox(hwnd, message, caption, uiStyle));
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// Function: ErrorMessage
|
|
//
|
|
// Purpose: Display an error based on return codes from Whiteboard
|
|
// processing.
|
|
//
|
|
//
|
|
void ErrorMessage(UINT uiFEReturnCode, UINT uiDCGReturnCode)
|
|
{
|
|
MLZ_EntryOut(ZONE_FUNCTION, "::ErrorMessage (codes)");
|
|
|
|
TRACE_MSG(("FE return code = %hd", uiFEReturnCode));
|
|
TRACE_MSG(("DCG return code = %hd", uiDCGReturnCode));
|
|
|
|
// check for special OM_RC_OBJECT_DELETED case
|
|
if (uiDCGReturnCode == OM_RC_OBJECT_DELETED)
|
|
{
|
|
// don't complain, just cancel drawing
|
|
g_pMain->m_drawingArea.CancelDrawingMode();
|
|
return;
|
|
}
|
|
|
|
// Find the associated string resource IDS
|
|
int iIndex;
|
|
|
|
for (iIndex = 0; ; iIndex++)
|
|
{
|
|
// If we have come to the end of the list, stop
|
|
if (g_ErrorStringID[iIndex].uiFEReturnCode == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Check for a match
|
|
if (g_ErrorStringID[iIndex].uiFEReturnCode == uiFEReturnCode)
|
|
{
|
|
if ( (g_ErrorStringID[iIndex].uiDCGReturnCode == uiDCGReturnCode)
|
|
|| (g_ErrorStringID[iIndex].uiDCGReturnCode == 0))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Display the message
|
|
Message(NULL, g_ErrorStringID[iIndex].uiCaption, g_ErrorStringID[iIndex].uiMessage);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// Function: DefaultExceptionHandler
|
|
//
|
|
// Purpose: Default exception processing. This can be called in an
|
|
// exception handler to get a message relevant to the
|
|
// exception. The message is generated by posting a message to
|
|
// the applications main window.
|
|
//
|
|
//
|
|
void DefaultExceptionHandler(UINT uiFEReturnCode, UINT uiDCGReturnCode)
|
|
{
|
|
MLZ_EntryOut(ZONE_FUNCTION, "DefaultExceptionHandler");
|
|
|
|
// Post a message to the main window to get the error displayed
|
|
if (g_pMain != NULL)
|
|
{
|
|
// check for special OM_RC_OBJECT_DELETED case
|
|
if (uiDCGReturnCode == OM_RC_OBJECT_DELETED)
|
|
{
|
|
// don't complain, just cancel drawing
|
|
g_pMain->m_drawingArea.CancelDrawingMode();
|
|
return;
|
|
}
|
|
|
|
if (g_pMain->m_hwnd)
|
|
::PostMessage(g_pMain->m_hwnd, WM_USER_DISPLAY_ERROR, uiFEReturnCode, uiDCGReturnCode);
|
|
}
|
|
}
|