From 9ea691dd251b5e29b51c78d713fb5f6360f524f6 Mon Sep 17 00:00:00 2001 From: Alexander Gluzsky Date: Sun, 29 Jul 2012 20:21:22 +0000 Subject: added msg_export plugin port git-svn-id: http://svn.miranda-ng.org/main/trunk@1249 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/msg_export/src/FileViewer.cpp | 1424 +++++++++++++++++++++++++++++++++ 1 file changed, 1424 insertions(+) create mode 100755 plugins/msg_export/src/FileViewer.cpp (limited to 'plugins/msg_export/src/FileViewer.cpp') diff --git a/plugins/msg_export/src/FileViewer.cpp b/plugins/msg_export/src/FileViewer.cpp new file mode 100755 index 0000000000..b7765b6755 --- /dev/null +++ b/plugins/msg_export/src/FileViewer.cpp @@ -0,0 +1,1424 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include + +#include +#include + +using namespace std; + + +#include "Utils.h" +#include "Glob.h" +#include "FileViewer.h" + +#include "resource.h" + +#include +#include + +//#include + +#define szFileViewDB "FileV_" + +#define WM_RELOAD_FILE (WM_USER+10) + +using namespace std; + +static UINT UM_FIND_CMD = RegisterWindowMessage( FINDMSGSTRING ); + +#define ID_FV_FONT 0x0010 +#define ID_FV_COLOR 0x0020 +#define ID_FV_SYNTAX_HL 0x0030 +#define ID_FV_SAVE_AS_RTF 0x0040 +// ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); +// ASSERT(IDM_ABOUTBOX < 0xF000); + + +// Specifies if history is opened internaly or externaly +bool bUseIntViewer = true; + +// External program used to view files +tstring sFileViewerPrg; + +// handle to the RichEditDll. We need to load this dll to use a RichEdit. +HMODULE hRichEditDll = NULL; + + +#define CONT(i) ((in[i]&0xc0) == 0x80) +#define VAL(i, s) ((in[i]&0x3f) << s) + +void swap(char &c1, char &c2) { + char ch; + ch=c1; + c1=c2; + c2=ch; +} + +int DecodeUTF8(const char *pcBuff,int /*iBufSize*/,char *pcOutBuf) { + int iBytesInOut=0; + int /*cp,*/i; + char ch,*p; + +//Parse UTF-8 sequence +//Support only chars up to three bytes (UCS-4 - go away!) +//Warning: Partial decoding is possible! + i=0; + ch=pcBuff[i]; + if(!(ch&0x80)) { + pcOutBuf[iBytesInOut++]=ch; + pcOutBuf[iBytesInOut++]='\0'; + } + else if(!(ch&0x20)) { + pcOutBuf[iBytesInOut++]=(ch>>2)&0x07; + i++; + pcOutBuf[iBytesInOut++]=(pcBuff[i]&0x3F)|(ch<<6); + swap(pcOutBuf[iBytesInOut-1],pcOutBuf[iBytesInOut-2]); + } + else if(!(ch&0x10)) { + i++; + + pcOutBuf[iBytesInOut++]=(ch<<4)|((pcBuff[i]>>2)&0x0F); + ch=pcBuff[i]; + i++; + pcOutBuf[iBytesInOut++]=(pcBuff[i]&0x3F)|(ch<<6); + swap(pcOutBuf[iBytesInOut-1],pcOutBuf[iBytesInOut-2]); + } + else { + p=(char*)&pcBuff[i]; + pcOutBuf[iBytesInOut++]='\x3F'; + pcOutBuf[iBytesInOut++]='\0'; + if(!(ch&0x08)) i+=3; + else if(!(ch&0x04)) i+=4; + else if(!(ch&0x02)) i+=5; + } + + i++; + + return i; +} + + +int __utf8_get_char(const char *in, int *chr) +{ /* 2-byte, 0x80-0x7ff */ + return DecodeUTF8(in,256,(char *)chr); +} + +// there is one instance of CLHistoryDlg for every history dialog on screeen. +class CLHistoryDlg +{ + public: + HWND hWnd; + + HANDLE hContact; + tstring sPath; + + WNDPROC wpOrigEditProc; + + HWND hFindDlg; + FINDREPLACE fr; + _TCHAR acFindStr[100]; + + bool bFirstLoad; + bool bUtf8File; + + CLHistoryDlg( HANDLE hContact ) : hContact( hContact ) + { + hFindDlg = NULL; + acFindStr[0] = 0; + ZeroMemory( &fr , sizeof( fr )); + fr.lStructSize = sizeof( fr ); + fr.hInstance = hInstance; + fr.Flags = FR_NOUPDOWN|FR_HIDEUPDOWN;//|FR_MATCHCASE|FR_WHOLEWORD; + // FR_DOWN|FR_FINDNEXT|FR_NOMATCHCASE; + fr.lpstrFindWhat = acFindStr; + fr.wFindWhatLen = sizeof(acFindStr); + bFirstLoad = true; + bUtf8File = false; + } +}; + +// List of all open history windows +list< CLHistoryDlg* > clHistoryDlgList; +// CRITICAL_SECTION used to access the window list +// this is nesery because UpdateFileViews is called from callback thread. +CRITICAL_SECTION csHistoryList; + + +// CLStreamRTFInfo is used when reading RTF into rich edit from a stream. +// RTF is used when Syntax highlighting is used. +class CLStreamRTFInfo +{ + private: + HANDLE hFile; + bool bHeaderWriten; + bool bTailWriten; + bool bCheckFirstForNick; + bool bLastColorMyNick; + + // buffer size supplyed on win XP 4092 byte when streamin in + // optimal size it to fully use this buffer but we can guess + // how may bytes need converting in the file we are reading. + BYTE abBuf[3300]; + char szMyNick[100]; + int nNickLen; + static int nOptimalReadLen; + + int nWriteHeader( char * pszTarget , int nLen ); + public: + bool bUtf8File; + CLStreamRTFInfo( HANDLE hFile ) + { + this->hFile = hFile; + bHeaderWriten = false; + bTailWriten = false; + bCheckFirstForNick = false; + bLastColorMyNick = false; + bUtf8File = false; + nNickLen = 0; + } + int nLoadFileStream( LPBYTE pbBuff , LONG cb ); +}; +int CLStreamRTFInfo::nOptimalReadLen = 3300; + +///////////////////////////////////////////////////////////////////// +// Member Function : nWriteHeader +// Type : Private / Public / Protected +// Parameters : pszTarget - ? +// nLen - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030204 , 04 February 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int CLStreamRTFInfo::nWriteHeader( char * pszTarget , int nLen ) +{ + COLORREF cMyText = DBGetContactSettingDword(NULL,"SRMsg","Font3Col",RGB(64,0,128)); + COLORREF cYourText = DBGetContactSettingDword(NULL,"SRMsg","Font0Col",RGB(240,0,0)); + +/* original header !! + "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\r\n" + "{\\colortbl ;\\red%d\\green%d\\blue%d;\\red%d\\green%d\\blue%d;}\r\n" + "\\viewkind4\\uc1\\pard\\cf2\\lang1033\\f0\\fs16 " , + +*/ + char szRtfHeader[400]; + int nSrcLen = _snprintf( szRtfHeader , sizeof( szRtfHeader ) , + "{\\rtf1\\ansi\r\n" + "{\\colortbl ;\\red%d\\green%d\\blue%d;\\red%d\\green%d\\blue%d;}\r\n" + "\\viewkind4\\uc1\\pard\\cf2 " , + GetRValue( cMyText ) ,GetGValue( cMyText ) ,GetBValue( cMyText ) , + GetRValue( cYourText ) ,GetGValue( cYourText ) ,GetBValue( cYourText ) ); + + if( nSrcLen > nLen ) + { + MessageBox( NULL , _T("Failed to write to the RichEdit the buffer was to small."),MSG_BOX_TITEL,MB_OK ); + return 0; // target buffer to small + } + + memcpy( pszTarget , szRtfHeader , nSrcLen ); + bHeaderWriten = true; + return nSrcLen; +} + +const char szNewLine[] = "\n\\par "; +const char szRtfEnd[] = "\r\n\\par }\r\n\0"; + +///////////////////////////////////////////////////////////////////// +// Member Function : nLoadFileStream +// Type : Private / Public / Protected +// Parameters : pbBuff - ? +// cb - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030204 , 04 February 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int CLStreamRTFInfo::nLoadFileStream( LPBYTE pbBuff , LONG cb ) +{ + if( bTailWriten ) + return 0; + + if( nOptimalReadLen < 500 ) + { + MessageBox( NULL , _T("Error: Optimal buffer size decrecied to a to low size !!"),MSG_BOX_TITEL,MB_OK ); + return 0; + } + + DWORD dwRead; + DWORD dwToRead = nOptimalReadLen; + + if( ! ReadFile(hFile , abBuf, dwToRead , &dwRead, (LPOVERLAPPED)NULL) ) + return 0; + + DWORD dwCurrent = 0; + DWORD n = 0; + if( ! bHeaderWriten ) + { + if( dwRead >= 3 ) + { + bUtf8File = bIsUtf8Header( abBuf ); + if( bUtf8File ) + n = 3; + } + dwCurrent += nWriteHeader( (char*)pbBuff , cb ); + + tstring sMyNick = NickFromHandle(0); +#ifdef _UNICODE + nNickLen = WideCharToMultiByte(bUtf8File ? CP_UTF8 : CP_ACP , 0, sMyNick.c_str(), sMyNick.length() , szMyNick , sizeof( szMyNick ), NULL , NULL ); +#else + strcpy( szMyNick , sMyNick.c_str() ); + nNickLen = sMyNick.length(); +#endif + } + else + { + if( bCheckFirstForNick ) + { + // Test against "<<" also + if( ( (memcmp( abBuf , szMyNick , nNickLen ) == 0) || + (abBuf[0] == '<' && abBuf[1] == '<') + ) != bLastColorMyNick ) + { + // we shut only get here if we need to change color !! + bLastColorMyNick = !bLastColorMyNick; + // change color + memcpy( &pbBuff[dwCurrent] , bLastColorMyNick ? "\\cf1 " : "\\cf2 ", 5 ); + } + bCheckFirstForNick = false; + } + } + + bool bIsFileEnd = dwRead < dwToRead; + + for( ; n < dwRead ; n++ ) + { + // worst case is a file ending with \n or a unicode letter. resulting in a big unicode string + // here we need szNewLine and szRtfEnd. the 10 is a small safty margin. + if( dwCurrent + (sizeof( szNewLine ) + sizeof( szRtfEnd ) + 10 ) > (DWORD)cb ) + { + // oh no !!! we have almost reached the end of the windows supplyed buffer + // we are writing to. we need to abort mision *S*!! + // and rewinde file + // we will adjust the optima buffer size + nOptimalReadLen -= 50; + SetFilePointer( hFile , n - dwRead , NULL , FILE_CURRENT ); + return dwCurrent; + } + + if( abBuf[n] == '\n' ) + { + memcpy( &pbBuff[dwCurrent] , szNewLine , sizeof( szNewLine )-1 ); + dwCurrent += sizeof( szNewLine )-1; + + if( n + 1 >= dwRead ) + { + // this is an anoing case because here we have read \n as the last char in the file + // this means that the if the next data read from file begins with it has + // to be highlighted + if( !bIsFileEnd ) + bCheckFirstForNick = true; + break; + } + + if( abBuf[n+1] == ' ' || abBuf[n+1] == '\t' || abBuf[n+1] == '\r' ) + continue; + + if( n + nNickLen >= dwRead ) + { + if( !bIsFileEnd ) + { + // here we have a problem we haven't read this data yet + // the data we need to compare to is still in the file. + // we can't read more data from the file because the we + // might just move the problem. if file contains \n\n\n\n\n ... + + LONG lExtraRead = (n+1) - dwRead; + if( lExtraRead >= 0 ) + MessageBox( NULL , _T("Internal error !! (lExtraRead >= 0)"),MSG_BOX_TITEL,MB_OK ); + SetFilePointer( hFile , lExtraRead , NULL , FILE_CURRENT ); + bCheckFirstForNick = true; + return dwCurrent; + } + + if( ! bLastColorMyNick ) + continue; + // else the last color user was my nick + // we needd to change color to the other user color. + + + /* old code !! + DWORD dwAddedToBuf; + if( ! ReadFile(hFile , &abBuf[dwRead], dwNeeded , &dwAddedToBuf, (LPOVERLAPPED)NULL) ) + return 0; + dwToRead += dwNeeded; + dwRead += dwAddedToBuf;*/ + } + else + { + // the data we need is here just compare + if( ( ( memcmp( &abBuf[n+1] , szMyNick , nNickLen ) == 0) || + ( abBuf[n+1] == '<' && abBuf[n+2] == '<') + ) == bLastColorMyNick ) + continue; + } + // we shut only get here if we need to change color !! + bLastColorMyNick = !bLastColorMyNick; + + // change color + memcpy( &pbBuff[dwCurrent] , bLastColorMyNick ? "\\cf1 " : "\\cf2 ", 5 ); + dwCurrent += 5; + continue; + } + else if( abBuf[n] == '\\' || abBuf[n] == '}' || abBuf[n] == '{') + { + pbBuff[dwCurrent++]='\\'; + } + else if( bUtf8File && (abBuf[n] & 0x80) ) + { + int nValue; + int nLen = __utf8_get_char( (const char *)&abBuf[n] , &nValue ); + if(nLen+n>dwRead) { + SetFilePointer(hFile,n-dwRead,NULL,FILE_CURRENT); + break; + } + dwCurrent += sprintf( (char*)&pbBuff[dwCurrent] , "\\u%d?" , nValue ); + //continue; +/* // Then we have an extended char in the UTF8 file. + // we need to convert this to UCS-2 and then to \uN in the RTF + int nUtf8Len = 1; + while( ( (n + nUtf8Len) < dwRead ) && ((abBuf[ n + nUtf8Len ] & 0xC0) == 0x80) ) + nUtf8Len++; + wchar_t szWstr[2]; + if( MultiByteToWideChar( CP_UTF8 , 0 , (char*)&abBuf[n] , nUtf8Len , szWstr , 2 ) == 1 ) + { + if( (int)(szWstr[0]) != nValue ) + __utf8_get_char( (const char *)&abBuf[n] , &nValue ); + +// dwCurrent += sprintf( (char*)&pbBuff[dwCurrent] , "\\u%d?" , (int)(szWstr[0]) ); +// n += nUtf8Len - 1; +// continue; + }*/ + n += nLen-1; + continue; + } + pbBuff[dwCurrent++] = abBuf[n]; + } + + if( bIsFileEnd ) + {// write end + memcpy( &pbBuff[dwCurrent] , szRtfEnd , sizeof( szRtfEnd )-1 ); + dwCurrent += sizeof( szRtfEnd )-1; + bTailWriten = true; + } + //memcpy( pbBuff , abBuf , dwRead ); + return dwCurrent; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : Initilize +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021213 , 13 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void Initilize() +{ + InitializeCriticalSection( &csHistoryList ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : Uninitilize +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021213 , 13 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void Uninitilize() +{ + DeleteCriticalSection( &csHistoryList ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : UpdateFileViews +// Type : Global +// Parameters : pszFile - File which has been updated +// Returns : void +// Description : Send a message to alle to windows that need updating +// +// References : - +// Remarks : - +// Created : 021213 , 13 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void UpdateFileViews( const _TCHAR * pszFile ) +{ + EnterCriticalSection( &csHistoryList ); + + list< CLHistoryDlg* >::const_iterator iterator; + for( iterator = clHistoryDlgList.begin() ; iterator != clHistoryDlgList.end() ; ++iterator ) + { + CLHistoryDlg* pcl = (*iterator); + if( pcl->sPath == pszFile ) + { + PostMessage( pcl->hWnd , WM_RELOAD_FILE , 0 , 0 ); + } + } + LeaveCriticalSection( &csHistoryList ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bOpenExternaly +// Type : Global +// Parameters : hContact - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021010 , 10 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bOpenExternaly( HANDLE hContact ) +{ + tstring sPath = GetFilePathFromUser( hContact ); + + if( sFileViewerPrg.empty() ) + { + SHELLEXECUTEINFO st = {0}; + st.cbSize = sizeof(st); + st.fMask = SEE_MASK_INVOKEIDLIST; + st.hwnd = NULL; + st.lpFile = sPath.c_str(); + st.nShow = SW_SHOWDEFAULT; + ShellExecuteEx(&st); + return true; + } + tstring sTmp = sFileViewerPrg; + sTmp += _T(" "); + sTmp += sPath; + //sTmp += '\"'; + + STARTUPINFO sStartupInfo = { 0 }; + GetStartupInfo(&sStartupInfo); // we parse oure owne info on + sStartupInfo.lpTitle = (_TCHAR*)sFileViewerPrg.c_str(); + PROCESS_INFORMATION stProcesses = {0}; + + if( ! CreateProcess( NULL, + (_TCHAR*)sTmp.c_str(), + NULL, + NULL, + FALSE, + CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP , + NULL, + NULL, + &sStartupInfo, + &stProcesses ) ) + { + DisplayLastError( _T("Faile to execute external file view") ); + } + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bGetInternalViewer +// Type : Global +// Parameters : None +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021016 , 16 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bUseInternalViewer() +{ + return bUseIntViewer; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bUseInternalViewer +// Type : Global +// Parameters : bNew - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021016 , 16 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bUseInternalViewer( bool bNew ) +{ + bUseIntViewer = bNew; + if( bUseIntViewer && !hRichEditDll ) + { + hRichEditDll = LoadLibraryA("RICHED32.DLL"); + if( !hRichEditDll ) + { + DisplayLastError( _T("Failed to load Rich Edit ( RICHED32.DLL )" )); + return false; + } + } + else if( !bUseIntViewer && hRichEditDll ) + { + if( ::FreeLibrary(hRichEditDll) == 0 ) + { + DisplayLastError( _T("Failed to unload Rich Edit ( RICHED32.DLL )") ); + hRichEditDll = NULL; + return false; + } + hRichEditDll = NULL; + } + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : RichEditStreamLoadFile +// Type : Global +// Parameters : dwCookie - ? +// pbBuff - ? +// cb - ? +// pcb - ? +// Returns : DWORD CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 021010 , 10 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +DWORD CALLBACK RichEditStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + ReadFile((HANDLE)dwCookie, pbBuff, (DWORD)cb, (DWORD *)pcb, (LPOVERLAPPED)NULL); + return (DWORD) ( *pcb >= 0 ? NOERROR : ( *pcb = 0, E_FAIL ) ); +} + +DWORD CALLBACK RichEditRTFStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + *pcb = ((CLStreamRTFInfo *)dwCookie)->nLoadFileStream( pbBuff, cb ); + if( *pcb ) + return NOERROR; + return (DWORD)E_FAIL; +} + +DWORD CALLBACK RichEditStreamSaveFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + WriteFile((HANDLE)dwCookie, pbBuff, cb , (DWORD*)pcb, (LPOVERLAPPED)NULL); + return *pcb != cb; +} + +/* +DWORD dwCurPos = 0; +DWORD dwDataRead = 0; +BYTE * pabFileData = NULL; + +DWORD CALLBACK RichEditStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + *pcb = 0; + while( dwCurPos < dwDataRead && *pcb < cb ) + { + pbBuff[ *pcb ] = pabFileData[ dwCurPos ]; + dwCurPos++; + (*pcb)++; + } + return (DWORD) ( *pcb >= 0 ? NOERROR : ( *pcb = 0, E_FAIL ) ); +} +*/ +///////////////////////////////////////////////////////////////////// +// Member Function : bLoadFile +// Type : Global +// Parameters : hwndDlg - ? +// hContact - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021010 , 10 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bLoadFile( HWND hwndDlg , CLHistoryDlg * pclDlg ) +{ + DWORD dwStart = GetTickCount(); + + HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + if( ! hRichEdit ) + { + MessageBox( hwndDlg , _T("Failed to get handle to RichEdit!"),MSG_BOX_TITEL,MB_OK ); + return false; + } + + + HANDLE hFile = CreateFile( pclDlg->sPath.c_str() , GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , + OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ); + + + if( hFile == INVALID_HANDLE_VALUE ) + { + int nDBCount = CallService( MS_DB_EVENT_GETCOUNT , (WPARAM)(pclDlg->hContact) ,0 ); + _TCHAR szTmp[1500]; + + if( nDBCount == -1 ) + { + _stprintf( szTmp , _T("Failed to open file\r\n%s\r\n\r\nContact handle is invalid") , pclDlg->sPath.c_str() ); + } + else + { + _stprintf( szTmp , _T("Failed to open file\r\n%s\r\n\r\nMiranda database contains %d events") , pclDlg->sPath.c_str() , nDBCount ); + } + + SETTEXTEX stText = {0}; + stText.codepage = CP_ACP; + SendMessage( hRichEdit , EM_SETTEXTEX, (WPARAM) &stText, (LPARAM) szTmp ); + return false; + } + + POINT ptOldPos; + SendMessage( hRichEdit , EM_GETSCROLLPOS , 0 , (LPARAM) &ptOldPos ); + + bool bScrollToBottom = true; + if( pclDlg->bFirstLoad ) + pclDlg->bFirstLoad = false; + else + { + SCROLLINFO sScrollInfo = { 0 }; + sScrollInfo.cbSize = sizeof( SCROLLINFO ); + sScrollInfo.fMask = SIF_POS | SIF_RANGE | SIF_PAGE; + if( GetScrollInfo( hRichEdit,SB_VERT,&sScrollInfo) ) + bScrollToBottom = sScrollInfo.nPos + (int)sScrollInfo.nPage + 50 > sScrollInfo.nMax; + } + + + HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE ); + bool bUseSyntaxHL = (GetMenuState( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND ) & MF_CHECKED)!=0; + +/* + DWORD dwSize = GetFileSize( hFile , NULL ); + dwCurPos = 0; + pabFileData = new BYTE[ dwSize ]; + ReadFile( hFile , pabFileData, dwSize , &dwDataRead, (LPOVERLAPPED)NULL); +*/ + + + // SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , RGB( 0 , 0 , 128 ) ); + // SendMessage( hRichEdit , EM_SETTEXTMODE, TM_RICHTEXT ,0); + + // DWORD dw = SendMessage( hRichEdit , EM_GETLIMITTEXT, NULL, NULL); + + EDITSTREAM eds; + eds.dwError = 0; + + if( bUseSyntaxHL ) + { + SendMessage( hRichEdit , // handle to destination window + EM_EXLIMITTEXT, // message to send + 0, // not used; must be zero + 0x7FFFFFFF ); + + CLStreamRTFInfo clInfo( hFile ); + eds.dwCookie = (DWORD)&clInfo; + eds.pfnCallback = RichEditRTFStreamLoadFile; + + SendMessage(hRichEdit, EM_STREAMIN, (WPARAM)SF_RTF , (LPARAM)&eds); + pclDlg->bUtf8File = clInfo.bUtf8File; + } + else + { + eds.dwCookie = (DWORD )hFile; + eds.pfnCallback = RichEditStreamLoadFile; + + SendMessage(hRichEdit, EM_STREAMIN, (WPARAM)SF_TEXT , (LPARAM)&eds); + } + + CloseHandle( hFile ); + //delete [] pabFileData; + + _TCHAR szTmp[100]; + _stprintf( szTmp , _T("File open time %d\n") , GetTickCount() - dwStart ); + OutputDebugString( szTmp ); + + + GETTEXTLENGTHEX sData = { 0 }; + sData.flags = GTL_NUMCHARS; + sData.flags = GTL_DEFAULT; + + DWORD dwDataRead = SendMessage( hRichEdit , EM_GETTEXTLENGTHEX, (WPARAM)&sData , 0 ); + SendMessage( hRichEdit , EM_SETSEL , dwDataRead - 1, dwDataRead - 1 ); + + if( ! bScrollToBottom ) + SendMessage( hRichEdit , EM_SETSCROLLPOS , 0 , (LPARAM) &ptOldPos ); + + _stprintf( szTmp , _T("With scroll to bottom %d\n") , GetTickCount() - dwStart ); + OutputDebugString( szTmp ); + + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bAdvancedCopy +// Type : Global +// Parameters : hwnd - handle to RichEdit control +// Returns : Returns true if text was copied to the clipboard +// Description : +// +// References : - +// Remarks : - +// Created : 030730 , 30 juli 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bAdvancedCopy(HWND hwnd) +{ + CHARRANGE sSelectRange; + SendMessage( hwnd, EM_EXGETSEL, 0 , (LPARAM)&sSelectRange ); + int nSelLenght = sSelectRange.cpMax - sSelectRange.cpMin + 1; // +1 for null termination + if( nSelLenght > 1 ) + { + OpenClipboard(NULL); + EmptyClipboard(); + + _TCHAR * pszSrcBuf = new _TCHAR[ nSelLenght]; + pszSrcBuf[0] = 0; + SendMessage( hwnd, EM_GETSELTEXT, 0 , (LPARAM)pszSrcBuf ); + + HANDLE hDecMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, nSelLenght ); + _TCHAR * pszCurDec = (_TCHAR*)GlobalLock(hDecMem); + + bool bInSpaces = false; + for( _TCHAR * pszCur = pszSrcBuf ; pszCur[0] ; pszCur++ ) + { + if( bInSpaces ) + { + if( pszCur[0] == ' ' ) + continue; + bInSpaces = false; + } + + if( pszCur[0] == '\n' ) + { + bInSpaces = true; + } + pszCurDec[0] = pszCur[0]; + pszCurDec++; + } + pszCurDec[0] = 0; + GlobalUnlock(hDecMem); + + SetClipboardData(CF_TEXT,hDecMem); + delete [] pszSrcBuf; + CloseClipboard(); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : EditSubclassProc +// Type : Global +// Parameters : hwnd - ? +// uMsg - ? +// wParam - ? +// lParam - ? +// Returns : LRESULT CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 021013 , 13 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK EditSubclassProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CLHistoryDlg * pclDlg = (CLHistoryDlg *)GetWindowLong(hwnd,GWL_USERDATA); + + switch( msg ) + { + case WM_CONTEXTMENU: + { + HMENU nMenu = LoadMenu( hInstance, MAKEINTRESOURCE( IDR_FV_EDIT ) ); + HMENU nSubMenu = GetSubMenu( nMenu , 0 ); + POINT pt; + pt.x=(short)LOWORD(lParam); + pt.y=(short)HIWORD(lParam); + + if(pt.x==-1 && pt.y==-1) + { + DWORD dwStart,dwEnd; + SendMessage( hwnd , EM_GETSEL , (WPARAM)&dwStart, (LPARAM)&dwEnd ); + SendMessage( hwnd , EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)dwEnd); + ClientToScreen( hwnd , &pt ); + } + TrackPopupMenu( nSubMenu , TPM_RIGHTBUTTON , pt.x , pt.y , 0 , hwnd , 0 ); + + DestroyMenu( nSubMenu ); + DestroyMenu( nMenu ); + return TRUE; + } + case WM_GETDLGCODE: + { + return DLGC_WANTARROWS; + } + case WM_COPY: + { // not working for "CTRL + C" + if( bAdvancedCopy( hwnd ) ) + return TRUE; + break; + } + case WM_KEYDOWN: + { + if( (wParam == VK_INSERT || wParam == 'C') && (GetKeyState(VK_CONTROL) & 0x80) ) + { + if( bAdvancedCopy( hwnd ) ) + return TRUE; + } + break; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_EDIT_COPY: + { + SendMessage( hwnd , WM_COPY, 0, 0 ); + return TRUE; + } + } + } + } + if( msg == UM_FIND_CMD ) + { + FINDREPLACE *fr = (FINDREPLACE *)lParam; + if( fr->Flags & FR_DIALOGTERM ) + { + pclDlg->hFindDlg = NULL; + return 0; + } + + FINDTEXT ft = { 0 }; + + if( fr->Flags & FR_FINDNEXT) + { + ft.lpstrText = fr->lpstrFindWhat; + + SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&ft.chrg); + ft.chrg.cpMin = ft.chrg.cpMax+1; + ft.chrg.cpMax = -1; + int res = SendMessage(hwnd, EM_FINDTEXT, (WPARAM)fr->Flags,(LPARAM)&ft); + if(res == -1) + { + ft.chrg.cpMin = 0; + res = SendMessage(hwnd, EM_FINDTEXT, (WPARAM)fr->Flags,(LPARAM)&ft); + if(res == -1) + { + MessageBox( hwnd , TranslateTS(_T("Search string was not found !")),MSG_BOX_TITEL,MB_OK ); + return 0; + } + } + ft.chrg.cpMin = res; + ft.chrg.cpMax = res + _tcslen(fr->lpstrFindWhat); + SendMessage(hwnd , EM_EXSETSEL, 0, (LPARAM)&ft.chrg); + return 0; + } + + } + return CallWindowProc(pclDlg->wpOrigEditProc, hwnd, msg, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SetWindowsCtrls +// Type : Global +// Parameters : hwndDlg - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021001 , 01 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SetWindowsCtrls( HWND hwndDlg ) +{ + RECT rNewSize; + GetClientRect( hwndDlg , &rNewSize ); + + RECT rCurSize; + + const int nSpacing = 12; + + + HWND hButton = GetDlgItem( hwndDlg , IDOK ); + GetWindowRect( hButton , &rCurSize ); + int nButtonHeight = rCurSize.bottom - rCurSize.top; + + SetWindowPos( GetDlgItem( hwndDlg , IDC_RICHEDIT ) , 0 , + nSpacing , nSpacing , + rNewSize.right - (nSpacing * 2) , + rNewSize.bottom - ( nSpacing * 3 + nButtonHeight ), + SWP_NOZORDER ); + + + int nButtonWidth = rCurSize.right - rCurSize.left; + int nButtonSpace = (rNewSize.right - ( 3 * nButtonWidth )) / 4; + int nButtonTop = rNewSize.bottom - ( nSpacing + nButtonHeight ); + int nCurLeft = nButtonSpace; + + SetWindowPos( GetDlgItem( hwndDlg , IDC_FV_FIND ) , 0 , + nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE ); + + nCurLeft += nButtonSpace + nButtonWidth; + + SetWindowPos( GetDlgItem( hwndDlg , IDC_FV_EXTERNAL ) , 0 , + nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE ); + + nCurLeft += nButtonSpace + nButtonWidth; + + SetWindowPos( hButton , 0 , + nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE ); + +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SetRichEditFont +// Type : Global +// Parameters : hRichEdit - RichEdit to set the font in +// bUseSyntaxHL - Is Syntax hilighting is used the color +// will not be set +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030205 , 05 February 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SetRichEditFont(HWND hRichEdit, bool bUseSyntaxHL ) +{ + CHARFORMAT ncf = { 0 }; + ncf.cbSize = sizeof( CHARFORMAT ); + ncf.dwMask = CFM_BOLD | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE; + ncf.dwEffects = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , 0 ); + ncf.yHeight = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "THeight" , 165 ); + _tcscpy( ncf.szFaceName , _DBGetString( NULL , MODULE , szFileViewDB "TFace" , _T("Courier New")).c_str() ); + + if( ! bUseSyntaxHL ) + { + ncf.dwMask |= CFM_COLOR; + ncf.crTextColor = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , 0 ); + } + SendMessage(hRichEdit, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&ncf); + +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DlgProcFileViewer +// Type : Global +// Parameters : hwndDlg - ? +// msg - ? +// wParam - ? +// lParam - ? +// Returns : static BOOL CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 020929 , 29 September 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static BOOL CALLBACK DlgProcFileViewer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CLHistoryDlg * pclDlg = (CLHistoryDlg *)GetWindowLong(hwndDlg,GWL_USERDATA); + + switch (msg) + { + case WM_INITDIALOG: + { + SetWindowLong(hwndDlg,GWL_USERDATA,lParam); + CLHistoryDlg * pclDlg = (CLHistoryDlg *)lParam; +#ifdef _UNICODE + EnableWindow( GetDlgItem( hwndDlg , IDC_FV_FIND ) , FALSE ); +#endif + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, + (LPARAM)LoadIcon( hInstance, MAKEINTRESOURCE(IDI_EXPORT_MESSAGE))); + + HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + pclDlg->wpOrigEditProc = (WNDPROC) SetWindowLongPtr( hRichEdit, GWL_WNDPROC, (LONG) EditSubclassProc); + + SetWindowLongPtr( hRichEdit, GWLP_USERDATA, (LONG) pclDlg ); + + SendMessage( hRichEdit , EM_SETEVENTMASK , 0 , ENM_LINK); + SendMessage( hRichEdit , EM_AUTOURLDETECT , TRUE , 0 ); + + HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE ); + + InsertMenu( hSysMenu , 0 , MF_SEPARATOR | MF_BYPOSITION , 0 , 0 ); + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION , ID_FV_SAVE_AS_RTF, TranslateTS(_T("Save as RTF")) ); + + InsertMenu( hSysMenu , 0 , MF_SEPARATOR | MF_BYPOSITION , 0 , 0 ); + + BYTE bUseCC = (BYTE)DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , 0 ); + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION | ( bUseCC ? MF_CHECKED : 0 ) , ID_FV_COLOR, TranslateTS(_T("Color...")) ); + + if( bUseCC ) + { + SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , + DBGetContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , RGB(255,255,255) ) + ); + } + + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION , ID_FV_FONT, TranslateTS(_T("Font...")) ); + + + bool bUseSyntaxHL = DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseSyntaxHL" , 1 )!=0; + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION | ( bUseSyntaxHL ? MF_CHECKED : 0 ) , ID_FV_SYNTAX_HL, TranslateTS(_T("Syntax highlight")) ); + + SetRichEditFont( hRichEdit , bUseSyntaxHL ); + + TranslateDialogDefault(hwndDlg); + + int cx= DBGetContactSettingDword( NULL , MODULE , szFileViewDB "cx" , 0 ); + int cy= DBGetContactSettingDword( NULL , MODULE , szFileViewDB "cy" , 0 ); + + if( cx > 0 && cy > 0) + { + int x = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "x" , 0 ); + int y = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "y" , 0 ); + + SetWindowPos( hwndDlg , NULL , x , y , cx , cy , SWP_NOZORDER ); + } + + pclDlg->sPath = GetFilePathFromUser( pclDlg->hContact ); + + SetWindowsCtrls( hwndDlg ); + + + bLoadFile(hwndDlg , pclDlg ); + + { // set Title + _TCHAR szFormat[200]; + _TCHAR szTitle[200]; + if( GetWindowText( hwndDlg , szFormat , sizeof( szFormat ) ) ) + { + const _TCHAR * pszNick = NickFromHandle( pclDlg->hContact ); + tstring sPath = pclDlg->sPath; + string::size_type n = sPath.find_last_of( '\\' ); + if( n != sPath.npos ) + sPath.erase( 0 , n + 1 ); + + if( _sntprintf( szTitle , sizeof( szTitle ) , szFormat , pszNick , sPath.c_str() , (pclDlg->bUtf8File ? _T("UTF8"):_T("ANSI")) ) > 0 ) + { + SetWindowText( hwndDlg , szTitle); + } + } + } + + return TRUE; + } + case WM_RELOAD_FILE: + { + bLoadFile(hwndDlg , pclDlg ); + return TRUE; + } + case WM_SIZE: + case WM_SIZING: + { + SetWindowsCtrls( hwndDlg ); + return TRUE; + } + case WM_NCDESTROY: + { + EnterCriticalSection( &csHistoryList ); + clHistoryDlgList.remove( pclDlg ); + LeaveCriticalSection( &csHistoryList ); + + delete pclDlg; + SetWindowLong(hwndDlg,GWL_USERDATA,NULL); + return 0; + } + case WM_DESTROY: + { + RECT rSize; + if( GetWindowRect( hwndDlg , &rSize ) ) + { + // first we make sure the window has resonable dimentions. + // if it is minimized it will not have that. + if( rSize.left <= -32000 || rSize.top <= -32000 ) + return 0; + if( rSize.right <= -32000 || rSize.bottom <= -32000 ) + return 0; + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "x" , rSize.left ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "y" , rSize.top ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "cx" , rSize.right - rSize.left ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "cy" , rSize.bottom - rSize.top ); + } + return 0; + } + case WM_SYSCOMMAND: + { + HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE ); + bool bUseSyntaxHL = (GetMenuState( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND ) & MF_CHECKED)!=0; + HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + + if ((wParam & 0xFFF0) == ID_FV_FONT) + { + LOGFONT lf = { 0 }; + lf.lfHeight = 14L; + + { DWORD dwEffects = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , 0 ); + lf.lfWeight = (dwEffects & CFE_BOLD) ? FW_BOLD : 0; + lf.lfUnderline = (dwEffects & CFE_UNDERLINE) != 0; + lf.lfStrikeOut = (dwEffects & CFE_STRIKEOUT) != 0; + lf.lfItalic = (dwEffects & CFE_ITALIC) != 0; + } + _tcscpy(lf.lfFaceName, _DBGetString( NULL , MODULE , szFileViewDB "TFace" , _T("Courier New")).c_str()); + CHOOSEFONT cf = { 0 }; + cf.lStructSize = sizeof( cf ); + cf.hwndOwner = hwndDlg; + cf.lpLogFont = &lf; + cf.rgbColors = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , 0 ); + cf.Flags = CF_EFFECTS | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT; + + if( ChooseFont( &cf ) ) + { + DWORD dwEffects = (lf.lfWeight == FW_BOLD ? CFE_BOLD : 0) | + (lf.lfItalic ? CFE_ITALIC : 0) | + (lf.lfStrikeOut ? CFE_STRIKEOUT : 0) | + (lf.lfUnderline ? CFE_UNDERLINE : 0); + + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , dwEffects ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "THeight" , cf.iPointSize * 2 ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , cf.rgbColors ); + DBWriteContactSettingTString( NULL , MODULE , szFileViewDB "TFace" , lf.lfFaceName ); + SetRichEditFont( hRichEdit , bUseSyntaxHL ); + } + return TRUE; + } + else if ((wParam & 0xFFF0) == ID_FV_COLOR) + { + BYTE bUseCC = ! DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , 0 ); + if( bUseCC ) + { + CHOOSECOLOR cc = {0}; + cc.lStructSize = sizeof( cc ); + cc.hwndOwner = hwndDlg; + cc.rgbResult = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , RGB(255,255,255) ); + cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT; + static COLORREF MyCustColors[16] = { 0xFFFFFFFF }; + cc.lpCustColors = MyCustColors; + if( ChooseColor( &cc ) ) + { + SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , cc.rgbResult ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , cc.rgbResult ); + } + else + { + /*DWORD dwError =*/ CommDlgExtendedError(); + return TRUE; + } + } + else + { + SendMessage( hRichEdit , EM_SETBKGNDCOLOR, TRUE , 0 ); + } + CheckMenuItem( hSysMenu , ID_FV_COLOR , MF_BYCOMMAND | (bUseCC ? MF_CHECKED : 0) ); + DBWriteContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , bUseCC ); + return TRUE; + } + else if ((wParam & 0xFFF0) == ID_FV_SYNTAX_HL) + { + // we use the current state from the menu not the DB value + // because we want to toggel the option for this window + // still the new option selected will be stored. + // so user may open 2 windows, now he can set SyntaxHL in both. + + bUseSyntaxHL = !bUseSyntaxHL; + CheckMenuItem( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND | (bUseSyntaxHL ? MF_CHECKED : 0) ); + DBWriteContactSettingByte( NULL , MODULE , szFileViewDB "UseSyntaxHL" , bUseSyntaxHL ); + + if( bUseSyntaxHL ) + bLoadFile(hwndDlg , pclDlg ); + else + SetRichEditFont( hRichEdit , bUseSyntaxHL ); + + return TRUE; + } + else if ((wParam & 0xFFF0) == ID_FV_SAVE_AS_RTF) + { + tstring sFile = pclDlg->sPath; + sFile += _T(".rtf"); + HANDLE hFile = CreateFile( sFile.c_str() , GENERIC_WRITE , + FILE_SHARE_READ , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ); + + if( hFile == INVALID_HANDLE_VALUE ) + { + DisplayLastError( _T("Failed to create file") ); + return TRUE; + } + + EDITSTREAM eds; + eds.dwCookie = (DWORD )hFile; + eds.dwError = 0; + eds.pfnCallback = RichEditStreamSaveFile; + int nWriteOk = SendMessage(hRichEdit, EM_STREAMOUT, (WPARAM)SF_RTF , (LPARAM)&eds); + if( nWriteOk <= 0 || eds.dwError != 0 ) + { + DisplayLastError( _T("Failed to save file") ); + CloseHandle( hFile ); + return TRUE; + } + CloseHandle( hFile ); + tstring sReport = _T("History was saved successfully in file\r\n"); + sReport += sFile; + MessageBox( NULL , sReport.c_str() ,MSG_BOX_TITEL ,MB_OK ); + return TRUE; + } + return FALSE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + case IDOK: + DestroyWindow(hwndDlg); + return TRUE; + case IDC_FV_EXTERNAL: + bOpenExternaly( pclDlg->hContact ); + return TRUE; + case IDC_FV_FIND: + { + if( pclDlg->hFindDlg ) + { + BringWindowToTop( pclDlg->hFindDlg ); + return TRUE; + } + pclDlg->fr.hwndOwner = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + pclDlg->hFindDlg = FindText( &pclDlg->fr ); + return TRUE; + } + } + break; + } + case WM_NOTIFY: + { + if( ((NMHDR*)lParam)->idFrom == IDC_RICHEDIT ) + { + if( ((NMHDR*)lParam)->code == EN_LINK ) + { + ENLINK* pstLink = (ENLINK*)lParam; + if( pstLink->msg == WM_LBUTTONUP ) + { + _TCHAR szUrl[ 500 ]; + if( (pstLink->chrg.cpMax - pstLink->chrg.cpMin) > (sizeof( szUrl ) - 2) ) + return FALSE; + + TEXTRANGE stToGet; + stToGet.chrg = pstLink->chrg; + stToGet.lpstrText = szUrl; + if( SendMessage( pstLink->nmhdr.hwndFrom , EM_GETTEXTRANGE , 0 , (LPARAM)&stToGet ) > 0 ) + { + CallService(MS_UTILS_OPENURL,1,(LPARAM)szUrl); + } + return TRUE; + } + } + } + break; + } + case WM_CLOSE: + { + DestroyWindow(hwndDlg); + return TRUE; + } + } + return FALSE; +//FALSE;//DefWindowProc( hwndDlg, msg, wParam, lParam ); +//DefDlgProc( hwndDlg, msg, wParam, lParam ); +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : bShowFileViewer +// Type : Global +// Parameters : hContact - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 020929 , 29 September 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bShowFileViewer( HANDLE hContact ) +{ + CLHistoryDlg * pcl = new CLHistoryDlg( hContact ); + pcl->hWnd = CreateDialogParam( hInstance,MAKEINTRESOURCE(IDD_FILE_VIEWER),NULL,DlgProcFileViewer,(LPARAM)pcl); + if( pcl->hWnd ) + { + EnterCriticalSection( &csHistoryList ); + clHistoryDlgList.push_front( pcl ); + LeaveCriticalSection( &csHistoryList ); + + ShowWindow( pcl->hWnd , SW_SHOWNORMAL ); + return true; + } + DisplayLastError( _T("Failed to create history dialog") ); + delete pcl; + return false; +} -- cgit v1.2.3