windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/nmctl1/nmchatctl.cpp
2020-09-26 16:20:57 +08:00

3287 lines
78 KiB
C++

// NmChatCtl.cpp : Implementation of CNmChatCtl
#include "precomp.h"
#include "NmCtl1.h"
#include "NmChatCtl.h"
#include "ComboBoxEx.h"
#include "Message.h"
#include "OprahCom.h"
#include <version.h>
#include <nmhelp.h>
#include <help_ids.h>
extern CChatObj *g_pChatObj;
extern DWORD g_dwWorkThreadID;
// Class name
TCHAR szMainClassName[] = "ChatMainWindowClass";
static const TCHAR s_cszHtmlHelpFile[] = TEXT("nmchat.chm");
static const DWORD _mpIdHelpChatOptions[] = {
// Information display group
IDR_MESSAGE_GROUP, IDH_CHAT_FORMAT_HEADER,
IDC_INCLUDE_NAME, IDH_CHAT_NAME,
IDC_INCLUDE_DATE, IDH_CHAT_DATE,
IDC_INCLUDE_TIME, IDH_CHAT_TIME,
// Message Format group
IDC_HEADER_GROUP, IDH_CHAT_FORMAT_MESSAGE,
IDR_SINGLE_LINE, IDH_CHAT_FORMAT_MESSAGE,
IDR_SAME_LINE, IDH_CHAT_FORMAT_MESSAGE,
IDR_NEW_LINE, IDH_CHAT_FORMAT_MESSAGE,
IDC_FORMATSINGLE, IDH_CHAT_FORMAT_MESSAGE,
IDC_FORMATWRAP, IDH_CHAT_FORMAT_MESSAGE,
IDC_FORMATWRAPNEW, IDH_CHAT_FORMAT_MESSAGE,
// Font buttons and edit controls
IDC_FONTS_GROUP, IDH_CHAT_FONTS_LABEL,
IDC_FONT_MSGIN, IDH_CHAT_RECEIVE_MSG,
IDC_EDIT_MSGIN, IDH_CHAT_FONT,
IDC_FONT_PRIVATEIN, IDH_CHAT_RECEIVE_PRIV,
IDC_EDIT_PRIVATEIN, IDH_CHAT_FONT,
IDC_FONT_MSGOUT, IDH_CHAT_SENT_MSG,
IDC_EDIT_MSGOUT, IDH_CHAT_FONT,
IDC_FONT_PRIVATEOUT, IDH_CHAT_SENT_PRIV,
IDC_EDIT_PRIVATEOUT, IDH_CHAT_FONT,
// terminator
0, 0
};
// Option entry names
#define OPT_MAIN_INFORMATION_DISPLAY_NAME "Information Display Name"
#define OPT_MAIN_INFORMATION_DISPLAY_TIME "Information Display Time"
#define OPT_MAIN_INFORMATION_DISPLAY_DATE "Information Display Date"
#define OPT_MAIN_MESSAGE_FORMAT "Message format"
const LPTSTR OPT_FONT_FORMAT[] = {"Received Message", "Received Private Messages",
"Send Messages", "Send Private Messages", "System Format"};
const LPTSTR OPT_FONT_COLOR[] = {"Received Message Color", "Received Private Messages Color",
"Send Messages Color", "Send Private Messages Color", "System Format Color"};
extern CNmChatCtl *g_pChatWindow;
CNmChatCtl *CNmChatCtl::ms_pThis = NULL;
WORD CChatOptionsDlg::IDD = IDD_CHAT_OPTIONS;
///////////////////////////////////////////////////////////////////////////////////////////////////////
// CNmChatCtl Construction and initialization
///////////////////////////////////////////////////////////////////////////////////////////////////////
CNmChatCtl::CNmChatCtl( void )
: m_hWndMsg( NULL ),
m_himlIconSmall( NULL ),
m_cOtherMembers( 0 ),
m_hMenuShared(NULL),
m_cchBufferSize( 0 ),
m_hInstRichEd32( NULL ),
m_bUseName( -1 ),
m_bTimeStamp( 0 ),
m_bUseDate( 0 ),
m_style( MSGSTYLE_2_LINE_WRAP ),
m_lpszOwnName( NULL ),
m_iNameLen( 0 ),
m_iStaticLen( 0 ),
m_iDLGUX( 0 ),
m_iDLGUY( 0 ),
m_iStaticY( 0 ),
m_iExtra( 0 ),
m_szTo( NULL ),
m_szPrivate( NULL ),
m_bWeAreActiveApp(false),
m_dwChatFlags( CHAT_FLAG_NONE ),
m_hWndPrint( NULL ),
m_lpszSaveFile( NULL ),
m_bStatusBarVisible( TRUE ),
m_wFileOffset( 0 ),
m_lpszRichEdEOL( NULL ),
m_lpszRichEd( NULL ),
m_pChatOptions( NULL ),
m_cMessages( 0 )
{
DBGENTRY(CNmChatCtl::CNmChatCtl);
g_pChatWindow = this;
// Ensure the common controls are loaded
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES | ICC_COOL_CLASSES | ICC_USEREX_CLASSES;
::InitCommonControlsEx(&icc);
_LoadIconImages();
_InitFontsAndColors();
//
// CREATE THE MAIN FRAME WINDOW
//
//
// Get the class info for it, and change the name.
//
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(wc));
wc.cbSize = sizeof(wc);
wc.style = CS_DBLCLKS; // CS_HREDRAW | CS_VREDRAW?
wc.lpfnWndProc = ChatMainWindowProc;
wc.hInstance = g_hInstance;
wc.hIcon = ::LoadIcon(g_hInstance, MAKEINTRESOURCE(CHAT_ICON));
wc.hCursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU_CHAT_WITHFILE);
wc.lpszClassName = szMainClassName;
if (!::RegisterClassEx(&wc))
{
ERROR_OUT(("Can't register private frame window class"));
}
TCHAR szCaption[MAX_PATH * 2];
::LoadString(g_hInstance, IDS_CHAT_NOT_IN_CALL_WINDOW_CAPTION, szCaption, sizeof(szCaption) );
m_hWnd = ::CreateWindow(
szMainClassName,
szCaption,
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // no parent window
NULL, // use class' menu
g_hInstance,
(LPVOID) this); // this window is for this object
m_hMenuShared = ::GetMenu(m_hWnd);
ASSERT(m_hWnd);
DBGEXIT(CNmChatCtl::CNmChatCtl);
}
CNmChatCtl::~CNmChatCtl( void )
{
DBGENTRY(CNmChatCtl::~CNmChatCtl);
delete [] m_lpszOwnName;
delete [] m_szTo;
delete [] m_szPrivate;
delete [] m_lpszSaveFile;
delete [] m_lpszRichEdEOL;
delete [] m_lpszRichEd;
if( NULL != m_hInstRichEd32 )
FreeLibrary( m_hInstRichEd32 );
CChatMessage::DeleteAll();
m_pButton->Release();
_DeleteFonts();
_FreeIconImages();
delete m_pChatOptions;
DBGEXIT(CNmChatCtl::~CNmChatCtl);
}
//
// FilterMessage()
//
// This does tooltip message filtering, then translates accelerators.
//
BOOL CNmChatCtl::FilterMessage(MSG* pMsg)
{
return ( (m_hAccelTable != NULL)
&& ::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg));
}
//
// ChatMainWindowProc()
// Frame window message handler
//
LRESULT CNmChatCtl::ChatMainWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
CNmChatCtl * pMain;
LPWINDOWPOS pos;
pMain = (CNmChatCtl *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch (message)
{
case WM_NCCREATE:
pMain = (CNmChatCtl *)((LPCREATESTRUCT)lParam)->lpCreateParams;
ASSERT(pMain);
pMain->m_hWnd = hwnd;
::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pMain);
pMain->OnCreate(wParam,lParam);
goto DefWndProc;
break;
case WM_CREATE:
::SetFocus(pMain->m_hWndEdit);
break;
case WM_NCDESTROY:
pMain->m_hWnd = NULL;
break;
case WM_MENUSELECT:
pMain->OnMenuSelect((DWORD)wParam, (DWORD)lParam);
break;
case WM_INITMENUPOPUP:
pMain->OnInitMenuPopup((DWORD)wParam, (DWORD)lParam);
break;
case WM_ENDSESSION:
case WM_CLOSE:
pMain->cmdFileExit(wParam);
break;
case WM_COMMAND:
pMain->OnCommand((DWORD)wParam, (DWORD)lParam);
break;
case WM_CONTEXTMENU:
pMain->OnContextMenu((short)LOWORD(lParam), (short)HIWORD(lParam));
break;
case WM_SIZE:
pMain->_Resize(0, 0, (short)LOWORD(lParam), (short)HIWORD(lParam));
break;
case WM_GETMINMAXINFO:
if (pMain)
{
pMain->OnGetMinMaxInfo((LPMINMAXINFO)lParam);
}
break;
case WM_USER_BRING_TO_FRONT_WINDOW:
pMain->BringToFront();
break;
case WM_ACTIVATE:
if (WA_INACTIVE != LOWORD(wParam) && IsWindowVisible(pMain->m_hWndEdit))
{
::SetFocus(pMain->m_hWndEdit);
}
break;
case WM_NOTIFY:
if(EN_LINK == ((LPNMHDR)lParam)->code)
{
pMain->OnNotifyEnLink((ENLINK*)lParam);
}
break;
default:
DefWndProc:
lResult = ::DefWindowProc(hwnd, message, wParam, lParam);
break;
}
return(lResult);
}
void CNmChatCtl::BringToFront(void)
{
if (NULL != m_hWnd)
{
int nCmdShow = SW_SHOW;
WINDOWPLACEMENT wp;
::ZeroMemory(&wp, sizeof(wp));
wp.length = sizeof(wp);
if (::GetWindowPlacement(m_hWnd, &wp))
{
if (SW_MINIMIZE == wp.showCmd || SW_SHOWMINIMIZED == wp.showCmd)
{
// The window is minimized - restore it:
nCmdShow = SW_RESTORE;
}
}
// show the window now
::ShowWindow(m_hWnd, nCmdShow);
// bring it to the foreground
::SetForegroundWindow(m_hWnd);
//
// Set the focus on the edit box
//
::SetFocus(m_hWndEdit);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// CNmChatCtl Window message and command handlers
///////////////////////////////////////////////////////////////////////////////////////////////////////
LRESULT CNmChatCtl::OnCreate(WPARAM wParam, LPARAM lParam)
{
DBGENTRY(CNmChatCtl::OnCreate);
RECT rc;
SetRect( &rc, 0, 0, 0, 0 );
if( NULL == ( m_hInstRichEd32 = ::LoadLibrary( "RICHED20.DLL" ) ) )
{
if( NULL == ( m_hInstRichEd32 = ::LoadLibrary( "RICHED32.DLL" ) ) )
{
return 0;
}
else
{
LPTSTR szValue = TEXT("RichEdit");
LPTSTR szValueEOL = TEXT("\r\n");
DBG_SAVE_FILE_LINE
m_lpszRichEd = new TCHAR[ lstrlen( szValue ) + 1 ];
lstrcpy( m_lpszRichEd, szValue );
m_lpszRichEdEOL = new TCHAR[ lstrlen( szValueEOL ) + 1 ];
lstrcpy( m_lpszRichEdEOL, szValueEOL );
}
}
else
{
LPTSTR szValue = RICHEDIT_CLASS;
LPTSTR szValueEOL = TEXT(" \r");
DBG_SAVE_FILE_LINE
m_lpszRichEd = new TCHAR[ lstrlen( szValue ) + 1 ];
lstrcpy( m_lpszRichEd, szValue );
DBG_SAVE_FILE_LINE
m_lpszRichEdEOL = new TCHAR[ lstrlen( szValueEOL ) + 1 ];
lstrcpy( m_lpszRichEdEOL, szValueEOL );
}
////////// Edit control
m_hWndEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE,
_T("EDIT"),
NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE |
WS_TABSTOP | ES_MULTILINE | ES_AUTOVSCROLL,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
m_hWnd, NULL, g_hInstance, NULL);
::SendMessage( m_hWndEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT ), TRUE);
::SendMessage( m_hWndEdit, EM_LIMITTEXT, CCHMAX_CHAT_MSG - 1, 0 );
::SendMessage( m_hWndEdit, EM_EXLIMITTEXT, 0, CCHMAX_CHAT_MSG - 1 );
//// Get info from edit control
TEXTMETRIC textmex;
ZeroMemory( &textmex, sizeof( textmex ) );
HDC hdc = GetDC(m_hWndEdit);
GetTextMetrics( hdc, &textmex );
ReleaseDC(m_hWndEdit, hdc );
m_iDLGUY = PIX_FROM_DLGU_Y( 1, textmex.tmHeight );
m_iDLGUX = PIX_FROM_DLGU_X( 1, textmex.tmAveCharWidth);
////////// Send Button
DBG_SAVE_FILE_LINE
m_pButton = new CBitmapButton();
if(m_pButton)
{
BOOL fRet = m_pButton->Create(m_hWnd,
IDI_SENDBUTTON,
g_hInstance,
IDB_SENDCHAT,
TRUE,
CBitmapButton::Disabled,
1,
NULL);
m_hWndSend = m_pButton->GetWindow();
if(fRet == FALSE)
{
m_pButton->Release();
return fRet;
}
m_pButton->SetTooltip((LPSTR)IDS_TOOLTIP_SEND_MESSAGE);
}
else
{
return FALSE;
}
////////// Member List
m_hWndMemberList = ::CreateWindowEx(0,
_T(WC_COMBOBOXEX),
NULL,
WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VSCROLL,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
m_hWnd, NULL, g_hInstance, NULL);
ASSERT( m_himlIconSmall );
::SendMessage(m_hWndMemberList, WM_SETFONT, (WPARAM)GetStockObject( DEFAULT_GUI_FONT ), TRUE);
ComboBoxEx_SetImageList( m_hWndMemberList, m_himlIconSmall );
int yFrameBorder = GetSystemMetrics( SM_CYFIXEDFRAME );
int ySpace = GetSystemMetrics( SM_CYBORDER );
int iHeight = ComboBoxEx_GetItemHeight( m_hWndMemberList, 0 );
ComboBoxEx_SetHeight( m_hWndMemberList, ((iHeight + ySpace) * MSGLIST_VISMEMBERS) + yFrameBorder);
////////// Status bar
RECT clientRect;
::GetClientRect(m_hWnd, &clientRect);
m_hwndSB = ::CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_NOMOVEY |
CCS_NORESIZE | SBARS_SIZEGRIP,
clientRect.left, clientRect.bottom - STATUSBAR_HEIGHT,
(clientRect.right - clientRect.left), STATUSBAR_HEIGHT,
m_hWnd, 0, g_hInstance, NULL);
if (!m_hwndSB)
{
ERROR_OUT(("Failed to create status bar window"));
return(FALSE);
}
////////// Static
TCHAR szBuff[ MAX_PATH ];
NmCtlLoadString( IDS_CHAT_MESSAGE, szBuff, CCHMAX(szBuff));
m_hWndStaticMessage = ::CreateWindowEx(0,
_T("STATIC"),
szBuff,
WS_VISIBLE | WS_CHILD | SS_LEFT,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
m_hWnd, NULL, g_hInstance, NULL);
::SendMessage(m_hWndStaticMessage, WM_SETFONT, (WPARAM)GetStockObject( DEFAULT_GUI_FONT ), TRUE);
////////// Static
NmCtlLoadString( IDS_CHAT_SENDTO, szBuff, CCHMAX(szBuff));
m_hWndStaticSendTo = ::CreateWindowEx(0,
_T("STATIC"),
szBuff,
WS_VISIBLE | WS_CHILD | SS_LEFT,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
m_hWnd, NULL, g_hInstance, NULL);
::SendMessage(m_hWndStaticSendTo, WM_SETFONT, (WPARAM)GetStockObject( DEFAULT_GUI_FONT ), TRUE);
////// Get info for static controls
hdc = ::GetDC(m_hWndStaticMessage);
GetTextMetrics( hdc, &textmex );
TCHAR szBuffer[ MAX_PATH ];
GetWindowText(m_hWndStaticMessage, szBuffer, CCHMAX( szBuffer ) );
RECT rect1;
ZeroMemory( &rect1, sizeof( rect1 ) );
DrawText( hdc, szBuffer, lstrlen( szBuffer ), &rect1, DT_CALCRECT );
GetWindowText(m_hWndStaticSendTo, szBuffer, CCHMAX( szBuffer ) );
RECT rect2;
ZeroMemory( &rect2, sizeof( rect2 ) );
DrawText( hdc, szBuffer, lstrlen( szBuffer ), &rect1, DT_CALCRECT );
ReleaseDC(m_hWndStaticMessage, hdc );
m_iStaticLen = max( rect1.right, rect2.right );
m_iStaticY = max( rect1.bottom, rect2.bottom );
_UpdateContainerCaption();
put_MsgStyle( m_style );
_LoadStrings();
HICON hIconSmall = (HICON)LoadImage(
g_hInstance, // handle of the instance containing the image
MAKEINTRESOURCE( CHAT_ICON ), // name or identifier of image
IMAGE_ICON, // type of image
ICON_SMALL_SIZE, // desired width
ICON_SMALL_SIZE, // desired height
LR_DEFAULTCOLOR // load flags
);
HICON hIconLarge = (HICON)LoadImage(
g_hInstance, // handle of the instance containing the image
MAKEINTRESOURCE( CHAT_ICON ), // name or identifier of image
IMAGE_ICON, // type of image
ICON_BIG_SIZE, // desired width
ICON_BIG_SIZE, // desired height
LR_DEFAULTCOLOR // load flags
);
DBGEXIT_ULONG(CNmChatCtl::OnCreate, 0);
// Load the main accelerator table
m_hAccelTable = ::LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR));
RECT rcUI;
_GetWindowRectOption(&rcUI);
::MoveWindow(m_hWnd, rcUI.left, rcUI.top, rcUI.right - rcUI.left, rcUI.bottom - rcUI.top, TRUE);
return TRUE;
}
void CNmChatCtl::_LoadStrings()
{
TCHAR buffer[ MAX_PATH ];
NmCtlLoadString(IDS_PRIVATE, buffer, CCHMAX(buffer));
DBG_SAVE_FILE_LINE
m_szPrivate = new TCHAR[ lstrlen( buffer ) + 1 ];
ASSERT( m_szPrivate );
lstrcpy( m_szPrivate, buffer );
NmCtlLoadString(IDS_TO, buffer, CCHMAX(buffer));
DBG_SAVE_FILE_LINE
m_szTo = new TCHAR[ lstrlen( buffer ) + 1 ];
ASSERT( m_szTo );
lstrcpy( m_szTo, buffer );
m_iExtra = lstrlen( m_szTo ) + lstrlen( m_szPrivate ) + 1;
}
void CNmChatCtl::_InitFontsAndColors()
{
if (_LoadChatOptions())
{ // Load options succeed
return;
}
// Load Fonts
for( int i = 0; i < CChatOptionsDlg::FONT_COUNT; i++ )
{
GetObject( GetStockObject( DEFAULT_GUI_FONT ), sizeof( m_hMsgLogFonts[i] ), &m_hMsgLogFonts[i] );
m_hMsgFonts[ i ] = CreateFontIndirect( &m_hMsgLogFonts[i] );
}
m_hMsgColors[ CChatOptionsDlg::FONT_MSGOUT ] = RGB( 0, 0, 0 );
m_hMsgColors[ CChatOptionsDlg::FONT_MSGIN ] = RGB( 0, 0, 0 );
m_hMsgColors[ CChatOptionsDlg::FONT_PRIVATEOUT ] = RGB( 100, 100, 100 );
m_hMsgColors[ CChatOptionsDlg::FONT_PRIVATEIN ] = RGB( 100, 100, 100 );
m_hMsgColors[ CChatOptionsDlg::FONT_MSGSYSTEM ] = RGB( 255, 0, 0 );
}
void CNmChatCtl::_DeleteFonts()
{
for( int i = 0; i < CChatOptionsDlg::FONT_COUNT; i++ )
{
DeleteObject( m_hMsgFonts[i] );
}
}
LRESULT CNmChatCtl::OnInitMenuPopup(WPARAM wParam, LPARAM lParam)
{
DBGENTRY(CNmChatCtl::OnInitMenuPopup);
if( FALSE == (BOOL)HIWORD(lParam ) )
{
switch( LOWORD( lParam ) )
{
case MENUPOS_FILE:
{
if( CChatMessage::get_count() )
{
EnableMenuItem( m_hMenuShared, ID_FILE_SAVE,
( m_lpszSaveFile && *m_lpszSaveFile ) ? MF_ENABLED : MF_GRAYED );
EnableMenuItem( m_hMenuShared, ID_FILE_SAVEAS, MF_ENABLED );
EnableMenuItem( m_hMenuShared, ID_FILE_PRINT,
!_IsPrinting() ? MF_ENABLED : MF_GRAYED );
}
else
{
EnableMenuItem( m_hMenuShared, ID_FILE_SAVE, MF_GRAYED );
EnableMenuItem( m_hMenuShared, ID_FILE_SAVEAS, MF_GRAYED );
EnableMenuItem( m_hMenuShared, ID_FILE_PRINT, MF_GRAYED );
}
return 0;
}
case MENUPOS_EDIT:
{
EnableMenuItem( m_hMenuShared, ID_EDIT_CLEARALL,
CChatMessage::get_count() && !_IsPrinting() ? MF_ENABLED : MF_GRAYED );
int iEnable = 0;
HWND hwnd = ::GetFocus();
if(hwnd == m_hWndEdit)
{
iEnable = (int)::SendMessage( hwnd, EM_GETSEL, 0, 0 );
iEnable = (HIWORD(iEnable) == LOWORD(iEnable)) ? MF_GRAYED : MF_ENABLED;
}
else if(hwnd == m_hWndMsg)
{
CHARRANGE range;
::SendMessage( hwnd, EM_EXGETSEL, 0, (LPARAM) &range );
iEnable = (range.cpMin == range.cpMax) ? MF_GRAYED : MF_ENABLED;
}
EnableMenuItem( m_hMenuShared, ID_EDIT_CUT,hwnd == m_hWndEdit ? iEnable : MF_GRAYED);
EnableMenuItem( m_hMenuShared, ID_EDIT_PASTE,
(IsClipboardFormatAvailable( CF_TEXT ) && (hwnd == m_hWndEdit)) ? MF_ENABLED : MF_GRAYED );
EnableMenuItem( m_hMenuShared, ID_EDIT_COPY, iEnable );
return 0;
}
case MENUPOS_VIEW:
{
_SetMenuItemCheck( ID_VIEW_STATUSBAR, _IsStatusBarVisibleFlagSet() );
_SetMenuItemCheck( ID_VIEW_EDITWINDOW, _IsEditWindowVisibleFlagSet() );
EnableMenuItem( m_hMenuShared, ID_VIEW_OPTIONS, _IsPrinting() ? MF_GRAYED : MF_ENABLED );
return 0;
break;
}
default:
return 0;
}
}
return 0;
}
LRESULT CNmChatCtl::OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DBGENTRY(CNmChatCtl::OnMenuSelect);
UINT fuFlags = HIWORD( wParam );
// If fuFlags == 0xffff and NULL == lParam, the menu is closed
if( !( ( 0xFFFF == fuFlags ) && ( NULL == lParam ) ) )
{
UINT uStringID = 0;
if( ( HIWORD( wParam ) & MF_HILITE ) )
{
if(( HIWORD( wParam ) & MF_SYSMENU))
{
uStringID = LOWORD( wParam );
if(!uStringID)
{
uStringID = IDS_SYSTEM_HELP;
}
}
else
{
switch( LOWORD( wParam ) )
{
case 0: // FILE top-level item
uStringID = IDS_HELPTEXT_CHAT_FILE;
break;
case 1: // EDIT top-level item
uStringID = IDS_HELPTEXT_CHAT_EDIT;
break;
case 2: // VIEW top-level item
uStringID = IDS_HELPTEXT_CHAT_VIEW;
break;
case 3: // OPTIONS top-level item
uStringID = IDS_HELPTEXT_CHAT_HELP;
break;
case ID_SEND_MESSAGE:
uStringID = IDS_HELPTEXT_CHAT_FILE_SEND_MESSAGE;
break;
case ID_FILE_SAVE:
uStringID = IDS_HELPTEXT_CHAT_FILE_SAVE;
break;
case ID_FILE_SAVEAS:
uStringID = IDS_HELPTEXT_CHAT_FILE_SAVEAS;
break;
case ID_FILE_PRINT:
uStringID = IDS_HELPTEXT_CHAT_FILE_PRINT;
break;
case ID_FILE_EXIT:
uStringID = IDS_HELPTEXT_CHAT_FILE_EXIT;
break;
case ID_VIEW_EDITWINDOW:
uStringID = IDS_HELPTEXT_CHAT_VIEW_EDITWINDOW;
break;
case ID_VIEW_STATUSBAR:
uStringID = IDS_VIEW_STATUSBAR_HELP;
break;
case ID_VIEW_OPTIONS:
uStringID = IDS_HELPTEXT_CHAT_VIEW_OPTIONS;
break;
case ID_EDIT_CUT:
uStringID = IDS_HELPTEXT_EDIT_CUT ;
break;
case ID_EDIT_COPY:
uStringID = IDS_HELPTEXT_EDIT_COPY;
break;
case ID_EDIT_PASTE:
uStringID = IDS_HELPTEXT_EDIT_PASTE;
break;
case ID_EDIT_CLEARALL:
uStringID = IDS_HELPTEXT_EDIT_CLEARALL;
break;
case ID_HELP_ABOUTCHAT:
uStringID = IDS_HELPTEXT_HELP_ABOUTCHAT;
break;
case ID_HELP_HELPTOPICS:
uStringID = IDS_HELPTEXT_HELP_HELPTOPICS;
break;
}
}
_SetContainerStatusText(uStringID);
}
}
DBGEXIT(CNmChatCtl::OnMenuSelect);
return 0;
}
void CNmChatCtl::OnSendClicked(void)
{
DBGENTRY(CNmChatCtl::OnSendClicked);
_SendChatText();
::SetFocus( m_hWndEdit );
DBGEXIT(CNmChatCtl::OnCreate);
}
LRESULT CNmChatCtl::OnNotifyEnLink(ENLINK *pEnLink)
{
DBGENTRY(CNmChatCtl::OnMsgWndNotify);
switch( pEnLink->msg )
{
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
{
return 1;
break;
}
case WM_LBUTTONDOWN:
{
TEXTRANGE Range;
ZeroMemory( &Range, sizeof( TEXTRANGE ) );
DBG_SAVE_FILE_LINE
Range.lpstrText = new TCHAR[ pEnLink->chrg.cpMax - pEnLink->chrg.cpMin + 1];
ASSERT( Range.lpstrText );
Range.chrg = pEnLink->chrg;
::SendMessage( m_hWndMsg, EM_GETTEXTRANGE, 0L, (LPARAM)&Range );
ShellExecute( m_hWndMsg, NULL, Range.lpstrText, NULL, NULL, SW_SHOWNORMAL );
delete [] Range.lpstrText;
return 1;
break;
}
default:
{
break;
}
}
DBGEXIT(CNmChatCtl::OnMsgWndNotify);
return 0;
}
//////////////////////////////////////////////////////////////////////////
void CNmChatCtl::cmdFileSave(void)
{
DBGENTRY(CNmChatCtl::cmdFileSave);
if( ( NULL == m_lpszSaveFile ) || ( _T('\0') == *m_lpszSaveFile ) )
{
_SaveAs();
}
else
{
_Save();
}
DBGEXIT(CNmChatCtl::cmdFileSave);
}
void CNmChatCtl::cmdFileSaveAs(void)
{
DBGENTRY(CNmChatCtl::cmdFileSaveAs);
_SaveAs();
DBGEXIT(CNmChatCtl::cmdFileSaveAs);
}
void CNmChatCtl::cmdFilePrint(void)
{
DBGENTRY(CNmChatCtl::cmdFilePrint);
m_dwChatFlags |= CHAT_PRINT_FLAG_PRINTING;
_Print();
m_dwChatFlags &= ~CHAT_PRINT_FLAG_PRINTING;
DBGEXIT(CNmChatCtl::cmdFilePrint);
}
void CNmChatCtl::cmdFileExit(WPARAM wParam)
{
DBGENTRY(CNmChatCtl::cmdFileExit);
int iOnSave = IDOK;
if(wParam == 0)
{
// Check whether there are changes to be saved
iOnSave = QueryEndSession();
}
// If the exit was not cancelled, close the application
if (iOnSave != IDCANCEL)
{
// no more T.120
g_pChatObj->LeaveT120();
// Close chat
::T120_AppletStatus(APPLET_ID_CHAT, APPLET_CLOSING);
::DestroyWindow(m_hWnd);
::UnregisterClass(szMainClassName, g_hInstance);
m_hWnd = NULL;
PostQuitMessage(0);
}
DBGEXIT(CNmChatCtl::cmdFileExit);
}
void CNmChatCtl::cmdViewStatusBar(void)
{
DBGENTRY(CNmChatCtl::cmdViewStatusBar);
RECT rect;
GetClientRect(m_hWnd, &rect );
::ShowWindow(m_hwndSB, _IsStatusBarVisibleFlagSet() ? SW_HIDE : SW_SHOW);
_Resize( 0, 0, rect.right, rect.bottom );
RedrawWindow(m_hWnd, NULL, NULL, RDW_UPDATENOW | RDW_INVALIDATE);
DBGEXIT(CNmChatCtl::cmdViewStatusBar);
}
//////////////////////////////////////////////////////////////////////////
void CNmChatCtl::cmdViewEditWindow(void)
{
DBGENTRY(CNmChatCtl::cmdViewEditWindow);
int iShowCommand = _IsEditWindowVisibleFlagSet() ? SW_HIDE : SW_SHOW;
::ShowWindow( m_hWndEdit, iShowCommand );
::ShowWindow( m_hWndSend, iShowCommand );
::ShowWindow( m_hWndStaticMessage, iShowCommand );
::ShowWindow( m_hWndStaticSendTo, iShowCommand );
::ShowWindow( m_hWndMemberList, iShowCommand );
_CalculateFontMetrics();
RECT rect;
GetClientRect(m_hWnd, &rect );
_Resize( 0, 0, rect.right, rect.bottom );
RedrawWindow(m_hWnd, NULL, NULL, RDW_UPDATENOW | RDW_INVALIDATE);
DBGEXIT(CNmChatCtl::cmdViewEditWindow);
}
void CNmChatCtl::cmdEditCut(void)
{
DBGENTRY(CNmChatCtl::cmdEditCut);
::SendMessage(m_hWndEdit, WM_CUT, 0, 0);
DBGEXIT(CNmChatCtl::cmdEditCut);
}
void CNmChatCtl::cmdEditCopy(void)
{
DBGENTRY(CNmChatCtl::cmdEditCopy);
HWND hwnd = ::GetFocus();
if(hwnd == 0)
{
hwnd = m_hWndEdit;
}
::SendMessage(hwnd, WM_COPY, 0, 0);
DBGEXIT(CNmChatCtl::cmdEditCopy);
}
void CNmChatCtl::cmdEditPaste(void)
{
DBGENTRY(CNmChatCtl::cmdEditPaste);
::SendMessage(m_hWndEdit, WM_PASTE, 0, 0);
DBGEXIT(CNmChatCtl::cmdEditPaste);
}
void CNmChatCtl::cmdEditClearAll(void)
{
DBGENTRY(CNmChatCtl::cmdEditClearAll);
if( !_IsPrinting() )
{
ResetView();
}
DBGEXIT(CNmChatCtl::cmdEditClearAll);
}
void CNmChatCtl::cmdViewOptions(void)
{
DBGENTRY(CNmChatCtl::cmdViewOptions);
if(m_pChatOptions == NULL)
{
DBG_SAVE_FILE_LINE
m_pChatOptions = new CChatOptionsDlg( this );
}
::DialogBox (g_hInstance,
MAKEINTRESOURCE(IDD_CHAT_OPTIONS),
m_hWnd,
CChatOptionsDlg::_OptionsDlgProc);
delete m_pChatOptions;
m_pChatOptions = NULL;
DBGEXIT(CNmChatCtl::cmdViewOptions);
}
void CNmChatCtl::cmdHelpHelpTopics(void)
{
DBGENTRY(CNmChatCtl::cmdHelpHelpTopics);
ShowNmHelp(s_cszHtmlHelpFile);
DBGEXIT(CNmChatCtl::cmdHelpHelpTopics);
}
void CNmChatCtl::cmdHelpAboutChat()
{
DBGENTRY(CNmChatCtl::cmdHelpAboutChat);
::DialogBox( g_hInstance,
MAKEINTRESOURCE( IDD_CHAT_ABOUT ),
m_hWnd,
_AboutDlgProc );
DBGEXIT(CNmChatCtl::cmdHelpAboutChat);
}
int CNmChatCtl::QueryEndSession()
{
DBGENTRY(CNmChatCtl::QueryEndSession);
//
// We may be shuting down, last good chance to save the position
//
_SaveWindowPosition();
_SaveChatOptions();
int iRet;
{
if( m_dwChatFlags & CHAT_FLAG_DIRTYBIT )
{
TCHAR szRes[MAX_PATH];
TCHAR szRes2[MAX_PATH];
iRet = ::MessageBox( m_hWnd,
RES2T(IDS_SAVE_CHANGES_TO_CHAT_BEFORE_EXITING,szRes),
RES2T(IDS_NETMEETING_CHAT,szRes2),
MB_YESNOCANCEL | MB_ICONEXCLAMATION
);
if( IDCANCEL == iRet )
{
return iRet;
}
else if( IDYES == iRet )
{
if( m_lpszSaveFile && *m_lpszSaveFile )
{
// if we already have a save file name
// we just save it....
_Save();
}
else
{
iRet = _SaveAs();
}
}
}
}
DBGEXIT(CNmChatCtl::QueryEndSession);
return iRet;
}
STDMETHODIMP CNmChatCtl::OnMenuSelect( IN DWORD wParam, IN DWORD lParam )
{
DBGENTRY(CNmChatCtl::OnMenuSelect);
HRESULT hr = S_OK;
UINT fuFlags = HIWORD( wParam );
if( !( ( 0xFFFF == fuFlags ) && ( NULL == lParam ) ) )
{
switch( LOWORD( wParam ) )
{
case ID_SEND_MESSAGE:
case ID_FILE_SAVE:
case ID_FILE_SAVEAS:
case ID_FILE_PRINT:
case ID_FILE_EXIT:
case MENUPOS_FILE:
OnInitMenuPopup( 0, MAKELPARAM( MENUPOS_FILE, 0 ));
break;
case ID_VIEW_STATUSBAR:
case ID_VIEW_EDITWINDOW:
case ID_VIEW_OPTIONS:
case MENUPOS_VIEW:
OnInitMenuPopup( 0, MAKELPARAM( MENUPOS_VIEW, 0 ));
break;
case ID_EDIT_CUT:
case ID_EDIT_COPY:
case ID_EDIT_PASTE:
case ID_EDIT_CLEARALL:
case MENUPOS_EDIT:
OnInitMenuPopup( 0, MAKELPARAM( MENUPOS_EDIT, 0 ));
break;
case ID_HELP_HELPTOPICS:
case ID_HELP_ABOUTCHAT:
default:
break;
}
OnMenuSelect(WM_MENUSELECT, wParam, lParam);
}
DBGEXIT_HR(CNmChatCtl::OnMenuSelect,hr);
return hr;
}
LRESULT CNmChatCtl::OnContextMenu(short x, short y)
{
// pop it up
OnInitMenuPopup(0, MENUPOS_EDIT);
::TrackPopupMenu(::GetSubMenu(m_hMenuShared, MENUPOS_EDIT), TPM_RIGHTALIGN | TPM_RIGHTBUTTON,
x , y , 0, m_hWnd, NULL);
return 0;
}
STDMETHODIMP CNmChatCtl::OnCommand( IN WPARAM wParam, IN LPARAM lParam )
{
DBGENTRY(CNmChatCtl::OnCommand);
HRESULT hr = S_OK;
if(m_hWndSend == (HWND)lParam)
{
OnSendClicked();
return 0;
}
if((CBN_SETFOCUS == HIWORD(wParam) && m_hWndMemberList == (HWND)lParam) ||
(EN_SETFOCUS == HIWORD(wParam) && m_hWndEdit == (HWND)lParam))
{
//
// Deselect the text in the message window
//
CHARRANGE charRange;
charRange.cpMin = m_cchBufferSize + 1;
charRange.cpMax = m_cchBufferSize + 1;
::SendMessage( m_hWndMsg, EM_EXSETSEL, 0L, (LPARAM) &charRange );
}
switch( LOWORD( wParam ) )
{
case ID_SEND_MESSAGE: OnSendClicked(); break;
case ID_FILE_SAVE: cmdFileSave(); break;
case ID_FILE_SAVEAS: cmdFileSaveAs(); break;
case ID_FILE_PRINT: cmdFilePrint(); break;
case ID_FILE_EXIT: cmdFileExit(0); break;
case ID_VIEW_STATUSBAR: cmdViewStatusBar(); break;
case ID_EDIT_CUT: cmdEditCut(); break;
case ID_EDIT_COPY: cmdEditCopy(); break;
case ID_EDIT_PASTE: cmdEditPaste(); break;
case ID_EDIT_CLEARALL: cmdEditClearAll(); break;
case ID_VIEW_EDITWINDOW: cmdViewEditWindow(); break;
case ID_VIEW_OPTIONS: cmdViewOptions (); break;
case ID_HELP_HELPTOPICS: cmdHelpHelpTopics(); break;
case ID_HELP_ABOUTCHAT: cmdHelpAboutChat(); break;
}
DBGEXIT_HR(CNmChatCtl::OnCommand,hr);
return hr;
}
void CNmChatCtl::OnGetMinMaxInfo(LPMINMAXINFO lpmmi)
{
DBGENTRY(CNmChatCtl::OnGetMinMaxInfo);
SIZE csFrame;
csFrame.cx = ::GetSystemMetrics(SM_CXSIZEFRAME);
csFrame.cy = ::GetSystemMetrics(SM_CYSIZEFRAME);
lpmmi->ptMinTrackSize.y =
csFrame.cy +
GetSystemMetrics( SM_CYCAPTION ) +
GetSystemMetrics( SM_CYMENU ) +
DYP_CHAT_SEND * 2 + // At least 2 lines
m_iStaticY + // Message:
DYP_CHAT_SEND + // Edit box
m_iStaticY + // Send to:
ComboBoxEx_GetItemHeight(m_hWndMemberList, 0) + // ComboBox
STATUSBAR_HEIGHT +
csFrame.cy;
lpmmi->ptMinTrackSize.x =
csFrame.cx +
m_iStaticLen * 2 +
SPACING_DLU_X * m_iDLGUX +
DXP_CHAT_SEND +
csFrame.cx;
// Retrieves the size of the work area on the primary display monitor. The work
// area is the portion of the screen not obscured by the system taskbar or by
// application desktop toolbars
//
RECT rcWorkArea;
::SystemParametersInfo( SPI_GETWORKAREA, 0, (&rcWorkArea), NULL );
csFrame.cx = rcWorkArea.right - rcWorkArea.left;
csFrame.cy = rcWorkArea.bottom - rcWorkArea.top;
lpmmi->ptMaxPosition.x = 0;
lpmmi->ptMaxPosition.y = 0;
lpmmi->ptMaxSize.x = csFrame.cx;
lpmmi->ptMaxSize.y = csFrame.cy;
lpmmi->ptMaxTrackSize.x = csFrame.cx;
lpmmi->ptMaxTrackSize.y = csFrame.cy;
DBGEXIT(CNmChatCtl::OnGetMinMaxInfo);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// CNmChatCtl INmChatCtl implementation
///////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CNmChatCtl::ResetView()
{
DBGENTRY(CNmChatCtl::ResetView());
HRESULT hr;
if( _IsPrinting() )
{
hr = E_FAIL;
}
else
{
::SetWindowText( m_hWndMsg, TEXT(""));
m_cchBufferSize = 0;
m_cMessages = 0;
CChatMessage::DeleteAll();
m_dwChatFlags &= ~CHAT_FLAG_DIRTYBIT;
hr = S_OK;
}
DBGEXIT_HR(CNmChatCtl::ResetView, hr);
return hr;
}
void CNmChatCtl::_ReDisplayMessages()
{
DBGENTRY(CNmChatCtl::_ReDisplayMessages());
SNDMSG( m_hWndMsg, WM_SETREDRAW, FALSE, 0 );
::SetWindowText( m_hWndMsg, TEXT(""));
CChatMessage *pMsg = CChatMessage::get_head();
while( pMsg != NULL )
{
_DisplayMsg( pMsg, FALSE );
pMsg = pMsg->get_next();
}
SNDMSG( m_hWndMsg, WM_SETREDRAW, TRUE, 0 );
::InvalidateRect( m_hWndMsg, NULL, INVALIDATE_BACKGROUND );
DBGEXIT(CNmChatCtl::_ReDisplayMessages);
}
CNmChatCtl::MSGSTYLE CNmChatCtl::get_MsgStyle()
{
return m_style;
}
STDMETHODIMP CNmChatCtl::put_MsgStyle( /*[in]*/ MSGSTYLE iStyle )
{
DBGENTRY(CNmChatCtl::put_MsgStyle);
HRESULT hr = S_OK;
DWORD dwStyle;
if( MSGSTYLE_2_LINE_WRAP == iStyle ||
MSGSTYLE_1_LINE_WRAP == iStyle )
{
dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | ES_READONLY | \
ES_SAVESEL | ES_NOHIDESEL | ES_AUTOVSCROLL | WS_VSCROLL;
}
else if( MSGSTYLE_NO_WRAP == iStyle )
{
dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | ES_READONLY | \
ES_SAVESEL | ES_NOHIDESEL | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL;
}
else
{
hr = E_FAIL;
DBGEXIT_HR(CNmChatCtl::put_MsgStyle, hr);
return hr;
}
HWND hwndKill = m_hWndMsg;
m_hWndMsg = ::CreateWindowEx( WS_EX_CLIENTEDGE,
m_lpszRichEd,
NULL,
dwStyle,
0,0,0,0,
m_hWnd,
NULL,
g_hInstance,
this );
ASSERT( m_hWndMsg );
::SendMessage( m_hWndMsg, WM_SETFONT, (WPARAM)m_hMsgFonts[ CChatOptionsDlg::FONT_MSGOUT ], 0L );
::SendMessage( m_hWndMsg, EM_AUTOURLDETECT, (WPARAM) TRUE, 0L );
::SendMessage( m_hWndMsg, EM_SETBKGNDCOLOR, (WPARAM) TRUE, 0L );
::SendMessage( m_hWndMsg, EM_SETEVENTMASK, 0L, (LPARAM) ENM_LINK );
::SendMessage( m_hWndMsg, WM_PAINT, 0, 0);
m_style = iStyle;
_CalculateFontMetrics();
RECT rect;
GetClientRect(m_hWnd, &rect );
_Resize( 0, 0, rect.right, rect.bottom );
::SendMessage( m_hWndMsg, EM_SETPARAFORMAT, 0, (LPARAM) &m_paraLine1 );
_ReDisplayMessages();
if( ::IsWindow( hwndKill ) )
{
::DestroyWindow( hwndKill );
}
DBGEXIT_HR(CNmChatCtl::put_MsgStyle, hr);
return hr;
}
STDMETHODIMP CNmChatCtl::put_ShowName(/*[in]*/ short bUseName )
{
DBGENTRY(CNmChatCtl::put_ShowName);
m_bUseName = bUseName;
DBGEXIT_HR(CNmChatCtl::put_ShowName, S_OK);
return S_OK;
}
STDMETHODIMP CNmChatCtl::get_ShowName(/*[out]*/ short *pbUseName )
{
DBGENTRY(CNmChatCtl::get_ShowName);
HRESULT hr = S_OK;
if( NULL == pbUseName )
{
hr = E_POINTER;
}
else
{
*pbUseName = m_bUseName;
}
DBGEXIT_HR(CNmChatCtl::get_ShowName, hr);
return hr;
}
STDMETHODIMP CNmChatCtl::put_Date(/*[in]*/ short bUseDate )
{
DBGENTRY(CNmChatCtl::put_Date);
m_bUseDate = bUseDate;
DBGEXIT_HR(CNmChatCtl::put_Date, S_OK);
return S_OK;
}
STDMETHODIMP CNmChatCtl::get_Date(/*[out]*/ short *pbUseDate )
{
DBGENTRY(CNmChatCtl::get_Date);
HRESULT hr = S_OK;
if( NULL == pbUseDate )
{
hr = E_POINTER;
}
else
{
*pbUseDate = m_bUseDate;
}
DBGEXIT_HR(CNmChatCtl::get_Date, hr);
return hr;
}
STDMETHODIMP CNmChatCtl::put_Timestamp(/*[in]*/ short bUseTimeStamp )
{
DBGENTRY(CNmChatCtl::put_Timestamp);
m_bTimeStamp = bUseTimeStamp;
DBGEXIT_HR(CNmChatCtl::put_Timestamp, S_OK);
return S_OK;
}
STDMETHODIMP CNmChatCtl::get_Timestamp(/*[out]*/ short *pbUseTimeStamp )
{
DBGENTRY(CNmChatCtl::get_Timestamp);
HRESULT hr = S_OK;
if( NULL == pbUseTimeStamp )
{
hr = E_POINTER;
}
else
{
*pbUseTimeStamp = m_bTimeStamp;
}
DBGEXIT_HR(CNmChatCtl::get_Timestamp, hr);
return hr;
}
void CNmChatCtl::_Resize(int x, int y, int cx, int cy)
{
DBGENTRY(CNmChatCtl::_Resize);
if( _IsEditWindowVisibleFlagSet() )
{
int iStatusBarHeight = _IsStatusBarVisibleFlagSet() ? STATUSBAR_HEIGHT : 0;
int iMsgListY = MSGLIST_DLU_Y * m_iDLGUY;
int iBetweenX = SPACING_DLU_X * m_iDLGUX;
int iStaticHeight = m_iStaticY + STATIC_DLU_Y * m_iDLGUY;
int iStaticStart = STATIC_DLU_Y * m_iDLGUY;
HDWP hdwp = ::BeginDeferWindowPos(7);
::DeferWindowPos(hdwp, m_hWndMsg, NULL,
0,
0,
cx,
cy-DYP_CHAT_SEND-iMsgListY-(iStaticHeight*2) - iStatusBarHeight,
SWP_NOZORDER);
::DeferWindowPos(hdwp, m_hWndStaticMessage, NULL,
0,
cy-DYP_CHAT_SEND-iMsgListY-iStaticHeight*2 + iStaticStart - iStatusBarHeight,
m_iStaticLen,
m_iStaticY,
SWP_NOZORDER);
::DeferWindowPos(hdwp, m_hWndEdit, NULL,
0,
cy-iMsgListY-iStaticHeight-DYP_CHAT_SEND - iStatusBarHeight,
cx - DXP_CHAT_SEND - iBetweenX,
DYP_CHAT_SEND,
SWP_NOZORDER);
::DeferWindowPos(hdwp, m_hWndSend, NULL,
cx-DXP_CHAT_SEND,
cy-iMsgListY-iStaticHeight-DYP_CHAT_SEND - iStatusBarHeight,
DXP_CHAT_SEND,
DYP_CHAT_SEND,
SWP_NOZORDER);
::DeferWindowPos(hdwp, m_hWndStaticSendTo, NULL,
0,
cy-iMsgListY-iStaticHeight + iStaticStart - iStatusBarHeight,
m_iStaticLen,
m_iStaticY,
SWP_NOZORDER);
::DeferWindowPos(hdwp, m_hWndMemberList, NULL,
0,
cy-iMsgListY - iStatusBarHeight,
cx,
ComboBoxEx_GetItemHeight(m_hWndMemberList, 0),
SWP_NOZORDER);
RECT rect;
::GetClientRect(m_hWnd, &rect);
rect.top = rect.bottom - iStatusBarHeight;
::DeferWindowPos(hdwp, m_hwndSB, NULL,
rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
SWP_NOZORDER);
::EndDeferWindowPos(hdwp);
}
else
{
int iStatusBarHeight = _IsStatusBarVisibleFlagSet() ? STATUSBAR_HEIGHT : 0;
::MoveWindow(m_hWndMsg,
0, 0, cx, cy - iStatusBarHeight,
TRUE);
}
DBGEXIT(CNmChatCtl::_Resize);
}
void CNmChatCtl::_LoadIconImages(void)
{
DBGENTRY(CNmChatCtl::_LoadIconImages);
COLORREF crTOOLBAR_MASK_COLOR = ( RGB( 255, 0, 255 ) );
if( NULL == m_himlIconSmall )
{
m_himlIconSmall = ImageList_Create(DXP_ICON_SMALL, DYP_ICON_SMALL, ILC_MASK, 1, 0);
if (NULL != m_himlIconSmall)
{
HBITMAP hBmp = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_CHAT_SMALL_ICON_IMAGES));
if (NULL != hBmp)
{
ImageList_AddMasked(m_himlIconSmall, hBmp, crTOOLBAR_MASK_COLOR);
::DeleteObject(hBmp);
}
}
}
DBGEXIT(CNmChatCtl::_LoadIconImages);
}
void CNmChatCtl::_FreeIconImages(void)
{
DBGENTRY(CNmChatCtl::_FreeIconImages);
if (NULL != m_himlIconSmall)
{
ImageList_Destroy(m_himlIconSmall);
m_himlIconSmall = NULL;
}
DBGEXIT(CNmChatCtl::_FreeIconImages);
}
HRESULT CNmChatCtl::_SendChatText(void)
{
DBGENTRY(CNmChatCtl::_SendChatText);
HRESULT hr = S_OK;
TCHAR szMsg[CCHMAX_CHAT_MSG];
// Get the text line
int cb = (int)::SendMessage(m_hWndEdit, WM_GETTEXT, (WPARAM) CCHMAX(szMsg), (LPARAM) szMsg);
if (0 != cb)
{
if (cb == 1)
{
szMsg[1] = ' ';
szMsg[2] = 0;
cb++;
}
// Delete the text in the edit box ( remember it is stored in szMsg )
::SendMessage(m_hWndEdit, EM_SETSEL, (WPARAM) 0, (LPARAM)-1);
::SendMessage(m_hWndEdit, WM_SETTEXT, (WPARAM) 0, (LPARAM) "");
::SetFocus(m_hWndEdit); // reset the focus if we actually sent something
MEMBER_CHANNEL_ID *pMemberID = (MEMBER_CHANNEL_ID*)_GetSelectedMember();
MEMBER_ID memberID;
TCHAR szName[MAX_PATH*2];
szName[0] = '\0';
CChatMessage::CHAT_MSGTYPE cmtype;
LPTSTR szPerson = NULL;
if( pMemberID == 0 )
{
cmtype = CChatMessage::MSG_SAY;
memberID = MAKE_MEMBER_ID(0, g_pChatObj->m_broadcastChannel);
}
else
{
// Use the whisper
memberID = MAKE_MEMBER_ID(pMemberID->nNodeId, pMemberID->nWhisperId);
cmtype = CChatMessage::MSG_WHISPER;
ULONG cb = T120_GetNodeName(g_pChatObj->m_nConfID, pMemberID->nNodeId, szName, MAX_PATH*2);
}
_DisplayMsg( new CChatMessage( szName, szMsg, cmtype ) );
if (g_pChatObj)
{
// Allocate a temporary buffer
BYTE * pb = new BYTE[CB_NM2_HDR + (CCHMAX_CHAT_MSG * sizeof(WCHAR))];
if (NULL != pb)
{
BYTE * pbData = pb+CB_NM2_HDR;
// Initialize the header
ZeroMemory(pb, CB_NM2_HDR);
* ((LPDWORD) pb) = CB_NM2_HDR;
cb++; // include final null
#ifdef UNICODE
lstrcpy(pbData, szMsg);
#else
cb = MultiByteToWideChar(CP_ACP, 0, szMsg, cb, (LPWSTR) pbData, CCHMAX_CHAT_MSG);
cb *= 2; // adjust for UNICODE
#endif //!UNICODE
// Add special prefix
cb += CB_NM2_HDR;
hr = g_pChatObj->SendData(GET_USER_ID_FROM_MEMBER_ID(memberID), cb, (BYTE*)pb);
delete pb;
}
else
{
ERROR_OUT(("Out of memory!!!"));
hr = E_OUTOFMEMORY;
}
}
}
else
{
// There was no chat text
}
DBGEXIT_HR(CNmChatCtl::_SendChatText, hr);
return hr;
}
void CNmChatCtl::_DataReceived(ULONG uSize, LPBYTE pb, T120ChannelID destinationID, T120UserID senderID)
{
DBGENTRY(CNmChatCtl::DataReceived);
ASSERT(uSize > CNmChatCtl::CB_NM2_HDR);
LPTSTR psz = (LPTSTR) (pb + *(LPDWORD) pb); // skip past header
#ifndef UNICODE
// Convert UNICODE to ANSI
char sz[CNmChatCtl::CCHMAX_CHAT_MSG];
WideCharToMultiByte(CP_ACP, 0, (LPWSTR) psz, -1, sz, CNmChatCtl::
CCHMAX_CHAT_MSG, NULL, NULL);
psz = sz;
#endif //
TCHAR szPerson[MAX_PATH*2] = "\0";
T120NodeID nodeID = ComboBoxEx_GetNodeIDFromSendID(m_hWndMemberList, senderID );
if (0 == nodeID)
{
nodeID = ComboBoxEx_GetNodeIDFromPrivateSendID(m_hWndMemberList, senderID);
}
ULONG cb = T120_GetNodeName(g_pChatObj->m_nConfID, nodeID, szPerson, MAX_PATH*2);
// Display the message to the chat window
_DisplayMsg(new CChatMessage( szPerson, psz,
( destinationID == GET_USER_ID_FROM_MEMBER_ID(g_pChatObj->m_MyMemberID)) ?
CChatMessage::MSG_WHISPER_FROM_OTHER : CChatMessage::MSG_FROM_OTHER ));
DBGEXIT_HR(CNmChannelEventSink::DataReceived, S_OK);
}
inline void CNmChatCtl::_Write_Msg( LPTSTR pszText )
{
ASSERT( NULL != pszText );
::SendMessage( m_hWndMsg, EM_REPLACESEL, (WPARAM) FALSE, (WPARAM) pszText );
m_cchBufferSize += lstrlen( pszText );
}
inline void CNmChatCtl::_Write_Msg_Range_Format( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat )
{
charRange.cpMin = m_cchBufferSize;
charRange.cpMax = m_cchBufferSize;
::SendMessage( m_hWndMsg, EM_EXSETSEL, 0L, (LPARAM) &charRange );
::SendMessage( m_hWndMsg, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM) &chatFormat );
_Write_Msg( pszText );
}
inline void CNmChatCtl::_Write_Date_And_Time( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat, CChatMessage *pChatMsg )
{
if( m_bUseDate )
{
wsprintf( pszText, TEXT("%s\t"), pChatMsg->get_date() );
_Write_Msg_Range_Format( pszText, charRange, chatFormat ) ;
}
if( m_bTimeStamp )
{
wsprintf( pszText, TEXT("%s\t"), pChatMsg->get_time() );
_Write_Msg_Range_Format( pszText, charRange, chatFormat ) ;
}
}
inline void CNmChatCtl::_Write_Name( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat, CChatMessage *pChatMsg )
{
if( m_bUseName )
{
wsprintf( pszText, TEXT("%s\t"), pChatMsg->get_person() );
_Write_Msg_Range_Format( pszText, charRange, chatFormat );
}
}
inline void CNmChatCtl::_Write_Own_Name( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat )
{
if( m_bUseName )
{
if(m_lpszOwnName == NULL)
{
RegEntry re(ISAPI_CLIENT_KEY, HKEY_CURRENT_USER);
LPCTSTR pcszName = re.GetString(REGVAL_ULS_NAME);
DBG_SAVE_FILE_LINE
m_lpszOwnName = new TCHAR[lstrlen(pcszName) + 1];
wsprintf( m_lpszOwnName, TEXT("%s"),pcszName);
}
wsprintf( pszText, TEXT("%s\t"), m_lpszOwnName );
_Write_Msg_Range_Format( pszText, charRange, chatFormat );
}
}
inline void CNmChatCtl::_Write_Message( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat, CChatMessage *pChatMsg )
{
_Write_Msg_Range_Format( pChatMsg->get_message(), charRange, chatFormat );
_Write_Msg_Range_Format( m_lpszRichEdEOL, charRange, chatFormat );
}
inline void CNmChatCtl::_Write_Private_In( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat, CChatMessage *pChatMsg )
{
wsprintf( pszText, TEXT("[%s]"), m_szPrivate );
_Write_Msg_Range_Format( pszText, charRange, chatFormat );
_Write_Message( pszText, charRange, chatFormat, pChatMsg );
}
inline void CNmChatCtl::_Write_Private_Out( LPTSTR pszText, CHARRANGE& charRange, CHARFORMAT& chatFormat, CChatMessage *pChatMsg )
{
wsprintf( pszText, TEXT("[%s %s %s] "), m_szPrivate, m_szTo, pChatMsg->get_person() );
_Write_Msg_Range_Format( pszText, charRange, chatFormat );
_Write_Message( pszText, charRange, chatFormat, pChatMsg );
}
inline void CNmChatCtl::_Write_New_Line_If_Needed( CHARRANGE& charRange, CHARFORMAT& chatFormat )
{
if( MSGSTYLE_2_LINE_WRAP == m_style )
{
_Write_Msg_Range_Format( m_lpszRichEdEOL, charRange, chatFormat );
::SendMessage( m_hWndMsg, EM_SETPARAFORMAT, 0, (LPARAM) &m_paraLine2 );
::SendMessage( m_hWndMsg, EM_GETPARAFORMAT, 0, (LPARAM) &m_paraLine2 );
}
}
inline void CNmChatCtl::_AddFontToCharFormat( CHARFORMAT& chatFormat, int i )
{
chatFormat.dwMask |= CFM_COLOR | CFM_ALLCAPS | CFM_CHARSET | CFM_BOLD | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_STRIKEOUT | CFM_UNDERLINE;
chatFormat.crTextColor = m_hMsgColors[ i ];
if( m_hMsgLogFonts[i].lfWeight >= FW_BOLD )
{
chatFormat.dwEffects |= CFE_BOLD;
}
if( m_hMsgLogFonts[i].lfItalic )
{
chatFormat.dwEffects |= CFE_ITALIC;
}
if( m_hMsgLogFonts[i].lfUnderline )
{
chatFormat.dwEffects |= CFE_UNDERLINE;
}
if( m_hMsgLogFonts[i].lfStrikeOut )
{
chatFormat.dwEffects |= CFE_STRIKEOUT;
}
chatFormat.yHeight = 20 * _Points_From_LogFontHeight( m_hMsgLogFonts[i].lfHeight, m_hWnd );
chatFormat.bCharSet = m_hMsgLogFonts[i].lfCharSet;
chatFormat.bPitchAndFamily = m_hMsgLogFonts[i].lfPitchAndFamily;
lstrcpy( chatFormat.szFaceName, m_hMsgLogFonts[i].lfFaceName );
}
void CNmChatCtl::_DisplayMsg( CChatMessage *pChatMsg, BOOL bBatchRedraw /*= TRUE*/ )
{
DBGENTRY(CNmChatCtl::_DisplayMsg);
if( pChatMsg != NULL && !pChatMsg->IsValid() )
{
ERROR_OUT(( TEXT("CNmChatCtl::_DisplayMsg passed invalid message") ));
return;
}
TCHAR pszText[CCHMAX_CHAT_MSG];
CHARRANGE charRange;
//
// Start at the end of the last message
//
charRange.cpMin = m_cchBufferSize + 1;
charRange.cpMax = m_cchBufferSize + 1;
::SendMessage( m_hWndMsg, EM_EXSETSEL, 0L, (LPARAM) &charRange );
CHARFORMAT chatFormat;
ZeroMemory( &chatFormat, sizeof( chatFormat ) );
chatFormat.cbSize = sizeof( chatFormat );
::SendMessage( m_hWndMsg, EM_SETPARAFORMAT, 0, (LPARAM) &m_paraLine1 );
::SendMessage( m_hWndMsg, EM_GETPARAFORMAT, 0, (LPARAM) &m_paraLine1 );
CChatMessage::CHAT_MSGTYPE msgType = pChatMsg->get_type();
switch( msgType )
{
case CChatMessage::MSG_WHISPER_FROM_OTHER:
case CChatMessage::MSG_FROM_OTHER:
case CChatMessage::MSG_WHISPER:
case CChatMessage::MSG_SAY:
{
if( bBatchRedraw )
{
SNDMSG( m_hWndMsg, WM_SETREDRAW, FALSE, 0 );
}
switch( msgType )
{
case CChatMessage::MSG_WHISPER_FROM_OTHER:
{
_AddFontToCharFormat( chatFormat, CChatOptionsDlg::FONT_PRIVATEIN );
break;
}
case CChatMessage::MSG_FROM_OTHER:
{
_AddFontToCharFormat( chatFormat, CChatOptionsDlg::FONT_MSGIN );
break;
}
case CChatMessage::MSG_WHISPER:
{
_AddFontToCharFormat( chatFormat, CChatOptionsDlg::FONT_PRIVATEOUT );
break;
}
case CChatMessage::MSG_SAY:
{
_AddFontToCharFormat( chatFormat, CChatOptionsDlg::FONT_MSGOUT );
break;
}
}
_Write_Date_And_Time( pszText, charRange, chatFormat, pChatMsg );
if( pChatMsg->IsIncoming() )
{
_Write_Name( pszText, charRange, chatFormat, pChatMsg );
}
else
{
_Write_Own_Name( pszText, charRange, chatFormat );
}
_Write_New_Line_If_Needed( charRange, chatFormat );
if( !pChatMsg->IsPrivate() )
{
_Write_Message( pszText, charRange, chatFormat, pChatMsg );
}
else if( pChatMsg->IsIncoming() )
{
_Write_Private_In( pszText, charRange, chatFormat, pChatMsg );
}
else
{
_Write_Private_Out( pszText, charRange, chatFormat, pChatMsg );
}
// Update message count
m_cMessages++;
m_dwChatFlags |= CHAT_FLAG_DIRTYBIT;
if( bBatchRedraw )
{
SNDMSG( m_hWndMsg, WM_SETREDRAW, TRUE, 0 );
::InvalidateRect( m_hWndMsg, NULL, INVALIDATE_BACKGROUND );
}
break;
}
case CChatMessage::MSG_SYSTEM:
{
_AddFontToCharFormat( chatFormat, CChatOptionsDlg::FONT_MSGSYSTEM );
_Write_Message( pszText, charRange, chatFormat, pChatMsg );
break;
}
default:
{
ERROR_OUT(( TEXT("CNmChatCtl::_DisplayMsg - Unknown Message Type") ));
return;
break;
}
}
DBGEXIT(CNmChatCtl::_DisplayMsg);
}
HRESULT CNmChatCtl::_AddEveryoneInChat()
{
DBGENTRY( CNmChatCtl::_AddEveryoneInChat );
ASSERT( m_hWndMemberList );
HRESULT hr = S_OK;
int iImage = II_PERSON_PERSON;
int iItem = 0;
TCHAR szName[MAX_PATH];
TCHAR szRes[MAX_PATH];
lstrcpy( szName, RES2T( IDS_FILTER_ALL, szRes ) );
COMBOBOXEXITEM cbexi;
ClearStruct( &cbexi );
cbexi.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE ;
cbexi.iItem = iItem;
cbexi.pszText = szName;
cbexi.cchTextMax = lstrlen(cbexi.pszText);
cbexi.iSelectedImage = iImage;
cbexi.iImage = iImage;
cbexi.lParam = (LPARAM) NULL;
ComboBoxEx_InsertItem(m_hWndMemberList, &cbexi);
ComboBoxEx_SetCurSel( m_hWndMemberList, 0 );
DBGEXIT_HR( CNmChatCtl::_AddEveryoneInChat, hr );
return hr;
}
HBITMAP CNmChatCtl::_GetHBITMAP( DWORD dwID )
{
DBGENTRY(CNmChatCtl::_GetHBITMAP);
HBITMAP hb = static_cast<HBITMAP>( LoadImage(g_hInstance, MAKEINTRESOURCE(dwID), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE));
DBGEXIT(CNmChatCtl::_GetHBITMAP);
return hb;
}
// Delete item iIndex from the m_hWndMemberList list view and free the
// pMember that is stored in the lParam of that item...
HRESULT CNmChatCtl::_DeleteMemberListItem( int iIndex )
{
DBGENTRY(CNmChatCtl::_DeleteMemberListItem);
HRESULT hr = S_OK;
TCHAR szName[MAX_PATH];
COMBOBOXEXITEM cbexi;
ClearStruct( &cbexi );
cbexi.iItem = iIndex;
cbexi.mask = CBEIF_LPARAM | CBEIF_TEXT;
cbexi.pszText = szName;
cbexi.cchTextMax = CCHMAX(szName);
// Find the item iIndex and get the Text and lParam data
if( ComboBoxEx_GetItem( m_hWndMemberList, &cbexi ) )
{
if( CB_ERR == ComboBoxEx_DeleteItem(m_hWndMemberList, iIndex) )
{
WARNING_OUT(( "Could not delete %s from ComboBox", cbexi.pszText ));
}
}
else
{
// There was an error...
WARNING_OUT(("There was an error getting the list view item..."));
DWORD dwErr = GetLastError();
hr = HRESULT_FROM_WIN32( dwErr );
}
DBGEXIT_HR(CNmChatCtl::_DeleteMemberListItem, hr);
return hr;
}
void CNmChatCtl::_DeleteAllListItems( void )
{
DBGENTRY(CNmChatCtl::_DeleteAllListItems);
int cItems = ComboBoxEx_GetCount( m_hWndMemberList );
while( cItems-- )
{ // Delete the first item in the list...
int IndexOfFirstItemInList = 0;
_DeleteMemberListItem( IndexOfFirstItemInList );
}
ComboBoxEx_SetCurSel( m_hWndMemberList, 0 );
DBGEXIT(CNmChatCtl::_DeleteAllListItems);
}
HRESULT CNmChatCtl::_GetOwnName()
{
DBGENTRY( CNmChatCtl::_GetOwnName );
HRESULT hr = E_FAIL;
DBGEXIT_HR( CNmChatCtl::_GetOwnName, hr );
return( hr );
}
void CNmChatCtl::_UpdateContainerCaption( void )
{
DBGENTRY(CNmChatCtl::_UpdateContainerCaption);
TCHAR szCaption[MAX_PATH * 2];
TCHAR szCaption2[MAX_PATH * 2];
UINT captionID;
UINT statusID;
if (! g_pChatObj->IsInConference())
{
captionID = IDS_CHAT_NOT_IN_CALL_WINDOW_CAPTION;
statusID = IDS_CHAT_STATUS_CHAT_NOT_ACTIVE;
}
else
{
captionID = IDS_CHAT_IN_CALL_WINDOW_CAPTION;
statusID = IDS_CHAT_STATUS_CHAT_ACTIVE;
}
::LoadString(g_hInstance, captionID, szCaption, sizeof(szCaption) );
wsprintf(szCaption2, szCaption, m_cOtherMembers);
::SetWindowText(m_hWnd, szCaption2);
_SetContainerStatusText( statusID );
DBGEXIT(CNmChatCtl::_UpdateContainerCaption);
}
void CNmChatCtl::_CalculateFontMetrics()
{
DBGENTRY(CNmChatCtl::_CalculateFontMetrics);
ASSERT( m_hWndMsg );
///// Get Info for RichEdit Box
CHARFORMAT chfmt2;
int yMaxHeightInTwips = 0;
for( int i = 0; i < CChatOptionsDlg::FONT_COUNT; i++ )
{
ZeroMemory( &chfmt2, sizeof( chfmt2 ) );
_AddFontToCharFormat( chfmt2, i );
if( yMaxHeightInTwips < chfmt2.yHeight )
{
yMaxHeightInTwips = chfmt2.yHeight;
}
}
TEXTMETRIC textmex;
HDC hdc = ::GetDC( m_hWndMsg );
::GetTextMetrics( hdc, &textmex );
::ReleaseDC( m_hWndMsg, hdc );
/*
* Average Width of Char in Twips Average Width of Chars Logical Unit
* ------------------------------ = -----------------------------------
* Height of Char in Twips Height of Char in Logical Unit
*
*/
int iAveWidthInTwips = yMaxHeightInTwips * textmex.tmAveCharWidth / textmex.tmHeight;
int iMaxWidthInTwips = yMaxHeightInTwips * textmex.tmMaxCharWidth / textmex.tmHeight;
// Set the tabs on the two paragraph format rich edit things
ZeroMemory( &m_paraLine1, sizeof( m_paraLine1 ) );
m_paraLine1.cbSize = sizeof( m_paraLine1 );
m_paraLine1.dwMask = PFM_OFFSET | PFM_TABSTOPS | PFM_STARTINDENT | PFM_RIGHTINDENT ;
ZeroMemory( &m_paraLine2, sizeof( m_paraLine2 ) );
m_paraLine2.cbSize = sizeof( m_paraLine2 );
m_paraLine2.dwMask = PFM_OFFSET | PFM_TABSTOPS | PFM_STARTINDENT | PFM_RIGHTINDENT ;
m_paraLine2.dxStartIndent = MULTILINE_MSG_OFFSET * iAveWidthInTwips;
int iDelta = 0;
if( m_bUseDate )
{
iDelta = DATE_EXTRA + GetDateFormat(
LOCALE_USER_DEFAULT, // locale for which date is to be formatted
0, // flags specifying function options
NULL, // time to be formatted
NULL, // time format string
NULL, // buffer for storing formatted string
0 // size, in bytes or characters, of the buffer
);
iDelta *= iAveWidthInTwips;
if( m_paraLine1.cTabCount )
{
m_paraLine1.rgxTabs[ m_paraLine1.cTabCount ] = m_paraLine1.rgxTabs[ m_paraLine1.cTabCount -1 ] + iDelta;
}
else
{
m_paraLine1.rgxTabs[ 0 ] = iDelta;
}
m_paraLine1.cTabCount++;
}
if( m_bTimeStamp )
{
iDelta = TIME_EXTRA + GetTimeFormat(
LOCALE_USER_DEFAULT, // locale for which date is to be formatted
0, // flags specifying function options
NULL, // time to be formatted
NULL, // time format string
NULL, // buffer for storing formatted string
0 // size, in bytes or characters, of the buffer
);
iDelta *= iAveWidthInTwips;
if( m_paraLine1.cTabCount )
{
m_paraLine1.rgxTabs[ m_paraLine1.cTabCount ] = m_paraLine1.rgxTabs[ m_paraLine1.cTabCount -1 ] + iDelta;
}
else
{
m_paraLine1.rgxTabs[ 0 ] = iDelta;
}
m_paraLine1.cTabCount++;
}
if( m_bUseName )
{
iDelta = (MAX_NAME + NAME_EXTRA) * iAveWidthInTwips;
if( m_paraLine1.cTabCount )
{
m_paraLine1.rgxTabs[ m_paraLine1.cTabCount ] = m_paraLine1.rgxTabs[ m_paraLine1.cTabCount -1 ] + iDelta;
}
else
{
m_paraLine1.rgxTabs[ 0 ] = iDelta;
}
m_paraLine1.cTabCount++;
}
if( m_paraLine1.cTabCount )
{
m_paraLine1.dxOffset = m_paraLine1.rgxTabs[ m_paraLine1.cTabCount -1 ];
}
DBGEXIT(CNmChatCtl::_CalculateFontMetrics );
}
void CNmChatCtl::_SetContainerStatusText( UINT uID )
{
DBGENTRY(CNmChatCtl::_SetContainerStatusText);
TCHAR szStatus[MAX_RESOURCE_STRING_LEN] = "";
NmCtlLoadString( uID, szStatus, CchMax(szStatus) );
::SetWindowText(m_hwndSB, szStatus);
DBGEXIT(CNmChatCtl::_SetContainerStatusText);
}
// Get the selected member from the m_hWndMemberList list view...
MEMBER_ID CNmChatCtl::_GetSelectedMember()
{
DBGENTRY(CNmChatCtl::_GetSelectedMember);
COMBOBOXEXITEM cbexi;
ClearStruct( &cbexi );
cbexi.mask = CBEIF_LPARAM;
// Find the matching item
if( CB_ERR == ( cbexi.iItem = ComboBoxEx_GetCurSel(m_hWndMemberList ) ) )
{
ATLTRACE(("CNmChatCtl::_GetSelectedMember - no selection?\n"));
DBGEXIT(CNmChatCtl::_GetSelectedMember);
return 0;
}
ComboBoxEx_GetItem( m_hWndMemberList, &cbexi );
MEMBER_ID memberID = (MEMBER_ID)( cbexi.lParam );
DBGEXIT(CNmChatCtl::_GetSelectedMember);
return memberID;
}
HRESULT CNmChatCtl::_AddMember(MEMBER_CHANNEL_ID *pMemberID)
{
DBGENTRY(CNmChatCtl::_AddMember);
HRESULT hr = S_OK;
int iImage;
int iItem = -1;
TCHAR szName[MAX_PATH];
if (GET_NODE_ID_FROM_MEMBER_ID(g_pChatObj->m_MyMemberID) != pMemberID->nNodeId)
{
TCHAR szName[MAX_PATH*2];
ULONG cb = T120_GetNodeName(g_pChatObj->m_nConfID, pMemberID->nNodeId, szName, MAX_PATH*2);
iImage = II_USER;
COMBOBOXEXITEM cbexi;
ClearStruct( &cbexi );
cbexi.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE ;
cbexi.iItem = iItem;
cbexi.pszText = szName;
cbexi.cchTextMax = lstrlen(cbexi.pszText);
cbexi.iSelectedImage = iImage;
cbexi.iImage = iImage;
cbexi.lParam = (LPARAM) pMemberID;
ComboBoxEx_InsertItem(m_hWndMemberList, &cbexi);
}
DBGEXIT_HR(CNmChatCtl::_AddMember, hr);
return hr;
}
HRESULT CNmChatCtl::_RemoveMember(MEMBER_CHANNEL_ID *pMemberID)
{
DBGENTRY(CNmChatCtl::_RemoveMember);
HRESULT hr = S_OK;
int iItem = ComboBoxEx_FindMember( m_hWndMemberList, -1, pMemberID);
if( -1 != iItem )
{
_DeleteMemberListItem( iItem );
}
else
{
WARNING_OUT(("Could not find the specified item..."));
hr = HRESULT_FROM_WIN32(GetLastError());
}
DBGEXIT_HR(CNmChatCtl::_RemoveMember, hr);
return hr;
}
HRESULT CNmChatCtl::_SetMenuItemCheck( UINT idItem, BOOL bChecked /* = true */ )
{
DBGENTRY(CNmChatCtl::_SetMenuItemCheck);
HRESULT hr = S_OK;
if( m_hMenuShared )
{
MENUITEMINFO mii;
ClearStruct(&mii);
mii.cbSize = sizeof( MENUITEMINFO );
mii.fMask = MIIM_STATE;
mii.fState = bChecked ? MFS_CHECKED : MFS_UNCHECKED;
if( !SetMenuItemInfo(m_hMenuShared, idItem, FALSE, &mii) )
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = E_UNEXPECTED;
}
DBGEXIT_HR(CNmChatCtl::_SetMenuItemCheck,hr);
return hr;
}
bool CNmChatCtl::_IsEditWindowVisibleFlagSet(void)
{
return ( ::IsWindow( m_hWndEdit ) && IsWindowVisible(m_hWndEdit));
}
bool CNmChatCtl::_IsStatusBarVisibleFlagSet(void)
{
return ( ::IsWindow( m_hwndSB ) && IsWindowVisible(m_hwndSB));
}
int CNmChatCtl::_SaveAs()
{
int iRet = 0;
if( NULL == m_lpszSaveFile )
{
DBG_SAVE_FILE_LINE
m_lpszSaveFile = new TCHAR[ MAX_PATH ];
ASSERT( m_lpszSaveFile );
ZeroMemory( m_lpszSaveFile, sizeof( m_lpszSaveFile ) );
}
if( SUCCEEDED( SaveDialog( m_lpszSaveFile, OFN_HIDEREADONLY | OFN_CREATEPROMPT, &m_wFileOffset ) ) )
{
// Since the file name has changed, we are dirty....
m_dwChatFlags |= CHAT_FLAG_DIRTYBIT;
_Save();
}
else
{
iRet = IDCANCEL;
}
return iRet;
}
LRESULT CNmChatCtl::SaveDialog(LPTSTR lpszFile, DWORD dwFlags, LPWORD pnFileOffset )
{
DBGENTRY(CNmChatCtl::SaveDialog)
HRESULT hr = S_OK;
TCHAR szFilter[MAX_PATH];
TCHAR szDefExt[MAX_PATH];
if( SUCCEEDED ( hr = _GetNmAppletFileOpenFilter( szFilter, CCHMAX( szFilter ), szDefExt, CCHMAX( szDefExt ) ) ) )
{
ConvertSzCh(szFilter);
OPENFILENAME ofn;
ClearStruct( &ofn );
ofn.lStructSize = sizeof( OPENFILENAME );
ofn.hwndOwner = m_hWnd;
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = lpszFile;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = szDefExt;
ofn.Flags = dwFlags;
if( !GetSaveFileName( &ofn ) )
{
hr = E_FAIL;
}
else
{
*pnFileOffset = ofn.nFileOffset;
}
}
DBGEXIT_HR(CNmChatCtl::SaveDialog,hr)
return hr;
}
void CNmChatCtl::_SaveWindowPosition()
{
RECT rectWindow;
// If we are not maximized
if (!::IsZoomed(m_hWnd) && !::IsIconic(m_hWnd))
{
// Get the new window rectangle
::GetWindowRect(m_hWnd, &rectWindow);
// Write the new option values to file
_SetWindowRectOption(&rectWindow);
}
}
void CNmChatCtl::_SaveChatOptions()
{
RegEntry reWnd( CHAT_KEY, HKEY_CURRENT_USER );
reWnd.SetValue(OPT_MAIN_INFORMATION_DISPLAY_NAME, m_bUseName);
reWnd.SetValue(OPT_MAIN_INFORMATION_DISPLAY_TIME, m_bTimeStamp);
reWnd.SetValue(OPT_MAIN_INFORMATION_DISPLAY_DATE, m_bUseDate);
reWnd.SetValue(OPT_MAIN_MESSAGE_FORMAT, m_style);
for (int i = 0; i < CChatOptionsDlg::FONT_COUNT; i++ )
{
reWnd.SetValue( OPT_FONT_COLOR[i], &m_hMsgColors[i], sizeof(COLORREF));
reWnd.SetValue( OPT_FONT_FORMAT[i], &m_hMsgLogFonts[i], sizeof(LOGFONT));
}
}
BOOL CNmChatCtl::_LoadChatOptions()
{
BOOL fRet = FALSE;
int i;
RegEntry reWnd(CHAT_KEY, HKEY_CURRENT_USER);
LPVOID pData;
for (i = 0; i < CChatOptionsDlg::FONT_COUNT; i++ )
{
if (reWnd.GetBinary(OPT_FONT_COLOR[i], &pData) != sizeof(COLORREF))
break;
::CopyMemory(&m_hMsgColors[i], pData, sizeof(COLORREF));
if (reWnd.GetBinary(OPT_FONT_FORMAT[i], &pData) != sizeof(LOGFONT))
break;
::CopyMemory(&m_hMsgLogFonts[i], pData, sizeof(LOGFONT));
}
if (i == CChatOptionsDlg::FONT_COUNT)
{
for (i = 0; i < CChatOptionsDlg::FONT_COUNT; i++ )
{
m_hMsgFonts[ i ] = CreateFontIndirect( &m_hMsgLogFonts[i] );
}
m_bUseName = (BOOL)reWnd.GetNumber(OPT_MAIN_INFORMATION_DISPLAY_NAME);
m_bTimeStamp = (BOOL)reWnd.GetNumber(OPT_MAIN_INFORMATION_DISPLAY_TIME);
m_bUseDate = (BOOL)reWnd.GetNumber(OPT_MAIN_INFORMATION_DISPLAY_DATE);
m_style = (CNmChatCtl::eMsgStyles)reWnd.GetNumber(OPT_MAIN_MESSAGE_FORMAT);
fRet = TRUE;
}
return fRet;
}
void CNmChatCtl::_Save()
{
ASSERT( m_lpszSaveFile );
if( 0 == (m_dwChatFlags & CHAT_FLAG_DIRTYBIT) )
{
return;
}
TCHAR szDrive[ MAX_PATH ];
lstrcpyn( szDrive, m_lpszSaveFile, m_wFileOffset + 1 );
if( !FDirExists( szDrive ) )
{
TCHAR szBuffer[ 2 * MAX_PATH ];
TCHAR szRes[MAX_PATH];
wsprintf( szBuffer, RES2T( IDS_CHAT_CREATE_DIRECTORY, szRes ), szDrive );
if( IDYES == MessageBox(m_hWnd, szBuffer, RES2T(IDS_CHAT_DOCUMENTNAME, szRes), MB_YESNO | MB_ICONQUESTION ) )
{
if( !FEnsureDirExists( szDrive ) )
{
wsprintf( szBuffer, RES2T( IDS_CHAT_COULD_NOT_CREATE_DIR, szRes ), szDrive );
MessageBox(m_hWnd, szBuffer, RES2T(IDS_CHAT_DOCUMENTNAME, szRes), MB_OK | MB_ICONEXCLAMATION );
return;
}
}
}
HANDLE hFile = CreateFile( m_lpszSaveFile,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
NULL );
if( INVALID_HANDLE_VALUE == hFile )
{
DWORD dw = GetLastError();
switch( dw )
{
case ERROR_ACCESS_DENIED:
{
TCHAR szBuffer[ 2 * MAX_PATH ];
TCHAR szRes[MAX_PATH];
wsprintf( szBuffer, RES2T( IDS_CHAT_SAVE_ACCESS_DENIED, szRes ), m_lpszSaveFile );
MessageBox(m_hWnd, szBuffer, RES2T(IDS_CHAT_DOCUMENTNAME, szRes), MB_OK | MB_ICONEXCLAMATION );
break;
}
default:
{
TCHAR szBuffer[ 2 * MAX_PATH ];
TCHAR szRes[MAX_PATH];
wsprintf( szBuffer, RES2T( IDS_CHAT_SAVE_FAILED, szRes ), m_lpszSaveFile );
MessageBox(m_hWnd, szBuffer, RES2T(IDS_CHAT_DOCUMENTNAME, szRes), MB_OK | MB_ICONEXCLAMATION );
break;
}
}
}
else
{
LPTSTR szHeader1 = TEXT("<HTML>\n<HEAD>\n<TITLE>");
LPTSTR szHeader2 = TEXT("</TITLE>\n</HEAD>\n<BODY BGCOLOR=\"white\" TEXT=\"black\">\n<TABLE BORDER=1>");
LPTSTR szEnd = TEXT("</TABLE>\n</BODY>\n</HTML>\n");
LPTSTR szStartRow = TEXT("<TR><TD>");
LPTSTR szEndRow = TEXT("</TD></TR>");
LPTSTR szSplitRow = TEXT("</TD><TD>");
TCHAR szPrivateTo[ MAX_PATH ];
TCHAR szPrivateFrom[ MAX_PATH ];
TCHAR szBuffer[ CCHMAX_CHAT_MSG ];
DWORD dwWritten;
NmCtlLoadString(IDS_CHAT_SAVE_PRIVATE_TO, szPrivateTo, MAX_PATH);
NmCtlLoadString(IDS_CHAT_SAVE_PRIVATE, szPrivateFrom, MAX_PATH);
WriteFile( hFile, szHeader1, lstrlen( szHeader1 ), &dwWritten, NULL );
NmCtlLoadString(IDS_CHAT_DOCUMENTNAME, szBuffer, MAX_PATH);
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szHeader2, lstrlen( szHeader2 ), &dwWritten, NULL );
CChatMessage *pMsg = CChatMessage::get_head();
while( pMsg != NULL )
{
CChatMessage::CHAT_MSGTYPE style = pMsg->get_type();
switch( style )
{
case CChatMessage::MSG_SAY:
case CChatMessage::MSG_WHISPER:
{
WriteFile( hFile, szStartRow, lstrlen( szStartRow ), &dwWritten, NULL );
lstrcpy( szBuffer, m_lpszOwnName );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szSplitRow, lstrlen( szSplitRow ), &dwWritten, NULL );
lstrcpy( szBuffer, pMsg->get_date() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szSplitRow, lstrlen( szSplitRow ), &dwWritten, NULL );
lstrcpy( szBuffer, pMsg->get_time() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szSplitRow, lstrlen( szSplitRow ), &dwWritten, NULL );
if( CChatMessage::MSG_WHISPER == style )
{
wsprintf( szBuffer, szPrivateTo, pMsg->get_person() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
}
lstrcpy( szBuffer, pMsg->get_message() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szEndRow, lstrlen( szEndRow ), &dwWritten, NULL );
break;
}
case CChatMessage::MSG_FROM_OTHER:
case CChatMessage::MSG_WHISPER_FROM_OTHER:
{
WriteFile( hFile, szStartRow, lstrlen( szStartRow ), &dwWritten, NULL );
lstrcpy( szBuffer, pMsg->get_person() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szSplitRow, lstrlen( szSplitRow ), &dwWritten, NULL );
lstrcpy( szBuffer, pMsg->get_date() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szSplitRow, lstrlen( szSplitRow ), &dwWritten, NULL );
lstrcpy( szBuffer, pMsg->get_time() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szSplitRow, lstrlen( szSplitRow ), &dwWritten, NULL );
if( CChatMessage::MSG_WHISPER_FROM_OTHER == style )
{
WriteFile( hFile, szPrivateFrom, lstrlen( szPrivateFrom ), &dwWritten, NULL );
}
lstrcpy( szBuffer, pMsg->get_message() );
WriteFile( hFile, szBuffer, lstrlen( szBuffer ), &dwWritten, NULL );
WriteFile( hFile, szEndRow, lstrlen( szEndRow ), &dwWritten, NULL );
break;
}
default:
{
break;
}
}
pMsg = pMsg->get_next();
};
WriteFile( hFile, szEnd, lstrlen( szEnd ), &dwWritten, NULL );
CloseHandle( hFile );
m_dwChatFlags &= ~CHAT_FLAG_DIRTYBIT;
}
}
inline BOOL CNmChatCtl::_IsPrinting()
{
return( m_dwChatFlags & CHAT_PRINT_FLAG_PRINTING );
}
// From: KB Article ID: Q129860
// Modified by t-ivanl
void CNmChatCtl::_PrintIt(HDC hPrinterDC )
{
DBGENTRY(CNmChatCtl::_PrintIt);
FORMATRANGE fr;
int nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES);
int nVertRes = GetDeviceCaps(hPrinterDC, VERTRES);
int nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX);
int nLogPixelsY = GetDeviceCaps(hPrinterDC, LOGPIXELSY);
LONG lTextLength = 0; // Length of document.
LONG lTextPrinted = 0; // Amount of document printed.
TCHAR lpszDateOrTime[ MAX_PATH ];
TCHAR lpszHeader[ MAX_PATH ];
RECT rcPrintLoc;
// Ensure the printer DC is in MM_TEXT mode.
SetMapMode ( hPrinterDC, MM_TEXT );
// Rendering to the same DC we are measuring.
ZeroMemory(&fr, sizeof(fr));
fr.hdc = fr.hdcTarget = hPrinterDC;
// Set up the page.
fr.rcPage.left = fr.rcPage.top = 0;
fr.rcPage.right = (nHorizRes/nLogPixelsX) * TWIPSPERINCH;
fr.rcPage.bottom = (nVertRes/nLogPixelsY) * TWIPSPERINCH;
// Set up 1" margins all around.
fr.rc.left = fr.rcPage.left + TWIPSPERINCH;
fr.rc.top = fr.rcPage.top + TWIPSPERINCH;
fr.rc.right = fr.rcPage.right - TWIPSPERINCH;
fr.rc.bottom = fr.rcPage.bottom - TWIPSPERINCH;
// Default the range of text to print as the entire document.
fr.chrg.cpMin = 0;
fr.chrg.cpMax = -1;
// Set up the print job (standard printing stuff here).
DOCINFO di;
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(DOCINFO);
// Set the document name
DBG_SAVE_FILE_LINE
LPTSTR lpszDocName = new TCHAR[ MAX_PATH ];
ASSERT( lpszDocName );
NmCtlLoadString(IDS_CHAT_DOCUMENTNAME, lpszDocName, MAX_PATH);
di.lpszDocName = lpszDocName;
NmCtlLoadString(IDS_CHAT_HEADER, lpszHeader, MAX_PATH);
GetDateFormat( LOCALE_USER_DEFAULT, 0, NULL, NULL, lpszDateOrTime, CCHMAX( lpszDateOrTime ) );
lstrcat( lpszHeader, lpszDateOrTime );
lstrcat( lpszHeader, TEXT(" " ) );
GetTimeFormat( LOCALE_USER_DEFAULT, 0, NULL, NULL, lpszDateOrTime, CCHMAX( lpszDateOrTime ) );
lstrcat( lpszHeader, lpszDateOrTime );
GETTEXTLENGTHEX txtLength;
txtLength.flags = GTL_NUMCHARS | GTL_PRECISE;
txtLength.codepage = CP_ACP;
int bufferSize = (int)::SendMessage( m_hWndMsg, EM_GETTEXTLENGTHEX, (WPARAM)&txtLength, 0 );
if(bufferSize == E_INVALIDARG)
{
return;
}
lTextLength =bufferSize;
if( lTextLength > 1 )
{
m_hWndPrint = ::CreateDialog( g_hInstance,
MAKEINTRESOURCE( IDD_CHAT_PRINT ),
m_hWnd,
_PrintDlgProc );
ASSERT( m_hWndPrint );
SetAbortProc( hPrinterDC, _AbortProc );
// Start the document.
StartDoc(hPrinterDC, &di);
while( (lTextPrinted < lTextLength) && (0 == (CHAT_PRINT_FLAG_ABORT & m_dwChatFlags) ) )
{
// Start the page.
StartPage(hPrinterDC);
// New Header print code for bugfix #29365 [mmaddin].
rcPrintLoc.left = nLogPixelsX;
rcPrintLoc.top = nLogPixelsY / 2;
rcPrintLoc.right = fr.rc.right;
rcPrintLoc.bottom = fr.rc.bottom;
DrawText( hPrinterDC, lpszHeader, lstrlen( lpszHeader ), &rcPrintLoc, 0);
// Print as much text as can fit on a page. The return value is the
// index of the first character on the next page.
lTextPrinted = (LONG)::SendMessage(m_hWndMsg,
EM_FORMATRANGE,
FALSE,
(LPARAM)&fr);
if( 0 != lTextPrinted )
{
::SendMessage(m_hWndMsg, EM_DISPLAYBAND, 0, (LPARAM)&fr.rc);
}
// Print last page.
EndPage(hPrinterDC);
if(lTextPrinted < fr.chrg.cpMin)
{
break;
}
// If there is more text to print, adjust the range of characters to
// start printing at the first character of the next page.
if( 0 == lTextPrinted )
{
break;
}
else if (lTextPrinted < lTextLength)
{
fr.chrg.cpMin = lTextPrinted;
fr.chrg.cpMax = -1;
}
}
// Tell the control to release cached information.
::SendMessage(m_hWndMsg, EM_FORMATRANGE, 0, (LPARAM)NULL);
EndDoc(hPrinterDC);
}
delete [] lpszDocName;
EndDialog( m_hWndPrint, 0 );
DBGEXIT(CNmChatCtl::_PrintIt);
}
HRESULT CNmChatCtl::_Print()
{
DBGENTRY(CNmChatCtl::_Print);
HRESULT hr = E_FAIL;
if( 0 == ( CHAT_PRINT_FLAG_PRINTDLG_INITIALIZED & m_dwChatFlags ) )
{
ZeroMemory( &m_PrintDlg, sizeof( m_PrintDlg ) );
m_PrintDlg.lStructSize = sizeof( m_PrintDlg );
m_PrintDlg.hwndOwner = m_hWnd;
m_PrintDlg.Flags = PD_ALLPAGES | PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC | PD_DISABLEPRINTTOFILE;
m_dwChatFlags |= CHAT_PRINT_FLAG_PRINTDLG_INITIALIZED;
}
BOOL b;
if( FALSE != (b = PrintDlg( &m_PrintDlg ) ) )
{
ms_pThis = this;
_PrintIt( m_PrintDlg.hDC );
ms_pThis = NULL;
hr = S_OK;
}
DBGEXIT_HR(CNmChatCtl::_Print, hr);
return hr;
}
BOOL CALLBACK CNmChatCtl::_AbortProc( HDC hdcPrinter, int iCode )
{
MSG msg;
while( (0 == (CHAT_PRINT_FLAG_ABORT & ms_pThis->m_dwChatFlags) ) &&
PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if( NULL == ms_pThis->m_hWndPrint ||
!::IsDialogMessage( ms_pThis->m_hWndPrint, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
return(0 == (CHAT_PRINT_FLAG_ABORT & ms_pThis->m_dwChatFlags) );
}
INT_PTR CALLBACK CNmChatCtl::_PrintDlgProc( HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
switch( uiMsg )
{
case WM_INITDIALOG:
{
return TRUE;
break;
}
case WM_COMMAND:
{
switch( LOWORD( wParam ) )
{
case IDCANCEL:
{
ms_pThis->m_dwChatFlags |= CHAT_PRINT_FLAG_ABORT;
//EndDialog( hDlg, CHAT_PRINT_FLAG_ABORT );
return TRUE;
}
}
}
}
return FALSE;
}
INT_PTR CALLBACK CNmChatCtl::_AboutDlgProc( HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
switch( uiMsg )
{
case WM_INITDIALOG:
{
TCHAR szFormat[256];
TCHAR szVersion[512];
::GetDlgItemText(hDlg, IDC_CHAT_ABOUT_VERSION, szFormat, 256);
wsprintf(szVersion, szFormat, VER_PRODUCTRELEASE_STR,
VER_PRODUCTVERSION_STR);
::SetDlgItemText(hDlg, IDC_CHAT_ABOUT_VERSION, szVersion);
return TRUE;
break;
}
case WM_QUIT:
case WM_COMMAND:
{
EndDialog( hDlg, IDOK );
return TRUE;
}
}
return FALSE;
}
INT_PTR CALLBACK CChatOptionsDlg::_OptionsDlgProc( HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
switch(uiMsg)
{
case WM_INITDIALOG:
g_pChatWindow->m_pChatOptions->OnInit(hDlg);
break;
case WM_HELP:
g_pChatWindow->m_pChatOptions->OnHelp(lParam);
break;
case WM_CONTEXTMENU:
g_pChatWindow->m_pChatOptions->OnHelpWhatsThis(wParam);
break;
case WM_COMMAND:
g_pChatWindow->m_pChatOptions->OnCommand(wParam);
break;
}
return 0;
}
void CChatOptionsDlg::OnCommand(WPARAM wParam)
{
switch( LOWORD( wParam ) )
{
case IDOK:
OnOkClicked();
break;
case IDCANCEL:
OnCancelClicked();
break;
case IDC_FONT_MSGOUT:
case IDC_FONT_MSGIN:
case IDC_FONT_PRIVATEOUT:
case IDC_FONT_PRIVATEIN:
OnFontClicked(LOWORD( wParam ));
break;
}
}
CChatOptionsDlg::CChatOptionsDlg( CNmChatCtl *pChatCtl )
: m_pChatCtl( pChatCtl )
{
}
void CChatOptionsDlg::_DisplayFontNameAndSize( int iFont )
{
TCHAR szBuffer[ MAX_PATH ];
TCHAR szRes[MAX_PATH];
ASSERT( iFont < FONT_COUNT );
wsprintf( szBuffer, RES2T( IDS_CHAT_OPTIONS_FONT_FORMAT,szRes ),
_Points_From_LogFontHeight( m_hMsgLogFonts[iFont].lfHeight, m_pChatCtl->GetHandle() ),
m_hMsgLogFonts[iFont].lfFaceName );
HWND hwndEdit = NULL;
switch( iFont )
{
case FONT_MSGOUT:
{
hwndEdit = GetDlgItem(m_hOptionsDlg, IDC_EDIT_MSGOUT );
break;
}
case FONT_MSGIN:
{
hwndEdit = GetDlgItem(m_hOptionsDlg, IDC_EDIT_MSGIN );
break;
}
case FONT_PRIVATEOUT:
{
hwndEdit = GetDlgItem(m_hOptionsDlg, IDC_EDIT_PRIVATEOUT );
break;
}
case FONT_PRIVATEIN:
{
hwndEdit = GetDlgItem(m_hOptionsDlg, IDC_EDIT_PRIVATEIN );
break;
}
}
::SetWindowText( hwndEdit, szBuffer );
}
LRESULT CChatOptionsDlg::OnInit(HWND hDlg)
{
m_hOptionsDlg = hDlg;
for( int i = 0; i < FONT_COUNT; i++ )
{
m_hMsgLogFonts[ i ] = m_pChatCtl->m_hMsgLogFonts[ i ];
m_hMsgColors[ i ] = m_pChatCtl->m_hMsgColors[ i ];
m_bDirtyFonts[ i ] = FALSE;
_DisplayFontNameAndSize( i );
}
::SendMessage( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_NAME ),
BM_SETCHECK,
(WPARAM)m_pChatCtl->m_bUseName,
0L );
::SetFocus( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_NAME ));
::SendMessage( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_DATE ),
BM_SETCHECK,
(WPARAM)m_pChatCtl->m_bUseDate,
0L );
::SendMessage( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_TIME ),
BM_SETCHECK,
(WPARAM)m_pChatCtl->m_bTimeStamp,
0L );
switch( m_pChatCtl->m_style )
{
case CNmChatCtl::MSGSTYLE_2_LINE_WRAP:
::SendMessage( GetDlgItem(m_hOptionsDlg, IDR_NEW_LINE ),
BM_SETCHECK,
TRUE,
0L );
break;
case CNmChatCtl::MSGSTYLE_1_LINE_WRAP:
::SendMessage( GetDlgItem(m_hOptionsDlg, IDR_SAME_LINE ),
BM_SETCHECK,
TRUE,
0L );
break;
case CNmChatCtl::MSGSTYLE_NO_WRAP:
::SendMessage( GetDlgItem(m_hOptionsDlg, IDR_SINGLE_LINE ),
BM_SETCHECK,
TRUE,
0L );
break;
}
return 0L;
}
LRESULT CChatOptionsDlg::OnHelp(LPARAM lParam)
{
DoHelp(lParam, _mpIdHelpChatOptions);
return 0L;
}
LRESULT CChatOptionsDlg::OnHelpWhatsThis(WPARAM wParam)
{
DoHelpWhatsThis(wParam, _mpIdHelpChatOptions);
return 0L;
}
LRESULT CChatOptionsDlg::OnOkClicked()
{
BOOL bChanged = FALSE;
// View Fields
BOOL bVal = (BOOL)::SendMessage( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_NAME ),
BM_GETCHECK,
0L,
0L );
bChanged = ( !m_pChatCtl->m_bUseName == !bVal ) ? bChanged : TRUE;
m_pChatCtl->m_bUseName = (short)bVal;
bVal = (BOOL)::SendMessage( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_TIME ),
BM_GETCHECK,
0L,
0L );
bChanged = ( !m_pChatCtl->m_bTimeStamp == !bVal ) ? bChanged : TRUE;
m_pChatCtl->m_bTimeStamp = (short)bVal;
bVal = (BOOL)::SendMessage( GetDlgItem(m_hOptionsDlg, IDC_INCLUDE_DATE ),
BM_GETCHECK,
0L,
0L );
bChanged = ( !m_pChatCtl->m_bUseDate == !bVal ) ? bChanged : TRUE;
m_pChatCtl->m_bUseDate = (short)bVal;
// Msg Style
CNmChatCtl::MSGSTYLE style;
if( ::SendMessage( GetDlgItem(m_hOptionsDlg, IDR_SINGLE_LINE ),
BM_GETCHECK,
0L,
0L ) )
{
style = CNmChatCtl::MSGSTYLE_NO_WRAP;
}
else if( ::SendMessage( GetDlgItem(m_hOptionsDlg, IDR_SAME_LINE ),
BM_GETCHECK,
0L,
0L ) )
{
style = CNmChatCtl::MSGSTYLE_1_LINE_WRAP;
}
else
{
style = CNmChatCtl::MSGSTYLE_2_LINE_WRAP;
}
bChanged = ( style == m_pChatCtl->get_MsgStyle() ) ? bChanged : TRUE;
// Fonts
for( int i = 0; i < FONT_COUNT; i++ )
{
if( m_bDirtyFonts[i] )
{
m_pChatCtl->m_hMsgColors[ i ] = m_hMsgColors[ i ];
m_pChatCtl->m_hMsgLogFonts[ i ] = m_hMsgLogFonts[ i ];
DeleteObject( m_pChatCtl->m_hMsgFonts[i] );
m_pChatCtl->m_hMsgFonts[i] = CreateFontIndirect( &m_pChatCtl->m_hMsgLogFonts[ i ] );
bChanged = TRUE;
}
}
if( bChanged )
{
m_pChatCtl->put_MsgStyle( style );
}
EndDialog(m_hOptionsDlg, IDOK );
return 0L;
}
LRESULT CChatOptionsDlg::OnCancelClicked()
{
EndDialog(m_hOptionsDlg, IDCANCEL );
return 0L;
}
LRESULT CChatOptionsDlg::OnFontClicked(WORD wID)
{
int iIndex = FONT_COUNT;
switch( wID )
{
case IDC_FONT_MSGOUT:
{
iIndex = FONT_MSGOUT;
break;
}
case IDC_FONT_MSGIN:
{
iIndex = FONT_MSGIN;
break;
}
case IDC_FONT_PRIVATEOUT:
{
iIndex = FONT_PRIVATEOUT;
break;
}
case IDC_FONT_PRIVATEIN:
{
iIndex = FONT_PRIVATEIN;
break;
}
default:
ASSERT( 0 );
}
CHOOSEFONT cf;
ZeroMemory( &cf, sizeof( cf ) );
cf.lStructSize = sizeof( cf );
cf.hwndOwner = m_hOptionsDlg;
cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_EFFECTS;
cf.lpLogFont = &m_hMsgLogFonts[ iIndex ];
cf.rgbColors = m_hMsgColors[ iIndex ];
if( ChooseFont( &cf ) )
{
m_bDirtyFonts[ iIndex ] = TRUE;
m_hMsgColors[ iIndex ] = cf.rgbColors;
_DisplayFontNameAndSize( iIndex );
}
return 0L;
}
//
//
// Function: _GetWindowRectOption
//
// Purpose: Retrieve a named option from the dictionary and convert it to
// a window rectangle. The rectangle is checked to make sure that
// it is at least partially on screen, and not zero sized.
//
//
void _GetWindowRectOption(LPRECT pRect)
{
RegEntry reWnd( CHAT_KEY, HKEY_CURRENT_USER );
pRect->left = reWnd.GetNumber( REGVAL_WINDOW_XPOS, 0);
pRect->top = reWnd.GetNumber( REGVAL_WINDOW_YPOS, 0);
int cx = reWnd.GetNumber( REGVAL_WINDOW_WIDTH, 0);
int cy = reWnd.GetNumber( REGVAL_WINDOW_HEIGHT, 0);
pRect->right = pRect->left + cx;
pRect->bottom = pRect->top + cy;
int iTop = pRect->top;
int iLeft = pRect->left;
int iBottom = pRect->bottom;
int iRight = pRect->right;
//
// If it was an empty rect
//
if( !(pRect->bottom || pRect->top || pRect->left || pRect->right) )
{
MINMAXINFO lpmmi;
g_pChatWindow->OnGetMinMaxInfo(&lpmmi);
iTop = 50;
iLeft = 50;
iBottom = lpmmi.ptMinTrackSize.y + 100;
iRight = lpmmi.ptMinTrackSize.x + 200;
pRect->top = iTop;
pRect->left = iLeft;
pRect->bottom = iBottom;
pRect->right = iRight;
return;
}
// Make sure that the window rectangle is (at least partially) on
// screen, and not too large. First get the screen size
int screenWidth = ::GetSystemMetrics(SM_CXSCREEN);
int screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
// Check the window size
if ((iRight - iLeft) > screenWidth)
{
iRight = iLeft + screenWidth;
}
if ((iBottom - iTop) > screenHeight)
{
iTop = screenHeight;
}
// Check the window position
if (iLeft >= screenWidth)
{
// Off screen to the right - keep the width the same
iLeft = screenWidth - (iRight - iLeft);
iRight = screenWidth;
}
if (iRight < 0)
{
// Off screen to the left - keep the width the same
iRight = iRight - iLeft;
iLeft = 0;
}
if (iTop >= screenHeight)
{
// Off screen to the bottom - keep the height the same
iTop = screenHeight - (iBottom - iTop);
iBottom = screenHeight;
}
if (iBottom < 0)
{
// Off screen to the top - keep the height the same
iBottom = (iBottom - iTop);
iTop = 0;
}
pRect->left = iLeft;
pRect->top = iTop;
pRect->right = iRight;
pRect->bottom = iBottom;
}
//
//
// Function: SetWindowRectOption
//
// Purpose: Write a window position rectangle
//
//
void _SetWindowRectOption(LPCRECT pcRect)
{
RegEntry reWnd( CHAT_KEY, HKEY_CURRENT_USER );
reWnd.SetValue( REGVAL_WINDOW_XPOS, pcRect->left );
reWnd.SetValue( REGVAL_WINDOW_YPOS, pcRect->top );
reWnd.SetValue( REGVAL_WINDOW_WIDTH, pcRect->right - pcRect->left );
reWnd.SetValue( REGVAL_WINDOW_HEIGHT, pcRect->bottom - pcRect->top );
}