diff options
Diffstat (limited to 'plugins/Scriver/src')
39 files changed, 20135 insertions, 0 deletions
diff --git a/plugins/Scriver/src/chat/chat.h b/plugins/Scriver/src/chat/chat.h new file mode 100644 index 0000000000..b8671fdb82 --- /dev/null +++ b/plugins/Scriver/src/chat/chat.h @@ -0,0 +1,438 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _CHAT_H_
+#define _CHAT_H_
+
+#include <m_protomod.h>
+#include <m_chat.h>
+
+#ifndef TVM_GETITEMSTATE
+#define TVM_GETITEMSTATE (TV_FIRST + 39)
+#endif
+
+#ifndef TreeView_GetItemState
+#define TreeView_GetItemState(hwndTV, hti, mask) \
+ (UINT)SNDMSG((hwndTV), TVM_GETITEMSTATE, (WPARAM)(hti), (LPARAM)(mask))
+#endif
+
+#ifndef CFM_BACKCOLOR
+#define CFM_BACKCOLOR 0x04000000
+#endif
+
+//defines
+#define OPTIONS_FONTCOUNT 17
+#define GC_SPLITTERMOVED (WM_USER+101)
+#define GC_CLOSEWINDOW (WM_USER+103)
+#define GC_GETITEMDATA (WM_USER+104)
+#define GC_SETITEMDATA (WM_USER+105)
+#define GC_SETVISIBILITY (WM_USER+107)
+#define GC_SETWNDPROPS (WM_USER+108)
+#define GC_REDRAWLOG (WM_USER+109)
+#define GC_FIREHOOK (WM_USER+110)
+#define GC_FILTERFIX (WM_USER+111)
+#define GC_CHANGEFILTERFLAG (WM_USER+112)
+#define GC_SHOWFILTERMENU (WM_USER+113)
+#define GC_SETWINDOWPOS (WM_USER+114)
+//#define GC_NICKLISTCLEAR (WM_USER+117)
+#define GC_REDRAWWINDOW (WM_USER+118)
+#define GC_SHOWCOLORCHOOSER (WM_USER+119)
+#define GC_ADDLOG (WM_USER+120)
+#define GC_ACKMESSAGE (WM_USER+121)
+//#define GC_ADDUSER (WM_USER+122)
+//#define GC_REMOVEUSER (WM_USER+123)
+//#define GC_NICKCHANGE (WM_USER+124)
+#define GC_UPDATENICKLIST (WM_USER+125)
+//#define GC_MODECHANGE (WM_USER+126)
+#define GC_TABCHANGE (WM_USER+127)
+#define GC_SCROLLTOBOTTOM (WM_USER+129)
+#define GC_FIXTABICONS (WM_USER+132)
+#define GC_SETTABHIGHLIGHT (WM_USER+138)
+#define GC_SETMESSAGEHIGHLIGHT (WM_USER+139)
+#define GC_REDRAWLOG2 (WM_USER+140)
+#define GC_REDRAWLOG3 (WM_USER+141)
+
+//#define EM_SUBCLASSED (WM_USER+200)
+//#define EM_UNSUBCLASSED (WM_USER+201)
+#define EM_ACTIVATE (WM_USER+202)
+
+#define GCW_TABROOM 10
+#define GCW_TABPRIVMSG 11
+
+#define GC_EVENT_HIGHLIGHT 0x1000
+#define STATE_TALK 0x0001
+
+
+// special service for tweaking performance
+#define MS_GC_GETEVENTPTR "GChat/GetNewEventPtr"
+typedef INT_PTR (*GETEVENTFUNC)(WPARAM wParam, LPARAM lParam);
+typedef struct {
+ GETEVENTFUNC pfnAddEvent;
+}GCPTRS;
+
+//structs
+
+typedef struct MODULE_INFO_TYPE
+{
+ char* pszModule;
+ TCHAR* ptszModDispName;
+ BOOL bBold;
+ BOOL bUnderline;
+ BOOL bItalics;
+ BOOL bColor;
+ BOOL bBkgColor;
+ BOOL bFontSize;
+ BOOL bChanMgr;
+ BOOL bAckMsg;
+ BOOL bSingleFormat;
+ int nColorCount;
+ COLORREF* crColors;
+ HICON hOnlineIcon;
+ HICON hOfflineIcon;
+ HICON hOnlineIconBig;
+ HICON hOfflineIconBig;
+ HICON hOnlineTalkIcon;
+ HICON hOfflineTalkIcon;
+ int iMaxText;
+ struct MODULE_INFO_TYPE *next;
+}
+ MODULEINFO;
+
+typedef struct COMMAND_INFO_TYPE
+{
+ char* lpCommand;
+ struct COMMAND_INFO_TYPE *prev, *next;
+}
+ COMMAND_INFO;
+
+typedef struct
+{
+ LOGFONT lf;
+ COLORREF color;
+}
+ FONTINFO;
+
+typedef struct LOG_INFO_TYPE
+{
+ TCHAR* ptszText;
+ TCHAR* ptszNick;
+ TCHAR* ptszUID;
+ TCHAR* ptszStatus;
+ TCHAR* ptszUserInfo;
+ BOOL bIsMe;
+ BOOL bIsHighlighted;
+ time_t time;
+ int iType;
+ struct LOG_INFO_TYPE *next;
+ struct LOG_INFO_TYPE *prev;
+}
+ LOGINFO;
+
+typedef struct STATUSINFO_TYPE
+{
+ TCHAR* pszGroup;
+ HICON hIcon;
+ WORD Status;
+ struct STATUSINFO_TYPE *next;
+}
+ STATUSINFO;
+
+typedef struct USERINFO_TYPE
+{
+ TCHAR* pszNick;
+ TCHAR* pszUID;
+ WORD Status;
+ int iStatusEx;
+ WORD ContactStatus;
+ struct USERINFO_TYPE *next;
+}
+ USERINFO;
+
+typedef struct TABLIST_TYPE
+{
+ TCHAR* pszID;
+ char* pszModule;
+ struct TABLIST_TYPE *next;
+}
+ TABLIST;
+
+typedef struct SESSION_INFO_TYPE
+{
+ HWND hWnd;
+
+ BOOL bFGSet;
+ BOOL bBGSet;
+ BOOL bFilterEnabled;
+ BOOL bNicklistEnabled;
+ BOOL bInitDone;
+
+ char* pszModule;
+ char* pszHeader;
+ TCHAR* ptszID;
+ TCHAR* ptszName;
+ TCHAR* ptszStatusbarText;
+ TCHAR* ptszTopic;
+
+ char* pszID; // ugly fix for returning static ANSI strings in GC_INFO
+ char* pszName; // just to fix a bug quickly, should die after porting IRC to Unicode
+
+ int iType;
+ int iFG;
+ int iBG;
+ int iSplitterY;
+ int desiredInputAreaHeight;
+ int iSplitterX;
+ int iLogFilterFlags;
+ int nUsersInNicklist;
+ int iEventCount;
+ int iStatusCount;
+
+ WORD wStatus;
+ WORD wState;
+ WORD wCommandsNum;
+ DWORD dwItemData;
+ DWORD dwFlags;
+ time_t LastTime;
+ CommonWindowData windowData;
+ LOGINFO* pLog;
+ LOGINFO* pLogEnd;
+ USERINFO* pUsers;
+ USERINFO* pMe;
+ STATUSINFO* pStatuses;
+ TCHAR szSearch[255];
+
+ struct SESSION_INFO_TYPE *next;
+
+}SESSION_INFO;
+
+typedef struct
+{
+ char* buffer;
+ int bufferOffset, bufferLen;
+ HWND hwnd;
+ LOGINFO* lin;
+ BOOL bStripFormat;
+ BOOL bRedraw;
+ BOOL isFirst;
+ SESSION_INFO* si;
+}
+ LOGSTREAMDATA;
+
+struct GlobalLogSettings_t {
+ BOOL ShowTime;
+ BOOL ShowTimeIfChanged;
+ BOOL LoggingEnabled;
+ BOOL FlashWindow;
+ BOOL HighlightEnabled;
+ BOOL LogIndentEnabled;
+ BOOL StripFormat;
+ BOOL SoundsFocus;
+ BOOL PopUpInactiveOnly;
+ BOOL TrayIconInactiveOnly;
+ BOOL AddColonToAutoComplete;
+ BOOL LogLimitNames;
+ BOOL TimeStampEventColour;
+ DWORD dwIconFlags;
+ DWORD dwTrayIconFlags;
+ DWORD dwPopupFlags;
+ int LogTextIndent;
+ int LoggingLimit;
+ int iEventLimit;
+ int iPopupStyle;
+ int iPopupTimeout;
+ int iSplitterX;
+ int iSplitterY;
+ TCHAR* pszTimeStamp;
+ TCHAR* pszTimeStampLog;
+ TCHAR* pszIncomingNick;
+ TCHAR* pszOutgoingNick;
+ TCHAR* pszHighlightWords;
+ TCHAR* pszLogDir;
+ HFONT UserListFont;
+ HFONT UserListHeadingsFont;
+ HFONT MessageBoxFont;
+ HFONT NameFont;
+ COLORREF crLogBackground;
+ COLORREF crUserListColor;
+ COLORREF crUserListBGColor;
+ COLORREF crUserListSelectedBGColor;
+ COLORREF crUserListHeadingsColor;
+ COLORREF crPUTextColour;
+ COLORREF crPUBkgColour;
+ BOOL ShowContactStatus;
+ BOOL ContactStatusFirst;
+};
+extern struct GlobalLogSettings_t g_Settings;
+
+typedef struct{
+ MODULEINFO* pModule;
+ int xPosition;
+ int yPosition;
+ HWND hWndTarget;
+ BOOL bForeground;
+ SESSION_INFO* si;
+}
+ COLORCHOOSER;
+
+//main.c
+void LoadIcons(void);
+void FreeIcons(void);
+void UpgradeCheck(void);
+
+//colorchooser.c
+INT_PTR CALLBACK DlgProcColorToolWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//log.c
+void Log_StreamInEvent(HWND hwndDlg, LOGINFO* lin, SESSION_INFO* si, BOOL bRedraw);
+void LoadMsgLogBitmaps(void);
+void FreeMsgLogBitmaps(void);
+TCHAR* GetChatLogsFilename (HANDLE hContact, time_t tTime);
+TCHAR* MakeTimeStamp(TCHAR* pszStamp, time_t time);
+char* Log_CreateRtfHeader(MODULEINFO * mi, SESSION_INFO* si);
+
+//window.c
+INT_PTR CALLBACK RoomWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
+int GetTextPixelSize( TCHAR* pszText, HFONT hFont, BOOL bWidth);
+
+//options.c
+int OptionsInit(void);
+int OptionsUnInit(void);
+void LoadGlobalSettings(void);
+void LoadLogFonts(void);
+void SetIndentSize();
+
+//services.c
+void HookEvents(void);
+void UnhookEvents(void);
+void CreateServiceFunctions(void);
+void DestroyServiceFunctions(void);
+void DestroyHookableEvents(void);
+void CreateHookableEvents(void);
+int Chat_ModulesLoaded(WPARAM wParam,LPARAM lParam);
+int Chat_FontsChanged(WPARAM wParam,LPARAM lParam);
+int Chat_SmileyOptionsChanged(WPARAM wParam,LPARAM lParam);
+int Chat_PreShutdown(WPARAM wParam,LPARAM lParam);
+int Chat_IconsChanged(WPARAM wParam,LPARAM lParam);
+void ShowRoom(SESSION_INFO* si, WPARAM wp, BOOL bSetForeground);
+
+//manager.c
+void SetActiveSession(const TCHAR* pszID, const char* pszModule);
+void SetActiveSessionEx(SESSION_INFO* si);
+SESSION_INFO* GetActiveSession(void);
+SESSION_INFO* SM_AddSession(const TCHAR* pszID, const char* pszModule);
+int SM_RemoveSession(const TCHAR* pszID, const char* pszModule, BOOL removeContact);
+SESSION_INFO* SM_FindSession(const TCHAR* pszID, const char* pszModule);
+HWND SM_FindWindowByContact(HANDLE hContact);
+USERINFO* SM_AddUser(SESSION_INFO* si, const TCHAR* pszUID, const TCHAR* pszNick, WORD wStatus);
+BOOL SM_ChangeUID(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszNewUID);
+BOOL SM_ChangeNick(const TCHAR* pszID, const char* pszModule, GCEVENT * gce);
+BOOL SM_RemoveUser(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID);
+BOOL SM_SetOffline(const TCHAR* pszID, const char* pszModule);
+HICON SM_GetStatusIcon(SESSION_INFO* si, USERINFO * ui);
+BOOL SM_SetStatus(const TCHAR* pszID, const char* pszModule, int wStatus);
+BOOL SM_SetStatusEx(const TCHAR* pszID, const char* pszModule, const TCHAR* pszText, int flags );
+BOOL SM_SendUserMessage(const TCHAR* pszID, const char* pszModule, const TCHAR* pszText);
+STATUSINFO* SM_AddStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszStatus);
+BOOL SM_AddEventToAllMatchingUID(GCEVENT * gce);
+BOOL SM_AddEvent(const TCHAR* pszID, const char* pszModule, GCEVENT * gce, BOOL bIsHighlighted);
+LRESULT SM_SendMessage(const TCHAR* pszID, const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL SM_PostMessage(const TCHAR* pszID, const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL SM_BroadcastMessage(const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAsync);
+BOOL SM_RemoveAll (void);
+BOOL SM_GiveStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszStatus);
+BOOL SM_SetContactStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, WORD pszStatus);
+BOOL SM_TakeStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszStatus);
+BOOL SM_MoveUser(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID);
+int SM_GetCount(const char* pszModule);
+SESSION_INFO* SM_FindSessionByIndex(const char* pszModule, int iItem);
+char* SM_GetUsers(SESSION_INFO* si);
+USERINFO* SM_GetUserFromIndex(const TCHAR* pszID, const char* pszModule, int index);
+char SM_GetStatusIndicator(SESSION_INFO* si, USERINFO * ui);
+SESSION_INFO* SM_FindSessionAutoComplete(const char* pszModule, SESSION_INFO* currSession, SESSION_INFO* prevSession, const TCHAR* pszOriginal, const TCHAR* pszCurrent);
+MODULEINFO* MM_AddModule(const char* pszModule);
+MODULEINFO* MM_FindModule(const char* pszModule);
+void MM_FixColors();
+void MM_FontsChanged(void);
+void MM_IconsChanged(void);
+BOOL MM_RemoveAll (void);
+BOOL TabM_AddTab(const TCHAR* pszID, const char* pszModule);
+BOOL TabM_RemoveAll (void);
+STATUSINFO* TM_AddStatus(STATUSINFO** ppStatusList, const TCHAR* pszStatus, int* iCount);
+STATUSINFO* TM_FindStatus(STATUSINFO* pStatusList, const TCHAR* pszStatus);
+WORD TM_StringToWord(STATUSINFO* pStatusList, const TCHAR* pszStatus);
+TCHAR* TM_WordToString(STATUSINFO* pStatusList, WORD Status);
+BOOL TM_RemoveAll (STATUSINFO** pStatusList);
+BOOL UM_SetStatusEx(USERINFO* pUserList,const TCHAR* pszText, int onlyMe );
+USERINFO* UM_AddUser(STATUSINFO* pStatusList, USERINFO** pUserList, const TCHAR* pszUID, const TCHAR* pszNick, WORD wStatus);
+USERINFO* UM_SortUser(USERINFO** ppUserList, const TCHAR* pszUID);
+USERINFO* UM_FindUser(USERINFO* pUserList, const TCHAR* pszUID);
+USERINFO* UM_FindUserFromIndex(USERINFO* pUserList, int index);
+USERINFO* UM_GiveStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status);
+USERINFO* UM_SetContactStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status);
+USERINFO* UM_TakeStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status);
+TCHAR* UM_FindUserAutoComplete(USERINFO* pUserList, const TCHAR* pszOriginal, const TCHAR* pszCurrent);
+BOOL UM_RemoveUser(USERINFO** pUserList, const TCHAR* pszUID);
+BOOL UM_RemoveAll (USERINFO** ppUserList);
+LOGINFO* LM_AddEvent(LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd);
+BOOL LM_TrimLog(LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd, int iCount);
+BOOL LM_RemoveAll (LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd);
+
+//clist.c
+HANDLE CList_AddRoom(const char* pszModule, const TCHAR* pszRoom, const TCHAR* pszDisplayName, int iType);
+BOOL CList_SetOffline(HANDLE hContact, BOOL bHide);
+BOOL CList_SetAllOffline(BOOL bHide, const char *pszModule);
+int CList_RoomDoubleclicked(WPARAM wParam,LPARAM lParam);
+int CList_EventDoubleclicked(WPARAM wParam,LPARAM lParam);
+INT_PTR CList_EventDoubleclickedSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR CList_JoinChat(WPARAM wParam, LPARAM lParam);
+INT_PTR CList_LeaveChat(WPARAM wParam, LPARAM lParam);
+INT_PTR CList_PrebuildContactMenuSvc(WPARAM wParam, LPARAM lParam);
+int CList_PrebuildContactMenu(WPARAM wParam, LPARAM lParam);
+void CList_CreateGroup(TCHAR* group);
+BOOL CList_AddEvent(HANDLE hContact, HICON Icon, HANDLE event, int type, TCHAR* fmt, ... ) ;
+HANDLE CList_FindRoom (const char* pszModule, const TCHAR* pszRoom) ;
+int WCCmp(TCHAR* wild, TCHAR*string);
+
+//tools.c
+TCHAR* RemoveFormatting(const TCHAR* pszText);
+BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO* si, GCEVENT * gce, BOOL bHighlight, int bManyFix);
+int GetColorIndex(const char* pszModule, COLORREF cr);
+void CheckColorsInModule(const char* pszModule);
+TCHAR* my_strstri(const TCHAR* s1, const TCHAR* s2) ;
+BOOL IsHighlighted(SESSION_INFO* si, const TCHAR* pszText);
+UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO* si, TCHAR* pszUID, TCHAR* pszWordText);
+void DestroyGCMenu(HMENU *hMenu, int iIndex);
+BOOL DoEventHookAsync(HWND hwnd, const TCHAR* pszID, const char* pszModule, int iType, TCHAR* pszUID, TCHAR* pszText, DWORD dwItem);
+BOOL DoEventHook(const TCHAR* pszID, const char* pszModule, int iType, const TCHAR* pszUID, const TCHAR* pszText, DWORD dwItem);
+BOOL IsEventSupported(int eventType);
+BOOL LogToFile(SESSION_INFO* si, GCEVENT * gce);
+
+// message.c
+TCHAR* DoRtfToTags( char* pszRtfText, SESSION_INFO* si);
+
+//////////////////////////////////////////////////////////////////////////////////
+
+TCHAR* a2tf( const TCHAR* str, int flags );
+TCHAR* replaceStr( TCHAR** dest, const TCHAR* src );
+char* replaceStrA( char** dest, const char* src );
+
+#define DEFLOGFILENAME _T("%miranda_logpath%\\%proto%\\%userid%.log")
+#endif
diff --git a/plugins/Scriver/src/chat/clist.cpp b/plugins/Scriver/src/chat/clist.cpp new file mode 100644 index 0000000000..2c32bc7169 --- /dev/null +++ b/plugins/Scriver/src/chat/clist.cpp @@ -0,0 +1,364 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+
+extern HANDLE hJoinMenuItem, hLeaveMenuItem;
+
+HANDLE CList_AddRoom(const char* pszModule, const TCHAR* pszRoom, const TCHAR* pszDisplayName, int iType)
+{
+ HANDLE hContact = CList_FindRoom(pszModule, pszRoom);
+ DBVARIANT dbv;
+ TCHAR pszGroup[50];
+
+ *pszGroup = '\0';
+ if ( !DBGetContactSettingTString( NULL, "Chat", "AddToGroup", &dbv )) {
+ if ( lstrlen( dbv.ptszVal ) > 0 )
+ lstrcpyn( pszGroup, dbv.ptszVal, 50);
+ DBFreeVariant(&dbv);
+ }
+ else lstrcpyn( pszGroup, _T("Chat rooms"), 50);
+
+ if ( pszGroup[0] )
+ CList_CreateGroup(pszGroup);
+
+ if ( hContact ) { //contact exist, make sure it is in the right group
+ DBVARIANT dbv;
+ DBVARIANT dbv2;
+ char str[50];
+ int i;
+
+ if ( pszGroup[0] ) {
+ for (i = 0;; i++) {
+ _itoa(i, str, 10);
+ if ( DBGetContactSettingTString( NULL, "CListGroups", str, &dbv )) {
+ DBWriteContactSettingTString(hContact, "CList", "Group", pszGroup);
+ goto END_GROUPLOOP;
+ }
+
+ if ( !DBGetContactSettingTString( hContact, "CList", "Group", &dbv2 )) {
+ if ( dbv.ptszVal[0] != '\0' && dbv2.ptszVal[0] != '\0' && !lstrcmpi( dbv.ptszVal + 1, dbv2.ptszVal )) {
+ DBFreeVariant(&dbv);
+ DBFreeVariant(&dbv2);
+ goto END_GROUPLOOP;
+ }
+ DBFreeVariant(&dbv2);
+ }
+ DBFreeVariant(&dbv);
+ } }
+
+END_GROUPLOOP:
+ DBWriteContactSettingWord(hContact, pszModule, "Status", ID_STATUS_OFFLINE);
+ DBWriteContactSettingTString(hContact, pszModule, "Nick", pszDisplayName );
+/* if (iType != GCW_SERVER)
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);*/
+ return hContact;
+ }
+
+ // here we create a new one since no one is to be found
+ if (( hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0)) == NULL )
+ return NULL;
+
+ CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) pszModule);
+ if ( lstrlen( pszGroup ) > 0 )
+ DBWriteContactSettingTString(hContact, "CList", "Group", pszGroup );
+ else
+ DBDeleteContactSetting(hContact, "CList", "Group");
+ DBWriteContactSettingTString( hContact, pszModule, "Nick", pszDisplayName );
+ DBWriteContactSettingTString( hContact, pszModule, "ChatRoomID", pszRoom );
+ DBWriteContactSettingByte(hContact, pszModule, "ChatRoom", (BYTE)iType);
+ DBWriteContactSettingWord(hContact, pszModule, "Status", ID_STATUS_OFFLINE);
+// if (iType == GCW_SERVER)
+ // DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
+ return hContact;
+ }
+
+BOOL CList_SetOffline(HANDLE hContact, BOOL bHide)
+{
+ if ( hContact ) {
+ char * szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ DBWriteContactSettingWord(hContact, szProto,"ApparentMode",(LPARAM) 0);
+ DBWriteContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+/*
+ int i = DBGetContactSettingByte(hContact, szProto, "ChatRoom", 0);
+ if (bHide && i != GCW_SERVER)
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);*/
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL CList_SetAllOffline(BOOL bHide, const char *pszModule)
+{
+ HANDLE hContact;
+ char * szProto;
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while ( hContact ) {
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if ( MM_FindModule( szProto )) {
+ if (!pszModule || (pszModule && !strcmp(pszModule, szProto))) {
+ int i = DBGetContactSettingByte(hContact, szProto, "ChatRoom", 0);
+ if ( i != 0 ) {
+ DBWriteContactSettingWord(hContact, szProto,"ApparentMode",(LPARAM)(WORD) 0);
+ DBWriteContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+/* if (bHide && i == GCW_CHATROOM)
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);*/
+ }
+ }
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ return TRUE;
+}
+
+int CList_RoomDoubleclicked(WPARAM wParam,LPARAM lParam)
+{
+ DBVARIANT dbv;
+ char *szProto;
+
+ HANDLE hContact = (HANDLE)wParam;
+ if (!hContact)
+ return 0;
+
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if ( MM_FindModule(szProto)) {
+ if (DBGetContactSettingByte(hContact, szProto, "ChatRoom", 0) == 0)
+ return 0;
+
+ if ( !DBGetContactSettingTString( hContact, szProto, "ChatRoomID", &dbv )) {
+ SESSION_INFO* si = SM_FindSession( dbv.ptszVal, szProto );
+ if ( si ) {
+ // is the "toggle visibility option set, so we need to close the window?
+ if (si->hWnd != NULL
+ && DBGetContactSettingByte(NULL, "Chat", "ToggleVisibility", 0)==1
+ && !CallService(MS_CLIST_GETEVENT, (WPARAM)hContact, 0)
+ && IsWindowVisible(si->hWnd)
+ && !IsIconic(si->hWnd))
+ {
+ PostMessage(si->hWnd, GC_CLOSEWINDOW, 0, 0);
+ DBFreeVariant(&dbv);
+ return 1;
+ }
+ ShowRoom(si, WINDOW_VISIBLE, TRUE);
+ }
+ DBFreeVariant(&dbv);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int CList_EventDoubleclicked(WPARAM wParam,LPARAM lParam)
+{
+ return CList_RoomDoubleclicked((WPARAM) ((CLISTEVENT*)lParam)->hContact,(LPARAM) 0);
+}
+
+INT_PTR CList_EventDoubleclickedSvc(WPARAM wParam,LPARAM lParam)
+{
+ return CList_EventDoubleclicked(wParam, lParam);
+}
+
+INT_PTR CList_JoinChat(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if ( hContact ) {
+ char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if ( szProto ) {
+ if ( DBGetContactSettingWord( hContact, szProto, "Status", 0 ) == ID_STATUS_OFFLINE )
+ CallProtoService( szProto, PS_JOINCHAT, wParam, lParam );
+ else
+ CList_RoomDoubleclicked( wParam, 0 );
+ } }
+
+ return 0;
+}
+
+INT_PTR CList_LeaveChat(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if ( hContact ) {
+ char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if ( szProto )
+ CallProtoService( szProto, PS_LEAVECHAT, wParam, lParam );
+ }
+ return 0;
+}
+
+int CList_PrebuildContactMenu(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if ( hContact ) {
+ char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(CLISTMENUITEM);
+ clmi.flags = CMIM_FLAGS | CMIF_DEFAULT | CMIF_HIDDEN;
+
+ if ( szProto ) {
+ // display this menu item only for chats
+ if ( DBGetContactSettingByte( hContact, szProto, "ChatRoom", 0 )) {
+ // still hide it for offline protos
+ if ( CallProtoService( szProto, PS_GETSTATUS, 0, 0 ) != ID_STATUS_OFFLINE ) {
+ clmi.flags &= ~CMIF_HIDDEN;
+ clmi.flags |= CMIM_NAME;
+
+ if ( DBGetContactSettingWord( hContact, szProto, "Status", 0 ) == ID_STATUS_OFFLINE )
+ clmi.pszName = ( char* )LPGEN("Join chat");
+ else
+ clmi.pszName = ( char* )LPGEN("Open chat window");
+ } } }
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hJoinMenuItem, ( LPARAM )&clmi );
+
+ clmi.flags &= ~(CMIM_NAME | CMIF_DEFAULT);
+ clmi.flags |= CMIF_NOTOFFLINE;
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hLeaveMenuItem, ( LPARAM )&clmi );
+ }
+ return 0;
+}
+
+INT_PTR CList_PrebuildContactMenuSvc(WPARAM wParam, LPARAM lParam)
+{
+ return CList_PrebuildContactMenu(wParam, lParam);
+}
+
+void CList_CreateGroup(TCHAR* group)
+{
+ int i;
+ char str[50];
+ TCHAR name[256];
+ DBVARIANT dbv;
+
+ if (!group)
+ return;
+
+ for (i = 0;; i++)
+ {
+ _itoa(i, str, 10);
+ if ( DBGetContactSettingTString( NULL, "CListGroups", str, &dbv ))
+ break;
+
+ if ( dbv.pszVal[0] != '\0' && !lstrcmpi(dbv.ptszVal + 1, group)) {
+ DBFreeVariant(&dbv);
+ return;
+ }
+
+ DBFreeVariant(&dbv);
+ }
+
+ // CallService(MS_CLIST_GROUPCREATE, (WPARAM)group, 0);
+ name[0] = 1 | GROUPF_EXPANDED;
+ _tcsncpy(name + 1, group, SIZEOF(name) - 1);
+ name[ lstrlen(group) + 1] = '\0';
+ DBWriteContactSettingTString(NULL, "CListGroups", str, name);
+ CallService(MS_CLUI_GROUPADDED, i + 1, 0);
+}
+
+BOOL CList_AddEvent(HANDLE hContact, HICON Icon, HANDLE event, int type, TCHAR* fmt, ... )
+{
+ CLISTEVENT cle;
+ va_list marker;
+ TCHAR* szBuf = (TCHAR*)alloca(4096 * sizeof(TCHAR));
+
+ if (!fmt || lstrlen(fmt) < 1 || lstrlen(fmt) > 2000)
+ return FALSE;
+
+ va_start(marker, fmt);
+ _vsntprintf(szBuf, 4096, fmt, marker);
+ va_end(marker);
+
+ cle.cbSize=sizeof(cle);
+ cle.hContact=(HANDLE)hContact;
+ cle.hDbEvent=(HANDLE)event;
+ cle.flags = type | CLEF_TCHAR;
+ cle.hIcon=Icon;
+ cle.pszService= "GChat/DblClickEvent" ;
+ cle.ptszTooltip = TranslateTS(szBuf);
+ if ( type ) {
+ if (!CallService(MS_CLIST_GETEVENT, (WPARAM)hContact, (LPARAM)0))
+ CallService(MS_CLIST_ADDEVENT,(WPARAM) hContact,(LPARAM) &cle);
+ } else {
+ if (CallService(MS_CLIST_GETEVENT, (WPARAM)hContact, (LPARAM)0))
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)event);
+ CallService(MS_CLIST_ADDEVENT,(WPARAM) hContact,(LPARAM) &cle);
+ }
+ return TRUE;
+}
+
+HANDLE CList_FindRoom ( const char* pszModule, const TCHAR* pszRoom)
+{
+ HANDLE hContact = ( HANDLE )CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) {
+ char* szProto = ( char* )CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0 );
+ if ( szProto && !lstrcmpiA( szProto, pszModule )) {
+ if ( DBGetContactSettingByte( hContact, szProto, "ChatRoom", 0) != 0 ) {
+ DBVARIANT dbv;
+ if ( !DBGetContactSettingTString( hContact, szProto, "ChatRoomID", &dbv )) {
+ if ( !lstrcmpi(dbv.ptszVal, pszRoom)) {
+ DBFreeVariant(&dbv);
+ return hContact;
+ }
+ DBFreeVariant(&dbv);
+ } } }
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ return 0;
+}
+
+int WCCmp(TCHAR* wild, TCHAR* string)
+{
+ TCHAR *cp = NULL, *mp = NULL;
+ if ( wild == NULL || !lstrlen(wild) || string == NULL || !lstrlen(string))
+ return 0;
+
+ while ((*string) && (*wild != '*')) {
+ if ((*wild != *string) && (*wild != '?'))
+ return 0;
+
+ wild++;
+ string++;
+ }
+
+ while (*string) {
+ if (*wild == '*') {
+ if (!*++wild)
+ return 1;
+
+ mp = wild;
+ cp = string+1;
+ }
+ else if ((*wild == *string) || (*wild == '?')) {
+ wild++;
+ string++;
+ }
+ else {
+ wild = mp;
+ string = cp++;
+ } }
+
+ while (*wild == '*')
+ wild++;
+
+ return !*wild;
+}
diff --git a/plugins/Scriver/src/chat/colorchooser.cpp b/plugins/Scriver/src/chat/colorchooser.cpp new file mode 100644 index 0000000000..67dc78a90d --- /dev/null +++ b/plugins/Scriver/src/chat/colorchooser.cpp @@ -0,0 +1,279 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+// this color chooser window is inspired by PeaCow's smiley chooser window for the Smileyadd plugin
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include <math.h>
+
+static int CalculateCoordinatesToButton(COLORCHOOSER * pCC, POINT pt)
+{
+ int iSquareRoot = (int)sqrt((double)pCC->pModule->nColorCount);
+ int nCols = iSquareRoot * iSquareRoot < pCC->pModule->nColorCount?iSquareRoot+1:iSquareRoot;
+
+ int col = pt.x / 25;
+ int row = (pt.y-20) / 20;
+ int pos = nCols * row + col;
+
+ if (pt.y < 20 && pos >= pCC->pModule->nColorCount)
+ pos = -1;
+
+ return pos;
+}
+
+static RECT CalculateButtonToCoordinates(COLORCHOOSER * pCC, int buttonPosition)
+{
+ RECT pt;
+ int iSquareRoot = (int)sqrt((double)pCC->pModule->nColorCount);
+ int nCols = iSquareRoot * iSquareRoot < pCC->pModule->nColorCount?iSquareRoot+1:iSquareRoot;
+
+ int row = buttonPosition / nCols;
+ int col = buttonPosition % nCols;
+
+ pt.left = col * 25+1;
+ pt.top = row * 20 + 20;
+ pt.right = pt.left + 25-1;
+ pt.bottom = pt.top + 20;
+
+ return pt;
+}
+
+INT_PTR CALLBACK DlgProcColorToolWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static COLORCHOOSER* pCC = NULL;
+ static int iCurrentHotTrack;
+ static BOOL bChoosing;
+ static int iRows;
+ static int iColumns;
+ static HWND hPreviousActiveWindow;
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ RECT rc;
+ int iSquareRoot;
+ int width ;
+ int height;
+
+ TranslateDialogDefault(hwndDlg);
+ pCC = (COLORCHOOSER*) lParam;
+
+ iCurrentHotTrack = -2;
+ bChoosing = FALSE;
+
+ iSquareRoot = (int)sqrt((double)pCC->pModule->nColorCount);
+
+ iColumns = iSquareRoot * iSquareRoot == pCC->pModule->nColorCount?iSquareRoot:iSquareRoot+1;
+ iRows = iSquareRoot;
+
+ rc.top = rc.left = 100;
+ rc.right = 100 + iColumns * 25 + 1;
+ rc.bottom = iRows * 20 + 100 + 20;
+
+ AdjustWindowRectEx(&rc, GetWindowLongPtr(hwndDlg, GWL_STYLE), FALSE, GetWindowLongPtr(hwndDlg, GWL_EXSTYLE));
+
+ width = rc.right - rc.left;
+ height = rc.bottom - rc.top;
+
+ pCC->yPosition -= height;
+
+
+ SetDlgItemText(hwndDlg, IDC_CHAT_COLORTEXT, pCC->bForeground?TranslateT("Text colour"):TranslateT("Background colour"));
+ SetWindowPos(GetDlgItem(hwndDlg, IDC_CHAT_COLORTEXT), NULL, 0, 0, width, 20, 0);
+ SetWindowPos(hwndDlg, NULL, pCC->xPosition, pCC->yPosition, width, height, SWP_SHOWWINDOW);
+ }
+ break;
+
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ if ((HWND)lParam==GetDlgItem(hwndDlg,IDC_CHAT_COLORTEXT)) {
+ SetTextColor((HDC)wParam,RGB(60,60,150));
+ SetBkColor((HDC)wParam,GetSysColor(COLOR_WINDOW));
+ return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
+ }
+ break;
+
+ case WM_COMMAND:
+ switch ( LOWORD( wParam )) {
+ case IDOK:
+ if (iCurrentHotTrack >= 0)
+ PostMessage(hwndDlg, WM_LBUTTONUP, 0, 0);
+ break;
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ if (iCurrentHotTrack >= 0 && iCurrentHotTrack < pCC->pModule->nColorCount && pCC->hWndTarget != NULL) {
+ HWND hWindow;
+ CHARFORMAT2 cf;
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwMask = 0;
+ cf.dwEffects = 0;
+ hWindow = GetParent(pCC->hWndTarget);
+
+ if ( pCC->bForeground ) {
+ pCC->si->bFGSet = TRUE;
+ pCC->si->iFG = iCurrentHotTrack;
+ if ( IsDlgButtonChecked( hWindow, IDC_CHAT_COLOR )) {
+ cf.dwMask = CFM_COLOR;
+ cf.crTextColor = pCC->pModule->crColors[iCurrentHotTrack];
+ if (pCC->pModule->bSingleFormat) {
+ SendMessage(pCC->hWndTarget, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendMessage(pCC->hWndTarget, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ }
+ }
+ else {
+ pCC->si->bBGSet = TRUE;
+ pCC->si->iBG = iCurrentHotTrack;
+ if (IsDlgButtonChecked(hWindow, IDC_CHAT_BKGCOLOR)) {
+ cf.dwMask = CFM_BACKCOLOR;
+ cf.crBackColor = pCC->pModule->crColors[iCurrentHotTrack];
+ if (pCC->pModule->bSingleFormat) {
+ SendMessage(pCC->hWndTarget, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendMessage(pCC->hWndTarget, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ }
+ }
+ }
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+
+ case WM_ACTIVATE:
+ if (wParam == WA_INACTIVE)
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ else if ((wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE))
+ hPreviousActiveWindow = (HWND)lParam;
+ break;
+
+ case WM_MOUSEMOVE:
+ {
+ HDC hdc = GetDC(hwndDlg);
+ POINT pt;
+ RECT rect;
+ int but;
+
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+
+ if (iCurrentHotTrack == -2)
+ return 0; // prevent focussing when not drawn yet!
+
+ but = CalculateCoordinatesToButton(pCC, pt);
+
+ // weird stuff
+ if (but != iCurrentHotTrack) {
+ if (iCurrentHotTrack >= 0) {
+ rect = CalculateButtonToCoordinates(pCC, iCurrentHotTrack);
+ DrawFocusRect(hdc, &rect);
+ iCurrentHotTrack = -1;
+ }
+ iCurrentHotTrack = but;
+
+ if (iCurrentHotTrack >= 0) {
+ rect = CalculateButtonToCoordinates(pCC, iCurrentHotTrack);
+ DrawFocusRect(hdc, &rect);
+ }
+ }
+ ReleaseDC(hwndDlg, hdc);
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdc;
+ RECT rc;
+ int i;
+ int iThisRow = 1;
+ int iThisColumn = 0;
+
+ GetClientRect(hwndDlg, &rc);
+
+ rc.top += 20;
+
+ hdc = BeginPaint(hwndDlg, &ps);
+
+ // fill background
+ FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
+
+ for (i=0; i < pCC->pModule->nColorCount; i++)
+ {
+ HBRUSH hbr;
+
+ // decide place to draw the color block in the window
+ iThisColumn ++;
+ if (iThisColumn > iColumns) {
+ iThisColumn = 1;
+ iThisRow++;
+ }
+
+ if ( (pCC->bForeground && pCC->si->bFGSet && pCC->si->iFG == i) ||
+ (!pCC->bForeground && pCC->si->bBGSet && pCC->si->iBG == i)) {
+ rc.top = (iThisRow-1) * 20+ 1 +20 ;
+ rc.left = (iThisColumn-1) * 25 + 1 + 1 ;
+ rc.bottom = iThisRow * 20- 1 + 20 ;
+ rc.right = iThisColumn * 25-1 ;
+
+ DrawEdge(hdc, &rc, EDGE_RAISED, BF_TOP|BF_LEFT|BF_RIGHT|BF_BOTTOM);
+ }
+
+ rc.top = (iThisRow-1) * 20+ 3 +20 ;
+ rc.left = (iThisColumn-1) * 25 + 3 + 1 ;
+ rc.bottom = iThisRow * 20- 3 + 20 ;
+ rc.right = iThisColumn * 25-3 ;
+
+ FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
+
+ hbr = CreateSolidBrush(pCC->pModule->crColors[i]);
+
+ rc.top = (iThisRow-1) * 20+4 +20;
+ rc.left = (iThisColumn-1) * 25+ 4 + 1;
+ rc.bottom = iThisRow * 20-4 + 20;
+ rc.right = iThisColumn * 25-4;
+
+ FillRect(hdc, &rc, hbr);
+ DeleteObject(hbr);
+ }
+
+ EndPaint(hwndDlg, &ps);
+ iCurrentHotTrack = -1;
+ }
+ break;
+
+ case WM_CLOSE:
+ SetFocus(pCC->hWndTarget);
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ mir_free( pCC );
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/plugins/Scriver/src/chat/log.cpp b/plugins/Scriver/src/chat/log.cpp new file mode 100644 index 0000000000..a7fc260fd1 --- /dev/null +++ b/plugins/Scriver/src/chat/log.cpp @@ -0,0 +1,981 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include <math.h>
+#include <mbstring.h>
+#include <shlwapi.h>
+
+
+#ifndef EM_GETSCROLLPOS
+#define EM_GETSCROLLPOS (WM_USER+221)
+#endif
+// The code for streaming the text is to a large extent copied from
+// the srmm module and then modified to fit the chat module.
+
+extern FONTINFO aFonts[OPTIONS_FONTCOUNT];
+
+static PBYTE pLogIconBmpBits[14];
+static const char *logIconNames[14] = {
+ "chat_log_action", "chat_log_addstatus", "chat_log_highlight", "chat_log_info", "chat_log_join",
+ "chat_log_kick", "chat_log_message_in", "chat_log_message_out", "chat_log_nick", "chat_log_notice",
+ "chat_log_part", "chat_log_quit", "chat_log_removestatus", "chat_log_topic"
+};
+static int logIconBmpSize[ SIZEOF(pLogIconBmpBits) ];
+
+static int EventToIndex(LOGINFO * lin)
+{
+ switch (lin->iType) {
+ case GC_EVENT_MESSAGE:
+ if (lin->bIsMe)
+ return 10;
+ else
+ return 9;
+
+ case GC_EVENT_JOIN: return 3;
+ case GC_EVENT_PART: return 4;
+ case GC_EVENT_QUIT: return 5;
+ case GC_EVENT_NICK: return 7;
+ case GC_EVENT_KICK: return 6;
+ case GC_EVENT_NOTICE: return 8;
+ case GC_EVENT_TOPIC: return 11;
+ case GC_EVENT_INFORMATION:return 12;
+ case GC_EVENT_ADDSTATUS: return 13;
+ case GC_EVENT_REMOVESTATUS: return 14;
+ case GC_EVENT_ACTION: return 15;
+ }
+ return 0;
+}
+
+static int EventToIcon(LOGINFO * lin)
+{
+ switch (lin->iType) {
+ case GC_EVENT_MESSAGE:
+ if (lin->bIsMe)
+ return 7;
+ else
+ return 6;
+
+ case GC_EVENT_JOIN: return 4;
+ case GC_EVENT_PART: return 10;
+ case GC_EVENT_QUIT: return 11;
+ case GC_EVENT_NICK: return 8;
+ case GC_EVENT_KICK: return 5;
+ case GC_EVENT_NOTICE: return 9;
+ case GC_EVENT_TOPIC: return 13;
+ case GC_EVENT_INFORMATION:return 3;
+ case GC_EVENT_ADDSTATUS: return 1;
+ case GC_EVENT_REMOVESTATUS: return 12;
+ case GC_EVENT_ACTION: return 0;
+ }
+ return 0;
+}
+
+static char *Log_SetStyle(int style, int fontindex)
+{
+ static char szStyle[128];
+ mir_snprintf(szStyle, SIZEOF(szStyle), "\\f%u\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", style, style+1, aFonts[fontindex].lf.lfWeight >= FW_BOLD ? 1 : 0, aFonts[fontindex].lf.lfItalic, 2 * abs(aFonts[fontindex].lf.lfHeight) * 74 / g_dat->logPixelSY);
+ return szStyle;
+}
+
+static int Log_AppendRTF(LOGSTREAMDATA* streamData, BOOL simpleMode, char **buffer, int *cbBufferEnd, int *cbBufferAlloced, const TCHAR *fmt, ...)
+{
+ va_list va;
+ int lineLen, textCharsCount=0;
+ TCHAR* line = (TCHAR*)alloca( 8001*sizeof(TCHAR));
+ char* d;
+
+ va_start(va, fmt);
+ lineLen = _vsntprintf( line, 8000, fmt, va);
+ if (lineLen < 0) lineLen = 8000;
+ line[lineLen] = 0;
+ va_end(va);
+
+ lineLen = lineLen*20 + 8;
+ if (*cbBufferEnd + lineLen > *cbBufferAlloced) {
+ cbBufferAlloced[0] += (lineLen + 1024 - lineLen % 1024);
+ *buffer = (char *) mir_realloc(*buffer, *cbBufferAlloced);
+ }
+
+ d = *buffer + *cbBufferEnd;
+
+ for (; *line; line++, textCharsCount++) {
+ if (*line == '\r' && line[1] == '\n') {
+ CopyMemory(d, "\\par ", 5);
+ line++;
+ d += 5;
+ }
+ else if (*line == '\n') {
+ CopyMemory(d, "\\line ", 6);
+ d += 6;
+ }
+ else if (*line == '%' && !simpleMode ) {
+ char szTemp[200];
+
+ szTemp[0] = '\0';
+ switch ( *++line ) {
+ case '\0':
+ case '%':
+ *d++ = '%';
+ break;
+
+ case 'c':
+ case 'f':
+ if (g_Settings.StripFormat || streamData->bStripFormat) {
+ line += 2;
+ }
+ else if ( line[1] != '\0' && line[2] != '\0') {
+ TCHAR szTemp3[3], c = *line;
+ int col;
+ szTemp3[0] = line[1];
+ szTemp3[1] = line[2];
+ szTemp3[2] = '\0';
+ line += 2;
+
+ col = _ttoi(szTemp3);
+ col += (OPTIONS_FONTCOUNT + 1);
+ mir_snprintf(szTemp, SIZEOF(szTemp), ( c == 'c' ) ? "\\cf%u " : "\\highlight%u ", col);
+ }
+ break;
+ case 'C':
+ case 'F':
+ if ( !g_Settings.StripFormat && !streamData->bStripFormat) {
+ int j = streamData->lin->bIsHighlighted ? 16 : EventToIndex(streamData->lin);
+ if ( *line == 'C' )
+ mir_snprintf(szTemp, SIZEOF(szTemp), "\\cf%u ", j+1);
+ else
+ mir_snprintf(szTemp, SIZEOF(szTemp), "\\highlight0 ");
+ }
+ break;
+ case 'b':
+ case 'u':
+ case 'i':
+ if ( !streamData->bStripFormat ) {
+ mir_snprintf(szTemp, SIZEOF(szTemp), (*line == 'u') ? "\\%cl " : "\\%c ", *line );
+ }
+ break;
+
+ case 'B':
+ case 'U':
+ case 'I':
+ if ( !streamData->bStripFormat ) {
+ mir_snprintf( szTemp, SIZEOF(szTemp), (*line == 'U') ? "\\%cl0 " : "\\%c0 ", *line );
+ CharLowerA( szTemp );
+ }
+ break;
+
+ case 'r':
+ if ( !streamData->bStripFormat ) {
+ int index = EventToIndex(streamData->lin);
+ mir_snprintf(szTemp, SIZEOF(szTemp), "%s ", Log_SetStyle(index, index));
+ }
+ break;
+ }
+
+ if ( szTemp[0] ) {
+ int iLen = lstrlenA(szTemp);
+ memcpy( d, szTemp, iLen );
+ d += iLen;
+ }
+ }
+ else if (*line == '\t' && !streamData->bStripFormat) {
+ CopyMemory(d, "\\tab ", 5);
+ d += 5;
+ }
+ else if ((*line == '\\' || *line == '{' || *line == '}') && !streamData->bStripFormat) {
+ *d++ = '\\';
+ *d++ = (char) *line;
+ }
+ else if (*line > 0 && *line < 128) {
+ *d++ = (char) *line;
+ } else {
+ d += sprintf(d, "\\u%u ?", (WORD)*line);
+ }
+ }
+
+ *cbBufferEnd = (int) (d - *buffer);
+ return textCharsCount;
+}
+
+static int Log_AppendIEView(LOGSTREAMDATA* streamData, BOOL simpleMode, TCHAR **buffer, int *cbBufferEnd, int *cbBufferAlloced, const TCHAR *fmt, ...)
+{
+ va_list va;
+ int lineLen, textCharsCount=0;
+ TCHAR* line = (TCHAR*)alloca( 8001 * sizeof(TCHAR));
+ TCHAR* d;
+ MODULEINFO *mi = MM_FindModule(streamData->si->pszModule);
+
+ va_start(va, fmt);
+ lineLen = _vsntprintf( line, 8000, fmt, va);
+ if (lineLen < 0)
+ return 0;
+ line[lineLen] = 0;
+ va_end(va);
+
+ lineLen = lineLen*9 + 8;
+ if (*cbBufferEnd + lineLen > *cbBufferAlloced) {
+ cbBufferAlloced[0] += (lineLen + 1024 - lineLen % 1024);
+ *buffer = (TCHAR *) mir_realloc(*buffer, *cbBufferAlloced * sizeof(TCHAR));
+ }
+
+ d = *buffer + *cbBufferEnd;
+
+ for (; *line; line++, textCharsCount++) {
+ if (*line == '%' && !simpleMode ) {
+ TCHAR szTemp[200];
+
+ szTemp[0] = '\0';
+ switch ( *++line ) {
+ case '\0':
+ case '%':
+ *d++ = '%';
+ break;
+
+ case 'c':
+ case 'f':
+ if (!g_Settings.StripFormat && !streamData->bStripFormat) {
+ if ( line[1] != '\0' && line[2] != '\0') {
+ TCHAR szTemp3[3], c = *line;
+ int col;
+ szTemp3[0] = line[1];
+ szTemp3[1] = line[2];
+ szTemp3[2] = '\0';
+ col = _ttoi(szTemp3);
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%%%c#%02X%02X%02X"), c, GetRValue(mi->crColors[col]), GetGValue(mi->crColors[col]), GetBValue(mi->crColors[col]));
+ }
+ }
+ line += 2;
+ break;
+ case 'C':
+ case 'F':
+ if ( !g_Settings.StripFormat && !streamData->bStripFormat) {
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%%%c"), *line );
+ }
+ break;
+ case 'b':
+ case 'u':
+ case 'i':
+ case 'B':
+ case 'U':
+ case 'I':
+ case 'r':
+ if ( !streamData->bStripFormat ) {
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%%%c"), *line );
+ }
+ break;
+ }
+
+ if ( szTemp[0] ) {
+ size_t iLen = _tcslen(szTemp);
+ memcpy( d, szTemp, iLen * sizeof(TCHAR));
+ d += iLen;
+ }
+ }
+ else if (*line == '%') {
+ *d++ = '%';
+ *d++ = (char) *line;
+ }
+ else {
+ *d++ = (char) *line;
+ }
+ }
+ *d = '\0';
+ *cbBufferEnd = (int) (d - *buffer);
+ return textCharsCount;
+}
+
+
+static void AddEventTextToBuffer(char **buffer, int *bufferEnd, int *bufferAlloced, LOGSTREAMDATA *streamData)
+{
+ if (streamData->lin->ptszText)
+ Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T(": %s"), streamData->lin->ptszText);
+}
+
+static void AddEventToBuffer(char **buffer, int *bufferEnd, int *bufferAlloced, LOGSTREAMDATA *streamData, TCHAR *pszNick)
+{
+
+ if ( streamData && streamData->lin ) {
+ switch ( streamData->lin->iType ) {
+ case GC_EVENT_MESSAGE:
+ if ( streamData->lin->ptszText ) {
+ TCHAR *ptszTemp = NULL;
+ TCHAR *ptszText = streamData->lin->ptszText;
+ if (streamData->si->windowData.codePage != CP_ACP) {
+ char *aText = t2acp(streamData->lin->ptszText, CP_ACP);
+ ptszText = ptszTemp = a2tcp(aText, streamData->si->windowData.codePage);
+ mir_free(aText);
+ }
+
+ Log_AppendRTF( streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), ptszText );
+ mir_free(ptszTemp);
+ }
+ break;
+ case GC_EVENT_ACTION:
+ if ( pszNick && streamData->lin->ptszText) {
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, _T("%s "), pszNick);
+ Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), streamData->lin->ptszText);
+ }
+ break;
+ case GC_EVENT_JOIN:
+ if (pszNick) {
+ if (!streamData->lin->bIsMe)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has joined"), pszNick);
+ else
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("You have joined %s"), streamData->si->ptszName);
+ }
+ break;
+ case GC_EVENT_PART:
+ if (pszNick)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has left"), pszNick);
+ AddEventTextToBuffer(buffer, bufferEnd, bufferAlloced, streamData);
+ break;
+ case GC_EVENT_QUIT:
+ if (pszNick)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has disconnected"), pszNick);
+ AddEventTextToBuffer(buffer, bufferEnd, bufferAlloced, streamData);
+ break;
+ case GC_EVENT_NICK:
+ if (pszNick && streamData->lin->ptszText) {
+ if (!streamData->lin->bIsMe)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s is now known as %s"), pszNick, streamData->lin->ptszText);
+ else
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("You are now known as %s"), streamData->lin->ptszText);
+ }
+ break;
+ case GC_EVENT_KICK:
+ if (pszNick && streamData->lin->ptszStatus)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s kicked %s"), streamData->lin->ptszStatus, pszNick);
+ AddEventTextToBuffer(buffer, bufferEnd, bufferAlloced, streamData);
+ break;
+ case GC_EVENT_NOTICE:
+ if (pszNick && streamData->lin->ptszText) {
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("Notice from %s"), pszNick );
+ AddEventTextToBuffer(buffer, bufferEnd, bufferAlloced, streamData);
+ }
+ break;
+ case GC_EVENT_TOPIC:
+ if (streamData->lin->ptszText)
+ Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, TranslateT("The topic is \'%s%s\'"), streamData->lin->ptszText, _T("%r"));
+ if (pszNick)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced,
+ streamData->lin->ptszUserInfo ? TranslateT(" (set by %s on %s)"): TranslateT(" (set by %s)"),
+ pszNick, streamData->lin->ptszUserInfo);
+ break;
+ case GC_EVENT_INFORMATION:
+ if (streamData->lin->ptszText)
+ Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, (streamData->lin->bIsMe) ? _T("--> %s") : _T("%s"), streamData->lin->ptszText);
+ break;
+ case GC_EVENT_ADDSTATUS:
+ if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s enables \'%s\' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, pszNick);
+ break;
+ case GC_EVENT_REMOVESTATUS:
+ if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus)
+ Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s disables \'%s\' status for %s"), streamData->lin->ptszText , streamData->lin->ptszStatus, pszNick);
+ break;
+} } }
+
+
+static void AddEventTextToBufferIEView(TCHAR **buffer, int *bufferEnd, int *bufferAlloced, LOGSTREAMDATA *streamData)
+{
+ if (streamData->lin->ptszText)
+ Log_AppendIEView(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T(": %s"), streamData->lin->ptszText);
+}
+
+
+static void AddEventToBufferIEView(TCHAR **buffer, int *bufferEnd, int *bufferAlloced, LOGSTREAMDATA *streamData, TCHAR *pszNick)
+{
+
+ if ( streamData && streamData->lin ) {
+ switch ( streamData->lin->iType ) {
+ case GC_EVENT_MESSAGE:
+ if ( streamData->lin->ptszText ) {
+ TCHAR *ptszTemp = NULL;
+ TCHAR *ptszText = streamData->lin->ptszText;
+ if (streamData->si->windowData.codePage != CP_ACP) {
+ char *aText = t2acp(streamData->lin->ptszText, CP_ACP);
+ ptszText = ptszTemp = a2tcp(aText, streamData->si->windowData.codePage);
+ mir_free(aText);
+ }
+
+ Log_AppendIEView( streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), ptszText );
+ mir_free(ptszTemp);
+ }
+ break;
+ case GC_EVENT_ACTION:
+ if ( pszNick && streamData->lin->ptszText) {
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, _T("%s "), streamData->lin->ptszNick);
+ Log_AppendIEView(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), streamData->lin->ptszText);
+ }
+ break;
+ case GC_EVENT_JOIN:
+ if (pszNick) {
+ if (!streamData->lin->bIsMe)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has joined"), pszNick);
+ else
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("You have joined %s"), streamData->si->ptszName);
+ }
+ break;
+ case GC_EVENT_PART:
+ if (pszNick)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has left"), pszNick);
+ AddEventTextToBufferIEView(buffer, bufferEnd, bufferAlloced, streamData);
+ break;
+ case GC_EVENT_QUIT:
+ if (pszNick)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has disconnected"), pszNick);
+ AddEventTextToBufferIEView(buffer, bufferEnd, bufferAlloced, streamData);
+ break;
+ case GC_EVENT_NICK:
+ if (pszNick && streamData->lin->ptszText) {
+ if (!streamData->lin->bIsMe)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s is now known as %s"), pszNick, streamData->lin->ptszText);
+ else
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("You are now known as %s"), streamData->lin->ptszText);
+ }
+ break;
+ case GC_EVENT_KICK:
+ if (pszNick && streamData->lin->ptszStatus)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s kicked %s"), streamData->lin->ptszStatus, streamData->lin->ptszNick);
+ AddEventTextToBufferIEView(buffer, bufferEnd, bufferAlloced, streamData);
+ break;
+ case GC_EVENT_NOTICE:
+ if (pszNick && streamData->lin->ptszText) {
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("Notice from %s"), pszNick );
+ AddEventTextToBufferIEView(buffer, bufferEnd, bufferAlloced, streamData);
+ }
+ break;
+ case GC_EVENT_TOPIC:
+ if (streamData->lin->ptszText)
+ Log_AppendIEView(streamData, FALSE, buffer, bufferEnd, bufferAlloced, TranslateT("The topic is \'%s%s\'"), streamData->lin->ptszText, _T("%r"));
+ if (pszNick)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced,
+ streamData->lin->ptszUserInfo ? TranslateT(" (set by %s on %s)"): TranslateT(" (set by %s)"),
+ pszNick, streamData->lin->ptszUserInfo);
+ break;
+ case GC_EVENT_INFORMATION:
+ if (streamData->lin->ptszText)
+ Log_AppendIEView(streamData, FALSE, buffer, bufferEnd, bufferAlloced, (streamData->lin->bIsMe) ? _T("--> %s") : _T("%s"), streamData->lin->ptszText);
+ break;
+ case GC_EVENT_ADDSTATUS:
+ if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s enables \'%s\' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, streamData->lin->ptszNick);
+ break;
+ case GC_EVENT_REMOVESTATUS:
+ if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus)
+ Log_AppendIEView(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s disables \'%s\' status for %s"), streamData->lin->ptszText , streamData->lin->ptszStatus, streamData->lin->ptszNick);
+ break;
+ }
+ }
+}
+
+
+static void LogEventIEView(LOGSTREAMDATA *streamData, TCHAR *ptszNick)
+{
+ TCHAR *buffer = NULL;
+ int bufferEnd = 0;
+ int bufferAlloced = 0;
+ IEVIEWEVENTDATA ied;
+ IEVIEWEVENT event;
+ ZeroMemory(&event, sizeof(event));
+ event.cbSize = sizeof(event);
+ event.dwFlags = 0;
+ event.hwnd = streamData->si->windowData.hwndLog;
+ event.hContact = streamData->si->windowData.hContact;
+ event.codepage = streamData->si->windowData.codePage;
+ event.pszProto = streamData->si->pszModule;
+ /*
+ if (!fAppend) {
+ event.iType = IEE_CLEAR_LOG;
+ CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
+ }
+ */
+ event.iType = IEE_LOG_MEM_EVENTS;
+ event.eventData = &ied;
+ event.count = 1;
+
+ ZeroMemory(&ied, sizeof(ied));
+ AddEventToBufferIEView(&buffer, &bufferEnd, &bufferAlloced, streamData, ptszNick);
+ ied.ptszNick = ptszNick;
+ ied.ptszText = buffer;
+ ied.time = streamData->lin->time;
+ ied.bIsMe = streamData->lin->bIsMe;
+
+ switch ( streamData->lin->iType ) {
+ case GC_EVENT_MESSAGE:
+ ied.iType = IEED_GC_EVENT_MESSAGE;
+ ied.dwData = IEEDD_GC_SHOW_NICK;
+ break;
+ case GC_EVENT_ACTION:
+ ied.iType = IEED_GC_EVENT_ACTION;
+ break;
+ case GC_EVENT_JOIN:
+ ied.iType = IEED_GC_EVENT_JOIN;
+ break;
+ case GC_EVENT_PART:
+ ied.iType = IEED_GC_EVENT_PART;
+ break;
+ case GC_EVENT_QUIT:
+ ied.iType = IEED_GC_EVENT_QUIT;
+ break;
+ case GC_EVENT_NICK:
+ ied.iType = IEED_GC_EVENT_NICK;
+ break;
+ case GC_EVENT_KICK:
+ ied.iType = IEED_GC_EVENT_KICK;
+ break;
+ case GC_EVENT_NOTICE:
+ ied.iType = IEED_GC_EVENT_NOTICE;
+ break;
+ case GC_EVENT_TOPIC:
+ ied.iType = IEED_GC_EVENT_TOPIC;
+ break;
+ case GC_EVENT_INFORMATION:
+ ied.iType = IEED_GC_EVENT_INFORMATION;
+ break;
+ case GC_EVENT_ADDSTATUS:
+ ied.iType = IEED_GC_EVENT_ADDSTATUS;
+ break;
+ case GC_EVENT_REMOVESTATUS:
+ ied.iType = IEED_GC_EVENT_REMOVESTATUS;
+ break;
+ }
+ ied.dwData |= g_Settings.ShowTime ? IEEDD_GC_SHOW_TIME : 0;
+ ied.dwData |= IEEDD_GC_SHOW_ICON;
+ ied.dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2;
+ ied.next = NULL;
+ /*
+ ied.color = event->color;
+ ied.fontSize = event->iFontSize;
+ ied.fontStyle = event->dwFlags;
+ ied.fontName = getFontName(event->iFont);
+ */
+ CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
+ mir_free(buffer);
+/*
+ iew.cbSize = sizeof(IEVIEWWINDOW);
+ iew.iType = IEW_SCROLLBOTTOM;
+ iew.hwnd = hWndLog;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&iew);
+*/
+}
+
+TCHAR* MakeTimeStamp( TCHAR* pszStamp, time_t time)
+{
+ static TCHAR szTime[30];
+ _tcsftime(szTime, 29, pszStamp, localtime(&time));
+ return szTime;
+}
+
+static char* Log_CreateRTF(LOGSTREAMDATA *streamData, BOOL ieviewMode)
+{
+ char *buffer, *header;
+ int bufferAlloced, bufferEnd, i;
+ LOGINFO * lin = streamData->lin;
+
+ // guesstimate amount of memory for the RTF
+ bufferEnd = 0;
+ bufferAlloced = streamData->bRedraw ? 1024 * (streamData->si->iEventCount+2) : 2048;
+ buffer = (char *) mir_alloc(bufferAlloced);
+ buffer[0] = '\0';
+
+ // ### RTF HEADER
+ header = streamData->si->pszHeader;
+
+ if (header)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, header);
+
+
+ // ### RTF BODY (one iteration per event that should be streamed in)
+ while ( lin )
+ {
+ // filter
+ if (streamData->si->iType != GCW_CHATROOM || !streamData->si->bFilterEnabled || (streamData->si->iLogFilterFlags&lin->iType) != 0)
+ {
+ TCHAR szTemp[512], szTemp2[512];
+ TCHAR* pszNick = NULL;
+ streamData->lin = lin;
+
+ if ( lin->ptszNick ) {
+ if ( g_Settings.LogLimitNames && lstrlen( lin->ptszNick ) > 20 ) {
+ lstrcpyn( szTemp2, lin->ptszNick, 20 );
+ lstrcpyn( szTemp2+20, _T("..."), 4);
+ }
+ else lstrcpyn( szTemp2, lin->ptszNick, 511 );
+
+ if ( lin->ptszUserInfo && lin->iType != GC_EVENT_TOPIC)
+ mir_sntprintf( szTemp, SIZEOF(szTemp), _T("%s (%s)"), szTemp2, lin->ptszUserInfo );
+ else
+ mir_sntprintf( szTemp, SIZEOF(szTemp), _T("%s"), szTemp2 );
+ pszNick = szTemp;
+ }
+
+ if (streamData->si->windowData.hwndLog != NULL) {
+ LogEventIEView(streamData, pszNick);
+ }
+ {
+ // create new line, and set font and color
+ if (!streamData->isFirst) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\par");
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", Log_SetStyle(0, 0));
+ // Insert icon
+ if ((lin->iType&g_Settings.dwIconFlags) || (lin->bIsHighlighted&&g_Settings.dwIconFlags&GC_EVENT_HIGHLIGHT))
+ {
+ int iIndex = (lin->bIsHighlighted&&g_Settings.dwIconFlags&GC_EVENT_HIGHLIGHT) ? 2 : EventToIcon(lin);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\fs1 ");
+ while (bufferAlloced - bufferEnd < logIconBmpSize[0])
+ bufferAlloced += 4096;
+ buffer = (char *) mir_realloc(buffer, bufferAlloced);
+ CopyMemory(buffer + bufferEnd, pLogIconBmpBits[iIndex], logIconBmpSize[iIndex]);
+ bufferEnd += logIconBmpSize[iIndex];
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " ");
+ }
+
+ if (g_Settings.TimeStampEventColour)
+ {
+ // colored timestamps
+ static char szStyle[256];
+ int iii;
+ if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE)
+ {
+ iii = lin->bIsHighlighted?16:(lin->bIsMe ? 2 : 1);
+ mir_snprintf(szStyle, SIZEOF(szStyle), "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii+1, aFonts[0].lf.lfWeight >= FW_BOLD ? 1 : 0, aFonts[0].lf.lfItalic, 2 * abs(aFonts[0].lf.lfHeight) * 74 / g_dat->logPixelSY);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", szStyle);
+ }
+ else
+ {
+ iii = lin->bIsHighlighted?16:EventToIndex(lin);
+ mir_snprintf(szStyle, SIZEOF(szStyle), "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii+1, aFonts[0].lf.lfWeight >= FW_BOLD ? 1 : 0, aFonts[0].lf.lfItalic, 2 * abs(aFonts[0].lf.lfHeight) * 74 / g_dat->logPixelSY);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", szStyle);
+ }
+ }
+ else
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", Log_SetStyle(0, 0 ));
+ // insert a TAB if necessary to put the timestamp in the right position
+// if (g_Settings.dwIconFlags)
+// AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\tab ");
+
+ //insert timestamp
+ if (g_Settings.ShowTime)
+ {
+ TCHAR szTimeStamp[30], szOldTimeStamp[30];
+
+ lstrcpyn( szTimeStamp, MakeTimeStamp(g_Settings.pszTimeStamp, lin->time), 30);
+ lstrcpyn( szOldTimeStamp, MakeTimeStamp(g_Settings.pszTimeStamp, streamData->si->LastTime), 30);
+ if ( !g_Settings.ShowTimeIfChanged || streamData->si->LastTime == 0 || lstrcmp(szTimeStamp, szOldTimeStamp )) {
+ streamData->si->LastTime = lin->time;
+ Log_AppendRTF( streamData, TRUE, &buffer, &bufferEnd, &bufferAlloced, _T("%s"), szTimeStamp );
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\tab ");
+ }
+
+ // Insert the nick
+
+ if (pszNick && lin->iType == GC_EVENT_MESSAGE)
+ {
+ TCHAR pszTemp[300], *p1;
+
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", Log_SetStyle(lin->bIsMe ? 2 : 1, lin->bIsMe ? 2 : 1));
+ lstrcpyn(pszTemp, lin->bIsMe ? g_Settings.pszOutgoingNick : g_Settings.pszIncomingNick, 299);
+ p1 = _tcsstr(pszTemp, _T("%n"));
+ if (p1)
+ p1[1] = 's';
+
+ Log_AppendRTF(streamData, TRUE, &buffer, &bufferEnd, &bufferAlloced, pszTemp, pszNick);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " ");
+ }
+
+ // Insert the message
+ i = lin->bIsHighlighted?16:EventToIndex(lin);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", Log_SetStyle(i, i));
+ AddEventToBuffer(&buffer, &bufferEnd, &bufferAlloced, streamData, pszNick);
+ }
+ streamData->isFirst = FALSE;
+
+ }
+ lin = lin->prev;
+ }
+
+ // ### RTF END
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}");
+ return buffer;
+}
+
+static DWORD CALLBACK Log_StreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+{
+ LOGSTREAMDATA *lstrdat = (LOGSTREAMDATA *) dwCookie;
+
+ if (lstrdat)
+ {
+ // create the RTF
+ if (lstrdat->buffer == NULL)
+ {
+ lstrdat->bufferOffset = 0;
+ lstrdat->buffer = Log_CreateRTF(lstrdat, lstrdat->si->windowData.hwndLog != NULL);
+ lstrdat->bufferLen = lstrlenA(lstrdat->buffer);
+ }
+
+ // give the RTF to the RE control
+ *pcb = min(cb, lstrdat->bufferLen - lstrdat->bufferOffset);
+ CopyMemory(pbBuff, lstrdat->buffer + lstrdat->bufferOffset, *pcb);
+ lstrdat->bufferOffset += *pcb;
+
+ // free stuff if the streaming operation is complete
+ if (lstrdat->bufferOffset == lstrdat->bufferLen)
+ {
+ mir_free(lstrdat->buffer);
+ lstrdat->buffer = NULL;
+ }
+ }
+
+ return 0;
+}
+
+void Log_StreamInEvent(HWND hwndDlg, LOGINFO* lin, SESSION_INFO* si, BOOL bRedraw)
+{
+ EDITSTREAM stream;
+ LOGSTREAMDATA streamData;
+ CHARRANGE oldsel, sel, newsel;
+ POINT point ={0};
+ SCROLLINFO scroll;
+ WPARAM wp;
+ HWND hwndRich;
+
+ if (hwndDlg == 0 || lin == 0 || si == 0)
+ return;
+
+ hwndRich = GetDlgItem(hwndDlg, IDC_CHAT_LOG);
+ ZeroMemory(&streamData, sizeof(LOGSTREAMDATA));
+ streamData.hwnd = hwndRich;
+ streamData.si = si;
+ streamData.lin = lin;
+ streamData.bStripFormat = FALSE;
+ streamData.isFirst = bRedraw ? 1 : (GetRichTextLength(hwndRich, CP_ACP, FALSE) == 0);
+
+ // bPhaseTwo = bRedraw && bPhaseTwo;
+
+ if (bRedraw || si->iType != GCW_CHATROOM || !si->bFilterEnabled || (si->iLogFilterFlags&lin->iType) != 0)
+ {
+ BOOL bFlag = FALSE;
+
+ ZeroMemory(&stream, sizeof(stream));
+ stream.pfnCallback = Log_StreamCallback;
+ stream.dwCookie = (DWORD_PTR) & streamData;
+ scroll.cbSize= sizeof(SCROLLINFO);
+ scroll.fMask= SIF_RANGE | SIF_POS|SIF_PAGE;
+ GetScrollInfo(hwndRich, SB_VERT, &scroll);
+ SendMessage(hwndRich, EM_GETSCROLLPOS, 0, (LPARAM) &point);
+
+ // do not scroll to bottom if there is a selection
+ SendMessage(hwndRich, EM_EXGETSEL, 0, (LPARAM) &oldsel);
+ if (oldsel.cpMax != oldsel.cpMin)
+ SendMessage(hwndRich, WM_SETREDRAW, FALSE, 0);
+
+ //set the insertion point at the bottom
+ sel.cpMin = sel.cpMax = GetRichTextLength(hwndRich, CP_ACP, FALSE);
+ SendMessage(hwndRich, EM_EXSETSEL, 0, (LPARAM) & sel);
+ SendMessage(hwndRich, EM_EXGETSEL, 0, (LPARAM) & sel);
+
+ // fix for the indent... must be a M$ bug
+ if (sel.cpMax == 0)
+ bRedraw = TRUE;
+
+ // should the event(s) be appended to the current log
+ wp = bRedraw?SF_RTF:SFF_SELECTION|SF_RTF;
+
+ //get the number of pixels per logical inch
+ if (bRedraw)
+ {
+ SendMessage(hwndRich, WM_SETREDRAW, FALSE, 0);
+ bFlag = TRUE;
+// SetCursor(LoadCursor(NULL, IDC_CHAT_ARROW));
+ }
+
+ // stream in the event(s)
+ streamData.lin = lin;
+ streamData.bRedraw = bRedraw;
+ SendMessage(hwndRich, EM_STREAMIN, wp, (LPARAM) & stream);
+
+ // do smileys
+ if (g_dat->smileyAddInstalled && (bRedraw
+ || (lin->ptszText
+ && lin->iType != GC_EVENT_JOIN
+ && lin->iType != GC_EVENT_NICK
+ && lin->iType != GC_EVENT_ADDSTATUS
+ && lin->iType != GC_EVENT_REMOVESTATUS )))
+ {
+ SMADD_RICHEDIT3 sm;
+
+ newsel.cpMax = -1;
+ newsel.cpMin = sel.cpMin;
+ if (newsel.cpMin < 0)
+ newsel.cpMin = 0;
+ ZeroMemory(&sm, sizeof(sm));
+ sm.cbSize = sizeof(sm);
+ sm.hwndRichEditControl = hwndRich;
+ sm.Protocolname = si->pszModule;
+ sm.rangeToReplace = bRedraw?NULL:&newsel;
+ sm.flags = 0;
+ sm.disableRedraw = TRUE;
+ sm.hContact = si->windowData.hContact;
+ CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm);
+ }
+
+ // scroll log to bottom if the log was previously scrolled to bottom, else restore old position
+ if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax-scroll.nPage-5 || scroll.nMax-scroll.nMin-scroll.nPage < 50)
+ {
+ SendMessage(GetParent(hwndRich), GC_SCROLLTOBOTTOM, 0, 0);
+ }
+ else
+ SendMessage(hwndRich, EM_SETSCROLLPOS, 0, (LPARAM) &point);
+
+ // do we need to restore the selection
+ if (oldsel.cpMax != oldsel.cpMin)
+ {
+ SendMessage(hwndRich, EM_EXSETSEL, 0, (LPARAM) & oldsel);
+ SendMessage(hwndRich, WM_SETREDRAW, TRUE, 0);
+ InvalidateRect(hwndRich, NULL, TRUE);
+ }
+
+ // need to invalidate the window
+ if (bFlag)
+ {
+ sel.cpMin = sel.cpMax = GetRichTextLength(hwndRich, CP_ACP, FALSE);
+ SendMessage(hwndRich, EM_EXSETSEL, 0, (LPARAM) & sel);
+ SendMessage(hwndRich, WM_SETREDRAW, TRUE, 0);
+ InvalidateRect(hwndRich, NULL, TRUE);
+} } }
+
+char * Log_CreateRtfHeader(MODULEINFO * mi, SESSION_INFO* si)
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd, i = 0;
+ int charset = 0;
+ BOOL forceCharset = FALSE;
+
+ // guesstimate amount of memory for the RTF header
+ bufferEnd = 0;
+ bufferAlloced = 4096;
+ buffer = (char *) mir_realloc(si->pszHeader, bufferAlloced);
+ buffer[0] = '\0';
+
+ // ### RTF HEADER
+
+ // font table
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\rtf1\\ansi\\deff0{\\fonttbl");
+ for (i = 0; i < OPTIONS_FONTCOUNT; i++) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\f%u\\fnil\\fcharset%u" TCHAR_STR_PARAM ";}", i, (!forceCharset) ? aFonts[i].lf.lfCharSet : charset, aFonts[i].lf.lfFaceName);
+ }
+ // colour table
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}{\\colortbl ;");
+
+ for (i = 0; i < OPTIONS_FONTCOUNT; i++)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(aFonts[i].color), GetGValue(aFonts[i].color), GetBValue(aFonts[i].color));
+
+ for(i = 0; i < mi->nColorCount; i++)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(mi->crColors[i]), GetGValue(mi->crColors[i]), GetBValue(mi->crColors[i]));
+
+ // new paragraph
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}\\pard");
+
+ // set tabs and indents
+ {
+ int iIndent = 0;
+
+ if (g_Settings.dwIconFlags)
+ {
+ iIndent += (14*1440)/g_dat->logPixelSX;
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\tx%u", iIndent);
+ }
+ if (g_Settings.ShowTime)
+ {
+ int iSize = (g_Settings.LogTextIndent*1440)/g_dat->logPixelSX;
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\tx%u", iIndent + iSize );
+ if (g_Settings.LogIndentEnabled)
+ iIndent += iSize;
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\fi-%u\\li%u", iIndent, iIndent);
+ }
+ return buffer;
+}
+
+#define RTFPICTHEADERMAXSIZE 78
+void LoadMsgLogBitmaps(void)
+{
+ HICON hIcon;
+ HBITMAP hBmp, hoBmp;
+ HDC hdc, hdcMem;
+ BITMAPINFOHEADER bih = { 0 };
+ int widthBytes, i;
+ RECT rc;
+ HBRUSH hBkgBrush;
+ int rtfHeaderSize;
+ PBYTE pBmpBits;
+
+ hBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, "Chat", "ColorLogBG", GetSysColor(COLOR_WINDOW)));
+ bih.biSize = sizeof(bih);
+ bih.biBitCount = 24;
+ bih.biCompression = BI_RGB;
+ bih.biHeight = 10; //GetSystemMetrics(SM_CYSMICON);
+ bih.biPlanes = 1;
+ bih.biWidth = 10; //GetSystemMetrics(SM_CXSMICON);
+ widthBytes = ((bih.biWidth * bih.biBitCount + 31) >> 5) * 4;
+ rc.top = rc.left = 0;
+ rc.right = bih.biWidth;
+ rc.bottom = bih.biHeight;
+ hdc = GetDC(NULL);
+ hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight);
+ hdcMem = CreateCompatibleDC(hdc);
+ pBmpBits = (PBYTE) mir_alloc(widthBytes * bih.biHeight);
+ for (i = 0; i < SIZEOF(pLogIconBmpBits); i++) {
+ hIcon = GetCachedIcon(logIconNames[i]);
+ pLogIconBmpBits[i] = (PBYTE) mir_alloc(RTFPICTHEADERMAXSIZE + (bih.biSize + widthBytes * bih.biHeight) * 2);
+ rtfHeaderSize = sprintf((char *)pLogIconBmpBits[i], "{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes1\\wbmwidthbytes%u\\picw%u\\pich%u ", bih.biBitCount, widthBytes, (unsigned int)bih.biWidth, (unsigned int)bih.biHeight);
+ hoBmp = (HBITMAP) SelectObject(hdcMem, hBmp);
+ FillRect(hdcMem, &rc, hBkgBrush);
+ DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, NULL, DI_NORMAL);
+ SelectObject(hdcMem, hoBmp);
+ GetDIBits(hdc, hBmp, 0, bih.biHeight, pBmpBits, (BITMAPINFO *) & bih, DIB_RGB_COLORS);
+ {
+ int n;
+ for (n = 0; n < sizeof(BITMAPINFOHEADER); n++)
+ sprintf((char *)pLogIconBmpBits[i] + rtfHeaderSize + n * 2, "%02X", ((PBYTE) & bih)[n]);
+ for (n = 0; n < widthBytes * bih.biHeight; n += 4)
+ sprintf((char *)pLogIconBmpBits[i] + rtfHeaderSize + (bih.biSize + n) * 2, "%02X%02X%02X%02X", pBmpBits[n], pBmpBits[n + 1], pBmpBits[n + 2], pBmpBits[n + 3]);
+ }
+ logIconBmpSize[i] = rtfHeaderSize + (bih.biSize + widthBytes * bih.biHeight) * 2 + 1;
+ pLogIconBmpBits[i][logIconBmpSize[i] - 1] = '}';
+ }
+ mir_free(pBmpBits);
+ DeleteDC(hdcMem);
+ DeleteObject(hBmp);
+ ReleaseDC(NULL, hdc);
+ DeleteObject(hBkgBrush);
+}
+
+void FreeMsgLogBitmaps(void)
+{
+ int i;
+ for (i = 0; i < SIZEOF(pLogIconBmpBits); i++)
+ mir_free(pLogIconBmpBits[i]);
+}
diff --git a/plugins/Scriver/src/chat/main.cpp b/plugins/Scriver/src/chat/main.cpp new file mode 100644 index 0000000000..4ff0eef47d --- /dev/null +++ b/plugins/Scriver/src/chat/main.cpp @@ -0,0 +1,110 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+
+void RegisterChatFonts( void );
+
+extern struct GlobalMessageData *g_dat;
+extern CRITICAL_SECTION cs;
+//globals
+HMENU g_hMenu = NULL;
+HANDLE hJoinMenuItem, hLeaveMenuItem;
+
+FONTINFO aFonts[OPTIONS_FONTCOUNT];
+HBRUSH hListBkgBrush = NULL;
+HBRUSH hListSelectedBkgBrush = NULL;
+
+TCHAR* pszActiveWndID = 0;
+char* pszActiveWndModule = 0;
+
+struct GlobalLogSettings_t g_Settings;
+
+int Chat_Load()
+{
+ InitializeCriticalSection(&cs);
+ g_hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU));
+ TranslateMenu(g_hMenu);
+ HookEvents();
+ CreateServiceFunctions();
+ CreateHookableEvents();
+ return 0;
+}
+
+int Chat_Unload(void)
+{
+ DBWriteContactSettingWord(NULL, "Chat", "SplitterX", (WORD)g_Settings.iSplitterX);
+
+ CList_SetAllOffline(TRUE, NULL);
+
+ mir_free( pszActiveWndID );
+ mir_free( pszActiveWndModule );
+
+ DestroyHookableEvents();
+
+ DestroyMenu(g_hMenu);
+ FreeIcons();
+ OptionsUnInit();
+ DeleteCriticalSection(&cs);
+ return 0;
+}
+
+int Chat_ModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ char* mods[3] = { "Chat", "ChatFonts" };
+ CallService( "DBEditorpp/RegisterModule", (WPARAM)mods, 2 );
+ RegisterChatFonts();
+ OptionsInit();
+ LoadIcons();
+ {
+ CLISTMENUITEM mi = { 0 };
+ mi.cbSize = sizeof(mi);
+ mi.position = -2000090001;
+ mi.flags = CMIF_DEFAULT | CMIF_ICONFROMICOLIB;
+ mi.icolibItem = LoadSkinnedIconHandle( SKINICON_CHAT_JOIN );
+ mi.pszName = LPGEN("&Join");
+ mi.pszService = "GChat/JoinChat";
+ hJoinMenuItem = Menu_AddContactMenuItem(&mi);
+
+ mi.position = -2000090000;
+ mi.flags = CMIF_NOTOFFLINE | CMIF_ICONFROMICOLIB;
+ mi.icolibItem = LoadSkinnedIconHandle( SKINICON_CHAT_LEAVE );
+ mi.pszName = LPGEN("&Leave");
+ mi.pszService = "GChat/LeaveChat";
+ hLeaveMenuItem = Menu_AddContactMenuItem(&mi);
+ }
+ CList_SetAllOffline(TRUE, NULL);
+ return 0;
+}
+
+
+void LoadIcons(void)
+{
+ LoadMsgLogBitmaps();
+ return ;
+}
+
+void FreeIcons(void)
+{
+ FreeMsgLogBitmaps();
+ return;
+}
diff --git a/plugins/Scriver/src/chat/manager.cpp b/plugins/Scriver/src/chat/manager.cpp new file mode 100644 index 0000000000..9573c920fa --- /dev/null +++ b/plugins/Scriver/src/chat/manager.cpp @@ -0,0 +1,1400 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+
+extern TCHAR* pszActiveWndID ;
+extern char* pszActiveWndModule ;
+extern struct MM_INTERFACE mmi ;
+
+extern struct GlobalMessageData *g_dat;
+
+void LoadModuleIcons(MODULEINFO * mi);
+
+#define WINDOWS_COMMANDS_MAX 30
+#define STATUSICONCOUNT 6
+
+SESSION_INFO* m_WndList = 0;
+TABLIST * g_TabList = 0;
+MODULEINFO *m_ModList = 0;
+
+void SetActiveSession(const TCHAR* pszID, const char* pszModule)
+{
+ SESSION_INFO* si = SM_FindSession(pszID, pszModule);
+ if ( si )
+ SetActiveSessionEx(si);
+}
+
+void SetActiveSessionEx(SESSION_INFO* si)
+{
+ if ( si ) {
+ replaceStr( &pszActiveWndID, si->ptszID );
+ replaceStrA( &pszActiveWndModule, si->pszModule );
+} }
+
+SESSION_INFO* GetActiveSession( void )
+{
+ SESSION_INFO* si = SM_FindSession( pszActiveWndID, pszActiveWndModule );
+ if ( si )
+ return si;
+
+ return m_WndList;
+}
+
+//---------------------------------------------------
+// Session Manager functions
+//
+// Keeps track of all sessions and its windows
+//---------------------------------------------------
+
+SESSION_INFO* SM_AddSession( const TCHAR* pszID, const char* pszModule)
+{
+ if ( !pszID || !pszModule )
+ return NULL;
+
+ if ( !SM_FindSession(pszID, pszModule)) {
+ SESSION_INFO*node = (SESSION_INFO*) mir_alloc(sizeof(SESSION_INFO));
+ ZeroMemory(node, sizeof(SESSION_INFO));
+ node->ptszID = mir_tstrdup( pszID );
+ node->pszModule = mir_strdup( pszModule );
+ node->windowData.flags = CWDF_RTF_INPUT;
+
+ if (m_WndList == NULL) { // list is empty
+ m_WndList = node;
+ node->next = NULL;
+ }
+ else {
+ node->next = m_WndList;
+ m_WndList = node;
+ }
+ return node;
+ }
+ return NULL;
+}
+
+int SM_RemoveSession(const TCHAR* pszID, const char* pszModule, BOOL removeContact)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while (pTemp != NULL)
+ {
+ if (((!pszID && pTemp->iType != GCW_SERVER) || !lstrcmpi(pTemp->ptszID,pszID)) && !lstrcmpiA(pTemp->pszModule,pszModule)) // match
+ {
+ DWORD dw = pTemp->dwItemData;
+
+ if (pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_EVENT_CONTROL+WM_USER+500, SESSION_TERMINATE, 0);
+
+ DoEventHook(pTemp->ptszID, pTemp->pszModule, GC_SESSION_TERMINATE, NULL, NULL, (DWORD)pTemp->dwItemData);
+
+ if (pLast == NULL)
+ m_WndList = pTemp->next;
+ else
+ pLast->next = pTemp->next;
+
+ UM_RemoveAll(&pTemp->pUsers);
+ TM_RemoveAll(&pTemp->pStatuses);
+ LM_RemoveAll(&pTemp->pLog, &pTemp->pLogEnd);
+ pTemp->iStatusCount = 0;
+ pTemp->nUsersInNicklist = 0;
+
+ if (pTemp->windowData.hContact)
+ {
+ CList_SetOffline(pTemp->windowData.hContact, pTemp->iType == GCW_CHATROOM?TRUE:FALSE);
+/* if (pTemp->iType != GCW_SERVER)
+ DBWriteContactSettingByte(pTemp->windowData.hContact, "CList", "Hidden", 1);*/
+ }
+ DBWriteContactSettingString(pTemp->windowData.hContact, pTemp->pszModule , "Topic", "");
+ DBWriteContactSettingString(pTemp->windowData.hContact, pTemp->pszModule, "StatusBar", "");
+ DBDeleteContactSetting(pTemp->windowData.hContact, "CList", "StatusMsg");
+
+ if (removeContact)
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)pTemp->windowData.hContact, 0);
+
+ mir_free( pTemp->pszModule );
+ mir_free( pTemp->ptszID );
+ mir_free( pTemp->ptszName );
+ mir_free( pTemp->ptszStatusbarText );
+ mir_free( pTemp->ptszTopic );
+ mir_free( pTemp->pszHeader );
+ mir_free( pTemp->pszID );
+ mir_free( pTemp->pszName );
+
+ // delete commands
+ tcmdlist_free(pTemp->windowData.cmdList);
+ mir_free(pTemp);
+ if (pszID)
+ return (int)dw;
+ if (pLast)
+ pTemp = pLast->next;
+ else
+ pTemp = m_WndList;
+ }
+ else
+ {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ }
+ return FALSE;
+}
+
+SESSION_INFO* SM_FindSession(const TCHAR* pszID, const char* pszModule)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ if ( !pszID || !pszModule )
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA(pTemp->pszModule,pszModule))
+ return pTemp;
+
+ pTemp = pTemp->next;
+ }
+ return NULL;
+}
+
+HWND SM_FindWindowByContact(HANDLE hContact)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ while ( pTemp != NULL ) {
+ if ( pTemp->windowData.hContact == hContact)
+ return pTemp->hWnd;
+
+ pTemp = pTemp->next;
+ }
+ return NULL;
+}
+
+BOOL SM_SetOffline(const TCHAR* pszID, const char* pszModule)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while (pTemp != NULL)
+ {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA(pTemp->pszModule,pszModule))
+ {
+ UM_RemoveAll(&pTemp->pUsers);
+ pTemp->nUsersInNicklist = 0;
+ if (pTemp->iType != GCW_SERVER)
+ pTemp->bInitDone = FALSE;
+
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+BOOL SM_SetStatusEx( const TCHAR* pszID, const char* pszModule, const TCHAR* pszText, int flags )
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA(pTemp->pszModule,pszModule)) {
+ UM_SetStatusEx(pTemp->pUsers, pszText, flags);
+ if (pTemp->hWnd)
+ RedrawWindow(GetDlgItem(pTemp->hWnd, IDC_CHAT_LIST), NULL, NULL, RDW_INVALIDATE);
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+char SM_GetStatusIndicator(SESSION_INFO* si, USERINFO * ui)
+{
+ STATUSINFO * ti;
+ if (!ui || !si)
+ return '\0';
+
+ ti = TM_FindStatus(si->pStatuses, TM_WordToString(si->pStatuses, ui->Status));
+ if (ti)
+ {
+ if ((INT_PTR)ti->hIcon < STATUSICONCOUNT)
+ {
+ INT_PTR id = si->iStatusCount - (INT_PTR)ti->hIcon - 1;
+ if (id == 0)
+ return '\0';
+ if (id == 1)
+ return '+';
+ if (id == 2)
+ return '%';
+ if (id == 3)
+ return '@';
+ if (id == 4)
+ return '!';
+ if (id == 5)
+ return '*';
+ }
+ else
+ return '\0';
+ }
+ return '\0';
+}
+
+HICON SM_GetStatusIcon(SESSION_INFO* si, USERINFO * ui)
+{
+ STATUSINFO * ti;
+ if (!ui || !si)
+ return NULL;
+
+ ti = TM_FindStatus(si->pStatuses, TM_WordToString(si->pStatuses, ui->Status));
+ if (ti)
+ {
+ if ((INT_PTR)ti->hIcon < STATUSICONCOUNT)
+ {
+ INT_PTR id = si->iStatusCount - (INT_PTR)ti->hIcon - 1;
+ char name[128];
+ sprintf(name, "chat_status%d", id);
+ return GetCachedIcon(name);
+ }
+ else
+ return ti->hIcon;
+ }
+ return GetCachedIcon("chat_status0");
+}
+
+BOOL SM_AddEventToAllMatchingUID(GCEVENT * gce)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+ int bManyFix = 0;
+
+ while (pTemp != NULL) {
+ if ( !lstrcmpiA( pTemp->pszModule, gce->pDest->pszModule )) {
+ if ( UM_FindUser( pTemp->pUsers, gce->ptszUID )) {
+ if ( pTemp->bInitDone ) {
+ if ( SM_AddEvent(pTemp->ptszID, pTemp->pszModule, gce, FALSE ) && pTemp->hWnd && pTemp->bInitDone) {
+ SendMessage(pTemp->hWnd, GC_ADDLOG, 0, 0);
+ }
+ else if (pTemp->hWnd && pTemp->bInitDone) {
+ SendMessage(pTemp->hWnd, GC_REDRAWLOG2, 0, 0);
+ }
+ DoSoundsFlashPopupTrayStuff(pTemp, gce, FALSE, bManyFix);
+ bManyFix ++;
+ if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings.LoggingEnabled)
+ LogToFile(pTemp, gce);
+ } } }
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return 0;
+}
+
+BOOL SM_AddEvent(const TCHAR* pszID, const char* pszModule, GCEVENT * gce, BOOL bIsHighlighted)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule)
+ return TRUE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA(pTemp->pszModule,pszModule)) {
+ LOGINFO * li = LM_AddEvent(&pTemp->pLog, &pTemp->pLogEnd);
+ pTemp->iEventCount += 1;
+
+ li->iType = gce->pDest->iType;
+ li->ptszNick = mir_tstrdup( gce->ptszNick );
+ li->ptszText = mir_tstrdup( gce->ptszText );
+ li->ptszStatus = mir_tstrdup( gce->ptszStatus );
+ li->ptszUserInfo = mir_tstrdup( gce->ptszUserInfo );
+
+ li->bIsMe = gce->bIsMe;
+ li->time = gce->time;
+ li->bIsHighlighted = bIsHighlighted;
+
+ if (g_Settings.iEventLimit > 0 && pTemp->iEventCount > g_Settings.iEventLimit + 20) {
+ LM_TrimLog(&pTemp->pLog, &pTemp->pLogEnd, pTemp->iEventCount - g_Settings.iEventLimit);
+ pTemp->iEventCount = g_Settings.iEventLimit;
+ return FALSE;
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+USERINFO * SM_AddUser( SESSION_INFO * si, const TCHAR* pszUID, const TCHAR* pszNick, WORD wStatus)
+{
+ USERINFO * p = UM_AddUser( si->pStatuses, &si->pUsers, pszUID, pszNick, wStatus);
+ si->nUsersInNicklist++;
+ return p;
+}
+
+BOOL SM_MoveUser(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ if (!pszID || !pszModule || !pszUID)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ UM_SortUser( &pTemp->pUsers, pszUID );
+ return TRUE;
+ }
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+
+BOOL SM_RemoveUser(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule || !pszUID)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ DWORD dw;
+ USERINFO * ui = UM_FindUser(pTemp->pUsers, pszUID);
+ if ( ui ) {
+ pTemp->nUsersInNicklist--;
+
+ dw = UM_RemoveUser(&pTemp->pUsers, pszUID);
+
+ if (pTemp->hWnd)
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+
+ if (pszID)
+ return TRUE;
+ } }
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return 0;
+}
+
+USERINFO * SM_GetUserFromIndex(const TCHAR* pszID, const char* pszModule, int index)
+{
+ SESSION_INFO *pTemp = m_WndList;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule ))
+ return UM_FindUserFromIndex( pTemp->pUsers, index );
+ pTemp = pTemp->next;
+ }
+
+ return NULL;
+}
+
+
+STATUSINFO * SM_AddStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule )
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ STATUSINFO* ti = TM_AddStatus( &pTemp->pStatuses, pszStatus, &pTemp->iStatusCount );
+ if ( ti )
+ pTemp->iStatusCount++;
+ return ti;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return 0;
+}
+
+BOOL SM_GiveStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if ( !pszID || !pszModule )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO * ui = UM_GiveStatus(pTemp->pUsers, pszUID, TM_StringToWord(pTemp->pStatuses, pszStatus));
+ if (ui) {
+ SM_MoveUser( pTemp->ptszID, pTemp->pszModule, ui->pszUID );
+ if ( pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+
+BOOL SM_SetContactStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, WORD wStatus)
+{
+ SESSION_INFO* pTemp = m_WndList, *pLast = NULL;
+
+ if ( !pszID || !pszModule )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO * ui = UM_SetContactStatus(pTemp->pUsers, pszUID, wStatus);
+ if (ui) {
+ SM_MoveUser( pTemp->ptszID, pTemp->pszModule, ui->pszUID );
+ if ( pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+
+BOOL SM_TakeStatus(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO* ui = UM_TakeStatus(pTemp->pUsers, pszUID, TM_StringToWord(pTemp->pStatuses, pszStatus));
+ if ( ui ) {
+ SM_MoveUser(pTemp->ptszID, pTemp->pszModule, ui->pszUID);
+ if ( pTemp->hWnd )
+ SendMessage(pTemp->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ return FALSE;
+}
+LRESULT SM_SendMessage(const TCHAR* pszID, const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ while ( pTemp && pszModule ) {
+ if (( !pszID ||!lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ if ( pTemp->hWnd ) {
+ LRESULT i = SendMessage(pTemp->hWnd, msg, wParam, lParam);
+ if ( pszID )
+ return i;
+ }
+ if ( pszID )
+ return 0;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+BOOL SM_PostMessage(const TCHAR* pszID, const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszID || !pszModule)
+ return 0;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->ptszID, pszID ) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ if ( pTemp->hWnd )
+ return PostMessage(pTemp->hWnd, msg, wParam, lParam);
+
+ return FALSE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return FALSE;
+}
+
+BOOL SM_BroadcastMessage(const char* pszModule, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAsync)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ while (pTemp != NULL)
+ {
+ if (!pszModule || !lstrcmpiA(pTemp->pszModule, pszModule))
+ {
+ if (pTemp->hWnd)
+ {
+ if (bAsync)
+ PostMessage(pTemp->hWnd, msg, wParam, lParam);
+ else
+ SendMessage(pTemp->hWnd, msg, wParam, lParam);
+ }
+
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+BOOL SM_SetStatus(const TCHAR* pszID, const char* pszModule, int wStatus)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ pTemp->wStatus = wStatus;
+
+ if ( pTemp->windowData.hContact ) {
+ if ( pTemp->iType != GCW_SERVER && wStatus != ID_STATUS_OFFLINE )
+ DBDeleteContactSetting(pTemp->windowData.hContact, "CList", "Hidden");
+
+ DBWriteContactSettingWord(pTemp->windowData.hContact, pTemp->pszModule, "Status", (WORD)wStatus);
+ }
+
+ PostMessage(pTemp->hWnd, GC_FIXTABICONS, 0, 0);
+
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+BOOL SM_SendUserMessage(const TCHAR* pszID, const char* pszModule, const TCHAR* pszText)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if ( !pszModule || !pszText )
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ if ( pTemp->iType == GCW_CHATROOM )
+ DoEventHook( pTemp->ptszID, pTemp->pszModule, GC_USER_MESSAGE, NULL, pszText, (LPARAM)NULL);
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+
+BOOL SM_ChangeUID(const TCHAR* pszID, const char* pszModule, const TCHAR* pszUID, const TCHAR* pszNewUID)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO* ui = UM_FindUser( pTemp->pUsers, pszUID );
+ if ( ui )
+ replaceStr( &ui->pszUID, pszNewUID );
+
+ if ( pszID )
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+
+BOOL SM_ChangeNick(const TCHAR* pszID, const char* pszModule, GCEVENT * gce)
+{
+ SESSION_INFO *pTemp = m_WndList, *pLast = NULL;
+
+ if (!pszModule)
+ return FALSE;
+
+ while ( pTemp != NULL ) {
+ if (( !pszID || !lstrcmpi( pTemp->ptszID, pszID )) && !lstrcmpiA( pTemp->pszModule, pszModule )) {
+ USERINFO* ui = UM_FindUser(pTemp->pUsers, gce->ptszUID );
+ if ( ui ) {
+ replaceStr( &ui->pszNick, gce->ptszText);
+ SM_MoveUser( pTemp->ptszID, pTemp->pszModule, ui->pszUID );
+ if ( pTemp->hWnd )
+ SendMessage( pTemp->hWnd, GC_UPDATENICKLIST, 0, 0 );
+ }
+
+ if (pszID)
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+BOOL SM_RemoveAll (void)
+{
+ while (m_WndList)
+ {
+ SESSION_INFO*pLast = m_WndList->next;
+
+ if (m_WndList->hWnd)
+ SendMessage(m_WndList->hWnd, GC_EVENT_CONTROL+WM_USER+500, SESSION_TERMINATE, 0);
+ DoEventHook(m_WndList->ptszID, m_WndList->pszModule, GC_SESSION_TERMINATE, NULL, NULL, (DWORD)m_WndList->dwItemData);
+ if (m_WndList->windowData.hContact)
+ CList_SetOffline(m_WndList->windowData.hContact, m_WndList->iType == GCW_CHATROOM?TRUE:FALSE);
+ DBWriteContactSettingString(m_WndList->windowData.hContact, m_WndList->pszModule , "Topic", "");
+ DBDeleteContactSetting(m_WndList->windowData.hContact, "CList", "StatusMsg");
+ DBWriteContactSettingString(m_WndList->windowData.hContact, m_WndList->pszModule, "StatusBar", "");
+
+ UM_RemoveAll(&m_WndList->pUsers);
+ TM_RemoveAll(&m_WndList->pStatuses);
+ LM_RemoveAll(&m_WndList->pLog, &m_WndList->pLogEnd);
+ m_WndList->iStatusCount = 0;
+ m_WndList->nUsersInNicklist = 0;
+
+ mir_free( m_WndList->pszModule );
+ mir_free( m_WndList->ptszID );
+ mir_free( m_WndList->ptszName );
+ mir_free( m_WndList->ptszStatusbarText );
+ mir_free( m_WndList->ptszTopic );
+ mir_free( m_WndList->pszHeader);
+ tcmdlist_free(m_WndList->windowData.cmdList);
+ mir_free(m_WndList);
+ m_WndList = pLast;
+ }
+ m_WndList = NULL;
+ return TRUE;
+}
+
+int SM_GetCount(const char* pszModule)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ int count = 0;
+
+ while (pTemp != NULL)
+ {
+ if (!lstrcmpiA(pszModule, pTemp->pszModule))
+ count++;
+
+ pTemp = pTemp->next;
+ }
+ return count;
+}
+
+SESSION_INFO* SM_FindSessionByIndex(const char* pszModule, int iItem)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ int count = 0;
+ while (pTemp != NULL)
+ {
+ if (!lstrcmpiA(pszModule, pTemp->pszModule))
+ {
+ if (iItem ==count)
+ return pTemp;
+ else
+ count++;
+ }
+
+ pTemp = pTemp->next;
+ }
+ return NULL;
+
+}
+
+char* SM_GetUsers(SESSION_INFO* si)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ USERINFO* utemp = NULL;
+ char* p = NULL;
+ int alloced = 0;
+
+ if ( si == NULL )
+ return NULL;
+
+ while (pTemp != NULL) {
+ if ( si == pTemp ) {
+ if (( utemp = pTemp->pUsers ) == NULL )
+ return NULL;
+
+ break;
+ }
+ pTemp = pTemp->next;
+ }
+
+ do {
+ int pLen = lstrlenA(p), nameLen = lstrlen(utemp->pszUID);
+ if ( pLen + nameLen + 2 > alloced )
+ p = (char *)mir_realloc( p, alloced += 4096 );
+
+ WideCharToMultiByte( CP_ACP, 0, utemp->pszUID, -1, p + pLen, nameLen+1, 0, 0 );
+
+ lstrcpyA( p + pLen + nameLen, " " );
+ utemp = utemp->next;
+ }
+ while ( utemp != NULL );
+ return p;
+}
+
+
+SESSION_INFO* SM_FindSessionAutoComplete(const char* pszModule, SESSION_INFO* currSession, SESSION_INFO* prevSession, const TCHAR* pszOriginal, const TCHAR* pszCurrent)
+{
+ SESSION_INFO* pResult = NULL;
+ if (prevSession == NULL && my_strstri( currSession->ptszName, pszOriginal) == currSession->ptszName) {
+ pResult = currSession;
+ } else {
+ TCHAR* pszName = NULL;
+ SESSION_INFO* pTemp = m_WndList;
+ if (currSession == prevSession) {
+ pszCurrent = pszOriginal;
+ }
+ while (pTemp != NULL) {
+ if (pTemp != currSession && !lstrcmpiA(pszModule, pTemp->pszModule)) {
+ if ( my_strstri( pTemp->ptszName, pszOriginal) == pTemp->ptszName ) {
+ if ( prevSession != pTemp && lstrcmpi( pTemp->ptszName, pszCurrent ) > 0 && ( !pszName || lstrcmpi( pTemp->ptszName, pszName ) < 0)) {
+ pResult = pTemp;
+ pszName = pTemp->ptszName;
+ }
+ }
+ }
+ pTemp = pTemp->next;
+ }
+ }
+ return pResult;
+
+}
+
+
+//---------------------------------------------------
+// Module Manager functions
+//
+// Necessary to keep track of all modules
+// that has registered with the plugin
+//---------------------------------------------------
+
+MODULEINFO* MM_AddModule(const char* pszModule)
+{
+ if (!pszModule)
+ return NULL;
+ if (!MM_FindModule(pszModule))
+ {
+ MODULEINFO *node = (MODULEINFO*) mir_calloc(sizeof(MODULEINFO));
+
+ node->pszModule = mir_strdup(pszModule);
+
+ if (m_ModList == NULL) // list is empty
+ {
+ m_ModList = node;
+ }
+ else
+ {
+ node->next = m_ModList;
+ m_ModList = node;
+ }
+ return node;
+ }
+ return FALSE;
+}
+
+void MM_IconsChanged(void)
+{
+ MODULEINFO *pTemp = m_ModList;
+
+ while (pTemp != NULL)
+ {
+ if (pTemp->hOnlineTalkIcon)
+ DestroyIcon(pTemp->hOnlineTalkIcon);
+ if (pTemp->hOfflineTalkIcon)
+ DestroyIcon(pTemp->hOfflineTalkIcon);
+
+ LoadModuleIcons(pTemp);
+ pTemp = pTemp->next;
+ }
+ return;
+}
+void MM_FontsChanged(void)
+{
+ SESSION_INFO* pTemp = m_WndList;
+ SetIndentSize();
+ while (pTemp != NULL)
+ {
+ pTemp->pszHeader = Log_CreateRtfHeader(MM_FindModule(pTemp->pszModule), pTemp);
+ pTemp = pTemp->next;
+ }
+ return;
+}
+MODULEINFO* MM_FindModule(const char* pszModule)
+{
+ MODULEINFO *pTemp = m_ModList, *pLast = NULL;
+
+ if (!pszModule)
+ return NULL;
+
+ while (pTemp != NULL) {
+ if (lstrcmpiA(pTemp->pszModule,pszModule) == 0)
+ return pTemp;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+// stupid thing..
+void MM_FixColors()
+{
+ MODULEINFO *pTemp = m_ModList;
+
+ while (pTemp != NULL)
+ {
+ CheckColorsInModule(pTemp->pszModule);
+ pTemp = pTemp->next;
+ }
+ return;
+}
+
+BOOL MM_RemoveAll (void)
+{
+ while (m_ModList != NULL)
+ {
+ MODULEINFO *pLast = m_ModList->next;
+ mir_free(m_ModList->pszModule);
+ mir_free(m_ModList->ptszModDispName);
+ mir_free(m_ModList->crColors);
+
+ if (m_ModList->hOnlineTalkIcon)
+ DestroyIcon(m_ModList->hOnlineTalkIcon);
+ if (m_ModList->hOfflineTalkIcon)
+ DestroyIcon(m_ModList->hOfflineTalkIcon);
+
+ mir_free(m_ModList);
+ m_ModList = pLast;
+ }
+ m_ModList = NULL;
+ return TRUE;
+}
+
+//---------------------------------------------------
+// Status manager functions
+//
+// Necessary to keep track of what user statuses
+// per window nicklist that is available
+//---------------------------------------------------
+
+STATUSINFO * TM_AddStatus(STATUSINFO** ppStatusList, const TCHAR* pszStatus, int* iCount)
+{
+ if (!ppStatusList || !pszStatus)
+ return NULL;
+
+ if ( !TM_FindStatus(*ppStatusList, pszStatus)) {
+ STATUSINFO *node = (STATUSINFO*) mir_alloc(sizeof(STATUSINFO));
+ ZeroMemory(node, sizeof(STATUSINFO));
+ replaceStr( &node->pszGroup, pszStatus );
+ node->hIcon = (HICON)(*iCount);
+ while ((INT_PTR)node->hIcon > STATUSICONCOUNT - 1)
+ node->hIcon--;
+
+ if (*ppStatusList == NULL) // list is empty
+ {
+ node->Status = 1;
+ *ppStatusList = node;
+ node->next = NULL;
+ }
+ else
+ {
+ node->Status = ppStatusList[0]->Status*2;
+ node->next = *ppStatusList;
+ *ppStatusList = node;
+ }
+ return node;
+
+ }
+ return FALSE;
+}
+
+STATUSINFO * TM_FindStatus(STATUSINFO* pStatusList, const TCHAR* pszStatus)
+{
+ STATUSINFO *pTemp = pStatusList, *pLast = NULL;
+
+ if (!pStatusList || !pszStatus)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( lstrcmpi(pTemp->pszGroup, pszStatus) == 0 )
+ return pTemp;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+WORD TM_StringToWord(STATUSINFO* pStatusList, const TCHAR* pszStatus)
+{
+ STATUSINFO *pTemp = pStatusList, *pLast = NULL;
+
+ if (!pStatusList || !pszStatus)
+ return 0;
+
+ while (pTemp != NULL) {
+ if ( lstrcmpi( pTemp->pszGroup, pszStatus ) == 0 )
+ return pTemp->Status;
+
+ if ( pTemp->next == NULL )
+ return pStatusList->Status;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+TCHAR* TM_WordToString(STATUSINFO* pStatusList, WORD Status)
+{
+ STATUSINFO *pTemp = pStatusList, *pLast = NULL;
+
+ if (!pStatusList)
+ return NULL;
+
+ while (pTemp != NULL) {
+ if (pTemp->Status&Status) {
+ Status -= pTemp->Status;
+ if (Status == 0)
+ return pTemp->pszGroup;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+BOOL TM_RemoveAll (STATUSINFO** ppStatusList)
+{
+
+ if (!ppStatusList)
+ return FALSE;
+
+ while (*ppStatusList != NULL)
+ {
+ STATUSINFO *pLast = ppStatusList[0]->next;
+ mir_free(ppStatusList[0]->pszGroup);
+ if ((INT_PTR)ppStatusList[0]->hIcon > 10)
+ DestroyIcon(ppStatusList[0]->hIcon);
+ mir_free(*ppStatusList);
+ *ppStatusList = pLast;
+ }
+ *ppStatusList = NULL;
+ return TRUE;
+}
+
+//---------------------------------------------------
+// User manager functions
+//
+// Necessary to keep track of the users
+// in a window nicklist
+//---------------------------------------------------
+
+
+static int UM_CompareItem(USERINFO * u1, const TCHAR* pszNick, WORD wStatus)
+{
+ int i;
+
+ WORD dw1 = u1->Status;
+ WORD dw2 = wStatus;
+
+ for (i=0; i<8; i++ )
+ {
+ if (( dw1 & 1 ) && !( dw2 & 1 ))
+ return -1;
+ if (( dw2 & 1 ) && !( dw1 & 1 ))
+ return 1;
+ if (( dw1 & 1 ) && ( dw2 & 1 ))
+ return lstrcmp( u1->pszNick, pszNick );
+
+ dw1 = dw1 >> 1;
+ dw2 = dw2 >> 1;
+ }
+ return lstrcmp( u1->pszNick, pszNick );
+
+}
+
+USERINFO * UM_SortUser(USERINFO** ppUserList, const TCHAR* pszUID)
+{
+ USERINFO * pTemp = *ppUserList, *pLast = NULL;
+ USERINFO * node = NULL;
+
+ if (!pTemp || !pszUID)
+ return NULL;
+
+ while(pTemp && lstrcmpi( pTemp->pszUID, pszUID)) {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ if ( pTemp ) {
+ node = pTemp;
+ if (pLast)
+ pLast->next = pTemp->next;
+ else
+ *ppUserList = pTemp->next;
+ pTemp = *ppUserList;
+
+ pLast = NULL;
+
+ while ( pTemp && UM_CompareItem(pTemp, node->pszNick, node->Status ) <= 0) {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ if (*ppUserList == NULL) { // list is empty
+ *ppUserList = node;
+ node->next = NULL;
+ }
+ else {
+ if ( pLast ) {
+ node->next = pTemp;
+ pLast->next = node;
+ }
+ else {
+ node->next = *ppUserList;
+ *ppUserList = node;
+ } }
+
+ return node;
+ }
+ return NULL;
+}
+
+USERINFO* UM_AddUser(STATUSINFO* pStatusList, USERINFO** ppUserList, const TCHAR* pszUID, const TCHAR* pszNick, WORD wStatus)
+{
+ USERINFO * pTemp = *ppUserList, *pLast = NULL;
+
+ if (!pStatusList || !ppUserList || !ppUserList)
+ return NULL;
+
+ while(pTemp && UM_CompareItem(pTemp, pszNick, wStatus) <= 0)
+ {
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+
+ // if (!UM_FindUser(*ppUserList, pszUI, wStatus)
+ {
+ USERINFO *node = (USERINFO*) mir_alloc(sizeof(USERINFO));
+ ZeroMemory(node, sizeof(USERINFO));
+ replaceStr( &node->pszUID, pszUID );
+
+ if (*ppUserList == NULL) { // list is empty
+ *ppUserList = node;
+ node->next = NULL;
+ }
+ else {
+ if ( pLast ) {
+ node->next = pTemp;
+ pLast->next = node;
+ }
+ else {
+ node->next = *ppUserList;
+ *ppUserList = node;
+ } }
+
+ return node;
+ }
+ return NULL;
+}
+
+USERINFO* UM_FindUser(USERINFO* pUserList, const TCHAR* pszUID)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID ))
+ return pTemp;
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+USERINFO* UM_FindUserFromIndex(USERINFO* pUserList, int index)
+{
+ int i = 0;
+ USERINFO *pTemp = pUserList;
+
+ if (!pUserList)
+ return NULL;
+
+ while (pTemp != NULL)
+ {
+ if (i == index)
+ {
+ return pTemp;
+ }
+ pTemp = pTemp->next;
+ i++;
+ }
+ return NULL;
+}
+
+USERINFO* UM_GiveStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID )) {
+ pTemp->Status |= status;
+ return pTemp;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+USERINFO* UM_SetContactStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID )) {
+ pTemp->ContactStatus = status;
+ return pTemp;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+BOOL UM_SetStatusEx(USERINFO* pUserList, const TCHAR* pszText, int flags )
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+ int bOnlyMe = ( flags & GC_SSE_ONLYLISTED ) != 0, bSetStatus = ( flags & GC_SSE_ONLINE ) != 0;
+ char cDelimiter = ( flags & GC_SSE_TABDELIMITED ) ? '\t' : ' ';
+
+ while (pTemp != NULL)
+ {
+ if ( !bOnlyMe )
+ pTemp->iStatusEx = 0;
+
+ if ( pszText != NULL ) {
+ TCHAR* s = (TCHAR *)_tcsstr( pszText, pTemp->pszUID );
+ if ( s ) {
+ pTemp->iStatusEx = 0;
+ if ( s == pszText || s[-1] == cDelimiter ) {
+ int len = lstrlen( pTemp->pszUID );
+ if ( s[len] == cDelimiter || s[len] == '\0' )
+ pTemp->iStatusEx = ( !bOnlyMe || bSetStatus ) ? 1 : 0;
+ } } }
+
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return TRUE;
+}
+
+USERINFO* UM_TakeStatus(USERINFO* pUserList, const TCHAR* pszUID, WORD status)
+{
+ USERINFO *pTemp = pUserList, *pLast = NULL;
+
+ if (!pUserList || !pszUID)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( !lstrcmpi( pTemp->pszUID, pszUID )) {
+ pTemp->Status &= ~status;
+ return pTemp;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return 0;
+}
+
+TCHAR* UM_FindUserAutoComplete(USERINFO* pUserList, const TCHAR* pszOriginal, const TCHAR* pszCurrent)
+{
+ TCHAR* pszName = NULL;
+ USERINFO *pTemp = pUserList;
+
+ if (!pUserList || !pszOriginal || !pszCurrent)
+ return NULL;
+
+ while ( pTemp != NULL ) {
+ if ( my_strstri( pTemp->pszNick, pszOriginal) == pTemp->pszNick )
+ if ( lstrcmpi( pTemp->pszNick, pszCurrent ) > 0 && ( !pszName || lstrcmpi( pTemp->pszNick, pszName ) < 0))
+ pszName = pTemp->pszNick;
+
+ pTemp = pTemp->next;
+ }
+ return pszName;
+}
+
+BOOL UM_RemoveUser(USERINFO** ppUserList, const TCHAR* pszUID)
+{
+ USERINFO *pTemp = *ppUserList, *pLast = NULL;
+
+ if (!ppUserList || !pszUID)
+ return FALSE;
+
+ while (pTemp != NULL) {
+ if (!lstrcmpi( pTemp->pszUID, pszUID )) {
+ if (pLast == NULL)
+ *ppUserList = pTemp->next;
+ else
+ pLast->next = pTemp->next;
+ mir_free(pTemp->pszNick);
+ mir_free(pTemp->pszUID);
+ mir_free(pTemp);
+ return TRUE;
+ }
+ pLast = pTemp;
+ pTemp = pTemp->next;
+ }
+ return FALSE;
+}
+
+BOOL UM_RemoveAll (USERINFO** ppUserList)
+{
+ if (!ppUserList)
+ return FALSE;
+
+ while (*ppUserList != NULL)
+ {
+ USERINFO *pLast = ppUserList[0]->next;
+ mir_free( ppUserList[0]->pszUID );
+ mir_free( ppUserList[0]->pszNick );
+ mir_free( *ppUserList );
+ *ppUserList = pLast;
+ }
+ *ppUserList = NULL;
+ return TRUE;
+}
+
+//---------------------------------------------------
+// Log manager functions
+//
+// Necessary to keep track of events
+// in a window log
+//---------------------------------------------------
+
+LOGINFO * LM_AddEvent(LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd)
+{
+
+ LOGINFO *node = NULL;
+
+ if (!ppLogListStart || !ppLogListEnd)
+ return NULL;
+
+ node = (LOGINFO*) mir_alloc(sizeof(LOGINFO));
+ ZeroMemory(node, sizeof(LOGINFO));
+
+
+ if (*ppLogListStart == NULL) // list is empty
+ {
+ *ppLogListStart = node;
+ *ppLogListEnd = node;
+ node->next = NULL;
+ node->prev = NULL;
+ }
+ else
+ {
+ ppLogListStart[0]->prev = node;
+ node->next = *ppLogListStart;
+ *ppLogListStart = node;
+ ppLogListStart[0]->prev=NULL;
+ }
+
+ return node;
+}
+
+BOOL LM_TrimLog(LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd, int iCount)
+{
+ LOGINFO *pTemp = *ppLogListEnd;
+ while (pTemp != NULL && iCount > 0) {
+ *ppLogListEnd = pTemp->prev;
+ if (*ppLogListEnd == NULL)
+ *ppLogListStart = NULL;
+
+ mir_free(pTemp->ptszNick);
+ mir_free(pTemp->ptszUserInfo);
+ mir_free(pTemp->ptszText);
+ mir_free(pTemp->ptszStatus);
+ mir_free(pTemp);
+ pTemp = *ppLogListEnd;
+ iCount--;
+ }
+ ppLogListEnd[0]->next = NULL;
+
+ return TRUE;
+}
+
+BOOL LM_RemoveAll (LOGINFO** ppLogListStart, LOGINFO** ppLogListEnd)
+{
+ while ( *ppLogListStart != NULL ) {
+ LOGINFO *pLast = ppLogListStart[0]->next;
+ mir_free( ppLogListStart[0]->ptszText );
+ mir_free( ppLogListStart[0]->ptszNick );
+ mir_free( ppLogListStart[0]->ptszStatus );
+ mir_free( ppLogListStart[0]->ptszUserInfo );
+ mir_free( *ppLogListStart );
+ *ppLogListStart = pLast;
+ }
+ *ppLogListStart = NULL;
+ *ppLogListEnd = NULL;
+ return TRUE;
+}
diff --git a/plugins/Scriver/src/chat/message.cpp b/plugins/Scriver/src/chat/message.cpp new file mode 100644 index 0000000000..7739e1acef --- /dev/null +++ b/plugins/Scriver/src/chat/message.cpp @@ -0,0 +1,312 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include <math.h>
+
+static int RTFColorToIndex(int *pIndex, int iCol, SESSION_INFO* si)
+{
+ int i;
+ MODULEINFO * pMod = MM_FindModule(si->pszModule);
+
+ for (i = 0; i < pMod->nColorCount ; i++)
+ if ( pIndex[i] == iCol )
+ return i;
+
+ return -1;
+}
+
+static void CreateColorMap( char* Text, int *pIndex, SESSION_INFO* si)
+{
+ char *p1, *p2, *pEnd;
+ int iIndex = 1;
+
+ static const char* lpszFmt = "\\red%[^ \x5b\\]\\green%[^ \x5b\\]\\blue%[^ \x5b;];";
+ char szRed[10], szGreen[10], szBlue[10];
+
+ p1 = strstr(Text, "\\colortbl" );
+ if ( !p1 )
+ return;
+
+ pEnd = strchr(p1, '}');
+ p2 = strstr(p1, "\\red" );
+
+ while (p2 && p2 < pEnd) {
+ if ( sscanf( p2, lpszFmt, &szRed, &szGreen, &szBlue) > 0 ) {
+ int i;
+ MODULEINFO * pMod = MM_FindModule(si->pszModule);
+ for (i = 0; i < pMod->nColorCount ; i ++)
+ if (pMod->crColors[i] == RGB( atoi(szRed), atoi(szGreen), atoi(szBlue)))
+ pIndex[i] = iIndex;
+ }
+ iIndex++;
+ p1 = p2;
+ p1 ++;
+ p2 = strstr(p1, "\\red" );
+} }
+
+static int ReadInteger( const char* p, int* result )
+{
+ char temp[10];
+ int i=0;
+ while ( isdigit( *p ))
+ temp[i++] = *p++;
+ temp[i] = 0;
+
+ if ( result != NULL )
+ *result = atoi( temp );
+
+ return i;
+}
+
+TCHAR* DoRtfToTags( char* pszText, SESSION_INFO* si)
+{
+ char *p1;
+ int* pIndex;
+ int i, iRemoveChars;
+ char InsertThis[50];
+ BOOL bJustRemovedRTF = TRUE;
+ BOOL bTextHasStarted = FALSE;
+ TCHAR *ptszResult;
+ int iUcMode = 0;
+
+ if ( !pszText )
+ return FALSE;
+
+ // create an index of colors in the module and map them to
+ // corresponding colors in the RTF color table
+ pIndex = (int *)mir_alloc(sizeof(int) * MM_FindModule(si->pszModule)->nColorCount);
+ for(i = 0; i < MM_FindModule(si->pszModule)->nColorCount ; i++)
+ pIndex[i] = -1;
+
+ CreateColorMap( pszText, pIndex, si );
+
+ // scan the file for rtf commands and remove or parse them
+ p1 = strstr( pszText, "\\pard" );
+ if ( p1 == NULL ) {
+ mir_free(pIndex);
+ return FALSE;
+ }
+
+ p1 += 5;
+
+ MoveMemory( pszText, p1, lstrlenA( p1 ) + 1 );
+ p1 = pszText;
+
+ // iterate through all characters, if rtf control character found then take action
+ while ( *p1 != '\0' ) {
+ InsertThis[0] = 0;
+ iRemoveChars = 0;
+
+ switch (*p1) {
+ case '\\':
+ if ( !memcmp(p1, "\\cf", 3 )) { // foreground color
+ int iCol, iInd;
+ iRemoveChars = 3 + ReadInteger(p1+3, &iCol);
+ iInd = RTFColorToIndex(pIndex, iCol, si);
+ bJustRemovedRTF = TRUE;
+
+ if (bTextHasStarted || iInd >= 0)
+ mir_snprintf( InsertThis, SIZEOF(InsertThis), ( iInd >= 0 ) ? "%%c%02u" : "%%C", iInd);
+ }
+ else if ( !memcmp(p1, "\\highlight", 10 )) { //background color
+ int iCol, iInd;
+ iRemoveChars = 10 + ReadInteger(p1+10, &iCol);
+ iInd = RTFColorToIndex(pIndex, iCol, si);
+ bJustRemovedRTF = TRUE;
+
+ if (bTextHasStarted || iInd >= 0)
+ mir_snprintf( InsertThis, SIZEOF(InsertThis), ( iInd >= 0 ) ? "%%f%02u" : "%%F", iInd);
+ }
+ else if ( !memcmp(p1, "\\lang", 5 )) { // language id
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iRemoveChars = 5 + ReadInteger( p1+5, NULL );
+ }
+ else if ( !memcmp(p1, "\\par", 4 )) { // newline
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iRemoveChars = 4;
+ strcpy(InsertThis, "\n" );
+ }
+ else if ( !memcmp(p1, "\\line", 5 )) { // newline
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iRemoveChars = 5;
+ strcpy(InsertThis, "\n" );
+ }
+ else if (!memcmp(p1, "\\bullet", 7)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 7;
+ strcpy(InsertThis, "\xE2\x80\xA2");
+ }
+ else if ( !memcmp(p1, "\\b", 2 )) { //bold
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iRemoveChars = (p1[2] != '0')?2:3;
+ mir_snprintf(InsertThis, SIZEOF(InsertThis), (p1[2] != '0') ? "%%b": "%%B" );
+ }
+ else if ( !memcmp(p1, "\\i", 2 )) { // italics
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iRemoveChars = (p1[2] != '0')?2:3;
+ mir_snprintf(InsertThis, SIZEOF(InsertThis), (p1[2] != '0') ? "%%i" : "%%I" );
+ }
+ else if ( !memcmp(p1, "\\uc", 3 )) { // number of Unicode chars
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iUcMode = p1[3] - '0';
+ iRemoveChars = 4;
+ }
+ else if ( !memcmp(p1, "\\ul", 3 )) { // underlined
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ if (p1[3] == 'n')
+ iRemoveChars = 7;
+ else if (p1[3] == '0')
+ iRemoveChars = 4;
+ else
+ iRemoveChars = 3;
+ mir_snprintf(InsertThis, SIZEOF(InsertThis), (p1[3] != '0' && p1[3] != 'n') ? "%%u" : "%%U" );
+ }
+ else if ( p1[1] == 'f' && isdigit( p1[2] )) { // unicode char
+ bTextHasStarted = bJustRemovedRTF = TRUE;
+ iRemoveChars = 2 + ReadInteger( p1+2, NULL );
+ }
+ else if ( !memcmp(p1, "\\tab", 4 )) { // tab
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 4;
+ strcpy(InsertThis, " " );
+ }
+ else if (!memcmp(p1, "\\endash", 7)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 7;
+ strcpy(InsertThis, "\xE2\x80\x93");
+ }
+ else if (!memcmp(p1, "\\emdash", 7)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 7;
+ strcpy(InsertThis, "\xE2\x80\x94");
+ }
+ else if (!memcmp(p1, "\\lquote",7)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 7;
+ strcpy(InsertThis, "\xE2\x80\x98");
+ }
+ else if (!memcmp(p1, "\\rquote",7)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 7;
+ strcpy(InsertThis, "\xE2\x80\x99");
+ }
+ else if (!memcmp(p1, "\\ldblquote",10)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 10;
+ strcpy(InsertThis, "\xe2\x80\x9c");
+ }
+ else if (!memcmp(p1, "\\rdblquote",10)) {
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = TRUE;
+ iRemoveChars = 10;
+ strcpy(InsertThis, "\xe2\x80\x9d");
+ }
+ else if ( p1[1] == '\\' || p1[1] == '{' || p1[1] == '}' ) { // escaped characters
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = FALSE;
+ iRemoveChars = 2;
+ mir_snprintf(InsertThis, SIZEOF(InsertThis), "%c", p1[1]);
+ }
+ else if ( p1[1] == '~' ) { // non-breaking space
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = FALSE;
+ iRemoveChars = 2;
+ strcpy(InsertThis, "\xC2\xA0");
+ }
+ else if ( p1[1] == '\'' ) { // special character
+ char tmp[4], *p3 = tmp;
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = FALSE;
+ if (p1[2] != ' ' && p1[2] != '\\') {
+ *p3++ = p1[2];
+ iRemoveChars = 3;
+ if ( p1[3] != ' ' && p1[3] != '\\') {
+ *p3++ = p1[3];
+ iRemoveChars++;
+ }
+ *p3 = 0;
+ sscanf( tmp, "%x", InsertThis );
+ InsertThis[1] = 0;
+ }
+ else iRemoveChars = 2;
+ }
+ else if ( bJustRemovedRTF ) { // remove unknown RTF command
+ int j = 1;
+ bJustRemovedRTF = TRUE;
+ while(p1[j] != ' ' && p1[j] != '\\' && p1[j] != '\0')
+ j++;
+ iRemoveChars = j;
+ }
+ break;
+
+ case '{': // other RTF control characters
+ case '}':
+ iRemoveChars = 1;
+ break;
+
+ case '\r': case '\n':
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = FALSE;
+ iRemoveChars = 1;
+ break;
+
+ case '%': // escape chat -> protocol control character
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = FALSE;
+ iRemoveChars = 1;
+ mir_snprintf(InsertThis, SIZEOF(InsertThis), "%%%%" );
+ break;
+ case ' ': // remove spaces following a RTF command
+ if (bJustRemovedRTF)
+ iRemoveChars = 1;
+ bJustRemovedRTF = FALSE;
+ bTextHasStarted = TRUE;
+ break;
+
+ default: // other text that should not be touched
+ bTextHasStarted = TRUE;
+ bJustRemovedRTF = FALSE;
+ break;
+ }
+
+ // move the memory and paste in new commands instead of the old RTF
+ if ( InsertThis[0] || iRemoveChars ) {
+ MoveMemory(p1 + lstrlenA(InsertThis) , p1 + iRemoveChars, lstrlenA(p1) - iRemoveChars +1 );
+ CopyMemory(p1, InsertThis, lstrlenA(InsertThis));
+ p1 += lstrlenA(InsertThis);
+ }
+ else p1++;
+ }
+
+ mir_free(pIndex);
+ mir_utf8decode(pszText, &ptszResult);
+ return ptszResult;
+}
+
diff --git a/plugins/Scriver/src/chat/options.cpp b/plugins/Scriver/src/chat/options.cpp new file mode 100644 index 0000000000..62ee3310fa --- /dev/null +++ b/plugins/Scriver/src/chat/options.cpp @@ -0,0 +1,928 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include <shlobj.h>
+#include <shlwapi.h>
+
+#define UM_CHECKSTATECHANGE (WM_USER+100)
+
+extern HBRUSH hListBkgBrush;
+extern HBRUSH hListSelectedBkgBrush;
+extern FONTINFO aFonts[OPTIONS_FONTCOUNT];
+
+HANDLE g_hOptions = NULL;
+static HWND hPathTip = 0;
+
+struct branch_t
+{
+ TCHAR* szDescr;
+ char* szDBName;
+ int iMode;
+ BYTE bDefault;
+ HTREEITEM hItem;
+};
+
+static struct branch_t branch1[] = {
+ {LPGENT("Flash when someone speaks"), "FlashWindow", 0,0, NULL},
+ {LPGENT("Flash when a word is highlighted"), "FlashWindowHighlight", 0,1, NULL},
+ {LPGENT("Show chat user list"), "ShowNicklist", 0,1, NULL},
+ {LPGENT("Enable button context menus"), "RightClickFilter", 0,0, NULL},
+ {LPGENT("Show topic on your contact list (if supported)"), "TopicOnClist", 0, 0, NULL},
+ {LPGENT("Do not play sounds when focused"), "SoundsFocus", 0, 0, NULL},
+ {LPGENT("Do not pop up when joining"), "PopupOnJoin", 0,0, NULL},
+ {LPGENT("Show and hide by double clicking in the contact list"), "ToggleVisibility", 0,0, NULL},
+ {LPGENT("Show contact statuses (if supported)"), "ShowContactStatus", 0,0, NULL},
+ {LPGENT("Display contact status icon before role icon"), "ContactStatusFirst", 0,0, NULL},
+ {LPGENT("Add \':\' to auto-completed names"), "AddColonToAutoComplete", 0, 1, NULL}
+};
+static struct branch_t branch2[] = {
+ {LPGENT("Show icons"), "IconFlags", GC_EVENT_TOPIC|GC_EVENT_JOIN|GC_EVENT_QUIT|
+ GC_EVENT_MESSAGE|GC_EVENT_ACTION|GC_EVENT_HIGHLIGHT|GC_EVENT_PART|
+ GC_EVENT_KICK|GC_EVENT_NOTICE|GC_EVENT_NICK|GC_EVENT_INFORMATION|GC_EVENT_ADDSTATUS, 0, NULL},
+ {LPGENT("Prefix all events with a timestamp"), "ShowTimeStamp", 0,1, NULL},
+ {LPGENT("Only prefix with timestamp if it has changed"), "ShowTimeStampIfChanged", 0,0, NULL},
+ {LPGENT("Timestamp has same colour as event"), "TimeStampEventColour", 0,0, NULL},
+ {LPGENT("Indent the second line of a message"), "LogIndentEnabled", 0,1, NULL},
+ {LPGENT("Limit user names to 20 characters"), "LogLimitNames", 0,1, NULL},
+ {LPGENT("Strip colors from messages"), "StripFormatting", 0, 0, NULL},
+ {LPGENT("Enable \'event filter\' for new rooms"), "FilterEnabled", 0,0, NULL}
+};
+static struct branch_t branch3[] = {
+ {LPGENT("Show topic changes"), "FilterFlags", GC_EVENT_TOPIC, 0, NULL},
+ {LPGENT("Show users joining"), "FilterFlags", GC_EVENT_JOIN, 0, NULL},
+ {LPGENT("Show users disconnecting"), "FilterFlags", GC_EVENT_QUIT, 0, NULL},
+ {LPGENT("Show messages"), "FilterFlags", GC_EVENT_MESSAGE, 1, NULL},
+ {LPGENT("Show actions"), "FilterFlags", GC_EVENT_ACTION, 1, NULL},
+ {LPGENT("Show users leaving"), "FilterFlags", GC_EVENT_PART, 0, NULL},
+ {LPGENT("Show users being kicked"), "FilterFlags", GC_EVENT_KICK, 1, NULL},
+ {LPGENT("Show notices"), "FilterFlags", GC_EVENT_NOTICE, 1, NULL},
+ {LPGENT("Show users changing name"), "FilterFlags", GC_EVENT_NICK, 0, NULL},
+ {LPGENT("Show information messages"), "FilterFlags", GC_EVENT_INFORMATION, 1, NULL},
+ {LPGENT("Show status changes of users"), "FilterFlags", GC_EVENT_ADDSTATUS, 0, NULL},
+};
+
+static struct branch_t branch4[] = {
+ {LPGENT("Show icons in tray only when the chat room is not active"), "TrayIconInactiveOnly", 0, 1, NULL},
+ {LPGENT("Show icon in tray for topic changes"), "TrayIconFlags", GC_EVENT_TOPIC, 0, NULL},
+ {LPGENT("Show icon in tray for users joining"), "TrayIconFlags", GC_EVENT_JOIN, 0, NULL},
+ {LPGENT("Show icon in tray for users disconnecting"), "TrayIconFlags", GC_EVENT_QUIT, 0, NULL},
+ {LPGENT("Show icon in tray for messages"), "TrayIconFlags", GC_EVENT_MESSAGE, 0, NULL},
+ {LPGENT("Show icon in tray for actions"), "TrayIconFlags", GC_EVENT_ACTION, 0, NULL},
+ {LPGENT("Show icon in tray for highlights"), "TrayIconFlags", GC_EVENT_HIGHLIGHT, 1, NULL},
+ {LPGENT("Show icon in tray for users leaving"), "TrayIconFlags", GC_EVENT_PART, 0, NULL},
+ {LPGENT("Show icon in tray for users kicking other user"), "TrayIconFlags", GC_EVENT_KICK, 0, NULL},
+ {LPGENT("Show icon in tray for notices "), "TrayIconFlags", GC_EVENT_NOTICE, 0, NULL},
+ {LPGENT("Show icon in tray for name changes"), "TrayIconFlags", GC_EVENT_NICK, 0, NULL},
+ {LPGENT("Show icon in tray for information messages"), "TrayIconFlags", GC_EVENT_INFORMATION, 0, NULL},
+ {LPGENT("Show icon in tray for status changes"), "TrayIconFlags", GC_EVENT_ADDSTATUS, 0, NULL},
+};
+
+static struct branch_t branch6[] = {
+ {LPGENT("Show pop-ups only when the chat room is not active"), "PopUpInactiveOnly", 0, 1, NULL},
+ {LPGENT("Show pop-up for topic changes"), "PopupFlags", GC_EVENT_TOPIC, 0, NULL},
+ {LPGENT("Show pop-up for users joining"), "PopupFlags", GC_EVENT_JOIN, 0, NULL},
+ {LPGENT("Show pop-up for users disconnecting"), "PopupFlags", GC_EVENT_QUIT, 0, NULL},
+ {LPGENT("Show pop-up for messages"), "PopupFlags", GC_EVENT_MESSAGE, 0, NULL},
+ {LPGENT("Show pop-up for actions"), "PopupFlags", GC_EVENT_ACTION, 0, NULL},
+ {LPGENT("Show pop-up for highlights"), "PopupFlags", GC_EVENT_HIGHLIGHT, 0, NULL},
+ {LPGENT("Show pop-up for users leaving"), "PopupFlags", GC_EVENT_PART, 0, NULL},
+ {LPGENT("Show pop-up for users kicking other user"), "PopupFlags", GC_EVENT_KICK, 0, NULL},
+ {LPGENT("Show pop-up for notices "), "PopupFlags", GC_EVENT_NOTICE, 0, NULL},
+ {LPGENT("Show pop-up for name changes"), "PopupFlags", GC_EVENT_NICK, 0, NULL},
+ {LPGENT("Show pop-up for information messages"), "PopupFlags", GC_EVENT_INFORMATION, 0, NULL},
+ {LPGENT("Show pop-up for status changes"), "PopupFlags", GC_EVENT_ADDSTATUS, 0, NULL},
+};
+
+static HTREEITEM InsertBranch(HWND hwndTree, TCHAR* pszDescr, BOOL bExpanded)
+{
+ TVINSERTSTRUCT tvis;
+
+ tvis.hParent=NULL;
+ tvis.hInsertAfter=TVI_LAST;
+ tvis.item.mask=TVIF_TEXT|TVIF_STATE;
+ tvis.item.pszText=TranslateTS(pszDescr);
+ tvis.item.stateMask=bExpanded?TVIS_STATEIMAGEMASK|TVIS_EXPANDED:TVIS_STATEIMAGEMASK;
+ tvis.item.state=bExpanded?INDEXTOSTATEIMAGEMASK(1)|TVIS_EXPANDED:INDEXTOSTATEIMAGEMASK(1);
+ return TreeView_InsertItem(hwndTree, &tvis);
+}
+
+static void FillBranch(HWND hwndTree, HTREEITEM hParent, struct branch_t *branch, int nValues, DWORD defaultval)
+{
+ TVINSERTSTRUCT tvis;
+ int i;
+ int iState;
+
+ tvis.hParent=hParent;
+ tvis.hInsertAfter=TVI_LAST;
+ tvis.item.mask=TVIF_TEXT|TVIF_STATE;
+ for(i=0;i<nValues;i++) {
+ tvis.item.pszText = TranslateTS(branch[i].szDescr);
+ tvis.item.stateMask = TVIS_STATEIMAGEMASK;
+ if (branch[i].iMode)
+ iState = ((DBGetContactSettingDword(NULL, "Chat", branch[i].szDBName, defaultval)&branch[i].iMode)&branch[i].iMode)!=0?2:1;
+ else
+ iState = DBGetContactSettingByte(NULL, "Chat", branch[i].szDBName, branch[i].bDefault)!=0?2:1;
+ tvis.item.state=INDEXTOSTATEIMAGEMASK(iState);
+ branch[i].hItem = TreeView_InsertItem(hwndTree, &tvis);
+ }
+}
+static void SaveBranch(HWND hwndTree, struct branch_t *branch, int nValues)
+{
+ TVITEM tvi;
+ BYTE bChecked;
+ int i;
+ int iState = 0;
+
+ tvi.mask=TVIF_HANDLE|TVIF_STATE;
+ for(i=0;i<nValues;i++) {
+ tvi.hItem = branch[i].hItem;
+ TreeView_GetItem(hwndTree,&tvi);
+ bChecked = ((tvi.state&TVIS_STATEIMAGEMASK)>>12==1)?0:1;
+ if (branch[i].iMode)
+ {
+ if (bChecked)
+ iState |= branch[i].iMode;
+ if (iState&GC_EVENT_ADDSTATUS)
+ iState |= GC_EVENT_REMOVESTATUS;
+ DBWriteContactSettingDword(NULL, "Chat", branch[i].szDBName, (DWORD)iState);
+ }
+ else DBWriteContactSettingByte(NULL, "Chat", branch[i].szDBName, bChecked);
+ } }
+
+static void CheckHeading(HWND hwndTree, HTREEITEM hHeading)
+{
+ BOOL bChecked = TRUE;
+ TVITEM tvi;
+
+ if (hHeading == 0)
+ return;
+
+ tvi.mask=TVIF_HANDLE|TVIF_STATE;
+ tvi.hItem=TreeView_GetNextItem(hwndTree, hHeading, TVGN_CHILD);
+ while(tvi.hItem && bChecked) {
+ if (tvi.hItem != branch1[0].hItem && tvi.hItem != branch1[1].hItem )
+ {
+ TreeView_GetItem(hwndTree,&tvi);
+ if (((tvi.state&TVIS_STATEIMAGEMASK)>>12==1))
+ bChecked = FALSE;
+ }
+ tvi.hItem=TreeView_GetNextSibling(hwndTree,tvi.hItem);
+ }
+ tvi.stateMask = TVIS_STATEIMAGEMASK;
+ tvi.state=INDEXTOSTATEIMAGEMASK(bChecked?2:1);
+ tvi.hItem = hHeading;
+ TreeView_SetItem(hwndTree,&tvi);
+}
+static void CheckBranches(HWND hwndTree, HTREEITEM hHeading)
+{
+ BOOL bChecked = TRUE;
+ TVITEM tvi;
+
+ if (hHeading == 0)
+ return;
+
+ tvi.mask=TVIF_HANDLE|TVIF_STATE;
+ tvi.hItem = hHeading;
+ TreeView_GetItem(hwndTree,&tvi);
+ if (((tvi.state&TVIS_STATEIMAGEMASK)>>12==2))
+ bChecked = FALSE;
+ tvi.hItem=TreeView_GetNextItem(hwndTree, hHeading, TVGN_CHILD);
+ tvi.stateMask = TVIS_STATEIMAGEMASK;
+ while(tvi.hItem) {
+ tvi.state=INDEXTOSTATEIMAGEMASK(bChecked?2:1);
+ if (tvi.hItem != branch1[0].hItem && tvi.hItem != branch1[1].hItem )
+ TreeView_SetItem(hwndTree,&tvi);
+ tvi.hItem=TreeView_GetNextSibling(hwndTree,tvi.hItem);
+ }
+}
+
+static INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData)
+{
+ char szDir[MAX_PATH];
+ switch(uMsg) {
+ case BFFM_INITIALIZED:
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
+ break;
+ case BFFM_SELCHANGED:
+ if (SHGetPathFromIDListA((LPITEMIDLIST) lp ,szDir))
+ SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
+ break;
+ }
+ return 0;
+}
+
+void LoadLogFonts(void)
+{
+ int i;
+ for ( i = 0; i<OPTIONS_FONTCOUNT; i++)
+ LoadMsgDlgFont(i, &aFonts[i].lf, &aFonts[i].color, TRUE);
+}
+
+
+static void InitSetting(TCHAR** ppPointer, char* pszSetting, TCHAR* pszDefault)
+{
+ DBVARIANT dbv;
+ if ( !DBGetContactSettingTString(NULL, "Chat", pszSetting, &dbv )) {
+ replaceStr( ppPointer, dbv.ptszVal );
+ DBFreeVariant(&dbv);
+ }
+ else replaceStr( ppPointer, pszDefault );
+ }
+
+#define OPT_FIXHEADINGS (WM_USER+1)
+
+
+INT_PTR CALLBACK DlgProcOptions1(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ static HTREEITEM hListHeading1 = 0;
+ static HTREEITEM hListHeading4= 0;
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_CHECKBOXES),GWL_STYLE,GetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_CHECKBOXES),GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN2,UDM_SETRANGE,0,MAKELONG(255,10));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN2,UDM_SETPOS,0,MAKELONG(DBGetContactSettingByte(NULL,"Chat","NicklistRowDist",12),0));
+ hListHeading1 = InsertBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), TranslateT("Appearance and functionality of chat windows"), DBGetContactSettingByte(NULL, "Chat", "Branch1Exp", 0)?TRUE:FALSE);
+ hListHeading4 = InsertBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), TranslateT("Icons to display in the tray"), DBGetContactSettingByte(NULL, "Chat", "Branch5Exp", 0)?TRUE:FALSE);
+ FillBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading1, branch1, SIZEOF(branch1), 0);
+ FillBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading4, branch4, SIZEOF(branch4), 0x1000);
+ SendMessage(hwndDlg, OPT_FIXHEADINGS, 0, 0);
+ {
+ TCHAR* pszGroup = NULL;
+ InitSetting(&pszGroup, "AddToGroup", _T("Chat rooms"));
+ SetWindowText(GetDlgItem(hwndDlg, IDC_CHAT_GROUP), pszGroup);
+ mir_free(pszGroup);
+ }
+ break;
+
+ case OPT_FIXHEADINGS:
+ CheckHeading(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading1);
+ CheckHeading(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading4);
+ break;
+
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHAT_NICKROW || LOWORD(wParam) == IDC_CHAT_GROUP) && (HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus()))
+ return 0;
+
+ if (lParam != (LPARAM)NULL)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case UM_CHECKSTATECHANGE:
+ {
+ TVITEM tvi = {0};
+ tvi.mask=TVIF_HANDLE|TVIF_STATE;
+ tvi.hItem=(HTREEITEM) lParam;
+ TreeView_GetItem((HWND)wParam,&tvi);
+ if (tvi.hItem == hListHeading1)
+ CheckBranches(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading1);
+ else if (tvi.hItem == hListHeading4)
+ CheckBranches(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading4);
+ else
+ PostMessage(hwndDlg, OPT_FIXHEADINGS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case IDC_CHAT_CHECKBOXES:
+ if (((LPNMHDR)lParam)->code==NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt);
+ if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti))
+ if (hti.flags&TVHT_ONITEMSTATEICON) {
+ SendMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom, (LPARAM)hti.hItem);
+ }
+
+ } else if (((LPNMHDR) lParam)->code == TVN_KEYDOWN) {
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE) {
+ SendMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom,
+ (LPARAM)TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ }
+ }
+ break;
+
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ int iLen;
+ char * pszText = NULL;
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_GROUP));
+ if (iLen > 0)
+ {
+ pszText = (char *)mir_realloc(pszText, iLen+1);
+ GetDlgItemTextA(hwndDlg, IDC_CHAT_GROUP, pszText,iLen+1);
+ DBWriteContactSettingString(NULL, "Chat", "AddToGroup", pszText);
+ }
+ else DBWriteContactSettingString(NULL, "Chat", "AddToGroup", "");
+ mir_free(pszText);
+
+ iLen = SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN2,UDM_GETPOS,0,0);
+ if (iLen > 0)
+ DBWriteContactSettingByte(NULL, "Chat", "NicklistRowDist", (BYTE)iLen);
+ else
+ DBDeleteContactSetting(NULL, "Chat", "NicklistRowDist");
+ SaveBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), branch1, SIZEOF(branch1));
+ SaveBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), branch4, SIZEOF(branch4));
+
+ SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, TRUE);
+ }
+ return TRUE;
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ BYTE b = TreeView_GetItemState(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading1, TVIS_EXPANDED)&TVIS_EXPANDED?1:0;
+ DBWriteContactSettingByte(NULL, "Chat", "Branch1Exp", b);
+ b = TreeView_GetItemState(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading4, TVIS_EXPANDED)&TVIS_EXPANDED?1:0;
+ DBWriteContactSettingByte(NULL, "Chat", "Branch5Exp", b);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgProcOptions2(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ static HTREEITEM hListHeading2= 0;
+ static HTREEITEM hListHeading3= 0;
+
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_CHECKBOXES),GWL_STYLE,GetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_CHECKBOXES),GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN2,UDM_SETRANGE,0,MAKELONG(5000,0));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN2,UDM_SETPOS,0,MAKELONG(DBGetContactSettingWord(NULL,"Chat","LogLimit",100),0));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN3,UDM_SETRANGE,0,MAKELONG(10000,0));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN3,UDM_SETPOS,0,MAKELONG(DBGetContactSettingWord(NULL,"Chat","LoggingLimit",100),0));
+ {
+ TCHAR tszTemp[MAX_PATH];
+ CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)g_Settings.pszLogDir, (LPARAM)tszTemp );
+ SetDlgItemText(hwndDlg, IDC_CHAT_LOGDIRECTORY, tszTemp);
+ }
+ if (ServiceExists(MS_UTILS_REPLACEVARS)) {
+ TCHAR tszTooltipText[2048];
+ RECT rect;
+
+ mir_sntprintf(tszTooltipText, SIZEOF(tszTooltipText),
+ _T("%s - %s\n%s - %s\n%s - %s\n\n")
+ _T("%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n\n")
+ _T("%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s"),
+ // contact vars
+ _T("%nick%"), TranslateT("nick of current contact (if defined)"),
+ _T("%proto%"), TranslateT("protocol name of current contact (if defined). Account name is used when protocol supports multiaccounts"),
+ _T("%userid%"), TranslateT("UserID of current contact (if defined). It is like UIN Number for ICQ, JID for Jabber, etc."),
+ // global vars
+ _T("%miranda_path%"), TranslateT("path to root miranda folder"),
+ _T("%miranda_profile%"), TranslateT("path to current miranda profile"),
+ _T("%miranda_profilename%"), TranslateT("name of current miranda profile (filename, without extension)"),
+ _T("%miranda_userdata%"), TranslateT("will return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%"),
+ _T("%appdata%"), TranslateT("same as environment variable %APPDATA% for currently logged-on Windows user"),
+ _T("%username%"), TranslateT("username for currently logged-on Windows user"),
+ _T("%mydocuments%"), TranslateT("\"My Documents\" folder for currently logged-on Windows user"),
+ _T("%desktop%"), TranslateT("\"Desktop\" folder for currently logged-on Windows user"),
+ _T("%xxxxxxx%"), TranslateT("any environment variable defined in current Windows session (like %systemroot%, %allusersprofile%, etc.)"),
+ // date/time vars
+ _T("%d%"), TranslateT("day of month, 1-31"),
+ _T("%dd%"), TranslateT("day of month, 01-31"),
+ _T("%m%"), TranslateT("month number, 1-12"),
+ _T("%mm%"), TranslateT("month number, 01-12"),
+ _T("%mon%"), TranslateT("abbreviated month name"),
+ _T("%month%"), TranslateT("full month name"),
+ _T("%yy%"), TranslateT("year without century, 01- 99"),
+ _T("%yyyy%"), TranslateT("year with century, 1901-9999"),
+ _T("%wday%"), TranslateT("abbreviated weekday name"),
+ _T("%weekday%"), TranslateT("full weekday name"));
+ GetClientRect (GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRECTORY), &rect);
+ rect.left = -85;
+ hPathTip = CreateToolTip(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRECTORY), tszTooltipText, TranslateT("Variables"), &rect);
+ SetTimer(hwndDlg, 0, 3000, NULL);
+ }
+
+ SetDlgItemText(hwndDlg, IDC_CHAT_HIGHLIGHTWORDS, g_Settings.pszHighlightWords);
+ SetDlgItemText(hwndDlg, IDC_CHAT_LOGTIMESTAMP, g_Settings.pszTimeStampLog);
+ SetDlgItemText(hwndDlg, IDC_CHAT_TIMESTAMP, g_Settings.pszTimeStamp);
+ SetDlgItemText(hwndDlg, IDC_CHAT_OUTSTAMP, g_Settings.pszOutgoingNick);
+ SetDlgItemText(hwndDlg, IDC_CHAT_INSTAMP, g_Settings.pszIncomingNick);
+ CheckDlgButton(hwndDlg, IDC_CHAT_HIGHLIGHT, g_Settings.HighlightEnabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_HIGHLIGHTWORDS), g_Settings.HighlightEnabled?TRUE:FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHAT_LOGGING, g_Settings.LoggingEnabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRECTORY), g_Settings.LoggingEnabled?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRCHOOSE), g_Settings.LoggingEnabled?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIMIT), g_Settings.LoggingEnabled?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIMITTEXT2), g_Settings.LoggingEnabled?TRUE:FALSE);
+
+ hListHeading2 = InsertBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), TranslateT("Appearance"), DBGetContactSettingByte(NULL, "Chat", "Branch2Exp", 0)?TRUE:FALSE);
+ hListHeading3 = InsertBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), TranslateT("Default events to show in new chat rooms if the \'event filter\' is enabled"), DBGetContactSettingByte(NULL, "Chat", "Branch3Exp", 0)?TRUE:FALSE);
+ FillBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading2, branch2, SIZEOF(branch2), 0x0);
+ FillBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading3, branch3, SIZEOF(branch3), 0x03E0);
+ SendMessage(hwndDlg, OPT_FIXHEADINGS, 0, 0);
+ break;
+
+ case OPT_FIXHEADINGS:
+ CheckHeading(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading2);
+ CheckHeading(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading3);
+ break;
+
+ case WM_COMMAND:
+ if ( (LOWORD(wParam) == IDC_CHAT_INSTAMP
+ || LOWORD(wParam) == IDC_CHAT_OUTSTAMP
+ || LOWORD(wParam) == IDC_CHAT_TIMESTAMP
+ || LOWORD(wParam) == IDC_CHAT_LOGLIMIT
+ || LOWORD(wParam) == IDC_CHAT_HIGHLIGHTWORDS
+ || LOWORD(wParam) == IDC_CHAT_LOGDIRECTORY
+ || LOWORD(wParam) == IDC_CHAT_LOGTIMESTAMP
+ || LOWORD(wParam) == IDC_CHAT_LIMIT)
+ && (HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus())) return 0;
+
+ switch (LOWORD(wParam)) {
+ case IDC_CHAT_LOGGING:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRECTORY), IsDlgButtonChecked(hwndDlg, IDC_CHAT_LOGGING) == BST_CHECKED?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRCHOOSE), IsDlgButtonChecked(hwndDlg, IDC_CHAT_LOGGING) == BST_CHECKED?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIMIT), IsDlgButtonChecked(hwndDlg, IDC_CHAT_LOGGING) == BST_CHECKED?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIMITTEXT2), IsDlgButtonChecked(hwndDlg, IDC_CHAT_LOGGING) == BST_CHECKED?TRUE:FALSE);
+ break;
+ case IDC_CHAT_LOGDIRCHOOSE:
+ {
+ LPMALLOC psMalloc;
+ if ( SUCCEEDED(CoGetMalloc(1, &psMalloc))) {
+ TCHAR tszDirectory[MAX_PATH], tszTemp[MAX_PATH];
+ BROWSEINFO bi = {0};
+ bi.hwndOwner = hwndDlg;
+ bi.pszDisplayName = tszDirectory;
+ bi.lpszTitle = TranslateT("Select Folder");
+ bi.ulFlags = BIF_NEWDIALOGSTYLE|BIF_EDITBOX|BIF_RETURNONLYFSDIRS;
+ bi.lpfn = BrowseCallbackProc;
+ bi.lParam = (LPARAM)tszDirectory;
+
+ LPITEMIDLIST idList = SHBrowseForFolder(&bi);
+ if (idList) {
+ SHGetPathFromIDList(idList,tszDirectory);
+ lstrcat(tszDirectory, _T("\\"));
+ CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)tszDirectory, (LPARAM)tszTemp );
+ SetWindowText(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRECTORY), lstrlen(tszTemp) > 1?tszTemp:DEFLOGFILENAME);
+ }
+ psMalloc->Free(idList);
+ psMalloc->Release();
+ }
+ break;
+ }
+ case IDC_CHAT_HIGHLIGHT:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_HIGHLIGHTWORDS), IsDlgButtonChecked(hwndDlg, IDC_CHAT_HIGHLIGHT) == BST_CHECKED?TRUE:FALSE);
+ break;
+ }
+
+ if (lParam != (LPARAM)NULL)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case UM_CHECKSTATECHANGE:
+ {
+ TVITEM tvi = {0};
+ tvi.mask=TVIF_HANDLE|TVIF_STATE;
+ tvi.hItem=(HTREEITEM) lParam;
+ TreeView_GetItem((HWND)wParam,&tvi);
+ if (tvi.hItem == hListHeading2)
+ CheckBranches(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading2);
+ else if (tvi.hItem == hListHeading3)
+ CheckBranches(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading3);
+ else
+ PostMessage(hwndDlg, OPT_FIXHEADINGS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == IDC_CHAT_CHECKBOXES) {
+ if (((LPNMHDR)lParam)->code==NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt);
+ if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti))
+ if (hti.flags&TVHT_ONITEMSTATEICON) {
+ SendMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom, (LPARAM)hti.hItem);
+ }
+ }
+ else if (((LPNMHDR) lParam)->code == TVN_KEYDOWN) {
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE) {
+ SendMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom,
+ (LPARAM)TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ }
+ }
+ }
+ else if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY ) {
+ char *pszText = NULL;
+ int iLen;
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_HIGHLIGHTWORDS));
+ if ( iLen > 0 ) {
+ TCHAR *ptszText = (TCHAR *)mir_alloc((iLen+2) * sizeof(TCHAR));
+ TCHAR *p2 = NULL;
+
+ if (ptszText) {
+ GetDlgItemText(hwndDlg, IDC_CHAT_HIGHLIGHTWORDS, ptszText, iLen + 1);
+ p2 = _tcschr(ptszText, (TCHAR)',');
+ while ( p2 ) {
+ *p2 = ' ';
+ p2 = _tcschr(ptszText, (TCHAR)',');
+ }
+ DBWriteContactSettingTString(NULL, "Chat", "HighlightWords", ptszText);
+ mir_free(ptszText);
+ }
+ }
+ else DBDeleteContactSetting(NULL, "Chat", "HighlightWords");
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_LOGDIRECTORY));
+ if ( iLen > 0 ) {
+ TCHAR *pszText1 = (TCHAR *)malloc(iLen*sizeof(TCHAR) + 2);
+ GetDlgItemText(hwndDlg, IDC_CHAT_LOGDIRECTORY, pszText1, iLen + 1);
+ DBWriteContactSettingTString(NULL, "Chat", "LogDirectory", pszText1);
+ CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)pszText1, (LPARAM)g_Settings.pszLogDir);
+ free(pszText1);
+ }
+ else {
+ lstrcpyn(g_Settings.pszLogDir, DEFLOGFILENAME, MAX_PATH);
+ DBDeleteContactSetting(NULL, "Chat", "LogDirectory");
+ }
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_LOGTIMESTAMP));
+ if ( iLen > 0 ) {
+ pszText = (char *)mir_realloc(pszText, iLen+1);
+ GetDlgItemTextA(hwndDlg, IDC_CHAT_LOGTIMESTAMP, pszText,iLen+1);
+ DBWriteContactSettingString(NULL, "Chat", "LogTimestamp", pszText);
+ }
+ else DBDeleteContactSetting(NULL, "Chat", "LogTimestamp");
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_TIMESTAMP));
+ if ( iLen > 0 ) {
+ pszText = (char *)mir_realloc(pszText, iLen+1);
+ GetDlgItemTextA(hwndDlg, IDC_CHAT_TIMESTAMP, pszText,iLen+1);
+ DBWriteContactSettingString(NULL, "Chat", "HeaderTime", pszText);
+ }
+ else DBDeleteContactSetting(NULL, "Chat", "HeaderTime");
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_INSTAMP));
+ if ( iLen > 0 ) {
+ pszText = (char *)mir_realloc(pszText, iLen+1);
+ GetDlgItemTextA(hwndDlg, IDC_CHAT_INSTAMP, pszText,iLen+1);
+ DBWriteContactSettingString(NULL, "Chat", "HeaderIncoming", pszText);
+ }
+ else DBDeleteContactSetting(NULL, "Chat", "HeaderIncoming");
+
+ iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CHAT_OUTSTAMP));
+ if ( iLen > 0 ) {
+ pszText = (char *)mir_realloc(pszText, iLen+1);
+ GetDlgItemTextA(hwndDlg, IDC_CHAT_OUTSTAMP, pszText,iLen+1);
+ DBWriteContactSettingString(NULL, "Chat", "HeaderOutgoing", pszText);
+ }
+ else DBDeleteContactSetting(NULL, "Chat", "HeaderOutgoing");
+
+ g_Settings.HighlightEnabled = IsDlgButtonChecked(hwndDlg, IDC_CHAT_HIGHLIGHT) == BST_CHECKED?TRUE:FALSE;
+ DBWriteContactSettingByte(NULL, "Chat", "HighlightEnabled", (BYTE)g_Settings.HighlightEnabled);
+
+ g_Settings.LoggingEnabled = IsDlgButtonChecked(hwndDlg, IDC_CHAT_LOGGING) == BST_CHECKED?TRUE:FALSE;
+ DBWriteContactSettingByte(NULL, "Chat", "LoggingEnabled", (BYTE)g_Settings.LoggingEnabled);
+
+ iLen = SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN2,UDM_GETPOS,0,0);
+ DBWriteContactSettingWord(NULL, "Chat", "LogLimit", (WORD)iLen);
+ iLen = SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN3,UDM_GETPOS,0,0);
+ DBWriteContactSettingWord(NULL, "Chat", "LoggingLimit", (WORD)iLen);
+
+ SaveBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), branch2, SIZEOF(branch2));
+ SaveBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), branch3, SIZEOF(branch3));
+
+ mir_free(pszText);
+
+ g_Settings.dwIconFlags = DBGetContactSettingDword(NULL, "Chat", "IconFlags", 0x0000);
+ g_Settings.dwTrayIconFlags = DBGetContactSettingDword(NULL, "Chat", "TrayIconFlags", 0x1000);
+ g_Settings.dwPopupFlags = DBGetContactSettingDword(NULL, "Chat", "PopupFlags", 0x0000);
+ g_Settings.StripFormat = (BOOL)DBGetContactSettingByte(NULL, "Chat", "TrimFormatting", 0);
+ g_Settings.TrayIconInactiveOnly = (BOOL)DBGetContactSettingByte(NULL, "Chat", "TrayIconInactiveOnly", 1);
+ g_Settings.PopUpInactiveOnly = (BOOL)DBGetContactSettingByte(NULL, "Chat", "PopUpInactiveOnly", 1);
+
+ g_Settings.LogIndentEnabled = (DBGetContactSettingByte(NULL, "Chat", "LogIndentEnabled", 1) != 0)?TRUE:FALSE;
+ MM_FontsChanged();
+ SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, TRUE);
+ return TRUE;
+ }
+ break;
+
+ case WM_TIMER:
+ if (IsWindow(hPathTip))
+ KillTimer(hPathTip, 4); // It will prevent tooltip autoclosing
+ break;
+
+ case WM_DESTROY:
+ if (hPathTip) {
+ KillTimer(hwndDlg, 0);
+ DestroyWindow(hPathTip);
+ hPathTip = 0;
+ }
+ {
+ BYTE b = TreeView_GetItemState(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading2, TVIS_EXPANDED)&TVIS_EXPANDED?1:0;
+ DBWriteContactSettingByte(NULL, "Chat", "Branch2Exp", b);
+ b = TreeView_GetItemState(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), hListHeading3, TVIS_EXPANDED)&TVIS_EXPANDED?1:0;
+ DBWriteContactSettingByte(NULL, "Chat", "Branch3Exp", b);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK DlgProcOptionsPopup(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_CHECKBOXES),GWL_STYLE,GetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_CHECKBOXES),GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_BKG, CPM_SETCOLOUR,0,g_Settings.crPUBkgColour);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_TEXT, CPM_SETCOLOUR,0,g_Settings.crPUTextColour);
+
+ if (g_Settings.iPopupStyle ==2)
+ CheckDlgButton(hwndDlg, IDC_CHAT_RADIO2, BST_CHECKED);
+ else if (g_Settings.iPopupStyle ==3)
+ CheckDlgButton(hwndDlg, IDC_CHAT_RADIO3, BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg, IDC_CHAT_RADIO1, BST_CHECKED);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_BKG), IsDlgButtonChecked(hwndDlg, IDC_CHAT_RADIO3) ==BST_CHECKED?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_TEXT), IsDlgButtonChecked(hwndDlg, IDC_CHAT_RADIO3) ==BST_CHECKED?TRUE:FALSE);
+
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN1,UDM_SETRANGE,0,MAKELONG(100,-1));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN1,UDM_SETPOS,0,MAKELONG(g_Settings.iPopupTimeout,0));
+ FillBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), NULL, branch6, SIZEOF(branch6), 0x0000);
+ break;
+
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHAT_TIMEOUT) && (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()))
+ return 0;
+
+ if (lParam)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+
+ switch (LOWORD(wParam)) {
+ case IDC_CHAT_RADIO1:
+ case IDC_CHAT_RADIO2:
+ case IDC_CHAT_RADIO3:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_BKG), IsDlgButtonChecked(hwndDlg, IDC_CHAT_RADIO3) ==BST_CHECKED?TRUE:FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_TEXT), IsDlgButtonChecked(hwndDlg, IDC_CHAT_RADIO3) ==BST_CHECKED?TRUE:FALSE);
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case IDC_CHAT_CHECKBOXES:
+ if (((LPNMHDR)lParam)->code==NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt);
+ if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti))
+ if (hti.flags&TVHT_ONITEMSTATEICON) {
+ SendMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom, (LPARAM)hti.hItem);
+ }
+ }
+ else if (((LPNMHDR) lParam)->code == TVN_KEYDOWN) {
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE) {
+ SendMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom,
+ (LPARAM)TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ }
+ }
+ break;
+
+ case 0:
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_APPLY:
+ {
+ int iLen;
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_RADIO2) == BST_CHECKED)
+ iLen = 2;
+ else if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_RADIO3) == BST_CHECKED)
+ iLen = 3;
+ else
+ iLen = 1;
+
+ g_Settings.iPopupStyle = iLen;
+ DBWriteContactSettingByte(NULL, "Chat", "PopupStyle", (BYTE)iLen);
+
+ iLen = SendDlgItemMessage(hwndDlg,IDC_CHAT_SPIN1,UDM_GETPOS,0,0);
+ g_Settings.iPopupTimeout = iLen;
+ DBWriteContactSettingWord(NULL, "Chat", "PopupTimeout", (WORD)iLen);
+
+ g_Settings.crPUBkgColour = SendDlgItemMessage(hwndDlg,IDC_CHAT_BKG,CPM_GETCOLOUR,0,0);
+ DBWriteContactSettingDword(NULL, "Chat", "PopupColorBG", (DWORD)SendDlgItemMessage(hwndDlg,IDC_CHAT_BKG,CPM_GETCOLOUR,0,0));
+ g_Settings.crPUTextColour = SendDlgItemMessage(hwndDlg,IDC_CHAT_TEXT,CPM_GETCOLOUR,0,0);
+ DBWriteContactSettingDword(NULL, "Chat", "PopupColorText", (DWORD)SendDlgItemMessage(hwndDlg,IDC_CHAT_TEXT,CPM_GETCOLOUR,0,0));
+ SaveBranch(GetDlgItem(hwndDlg, IDC_CHAT_CHECKBOXES), branch6, SIZEOF(branch6));
+ }
+ return TRUE;
+ }
+ }
+ break;
+
+ case UM_CHECKSTATECHANGE:
+ PostMessage(hwndDlg, OPT_FIXHEADINGS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ return FALSE;
+}
+
+static int OptionsInitialize(WPARAM wParam, LPARAM lParam)
+{
+ if (g_dat->popupInstalled) {
+ OPTIONSDIALOGPAGE odp = {0};
+ odp.cbSize = sizeof(odp);
+ odp.position = 910000002;
+ odp.hInstance = g_hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONSPOPUP);
+ odp.pszTitle = LPGEN("Messaging");
+ odp.pszGroup = LPGEN("Popups");
+ odp.pfnDlgProc = DlgProcOptionsPopup;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.ptszTab = NULL;
+ Options_AddPage(wParam, &odp);
+ }
+
+ return 0;
+}
+
+void LoadGlobalSettings(void)
+{
+ LOGFONT lf;
+
+ g_Settings.LogLimitNames = DBGetContactSettingByte(NULL, "Chat", "LogLimitNames", 1);
+ g_Settings.ShowTime = DBGetContactSettingByte(NULL, "Chat", "ShowTimeStamp", 1);
+ g_Settings.SoundsFocus = DBGetContactSettingByte(NULL, "Chat", "SoundsFocus", 0);
+ g_Settings.ShowTimeIfChanged = (BOOL)DBGetContactSettingByte(NULL, "Chat", "ShowTimeStampIfChanged", 0);
+ g_Settings.TimeStampEventColour = (BOOL)DBGetContactSettingByte(NULL, "Chat", "TimeStampEventColour", 0);
+ g_Settings.iEventLimit = DBGetContactSettingWord(NULL, "Chat", "LogLimit", 100);
+ g_Settings.dwIconFlags = DBGetContactSettingDword(NULL, "Chat", "IconFlags", 0x0000);
+ g_Settings.dwTrayIconFlags = DBGetContactSettingDword(NULL, "Chat", "TrayIconFlags", 0x1000);
+ g_Settings.dwPopupFlags = DBGetContactSettingDword(NULL, "Chat", "PopupFlags", 0x0000);
+ g_Settings.LoggingLimit = DBGetContactSettingWord(NULL, "Chat", "LoggingLimit", 100);
+ g_Settings.LoggingEnabled = (BOOL)DBGetContactSettingByte(NULL, "Chat", "LoggingEnabled", 0);
+ g_Settings.FlashWindow = (BOOL)DBGetContactSettingByte(NULL, "Chat", "FlashWindow", 0);
+ g_Settings.HighlightEnabled = (BOOL)DBGetContactSettingByte(NULL, "Chat", "HighlightEnabled", 1);
+ g_Settings.crUserListColor = DBGetContactSettingDword(NULL, "ChatFonts", "Font18Col", RGB(0,0,0));
+ g_Settings.crUserListBGColor = DBGetContactSettingDword(NULL, "Chat", "ColorNicklistBG", GetSysColor(COLOR_WINDOW));
+ g_Settings.crUserListSelectedBGColor = DBGetContactSettingDword(NULL, "Chat", "ColorNicklistSelectedBG", GetSysColor(COLOR_HIGHLIGHT));
+ g_Settings.crUserListHeadingsColor = DBGetContactSettingDword(NULL, "ChatFonts", "Font19Col", RGB(170,170,170));
+ g_Settings.crLogBackground = DBGetContactSettingDword(NULL, "Chat", "ColorLogBG", GetSysColor(COLOR_WINDOW));
+ g_Settings.StripFormat = (BOOL)DBGetContactSettingByte(NULL, "Chat", "StripFormatting", 0);
+ g_Settings.TrayIconInactiveOnly = (BOOL)DBGetContactSettingByte(NULL, "Chat", "TrayIconInactiveOnly", 1);
+ g_Settings.PopUpInactiveOnly = (BOOL)DBGetContactSettingByte(NULL, "Chat", "PopUpInactiveOnly", 1);
+ g_Settings.AddColonToAutoComplete = (BOOL)DBGetContactSettingByte(NULL, "Chat", "AddColonToAutoComplete", 1);
+ g_Settings.iPopupStyle = DBGetContactSettingByte(NULL, "Chat", "PopupStyle", 1);
+ g_Settings.iPopupTimeout = DBGetContactSettingWord(NULL, "Chat", "PopupTimeout", 3);
+ g_Settings.crPUBkgColour = DBGetContactSettingDword(NULL, "Chat", "PopupColorBG", GetSysColor(COLOR_WINDOW));
+ g_Settings.crPUTextColour = DBGetContactSettingDword(NULL, "Chat", "PopupColorText", 0);
+ g_Settings.ShowContactStatus = DBGetContactSettingByte(NULL, "Chat", "ShowContactStatus", 0);
+ g_Settings.ContactStatusFirst = DBGetContactSettingByte(NULL, "Chat", "ContactStatusFirst", 0);
+
+ InitSetting( &g_Settings.pszTimeStamp, "HeaderTime", _T("[%H:%M]"));
+ InitSetting( &g_Settings.pszTimeStampLog, "LogTimestamp", _T("[%d %b %y %H:%M]"));
+ InitSetting( &g_Settings.pszIncomingNick, "HeaderIncoming", _T("%n:"));
+ InitSetting( &g_Settings.pszOutgoingNick, "HeaderOutgoing", _T("%n:"));
+ InitSetting( &g_Settings.pszHighlightWords, "HighlightWords", _T("%m"));
+
+ DBVARIANT dbv;
+ g_Settings.pszLogDir = (TCHAR *)mir_realloc(g_Settings.pszLogDir, MAX_PATH*sizeof(TCHAR));
+ if ( !DBGetContactSettingTString(NULL, "Chat", "LogDirectory", &dbv)) {
+ lstrcpyn(g_Settings.pszLogDir, dbv.ptszVal, MAX_PATH);
+ DBFreeVariant(&dbv);
+ }
+ else lstrcpyn(g_Settings.pszLogDir, DEFLOGFILENAME, MAX_PATH);
+
+ g_Settings.LogIndentEnabled = (DBGetContactSettingByte(NULL, "Chat", "LogIndentEnabled", 1) != 0)?TRUE:FALSE;
+
+ if (g_Settings.MessageBoxFont)
+ DeleteObject(g_Settings.MessageBoxFont);
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, NULL, FALSE);
+ g_Settings.MessageBoxFont = CreateFontIndirect(&lf);
+
+ if (g_Settings.UserListFont)
+ DeleteObject(g_Settings.UserListFont);
+ LoadMsgDlgFont(18, &lf, NULL, TRUE);
+ g_Settings.UserListFont = CreateFontIndirect(&lf);
+
+ if (g_Settings.UserListHeadingsFont)
+ DeleteObject(g_Settings.UserListHeadingsFont);
+ LoadMsgDlgFont(19, &lf, NULL, TRUE);
+ g_Settings.UserListHeadingsFont = CreateFontIndirect(&lf);
+
+ if (hListBkgBrush != NULL)
+ DeleteObject(hListBkgBrush);
+ hListBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, "Chat", "ColorNicklistBG", GetSysColor(COLOR_WINDOW)));
+
+ if (hListSelectedBkgBrush != NULL)
+ DeleteObject(hListSelectedBkgBrush);
+ hListSelectedBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, "Chat", "ColorNicklistSelectedBG", GetSysColor(COLOR_HIGHLIGHT)));
+}
+
+static void FreeGlobalSettings(void)
+{
+ mir_free(g_Settings.pszTimeStamp);
+ mir_free(g_Settings.pszTimeStampLog);
+ mir_free(g_Settings.pszIncomingNick);
+ mir_free(g_Settings.pszOutgoingNick);
+ mir_free(g_Settings.pszHighlightWords);
+ mir_free(g_Settings.pszLogDir);
+ if (g_Settings.MessageBoxFont)
+ DeleteObject(g_Settings.MessageBoxFont);
+ if (g_Settings.UserListFont)
+ DeleteObject(g_Settings.UserListFont);
+ if (g_Settings.UserListHeadingsFont)
+ DeleteObject(g_Settings.UserListHeadingsFont);
+}
+
+void SetIndentSize()
+{
+ if (g_Settings.ShowTime) {
+ LOGFONT lf;
+ HFONT hFont;
+ int iText;
+
+ LoadMsgDlgFont(0, &lf, NULL, TRUE);
+ hFont = CreateFontIndirect(&lf);
+ iText = GetTextPixelSize(MakeTimeStamp(g_Settings.pszTimeStamp, time(NULL)),hFont, TRUE);
+ DeleteObject(hFont);
+ g_Settings.LogTextIndent = iText*12/10;
+ }
+ else g_Settings.LogTextIndent = 0;
+}
+
+int OptionsInit(void)
+{
+ LOGFONT lf;
+
+ g_hOptions = HookEvent(ME_OPT_INITIALISE, OptionsInitialize);
+
+ LoadLogFonts();
+ LoadMsgDlgFont(18, &lf, NULL, TRUE);
+ lstrcpy(lf.lfFaceName, _T("MS Shell Dlg"));
+ lf.lfUnderline = lf.lfItalic = lf.lfStrikeOut = 0;
+ lf.lfHeight = -17;
+ lf.lfWeight = FW_BOLD;
+ g_Settings.NameFont = CreateFontIndirect(&lf);
+ g_Settings.UserListFont = NULL;
+ g_Settings.UserListHeadingsFont = NULL;
+ g_Settings.MessageBoxFont = NULL;
+ g_Settings.iSplitterX = DBGetContactSettingWord(NULL, "Chat", "SplitterX", 105);
+ LoadGlobalSettings();
+
+ SkinAddNewSoundEx("ChatMessage", LPGEN("Group chats"), LPGEN("Incoming message"));
+ SkinAddNewSoundEx("ChatHighlight", LPGEN("Group chats"), LPGEN("Message is highlighted"));
+ SkinAddNewSoundEx("ChatAction", LPGEN("Group chats"), LPGEN("User has performed an action"));
+ SkinAddNewSoundEx("ChatJoin", LPGEN("Group chats"), LPGEN("User has joined"));
+ SkinAddNewSoundEx("ChatPart", LPGEN("Group chats"), LPGEN("User has left"));
+ SkinAddNewSoundEx("ChatKick", LPGEN("Group chats"), LPGEN("User has kicked some other user"));
+ SkinAddNewSoundEx("ChatMode", LPGEN("Group chats"), LPGEN("User's status was changed"));
+ SkinAddNewSoundEx("ChatNick", LPGEN("Group chats"), LPGEN("User has changed name"));
+ SkinAddNewSoundEx("ChatNotice", LPGEN("Group chats"), LPGEN("User has sent a notice"));
+ SkinAddNewSoundEx("ChatQuit", LPGEN("Group chats"), LPGEN("User has disconnected"));
+ SkinAddNewSoundEx("ChatTopic", LPGEN("Group chats"), LPGEN("The topic has been changed"));
+ SetIndentSize();
+ return 0;
+}
+
+int OptionsUnInit(void)
+{
+ FreeGlobalSettings();
+ UnhookEvent(g_hOptions);
+ DeleteObject(hListBkgBrush);
+ DeleteObject(hListSelectedBkgBrush);
+ DeleteObject(g_Settings.NameFont);
+ return 0;
+}
diff --git a/plugins/Scriver/src/chat/services.cpp b/plugins/Scriver/src/chat/services.cpp new file mode 100644 index 0000000000..edda2bf488 --- /dev/null +++ b/plugins/Scriver/src/chat/services.cpp @@ -0,0 +1,671 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include "../msgwindow.h"
+
+extern HICON hIcons[30];
+
+HANDLE hSendEvent;
+HANDLE hBuildMenuEvent ;
+HANDLE g_hHookContactDblClick, g_hHookPrebuildMenu;
+CRITICAL_SECTION cs;
+
+#ifdef _WIN64
+
+#define SIZEOF_STRUCT_GCREGISTER_V1 40
+#define SIZEOF_STRUCT_GCWINDOW_V1 48
+#define SIZEOF_STRUCT_GCEVENT_V1 76
+#define SIZEOF_STRUCT_GCEVENT_V2 80
+
+#else
+
+#define SIZEOF_STRUCT_GCREGISTER_V1 28
+#define SIZEOF_STRUCT_GCWINDOW_V1 32
+#define SIZEOF_STRUCT_GCEVENT_V1 44
+#define SIZEOF_STRUCT_GCEVENT_V2 48
+
+#endif
+
+int Chat_SmileyOptionsChanged(WPARAM wParam,LPARAM lParam)
+{
+ SM_BroadcastMessage(NULL, GC_REDRAWLOG, 0, 1, FALSE);
+ return 0;
+}
+
+int Chat_PreShutdown(WPARAM wParam,LPARAM lParam)
+{
+ SM_BroadcastMessage(NULL, GC_CLOSEWINDOW, 0, 1, FALSE);
+
+ SM_RemoveAll();
+ MM_RemoveAll();
+ return 0;
+}
+
+int Chat_FontsChanged(WPARAM wParam,LPARAM lParam)
+{
+ LoadLogFonts();
+ LoadMsgLogBitmaps();
+ MM_FontsChanged();
+ MM_FixColors();
+ SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, TRUE);
+ return 0;
+}
+
+int Chat_IconsChanged(WPARAM wParam,LPARAM lParam)
+{
+ FreeMsgLogBitmaps();
+ LoadMsgLogBitmaps();
+ MM_IconsChanged();
+ SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, FALSE);
+ return 0;
+}
+
+static INT_PTR Service_GetCount(WPARAM wParam,LPARAM lParam)
+{
+ int i;
+
+ if (!lParam)
+ return -1;
+
+ EnterCriticalSection(&cs);
+
+ i = SM_GetCount((char *)lParam);
+
+ LeaveCriticalSection(&cs);
+ return i;
+}
+
+static INT_PTR Service_GetInfo(WPARAM wParam,LPARAM lParam)
+{
+ GC_INFO * gci = (GC_INFO *) lParam;
+ SESSION_INFO * si = NULL;
+
+ if (!gci || !gci->pszModule)
+ return 1;
+
+ EnterCriticalSection(&cs);
+
+ if (gci->Flags&BYINDEX)
+ si = SM_FindSessionByIndex( gci->pszModule, gci->iItem );
+ else
+ si = SM_FindSession( gci->pszID, gci->pszModule );
+
+ if ( si ) {
+ if ( gci->Flags & DATA ) gci->dwItemData = si->dwItemData;
+ if ( gci->Flags & HCONTACT ) gci->hContact = si->windowData.hContact;
+ if ( gci->Flags & TYPE ) gci->iType = si->iType;
+ if ( gci->Flags & COUNT ) gci->iCount = si->nUsersInNicklist;
+ if ( gci->Flags & USERS ) gci->pszUsers = SM_GetUsers(si);
+ if ( si->dwFlags & GC_UNICODE ) {
+ if ( gci->Flags & ID ) gci->pszID = si->ptszID;
+ if ( gci->Flags & NAME ) gci->pszName = si->ptszName;
+ }
+
+
+ LeaveCriticalSection(&cs);
+ return 0;
+ }
+
+ LeaveCriticalSection(&cs);
+ return 1;
+}
+
+void LoadModuleIcons(MODULEINFO * mi) {
+ int index;
+
+ HIMAGELIST hList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 0, 0);
+
+ int overlayIcon = ImageList_AddIcon(hList, GetCachedIcon("chat_overlay"));
+ ImageList_SetOverlayImage(hList, overlayIcon, 1);
+
+ mi->hOnlineIconBig = LoadSkinnedProtoIconBig(mi->pszModule, ID_STATUS_ONLINE);
+ mi->hOnlineIcon = LoadSkinnedProtoIcon(mi->pszModule, ID_STATUS_ONLINE);
+ index = ImageList_AddIcon(hList, mi->hOnlineIcon);
+ mi->hOnlineTalkIcon = ImageList_GetIcon(hList, index, ILD_TRANSPARENT | INDEXTOOVERLAYMASK(1));
+
+ mi->hOfflineIconBig = LoadSkinnedProtoIconBig(mi->pszModule, ID_STATUS_OFFLINE);
+ mi->hOfflineIcon = LoadSkinnedProtoIcon(mi->pszModule, ID_STATUS_OFFLINE);
+ index = ImageList_AddIcon(hList, mi->hOfflineIcon);
+ mi->hOfflineTalkIcon = ImageList_GetIcon(hList, index, ILD_TRANSPARENT | INDEXTOOVERLAYMASK(1));
+
+ ImageList_Destroy(hList);
+}
+
+static INT_PTR Service_Register(WPARAM wParam, LPARAM lParam)
+{
+ GCREGISTER *gcr = (GCREGISTER *)lParam;
+ MODULEINFO * mi = NULL;
+ if (gcr== NULL)
+ return GC_REGISTER_ERROR;
+
+ if (gcr->cbSize != SIZEOF_STRUCT_GCREGISTER_V1)
+ return GC_REGISTER_WRONGVER;
+
+ EnterCriticalSection(&cs);
+
+ mi = MM_AddModule( gcr->pszModule );
+ if ( mi ) {
+ mi->ptszModDispName = a2tf( gcr->ptszModuleDispName, gcr->dwFlags );
+ mi->bBold = gcr->dwFlags&GC_BOLD;
+ mi->bUnderline = gcr->dwFlags&GC_UNDERLINE ;
+ mi->bItalics = gcr->dwFlags&GC_ITALICS ;
+ mi->bColor = gcr->dwFlags&GC_COLOR ;
+ mi->bBkgColor = gcr->dwFlags&GC_BKGCOLOR ;
+ mi->bFontSize = gcr->dwFlags&GC_FONTSIZE;
+ mi->bAckMsg = gcr->dwFlags&GC_ACKMSG ;
+ mi->bChanMgr = gcr->dwFlags&GC_CHANMGR ;
+ mi->bSingleFormat = gcr->dwFlags&GC_SINGLEFORMAT;
+ mi->iMaxText= gcr->iMaxText;
+ mi->nColorCount = gcr->nColors;
+ if ( gcr->nColors > 0) {
+ mi->crColors = (COLORREF *)mir_alloc(sizeof(COLORREF) * gcr->nColors);
+ memcpy(mi->crColors, gcr->pColors, sizeof(COLORREF) * gcr->nColors);
+ }
+
+ CheckColorsInModule((char*)gcr->pszModule);
+ CList_SetAllOffline(TRUE, gcr->pszModule);
+
+ LeaveCriticalSection(&cs);
+ return 0;
+ }
+
+ LeaveCriticalSection(&cs);
+ return GC_REGISTER_ERROR;
+}
+
+static INT_PTR Service_NewChat(WPARAM wParam, LPARAM lParam)
+{
+ MODULEINFO* mi;
+ GCSESSION *gcw =(GCSESSION *)lParam;
+ if (gcw== NULL)
+ return GC_NEWSESSION_ERROR;
+
+ if (gcw->cbSize != SIZEOF_STRUCT_GCWINDOW_V1)
+ return GC_NEWSESSION_WRONGVER;
+
+ EnterCriticalSection(&cs);
+
+ if (( mi = MM_FindModule( gcw->pszModule )) != NULL ) {
+ TCHAR* ptszID = a2tf( gcw->ptszID, gcw->dwFlags );
+ SESSION_INFO* si = SM_AddSession( ptszID, gcw->pszModule);
+
+ if (mi->hOfflineIcon == NULL) {
+ LoadModuleIcons(mi);
+ }
+ // create a new session and set the defaults
+ if ( si != NULL ) {
+ TCHAR szTemp[256];
+
+ si->dwItemData = gcw->dwItemData;
+ if ( gcw->iType != GCW_SERVER )
+ si->wStatus = ID_STATUS_ONLINE;
+ si->iType = gcw->iType;
+ si->dwFlags = gcw->dwFlags;
+ si->ptszName = a2tf( gcw->ptszName, gcw->dwFlags );
+ si->ptszStatusbarText = a2tf( gcw->ptszStatusbarText, gcw->dwFlags );
+ si->iSplitterX = g_Settings.iSplitterX;
+ si->iSplitterY = g_Settings.iSplitterY;
+ si->iLogFilterFlags = (int)DBGetContactSettingDword(NULL, "Chat", "FilterFlags", 0x03E0);
+ si->bFilterEnabled = DBGetContactSettingByte(NULL, "Chat", "FilterEnabled", 0);
+ si->bNicklistEnabled = DBGetContactSettingByte(NULL, "Chat", "ShowNicklist", 1);
+
+ if ( !( gcw->dwFlags & GC_UNICODE )) {
+ si->pszID = mir_strdup( gcw->pszID );
+ si->pszName = mir_strdup( gcw->pszName );
+ }
+
+
+ if ( mi->bColor ) {
+ si->iFG = 4;
+ si->bFGSet = TRUE;
+ }
+ if ( mi->bBkgColor ) {
+ si->iBG = 2;
+ si->bBGSet = TRUE;
+ }
+ if (si->iType == GCW_SERVER)
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("Server: %s"), si->ptszName);
+ else
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%s"), si->ptszName);
+ si->windowData.hContact = CList_AddRoom( gcw->pszModule, ptszID, szTemp, si->iType);
+ si->windowData.codePage = DBGetContactSettingWord(si->windowData.hContact, si->pszModule, "CodePage", (WORD) CP_ACP);
+ si->pszHeader = Log_CreateRtfHeader(mi, si);
+ DBWriteContactSettingString(si->windowData.hContact, si->pszModule , "Topic", "");
+ DBDeleteContactSetting(si->windowData.hContact, "CList", "StatusMsg");
+ if (si->ptszStatusbarText)
+ DBWriteContactSettingTString(si->windowData.hContact, si->pszModule, "StatusBar", si->ptszStatusbarText);
+ else
+ DBWriteContactSettingString(si->windowData.hContact, si->pszModule, "StatusBar", "");
+ }
+ else {
+ SESSION_INFO* si2 = SM_FindSession( ptszID, gcw->pszModule );
+ if ( si2 ) {
+
+ UM_RemoveAll(&si2->pUsers);
+ TM_RemoveAll(&si2->pStatuses);
+
+ si2->iStatusCount = 0;
+ si2->nUsersInNicklist = 0;
+
+ if (si2->hWnd )
+ RedrawWindow(GetDlgItem(si2->hWnd, IDC_CHAT_LIST), NULL, NULL, RDW_INVALIDATE);
+
+ }
+ }
+
+ LeaveCriticalSection(&cs);
+ mir_free( ptszID );
+ return 0;
+ }
+
+ LeaveCriticalSection(&cs);
+ return GC_NEWSESSION_ERROR;
+}
+
+static INT_PTR DoControl(GCEVENT * gce, WPARAM wp)
+{
+ if ( gce->pDest->iType == GC_EVENT_CONTROL ) {
+ switch (wp) {
+ case WINDOW_HIDDEN:
+ {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if (si) {
+ si->bInitDone = TRUE;
+ SetActiveSession(si->ptszID, si->pszModule);
+ if (si->hWnd)
+ ShowRoom(si, wp, FALSE);
+ }
+ }
+ return 0;
+
+ case WINDOW_MINIMIZE:
+ case WINDOW_MAXIMIZE:
+ case WINDOW_VISIBLE:
+ case SESSION_INITDONE:
+ {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if (si) {
+ si->bInitDone = TRUE;
+ if (wp != SESSION_INITDONE || DBGetContactSettingByte(NULL, "Chat", "PopupOnJoin", 0) == 0)
+ ShowRoom(si, wp, TRUE);
+ return 0;
+ } }
+ break;
+
+ case SESSION_OFFLINE:
+ SM_SetOffline(gce->pDest->ptszID, gce->pDest->pszModule);
+ // fall through
+
+ case SESSION_ONLINE:
+ SM_SetStatus( gce->pDest->ptszID, gce->pDest->pszModule, wp==SESSION_ONLINE?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
+ break;
+
+ case WINDOW_CLEARLOG:
+ {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if ( si ) {
+ LM_RemoveAll(&si->pLog, &si->pLogEnd);
+ si->iEventCount = 0;
+ si->LastTime = 0;
+ }
+ break;
+ }
+ case SESSION_TERMINATE:
+ return SM_RemoveSession(gce->pDest->ptszID, gce->pDest->pszModule, (gce->dwFlags & GCEF_REMOVECONTACT) != 0);
+ }
+ SM_SendMessage(gce->pDest->ptszID, gce->pDest->pszModule, GC_EVENT_CONTROL + WM_USER + 500, wp, 0);
+ }
+
+ else if (gce->pDest->iType == GC_EVENT_CHUID && gce->pszText)
+ {
+ SM_ChangeUID( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszNick, gce->ptszText);
+ }
+
+ else if (gce->pDest->iType == GC_EVENT_CHANGESESSIONAME && gce->pszText)
+ {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if ( si ) {
+ replaceStr( &si->ptszName, gce->ptszText );
+ if (si->hWnd)
+ SendMessage(si->hWnd, DM_UPDATETITLEBAR, 0, 0);
+
+ }
+ }
+
+ else if (gce->pDest->iType == GC_EVENT_SETITEMDATA) {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if (si)
+ si->dwItemData = gce->dwItemData;
+ }
+
+ else if (gce->pDest->iType ==GC_EVENT_GETITEMDATA) {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if (si) {
+ gce->dwItemData = si->dwItemData;
+ return si->dwItemData;
+ }
+ return 0;
+ }
+ else if (gce->pDest->iType ==GC_EVENT_SETSBTEXT)
+ {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if (si) {
+ replaceStr( &si->ptszStatusbarText, gce->ptszText );
+ if ( si->ptszStatusbarText )
+ DBWriteContactSettingTString(si->windowData.hContact, si->pszModule, "StatusBar", si->ptszStatusbarText);
+ else
+ DBWriteContactSettingString(si->windowData.hContact, si->pszModule, "StatusBar", "");
+ if (si->hWnd)
+ {
+ SendMessage(si->hWnd, DM_UPDATESTATUSBAR, 0, 0);
+ }
+ }
+ }
+ else if (gce->pDest->iType == GC_EVENT_ACK)
+ {
+ SM_SendMessage(gce->pDest->ptszID, gce->pDest->pszModule, GC_ACKMESSAGE, 0, 0);
+ }
+ else if (gce->pDest->iType == GC_EVENT_SENDMESSAGE && gce->pszText)
+ {
+ SM_SendUserMessage( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszText);
+ }
+ else if (gce->pDest->iType == GC_EVENT_SETSTATUSEX)
+ {
+ SM_SetStatusEx( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszText, gce->dwItemData);
+ }
+ else return 1;
+
+ return 0;
+}
+
+static void AddUser(GCEVENT * gce)
+{
+ SESSION_INFO* si = SM_FindSession( gce->pDest->ptszID, gce->pDest->pszModule);
+ if ( si ) {
+ WORD status = TM_StringToWord( si->pStatuses, gce->ptszStatus );
+ USERINFO * ui = SM_AddUser( si, gce->ptszUID, gce->ptszNick, status);
+ if (ui) {
+ ui->pszNick = mir_tstrdup( gce->ptszNick );
+
+ if (gce->bIsMe)
+ si->pMe = ui;
+
+ ui->Status = status;
+ ui->Status |= si->pStatuses->Status;
+
+ if (si->hWnd) {
+ SendMessage(si->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ }
+ }
+ }
+}
+
+
+void ShowRoom(SESSION_INFO * si, WPARAM wp, BOOL bSetForeground)
+{
+ HWND hParent = NULL;
+ if (!si)
+ return;
+
+ //Do we need to create a window?
+ if (si->hWnd == NULL)
+ {
+ hParent = GetParentWindow(si->windowData.hContact, TRUE);
+ si->hWnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CHANNEL), hParent, RoomWndProc, (LPARAM)si);
+ }
+ SendMessage(si->hWnd, DM_UPDATETABCONTROL, -1, (LPARAM)si);
+ SendMessage(GetParent(si->hWnd), CM_ACTIVATECHILD, 0, (LPARAM) si->hWnd);
+ SendMessage(GetParent(si->hWnd), CM_POPUPWINDOW, 0, (LPARAM) si->hWnd);
+ SendMessage(si->hWnd, WM_MOUSEACTIVATE, 0, 0);
+ SetFocus(GetDlgItem(si->hWnd, IDC_CHAT_MESSAGE));
+}
+
+static INT_PTR Service_AddEvent(WPARAM wParam, LPARAM lParam)
+{
+ GCEVENT *gce = (GCEVENT*)lParam, save_gce;
+ GCDEST *gcd = NULL, save_gcd;
+ TCHAR* pWnd = NULL;
+ char* pMod = NULL;
+ BOOL bIsHighlighted = FALSE;
+ BOOL bRemoveFlag = FALSE;
+ int iRetVal = GC_EVENT_ERROR;
+
+ if ( gce == NULL )
+ return GC_EVENT_ERROR;
+
+ gcd = gce->pDest;
+ if ( gcd == NULL )
+ return GC_EVENT_ERROR;
+
+ if ( gce->cbSize != SIZEOF_STRUCT_GCEVENT_V1 && gce->cbSize != SIZEOF_STRUCT_GCEVENT_V2 )
+ return GC_EVENT_WRONGVER;
+
+ if ( !IsEventSupported( gcd->iType ))
+ return GC_EVENT_ERROR;
+
+ EnterCriticalSection(&cs);
+
+ if ( !( gce->dwFlags & GC_UNICODE )) {
+ save_gce = *gce;
+ save_gcd = *gce->pDest;
+ gce->pDest->ptszID = a2tf( gce->pDest->ptszID, gce->dwFlags );
+ gce->ptszUID = a2tf( gce->ptszUID, gce->dwFlags );
+ gce->ptszNick = a2tf( gce->ptszNick, gce->dwFlags );
+ gce->ptszStatus = a2tf( gce->ptszStatus, gce->dwFlags );
+ gce->ptszText = a2tf( gce->ptszText, gce->dwFlags );
+ gce->ptszUserInfo = a2tf( gce->ptszUserInfo, gce->dwFlags );
+ }
+
+ // Do different things according to type of event
+ switch(gcd->iType) {
+ case GC_EVENT_ADDGROUP:
+ {
+ STATUSINFO* si = SM_AddStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszStatus);
+ if ( si && gce->dwItemData)
+ si->hIcon = CopyIcon((HICON)gce->dwItemData);
+ }
+ iRetVal = 0;
+ goto LBL_Exit;
+
+ case GC_EVENT_CHUID:
+ case GC_EVENT_CHANGESESSIONAME:
+ case GC_EVENT_SETITEMDATA:
+ case GC_EVENT_GETITEMDATA:
+ case GC_EVENT_CONTROL:
+ case GC_EVENT_SETSBTEXT:
+ case GC_EVENT_ACK:
+ case GC_EVENT_SENDMESSAGE :
+ case GC_EVENT_SETSTATUSEX :
+ iRetVal = DoControl(gce, wParam);
+ goto LBL_Exit;
+
+ case GC_EVENT_SETCONTACTSTATUS:
+ iRetVal = SM_SetContactStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, (WORD)gce->dwItemData );
+ goto LBL_Exit;
+
+ case GC_EVENT_TOPIC:
+ {
+ SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
+ if ( si ) {
+ if ( gce->pszText ) {
+ replaceStr( &si->ptszTopic, gce->ptszText);
+ DBWriteContactSettingTString( si->windowData.hContact, si->pszModule , "Topic", RemoveFormatting( si->ptszTopic ));
+ if ( DBGetContactSettingByte( NULL, "Chat", "TopicOnClist", 0 ))
+ DBWriteContactSettingTString( si->windowData.hContact, "CList" , "StatusMsg", RemoveFormatting( si->ptszTopic ));
+ } }
+ break;
+ }
+ case GC_EVENT_ADDSTATUS:
+ SM_GiveStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszStatus );
+ break;
+
+ case GC_EVENT_REMOVESTATUS:
+ SM_TakeStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszStatus);
+ break;
+
+ case GC_EVENT_MESSAGE:
+ case GC_EVENT_ACTION:
+ if ( !gce->bIsMe && gce->pDest->pszID && gce->pszText ) {
+ SESSION_INFO* si = SM_FindSession( gce->pDest->ptszID, gce->pDest->pszModule );
+ if ( si )
+ if ( IsHighlighted( si, gce->ptszText ))
+ bIsHighlighted = TRUE;
+ }
+ break;
+
+ case GC_EVENT_NICK:
+ SM_ChangeNick( gce->pDest->ptszID, gce->pDest->pszModule, gce);
+ break;
+
+ case GC_EVENT_JOIN:
+ AddUser(gce);
+ break;
+
+ case GC_EVENT_PART:
+ case GC_EVENT_QUIT:
+ case GC_EVENT_KICK:
+ bRemoveFlag = TRUE;
+ break;
+ }
+
+ // Decide which window (log) should have the event
+ if ( gcd->pszID ) {
+ pWnd = gcd->ptszID;
+ pMod = gcd->pszModule;
+ }
+ else if ( gcd->iType == GC_EVENT_NOTICE || gcd->iType == GC_EVENT_INFORMATION ) {
+ SESSION_INFO* si = GetActiveSession();
+ if ( si && !lstrcmpA( si->pszModule, gcd->pszModule )) {
+ pWnd = si->ptszID;
+ pMod = si->pszModule;
+ }
+ else {
+ iRetVal = 0;
+ goto LBL_Exit;
+ }
+ }
+ else {
+ // Send the event to all windows with a user pszUID. Used for broadcasting QUIT etc
+ SM_AddEventToAllMatchingUID( gce );
+ if ( !bRemoveFlag ) {
+ iRetVal = 0;
+ goto LBL_Exit;
+ } }
+
+ // add to log
+ if ( pWnd ) {
+ SESSION_INFO* si = SM_FindSession(pWnd, pMod);
+
+ // fix for IRC's old stuyle mode notifications. Should not affect any other protocol
+ if ((gce->pDest->iType == GC_EVENT_ADDSTATUS || gce->pDest->iType == GC_EVENT_REMOVESTATUS) && !( gce->dwFlags & GCEF_ADDTOLOG )) {
+ iRetVal = 0;
+ goto LBL_Exit;
+ }
+
+ if (gce && gce->pDest->iType == GC_EVENT_JOIN && gce->time == 0) {
+ iRetVal = 0;
+ goto LBL_Exit;
+ }
+
+ if (si && (si->bInitDone || gce->pDest->iType == GC_EVENT_TOPIC || (gce->pDest->iType == GC_EVENT_JOIN && gce->bIsMe))) {
+ if (SM_AddEvent(pWnd, pMod, gce, bIsHighlighted) && si->hWnd) {
+ SendMessage(si->hWnd, GC_ADDLOG, 0, 0);
+ }
+ else if (si->hWnd) {
+ SendMessage(si->hWnd, GC_REDRAWLOG2, 0, 0);
+ }
+ DoSoundsFlashPopupTrayStuff(si, gce, bIsHighlighted, 0);
+ if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings.LoggingEnabled)
+ LogToFile(si, gce);
+ }
+
+ if ( !bRemoveFlag ) {
+ iRetVal = 0;
+ goto LBL_Exit;
+ } }
+
+ if ( bRemoveFlag )
+ iRetVal = ( SM_RemoveUser( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID ) == 0 ) ? 1 : 0;
+
+LBL_Exit:
+ LeaveCriticalSection(&cs);
+
+ if ( !( gce->dwFlags & GC_UNICODE )) {
+ mir_free((void*)gce->ptszText );
+ mir_free((void*)gce->ptszNick );
+ mir_free((void*)gce->ptszUID );
+ mir_free((void*)gce->ptszStatus );
+ mir_free((void*)gce->ptszUserInfo );
+ mir_free((void*)gce->pDest->ptszID );
+ *gce = save_gce;
+ *gce->pDest = save_gcd;
+ }
+
+ return iRetVal;
+}
+
+static INT_PTR Service_GetAddEventPtr(WPARAM wParam, LPARAM lParam)
+{
+ GCPTRS * gp = (GCPTRS *) lParam;
+
+ EnterCriticalSection(&cs);
+
+ gp->pfnAddEvent = Service_AddEvent;
+ LeaveCriticalSection(&cs);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Service creation
+
+void HookEvents(void)
+{
+ HookEvent_Ex(ME_CLIST_PREBUILDCONTACTMENU, CList_PrebuildContactMenu);
+}
+
+void CreateServiceFunctions(void)
+{
+ CreateServiceFunction_Ex(MS_GC_REGISTER, Service_Register);
+ CreateServiceFunction_Ex(MS_GC_NEWSESSION, Service_NewChat);
+ CreateServiceFunction_Ex(MS_GC_EVENT, Service_AddEvent);
+ CreateServiceFunction_Ex(MS_GC_GETEVENTPTR, Service_GetAddEventPtr);
+ CreateServiceFunction_Ex(MS_GC_GETINFO, Service_GetInfo);
+ CreateServiceFunction_Ex(MS_GC_GETSESSIONCOUNT, Service_GetCount);
+
+ CreateServiceFunction_Ex("GChat/DblClickEvent", CList_EventDoubleclickedSvc);
+ CreateServiceFunction_Ex("GChat/PrebuildMenuEvent", CList_PrebuildContactMenuSvc);
+ CreateServiceFunction_Ex("GChat/JoinChat", CList_JoinChat);
+ CreateServiceFunction_Ex("GChat/LeaveChat", CList_LeaveChat);
+}
+
+void CreateHookableEvents(void)
+{
+ hSendEvent = CreateHookableEvent(ME_GC_EVENT);
+ hBuildMenuEvent = CreateHookableEvent(ME_GC_BUILDMENU);
+}
+
+void DestroyHookableEvents(void)
+{
+ DestroyHookableEvent(hSendEvent);
+ DestroyHookableEvent(hBuildMenuEvent);
+}
diff --git a/plugins/Scriver/src/chat/tools.cpp b/plugins/Scriver/src/chat/tools.cpp new file mode 100644 index 0000000000..b448ca9aa4 --- /dev/null +++ b/plugins/Scriver/src/chat/tools.cpp @@ -0,0 +1,957 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include <string.h>
+#include <shlwapi.h>
+
+extern FONTINFO aFonts[OPTIONS_FONTCOUNT];
+extern HMENU g_hMenu;
+extern HANDLE hBuildMenuEvent ;
+extern HANDLE hSendEvent;
+
+TCHAR* RemoveFormatting(const TCHAR* pszWord)
+{
+ static TCHAR szTemp[10000];
+ int i = 0;
+ int j = 0;
+
+ if ( pszWord == 0 || lstrlen(pszWord) == 0 )
+ return NULL;
+
+ while(j < 9999 && i <= lstrlen( pszWord )) {
+ if (pszWord[i] == '%') {
+ switch ( pszWord[i+1] ) {
+ case '%':
+ szTemp[j] = '%';
+ j++;
+ i++; i++;
+ break;
+ case 'b':
+ case 'u':
+ case 'i':
+ case 'B':
+ case 'U':
+ case 'I':
+ case 'r':
+ case 'C':
+ case 'F':
+ i++; i++;
+ break;
+
+ case 'c':
+ case 'f':
+ i += 4;
+ break;
+
+ default:
+ szTemp[j] = pszWord[i];
+ j++;
+ i++;
+ break;
+ } }
+ else {
+ szTemp[j] = pszWord[i];
+ j++;
+ i++;
+ } }
+
+ return (TCHAR*) &szTemp;
+}
+
+static void __stdcall ShowRoomFromPopup(void * pi)
+{
+ SESSION_INFO* si = (SESSION_INFO*) pi;
+ ShowRoom(si, WINDOW_VISIBLE, TRUE);
+}
+
+static INT_PTR CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message) {
+ case WM_COMMAND:
+ if (HIWORD(wParam) == STN_CLICKED) {
+ SESSION_INFO* si = (SESSION_INFO*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd,(LPARAM)0);;
+
+ CallFunctionAsync(ShowRoomFromPopup, si);
+
+ PUDeletePopUp(hWnd);
+ return TRUE;
+ }
+ break;
+ case WM_CONTEXTMENU:
+ {
+ SESSION_INFO* si = (SESSION_INFO*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd,(LPARAM)0);
+ if (si->windowData.hContact)
+ if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, (LPARAM)0))
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon");
+
+ PUDeletePopUp( hWnd );
+ }
+ break;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+static int ShowPopup (HANDLE hContact, SESSION_INFO* si, HICON hIcon, char* pszProtoName, TCHAR* pszRoomName, COLORREF crBkg, const TCHAR* fmt, ...)
+{
+ POPUPDATAT pd = {0};
+ va_list marker;
+ static TCHAR szBuf[4*1024];
+
+ if (!fmt || lstrlen(fmt) == 0 || lstrlen(fmt) > 2000)
+ return 0;
+
+ va_start(marker, fmt);
+ _vsntprintf(szBuf, 4096, fmt, marker);
+ va_end(marker);
+
+ pd.lchContact = hContact;
+
+ if ( hIcon )
+ pd.lchIcon = hIcon ;
+ else
+ pd.lchIcon = GetCachedIcon("chat_window");
+
+ mir_sntprintf(pd.lptzContactName, MAX_CONTACTNAME-1, _T(TCHAR_STR_PARAM) _T(" - %s"),
+ pszProtoName, CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR ));
+ lstrcpyn( pd.lptzText, TranslateTS(szBuf), MAX_SECONDLINE-1);
+ pd.iSeconds = g_Settings.iPopupTimeout;
+
+ if (g_Settings.iPopupStyle == 2) {
+ pd.colorBack = 0;
+ pd.colorText = 0;
+ }
+ else if (g_Settings.iPopupStyle == 3) {
+ pd.colorBack = g_Settings.crPUBkgColour;
+ pd.colorText = g_Settings.crPUTextColour;
+ }
+ else {
+ pd.colorBack = g_Settings.crLogBackground;
+ pd.colorText = crBkg;
+ }
+
+ pd.PluginWindowProc = (WNDPROC)PopupDlgProc;
+ pd.PluginData = si;
+ return PUAddPopUpT(&pd);
+}
+
+static BOOL DoTrayIcon(SESSION_INFO* si, GCEVENT * gce)
+{
+ int iEvent = gce->pDest->iType;
+
+ if ( iEvent&g_Settings.dwTrayIconFlags ) {
+ switch ( iEvent ) {
+ case GC_EVENT_MESSAGE|GC_EVENT_HIGHLIGHT :
+ case GC_EVENT_ACTION|GC_EVENT_HIGHLIGHT :
+ CList_AddEvent(si->windowData.hContact, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE), "chaticon", 0, TranslateT("%s wants your attention in %s"), gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_MESSAGE :
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_message_in"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s speaks in %s"), gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_ACTION:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_action"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s speaks in %s"), gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_JOIN:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_join"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s has joined %s"), gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_PART:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_part"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s has left %s"), gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_QUIT:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_quit"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s has disconnected"), gce->ptszNick);
+ break;
+ case GC_EVENT_NICK:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_nick"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s is now known as %s"), gce->ptszNick, gce->pszText);
+ break;
+ case GC_EVENT_KICK:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_kick"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s kicked %s from %s"), gce->pszStatus, gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_NOTICE:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_notice"), "chaticon", CLEF_ONLYAFEW, TranslateT("Notice from %s"), gce->ptszNick);
+ break;
+ case GC_EVENT_TOPIC:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_topic"), "chaticon", CLEF_ONLYAFEW, TranslateT("Topic change in %s"), si->ptszName);
+ break;
+ case GC_EVENT_INFORMATION:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_info"), "chaticon", CLEF_ONLYAFEW, TranslateT("Information in %s"), si->ptszName);
+ break;
+ case GC_EVENT_ADDSTATUS:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_addstatus"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s enables \'%s\' status for %s in %s"), gce->pszText, gce->pszStatus, gce->ptszNick, si->ptszName);
+ break;
+ case GC_EVENT_REMOVESTATUS:
+ CList_AddEvent(si->windowData.hContact, GetCachedIcon("chat_log_removestatus"), "chaticon", CLEF_ONLYAFEW, TranslateT("%s disables \'%s\' status for %s in %s"), gce->pszText, gce->pszStatus, gce->ptszNick, si->ptszName);
+ break;
+ } }
+
+ return TRUE;
+}
+
+static BOOL DoPopup(SESSION_INFO* si, GCEVENT * gce)
+{
+ int iEvent = gce->pDest->iType;
+
+ if ( iEvent & g_Settings.dwPopupFlags ) {
+ switch (iEvent) {
+ case GC_EVENT_MESSAGE|GC_EVENT_HIGHLIGHT :
+ ShowPopup(si->windowData.hContact, si, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE), si->pszModule, si->ptszName, aFonts[16].color, TranslateT("%s says: %s"), gce->ptszNick, RemoveFormatting( gce->ptszText ));
+ break;
+ case GC_EVENT_ACTION|GC_EVENT_HIGHLIGHT :
+ ShowPopup(si->windowData.hContact, si, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE), si->pszModule, si->ptszName, aFonts[16].color, _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_MESSAGE :
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_message_in"), si->pszModule, si->ptszName, aFonts[9].color, TranslateT("%s says: %s"), gce->ptszNick, RemoveFormatting( gce->ptszText));
+ break;
+ case GC_EVENT_ACTION:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_action"), si->pszModule, si->ptszName, aFonts[15].color, _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_JOIN:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_join"), si->pszModule, si->ptszName, aFonts[3].color, TranslateT("%s has joined"), gce->ptszNick);
+ break;
+ case GC_EVENT_PART:
+ if (!gce->pszText)
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_part"), si->pszModule, si->ptszName, aFonts[4].color, TranslateT("%s has left"), gce->ptszNick);
+ else
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_part"), si->pszModule, si->ptszName, aFonts[4].color, TranslateT("%s has left (%s)"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_QUIT:
+ if (!gce->pszText)
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_quit"), si->pszModule, si->ptszName, aFonts[5].color, TranslateT("%s has disconnected"), gce->ptszNick);
+ else
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_quit"), si->pszModule, si->ptszName, aFonts[5].color, TranslateT("%s has disconnected (%s)"), gce->ptszNick,RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_NICK:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_nick"), si->pszModule, si->ptszName, aFonts[7].color, TranslateT("%s is now known as %s"), gce->ptszNick, gce->ptszText);
+ break;
+ case GC_EVENT_KICK:
+ if (!gce->pszText)
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_kick"), si->pszModule, si->ptszName, aFonts[6].color, TranslateT("%s kicked %s"), (char *)gce->pszStatus, gce->ptszNick);
+ else
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_kick"), si->pszModule, si->ptszName, aFonts[6].color, TranslateT("%s kicked %s (%s)"), (char *)gce->pszStatus, gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_NOTICE:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_notice"), si->pszModule, si->ptszName, aFonts[8].color, TranslateT("Notice from %s: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_TOPIC:
+ if (!gce->ptszNick)
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_topic"), si->pszModule, si->ptszName, aFonts[11].color, TranslateT("The topic is \'%s\'"), RemoveFormatting(gce->ptszText));
+ else
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_topic"), si->pszModule, si->ptszName, aFonts[11].color, TranslateT("The topic is \'%s\' (set by %s)"), RemoveFormatting(gce->ptszText), gce->ptszNick);
+ break;
+ case GC_EVENT_INFORMATION:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_info"), si->pszModule, si->ptszName, aFonts[12].color, _T("%s"), RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_ADDSTATUS:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_addstatus"), si->pszModule, si->ptszName, aFonts[13].color, TranslateT("%s enables \'%s\' status for %s"), gce->ptszText, (char *)gce->pszStatus, gce->ptszNick);
+ break;
+ case GC_EVENT_REMOVESTATUS:
+ ShowPopup(si->windowData.hContact, si, GetCachedIcon("chat_log_removestatus"), si->pszModule, si->ptszName, aFonts[14].color, TranslateT("%s disables \'%s\' status for %s"), gce->ptszText, (char *)gce->pszStatus, gce->ptszNick);
+ break;
+ } }
+
+ return TRUE;
+}
+
+BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO* si, GCEVENT * gce, BOOL bHighlight, int bManyFix)
+{
+ BOOL bInactive;
+ int iEvent;
+
+ if (!gce || !si || gce->bIsMe || si->iType == GCW_SERVER)
+ return FALSE;
+
+ bInactive = si->hWnd == NULL || GetForegroundWindow() != GetParent(si->hWnd);
+ // bInactive |= GetActiveWindow() != si->hWnd; // Removed this, because it seemed to be FALSE, even when window was focused, causing incorrect notifications
+
+ iEvent = gce->pDest->iType;
+
+ if ( bHighlight ) {
+ gce->pDest->iType |= GC_EVENT_HIGHLIGHT;
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatHighlight");
+ if (bInactive && si->hWnd && DBGetContactSettingByte(NULL, "Chat", "FlashWindowHighlight", 0) != 0)
+ SendMessage(GetParent(si->hWnd), CM_STARTFLASHING, 0, 0);
+ if (DBGetContactSettingByte(si->windowData.hContact, "CList", "Hidden", 0) != 0)
+ DBDeleteContactSetting(si->windowData.hContact, "CList", "Hidden");
+ if (bInactive)
+ DoTrayIcon(si, gce);
+ if (bInactive || !g_Settings.PopUpInactiveOnly)
+ DoPopup(si, gce);
+ if (bInactive && si->hWnd)
+ SendMessage(si->hWnd, GC_SETMESSAGEHIGHLIGHT, 0, 0);
+ return TRUE;
+ }
+
+ // do blinking icons in tray
+ if (bInactive || !g_Settings.TrayIconInactiveOnly)
+ DoTrayIcon(si, gce);
+
+ // stupid thing to not create multiple popups for a QUIT event for instance
+ if (bManyFix == 0) {
+ // do popups
+ if (bInactive || !g_Settings.PopUpInactiveOnly)
+ DoPopup(si, gce);
+
+ // do sounds and flashing
+ switch (iEvent) {
+ case GC_EVENT_JOIN:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatJoin");
+ break;
+ case GC_EVENT_PART:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatPart");
+ break;
+ case GC_EVENT_QUIT:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatQuit");
+ break;
+ case GC_EVENT_ADDSTATUS:
+ case GC_EVENT_REMOVESTATUS:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatMode");
+ break;
+ case GC_EVENT_KICK:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatKick");
+ break;
+ case GC_EVENT_MESSAGE:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatMessage");
+ if (bInactive && g_Settings.FlashWindow && si->hWnd)
+ SendMessage(GetParent(si->hWnd), CM_STARTFLASHING, 0, 0);
+
+ if (bInactive && !( si->wState & STATE_TALK )) {
+ si->wState |= STATE_TALK;
+ DBWriteContactSettingWord(si->windowData.hContact, si->pszModule,"ApparentMode",(LPARAM)(WORD) 40071);
+ }
+ if (bInactive && si->hWnd)
+ SendMessage(si->hWnd, GC_SETTABHIGHLIGHT, 0, 0);
+ break;
+ case GC_EVENT_ACTION:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatAction");
+ break;
+ case GC_EVENT_NICK:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatNick");
+ break;
+ case GC_EVENT_NOTICE:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatNotice");
+ break;
+ case GC_EVENT_TOPIC:
+ if (bInactive || !g_Settings.SoundsFocus)
+ SkinPlaySound("ChatTopic");
+ break;
+ } }
+
+ return TRUE;
+}
+
+int GetColorIndex(const char* pszModule, COLORREF cr)
+{
+ MODULEINFO * pMod = MM_FindModule(pszModule);
+ int i = 0;
+
+ if (!pMod || pMod->nColorCount == 0)
+ return -1;
+
+ for (i = 0; i < pMod->nColorCount; i++)
+ if (pMod->crColors[i] == cr)
+ return i;
+
+ return -1;
+}
+
+// obscure function that is used to make sure that any of the colors
+// passed by the protocol is used as fore- or background color
+// in the messagebox. THis is to vvercome limitations in the richedit
+// that I do not know currently how to fix
+
+void CheckColorsInModule(const char* pszModule)
+{
+ MODULEINFO * pMod = MM_FindModule( pszModule );
+ int i = 0;
+ COLORREF crFG;
+ COLORREF crBG = (COLORREF)DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &crFG, FALSE);
+
+ if ( !pMod )
+ return;
+
+ for (i = 0; i < pMod->nColorCount; i++) {
+ if (pMod->crColors[i] == crFG || pMod->crColors[i] == crBG) {
+ if (pMod->crColors[i] == RGB(255,255,255))
+ pMod->crColors[i]--;
+ else
+ pMod->crColors[i]++;
+} } }
+
+TCHAR* my_strstri( const TCHAR* s1, const TCHAR* s2)
+{
+ int i,j,k;
+ for(i=0;s1[i];i++)
+ for(j=i,k=0; _totlower(s1[j]) == _totlower(s2[k]);j++,k++)
+ if (!s2[k+1])
+ return (TCHAR*)(s1+i);
+
+ return NULL;
+}
+
+BOOL IsHighlighted(SESSION_INFO* si, const TCHAR* pszText)
+{
+ if ( g_Settings.HighlightEnabled && g_Settings.pszHighlightWords && pszText && si->pMe ) {
+ TCHAR* p1 = g_Settings.pszHighlightWords;
+ TCHAR* p2 = NULL;
+ const TCHAR* p3 = pszText;
+ static TCHAR szWord1[1000];
+ static TCHAR szWord2[1000];
+ static TCHAR szTrimString[] = _T(":,.!?;\'>)");
+
+ // compare word for word
+ while (*p1 != '\0') {
+ // find the next/first word in the highlight word string
+ // skip 'spaces' be4 the word
+ while(*p1 == ' ' && *p1 != '\0')
+ p1 += 1;
+
+ //find the end of the word
+ p2 = _tcschr(p1, ' ');
+ if (!p2)
+ p2 = _tcschr(p1, '\0');
+ if (p1 == p2)
+ return FALSE;
+
+ // copy the word into szWord1
+ lstrcpyn(szWord1, p1, p2-p1>998?999:p2-p1+1);
+ p1 = p2;
+
+ // replace %m with the users nickname
+ p2 = _tcschr(szWord1, '%');
+ if (p2 && p2[1] == 'm') {
+ TCHAR szTemp[50];
+
+ p2[1] = 's';
+ lstrcpyn(szTemp, szWord1, SIZEOF(szTemp));
+ mir_sntprintf(szWord1, SIZEOF(szWord1), szTemp, si->pMe->pszNick);
+ }
+
+ // time to get the next/first word in the incoming text string
+ while(*p3 != '\0')
+ {
+ // skip 'spaces' be4 the word
+ while(*p3 == ' ' && *p3 != '\0')
+ p3 += 1;
+
+ //find the end of the word
+ p2 = (TCHAR *)_tcschr(p3, ' ');
+ if (!p2)
+ p2 = (TCHAR *)_tcschr(p3, '\0');
+
+
+ if (p3 != p2) {
+ // eliminate ending character if needed
+ if (p2-p3 > 1 && _tcschr(szTrimString, p2[-1]))
+ p2 -= 1;
+
+ // copy the word into szWord2 and remove formatting
+ lstrcpyn(szWord2, p3, p2-p3>998?999:p2-p3+1);
+
+ // reset the pointer if it was touched because of an ending character
+ if (*p2 != '\0' && *p2 != ' ')
+ p2 += 1;
+ p3 = p2;
+
+ CharLower(szWord1);
+ CharLower(szWord2);
+
+ // compare the words, using wildcards
+ if (WCCmp(szWord1, RemoveFormatting(szWord2)))
+ return TRUE;
+ } }
+
+ p3 = pszText;
+ } }
+
+ return FALSE;
+}
+
+BOOL LogToFile(SESSION_INFO* si, GCEVENT * gce)
+{
+ MODULEINFO * mi = NULL;
+ TCHAR szBuffer[4096];
+ TCHAR szLine[4096];
+ TCHAR szTime[100];
+ FILE *hFile = NULL;
+ TCHAR tszFile[MAX_PATH];
+ TCHAR tszFolder[MAX_PATH];
+ TCHAR p = '\0';
+ BOOL bFileJustCreated = TRUE;
+
+ if (!si || !gce)
+ return FALSE;
+
+ mi = MM_FindModule(si->pszModule);
+ if ( !mi )
+ return FALSE;
+
+ szBuffer[0] = '\0';
+
+ lstrcpyn(tszFile, GetChatLogsFilename(si->windowData.hContact, gce->time), MAX_PATH);
+ bFileJustCreated = !PathFileExists(tszFile);
+ _tcscpy(tszFolder, tszFile);
+ PathRemoveFileSpec(tszFolder);
+ if (!PathIsDirectory(tszFolder))
+ CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)tszFolder);
+
+ lstrcpyn(szTime, MakeTimeStamp(g_Settings.pszTimeStampLog, gce->time), 99);
+
+ hFile = _tfopen(tszFile, _T("ab+"));
+ if (hFile) {
+ TCHAR szTemp[512], szTemp2[512];
+ TCHAR* pszNick = NULL;
+ if (bFileJustCreated)
+ fputws((const wchar_t*)"\377\376", hFile); //UTF-16 LE BOM == FF FE
+ if ( gce->ptszNick ) {
+ if ( g_Settings.LogLimitNames && lstrlen(gce->ptszNick) > 20 ) {
+ lstrcpyn(szTemp2, gce->ptszNick, 20);
+ lstrcpyn(szTemp2+20, _T("..."), 4);
+ }
+ else lstrcpyn(szTemp2, gce->ptszNick, 511);
+
+ if (gce->pszUserInfo)
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%s (%s)"), szTemp2, gce->pszUserInfo);
+ else
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%s"), szTemp2);
+ pszNick = szTemp;
+ }
+ switch (gce->pDest->iType)
+ {
+ case GC_EVENT_MESSAGE:
+ case GC_EVENT_MESSAGE|GC_EVENT_HIGHLIGHT:
+ p = '*';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), _T("%s * %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_ACTION:
+ case GC_EVENT_ACTION|GC_EVENT_HIGHLIGHT:
+ p = '*';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_JOIN:
+ p = '>';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s has joined"), (char *)pszNick);
+ break;
+ case GC_EVENT_PART:
+ p = '<';
+ if (!gce->pszText)
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s has left"), (char *)pszNick);
+ else
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s has left (%s)"), (char *)pszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_QUIT:
+ p = '<';
+ if (!gce->pszText)
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s has disconnected"), (char *)pszNick);
+ else
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s has disconnected (%s)"), (char *)pszNick,RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_NICK:
+ p = '^';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s is now known as %s"), gce->ptszNick, gce->ptszText);
+ break;
+ case GC_EVENT_KICK:
+ p = '~';
+ if (!gce->pszText)
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s kicked %s"), (char *)gce->pszStatus, gce->ptszNick);
+ else
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s kicked %s (%s)"), (char *)gce->pszStatus, gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_NOTICE:
+ p = 'o';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("Notice from %s: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_TOPIC:
+ p = '#';
+ if (!gce->pszNick)
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("The topic is \'%s\'"), RemoveFormatting(gce->ptszText));
+ else
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("The topic is \'%s\' (set by %s)"), RemoveFormatting(gce->ptszText), gce->ptszNick);
+ break;
+ case GC_EVENT_INFORMATION:
+ p = '!';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), _T("%s"), RemoveFormatting(gce->ptszText));
+ break;
+ case GC_EVENT_ADDSTATUS:
+ p = '+';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s enables \'%s\' status for %s"), gce->ptszText, (char *)gce->pszStatus, gce->ptszNick);
+ break;
+ case GC_EVENT_REMOVESTATUS:
+ p = '-';
+ mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s disables \'%s\' status for %s"), gce->ptszText, (char *)gce->pszStatus, gce->ptszNick);
+ break;
+ }
+ if (p)
+ mir_sntprintf(szLine, SIZEOF(szLine), TranslateT("%s %c %s\r\n"), szTime, p, szBuffer);
+ else
+ mir_sntprintf(szLine, SIZEOF(szLine), TranslateT("%s %s\r\n"), szTime, szBuffer);
+
+ if (szLine[0]) {
+ _fputts(szLine, hFile);
+
+ if (g_Settings.LoggingLimit > 0) {
+ long dwSize;
+ long trimlimit;
+
+ fseek(hFile, 0, SEEK_END);
+ dwSize = ftell(hFile);
+ rewind(hFile);
+ trimlimit = g_Settings.LoggingLimit * 1024 + 1024 * 10;
+ if (dwSize > trimlimit) {
+ BYTE * pBuffer = 0;
+ BYTE * pBufferTemp = 0;
+ size_t read = 0;
+
+ pBuffer = (BYTE *)mir_alloc(g_Settings.LoggingLimit * 1024 + 2);
+ pBuffer[g_Settings.LoggingLimit*1024] = '\0';
+ pBuffer[g_Settings.LoggingLimit*1024+1] = '\0';
+ fseek(hFile, -g_Settings.LoggingLimit*1024, SEEK_END);
+ read = fread(pBuffer, 1, g_Settings.LoggingLimit * 1024, hFile);
+ fclose(hFile);
+ hFile = NULL;
+
+ // trim to whole lines, should help with broken log files I hope.
+ pBufferTemp = (BYTE*)_tcschr((TCHAR*)pBuffer, _T('\n'));
+ if (pBufferTemp) {
+ pBufferTemp+= sizeof(TCHAR);
+ read = read - (pBufferTemp - pBuffer);
+ } else pBufferTemp = pBuffer;
+
+ if (read > 0) {
+ hFile = _tfopen(tszFile, _T("wb"));
+ if (hFile) {
+ fputws((const wchar_t*)"\377\376", hFile); //UTF-16 LE BOM == FF FE
+ fwrite(pBufferTemp, 1, read, hFile);
+ fclose(hFile);
+ hFile = NULL;
+ } }
+ mir_free(pBuffer);
+ } } }
+
+ if (hFile)
+ fclose(hFile);
+ hFile = NULL;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+UINT CreateGCMenu(HWND hwnd, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO* si, TCHAR* pszUID, TCHAR* pszWordText)
+{
+ GCMENUITEMS gcmi = {0};
+ int i;
+ HMENU hSubMenu = 0;
+
+ *hMenu = GetSubMenu(g_hMenu, iIndex);
+ gcmi.pszID = si->ptszID;
+ gcmi.pszModule = si->pszModule;
+ gcmi.pszUID = pszUID;
+
+ if (iIndex == 1) {
+ int iLen = GetRichTextLength(hwnd, CP_ACP, FALSE);
+
+ EnableMenuItem(*hMenu, IDM_CLEAR, MF_ENABLED);
+ EnableMenuItem(*hMenu, ID_COPYALL, MF_ENABLED);
+ if (!iLen) {
+ EnableMenuItem(*hMenu, ID_COPYALL, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(*hMenu, IDM_CLEAR, MF_BYCOMMAND | MF_GRAYED);
+ }
+
+ if ( pszWordText && pszWordText[0] ) {
+ TCHAR szMenuText[4096];
+ mir_sntprintf( szMenuText, 4096, TranslateT("Look up \'%s\':"), pszWordText );
+ ModifyMenu( *hMenu, 4, MF_STRING|MF_BYPOSITION, 4, szMenuText );
+ SetSearchEngineIcons(*hMenu, g_dat->hSearchEngineIconList);
+ }
+ else ModifyMenu( *hMenu, 4, MF_STRING|MF_GRAYED|MF_BYPOSITION, 4, TranslateT( "No word to look up" ));
+ gcmi.Type = MENU_ON_LOG;
+ }
+ else if (iIndex == 0)
+ {
+ TCHAR szTemp[30], szTemp2[30];
+ lstrcpyn(szTemp, TranslateT("&Message"), 24);
+ if ( pszUID )
+ mir_sntprintf( szTemp2, SIZEOF(szTemp2), _T("%s %s"), szTemp, pszUID);
+ else
+ lstrcpyn(szTemp2, szTemp, 24);
+
+ if ( lstrlen(szTemp2) > 22 )
+ lstrcpyn( szTemp2+22, _T("..."), 4 );
+ ModifyMenu( *hMenu, ID_MESS, MF_STRING|MF_BYCOMMAND, ID_MESS, szTemp2 );
+ gcmi.Type = MENU_ON_NICKLIST;
+ }
+
+ NotifyEventHooks(hBuildMenuEvent, 0, (WPARAM)&gcmi);
+
+ if (gcmi.nItems > 0)
+ AppendMenu(*hMenu, MF_SEPARATOR, 0, 0);
+
+ for (i = 0; i < gcmi.nItems; i++) {
+ TCHAR* ptszDescr = a2tf(gcmi.Item[i].pszDesc, si->dwFlags);
+ TCHAR* ptszText = TranslateTS(ptszDescr);
+ DWORD dwState = gcmi.Item[i].bDisabled ? MF_GRAYED : 0;
+
+ if (gcmi.Item[i].uType == MENU_NEWPOPUP) {
+ hSubMenu = CreateMenu();
+ AppendMenu(*hMenu, dwState | MF_POPUP, (UINT_PTR)hSubMenu, ptszText);
+ }
+ else if (gcmi.Item[i].uType == MENU_POPUPHMENU)
+ AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText);
+ else if (gcmi.Item[i].uType == MENU_POPUPITEM)
+ AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText);
+ else if (gcmi.Item[i].uType == MENU_POPUPCHECK)
+ AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText);
+ else if (gcmi.Item[i].uType == MENU_POPUPSEPARATOR)
+ AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, MF_SEPARATOR, 0, ptszText);
+ else if (gcmi.Item[i].uType == MENU_SEPARATOR)
+ AppendMenu(*hMenu, MF_SEPARATOR, 0, ptszText);
+ else if (gcmi.Item[i].uType == MENU_HMENU)
+ AppendMenu(*hMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText);
+ else if (gcmi.Item[i].uType == MENU_ITEM)
+ AppendMenu(*hMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText);
+ else if (gcmi.Item[i].uType == MENU_CHECK)
+ AppendMenu(*hMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText);
+
+ mir_free( ptszDescr );
+ }
+ return TrackPopupMenu(*hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);
+}
+
+void DestroyGCMenu(HMENU *hMenu, int iIndex)
+{
+ MENUITEMINFO mi;
+ mi.cbSize = sizeof(mi);
+ mi.fMask = MIIM_SUBMENU;
+ while(GetMenuItemInfo(*hMenu, iIndex, TRUE, &mi))
+ {
+ if (mi.hSubMenu != NULL)
+ DestroyMenu(mi.hSubMenu);
+ RemoveMenu(*hMenu, iIndex, MF_BYPOSITION);
+ }
+}
+
+BOOL DoEventHookAsync(HWND hwnd, const TCHAR* pszID, const char* pszModule, int iType, TCHAR* pszUID, TCHAR* pszText, DWORD dwItem)
+{
+ SESSION_INFO* si;
+ GCHOOK* gch = (GCHOOK*)mir_alloc( sizeof( GCHOOK ));
+ GCDEST* gcd = (GCDEST*)mir_alloc( sizeof( GCDEST ));
+
+ memset( gch, 0, sizeof( GCHOOK ));
+ memset( gcd, 0, sizeof( GCDEST ));
+
+ replaceStrA( &gcd->pszModule, pszModule);
+ if (( si = SM_FindSession(pszID, pszModule)) == NULL )
+ return FALSE;
+
+ if ( !( si->dwFlags & GC_UNICODE )) {
+ gcd->pszID = t2a( pszID );
+ gch->pszUID = t2a( pszUID );
+ gch->pszText = t2a( pszText );
+ }
+ else {
+ replaceStr( &gcd->ptszID, pszID );
+ replaceStr( &gch->ptszUID, pszUID);
+ replaceStr( &gch->ptszText, pszText);
+ }
+
+ gcd->iType = iType;
+ gch->dwData = dwItem;
+ gch->pDest = gcd;
+ PostMessage(hwnd, GC_FIREHOOK, 0, (LPARAM) gch);
+ return TRUE;
+}
+
+BOOL DoEventHook(const TCHAR* pszID, const char* pszModule, int iType, const TCHAR* pszUID, const TCHAR* pszText, DWORD dwItem)
+{
+ SESSION_INFO* si;
+ GCHOOK gch = {0};
+ GCDEST gcd = {0};
+
+ gcd.pszModule = (char*)pszModule;
+ if (( si = SM_FindSession(pszID, pszModule)) == NULL )
+ return FALSE;
+
+ if ( !( si->dwFlags & GC_UNICODE )) {
+ gcd.pszID = t2a( pszID );
+ gch.pszUID = t2a( pszUID );
+ gch.pszText = t2a( pszText );
+ }
+ else {
+ gcd.ptszID = mir_tstrdup( pszID );
+ gch.ptszUID = mir_tstrdup( pszUID );
+ gch.ptszText = mir_tstrdup( pszText );
+ }
+
+ gcd.iType = iType;
+ gch.dwData = dwItem;
+ gch.pDest = &gcd;
+ NotifyEventHooks(hSendEvent,0,(WPARAM)&gch);
+
+ mir_free( gcd.pszID );
+ mir_free( gch.ptszUID );
+ mir_free( gch.ptszText );
+ return TRUE;
+}
+
+BOOL IsEventSupported(int eventType)
+{
+ switch (eventType)
+ {
+ // Supported events
+ case GC_EVENT_JOIN:
+ case GC_EVENT_PART:
+ case GC_EVENT_QUIT:
+ case GC_EVENT_KICK:
+ case GC_EVENT_NICK:
+ case GC_EVENT_NOTICE:
+ case GC_EVENT_MESSAGE:
+ case GC_EVENT_TOPIC:
+ case GC_EVENT_INFORMATION:
+ case GC_EVENT_ACTION:
+ case GC_EVENT_ADDSTATUS:
+ case GC_EVENT_REMOVESTATUS:
+ case GC_EVENT_CHUID:
+ case GC_EVENT_CHANGESESSIONAME:
+ case GC_EVENT_ADDGROUP:
+ case GC_EVENT_SETITEMDATA:
+ case GC_EVENT_GETITEMDATA:
+ case GC_EVENT_SETSBTEXT:
+ case GC_EVENT_ACK:
+ case GC_EVENT_SENDMESSAGE:
+ case GC_EVENT_SETSTATUSEX:
+ case GC_EVENT_CONTROL:
+ case GC_EVENT_SETCONTACTSTATUS:
+ return TRUE;
+ }
+
+ // Other events
+ return FALSE;
+}
+
+TCHAR* a2tf( const TCHAR* str, int flags )
+{
+ if ( str == NULL )
+ return NULL;
+
+ if ( flags & GC_UNICODE )
+ return mir_tstrdup( str );
+ else {
+ int codepage = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 );
+
+ int cbLen = MultiByteToWideChar( codepage, 0, (char*)str, -1, 0, 0 );
+ TCHAR* result = ( TCHAR* )mir_alloc( sizeof(TCHAR)*( cbLen+1 ));
+ if ( result == NULL )
+ return NULL;
+
+ MultiByteToWideChar( codepage, 0, (char*)str, -1, result, cbLen );
+ result[ cbLen ] = 0;
+ return result;
+ }
+}
+
+TCHAR* replaceStr( TCHAR** dest, const TCHAR* src )
+{
+ mir_free( *dest );
+ *dest = mir_tstrdup( src );
+ return *dest;
+}
+
+char* replaceStrA( char** dest, const char* src )
+{
+ mir_free( *dest );
+ *dest = mir_strdup( src );
+ return *dest;
+}
+
+TCHAR* GetChatLogsFilename (HANDLE hContact, time_t tTime)
+{ REPLACEVARSARRAY rva[11];
+ REPLACEVARSDATA dat = {0};
+ static TCHAR tszFileName[MAX_PATH];
+ TCHAR *p = {0}, *tszParsedName = {0};
+ int i;
+
+ if (g_Settings.pszLogDir[_tcslen(g_Settings.pszLogDir)-1] == '\\')
+ _tcscat(g_Settings.pszLogDir, _T("%userid%.log"));
+ if (!tTime)
+ time(&tTime);
+
+ // day 1-31
+ rva[0].lptzKey = _T("d");
+ rva[0].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%#d"), tTime));
+ // day 01-31
+ rva[1].lptzKey = _T("dd");
+ rva[1].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%d"), tTime));
+ // month 1-12
+ rva[2].lptzKey = _T("m");
+ rva[2].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%#m"), tTime));
+ // month 01-12
+ rva[3].lptzKey = _T("mm");
+ rva[3].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%m"), tTime));
+ // month text short
+ rva[4].lptzKey = _T("mon");
+ rva[4].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%b"), tTime));
+ // month text
+ rva[5].lptzKey = _T("month");
+ rva[5].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%B"), tTime));
+ // year 01-99
+ rva[6].lptzKey = _T("yy");
+ rva[6].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%y"), tTime));
+ // year 1901-9999
+ rva[7].lptzKey = _T("yyyy");
+ rva[7].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%Y"), tTime));
+ // weekday short
+ rva[8].lptzKey = _T("wday");
+ rva[8].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%a"), tTime));
+ // weekday
+ rva[9].lptzKey = _T("weekday");
+ rva[9].lptzValue = mir_tstrdup(MakeTimeStamp(_T("%A"), tTime));
+ // end of array
+ rva[10].lptzKey = NULL;
+ rva[10].lptzValue = NULL;
+
+ dat.cbSize = sizeof(dat);
+ dat.dwFlags = RVF_TCHAR;
+ dat.hContact = hContact;
+ dat.variables = rva;
+ tszParsedName = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)g_Settings.pszLogDir, (LPARAM)&dat);
+ _tcsncpy(tszFileName, tszParsedName, MAX_PATH);
+ mir_free(tszParsedName);
+ for (i=0; i < SIZEOF(rva);i++)
+ mir_free(rva[i].lptzValue);
+
+ for (p = tszFileName + 2; *p; ++p) {
+ if (*p == ':' || *p == '*' || *p == '?' || *p == '"' || *p == '<' || *p == '>' || *p == '|' )
+ *p = _T('_');
+ }
+
+ return tszFileName;
+}
diff --git a/plugins/Scriver/src/chat/window.cpp b/plugins/Scriver/src/chat/window.cpp new file mode 100644 index 0000000000..bf637ccb2b --- /dev/null +++ b/plugins/Scriver/src/chat/window.cpp @@ -0,0 +1,2188 @@ +/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+Copyright 2003-2009 Miranda ICQ/IM project,
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "../commonheaders.h"
+#include "chat.h"
+#include "../utils.h"
+#include "../statusicon.h"
+
+#ifndef WM_UNICHAR
+#define WM_UNICHAR 0x0109
+#endif
+
+extern HBRUSH hListBkgBrush;
+extern HBRUSH hListSelectedBkgBrush;
+extern HANDLE hSendEvent;
+extern CREOleCallback reOleCallback;
+extern HMENU g_hMenu;
+extern TABLIST * g_TabList;
+extern HANDLE hHookWinPopup;
+extern HCURSOR hCurSplitNS, hCurSplitWE;
+
+static WNDPROC OldSplitterProc;
+static WNDPROC OldMessageProc;
+static WNDPROC OldNicklistProc;
+static WNDPROC OldFilterButtonProc;
+static WNDPROC OldLogProc;
+
+static ToolbarButton toolbarButtons[] = {
+ {_T("Bold"), IDC_CHAT_BOLD, 0, 4, 24},
+ {_T("Italic"), IDC_CHAT_ITALICS, 0, 0, 24},
+ {_T("Underline"), IDC_CHAT_UNDERLINE, 0, 0, 24},
+ {_T("Text color"), IDC_CHAT_COLOR, 0, 0, 24},
+ {_T("Background color"), IDC_CHAT_BKGCOLOR, 0, 0, 24},
+// {_T("Font size"), IDC_CHAT_FONTSIZE, 0, 0, 48},
+ {_T("Smiley"), IDC_CHAT_SMILEY, 0, 8, 24},
+ {_T("History"), IDC_CHAT_HISTORY, 1, 0, 24},
+ {_T("Filter"), IDC_CHAT_FILTER, 1, 0, 24},
+ {_T("Manager"), IDC_CHAT_CHANMGR, 1, 0, 24},
+ {_T("Nick list"), IDC_CHAT_SHOWNICKLIST, 1, 0, 24},
+ {_T("Send"), IDOK, 1, 0, 38},
+};
+
+typedef struct
+{
+ time_t lastEnterTime;
+ TCHAR* szSearchQuery;
+ TCHAR* szSearchResult;
+ SESSION_INFO *lastSession;
+} MESSAGESUBDATA;
+
+
+static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_NCHITTEST:
+ return HTCLIENT;
+
+ case WM_SETCURSOR:
+ {
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE);
+ return TRUE;
+ }
+ return 0;
+ case WM_LBUTTONDOWN:
+ SetCapture(hwnd);
+ return 0;
+
+ case WM_MOUSEMOVE:
+ if (GetCapture()==hwnd) {
+ RECT rc;
+ GetClientRect(hwnd,&rc);
+ SendMessage(GetParent(hwnd),GC_SPLITTERMOVED,rc.right>rc.bottom?(short)HIWORD(GetMessagePos())+rc.bottom/2:(short)LOWORD(GetMessagePos())+rc.right/2,(LPARAM)hwnd);
+ }
+ return 0;
+
+ case WM_LBUTTONUP:
+ ReleaseCapture();
+ PostMessage(GetParent(hwnd),WM_SIZE, 0, 0);
+ return 0;
+ }
+ return CallWindowProc(OldSplitterProc,hwnd,msg,wParam,lParam);
+}
+
+static void InitButtons(HWND hwndDlg, SESSION_INFO* si)
+{
+ MODULEINFO * pInfo = MM_FindModule(si->pszModule);
+
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SMILEY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_smiley"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_BOLD,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_bold"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_ITALICS,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_italics"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_UNDERLINE,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_underline"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_COLOR,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_fgcol"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_BKGCOLOR,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_bkgcol"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_HISTORY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_history"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_CHANMGR,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon("chat_settings"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SHOWNICKLIST,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon(si->bNicklistEnabled?"chat_nicklist":"chat_nicklist2"));
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_FILTER,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon(si->bFilterEnabled?"chat_filter":"chat_filter2"));
+ SendDlgItemMessage(hwndDlg, IDOK, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_SEND"));
+
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SMILEY, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_BOLD, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_ITALICS, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_UNDERLINE, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_BKGCOLOR, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_COLOR, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_HISTORY, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SHOWNICKLIST, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_CHANMGR, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_FILTER, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg,IDOK, BUTTONSETASFLATBTN, TRUE, 0);
+
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_SMILEY), BUTTONADDTOOLTIP, (WPARAM)Translate("Insert a smiley"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_BOLD), BUTTONADDTOOLTIP, (WPARAM)Translate("Make the text bold (CTRL+B)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_ITALICS), BUTTONADDTOOLTIP, (WPARAM)Translate("Make the text italicized (CTRL+I)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_UNDERLINE), BUTTONADDTOOLTIP, (WPARAM)Translate("Make the text underlined (CTRL+U)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_BKGCOLOR), BUTTONADDTOOLTIP, (WPARAM)Translate("Select a background color for the text (CTRL+L)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_COLOR), BUTTONADDTOOLTIP, (WPARAM)Translate("Select a foreground color for the text (CTRL+K)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_HISTORY), BUTTONADDTOOLTIP, (WPARAM)Translate("Show the history (CTRL+H)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_SHOWNICKLIST), BUTTONADDTOOLTIP, (WPARAM)Translate("Show/hide the nicklist (CTRL+N)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_CHANMGR), BUTTONADDTOOLTIP, (WPARAM)Translate("Control this room (CTRL+O)"), 0);
+ SendMessage(GetDlgItem(hwndDlg,IDC_CHAT_FILTER), BUTTONADDTOOLTIP, (WPARAM)Translate("Enable/disable the event filter (CTRL+F)"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDOK), BUTTONADDTOOLTIP, (WPARAM) Translate("Send Message"), 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_BOLD, BUTTONSETASPUSHBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_ITALICS, BUTTONSETASPUSHBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_UNDERLINE, BUTTONSETASPUSHBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_COLOR, BUTTONSETASPUSHBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_BKGCOLOR, BUTTONSETASPUSHBTN, TRUE, 0);
+
+ if (pInfo)
+ {
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_BOLD), pInfo->bBold);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_ITALICS), pInfo->bItalics);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_UNDERLINE), pInfo->bUnderline);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_COLOR), pInfo->bColor);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_BKGCOLOR), pInfo->bBkgColor);
+ if (si->iType == GCW_CHATROOM)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_CHANMGR), pInfo->bChanMgr);
+ }
+}
+
+
+static void MessageDialogResize(HWND hwndDlg, SESSION_INFO *si, int w, int h) {
+ int logBottom, toolbarTopY;
+ HDWP hdwp;
+ BOOL bNick = si->iType!=GCW_SERVER && si->bNicklistEnabled;
+ BOOL bToolbar = SendMessage(GetParent(hwndDlg), CM_GETTOOLBARSTATUS, 0, 0);
+ int buttonVisibility = bToolbar ? g_dat->chatBbuttonVisibility : 0;
+ int hSplitterMinTop = TOOLBAR_HEIGHT + si->windowData.minLogBoxHeight, hSplitterMinBottom = si->windowData.minEditBoxHeight;
+ int toolbarHeight = bToolbar ? IsToolbarVisible(SIZEOF(toolbarButtons), g_dat->chatBbuttonVisibility) ? TOOLBAR_HEIGHT : TOOLBAR_HEIGHT / 3 : 0;
+
+ si->iSplitterY = si->desiredInputAreaHeight + SPLITTER_HEIGHT + 3;
+
+ if (h - si->iSplitterY < hSplitterMinTop) {
+ si->iSplitterY = h - hSplitterMinTop;
+ }
+ if (si->iSplitterY < hSplitterMinBottom) {
+ si->iSplitterY = hSplitterMinBottom;
+ }
+
+ ShowToolbarControls(hwndDlg, SIZEOF(toolbarButtons), toolbarButtons, buttonVisibility, SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHAT_SPLITTERX), bNick?SW_SHOW:SW_HIDE);
+ if (si->iType != GCW_SERVER)
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIST), si->bNicklistEnabled?SW_SHOW:SW_HIDE);
+ else
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIST), SW_HIDE);
+
+ if (si->iType == GCW_SERVER) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_SHOWNICKLIST), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_FILTER), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_CHANMGR), FALSE);
+ } else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_SHOWNICKLIST), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_FILTER), TRUE);
+ if (si->iType == GCW_CHATROOM)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_CHANMGR), MM_FindModule(si->pszModule)->bChanMgr);
+ }
+
+ hdwp = BeginDeferWindowPos(20);
+ toolbarTopY = bToolbar ? h - si->iSplitterY - toolbarHeight : h - si->iSplitterY;
+ if (si->windowData.hwndLog != NULL) {
+ logBottom = toolbarTopY / 2;
+ } else {
+ logBottom = toolbarTopY;
+ }
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_LOG), 0, 1, 0, bNick?w - si->iSplitterX - 1:w - 2, logBottom, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_LIST), 0, w - si->iSplitterX + 2, 0, si->iSplitterX - 3, toolbarTopY, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_SPLITTERX), 0, w - si->iSplitterX, 1, 2, toolbarTopY - 1, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_SPLITTERY), 0, 0, h - si->iSplitterY, w, SPLITTER_HEIGHT, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), 0, 1, h - si->iSplitterY + SPLITTER_HEIGHT, w - 2, si->iSplitterY - SPLITTER_HEIGHT - 1, SWP_NOZORDER);
+/*
+
+ toolbarTopY = h - toolbarHeight;
+ if (si->windowData.hwndLog != NULL) {
+ logBottom = (h - si->iSplitterY) / 2;
+ } else {
+ logBottom = h - si->iSplitterY;
+ }
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_LOG), 0, 0, 0, bNick?w - si->iSplitterX:w, logBottom, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_LIST), 0, w - si->iSplitterX + 2, 0, si->iSplitterX - 1, h - si->iSplitterY, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_SPLITTERX), 0, w - si->iSplitterX, 1, 2, h - si->iSplitterY, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_SPLITTERY), 0, 0, h - si->iSplitterY, w, splitterHeight, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), 0, 0, h - si->iSplitterY + splitterHeight, bSend?w-64:w, si->iSplitterY - toolbarHeight - splitterHeight, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDOK), 0, w - 64, h - si->iSplitterY + splitterHeight, 64, si->iSplitterY - toolbarHeight - splitterHeight - 1, SWP_NOZORDER);
+
+*/
+
+ hdwp = ResizeToolbar(hwndDlg, hdwp, w, toolbarTopY + 1, toolbarHeight - 1, SIZEOF(toolbarButtons), toolbarButtons, buttonVisibility);
+ EndDeferWindowPos(hdwp);
+ if (si->windowData.hwndLog != NULL) {
+ RECT rect;
+ POINT pt;
+ IEVIEWWINDOW ieWindow;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_CHAT_LOG), &rect);
+ pt.x = 0;
+ pt.y = rect.top;
+ ScreenToClient(GetDlgItem(hwndDlg,IDC_CHAT_LOG),&pt);
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_SETPOS;
+ ieWindow.parent = hwndDlg;
+ ieWindow.hwnd = si->windowData.hwndLog;
+ ieWindow.x = 0;
+ ieWindow.y = logBottom + 1;
+ ieWindow.cx = bNick ? w - si->iSplitterX:w;
+ ieWindow.cy = logBottom;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ } else {
+ RedrawWindow(GetDlgItem(hwndDlg,IDC_CHAT_LOG), NULL, NULL, RDW_INVALIDATE);
+ }
+ RedrawWindow(GetDlgItem(hwndDlg,IDC_CHAT_LIST), NULL, NULL, RDW_INVALIDATE);
+ RedrawWindow(GetDlgItem(hwndDlg,IDC_CHAT_MESSAGE), NULL, NULL, RDW_INVALIDATE);
+}
+
+
+static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int start;
+ int result;
+ MESSAGESUBDATA *dat;
+ SESSION_INFO* Parentsi;
+ CommonWindowData *windowData;
+ BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000;
+ BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000;
+ BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
+
+ Parentsi=(SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
+ dat = (MESSAGESUBDATA *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ windowData = &Parentsi->windowData;
+
+ result = InputAreaShortcuts(hwnd, msg, wParam, lParam, windowData);
+ if (result != -1) {
+ return result;
+ }
+
+ switch (msg) {
+ case EM_SUBCLASSED:
+ dat = (MESSAGESUBDATA *) mir_alloc(sizeof(MESSAGESUBDATA));
+ ZeroMemory(dat, sizeof(MESSAGESUBDATA));
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) dat);
+ return 0;
+
+ case WM_MOUSEWHEEL:
+ if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_VSCROLL) == 0) {
+ SendMessage(GetDlgItem(GetParent(hwnd), IDC_CHAT_LOG), WM_MOUSEWHEEL, wParam, lParam);
+ }
+ dat->lastEnterTime = 0;
+ return TRUE;
+
+ case EM_REPLACESEL:
+ PostMessage(hwnd, EM_ACTIVATE, 0, 0);
+ break;
+
+ case EM_ACTIVATE:
+ SetActiveWindow(GetParent(hwnd));
+ break;
+
+ case WM_KEYDOWN:
+ {
+ if (wParam == VK_RETURN) {
+ mir_free(dat->szSearchQuery);
+ dat->szSearchQuery = NULL;
+ mir_free(dat->szSearchResult);
+ dat->szSearchResult = NULL;
+ if (( isCtrl != 0 ) ^ (0 != DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))) {
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER)) {
+ if (dat->lastEnterTime + 2 < time(NULL))
+ dat->lastEnterTime = time(NULL);
+ else {
+ SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0);
+ SendMessage(hwnd, WM_KEYUP, VK_BACK, 0);
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ } } } else {
+ dat->lastEnterTime = 0;
+ }
+
+
+ if (wParam == VK_TAB && isShift && !isCtrl) { // SHIFT-TAB (go to nick list)
+ SetFocus(GetDlgItem(GetParent(hwnd), IDC_CHAT_LIST));
+ return TRUE;
+ }
+
+ if (wParam == VK_TAB && !isCtrl && !isShift) { //tab-autocomplete
+ int iLen, end, topicStart;
+ BOOL isTopic = FALSE;
+ BOOL isRoom = FALSE;
+ TCHAR* pszText = NULL;
+ GETTEXTEX gt = {0};
+ LRESULT lResult = (LRESULT)SendMessage(hwnd, EM_GETSEL, (WPARAM)NULL, (LPARAM)NULL);
+
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
+ start = LOWORD(lResult);
+ end = HIWORD(lResult);
+ SendMessage(hwnd, EM_SETSEL, end, end);
+
+ gt.codepage = 1200;
+ iLen = GetRichTextLength(hwnd, gt.codepage, TRUE);
+ if (iLen >0) {
+ TCHAR *pszName = NULL;
+ pszText = (TCHAR *)mir_alloc(iLen + 100 * sizeof(TCHAR));
+ gt.cb = iLen + 99 * sizeof(TCHAR);
+ gt.flags = GT_DEFAULT;
+
+ SendMessage(hwnd, EM_GETTEXTEX, (WPARAM)>, (LPARAM)pszText);
+ if (start > 1 && pszText[start-1] == ' ' && pszText[start-2] == ':') {
+ start--;
+ }
+ while ( start >0 && pszText[start-1] != ' ' && pszText[start-1] != 13 && pszText[start-1] != VK_TAB)
+ start--;
+ while (end < iLen && pszText[end] != ' ' && pszText[end] != 13 && pszText[end-1] != VK_TAB)
+ end ++;
+ if (pszText[start] == '#') {
+ isRoom = TRUE;
+ } else {
+ topicStart = start;
+ while ( topicStart >0 && (pszText[topicStart-1] == ' ' || pszText[topicStart-1] == 13 || pszText[topicStart-1] == VK_TAB))
+ topicStart--;
+ if (topicStart > 5 && _tcsstr(&pszText[topicStart-6], _T("/topic")) == &pszText[topicStart-6]) {
+ isTopic = TRUE;
+ }
+ }
+ if ( dat->szSearchQuery == NULL) {
+ dat->szSearchQuery = (TCHAR *)mir_alloc( sizeof(TCHAR)*( end-start+1 ));
+ lstrcpyn( dat->szSearchQuery, pszText+start, end-start+1);
+ dat->szSearchResult = mir_tstrdup(dat->szSearchQuery);
+ dat->lastSession = NULL;
+ }
+ if (isTopic) {
+ pszName = Parentsi->ptszTopic;
+ } else if (isRoom) {
+ dat->lastSession = SM_FindSessionAutoComplete(Parentsi->pszModule, Parentsi, dat->lastSession, dat->szSearchQuery, dat->szSearchResult);
+ if (dat->lastSession != NULL) {
+ pszName = dat->lastSession->ptszName;
+ }
+ } else {
+ pszName = UM_FindUserAutoComplete(Parentsi->pUsers, dat->szSearchQuery, dat->szSearchResult);
+ }
+ mir_free(pszText);
+ pszText = NULL;
+ mir_free(dat->szSearchResult);
+ dat->szSearchResult = NULL;
+ if (pszName == NULL) {
+ if (end !=start) {
+ SendMessage(hwnd, EM_SETSEL, start, end);
+ SendMessage(hwnd, EM_REPLACESEL, FALSE, (LPARAM) dat->szSearchQuery);
+ }
+ mir_free(dat->szSearchQuery);
+ dat->szSearchQuery = NULL;
+ } else {
+ dat->szSearchResult = mir_tstrdup(pszName);
+ if (end !=start) {
+ if (!isRoom && !isTopic && g_Settings.AddColonToAutoComplete && start == 0) {
+ pszText = (TCHAR *)mir_alloc((_tcslen(pszName) + 4) * sizeof(TCHAR));
+ _tcscpy(pszText, pszName);
+ _tcscat(pszText, _T(": "));
+ pszName = pszText;
+ }
+ SendMessage(hwnd, EM_SETSEL, start, end);
+ SendMessage(hwnd, EM_REPLACESEL, FALSE, (LPARAM) pszName);
+ }
+ mir_free(pszText);
+ }
+ }
+
+ SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
+ return 0;
+ } else if (wParam != VK_RIGHT && wParam != VK_LEFT) {
+ mir_free(dat->szSearchQuery);
+ dat->szSearchQuery = NULL;
+ mir_free(dat->szSearchResult);
+ dat->szSearchResult = NULL;
+ }
+ if (wParam == 0x49 && isCtrl && !isAlt) { // ctrl-i (italics)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_ITALICS, IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_ITALICS) == BST_UNCHECKED?BST_CHECKED:BST_UNCHECKED);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_ITALICS, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x42 && isCtrl && !isAlt) { // ctrl-b (bold)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BOLD, IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_BOLD) == BST_UNCHECKED?BST_CHECKED:BST_UNCHECKED);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_BOLD, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x55 && isCtrl && !isAlt) { // ctrl-u (paste clean text)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_UNDERLINE, IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_UNDERLINE) == BST_UNCHECKED?BST_CHECKED:BST_UNCHECKED);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_UNDERLINE, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x4b && isCtrl && !isAlt) { // ctrl-k (paste clean text)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_COLOR, IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_COLOR) == BST_UNCHECKED?BST_CHECKED:BST_UNCHECKED);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_COLOR, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == VK_SPACE && isCtrl && !isAlt) { // ctrl-space (paste clean text)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BKGCOLOR, BST_UNCHECKED);
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_COLOR, BST_UNCHECKED);
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BOLD, BST_UNCHECKED);
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_UNDERLINE, BST_UNCHECKED);
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_ITALICS, BST_UNCHECKED);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_BKGCOLOR, 0), 0);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_COLOR, 0), 0);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_BOLD, 0), 0);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_UNDERLINE, 0), 0);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_ITALICS, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x4c && isCtrl && !isAlt) { // ctrl-l (paste clean text)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BKGCOLOR, IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_BKGCOLOR) == BST_UNCHECKED?BST_CHECKED:BST_UNCHECKED);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_BKGCOLOR, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x46 && isCtrl && !isAlt) { // ctrl-f (paste clean text)
+ if (IsWindowEnabled(GetDlgItem(GetParent(hwnd), IDC_CHAT_FILTER)))
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_FILTER, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x4e && isCtrl && !isAlt) { // ctrl-n (nicklist)
+ if (IsWindowEnabled(GetDlgItem(GetParent(hwnd), IDC_CHAT_SHOWNICKLIST)))
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_SHOWNICKLIST, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x48 && isCtrl && !isAlt) { // ctrl-h (history)
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_HISTORY, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == 0x4f && isCtrl && !isAlt) { // ctrl-o (options)
+ if (IsWindowEnabled(GetDlgItem(GetParent(hwnd), IDC_CHAT_CHANMGR)))
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_CHAT_CHANMGR, 0), 0);
+ return TRUE;
+ }
+
+ if (wParam == VK_NEXT || wParam == VK_PRIOR) {
+ HWND htemp = GetParent(hwnd);
+ SendDlgItemMessage(htemp, IDC_CHAT_LOG, msg, wParam, lParam);
+ return TRUE;
+ }
+ break;
+ }
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_KILLFOCUS:
+ dat->lastEnterTime = 0;
+ break;
+ case WM_CONTEXTMENU:
+ InputAreaContextMenu(hwnd, wParam, lParam, Parentsi->windowData.hContact);
+ return TRUE;
+
+ case WM_KEYUP:
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ {
+ CHARFORMAT2 cf;
+ UINT u = 0;
+ UINT u2 = 0;
+ COLORREF cr;
+
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &cr, FALSE);
+
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_BACKCOLOR|CFM_COLOR;
+ SendMessage(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+
+ if (MM_FindModule(Parentsi->pszModule) && MM_FindModule(Parentsi->pszModule)->bColor) {
+ int index = GetColorIndex(Parentsi->pszModule, cf.crTextColor);
+ u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_COLOR);
+
+ if (index >= 0) {
+ Parentsi->bFGSet = TRUE;
+ Parentsi->iFG = index;
+ }
+
+ if (u == BST_UNCHECKED && cf.crTextColor != cr)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_COLOR, BST_CHECKED);
+ else if (u == BST_CHECKED && cf.crTextColor == cr)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_COLOR, BST_UNCHECKED);
+ }
+
+ if (MM_FindModule(Parentsi->pszModule) && MM_FindModule(Parentsi->pszModule)->bBkgColor) {
+ int index = GetColorIndex(Parentsi->pszModule, cf.crBackColor);
+ COLORREF crB = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+ u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_BKGCOLOR);
+
+ if (index >= 0) {
+ Parentsi->bBGSet = TRUE;
+ Parentsi->iBG = index;
+ }
+ if (u == BST_UNCHECKED && cf.crBackColor != crB)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BKGCOLOR, BST_CHECKED);
+ else if (u == BST_CHECKED && cf.crBackColor == crB)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BKGCOLOR, BST_UNCHECKED);
+ }
+
+ if (MM_FindModule(Parentsi->pszModule) && MM_FindModule(Parentsi->pszModule)->bBold) {
+ u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_BOLD);
+ u2 = cf.dwEffects;
+ u2 &= CFE_BOLD;
+ if (u == BST_UNCHECKED && u2)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BOLD, BST_CHECKED);
+ else if (u == BST_CHECKED && u2 == 0)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_BOLD, BST_UNCHECKED);
+ }
+
+ if (MM_FindModule(Parentsi->pszModule) && MM_FindModule(Parentsi->pszModule)->bItalics) {
+ u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_ITALICS);
+ u2 = cf.dwEffects;
+ u2 &= CFE_ITALIC;
+ if (u == BST_UNCHECKED && u2)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_ITALICS, BST_CHECKED);
+ else if (u == BST_CHECKED && u2 == 0)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_ITALICS, BST_UNCHECKED);
+ }
+
+ if (MM_FindModule(Parentsi->pszModule) && MM_FindModule(Parentsi->pszModule)->bUnderline) {
+ u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_UNDERLINE);
+ u2 = cf.dwEffects;
+ u2 &= CFE_UNDERLINE;
+ if (u == BST_UNCHECKED && u2)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_UNDERLINE, BST_CHECKED);
+ else if (u == BST_CHECKED && u2 == 0)
+ CheckDlgButton(GetParent(hwnd), IDC_CHAT_UNDERLINE, BST_UNCHECKED);
+ } }
+ break;
+
+ case EM_UNSUBCLASSED:
+ mir_free(dat->szSearchQuery);
+ mir_free(dat->szSearchResult);
+ mir_free(dat);
+ return 0;
+ }
+
+ return CallWindowProc(OldMessageProc, hwnd, msg, wParam, lParam);
+}
+
+static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ static SESSION_INFO* si = NULL;
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ si = (SESSION_INFO *)lParam;
+ CheckDlgButton(hwndDlg, IDC_CHAT_1, si->iLogFilterFlags&GC_EVENT_ACTION);
+ CheckDlgButton(hwndDlg, IDC_CHAT_2, si->iLogFilterFlags&GC_EVENT_MESSAGE);
+ CheckDlgButton(hwndDlg, IDC_CHAT_3, si->iLogFilterFlags&GC_EVENT_NICK);
+ CheckDlgButton(hwndDlg, IDC_CHAT_4, si->iLogFilterFlags&GC_EVENT_JOIN);
+ CheckDlgButton(hwndDlg, IDC_CHAT_5, si->iLogFilterFlags&GC_EVENT_PART);
+ CheckDlgButton(hwndDlg, IDC_CHAT_6, si->iLogFilterFlags&GC_EVENT_TOPIC);
+ CheckDlgButton(hwndDlg, IDC_CHAT_7, si->iLogFilterFlags&GC_EVENT_ADDSTATUS);
+ CheckDlgButton(hwndDlg, IDC_CHAT_8, si->iLogFilterFlags&GC_EVENT_INFORMATION);
+ CheckDlgButton(hwndDlg, IDC_CHAT_9, si->iLogFilterFlags&GC_EVENT_QUIT);
+ CheckDlgButton(hwndDlg, IDC_CHAT_10, si->iLogFilterFlags&GC_EVENT_KICK);
+ CheckDlgButton(hwndDlg, IDC_CHAT_11, si->iLogFilterFlags&GC_EVENT_NOTICE);
+ break;
+
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ SetTextColor((HDC)wParam,RGB(60,60,150));
+ SetBkColor((HDC)wParam,GetSysColor(COLOR_WINDOW));
+ return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
+
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) == WA_INACTIVE) {
+ int iFlags = 0;
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_1) == BST_CHECKED)
+ iFlags |= GC_EVENT_ACTION;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_2) == BST_CHECKED)
+ iFlags |= GC_EVENT_MESSAGE;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_3) == BST_CHECKED)
+ iFlags |= GC_EVENT_NICK;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_4) == BST_CHECKED)
+ iFlags |= GC_EVENT_JOIN;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_5) == BST_CHECKED)
+ iFlags |= GC_EVENT_PART;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_6) == BST_CHECKED)
+ iFlags |= GC_EVENT_TOPIC;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_7) == BST_CHECKED)
+ iFlags |= GC_EVENT_ADDSTATUS;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_8) == BST_CHECKED)
+ iFlags |= GC_EVENT_INFORMATION;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_9) == BST_CHECKED)
+ iFlags |= GC_EVENT_QUIT;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_10) == BST_CHECKED)
+ iFlags |= GC_EVENT_KICK;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_11) == BST_CHECKED)
+ iFlags |= GC_EVENT_NOTICE;
+
+ if (iFlags&GC_EVENT_ADDSTATUS)
+ iFlags |= GC_EVENT_REMOVESTATUS;
+
+ SendMessage(si->hWnd, GC_CHANGEFILTERFLAG, 0, (LPARAM)iFlags);
+ if (si->bFilterEnabled)
+ SendMessage(si->hWnd, GC_REDRAWLOG, 0, 0);
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ }
+
+ return(FALSE);
+}
+
+static LRESULT CALLBACK ButtonSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_RBUTTONUP:
+ {
+ HWND hFilter = GetDlgItem(GetParent(hwnd), IDC_CHAT_FILTER);
+ HWND hColor = GetDlgItem(GetParent(hwnd), IDC_CHAT_COLOR);
+ HWND hBGColor = GetDlgItem(GetParent(hwnd), IDC_CHAT_BKGCOLOR);
+
+ if (DBGetContactSettingByte(NULL, "Chat", "RightClickFilter", 0) != 0) {
+ if (hFilter == hwnd)
+ SendMessage(GetParent(hwnd), GC_SHOWFILTERMENU, 0, 0);
+ if (hColor == hwnd)
+ SendMessage(GetParent(hwnd), GC_SHOWCOLORCHOOSER, 0, (LPARAM)IDC_CHAT_COLOR);
+ if (hBGColor == hwnd)
+ SendMessage(GetParent(hwnd), GC_SHOWCOLORCHOOSER, 0, (LPARAM)IDC_CHAT_BKGCOLOR);
+ } }
+ break;
+ }
+
+ return CallWindowProc(OldFilterButtonProc, hwnd, msg, wParam, lParam);
+}
+
+static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL inMenu = FALSE;
+ SESSION_INFO* si =(SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
+ int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, &si->windowData);
+ if (result != -1) {
+ return result;
+ }
+ switch (msg) {
+ case WM_MEASUREITEM:
+ MeasureMenuItem(wParam, lParam);
+ return TRUE;
+ case WM_DRAWITEM:
+ return DrawMenuItem(wParam, lParam);
+ case WM_SETCURSOR:
+ if (inMenu) {
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ return TRUE;
+ }
+ break;
+ case WM_LBUTTONUP:
+ {
+ CHARRANGE sel;
+
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) &sel);
+ if (sel.cpMin != sel.cpMax)
+ {
+ SendMessage(hwnd, WM_COPY, 0, 0);
+ sel.cpMin = sel.cpMax ;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & sel);
+ }
+ SetFocus(GetDlgItem(GetParent(hwnd), IDC_CHAT_MESSAGE));
+ break;
+ }
+
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) == WA_INACTIVE) {
+ CHARRANGE sel;
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) &sel);
+ if (sel.cpMin != sel.cpMax) {
+ sel.cpMin = sel.cpMax ;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & sel);
+ } }
+ break;
+
+ case WM_CONTEXTMENU:
+ {
+ CHARRANGE sel, all = { 0, -1 };
+ POINT pt;
+ UINT uID = 0;
+ HMENU hMenu = 0;
+ TCHAR *pszWord = NULL;
+ POINTL ptl;
+
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) & sel);
+ if (lParam == 0xFFFFFFFF) {
+ SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM) & pt, (LPARAM) sel.cpMax);
+ ClientToScreen(hwnd, &pt);
+ } else {
+ pt.x = (short) LOWORD(lParam);
+ pt.y = (short) HIWORD(lParam);
+ }
+ ptl.x = (LONG)pt.x;
+ ptl.y = (LONG)pt.y;
+ ScreenToClient(hwnd, (LPPOINT)&ptl);
+ pszWord = GetRichTextWord(hwnd, &ptl);
+ inMenu = TRUE;
+ uID = CreateGCMenu(hwnd, &hMenu, 1, pt, si, NULL, pszWord);
+ inMenu = FALSE;
+ switch (uID) {
+ case 0:
+ PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0 );
+ break;
+
+ case ID_COPYALL:
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) & sel);
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & all);
+ SendMessage(hwnd, WM_COPY, 0, 0);
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & sel);
+ PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0 );
+ break;
+
+ case IDM_CLEAR:
+ if (si)
+ {
+ SetWindowText(hwnd, _T(""));
+ LM_RemoveAll(&si->pLog, &si->pLogEnd);
+ si->iEventCount = 0;
+ si->LastTime = 0;
+ PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0 );
+ }
+ break;
+
+ case IDM_SEARCH_GOOGLE:
+ case IDM_SEARCH_BING:
+ case IDM_SEARCH_YAHOO:
+ case IDM_SEARCH_WIKIPEDIA:
+ case IDM_SEARCH_FOODNETWORK:
+ case IDM_SEARCH_GOOGLE_MAPS:
+ case IDM_SEARCH_GOOGLE_TRANSLATE:
+ SearchWord(pszWord, uID - IDM_SEARCH_GOOGLE + SEARCHENGINE_GOOGLE);
+ PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0 );
+ break;
+ default:
+ PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0 );
+ DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_LOGMENU, NULL, NULL, (LPARAM)uID);
+ break;
+ }
+ DestroyGCMenu(&hMenu, 5);
+ mir_free(pszWord);
+ break;
+ }
+ case WM_CHAR:
+ SetFocus(GetDlgItem(GetParent(hwnd), IDC_CHAT_MESSAGE));
+ SendMessage(GetDlgItem(GetParent(hwnd), IDC_CHAT_MESSAGE), WM_CHAR, wParam, lParam);
+ break;
+ }
+
+ return CallWindowProc(OldLogProc, hwnd, msg, wParam, lParam);
+}
+
+static void ProcessNickListHovering(HWND hwnd, int hoveredItem, POINT * pt, SESSION_INFO * parentdat)
+{
+ static int currentHovered=-1;
+ static HWND hwndToolTip=NULL;
+ static HWND oldParent=NULL;
+ TOOLINFO ti={0};
+ RECT clientRect;
+ BOOL bNewTip=FALSE;
+ USERINFO *ui1 = NULL;
+
+ if (hoveredItem==currentHovered) return;
+ currentHovered=hoveredItem;
+
+ if (oldParent!=hwnd && hwndToolTip) {
+ SendMessage(hwndToolTip, TTM_DELTOOL, 0, 0);
+ DestroyWindow(hwndToolTip);
+ hwndToolTip=NULL;
+ }
+ if (hoveredItem==-1) {
+
+ SendMessage( hwndToolTip, TTM_ACTIVATE, 0, 0 );
+
+ } else {
+
+ if (!hwndToolTip) {
+ hwndToolTip=CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ hwnd, NULL, g_hInst, NULL );
+ //SetWindowPos(hwndToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ bNewTip=TRUE;
+ }
+
+ GetClientRect(hwnd,&clientRect);
+ ti.cbSize=sizeof(TOOLINFO);
+ ti.uFlags=TTF_SUBCLASS;
+ ti.hinst=g_hInst;
+ ti.hwnd=hwnd;
+ ti.uId=1;
+ ti.rect=clientRect;
+
+ ti.lpszText=NULL;
+
+ ui1 = SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, currentHovered);
+ if (ui1) {
+ // /GetChatToolTipText
+ // wParam = roomID parentdat->ptszID
+ // lParam = userID ui1->pszUID
+ char serviceName[256];
+ _snprintf(serviceName,SIZEOF(serviceName), "%s"MS_GC_PROTO_GETTOOLTIPTEXT, parentdat->pszModule);
+ if (ServiceExists(serviceName))
+ ti.lpszText=(TCHAR*)CallService(serviceName, (WPARAM)parentdat->ptszID, (LPARAM)ui1->pszUID);
+ else {
+ TCHAR ptszBuf[ 1024 ];
+ mir_sntprintf( ptszBuf, SIZEOF(ptszBuf), _T("%s: %s\r\n%s: %s\r\n%s: %s"),
+ TranslateT( "Nick name" ), ui1->pszNick,
+ TranslateT( "Unique id" ), ui1->pszUID,
+ TranslateT( "Status" ), TM_WordToString( parentdat->pStatuses, ui1->Status ));
+ ti.lpszText = mir_tstrdup( ptszBuf );
+ }
+ }
+
+ SendMessage( hwndToolTip, bNewTip ? TTM_ADDTOOL : TTM_UPDATETIPTEXT, 0, (LPARAM) &ti);
+ SendMessage( hwndToolTip, TTM_ACTIVATE, (ti.lpszText!=NULL) , 0 );
+ SendMessage( hwndToolTip, TTM_SETMAXTIPWIDTH, 0 , 400 );
+ if (ti.lpszText)
+ mir_free(ti.lpszText);
+ }
+}
+
+static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SESSION_INFO* si =(SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
+ int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, &si->windowData);
+ if (result != -1) {
+ return result;
+ }
+ switch (msg) {
+ case WM_ERASEBKGND:
+ {
+ HDC dc = (HDC)wParam;
+ if (dc) {
+ int height, index, items = 0;
+
+ index = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0);
+ if (index == LB_ERR || si->nUsersInNicklist <= 0)
+ return 0;
+
+ items = si->nUsersInNicklist - index;
+ height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0);
+
+ if (height != LB_ERR) {
+ RECT rc = {0};
+ GetClientRect(hwnd, &rc);
+
+ if (rc.bottom-rc.top > items * height) {
+ rc.top = items*height;
+ FillRect(dc, &rc, hListBkgBrush);
+ } } } }
+ return 1;
+
+ case WM_RBUTTONDOWN:
+ SendMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);
+ break;
+
+ case WM_RBUTTONUP:
+ SendMessage(hwnd, WM_LBUTTONUP, wParam, lParam);
+ break;
+
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *) lParam;
+ if (mis->CtlType == ODT_MENU)
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ return FALSE;
+ }
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *) lParam;
+ if (dis->CtlType == ODT_MENU)
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ return FALSE;
+ }
+ case WM_CONTEXTMENU:
+ {
+ TVHITTESTINFO hti;
+ DWORD item;
+ int height=0;
+ USERINFO * ui;
+
+ hti.pt.x = (short) LOWORD(lParam);
+ hti.pt.y = (short) HIWORD(lParam);
+ if (hti.pt.x == -1 && hti.pt.y == -1) {
+ int index = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
+ int top = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0);
+ height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0);
+ hti.pt.x = 4;
+ hti.pt.y = (index - top)*height + 1;
+ }
+ else ScreenToClient(hwnd,&hti.pt);
+
+ item = (DWORD)(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
+ if ( HIWORD( item ) == 1 )
+ item = (DWORD)(-1);
+ else
+ item &= 0xFFFF;
+ ui = SM_GetUserFromIndex(si->ptszID, si->pszModule, (int)item);
+ if (ui) {
+ HMENU hMenu = 0;
+ UINT uID;
+ USERINFO uinew;
+
+ memcpy(&uinew, ui, sizeof(USERINFO));
+ if (hti.pt.x == -1 && hti.pt.y == -1)
+ hti.pt.y += height - 4;
+ ClientToScreen(hwnd, &hti.pt);
+ uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, si, uinew.pszUID, NULL);
+
+ switch (uID) {
+ case 0:
+ break;
+
+ case ID_MESS:
+ DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_PRIVMESS, ui->pszUID, NULL, (LPARAM)NULL);
+ break;
+
+ default:
+ DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_NICKLISTMENU, ui->pszUID, NULL, (LPARAM)uID);
+ break;
+ }
+ DestroyGCMenu(&hMenu, 1);
+ return TRUE;
+ } }
+ break;
+
+ case WM_GETDLGCODE :
+ {
+ BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
+ BOOL isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) && !isAlt;
+
+ LPMSG lpmsg;
+ if ( ( lpmsg = (LPMSG)lParam ) != NULL ) {
+ if ( lpmsg->message == WM_KEYDOWN
+ && (lpmsg->wParam == VK_RETURN || lpmsg->wParam == VK_ESCAPE || (lpmsg->wParam == VK_TAB && (isAlt || isCtrl))))
+ return DLGC_WANTALLKEYS;
+ }
+ break;
+ }
+ case WM_KEYDOWN:
+ if (wParam == VK_RETURN) {
+ int index = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
+ if (index!=LB_ERR) {
+ USERINFO *ui = SM_GetUserFromIndex(si->ptszID, si->pszModule, index);
+ DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_PRIVMESS, ui->pszUID, NULL, (LPARAM)NULL);
+ }
+ break;
+ }
+ if (wParam == VK_ESCAPE || wParam == VK_UP || wParam == VK_DOWN || wParam == VK_NEXT ||
+ wParam == VK_PRIOR || wParam == VK_TAB || wParam == VK_HOME || wParam == VK_END) {
+ si->szSearch[0] = 0;
+ }
+ break;
+ case WM_CHAR:
+ case WM_UNICHAR:
+ /*
+ * simple incremental search for the user (nick) - list control
+ * typing esc or movement keys will clear the current search string
+ */
+ if (wParam == 27 && si->szSearch[0]) { // escape - reset everything
+ si->szSearch[0] = 0;
+ break;
+ }
+ else if (wParam == '\b' && si->szSearch[0]) // backspace
+ si->szSearch[lstrlen(si->szSearch) - 1] = '\0';
+ else if (wParam < ' ')
+ break;
+ else {
+ TCHAR szNew[2];
+ szNew[0] = (TCHAR) wParam;
+ szNew[1] = '\0';
+ if (lstrlen(si->szSearch) >= SIZEOF(si->szSearch) - 2) {
+ MessageBeep(MB_OK);
+ break;
+ }
+ _tcscat(si->szSearch, szNew);
+ }
+ if (si->szSearch[0]) {
+ int iItems = SendMessage(hwnd, LB_GETCOUNT, 0, 0);
+ int i;
+ USERINFO *ui;
+ /*
+ * iterate over the (sorted) list of nicknames and search for the
+ * string we have
+ */
+ char *str = t2a(si->szSearch);
+ mir_free(str);
+ for (i = 0; i < iItems; i++) {
+ ui = UM_FindUserFromIndex(si->pUsers, i);
+ if (ui) {
+ if (!_tcsnicmp(ui->pszNick, si->szSearch, lstrlen(si->szSearch))) {
+ SendMessage(hwnd, LB_SETCURSEL, i, 0);
+ InvalidateRect(hwnd, NULL, FALSE);
+ return 0;
+ }
+ }
+ }
+ if (i == iItems) {
+ MessageBeep(MB_OK);
+ si->szSearch[lstrlen(si->szSearch) - 1] = '\0';
+ }
+ return 0;
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ {
+ POINT pt;
+ RECT clientRect;
+ BOOL bInClient;
+ pt.x=LOWORD(lParam);
+ pt.y=HIWORD(lParam);
+ GetClientRect(hwnd,&clientRect);
+ bInClient=PtInRect(&clientRect, pt);
+ //Mouse capturing/releasing
+ if ( bInClient && GetCapture()!=hwnd)
+ SetCapture(hwnd);
+ else if (!bInClient)
+ ReleaseCapture();
+
+ if (bInClient) {
+ //hit test item under mouse
+ DWORD nItemUnderMouse=(DWORD)SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam);
+ if ( HIWORD( nItemUnderMouse ) == 1 )
+ nItemUnderMouse = (DWORD)(-1);
+ else
+ nItemUnderMouse &= 0xFFFF;
+
+ ProcessNickListHovering(hwnd, (int)nItemUnderMouse, &pt, si);
+ } else {
+ ProcessNickListHovering(hwnd, -1, &pt, NULL);
+ } }
+ break;
+ }
+
+ return CallWindowProc(OldNicklistProc, hwnd, msg, wParam, lParam);
+}
+
+
+int GetTextPixelSize( TCHAR* pszText, HFONT hFont, BOOL bWidth)
+{
+ HDC hdc;
+ HFONT hOldFont;
+ RECT rc = {0};
+ int i;
+
+ if (!pszText || !hFont)
+ return 0;
+
+ hdc = GetDC(NULL);
+ hOldFont = (HFONT)SelectObject(hdc, hFont);
+ i = DrawText(hdc, pszText , -1, &rc, DT_CALCRECT);
+ SelectObject(hdc, hOldFont);
+ ReleaseDC(NULL,hdc);
+ return bWidth ? rc.right - rc.left : rc.bottom - rc.top;
+}
+
+static void __cdecl phase2(void * lParam)
+{
+ SESSION_INFO* si = (SESSION_INFO*) lParam;
+ Sleep(30);
+ if (si && si->hWnd)
+ PostMessage(si->hWnd, GC_REDRAWLOG3, 0, 0);
+}
+
+INT_PTR CALLBACK RoomWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ static HMENU hToolbarMenu;
+ SESSION_INFO * si;
+ si = (SESSION_INFO *)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
+ if (!si && uMsg!=WM_INITDIALOG) return FALSE;
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ {
+ SESSION_INFO* psi = (SESSION_INFO*)lParam;
+ int mask;
+ RECT minEditInit;
+ HWND hNickList = GetDlgItem(hwndDlg,IDC_CHAT_LIST);
+ NotifyLocalWinEvent(psi->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_OPENING);
+
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LONG_PTR)psi);
+ si = psi;
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE));
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_CHAT_LOG));
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_CHAT_LIST));
+ OldSplitterProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_SPLITTERX),GWLP_WNDPROC,(LONG_PTR)SplitterSubclassProc);
+ OldNicklistProc=(WNDPROC)SetWindowLongPtr(hNickList,GWLP_WNDPROC,(LONG_PTR)NicklistSubclassProc);
+ OldLogProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_LOG),GWLP_WNDPROC,(LONG_PTR)LogSubclassProc);
+ OldFilterButtonProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_FILTER),GWLP_WNDPROC,(LONG_PTR)ButtonSubclassProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_COLOR),GWLP_WNDPROC,(LONG_PTR)ButtonSubclassProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_BKGCOLOR),GWLP_WNDPROC,(LONG_PTR)ButtonSubclassProc);
+ OldMessageProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), GWLP_WNDPROC,(LONG_PTR)MessageSubclassProc);
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), &minEditInit);
+ si->windowData.minEditBoxHeight = minEditInit.bottom - minEditInit.top;
+ si->windowData.minLogBoxHeight = si->windowData.minEditBoxHeight;
+
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SUBCLASSED, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_LOG, EM_AUTOURLDETECT, 1, 0);
+ mask = (int)SendDlgItemMessage(hwndDlg, IDC_CHAT_LOG, EM_GETEVENTMASK, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_LOG, EM_SETEVENTMASK, 0, mask | ENM_LINK | ENM_MOUSEEVENTS);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_LOG, EM_LIMITTEXT, (WPARAM)sizeof(TCHAR)*0x7FFFFFFF, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_LOG, EM_SETOLECALLBACK, 0, (LPARAM) & reOleCallback);
+
+ if (DBGetContactSettingByte(NULL, "Chat", "UseIEView", 0)) {
+ IEVIEWWINDOW ieWindow;
+ IEVIEWEVENT iee;
+
+ ZeroMemory(&ieWindow, sizeof(ieWindow));
+ ieWindow.cbSize = sizeof(ieWindow);
+ ieWindow.iType = IEW_CREATE;
+ ieWindow.dwFlags = 0;
+ ieWindow.dwMode = IEWM_CHAT;
+ ieWindow.parent = hwndDlg;
+ ieWindow.x = 0;
+ ieWindow.y = 0;
+ ieWindow.cx = 200;
+ ieWindow.cy = 300;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ si->windowData.hwndLog = ieWindow.hwnd;
+ ZeroMemory(&iee, sizeof(iee));
+ iee.cbSize = sizeof(iee);
+ iee.iType = IEE_CLEAR_LOG;
+ iee.hwnd = si->windowData.hwndLog;
+ iee.hContact = si->windowData.hContact;
+ iee.codepage = si->windowData.codePage;
+ iee.pszProto = si->pszModule;
+ CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee);
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHAT_SMILEY), TRUE);
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LOG), EM_HIDESELECTION, TRUE, 0);
+
+ SendMessage(hwndDlg, GC_SETWNDPROPS, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+
+ SendMessage(GetParent(hwndDlg), CM_ADDCHILD, (WPARAM) hwndDlg, (LPARAM) psi->windowData.hContact);
+ PostMessage(hwndDlg, GC_UPDATENICKLIST, 0, 0);
+ NotifyLocalWinEvent(psi->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_OPEN);
+ }
+ break;
+
+ case GC_SETWNDPROPS:
+ {
+ LoadGlobalSettings();
+ InitButtons(hwndDlg, si);
+
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+ SendMessage(hwndDlg, GC_FIXTABICONS, 0, 0);
+
+ { // log
+ //int iIndent = 0;
+ //PARAFORMAT2 pf2;
+ //if (g_Settings.dwIconFlags)
+ // iIndent += (14*1440)/g_dat->logPixelSX;
+ //if (g_Settings.ShowTime && g_Settings.LogIndentEnabled)
+ // iIndent += g_Settings.LogTextIndent*1440/g_dat->logPixelSX;
+ //pf2.cbSize = sizeof(pf2);
+ //pf2.dwMask = PFM_OFFSET;
+ //pf2.dxOffset = iIndent * 1440 / g_dat->logPixelSX;
+ //SendDlgItemMessage(hwndDlg, IDC_CHAT_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LOG), EM_SETBKGNDCOLOR , 0, g_Settings.crLogBackground);
+ }
+
+ { //messagebox
+ COLORREF crFore;
+
+ CHARFORMAT2 cf;
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &crFore, FALSE);
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwMask = CFM_COLOR|CFM_BOLD|CFM_UNDERLINE|CFM_BACKCOLOR;
+ cf.dwEffects = 0;
+ cf.crTextColor = crFore;
+ cf.crBackColor = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), EM_SETBKGNDCOLOR , 0, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR));
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, WM_SETFONT, (WPARAM) g_Settings.MessageBoxFont, MAKELPARAM(TRUE, 0));
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, (WPARAM)SCF_ALL , (LPARAM)&cf);
+ }
+ { // nicklist
+ int ih;
+ int ih2;
+ int font;
+ int height;
+
+ ih = GetTextPixelSize( _T("AQG_glo'"), g_Settings.UserListFont,FALSE);
+ ih2 = GetTextPixelSize( _T("AQG_glo'"), g_Settings.UserListHeadingsFont,FALSE);
+ height = DBGetContactSettingByte(NULL, "Chat", "NicklistRowDist", 12);
+ font = ih > ih2?ih:ih2;
+ // make sure we have space for icon!
+ if (DBGetContactSettingByte(NULL, "Chat", "ShowContactStatus", 0))
+ font = font > 16 ? font : 16;
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LIST), LB_SETITEMHEIGHT, 0, (LPARAM)height > font ? height : font);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_CHAT_LIST), NULL, TRUE);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_REQUESTRESIZE, 0, 0);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ SendMessage(hwndDlg, GC_REDRAWLOG2, 0, 0);
+ }
+ break;
+
+ case DM_UPDATETITLEBAR:
+ {
+ TitleBarData tbd = {0};
+ TCHAR szTemp [100];
+ if (g_dat->flags & SMF_STATUSICON) {
+ MODULEINFO* mi = MM_FindModule(si->pszModule);
+ tbd.hIcon = (si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon;
+ tbd.hIconBig = (si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig;
+ }
+ else {
+ tbd.hIcon = GetCachedIcon("chat_window");
+ tbd.hIconBig = g_dat->hIconChatBig;
+ }
+ tbd.hIconNot = (si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : NULL;
+
+ switch(si->iType) {
+ case GCW_CHATROOM:
+ mir_sntprintf(szTemp, SIZEOF(szTemp),
+ (si->nUsersInNicklist == 1) ? TranslateT("%s: Chat Room (%u user)") : TranslateT("%s: Chat Room (%u users)"),
+ si->ptszName, si->nUsersInNicklist);
+ break;
+ case GCW_PRIVMESS:
+ mir_sntprintf(szTemp, SIZEOF(szTemp),
+ (si->nUsersInNicklist ==1) ? TranslateT("%s: Message Session") : TranslateT("%s: Message Session (%u users)"),
+ si->ptszName, si->nUsersInNicklist);
+ break;
+ case GCW_SERVER:
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%s: Server"), si->ptszName);
+ break;
+ }
+ tbd.iFlags = TBDF_TEXT | TBDF_ICON;
+ tbd.pszText = szTemp;
+ SendMessage(GetParent(hwndDlg), CM_UPDATETITLEBAR, (WPARAM) &tbd, (LPARAM) hwndDlg);
+ SendMessage(hwndDlg, DM_UPDATETABCONTROL, 0, 0);
+ }
+ break;
+
+ case DM_UPDATESTATUSBAR:
+ {
+ StatusIconData sid;
+ StatusBarData sbd;
+ HICON hIcon;
+ MODULEINFO* mi = MM_FindModule(si->pszModule);
+ TCHAR szTemp[512];
+ hIcon = si->wStatus==ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon;
+ mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%s : %s"), mi->ptszModDispName, si->ptszStatusbarText ? si->ptszStatusbarText : _T(""));
+ sbd.iItem = 0;
+ sbd.iFlags = SBDF_TEXT | SBDF_ICON;
+ sbd.hIcon = hIcon;
+ sbd.pszText = szTemp;
+ SendMessage(GetParent(hwndDlg), CM_UPDATESTATUSBAR, (WPARAM) &sbd, (LPARAM) hwndDlg);
+ sbd.iItem = 1;
+ sbd.hIcon = NULL;
+ sbd.pszText = _T("");
+ SendMessage(GetParent(hwndDlg), CM_UPDATESTATUSBAR, (WPARAM) &sbd, (LPARAM) hwndDlg);
+ sid.cbSize = sizeof(sid);
+ sid.szModule = SRMMMOD;
+ sid.dwId = 0;
+ sid.flags = 0;
+
+ ModifyStatusIcon((WPARAM)si->windowData.hContact, (LPARAM) &sid);
+ // SendMessage(hwndDlg, GC_FIXTABICONS, 0, (LPARAM)si);
+ }
+ break;
+ case DM_GETCODEPAGE:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, si->windowData.codePage);
+ return TRUE;
+ case DM_SETCODEPAGE:
+ si->windowData.codePage = (int) lParam;
+ si->pszHeader = Log_CreateRtfHeader(MM_FindModule(si->pszModule), si);
+ SendMessage(hwndDlg, GC_REDRAWLOG2, 0, 0);
+ break;
+ case DM_SWITCHINFOBAR:
+ case DM_SWITCHTOOLBAR:
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ break;
+ case WM_SIZE:
+ {
+
+ if (wParam == SIZE_MAXIMIZED)
+ PostMessage(hwndDlg, GC_SCROLLTOBOTTOM, 0, 0);
+
+ if (IsIconic(hwndDlg)) break;
+
+ if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED) {
+ int dlgWidth, dlgHeight;
+ RECT rc;
+ dlgWidth = LOWORD(lParam);
+ dlgHeight = HIWORD(lParam);
+ /*if (dlgWidth == 0 && dlgHeight ==0) */{
+ GetClientRect(hwndDlg, &rc);
+ dlgWidth = rc.right - rc.left;
+ dlgHeight = rc.bottom - rc.top;
+ }
+
+ MessageDialogResize(hwndDlg, si, dlgWidth, dlgHeight);
+
+ }
+ }
+ break;
+
+ case GC_REDRAWWINDOW:
+ InvalidateRect(hwndDlg, NULL, TRUE);
+ break;
+
+ case GC_REDRAWLOG:
+ si->LastTime = 0;
+ if (si->pLog) {
+ LOGINFO * pLog = si->pLog;
+ if (si->iEventCount > 60) {
+ int index = 0;
+ while ( index < 59) {
+ if (pLog->next == NULL)
+ break;
+
+ pLog = pLog->next;
+ if (si->iType != GCW_CHATROOM || !si->bFilterEnabled || (si->iLogFilterFlags&pLog->iType) != 0)
+ index++;
+ }
+ Log_StreamInEvent(hwndDlg, pLog, si, TRUE);
+ mir_forkthread(phase2, si);
+ }
+ else Log_StreamInEvent(hwndDlg, si->pLogEnd, si, TRUE);
+ }
+ else SendMessage(hwndDlg, GC_EVENT_CONTROL + WM_USER+500, WINDOW_CLEARLOG, 0);
+ break;
+
+ case GC_REDRAWLOG2:
+ si->LastTime = 0;
+ if (si->pLog)
+ Log_StreamInEvent(hwndDlg, si->pLogEnd, si, TRUE);
+ break;
+
+ case GC_REDRAWLOG3:
+ si->LastTime = 0;
+ if (si->pLog)
+ Log_StreamInEvent(hwndDlg, si->pLogEnd, si, TRUE);
+ break;
+
+ case GC_ADDLOG:
+ if (si->pLogEnd)
+ Log_StreamInEvent(hwndDlg, si->pLog, si, FALSE);
+ else
+ SendMessage(hwndDlg, GC_EVENT_CONTROL + WM_USER+500, WINDOW_CLEARLOG, 0);
+ break;
+
+
+ case DM_UPDATETABCONTROL:
+ {
+ TabControlData tcd;
+ tcd.iFlags = TCDF_TEXT;
+ tcd.pszText = si->ptszName;
+ SendMessage(GetParent(hwndDlg), CM_UPDATETABCONTROL, (WPARAM) &tcd, (LPARAM) hwndDlg);
+
+ }
+ case GC_FIXTABICONS:
+ {
+ TabControlData tcd;
+ HICON hIcon;
+ if (!(si->wState & GC_EVENT_HIGHLIGHT))
+ {
+ if (si->wState & STATE_TALK)
+ hIcon = (si->wStatus==ID_STATUS_ONLINE) ? MM_FindModule(si->pszModule)->hOnlineTalkIcon : MM_FindModule(si->pszModule)->hOfflineTalkIcon;
+ else
+ hIcon = (si->wStatus==ID_STATUS_ONLINE) ? MM_FindModule(si->pszModule)->hOnlineIcon : MM_FindModule(si->pszModule)->hOfflineIcon;
+ } else {
+ hIcon = g_dat->hMsgIcon;
+ }
+ tcd.iFlags = TCDF_ICON;
+ tcd.hIcon = hIcon;
+ SendMessage(GetParent(hwndDlg), CM_UPDATETABCONTROL, (WPARAM) &tcd, (LPARAM) hwndDlg);
+ }
+ break;
+
+ case GC_SETMESSAGEHIGHLIGHT:
+ {
+ si->wState |= GC_EVENT_HIGHLIGHT;
+ SendMessage(si->hWnd, GC_FIXTABICONS, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+ if (DBGetContactSettingByte(NULL, "Chat", "FlashWindowHighlight", 0) != 0 && GetActiveWindow() != hwndDlg && GetForegroundWindow() != GetParent(hwndDlg))
+ SendMessage(GetParent(si->hWnd), CM_STARTFLASHING, 0, 0);
+ }
+ break;
+
+ case GC_SETTABHIGHLIGHT:
+ {
+ SendMessage(si->hWnd, GC_FIXTABICONS, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+ if (g_Settings.FlashWindow && GetActiveWindow() != GetParent(hwndDlg) && GetForegroundWindow() != GetParent(hwndDlg))
+ SendMessage(GetParent(si->hWnd), CM_STARTFLASHING, 0, 0);
+ }
+ break;
+
+ case DM_ACTIVATE:
+ {
+ if (si->wState & STATE_TALK) {
+ si->wState &= ~STATE_TALK;
+
+ DBWriteContactSettingWord(si->windowData.hContact, si->pszModule ,"ApparentMode",(LPARAM) 0);
+ }
+
+ if (si->wState & GC_EVENT_HIGHLIGHT) {
+ si->wState &= ~GC_EVENT_HIGHLIGHT;
+
+ if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, (LPARAM)0))
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon");
+ }
+
+ SendMessage(hwndDlg, GC_FIXTABICONS, 0, 0);
+ if (!si->hWnd) {
+ ShowRoom(si, (WPARAM)WINDOW_VISIBLE, TRUE);
+ SendMessage(hwndDlg, WM_MOUSEACTIVATE, 0, 0 );
+ } }
+ break;
+
+
+
+ case GC_ACKMESSAGE:
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_MESSAGE,EM_SETREADONLY,FALSE,0);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_MESSAGE,WM_SETTEXT,0, (LPARAM)_T(""));
+ return TRUE;
+
+ case WM_CTLCOLORLISTBOX:
+ SetBkColor((HDC) wParam, g_Settings.crUserListBGColor);
+ return (INT_PTR) hListBkgBrush;
+
+ case WM_MEASUREITEM:
+ if (!MeasureMenuItem(wParam, lParam)) {
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *) lParam;
+
+ if (mis->CtlType == ODT_MENU)
+ {
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ } else
+ {
+ int ih = GetTextPixelSize( _T("AQGgl'"), g_Settings.UserListFont,FALSE);
+ int ih2 = GetTextPixelSize( _T("AQGg'"), g_Settings.UserListHeadingsFont,FALSE);
+ int font = ih > ih2?ih:ih2;
+ int height = DBGetContactSettingByte(NULL, "Chat", "NicklistRowDist", 12);
+ // make sure we have space for icon!
+ if (DBGetContactSettingByte(NULL, "Chat", "ShowContactStatus", 0))
+ font = font > 16 ? font : 16;
+ mis->itemHeight = height > font?height:font;
+ }
+
+ return TRUE;
+ }
+
+ case WM_DRAWITEM:
+ if (!DrawMenuItem(wParam, lParam)) {
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *) lParam;
+ if (dis->CtlType == ODT_MENU) {
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ } else
+ if (dis->CtlID == IDC_CHAT_LIST) {
+ HFONT hFont, hOldFont;
+ HICON hIcon;
+ int offset;
+ int height;
+ int index = dis->itemID;
+ USERINFO * ui = SM_GetUserFromIndex(si->ptszID, si->pszModule, index);
+ if (ui) {
+ int x_offset = 2;
+
+ height = dis->rcItem.bottom - dis->rcItem.top;
+
+ if (height&1)
+ height++;
+ if (height == 10)
+ offset = 0;
+ else
+ offset = height/2 - 5;
+ hIcon = SM_GetStatusIcon(si, ui);
+ hFont = (ui->iStatusEx == 0) ? g_Settings.UserListFont : g_Settings.UserListHeadingsFont;
+ hOldFont = (HFONT) SelectObject(dis->hDC, hFont);
+ SetBkMode(dis->hDC, TRANSPARENT);
+
+ if (dis->itemAction == ODA_FOCUS && dis->itemState & ODS_SELECTED)
+ FillRect(dis->hDC, &dis->rcItem, hListSelectedBkgBrush);
+ else //if (dis->itemState & ODS_INACTIVE)
+ FillRect(dis->hDC, &dis->rcItem, hListBkgBrush);
+
+ if (g_Settings.ShowContactStatus && g_Settings.ContactStatusFirst && ui->ContactStatus) {
+ HICON hIcon = LoadSkinnedProtoIcon(si->pszModule, ui->ContactStatus);
+ DrawIconEx(dis->hDC, x_offset, dis->rcItem.top+offset-3,hIcon,16,16,0,NULL, DI_NORMAL);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ x_offset += 18;
+ }
+ DrawIconEx(dis->hDC,x_offset, dis->rcItem.top + offset,hIcon,10,10,0,NULL, DI_NORMAL);
+ x_offset += 12;
+ if (g_Settings.ShowContactStatus && !g_Settings.ContactStatusFirst && ui->ContactStatus) {
+ HICON hIcon = LoadSkinnedProtoIcon(si->pszModule, ui->ContactStatus);
+ DrawIconEx(dis->hDC, x_offset, dis->rcItem.top+offset-3,hIcon,16,16,0,NULL, DI_NORMAL);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ x_offset += 18;
+ }
+
+ SetTextColor(dis->hDC, ui->iStatusEx == 0?g_Settings.crUserListColor:g_Settings.crUserListHeadingsColor);
+ TextOut(dis->hDC, dis->rcItem.left+x_offset, dis->rcItem.top, ui->pszNick, lstrlen(ui->pszNick));
+ SelectObject(dis->hDC, hOldFont);
+ }
+ return TRUE;
+ } }
+
+ case GC_UPDATENICKLIST:
+ {
+ int index=0;
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_LIST, WM_SETREDRAW, FALSE, 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LIST), LB_RESETCONTENT, 0, 0);
+ for (index=0; index<si->nUsersInNicklist; index++) {
+ USERINFO * ui = SM_GetUserFromIndex(si->ptszID, si->pszModule, index);
+ if (ui) {
+ char szIndicator = SM_GetStatusIndicator(si, ui);
+ if (szIndicator>'\0') {
+ static TCHAR ptszBuf[128];
+ mir_sntprintf( ptszBuf, SIZEOF(ptszBuf), _T("%c%s"), szIndicator, ui->pszNick);
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LIST), LB_ADDSTRING, 0, (LPARAM)ptszBuf);
+ } else {
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LIST), LB_ADDSTRING, 0, (LPARAM)ui->pszNick);
+ }
+ }
+ }
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_LIST, WM_SETREDRAW, TRUE, 0);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_CHAT_LIST), NULL, FALSE) ;
+ UpdateWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIST)) ;
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+ }
+ break;
+
+ case GC_EVENT_CONTROL + WM_USER+500:
+ {
+ switch(wParam) {
+ case SESSION_OFFLINE:
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(si->hWnd, GC_UPDATENICKLIST, (WPARAM)0, (LPARAM)0);
+ return TRUE;
+
+ case SESSION_ONLINE:
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ return TRUE;
+
+ case WINDOW_HIDDEN:
+ SendMessage(hwndDlg, GC_CLOSEWINDOW, 0, 0);
+ return TRUE;
+
+ case WINDOW_CLEARLOG:
+ SetDlgItemText(hwndDlg, IDC_CHAT_LOG, _T(""));
+ return TRUE;
+
+ case SESSION_TERMINATE:
+ if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, (LPARAM)0))
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon");
+ si->wState &= ~STATE_TALK;
+ DBWriteContactSettingWord(si->windowData.hContact, si->pszModule ,"ApparentMode",(LPARAM) 0);
+ SendMessage(hwndDlg, GC_CLOSEWINDOW, 0, 0);
+ return TRUE;
+
+ case WINDOW_MINIMIZE:
+ ShowWindow(hwndDlg, SW_MINIMIZE);
+ goto LABEL_SHOWWINDOW;
+
+ case WINDOW_MAXIMIZE:
+ ShowWindow(hwndDlg, SW_MAXIMIZE);
+ goto LABEL_SHOWWINDOW;
+
+ case SESSION_INITDONE:
+ if (DBGetContactSettingByte(NULL, "Chat", "PopupOnJoin", 0)!=0)
+ return TRUE;
+ // fall through
+ case WINDOW_VISIBLE:
+ if (IsIconic(hwndDlg))
+ ShowWindow(hwndDlg, SW_NORMAL);
+LABEL_SHOWWINDOW:
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ SendMessage(hwndDlg, GC_REDRAWLOG, 0, 0);
+ SendMessage(hwndDlg, GC_UPDATENICKLIST, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ ShowWindow(hwndDlg, SW_SHOW);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ SetForegroundWindow(hwndDlg);
+ return TRUE;
+ } }
+ break;
+
+ case GC_SPLITTERMOVED:
+ if ((HWND)lParam==GetDlgItem(hwndDlg,IDC_CHAT_SPLITTERX)) {
+ POINT pt;
+ RECT rc;
+ int oldSplitterX;
+ GetClientRect(hwndDlg,&rc);
+ pt.x=wParam; pt.y=0;
+ ScreenToClient(hwndDlg,&pt);
+
+ oldSplitterX=si->iSplitterX;
+ si->iSplitterX=rc.right-pt.x+1;
+ if (si->iSplitterX < 35)
+ si->iSplitterX=35;
+ if (si->iSplitterX > rc.right-rc.left-35)
+ si->iSplitterX = rc.right-rc.left-35;
+ g_Settings.iSplitterX = si->iSplitterX;
+ }
+ else if ((HWND)lParam==GetDlgItem(hwndDlg,IDC_CHAT_SPLITTERY)) {
+ POINT pt;
+ RECT rc;
+ int oldSplitterY;
+ GetClientRect(hwndDlg,&rc);
+ pt.x=0; pt.y=wParam;
+ ScreenToClient(hwndDlg,&pt);
+ oldSplitterY=si->iSplitterY;
+ si->iSplitterY=rc.bottom-pt.y;
+ g_Settings.iSplitterY = si->iSplitterY;
+ }
+ PostMessage(hwndDlg,WM_SIZE,0,0);
+ break;
+
+ case GC_FIREHOOK:
+ if (lParam) {
+ GCHOOK* gch = (GCHOOK *) lParam;
+ NotifyEventHooks(hSendEvent,0,(WPARAM)gch);
+ if ( gch->pDest ) {
+ mir_free( gch->pDest->pszID );
+ mir_free( gch->pDest->pszModule );
+ mir_free( gch->pDest );
+ }
+ mir_free( gch->ptszText );
+ mir_free( gch->ptszUID );
+ mir_free( gch );
+ }
+ break;
+
+ case GC_CHANGEFILTERFLAG:
+ si->iLogFilterFlags = lParam;
+ break;
+
+ case GC_SHOWFILTERMENU:
+ {
+ RECT rc;
+ HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), hwndDlg, FilterWndProc, (LPARAM)si);
+ TranslateDialogDefault(hwnd);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_CHAT_FILTER), &rc);
+ SetWindowPos(hwnd, HWND_TOP, rc.left-85, (IsWindowVisible(GetDlgItem(hwndDlg, IDC_CHAT_FILTER))||IsWindowVisible(GetDlgItem(hwndDlg, IDC_CHAT_BOLD)))?rc.top-206:rc.top-186, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+ }
+ break;
+
+ case GC_SHOWCOLORCHOOSER:
+ {
+ HWND ColorWindow;
+ RECT rc;
+ BOOL bFG = lParam == IDC_CHAT_COLOR?TRUE:FALSE;
+ COLORCHOOSER * pCC = (COLORCHOOSER *)mir_alloc(sizeof(COLORCHOOSER));
+
+ GetWindowRect(GetDlgItem(hwndDlg, bFG?IDC_CHAT_COLOR:IDC_CHAT_BKGCOLOR), &rc);
+ pCC->hWndTarget = GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE);
+ pCC->pModule = MM_FindModule(si->pszModule);
+ pCC->xPosition = rc.left+3;
+ pCC->yPosition = IsWindowVisible(GetDlgItem(hwndDlg, IDC_CHAT_COLOR))?rc.top-1:rc.top+20;
+ pCC->bForeground = bFG;
+ pCC->si = si;
+
+ ColorWindow= CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_COLORCHOOSER), hwndDlg, DlgProcColorToolWindow, (LPARAM) pCC);
+ }
+ break;
+
+ case GC_SCROLLTOBOTTOM:
+ {
+ SCROLLINFO si = { 0 };
+ if ((GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CHAT_LOG), GWL_STYLE) & WS_VSCROLL) != 0){
+ CHARRANGE sel;
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_PAGE | SIF_RANGE;
+ GetScrollInfo(GetDlgItem(hwndDlg, IDC_CHAT_LOG), SB_VERT, &si);
+ si.fMask = SIF_POS;
+ si.nPos = si.nMax - si.nPage + 1;
+ SetScrollInfo(GetDlgItem(hwndDlg, IDC_CHAT_LOG), SB_VERT, &si, TRUE);
+ sel.cpMin = sel.cpMax = GetRichTextLength(GetDlgItem(hwndDlg, IDC_CHAT_LOG), CP_ACP, FALSE);
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LOG), EM_EXSETSEL, 0, (LPARAM) & sel);
+ PostMessage(GetDlgItem(hwndDlg, IDC_CHAT_LOG), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
+ } }
+ break;
+
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) != WA_ACTIVE)
+ break;
+
+ //fall through
+ case WM_MOUSEACTIVATE:
+ {
+ if (uMsg != WM_ACTIVATE)
+ SetFocus(GetDlgItem(hwndDlg,IDC_CHAT_MESSAGE));
+
+ SetActiveSession(si->ptszID, si->pszModule);
+
+ if (DBGetContactSettingWord(si->windowData.hContact, si->pszModule ,"ApparentMode", 0) != 0)
+ DBWriteContactSettingWord(si->windowData.hContact, si->pszModule ,"ApparentMode",(LPARAM) 0);
+ if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, (LPARAM)0))
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon");
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR pNmhdr;
+
+ pNmhdr = (LPNMHDR)lParam;
+ switch (pNmhdr->code) {
+ case EN_REQUESTRESIZE:
+ if (pNmhdr->idFrom == IDC_CHAT_MESSAGE) {
+ REQRESIZE *rr = (REQRESIZE *)lParam;
+ int height = rr->rc.bottom - rr->rc.top + 1;
+ if (height < g_dat->minInputAreaHeight) {
+ height = g_dat->minInputAreaHeight;
+ }
+ if (si->desiredInputAreaHeight != height) {
+ si->desiredInputAreaHeight = height;
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ PostMessage(hwndDlg, GC_SCROLLTOBOTTOM, 0, 0);
+ }
+ }
+ break;
+ case EN_MSGFILTER:
+ if (pNmhdr->idFrom == IDC_CHAT_LOG && ((MSGFILTER *) lParam)->msg == WM_RBUTTONUP){
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ case EN_LINK:
+ if (pNmhdr->idFrom == IDC_CHAT_LOG) {
+ switch (((ENLINK *) lParam)->msg) {
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ if (HandleLinkClick(g_hInst, hwndDlg, GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE),(ENLINK*)lParam)) {
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ } }
+ break;
+ case TTN_NEEDTEXT:
+ if (pNmhdr->idFrom == (UINT_PTR)GetDlgItem(hwndDlg,IDC_CHAT_LIST))
+ {
+ LPNMTTDISPINFO lpttd = (LPNMTTDISPINFO)lParam;
+ POINT p;
+ int item;
+ USERINFO * ui;
+ SESSION_INFO* parentdat =(SESSION_INFO*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
+
+ GetCursorPos( &p );
+ ScreenToClient(GetDlgItem(hwndDlg, IDC_CHAT_LIST), &p);
+ item = LOWORD(SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LIST), LB_ITEMFROMPOINT, 0, MAKELPARAM(p.x, p.y)));
+ ui = SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, item);
+ if ( ui != NULL ) {
+ static TCHAR ptszBuf[ 1024 ];
+ mir_sntprintf( ptszBuf, SIZEOF(ptszBuf), _T("%s: %s\r\n%s: %s\r\n%s: %s"),
+ TranslateT( "Nick name" ), ui->pszNick,
+ TranslateT( "Unique id" ), ui->pszUID,
+ TranslateT( "Status" ), TM_WordToString( parentdat->pStatuses, ui->Status ));
+ lpttd->lpszText = ptszBuf;
+ } }
+ break;
+ } }
+ break;
+
+ case WM_COMMAND:
+ if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM) si->windowData.hContact))
+ break;
+ switch (LOWORD(wParam)) {
+ case IDC_CHAT_LIST:
+ if (HIWORD(wParam) == LBN_DBLCLK) {
+ TVHITTESTINFO hti;
+ int item;
+ USERINFO * ui;
+
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(GetDlgItem(hwndDlg, IDC_CHAT_LIST),&hti.pt);
+
+ item = LOWORD(SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_LIST), LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
+ ui = SM_GetUserFromIndex(si->ptszID, si->pszModule, item);
+ if (ui) {
+ if (GetKeyState(VK_SHIFT) & 0x8000){
+ LRESULT lResult = (LRESULT)SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), EM_GETSEL, (WPARAM)NULL, (LPARAM)NULL);
+ int start = LOWORD(lResult);
+ TCHAR* pszName = (TCHAR*)alloca(sizeof(TCHAR)*(lstrlen(ui->pszUID) + 3));
+ if (start == 0)
+ mir_sntprintf(pszName, lstrlen(ui->pszUID)+3, _T("%s: "), ui->pszUID);
+ else
+ mir_sntprintf(pszName, lstrlen(ui->pszUID)+2, _T("%s "), ui->pszUID);
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), EM_REPLACESEL, FALSE, (LPARAM) pszName);
+ PostMessage(hwndDlg, WM_MOUSEACTIVATE, 0, 0);
+ }
+ else DoEventHookAsync(hwndDlg, si->ptszID, si->pszModule, GC_USER_PRIVMESS, ui->pszUID, NULL, (LPARAM)NULL);
+ }
+
+ return TRUE;
+ }
+
+ if ( HIWORD(wParam) == LBN_KILLFOCUS )
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_CHAT_LIST), NULL, NULL, RDW_INVALIDATE);
+ break;
+
+ case IDOK:
+ {
+ char* pszRtf;
+ TCHAR* ptszText, *p1;
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK)))
+ break;
+
+ pszRtf = GetRichTextRTF(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE));
+ {
+ TCmdList *cmdListNew = tcmdlist_last(si->windowData.cmdList);
+ while (cmdListNew != NULL && cmdListNew->temporary) {
+ si->windowData.cmdList = tcmdlist_remove(si->windowData.cmdList, cmdListNew);
+ cmdListNew = tcmdlist_last(si->windowData.cmdList);
+ }
+ }
+ si->windowData.cmdList = tcmdlist_append(si->windowData.cmdList, pszRtf, 20, FALSE);
+ ptszText = DoRtfToTags(pszRtf, si);
+ p1 = _tcschr(ptszText, '\0');
+
+ //remove trailing linebreaks
+ while ( p1 > ptszText && (*p1 == '\0' || *p1 == '\r' || *p1 == '\n')) {
+ *p1 = '\0';
+ p1--;
+ }
+
+ if ( MM_FindModule(si->pszModule)->bAckMsg ) {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHAT_MESSAGE),FALSE);
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_MESSAGE,EM_SETREADONLY,TRUE,0);
+ }
+ else SendDlgItemMessage(hwndDlg,IDC_CHAT_MESSAGE,WM_SETTEXT,0,(LPARAM)_T(""));
+
+ EnableWindow(GetDlgItem(hwndDlg,IDOK),FALSE);
+
+ DoEventHookAsync(hwndDlg, si->ptszID, si->pszModule, GC_USER_MESSAGE, NULL, ptszText, (LPARAM)NULL);
+ mir_free(pszRtf);
+ mir_free(ptszText);
+ SetFocus(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE));
+ }
+ break;
+
+ case IDC_CHAT_SHOWNICKLIST:
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_SHOWNICKLIST)))
+ break;
+ if (si->iType == GCW_SERVER)
+ break;
+
+ si->bNicklistEnabled = !si->bNicklistEnabled;
+
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_SHOWNICKLIST,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon(si->bNicklistEnabled?"chat_nicklist":"chat_nicklist2"));
+ SendMessage(hwndDlg, GC_SCROLLTOBOTTOM, 0, 0);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ break;
+
+ case IDC_CHAT_MESSAGE:
+ if (HIWORD(wParam) == EN_CHANGE) {
+ si->windowData.cmdListCurrent = NULL;
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), GetRichTextLength(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE), si->windowData.codePage, FALSE) != 0);
+ }
+ break;
+
+ case IDC_CHAT_SMILEY:
+ {
+ SMADD_SHOWSEL3 smaddInfo;
+ RECT rc;
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_CHAT_SMILEY), &rc);
+
+ smaddInfo.cbSize = sizeof(SMADD_SHOWSEL3);
+ smaddInfo.hwndParent = GetParent(hwndDlg);
+ smaddInfo.hwndTarget = GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE);
+ smaddInfo.targetMessage = EM_REPLACESEL;
+ smaddInfo.targetWParam = TRUE;
+ smaddInfo.Protocolname = si->pszModule;
+ //smaddInfo.Direction = 3;
+ smaddInfo.Direction = 0;
+ smaddInfo.xPosition = rc.left;
+ smaddInfo.yPosition = rc.bottom;
+ smaddInfo.hContact = si->windowData.hContact;
+ CallService(MS_SMILEYADD_SHOWSELECTION, 0, (LPARAM) &smaddInfo);
+ }
+ break;
+
+ case IDC_CHAT_HISTORY:
+ {
+ MODULEINFO * pInfo = MM_FindModule(si->pszModule);
+
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_HISTORY)))
+ break;
+
+ if ( pInfo )
+ ShellExecute(hwndDlg, NULL, GetChatLogsFilename(si->windowData.hContact, 0), NULL, NULL, SW_SHOW);
+ }
+ break;
+
+ case IDC_CHAT_CHANMGR:
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_CHANMGR)))
+ break;
+ DoEventHookAsync(hwndDlg, si->ptszID, si->pszModule, GC_USER_CHANMGR, NULL, NULL, (LPARAM)NULL);
+ break;
+
+ case IDC_CHAT_FILTER:
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_FILTER)))
+ break;
+
+ si->bFilterEnabled = !si->bFilterEnabled;
+ SendDlgItemMessage(hwndDlg,IDC_CHAT_FILTER,BM_SETIMAGE,IMAGE_ICON,(LPARAM)GetCachedIcon(si->bFilterEnabled?"chat_filter":"chat_filter2"));
+ if (si->bFilterEnabled && DBGetContactSettingByte(NULL, "Chat", "RightClickFilter", 0) == 0) {
+ SendMessage(hwndDlg, GC_SHOWFILTERMENU, 0, 0);
+ break;
+ }
+ SendMessage(hwndDlg, GC_REDRAWLOG, 0, 0);
+ break;
+
+ case IDC_CHAT_BKGCOLOR:
+ {
+ MODULEINFO * pInfo = MM_FindModule(si->pszModule);
+ CHARFORMAT2 cf;
+
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwEffects = 0;
+
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_BKGCOLOR)))
+ break;
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_BKGCOLOR)) {
+ if (DBGetContactSettingByte(NULL, "Chat", "RightClickFilter", 0) == 0)
+ SendMessage(hwndDlg, GC_SHOWCOLORCHOOSER, 0, (LPARAM)IDC_CHAT_BKGCOLOR);
+ else if (si->bBGSet){
+ cf.dwMask = CFM_BACKCOLOR;
+ cf.crBackColor = pInfo->crColors[si->iBG];
+ if (pInfo->bSingleFormat) {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ } }
+ else {
+ cf.dwMask = CFM_BACKCOLOR;
+ cf.crBackColor = (COLORREF)DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+ if (pInfo->bSingleFormat) {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ } }
+ break;
+
+ case IDC_CHAT_COLOR:
+ {
+ MODULEINFO * pInfo = MM_FindModule(si->pszModule);
+ CHARFORMAT2 cf;
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwEffects = 0;
+
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_COLOR)))
+ break;
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_COLOR)) {
+ if (DBGetContactSettingByte(NULL, "Chat", "RightClickFilter", 0) == 0)
+ SendMessage(hwndDlg, GC_SHOWCOLORCHOOSER, 0, (LPARAM)IDC_CHAT_COLOR);
+ else if (si->bFGSet) {
+ cf.dwMask = CFM_COLOR;
+ cf.crTextColor = pInfo->crColors[si->iFG];
+ if (pInfo->bSingleFormat) {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ } }
+ else {
+ COLORREF cr;
+
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &cr, FALSE);
+ cf.dwMask = CFM_COLOR;
+ cf.crTextColor = cr;
+ if (pInfo->bSingleFormat) {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+
+ } }
+ break;
+
+ case IDC_CHAT_BOLD:
+ case IDC_CHAT_ITALICS:
+ case IDC_CHAT_UNDERLINE:
+
+ {
+ MODULEINFO * pInfo = MM_FindModule(si->pszModule);
+ CHARFORMAT2 cf;
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE;
+ cf.dwEffects = 0;
+
+ if (LOWORD(wParam) == IDC_CHAT_BOLD && !IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_BOLD)))
+ break;
+ if (LOWORD(wParam) == IDC_CHAT_ITALICS && !IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_ITALICS)))
+ break;
+ if (LOWORD(wParam) == IDC_CHAT_UNDERLINE && !IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHAT_UNDERLINE)))
+ break;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_BOLD))
+ cf.dwEffects |= CFE_BOLD;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_ITALICS))
+ cf.dwEffects |= CFE_ITALIC;
+ if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_UNDERLINE))
+ cf.dwEffects |= CFE_UNDERLINE;
+ if (pInfo->bSingleFormat) {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+ } else {
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ }
+ break;
+ case IDCANCEL:
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ }
+ break;
+
+ case WM_KEYDOWN:
+ SetFocus(GetDlgItem(hwndDlg, IDC_CHAT_MESSAGE));
+ break;
+
+
+
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO* mmi = (MINMAXINFO*)lParam;
+ mmi->ptMinTrackSize.x = si->iSplitterX + 43;
+ if (mmi->ptMinTrackSize.x < 350)
+ mmi->ptMinTrackSize.x = 350;
+
+ mmi->ptMinTrackSize.y = si->windowData.minLogBoxHeight + TOOLBAR_HEIGHT + si->windowData.minEditBoxHeight + 5;
+ }
+ break;
+
+ case WM_LBUTTONDBLCLK:
+ if (LOWORD(lParam) < 30)
+ PostMessage(hwndDlg, GC_SCROLLTOBOTTOM, 0, 0);
+ else
+ SendMessage(GetParent(hwndDlg), WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ break;
+
+ case WM_LBUTTONDOWN:
+ SendMessage(GetParent(hwndDlg), WM_LBUTTONDOWN, wParam, lParam);
+ return TRUE;
+
+ case WM_RBUTTONUP:
+ {
+ int i;
+ POINT pt;
+ MENUITEMINFO mii;
+ hToolbarMenu = CreatePopupMenu();
+ for (i = 0; i < SIZEOF(toolbarButtons); i++) {
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE | MIIM_DATA | MIIM_BITMAP;
+ mii.fType = MFT_STRING;
+ mii.fState = (g_dat->chatBbuttonVisibility & (1<< i)) ? MFS_CHECKED : MFS_UNCHECKED;
+ mii.wID = i + 1;
+ mii.dwItemData = (ULONG_PTR)g_dat->hChatButtonIconList;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ mii.dwTypeData = TranslateTS((toolbarButtons[i].name));
+ InsertMenuItem(hToolbarMenu, i, TRUE, &mii);
+ }
+// TranslateMenu(hToolbarMenu);
+ pt.x = (short) LOWORD(GetMessagePos());
+ pt.y = (short) HIWORD(GetMessagePos());
+ i = TrackPopupMenu(hToolbarMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL);
+ if (i > 0) {
+ g_dat->chatBbuttonVisibility ^= (1 << (i - 1));
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_CHATBUTTONVISIBILITY, g_dat->chatBbuttonVisibility);
+ SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, TRUE);
+ }
+ DestroyMenu(hToolbarMenu);
+ return TRUE;
+ }
+
+ case DM_GETCONTEXTMENU:
+ {
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) si->windowData.hContact, 0);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)hMenu);
+ return TRUE;
+ }
+
+ case WM_CONTEXTMENU:
+ if (GetParent(hwndDlg) == (HWND) wParam) {
+ POINT pt;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) si->windowData.hContact, 0);
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+ }
+ break;
+
+ case WM_CLOSE:
+ SendMessage(hwndDlg, GC_CLOSEWINDOW, 0, 0);
+ break;
+
+ case GC_CLOSEWINDOW:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+
+ NotifyLocalWinEvent(si->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_CLOSING);
+ si->hWnd = NULL;
+ SetWindowLongPtr(hwndDlg,GWLP_USERDATA,0);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_SPLITTERY),GWLP_WNDPROC,(LONG_PTR)OldSplitterProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_LIST),GWLP_WNDPROC,(LONG_PTR)OldNicklistProc);
+ SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_UNSUBCLASSED, 0, 0);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_MESSAGE),GWLP_WNDPROC,(LONG_PTR)OldMessageProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_LOG),GWLP_WNDPROC,(LONG_PTR)OldLogProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_FILTER),GWLP_WNDPROC,(LONG_PTR)OldFilterButtonProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_COLOR),GWLP_WNDPROC,(LONG_PTR)OldFilterButtonProc);
+ SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_CHAT_BKGCOLOR),GWLP_WNDPROC,(LONG_PTR)OldFilterButtonProc);
+
+ SendMessage(GetParent(hwndDlg), CM_REMOVECHILD, 0, (LPARAM) hwndDlg);
+ if (si->windowData.hwndLog != NULL) {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_DESTROY;
+ ieWindow.hwnd = si->windowData.hwndLog;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ }
+
+ NotifyLocalWinEvent(si->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_CLOSE);
+ break;
+ }
+ return(FALSE);
+}
diff --git a/plugins/Scriver/src/cmdlist.cpp b/plugins/Scriver/src/cmdlist.cpp new file mode 100644 index 0000000000..8f8d5b1524 --- /dev/null +++ b/plugins/Scriver/src/cmdlist.cpp @@ -0,0 +1,157 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "commonheaders.h"
+
+TCmdList *tcmdlist_append(TCmdList *list, const char *data, int maxSize, BOOL temporary) {
+ TCmdList *n;
+ TCmdList *new_list = (TCmdList *)mir_alloc(sizeof(TCmdList));
+ TCmdList *attach_to = NULL;
+
+ if (!data) {
+ mir_free(new_list);
+ return list;
+ }
+ new_list->temporary = temporary;
+ new_list->next = NULL;
+ new_list->szCmd = mir_strdup(data);
+ for (n=list; n!=NULL; n=n->next) {
+ attach_to = n;
+ }
+ if (attach_to==NULL) {
+ new_list->prev = NULL;
+ return new_list;
+ } else {
+ new_list->prev = attach_to;
+ attach_to->next = new_list;
+ if (tcmdlist_len(list)>maxSize) {
+ list = tcmdlist_remove_first(list);
+ }
+ return list;
+ }
+}
+
+TCmdList *tcmdlist_remove_first(TCmdList *list) {
+ TCmdList *n = list;
+ if (n->next) n->next->prev = n->prev;
+ if (n->prev) n->prev->next = n->next;
+ list = n->next;
+ mir_free(n->szCmd);
+ mir_free(n);
+ return list;
+}
+
+TCmdList *tcmdlist_remove(TCmdList *list, TCmdList *n) {
+ if (n->next) n->next->prev = n->prev;
+ if (n->prev) n->prev->next = n->next;
+ if (n==list) list = n->next;
+ mir_free(n->szCmd);
+ mir_free(n);
+ return list;
+}
+
+TCmdList *tcmdlist_append2(TCmdList *list, HANDLE hContact, const char *data) {
+ TCmdList *n;
+ TCmdList *new_list = (TCmdList *)mir_alloc(sizeof(TCmdList));
+ TCmdList *attach_to = NULL;
+
+ if (!data) {
+ mir_free(new_list);
+ return list;
+ }
+ new_list->temporary = FALSE;
+ new_list->next = NULL;
+ new_list->hContact = hContact;
+ new_list->szCmd = mir_strdup(data);
+ list = tcmdlist_remove2(list, hContact);
+ for (n=list; n!=NULL; n=n->next) {
+ attach_to = n;
+ }
+ if (attach_to==NULL) {
+ new_list->prev = NULL;
+ return new_list;
+ }
+ else {
+ new_list->prev = attach_to;
+ attach_to->next = new_list;
+ return list;
+ }
+}
+
+TCmdList *tcmdlist_remove2(TCmdList *list, HANDLE hContact) {
+ TCmdList *n;
+ for (n=list; n!=NULL; n=n->next) {
+ if (n->hContact==hContact) {
+ if (n->next) n->next->prev = n->prev;
+ if (n->prev) n->prev->next = n->next;
+ if (n==list) list = n->next;
+ mir_free(n->szCmd);
+ mir_free(n);
+ return list;
+ }
+ }
+ return list;
+}
+
+TCmdList *tcmdlist_get2(TCmdList *list, HANDLE hContact) {
+ TCmdList *n;
+ for (n=list; n!=NULL; n=n->next) {
+ if (n->hContact==hContact) {
+ return n;
+ }
+ }
+ return NULL;
+}
+
+int tcmdlist_len(TCmdList *list) {
+ TCmdList *n;
+ int i = 0;
+
+ for (n=list; n!=NULL; n=n->next) {
+ i++;
+ }
+ return i;
+}
+
+TCmdList *tcmdlist_last(TCmdList *list) {
+ TCmdList *n;
+
+ for (n=list; n!=NULL; n=n->next) {
+ if (!n->next)
+ return n;
+ }
+ return NULL;
+}
+
+void tcmdlist_free(TCmdList *list) {
+ TCmdList *n = list, *next;
+
+ while (n!=NULL) {
+ next = n->next;
+ mir_free(n->szCmd);
+ mir_free(n);
+ n = next;
+ }
+}
diff --git a/plugins/Scriver/src/cmdlist.h b/plugins/Scriver/src/cmdlist.h new file mode 100644 index 0000000000..f3ff8309db --- /dev/null +++ b/plugins/Scriver/src/cmdlist.h @@ -0,0 +1,42 @@ +/*
+AOL Instant Messenger Plugin for Miranda IM
+
+Copyright (c) 2003 Robert Rainwater
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef SRMM_CMDLIST_H
+#define SRMM_CMDLIST_H
+
+
+typedef struct _TCmdList {
+ struct _TCmdList *next;
+ struct _TCmdList *prev;
+ HANDLE hContact;
+ char *szCmd;
+ BOOL temporary;
+} TCmdList;
+
+TCmdList *tcmdlist_append(TCmdList *list, const char *data, int maxSize, BOOL temporary);
+TCmdList *tcmdlist_remove(TCmdList *list, TCmdList *n);
+TCmdList *tcmdlist_remove_first(TCmdList *list);
+TCmdList *tcmdlist_append2(TCmdList *list, HANDLE hContact, const char *data);
+TCmdList *tcmdlist_remove2(TCmdList *list, HANDLE hContact);
+TCmdList *tcmdlist_get2(TCmdList *list, HANDLE hContact);
+int tcmdlist_len(TCmdList *list);
+TCmdList *tcmdlist_last(TCmdList *list);
+void tcmdlist_free(TCmdList * list);
+
+#endif
diff --git a/plugins/Scriver/src/commonheaders.h b/plugins/Scriver/src/commonheaders.h new file mode 100644 index 0000000000..6271ef0aa9 --- /dev/null +++ b/plugins/Scriver/src/commonheaders.h @@ -0,0 +1,130 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef SRMM_COMMONHEADERS_H
+#define SRMM_COMMONHEADERS_H
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#define MIRANDA_VER 0x0A00
+
+#define COMPILE_MULTIMON_STUBS
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0501
+#define WIN32_LEAN_AND_MEAN
+
+#include <m_stdhdr.h>
+
+#include <windows.h>
+#include <shellapi.h>
+#include <shlobj.h>
+#include <commctrl.h>
+#include <commdlg.h>
+#include <ole2.h>
+
+#include <uxtheme.h>
+#include <vssym32.h>
+
+#include <time.h>
+
+#include <win2k.h>
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_button.h>
+#include <m_clist.h>
+#include <m_clc.h>
+#include <m_clui.h>
+#include <m_options.h>
+#include <m_protosvc.h>
+#include <m_utils.h>
+#include <m_skin.h>
+#include <m_contacts.h>
+#include <m_userinfo.h>
+#include <m_history.h>
+#include <m_addcontact.h>
+#include <m_message.h>
+#include <m_file.h>
+#include <m_fontservice.h>
+#include <m_icolib.h>
+#include <m_avatars.h>
+#include <m_hotkeys.h>
+#include <m_popup.h>
+#include <m_timezones.h>
+
+#include "m_ieview.h"
+
+#include "resource.h"
+#include "globals.h"
+#include "msgs.h"
+#include "msgwindow.h"
+#include "utils.h"
+#include "input.h"
+#include "sendqueue.h"
+
+#include "m_smileyadd.h"
+#include "m_metacontacts.h"
+#include "m_historyevents.h"
+#include "richutil.h"
+
+#ifndef IMF_AUTOFONTSIZEADJUST
+#define IMF_AUTOFONTSIZEADJUST 0x0010
+#endif
+#ifndef IMF_AUTOKEYBOARD
+#define IMF_AUTOKEYBOARD 0x0001
+#endif
+#ifndef SES_EXTENDBACKCOLOR
+#define SES_EXTENDBACKCOLOR 4
+#endif
+#ifndef ST_NEWCHARS
+#define ST_NEWCHARS 4
+#endif
+#ifndef CFM_WEIGHT
+#define CFM_WEIGHT 0x00400000
+#endif
+
+extern HWND SM_FindWindowByContact(HANDLE hContact);
+extern HINSTANCE g_hInst;
+
+#define SPLITTER_HEIGHT 4
+#define TOOLBAR_HEIGHT 24
+#define INFO_BAR_HEIGHT 54
+#define INFO_BAR_INNER_HEIGHT (INFO_BAR_HEIGHT - 3)
+#define INFO_BAR_AVATAR_HEIGHT INFO_BAR_INNER_HEIGHT
+#define BOTTOM_RIGHT_AVATAR_HEIGHT 64
+#define INFO_BAR_COLOR COLOR_INACTIVEBORDER
+
+int Chat_Load();
+int Chat_Unload();
+int Chat_ModulesLoaded(WPARAM wParam,LPARAM lParam);
+int Chat_FontsChanged(WPARAM wParam,LPARAM lParam);
+int Chat_SmileyOptionsChanged(WPARAM wParam,LPARAM lParam);
+int Chat_PreShutdown(WPARAM wParam,LPARAM lParam);
+int Chat_IconsChanged(WPARAM wParam,LPARAM lParam);
+int OptInitialise(WPARAM wParam, LPARAM lParam);
+int FontServiceFontsChanged(WPARAM wParam, LPARAM lParam);
+int StatusIconPressed(WPARAM wParam, LPARAM lParam);
+
+#endif
diff --git a/plugins/Scriver/src/globals.cpp b/plugins/Scriver/src/globals.cpp new file mode 100644 index 0000000000..9a81ebcdbb --- /dev/null +++ b/plugins/Scriver/src/globals.cpp @@ -0,0 +1,504 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "m_ieview.h"
+
+struct GlobalMessageData *g_dat=NULL;
+extern PSLWA pSetLayeredWindowAttributes;
+
+HANDLE hEventSkin2IconsChanged;
+
+static int ackevent(WPARAM wParam, LPARAM lParam);
+
+extern int Chat_ModulesLoaded(WPARAM wParam,LPARAM lParam);
+extern int Chat_PreShutdown(WPARAM wParam,LPARAM lParam);
+
+static const char *buttonIcons[] = {"scriver_CLOSEX", "scriver_QUOTE", "scriver_SMILEY",
+ "scriver_ADD", NULL, "scriver_USERDETAILS", "scriver_HISTORY",
+ "scriver_SEND"};
+
+static const char *chatButtonIcons[] = {"scriver_CLOSEX",
+ "chat_bold", "chat_italics", "chat_underline",
+ "chat_fgcol", "chat_bkgcol",
+ "chat_smiley", "chat_history",
+ "chat_filter", "chat_settings", "chat_nicklist", "scriver_SEND"};
+
+typedef struct IconDefStruct
+{
+ char* section;
+ char *name;
+ int defaultIndex;
+ char *description;
+ int size;
+} IconDef;
+
+static const IconDef iconList[] = {
+ {LPGEN("Single Messaging"), "scriver_ADD", IDI_ADDCONTACT, LPGEN("Add contact")},
+ {LPGEN("Single Messaging"), "scriver_USERDETAILS", IDI_USERDETAILS, LPGEN("User's details")},
+ {LPGEN("Single Messaging"), "scriver_HISTORY", IDI_HISTORY, LPGEN("User's history")},
+ {LPGEN("Single Messaging"), "scriver_SEND", IDI_SEND, LPGEN("Send message")},
+ {LPGEN("Single Messaging"), "scriver_SMILEY", IDI_SMILEY, LPGEN("Smiley button")},
+ {LPGEN("Single Messaging"), "scriver_TYPING", IDI_TYPING, LPGEN("User is typing")},
+ {LPGEN("Single Messaging"), "scriver_TYPINGOFF", IDI_TYPINGOFF, LPGEN("Typing notification off")},
+ {LPGEN("Single Messaging"), "scriver_UNICODEON", IDI_UNICODEON, LPGEN("Unicode is on")},
+ {LPGEN("Single Messaging"), "scriver_UNICODEOFF", IDI_UNICODEOFF, LPGEN("Unicode is off")},
+ {LPGEN("Single Messaging"), "scriver_DELIVERING", IDI_TIMESTAMP, LPGEN("Sending")},
+ {LPGEN("Single Messaging"), "scriver_QUOTE", IDI_QUOTE, LPGEN("Quote button")},
+ {LPGEN("Single Messaging"), "scriver_CLOSEX", IDI_CLOSEX, LPGEN("Close button")},
+ {LPGEN("Single Messaging"), "scriver_OVERLAY", IDI_OVERLAY, LPGEN("Icon overlay")},
+ {LPGEN("Single Messaging"), "scriver_INCOMING", IDI_INCOMING, LPGEN("Incoming message (10x10)"),10},
+ {LPGEN("Single Messaging"), "scriver_OUTGOING", IDI_OUTGOING, LPGEN("Outgoing message (10x10)"),10},
+ {LPGEN("Single Messaging"), "scriver_NOTICE", IDI_NOTICE, LPGEN("Notice (10x10)"),10},
+ {LPGEN("Group Chats"), "chat_window", IDI_CHANMGR, LPGEN("Window Icon")},
+ {LPGEN("Group Chats"), "chat_fgcol", IDI_COLOR, LPGEN("Text colour")},
+ {LPGEN("Group Chats"), "chat_bkgcol", IDI_BKGCOLOR, LPGEN("Background colour")},
+ {LPGEN("Group Chats"), "chat_bold", IDI_BBOLD, LPGEN("Bold")},
+ {LPGEN("Group Chats"), "chat_italics", IDI_BITALICS, LPGEN("Italics")},
+ {LPGEN("Group Chats"), "chat_underline", IDI_BUNDERLINE, LPGEN("Underlined")},
+ {LPGEN("Group Chats"), "chat_smiley", IDI_SMILEY, LPGEN("Smiley button")},
+ {LPGEN("Group Chats"), "chat_history", IDI_HISTORY, LPGEN("Room history")},
+ {LPGEN("Group Chats"), "chat_settings", IDI_TOPICBUT, LPGEN("Room settings")},
+ {LPGEN("Group Chats"), "chat_filter", IDI_FILTER, LPGEN("Event filter disabled")},
+ {LPGEN("Group Chats"), "chat_filter2", IDI_FILTER2, LPGEN("Event filter enabled")},
+ {LPGEN("Group Chats"), "chat_nicklist", IDI_NICKLIST, LPGEN("Hide userlist")},
+ {LPGEN("Group Chats"), "chat_nicklist2", IDI_NICKLIST2, LPGEN("Show userlist")},
+ {LPGEN("Group Chats"), "chat_overlay", IDI_OVERLAY, LPGEN("Icon overlay")},
+ {LPGEN("Group Chats"), "chat_status0", IDI_STATUS0, LPGEN("Status 1 (10x10)"),10},
+ {LPGEN("Group Chats"), "chat_status1", IDI_STATUS1, LPGEN("Status 2 (10x10"),10},
+ {LPGEN("Group Chats"), "chat_status2", IDI_STATUS2, LPGEN("Status 3 (10x10)"),10},
+ {LPGEN("Group Chats"), "chat_status3", IDI_STATUS3, LPGEN("Status 4 (10x10)"),10},
+ {LPGEN("Group Chats"), "chat_status4", IDI_STATUS4, LPGEN("Status 5 (10x10)"),10},
+ {LPGEN("Group Chats"), "chat_status5", IDI_STATUS5, LPGEN("Status 6 (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_message_in", IDI_INCOMING, LPGEN("Message in (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_message_out", IDI_OUTGOING, LPGEN("Message out (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_action", IDI_ACTION, LPGEN("Action (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_addstatus", IDI_ADDSTATUS, LPGEN("Add Status (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_removestatus", IDI_REMSTATUS, LPGEN("Remove status (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_join", IDI_JOIN, LPGEN("Join (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_part", IDI_PART, LPGEN("Leave (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_quit", IDI_QUIT, LPGEN("Quit (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_kick", IDI_KICK, LPGEN("Kick (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_nick", IDI_NICK, LPGEN("Nickchange (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_notice", IDI_CHAT_NOTICE, LPGEN("Notice (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_topic", IDI_TOPIC, LPGEN("Topic (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_highlight", IDI_NOTICE, LPGEN("Highlight (10x10)"),10},
+ {LPGEN("Group Chats Log"), "chat_log_info", IDI_INFO, LPGEN("Information (10x10)"),10}
+};
+
+HICON hIconList[SIZEOF(iconList)];
+
+BOOL IsStaticIcon(HICON hIcon) {
+ int i;
+ for (i = 0; i < SIZEOF(hIconList); i++) {
+ if (hIcon == hIconList[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void ReleaseIconSmart(HICON hIcon) {
+ if (!IsStaticIcon(hIcon)) {
+ DWORD result = CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ if ( result == 1 || result == CALLSERVICE_NOTFOUND)
+ DestroyIcon(hIcon);
+ }
+}
+
+int ImageList_AddIcon_Ex(HIMAGELIST hIml, int id) {
+ HICON hIcon = LoadSkinnedIcon(id);
+ int res = ImageList_AddIcon(hIml, hIcon);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ return res;
+}
+
+int ImageList_AddIcon_Ex2(HIMAGELIST hIml, HICON hIcon) {
+ int res = ImageList_AddIcon(hIml, hIcon);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ return res;
+}
+
+int ImageList_ReplaceIcon_Ex(HIMAGELIST hIml, int nIndex, int id) {
+ HICON hIcon = LoadSkinnedIcon(id);
+ int res = ImageList_ReplaceIcon(hIml, nIndex, hIcon);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ return res;
+}
+
+int ImageList_AddIcon_ProtoEx(HIMAGELIST hIml, const char* szProto, int status) {
+ HICON hIcon = LoadSkinnedProtoIcon(szProto, status);
+ int res = ImageList_AddIcon(hIml, hIcon);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ return res;
+}
+
+void RegisterIcons(void)
+{
+ hEventSkin2IconsChanged = HookEvent_Ex(ME_SKIN2_ICONSCHANGED, IconsChanged);
+
+ TCHAR path[MAX_PATH];
+ char szSection[200];
+ GetModuleFileName(g_hInst, path, MAX_PATH);
+
+ SKINICONDESC sid = { 0 };
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.flags = SIDF_PATH_TCHAR;
+ sid.ptszDefaultFile = path;
+ sid.pszSection = szSection;
+ for (int i = 0; i < SIZEOF(iconList); i++) {
+ mir_snprintf(szSection, SIZEOF(szSection), "%s/%s", LPGEN("Messaging"), iconList[i].section);
+ sid.pszName = (char*)iconList[i].name;
+ sid.cx = sid.cy = iconList[i].size;
+ sid.iDefaultIndex = -iconList[i].defaultIndex;
+ sid.pszDescription = iconList[i].description;
+ Skin_AddIcon(&sid);
+ }
+}
+
+void ReleaseIcons()
+{
+ int i;
+ for (i = 0; i < SIZEOF(hIconList); i++) {
+ if (hIconList[i] != NULL) {
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIconList[i], 0);
+ }
+ }
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)g_dat->hMsgIcon, 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)g_dat->hMsgIconBig, 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)g_dat->hIconChatBig, 0);
+}
+
+HICON GetCachedIcon(const char *name)
+{
+ int i;
+ for (i = 0; i < SIZEOF(iconList); i++) {
+ if (!strcmp(iconList[i].name, name)) {
+ return hIconList[i];
+ }
+ }
+ return NULL;
+}
+
+void LoadGlobalIcons() {
+ int i;
+ int overlayIcon;
+ for (i = 0; i < SIZEOF(iconList); i++) {
+ hIconList[i] = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconList[i].name);
+ }
+
+ g_dat->hMsgIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ g_dat->hMsgIconBig = LoadSkinnedIconBig(SKINICON_EVENT_MESSAGE);
+ g_dat->hIconChatBig = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM)"chat_window");
+
+ ImageList_RemoveAll(g_dat->hButtonIconList);
+ ImageList_RemoveAll(g_dat->hChatButtonIconList);
+ ImageList_RemoveAll(g_dat->hHelperIconList);
+ ImageList_RemoveAll(g_dat->hSearchEngineIconList);
+ for (i=0; i<SIZEOF(buttonIcons); i++) {
+ if (buttonIcons[i] == NULL) {
+ ImageList_AddIcon_ProtoEx(g_dat->hButtonIconList, NULL, ID_STATUS_OFFLINE);
+ } else {
+ ImageList_AddIcon(g_dat->hButtonIconList, GetCachedIcon(buttonIcons[i]));
+ }
+ }
+ for (i=0; i<SIZEOF(chatButtonIcons); i++) {
+ ImageList_AddIcon(g_dat->hChatButtonIconList, GetCachedIcon(chatButtonIcons[i]));
+ }
+ ImageList_AddIcon(g_dat->hHelperIconList, GetCachedIcon("scriver_OVERLAY"));
+ overlayIcon = ImageList_AddIcon(g_dat->hHelperIconList, GetCachedIcon("scriver_OVERLAY"));
+ ImageList_SetOverlayImage(g_dat->hHelperIconList, overlayIcon, 1);
+ for (i=0; i<IDI_FOODNETWORK - IDI_GOOGLE + 1; i++) {
+ HICON hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_GOOGLE + i), IMAGE_ICON, 0, 0, 0);
+ ImageList_AddIcon(g_dat->hSearchEngineIconList, hIcon);
+ DestroyIcon(hIcon);
+ }
+}
+
+static BOOL CALLBACK LangAddCallback(CHAR * str) {
+ int i, count;
+ UINT cp;
+ static struct { UINT cpId; const TCHAR *cpName; } cpTable[] = {
+ { 874, _T("Thai") },
+ { 932, _T("Japanese") },
+ { 936, _T("Simplified Chinese") },
+ { 949, _T("Korean") },
+ { 950, _T("Traditional Chinese") },
+ { 1250, _T("Central European") },
+ { 1251, _T("Cyrillic") },
+ { 1252, _T("Latin I") },
+ { 1253, _T("Greek") },
+ { 1254, _T("Turkish") },
+ { 1255, _T("Hebrew") },
+ { 1256, _T("Arabic") },
+ { 1257, _T("Baltic") },
+ { 1258, _T("Vietnamese") },
+ { 1361, _T("Korean (Johab)") }
+ };
+ cp = atoi(str);
+ count = sizeof(cpTable)/sizeof(cpTable[0]);
+ for (i=0; i<count && cpTable[i].cpId!=cp; i++);
+ if (i < count) {
+ AppendMenu(g_dat->hMenuANSIEncoding, MF_STRING, cp, TranslateTS(cpTable[i].cpName));
+ }
+ return TRUE;
+}
+
+void LoadInfobarFonts()
+{
+ LOGFONT lf;
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, NULL, FALSE);
+ g_dat->minInputAreaHeight = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_AUTORESIZELINES, SRMSGDEFSET_AUTORESIZELINES) * abs(lf.lfHeight) * g_dat->logPixelSY / 72;
+ if (g_dat->hInfobarBrush != NULL) {
+ DeleteObject(g_dat->hInfobarBrush);
+ }
+ g_dat->hInfobarBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INFOBARBKGCOLOUR, SRMSGDEFSET_INFOBARBKGCOLOUR));
+}
+
+void InitGlobals() {
+ HDC hdc = GetDC(NULL);
+ g_dat = (struct GlobalMessageData *)mir_alloc(sizeof(struct GlobalMessageData));
+ ZeroMemory(g_dat, sizeof(struct GlobalMessageData));
+ g_dat->hMessageWindowList = (HANDLE) CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
+ g_dat->hParentWindowList = (HANDLE) CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
+
+ HookEvent_Ex(ME_PROTO_ACK, ackevent);
+ ReloadGlobals();
+ g_dat->lastParent = NULL;
+ g_dat->lastChatParent = NULL;
+ g_dat->hTabIconList = NULL;
+ g_dat->tabIconListUsage = NULL;
+ g_dat->tabIconListUsageSize = 0;
+ g_dat->hButtonIconList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 0, 0);
+ g_dat->hChatButtonIconList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 0, 0);
+ g_dat->hTabIconList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 0, 0);
+ g_dat->hHelperIconList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 0, 0);
+ g_dat->hSearchEngineIconList = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 0, 0);
+ g_dat->draftList = NULL;
+ g_dat->logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX);
+ g_dat->logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ LoadInfobarFonts();
+ ReleaseDC(NULL, hdc);
+}
+
+void FreeGlobals() {
+ if (g_dat) {
+ if (g_dat->hInfobarBrush != NULL) {
+ DeleteObject(g_dat->hInfobarBrush);
+ }
+ if (g_dat->draftList != NULL) tcmdlist_free(g_dat->draftList);
+ if (g_dat->hTabIconList)
+ ImageList_Destroy(g_dat->hTabIconList);
+ if (g_dat->hButtonIconList)
+ ImageList_Destroy(g_dat->hButtonIconList);
+ if (g_dat->hChatButtonIconList)
+ ImageList_Destroy(g_dat->hChatButtonIconList);
+ if (g_dat->hHelperIconList)
+ ImageList_Destroy(g_dat->hHelperIconList);
+ if (g_dat->hSearchEngineIconList)
+ ImageList_Destroy(g_dat->hSearchEngineIconList);
+ if (g_dat->hMenuANSIEncoding)
+ DestroyMenu(g_dat->hMenuANSIEncoding);
+ mir_free(g_dat->tabIconListUsage);
+ mir_free(g_dat);
+ g_dat = NULL;
+ }
+}
+
+void ReloadGlobals() {
+ g_dat->smileyAddInstalled = ServiceExists(MS_SMILEYADD_SHOWSELECTION);
+ g_dat->popupInstalled = ServiceExists(MS_POPUP_ADDPOPUPEX);
+ g_dat->ieviewInstalled = ServiceExists(MS_IEVIEW_WINDOW);
+ g_dat->flags = 0;
+ g_dat->flags2 = 0;
+// if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDBUTTON, SRMSGDEFSET_SENDBUTTON))
+// g_dat->flags |= SMF_SENDBTN;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AVATARENABLE, SRMSGDEFSET_AVATARENABLE)) {
+ g_dat->flags |= SMF_AVATAR;
+ }
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWPROGRESS, SRMSGDEFSET_SHOWPROGRESS))
+ g_dat->flags |= SMF_SHOWPROGRESS;
+
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, SRMSGDEFSET_SHOWLOGICONS))
+ g_dat->flags |= SMF_SHOWICONS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, SRMSGDEFSET_SHOWTIME))
+ g_dat->flags |= SMF_SHOWTIME;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECONDS, SRMSGDEFSET_SHOWSECONDS))
+ g_dat->flags |= SMF_SHOWSECONDS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, SRMSGDEFSET_SHOWDATE))
+ g_dat->flags |= SMF_SHOWDATE;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USELONGDATE, SRMSGDEFSET_USELONGDATE))
+ g_dat->flags |= SMF_LONGDATE;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USERELATIVEDATE, SRMSGDEFSET_USERELATIVEDATE))
+ g_dat->flags |= SMF_RELATIVEDATE;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_GROUPMESSAGES, SRMSGDEFSET_GROUPMESSAGES))
+ g_dat->flags |= SMF_GROUPMESSAGES;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_MARKFOLLOWUPS, SRMSGDEFSET_MARKFOLLOWUPS))
+ g_dat->flags |= SMF_MARKFOLLOWUPS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_MESSAGEONNEWLINE, SRMSGDEFSET_MESSAGEONNEWLINE))
+ g_dat->flags |= SMF_MSGONNEWLINE;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DRAWLINES, SRMSGDEFSET_DRAWLINES))
+ g_dat->flags |= SMF_DRAWLINES;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, SRMSGDEFSET_HIDENAMES))
+ g_dat->flags |= SMF_HIDENAMES;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOPOPUP, SRMSGDEFSET_AUTOPOPUP))
+ g_dat->flags |= SMF_AUTOPOPUP;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STAYMINIMIZED, SRMSGDEFSET_STAYMINIMIZED))
+ g_dat->flags |= SMF_STAYMINIMIZED;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEDRAFTS, SRMSGDEFSET_SAVEDRAFTS))
+ g_dat->flags |= SMF_SAVEDRAFTS;
+
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DELTEMP, SRMSGDEFSET_DELTEMP))
+ g_dat->flags |= SMF_DELTEMP;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))
+ g_dat->flags |= SMF_SENDONENTER;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER))
+ g_dat->flags |= SMF_SENDONDBLENTER;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON))
+ g_dat->flags |= SMF_STATUSICON;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_INDENTTEXT, SRMSGDEFSET_INDENTTEXT))
+ g_dat->flags |= SMF_INDENTTEXT;
+
+ g_dat->openFlags = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_POPFLAGS, SRMSGDEFSET_POPFLAGS);
+ g_dat->indentSize = DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_INDENTSIZE, SRMSGDEFSET_INDENTSIZE);
+ g_dat->logLineColour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LINECOLOUR, SRMSGDEFSET_LINECOLOUR);
+
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USETABS, SRMSGDEFSET_USETABS))
+ g_dat->flags2 |= SMF2_USETABS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TABSATBOTTOM, SRMSGDEFSET_TABSATBOTTOM))
+ g_dat->flags2 |= SMF2_TABSATBOTTOM;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SWITCHTOACTIVE, SRMSGDEFSET_SWITCHTOACTIVE))
+ g_dat->flags2 |= SMF2_SWITCHTOACTIVE;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITNAMES, SRMSGDEFSET_LIMITNAMES))
+ g_dat->flags2 |= SMF2_LIMITNAMES;
+ g_dat->flags2 |= SMF2_HIDEONETAB;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SEPARATECHATSCONTAINERS, SRMSGDEFSET_SEPARATECHATSCONTAINERS))
+ g_dat->flags2 |= SMF2_SEPARATECHATSCONTAINERS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITTABS, SRMSGDEFSET_LIMITTABS))
+ g_dat->flags2 |= SMF2_LIMITTABS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITCHATSTABS, SRMSGDEFSET_LIMITCHATSTABS))
+ g_dat->flags2 |= SMF2_LIMITCHATSTABS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDECONTAINERS, SRMSGDEFSET_HIDECONTAINERS))
+ g_dat->flags2 |= SMF2_HIDECONTAINERS;
+
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSBAR, SRMSGDEFSET_SHOWSTATUSBAR))
+ g_dat->flags2 |= SMF2_SHOWSTATUSBAR;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTITLEBAR, SRMSGDEFSET_SHOWTITLEBAR))
+ g_dat->flags2 |= SMF2_SHOWTITLEBAR;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWBUTTONLINE, SRMSGDEFSET_SHOWBUTTONLINE))
+ g_dat->flags2 |= SMF2_SHOWTOOLBAR;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWINFOBAR, SRMSGDEFSET_SHOWINFOBAR))
+ g_dat->flags2 |= SMF2_SHOWINFOBAR;
+
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPING, SRMSGDEFSET_SHOWTYPING))
+ g_dat->flags2 |= SMF2_SHOWTYPING;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGWIN, SRMSGDEFSET_SHOWTYPINGWIN))
+ g_dat->flags2 |= SMF2_SHOWTYPINGWIN;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGNOWIN, SRMSGDEFSET_SHOWTYPINGNOWIN))
+ g_dat->flags2 |= SMF2_SHOWTYPINGTRAY;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, SRMSGDEFSET_SHOWTYPINGCLIST))
+ g_dat->flags2 |= SMF2_SHOWTYPINGCLIST;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGSWITCH, SRMSGDEFSET_SHOWTYPINGSWITCH))
+ g_dat->flags2 |= SMF2_SHOWTYPINGSWITCH;
+
+ if (LOBYTE(LOWORD(GetVersion())) >= 5 && pSetLayeredWindowAttributes != NULL) {
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USETRANSPARENCY, SRMSGDEFSET_USETRANSPARENCY))
+ g_dat->flags2 |= SMF2_USETRANSPARENCY;
+ g_dat->activeAlpha = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_ACTIVEALPHA, SRMSGDEFSET_ACTIVEALPHA);
+ g_dat->inactiveAlpha = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INACTIVEALPHA, SRMSGDEFSET_INACTIVEALPHA);
+ }
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USEIEVIEW, SRMSGDEFSET_USEIEVIEW))
+ g_dat->flags |= SMF_USEIEVIEW;
+
+ g_dat->buttonVisibility = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BUTTONVISIBILITY, SRMSGDEFSET_BUTTONVISIBILITY);
+ g_dat->chatBbuttonVisibility = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_CHATBUTTONVISIBILITY, SRMSGDEFSET_CHATBUTTONVISIBILITY);
+
+ g_dat->limitNamesLength = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITNAMESLEN, SRMSGDEFSET_LIMITNAMESLEN);
+ g_dat->limitTabsNum = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITTABSNUM, SRMSGDEFSET_LIMITTABSNUM);
+ g_dat->limitChatsTabsNum = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITCHATSTABSNUM, SRMSGDEFSET_LIMITCHATSTABSNUM);
+
+}
+
+static int ackevent(WPARAM wParam, LPARAM lParam) {
+ ACKDATA *pAck = (ACKDATA *)lParam;
+
+ if (!pAck) return 0;
+ else if (pAck->type==ACKTYPE_MESSAGE) {
+ ACKDATA *ack = (ACKDATA *) lParam;
+ DBEVENTINFO dbei = { 0 };
+ HANDLE hNewEvent;
+ MessageSendQueueItem * item;
+ HWND hwndSender;
+
+ item = FindSendQueueItem((HANDLE)pAck->hContact, (HANDLE)pAck->hProcess);
+ if (item != NULL) {
+ hwndSender = item->hwndSender;
+ if (ack->result == ACKRESULT_FAILED) {
+ if (item->hwndErrorDlg != NULL) {
+ item = FindOldestPendingSendQueueItem(hwndSender, (HANDLE)pAck->hContact);
+ }
+ if (item != NULL && item->hwndErrorDlg == NULL) {
+ if (hwndSender != NULL) {
+ ErrorWindowData *ewd = (ErrorWindowData *) mir_alloc(sizeof(ErrorWindowData));
+ ewd->szName = GetNickname(item->hContact, item->proto);
+ ewd->szDescription = a2t((char *) ack->lParam);
+ ewd->szText = GetSendBufferMsg(item);
+ ewd->hwndParent = hwndSender;
+ ewd->queueItem = item;
+ SendMessage(hwndSender, DM_STOPMESSAGESENDING, 0, 0);
+ SendMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)ewd);
+ } else {
+ RemoveSendQueueItem(item);
+ }
+ }
+ return 0;
+ }
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT | (( item->flags & PREF_RTL) ? DBEF_RTL : 0 );
+ if ( item->flags & PREF_UTF )
+ dbei.flags |= DBEF_UTF;
+ dbei.szModule = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) item->hContact, 0);
+ dbei.timestamp = time(NULL);
+ dbei.cbBlob = lstrlenA(item->sendBuffer) + 1;
+ if ( !( item->flags & PREF_UTF ))
+ dbei.cbBlob *= sizeof(TCHAR) + 1;
+ dbei.pBlob = (PBYTE) item->sendBuffer;
+ hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM) item->hContact, (LPARAM) & dbei);
+
+ if (item->hwndErrorDlg != NULL) {
+ DestroyWindow(item->hwndErrorDlg);
+ }
+
+ if (RemoveSendQueueItem(item) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE)) {
+ if (hwndSender != NULL) {
+ DestroyWindow(hwndSender);
+ }
+ } else if (hwndSender != NULL) {
+ SendMessage(hwndSender, DM_STOPMESSAGESENDING, 0, 0);
+ SkinPlaySound("SendMsg");
+ }
+ }
+ }
+ return 0;
+}
diff --git a/plugins/Scriver/src/globals.h b/plugins/Scriver/src/globals.h new file mode 100644 index 0000000000..d3ec2af2d8 --- /dev/null +++ b/plugins/Scriver/src/globals.h @@ -0,0 +1,145 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef SRMM_GLOBALS_H
+#define SRMM_GLOBALS_H
+
+#include "cmdlist.h"
+#include "msgs.h"
+
+#define SMF_AUTOPOPUP 0x00000001
+#define SMF_STAYMINIMIZED 0x00000002
+#define SMF_CLOSEONSEND 0x00000004
+#define SMF_MINIMIZEONSEND 0x00000008
+#define SMF_SAVEDRAFTS 0x00000040
+#define SMF_DELTEMP 0x00000080
+#define SMF_SENDONENTER 0x00000100
+#define SMF_SENDONDBLENTER 0x00000200
+#define SMF_SHOWPROGRESS 0x00000400
+#define SMF_AVATAR 0x00000800
+#define SMF_STATUSICON 0x00002000
+#define SMF_RTL 0x00004000
+#define SMF_USEIEVIEW 0x00010000
+#define SMF_SHOWICONS 0x00020000
+#define SMF_HIDENAMES 0x00040000
+#define SMF_SHOWTIME 0x00080000
+#define SMF_SHOWDATE 0x00100000
+#define SMF_LONGDATE 0x00200000
+#define SMF_RELATIVEDATE 0x00400000
+#define SMF_SHOWSECONDS 0x00800000
+#define SMF_GROUPMESSAGES 0x01000000
+#define SMF_MARKFOLLOWUPS 0x02000000
+#define SMF_MSGONNEWLINE 0x04000000
+#define SMF_DRAWLINES 0x08000000
+#define SMF_INDENTTEXT 0x10000000
+#define SMF_ORIGINALAVATARH 0x20000000
+
+#define SMF2_USETABS 0x00000001
+#define SMF2_HIDEONETAB 0x00000002
+#define SMF2_TABSATBOTTOM 0x00000004
+#define SMF2_LIMITNAMES 0x00000008
+#define SMF2_SWITCHTOACTIVE 0x00000010
+#define SMF2_SEPARATECHATSCONTAINERS 0x00000020
+#define SMF2_LIMITTABS 0x00000080
+#define SMF2_LIMITCHATSTABS 0x00000100
+#define SMF2_HIDECONTAINERS 0x00000200
+#define SMF2_SHOWINFOBAR 0x00000400
+#define SMF2_SHOWSTATUSBAR 0x00010000
+#define SMF2_SHOWTITLEBAR 0x00020000
+#define SMF2_SHOWTOOLBAR 0x00040000
+#define SMF2_USETRANSPARENCY 0x00080000
+#define SMF2_SHOWTYPING 0x01000000
+#define SMF2_SHOWTYPINGWIN 0x02000000
+#define SMF2_SHOWTYPINGTRAY 0x04000000
+#define SMF2_SHOWTYPINGCLIST 0x08000000
+#define SMF2_SHOWTYPINGSWITCH 0x10000000
+
+typedef struct ImageListUsageEntry_tag
+{
+ int index;
+ int used;
+} ImageListUsageEntry;
+
+
+struct GlobalMessageData
+{
+ unsigned int flags;
+ unsigned int flags2;
+ HANDLE hMessageWindowList;
+ DWORD openFlags;
+ HANDLE hParentWindowList;
+ ParentWindowData *lastParent;
+ ParentWindowData *lastChatParent;
+ int limitNamesLength;
+ int activeAlpha;
+ int inactiveAlpha;
+ HMENU hMenuANSIEncoding;
+ int tabIconListUsageSize;
+ ImageListUsageEntry *tabIconListUsage;
+ TCmdList *draftList;
+ int smileyAddInstalled;
+ int popupInstalled;
+ int ieviewInstalled;
+ int buttonVisibility;
+ int chatBbuttonVisibility;
+ int limitTabsNum;
+ int limitChatsTabsNum;
+ int indentSize;
+ HIMAGELIST hTabIconList;
+ HIMAGELIST hButtonIconList;
+ HIMAGELIST hChatButtonIconList;
+ HIMAGELIST hHelperIconList;
+ HIMAGELIST hSearchEngineIconList;
+ HBRUSH hInfobarBrush;
+ int toolbarPosition;
+ HWND hFocusWnd;
+ DWORD logLineColour;
+ int logPixelSX;
+ int logPixelSY;
+ HICON hMsgIcon;
+ HICON hMsgIconBig;
+ HICON hIconChatBig;
+ int minInputAreaHeight;
+};
+
+int IconsChanged(WPARAM wParam, LPARAM lParam);
+int SmileySettingsChanged(WPARAM wParam, LPARAM lParam);
+void InitGlobals();
+void FreeGlobals();
+void ReloadGlobals();
+void RegisterIcons();
+void ReleaseIcons();
+void LoadGlobalIcons();
+HICON GetCachedIcon(const char *name);
+void RegisterFontServiceFonts();
+int ScriverRestoreWindowPosition(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix, int flags, int showCmd);
+
+int ImageList_AddIcon_Ex(HIMAGELIST hIml, int id);
+int ImageList_AddIcon_Ex2(HIMAGELIST hIml, HICON hIcon);
+int ImageList_ReplaceIcon_Ex(HIMAGELIST hIml, int nIndex, int id);
+int ImageList_AddIcon_ProtoEx(HIMAGELIST hIml, const char* szProto, int status);
+void ReleaseIconSmart(HICON hIcon);
+
+extern struct GlobalMessageData *g_dat;
+void StreamInTestEvents(HWND hEditWnd, struct GlobalMessageData *gdat);
+
+#endif
diff --git a/plugins/Scriver/src/infobar.cpp b/plugins/Scriver/src/infobar.cpp new file mode 100644 index 0000000000..a540606996 --- /dev/null +++ b/plugins/Scriver/src/infobar.cpp @@ -0,0 +1,293 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "infobar.h"
+#include "richutil.h"
+
+void SetupInfobar(InfobarWindowData* idat) {
+ HWND hwnd = idat->hWnd;
+ CHARFORMAT2 cf2;
+ memset(&cf2, 0, sizeof(cf2));
+ LOGFONT lf;
+ DWORD colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INFOBARBKGCOLOUR, SRMSGDEFSET_INFOBARBKGCOLOUR);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_NAME, EM_SETBKGNDCOLOR, 0, colour);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_STATUS, EM_SETBKGNDCOLOR, 0, colour);
+ LoadMsgDlgFont(MSGFONTID_INFOBAR_NAME, &lf, &colour, FALSE);
+ cf2.dwMask = CFM_COLOR | CFM_FACE | CFM_CHARSET | CFM_SIZE | CFM_WEIGHT | CFM_BOLD | CFM_ITALIC;
+ cf2.cbSize = sizeof(cf2);
+ cf2.crTextColor = colour;
+ cf2.bCharSet = lf.lfCharSet;
+ _tcsncpy(cf2.szFaceName, lf.lfFaceName, LF_FACESIZE);
+ cf2.dwEffects = ((lf.lfWeight >= FW_BOLD) ? CFE_BOLD : 0) | (lf.lfItalic ? CFE_ITALIC : 0);
+ cf2.wWeight = (WORD)lf.lfWeight;
+ cf2.bPitchAndFamily = lf.lfPitchAndFamily;
+ cf2.yHeight = abs(lf.lfHeight) * 1440 / g_dat->logPixelSY;
+ SendDlgItemMessageA(hwnd, IDC_INFOBAR_NAME, EM_SETCHARFORMAT, 0, (LPARAM)&cf2);
+
+ LoadMsgDlgFont(MSGFONTID_INFOBAR_STATUS, &lf, &colour, FALSE);
+ cf2.dwMask = CFM_COLOR | CFM_FACE | CFM_CHARSET | CFM_SIZE | CFM_WEIGHT | CFM_BOLD | CFM_ITALIC;
+ cf2.cbSize = sizeof(cf2);
+ cf2.crTextColor = colour;
+ cf2.bCharSet = lf.lfCharSet;
+ _tcsncpy(cf2.szFaceName, lf.lfFaceName, LF_FACESIZE);
+ cf2.dwEffects = ((lf.lfWeight >= FW_BOLD) ? CFE_BOLD : 0) | (lf.lfItalic ? CFE_ITALIC : 0);
+ cf2.wWeight = (WORD)lf.lfWeight;
+ cf2.bPitchAndFamily = lf.lfPitchAndFamily;
+ cf2.yHeight = abs(lf.lfHeight) * 1440 / g_dat->logPixelSY;
+ SendDlgItemMessageA(hwnd, IDC_INFOBAR_STATUS, EM_SETCHARFORMAT, 0, (LPARAM)&cf2);
+
+ RefreshInfobar(idat);
+}
+
+static HICON GetExtraStatusIcon(InfobarWindowData* idat) {
+ BYTE bXStatus = DBGetContactSettingByte(idat->mwd->windowData.hContact, idat->mwd->szProto, "XStatusId", 0);
+ if (bXStatus > 0) {
+ return (HICON) CallProtoService(idat->mwd->szProto, "/GetXStatusIcon", bXStatus, 0);
+ }
+ return NULL;
+}
+
+void RefreshInfobar(InfobarWindowData* idat) {
+ HWND hwnd = idat->hWnd;
+ struct SrmmWindowData *dat = idat->mwd;
+ TCHAR *szContactName = GetNickname(dat->windowData.hContact, dat->szProto);
+ TCHAR *szContactStatusMsg = DBGetStringT(dat->windowData.hContact, "CList", "StatusMsg");
+ TCHAR *szXStatusName = DBGetStringT(idat->mwd->windowData.hContact, idat->mwd->szProto, "XStatusName");
+ TCHAR *szXStatusMsg = DBGetStringT(idat->mwd->windowData.hContact, idat->mwd->szProto, "XStatusMsg");
+ HICON hIcon = GetExtraStatusIcon(idat);
+ TCHAR szText[2048];
+ SETTEXTEX st;
+ if ( szXStatusMsg && *szXStatusMsg )
+ mir_sntprintf(szText, 2047, _T("%s (%s)"), TranslateTS(szXStatusName), szXStatusMsg);
+ else
+ mir_sntprintf(szText, 2047, _T("%s"), TranslateTS(szXStatusName));
+ st.flags = ST_DEFAULT;
+ st.codepage = 1200;
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_NAME, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)szContactName);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_STATUS, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)szContactStatusMsg);
+ hIcon = (HICON)SendDlgItemMessage(hwnd, IDC_XSTATUSICON, STM_SETICON, (WPARAM)hIcon, 0);
+ if (hIcon) {
+ DestroyIcon(hIcon);
+ }
+ SetToolTipText(hwnd, idat->hXStatusTip, szText, NULL);
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ InvalidateRect(hwnd, NULL, TRUE);
+ //RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
+ RedrawWindow(GetDlgItem(hwnd, IDC_AVATAR), NULL, NULL, RDW_INVALIDATE);
+ mir_free(szContactStatusMsg);
+ mir_free(szContactName);
+ mir_free(szXStatusName);
+ mir_free(szXStatusMsg);
+}
+
+static LRESULT CALLBACK InfobarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL bWasCopy;
+ InfobarWindowData* idat = (InfobarWindowData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (!idat && msg!=WM_INITDIALOG) return FALSE;
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ RECT rect = {0};
+ bWasCopy = FALSE;
+ idat = (InfobarWindowData *) lParam;
+ idat->hWnd = hwnd;
+ idat->hXStatusTip = CreateToolTip(hwnd, NULL, NULL, &rect);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)idat);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_NAME, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_NAME, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_KEYEVENTS);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_STATUS, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwnd, IDC_INFOBAR_STATUS, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_KEYEVENTS);
+ SetupInfobar(idat);
+ }
+ return TRUE;
+
+ case WM_SIZE:
+ {
+ if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED) {
+ HDWP hdwp;
+ RECT rc;
+ int dlgWidth, dlgHeight;
+ int avatarWidth = 0;
+ int avatarHeight = 0;
+ GetClientRect(hwnd, &rc);
+ dlgWidth = rc.right - rc.left;
+ dlgHeight = rc.bottom - rc.top;
+ if (idat->mwd->avatarPic && (g_dat->flags&SMF_AVATAR)) {
+ BITMAP bminfo;
+ GetObject(idat->mwd->avatarPic, sizeof(bminfo), &bminfo);
+ if ( bminfo.bmWidth != 0 && bminfo.bmHeight != 0 ) {
+ avatarHeight = dlgHeight - 2;
+ avatarWidth = bminfo.bmWidth * avatarHeight / bminfo.bmHeight;
+ if (avatarWidth > dlgHeight) {
+ avatarWidth = dlgHeight - 2;
+ avatarHeight = bminfo.bmHeight * avatarWidth / bminfo.bmWidth;
+ }
+ }
+ }
+ hdwp = BeginDeferWindowPos(4);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_INFOBAR_NAME), 0, 16, 0, dlgWidth - avatarWidth - 2 - 32, dlgHeight/2, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_INFOBAR_STATUS), 0, 16, dlgHeight/2, dlgWidth - avatarWidth - 2 - 32, dlgHeight/2, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_AVATAR), 0, dlgWidth - avatarWidth - 2, (dlgHeight - avatarHeight) / 2, avatarWidth, (dlgHeight + avatarHeight - 2) / 2, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_XSTATUSICON), 0, dlgWidth - avatarWidth - 2 - 16, dlgHeight/4 - 8, 16, 16, SWP_NOZORDER);
+ rc.left = dlgWidth - avatarWidth - 2 - 16;
+ rc.top = dlgHeight/4 - 8;
+ rc.bottom = rc.top + 20;
+ rc.right = rc.left + 16;
+ SetToolTipRect(hwnd, idat->hXStatusTip, &rc);
+ EndDeferWindowPos(hdwp);
+ }
+ return TRUE;
+ }
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORSTATIC:
+ return (INT_PTR)g_dat->hInfobarBrush;
+
+ case WM_DROPFILES:
+ SendMessage(GetParent(hwnd), WM_DROPFILES, wParam, lParam);
+ return FALSE;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR pNmhdr = (LPNMHDR)lParam;
+ switch (pNmhdr->idFrom) {
+ case IDC_INFOBAR_NAME:
+ case IDC_INFOBAR_STATUS:
+ switch (pNmhdr->code) {
+ case EN_MSGFILTER:
+ switch (((MSGFILTER *) lParam)->msg) {
+ case WM_CHAR:
+ SendMessage(GetParent(hwnd), ((MSGFILTER *) lParam)->msg, ((MSGFILTER *) lParam)->wParam, ((MSGFILTER *) lParam)->lParam);
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ case WM_LBUTTONUP:
+ {
+ CHARRANGE sel;
+ SendDlgItemMessage(hwnd, pNmhdr->idFrom, EM_EXGETSEL, 0, (LPARAM) &sel);
+ bWasCopy = FALSE;
+ if (sel.cpMin != sel.cpMax) {
+ SendDlgItemMessage(hwnd, pNmhdr->idFrom, WM_COPY, 0, 0);
+ sel.cpMin = sel.cpMax ;
+ SendDlgItemMessage(hwnd, pNmhdr->idFrom, EM_EXSETSEL, 0, (LPARAM) & sel);
+ bWasCopy = TRUE;
+ }
+ SetFocus(GetParent(hwnd));
+ }
+ }
+ break;
+ case EN_LINK:
+ switch (((ENLINK *) lParam)->msg) {
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ if (!bWasCopy) {
+ if (HandleLinkClick(g_hInst, hwnd, GetDlgItem(GetParent(hwnd), IDC_MESSAGE),(ENLINK*)lParam)) {
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ }
+ bWasCopy = FALSE;
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+ if (dis->hwndItem == GetDlgItem(hwnd, IDC_AVATAR)) {
+ RECT rect;
+ HDC hdcMem = CreateCompatibleDC(dis->hDC);
+ int itemWidth = dis->rcItem.right - dis->rcItem.left + 1;
+ int itemHeight = dis->rcItem.bottom - dis->rcItem.top + 1;
+ HBITMAP hbmMem = CreateCompatibleBitmap(dis->hDC, itemWidth, itemHeight);
+ hbmMem = (HBITMAP) SelectObject(hdcMem, hbmMem);
+ rect.top = 0;
+ rect.left = 0;
+ rect.right = itemWidth - 1;
+ rect.bottom = itemHeight - 1;
+ FillRect(hdcMem, &rect, g_dat->hInfobarBrush);
+ if (idat->mwd->avatarPic && (g_dat->flags&SMF_AVATAR)) {
+ BITMAP bminfo;
+ GetObject(idat->mwd->avatarPic, sizeof(bminfo), &bminfo);
+ if ( bminfo.bmWidth != 0 && bminfo.bmHeight != 0 ) {
+ AVATARDRAWREQUEST adr;
+ int avatarHeight = itemHeight;
+ int avatarWidth = bminfo.bmWidth * avatarHeight / bminfo.bmHeight;
+ if (avatarWidth > itemWidth) {
+ avatarWidth = itemWidth;
+ avatarHeight = bminfo.bmHeight * avatarWidth / bminfo.bmWidth;
+ }
+ ZeroMemory(&adr, sizeof(adr));
+ adr.cbSize = sizeof (AVATARDRAWREQUEST);
+ adr.hContact = idat->mwd->windowData.hContact;
+ adr.hTargetDC = hdcMem;
+ adr.rcDraw.left = 0;
+ adr.rcDraw.top = 0;
+ adr.rcDraw.right = avatarWidth - 1;
+ adr.rcDraw.bottom = avatarHeight - 1;
+ adr.dwFlags = AVDRQ_DRAWBORDER | AVDRQ_HIDEBORDERONTRANSPARENCY;
+ CallService(MS_AV_DRAWAVATAR, (WPARAM)0, (LPARAM)&adr);
+ }
+ }
+ BitBlt(dis->hDC, 0, 0, itemWidth, itemHeight, hdcMem, 0, 0, SRCCOPY);
+ hbmMem = (HBITMAP) SelectObject(hdcMem, hbmMem);
+ DeleteObject(hbmMem);
+ DeleteDC(hdcMem);
+ return TRUE;
+ }
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ }
+ case WM_LBUTTONDOWN:
+ SendMessage(idat->mwd->hwnd, WM_LBUTTONDOWN, wParam, lParam);
+ return TRUE;
+ case WM_RBUTTONUP:
+ {
+ POINT pt;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) idat->mwd->windowData.hContact, 0);
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, GetParent(hwnd), NULL);
+ DestroyMenu(hMenu);
+ }
+ break;
+ case WM_DESTROY:
+ if (idat->hXStatusTip != NULL) {
+ DestroyWindow(idat->hXStatusTip);
+ idat->hXStatusTip = NULL;
+ }
+ mir_free(idat);
+ }
+ return FALSE;
+}
+
+InfobarWindowData *CreateInfobar(HWND hParent, struct SrmmWindowData *dat)
+{
+ InfobarWindowData *idat = (InfobarWindowData *) mir_alloc(sizeof(InfobarWindowData));
+ idat->mwd = dat;
+ idat->hWnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_INFOBAR), hParent, (DLGPROC)InfobarWndProc, (LPARAM)idat);
+ RichUtil_SubClass(idat->hWnd);
+ SetWindowPos(idat->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOREPOSITION);
+ return idat;
+}
diff --git a/plugins/Scriver/src/infobar.h b/plugins/Scriver/src/infobar.h new file mode 100644 index 0000000000..42580093f0 --- /dev/null +++ b/plugins/Scriver/src/infobar.h @@ -0,0 +1,37 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef INFOBAR_H
+#define INFOBAR_H
+
+typedef struct InfobarWindowDataStruct
+{
+ struct SrmmWindowData *mwd;
+ HWND hWnd;
+ HWND hXStatusTip;
+} InfobarWindowData;
+
+InfobarWindowData *CreateInfobar(HWND hParent, struct SrmmWindowData *dat);
+void SetupInfobar(InfobarWindowData* idat);
+void RefreshInfobar(InfobarWindowData* idat);
+
+#endif
diff --git a/plugins/Scriver/src/input.cpp b/plugins/Scriver/src/input.cpp new file mode 100644 index 0000000000..79dce58fdc --- /dev/null +++ b/plugins/Scriver/src/input.cpp @@ -0,0 +1,442 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+
+extern HANDLE hHookWinPopup;
+
+enum KB_ACTIONS {KB_PREV_TAB = 1, KB_NEXT_TAB, KB_SWITCHTOOLBAR,
+ KB_SWITCHSTATUSBAR, KB_SWITCHTITLEBAR, KB_SWITCHINFOBAR, KB_MINIMIZE, KB_CLOSE, KB_CLEAR_LOG,
+ KB_TAB1, KB_TAB2, KB_TAB3, KB_TAB4, KB_TAB5, KB_TAB6, KB_TAB7, KB_TAB8, KB_TAB9, KB_SEND_ALL, KB_PASTESEND, KB_QUOTE};
+
+void InputAreaContextMenu(HWND hwnd, WPARAM wParam, LPARAM lParam, HANDLE hContact) {
+
+ HMENU hMenu, hSubMenu;
+ POINT pt;
+ CHARRANGE sel, all = { 0, -1 };
+ MessageWindowPopupData mwpd;
+ int selection;
+
+ hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ hSubMenu = GetSubMenu(hMenu, 2);
+ TranslateMenu(hSubMenu);
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) & sel);
+ if (sel.cpMin == sel.cpMax) {
+ EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(hSubMenu, IDM_DELETE, MF_BYCOMMAND | MF_GRAYED);
+ }
+ if (!SendMessage(hwnd, EM_CANUNDO, 0, 0)) {
+ EnableMenuItem(hSubMenu, IDM_UNDO, MF_BYCOMMAND | MF_GRAYED);
+ }
+ if (!SendMessage(hwnd, EM_CANREDO, 0, 0)) {
+ EnableMenuItem(hSubMenu, IDM_REDO, MF_BYCOMMAND | MF_GRAYED);
+ }
+ if (!SendMessage(hwnd, EM_CANPASTE, 0, 0)) {
+ EnableMenuItem(hSubMenu, IDM_PASTESEND, MF_BYCOMMAND | MF_GRAYED);
+ if (!IsClipboardFormatAvailable(CF_HDROP))
+ EnableMenuItem(hSubMenu, IDM_PASTE, MF_BYCOMMAND | MF_GRAYED);
+ }
+ if (lParam == 0xFFFFFFFF) {
+ SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM) & pt, (LPARAM) sel.cpMax);
+ ClientToScreen(hwnd, &pt);
+ }
+ else {
+ pt.x = (short) LOWORD(lParam);
+ pt.y = (short) HIWORD(lParam);
+ }
+
+ // First notification
+ mwpd.cbSize = sizeof(mwpd);
+ mwpd.uType = MSG_WINDOWPOPUP_SHOWING;
+ mwpd.uFlags = MSG_WINDOWPOPUP_INPUT;
+ mwpd.hContact = hContact;
+ mwpd.hwnd = hwnd;
+ mwpd.hMenu = hSubMenu;
+ mwpd.selection = 0;
+ mwpd.pt = pt;
+ NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd);
+
+ selection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, GetParent(hwnd), NULL);
+
+ // Second notification
+ mwpd.selection = selection;
+ mwpd.uType = MSG_WINDOWPOPUP_SELECTED;
+ NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd);
+
+ switch (selection) {
+ case IDM_UNDO:
+ SendMessage(hwnd, WM_UNDO, 0, 0);
+ break;
+ case IDM_REDO:
+ SendMessage(hwnd, EM_REDO, 0, 0);
+ break;
+ case IDM_CUT:
+ SendMessage(hwnd, WM_CUT, 0, 0);
+ break;
+ case IDM_COPY:
+ SendMessage(hwnd, WM_COPY, 0, 0);
+ break;
+ case IDM_PASTE:
+ SendMessage(hwnd, WM_PASTE, 0, 0);
+ break;
+ case IDM_PASTESEND:
+ SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0);
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ break;
+ case IDM_DELETE:
+ SendMessage(hwnd, EM_REPLACESEL, TRUE, 0);
+ break;
+ case IDM_SELECTALL:
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & all);
+ break;
+ case IDM_CLEAR:
+ SetWindowText(hwnd, _T( "" ));
+ break;
+ }
+ DestroyMenu(hMenu);
+ //PostMessage(hwnd, WM_KEYUP, 0, 0 );
+}
+
+int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CommonWindowData *windowData) {
+
+ BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000;
+ BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
+ BOOL isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) && !isAlt;
+
+ int action;
+ MSG amsg;
+ amsg.hwnd = hwnd;
+ amsg.message = msg;
+ amsg.wParam = wParam;
+ amsg.lParam = lParam;
+ switch (action = CallService(MS_HOTKEY_CHECK, (WPARAM)&amsg, (LPARAM)"Messaging"))
+ {
+ case KB_PREV_TAB:
+ SendMessage(GetParent(GetParent(hwnd)), CM_ACTIVATEPREV, 0, (LPARAM)GetParent(hwnd));
+ return FALSE;
+ case KB_NEXT_TAB:
+ SendMessage(GetParent(GetParent(hwnd)), CM_ACTIVATENEXT, 0, (LPARAM)GetParent(hwnd));
+ return FALSE;
+ case KB_SWITCHSTATUSBAR:
+ SendMessage(GetParent(GetParent(hwnd)), DM_SWITCHSTATUSBAR, 0, 0);
+ return FALSE;
+ case KB_SWITCHTITLEBAR:
+ SendMessage(GetParent(GetParent(hwnd)), DM_SWITCHTITLEBAR, 0, 0);
+ return FALSE;
+ case KB_SWITCHINFOBAR:
+ SendMessage(GetParent(GetParent(hwnd)), DM_SWITCHINFOBAR, 0, 0);
+ return FALSE;
+ case KB_SWITCHTOOLBAR:
+ SendMessage(GetParent(GetParent(hwnd)), DM_SWITCHTOOLBAR, 0, 0);
+ return FALSE;
+ case KB_MINIMIZE:
+ ShowWindow(GetParent(GetParent(hwnd)), SW_MINIMIZE);
+ return FALSE;
+ case KB_CLOSE:
+ SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0);
+ return FALSE;
+ case KB_CLEAR_LOG:
+ SendMessage(GetParent(hwnd), DM_CLEARLOG, 0, 0);
+ return FALSE;
+ case KB_TAB1:
+ case KB_TAB2:
+ case KB_TAB3:
+ case KB_TAB4:
+ case KB_TAB5:
+ case KB_TAB6:
+ case KB_TAB7:
+ case KB_TAB8:
+ case KB_TAB9:
+ SendMessage(GetParent(GetParent(hwnd)), CM_ACTIVATEBYINDEX, 0, action - KB_TAB1);
+ return FALSE;
+ case KB_SEND_ALL:
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDC_SENDALL, 0);
+ return FALSE;
+ case KB_QUOTE:
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDC_QUOTE, 0);
+ return FALSE;
+ case KB_PASTESEND:
+ if (SendMessage(hwnd, EM_CANPASTE, 0, 0)) {
+ SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0);
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ }
+ return FALSE;
+ }
+
+ switch (msg) {
+ case WM_KEYDOWN:
+ {
+ if (wParam >= '1' && wParam <='9' && isCtrl) {
+ SendMessage(GetParent(GetParent(hwnd)), CM_ACTIVATEBYINDEX, 0, wParam - '1');
+ return 0;
+ }
+ /*
+ if (wParam == 'A' && isCtrl) { //ctrl-a; select all
+ SendMessage(hwnd, EM_SETSEL, 0, -1);
+ return FALSE;
+ }
+ */
+ if (wParam == 'I' && isCtrl) { // ctrl-i (italics)
+ return FALSE;
+ }
+ if (wParam == VK_SPACE && isCtrl) // ctrl-space (paste clean text)
+ return FALSE;
+ if (wParam == 'R' && isCtrl && isShift) { // ctrl-shift-r
+ SendMessage(GetParent(hwnd), DM_SWITCHRTL, 0, 0);
+ return FALSE;
+ }
+ if ((wParam == VK_UP || wParam == VK_DOWN) && isCtrl && !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE)) {
+ if (windowData->cmdList) {
+ TCmdList *cmdListNew = NULL;
+ if (wParam == VK_UP) {
+ if (windowData->cmdListCurrent == NULL) {
+ cmdListNew = tcmdlist_last(windowData->cmdList);
+ while (cmdListNew != NULL && cmdListNew->temporary) {
+ windowData->cmdList = tcmdlist_remove(windowData->cmdList, cmdListNew);
+ cmdListNew = tcmdlist_last(windowData->cmdList);
+ }
+ if (cmdListNew != NULL) {
+ char *textBuffer;
+ if (windowData->flags & CWDF_RTF_INPUT) {
+ textBuffer = GetRichTextRTF(hwnd);
+ } else {
+ textBuffer = GetRichTextEncoded(hwnd, windowData->codePage);
+ }
+ if (textBuffer != NULL) {
+ windowData->cmdList = tcmdlist_append(windowData->cmdList, textBuffer, 20, TRUE);
+ mir_free(textBuffer);
+ }
+ }
+ } else if (windowData->cmdListCurrent->prev != NULL) {
+ cmdListNew = windowData->cmdListCurrent->prev;
+ }
+ } else {
+ if (windowData->cmdListCurrent != NULL) {
+ if (windowData->cmdListCurrent->next != NULL) {
+ cmdListNew = windowData->cmdListCurrent->next;
+ } else if (!windowData->cmdListCurrent->temporary) {
+ SetWindowText(hwnd, _T(""));
+ }
+ }
+ }
+ if (cmdListNew != NULL) {
+ int iLen;
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
+ if (windowData->flags & CWDF_RTF_INPUT) {
+ iLen = SetRichTextRTF(hwnd, cmdListNew->szCmd);
+ } else {
+ iLen = SetRichTextEncoded(hwnd, cmdListNew->szCmd, windowData->codePage);
+ }
+ SendMessage(hwnd, EM_SCROLLCARET, 0,0);
+ SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
+ SendMessage(hwnd, EM_SETSEL, iLen, iLen);
+ windowData->cmdListCurrent = cmdListNew;
+ }
+ }
+ return FALSE;
+ }
+ }
+ break;
+ case WM_SYSKEYDOWN:
+ {
+ if ((wParam == VK_LEFT) && isAlt) {
+ SendMessage(GetParent(GetParent(hwnd)), CM_ACTIVATEPREV, 0, (LPARAM)GetParent(hwnd));
+ return 0;
+ }
+ if ((wParam == VK_RIGHT) && isAlt) {
+ SendMessage(GetParent(GetParent(hwnd)), CM_ACTIVATENEXT, 0, (LPARAM)GetParent(hwnd));
+ return 0;
+ }
+ }
+ break;
+ case WM_SYSKEYUP:
+ {
+ if ((wParam == VK_LEFT) && isAlt) {
+ return 0;
+ }
+ if ((wParam == VK_RIGHT) && isAlt) {
+ return 0;
+ }
+ }
+ break;
+
+ }
+
+ return -1;
+
+}
+
+void RegisterKeyBindings() {
+ int i;
+ char strDesc[64], strName[64];
+ HOTKEYDESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.cbSize = sizeof(desc);
+ desc.pszSection = "Messaging";
+ desc.pszName = "Scriver/Nav/Previous Tab";
+ desc.pszDescription = "Navigate: Previous Tab";
+ desc.lParam = KB_PREV_TAB;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_TAB);
+ Hotkey_Register( &desc);
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, VK_PRIOR);
+ Hotkey_Register( &desc);
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_ALT, VK_LEFT);
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Nav/Next Tab";
+ desc.pszDescription = "Navigate: Next Tab";
+ desc.lParam = KB_NEXT_TAB;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, VK_TAB);
+ Hotkey_Register( &desc);
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, VK_NEXT);
+ Hotkey_Register( &desc);
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_ALT, VK_RIGHT);
+ Hotkey_Register( &desc);
+ desc.pszName = strName;
+ desc.pszDescription = strDesc;
+ for (i = 0; i < 9; i++) {
+ mir_snprintf(strName, SIZEOF(strName), "Scriver/Nav/Tab %d", i + 1);
+ mir_snprintf(strDesc, SIZEOF(strDesc), "Navigate: Tab %d", i + 1);
+ desc.lParam = KB_TAB1 + i;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, '1' + i);
+ Hotkey_Register( &desc);
+ }
+
+ desc.pszName = "Scriver/Wnd/Toggle Statusbar";
+ desc.pszDescription = "Window: Toggle Statusbar";
+ desc.lParam = KB_SWITCHSTATUSBAR;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'S');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Wnd/Toggle Titlebar";
+ desc.pszDescription = "Window: Toggle Titlebar";
+ desc.lParam = KB_SWITCHTITLEBAR;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'M');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Wnd/Toggle Toolbar";
+ desc.pszDescription = "Window: Toggle Toolbar";
+ desc.lParam = KB_SWITCHTOOLBAR;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'T');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Wnd/Toggle Infobar";
+ desc.pszDescription = "Window: Toggle Infobar";
+ desc.lParam = KB_SWITCHINFOBAR;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'N');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Wnd/Clear Log";
+ desc.pszDescription = "Window: Clear Log";
+ desc.lParam = KB_CLEAR_LOG;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, 'L');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Wnd/Minimize";
+ desc.pszDescription = "Window: Minimize";
+ desc.lParam = KB_MINIMIZE;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_SHIFT, VK_ESCAPE);
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Wnd/Close Tab";
+ desc.pszDescription = "Window: Close Tab";
+ desc.lParam = KB_CLOSE;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, VK_F4);
+ Hotkey_Register( &desc);
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, 'W');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Action/Quote";
+ desc.pszDescription = "Action: Quote";
+ desc.lParam = KB_QUOTE;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, 'Q');
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Action/Send All";
+ desc.pszDescription = "Action: Send to All";
+ desc.lParam = KB_SEND_ALL;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL | HOTKEYF_SHIFT, VK_RETURN);
+ Hotkey_Register( &desc);
+
+ desc.pszName = "Scriver/Action/PasteSend";
+ desc.pszDescription = "Action: Paste & Send";
+ desc.lParam = KB_PASTESEND;
+ desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL | HOTKEYF_SHIFT, VK_INSERT);
+ Hotkey_Register( &desc);
+}
+
+BOOL HandleLinkClick(HINSTANCE hInstance, HWND hwndDlg, HWND hwndFocus, ENLINK *lParam) {
+ TEXTRANGE tr;
+ CHARRANGE sel;
+ char* pszUrl;
+ BOOL bOpenLink = TRUE;
+ SendMessage(lParam->nmhdr.hwndFrom, EM_EXGETSEL, 0, (LPARAM) & sel);
+ if (sel.cpMin != sel.cpMax)
+ return FALSE;
+ tr.chrg = lParam->chrg;
+ tr.lpstrText = (LPWSTR)mir_alloc(sizeof(TCHAR)*(tr.chrg.cpMax - tr.chrg.cpMin + 8));
+ SendMessage(lParam->nmhdr.hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM) & tr);
+ if (_tcschr(tr.lpstrText, _T('@')) != NULL && _tcschr(tr.lpstrText, _T(':')) == NULL && _tcschr(tr.lpstrText, _T('/')) == NULL) {
+ MoveMemory(tr.lpstrText + sizeof(TCHAR) * 7, tr.lpstrText, sizeof(TCHAR)*(tr.chrg.cpMax - tr.chrg.cpMin + 1));
+ CopyMemory(tr.lpstrText, _T("mailto:"), sizeof(TCHAR) * 7);
+ }
+ pszUrl = t2a( (const TCHAR *)tr.lpstrText );
+ if (((ENLINK *) lParam)->msg == WM_RBUTTONDOWN) {
+ HMENU hMenu, hSubMenu;
+ POINT pt;
+ bOpenLink = FALSE;
+ hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXT));
+ hSubMenu = GetSubMenu(hMenu, 1);
+ TranslateMenu(hSubMenu);
+ pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam);
+ pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam);
+ ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt);
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) {
+ case IDM_OPENLINK:
+ bOpenLink = TRUE;
+ break;
+ case IDM_COPYLINK:
+ {
+ HGLOBAL hData;
+ if (!OpenClipboard(hwndDlg))
+ break;
+ EmptyClipboard();
+ hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(TCHAR)*(lstrlen(tr.lpstrText) + 1));
+ lstrcpy((LPWSTR)GlobalLock(hData), tr.lpstrText);
+ GlobalUnlock(hData);
+ SetClipboardData(CF_UNICODETEXT, hData);
+ CloseClipboard();
+ break;
+ }
+ }
+ DestroyMenu(hMenu);
+ }
+ if (bOpenLink) {
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) pszUrl);
+ }
+ SetFocus(hwndFocus);
+ mir_free(tr.lpstrText);
+ mir_free(pszUrl);
+ return TRUE;
+}
diff --git a/plugins/Scriver/src/input.h b/plugins/Scriver/src/input.h new file mode 100644 index 0000000000..5cff9ba89d --- /dev/null +++ b/plugins/Scriver/src/input.h @@ -0,0 +1,31 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef INPUT_H
+#define INPUT_H
+
+extern void InputAreaContextMenu(HWND hwnd, WPARAM wParam, LPARAM lParam, HANDLE hContact);
+extern void RegisterKeyBindings();
+extern int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CommonWindowData *windowData);
+BOOL HandleLinkClick(HINSTANCE hInstance, HWND hwndDlg, HWND hwndFocus, ENLINK *lParam);
+
+#endif
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp new file mode 100644 index 0000000000..a5bb8d92dd --- /dev/null +++ b/plugins/Scriver/src/msgdialog.cpp @@ -0,0 +1,2107 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "statusicon.h"
+#include "infobar.h"
+
+#define TIMERID_MSGSEND 0
+#define TIMERID_FLASHWND 1
+#define TIMERID_TYPE 2
+#define TIMERID_UNREAD 3
+#define TIMEOUT_TYPEOFF 10000 //send type off after 10 seconds of inactivity
+#define TIMEOUT_UNREAD 800 //multiple-send bombproofing: send max 3 messages every 4 seconds
+#define VALID_AVATAR(x) (x==PA_FORMAT_PNG||x==PA_FORMAT_JPEG||x==PA_FORMAT_ICON||x==PA_FORMAT_BMP||x==PA_FORMAT_GIF)
+
+#define ENTERCLICKTIME 1000 //max time in ms during which a double-tap on enter will cause a send
+
+extern HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand, hDragCursor;
+extern HANDLE hHookWinEvt;
+extern HANDLE hHookWinPopup;
+extern CREOleCallback reOleCallback, reOleCallback2;
+
+static void UpdateReadChars(HWND hwndDlg, struct SrmmWindowData * dat);
+
+static WNDPROC OldMessageEditProc, OldLogEditProc;
+static ToolbarButton toolbarButtons[] = {
+ {_T("Quote"), IDC_QUOTE, 0, 4, 24},
+ {_T("Smiley"), IDC_SMILEYS, 0, 10, 24},
+ {_T("Add Contact"), IDC_ADD, 0, 10, 24},
+ {_T("User Menu"), IDC_USERMENU, 1, 0, 24},
+ {_T("User Details"), IDC_DETAILS, 1, 0, 24},
+ {_T("History"), IDC_HISTORY, 1, 0, 24},
+ {_T("Send"), IDOK, 1, 0, 38}
+};
+
+static DWORD CALLBACK StreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+{
+ MessageSendQueueItem * msi = (MessageSendQueueItem *) dwCookie;
+ msi->sendBuffer = (char *)mir_realloc(msi->sendBuffer, msi->sendBufferSize + cb + 2);
+ memcpy (msi->sendBuffer + msi->sendBufferSize, pbBuff, cb);
+ msi->sendBufferSize += cb;
+ *((TCHAR *)(msi->sendBuffer+msi->sendBufferSize)) = '\0';
+ *pcb = cb;
+ return 0;
+}
+
+static TCHAR *GetIEViewSelection(struct SrmmWindowData *dat) {
+ IEVIEWEVENT event;
+ ZeroMemory(&event, sizeof(event));
+ event.cbSize = sizeof(event);
+ event.dwFlags = 0;
+ event.codepage = dat->windowData.codePage;
+ event.hwnd = dat->windowData.hwndLog;
+ event.hContact = dat->windowData.hContact;
+ event.iType = IEE_GET_SELECTION;
+ return mir_tstrdup((TCHAR *)CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event));
+}
+
+static TCHAR *GetQuotedTextW(TCHAR * text) {
+ int i, j, l, newLine, wasCR;
+ TCHAR *out;
+ l = (int)wcslen(text);
+ newLine = 1;
+ wasCR = 0;
+ for (i=j=0; i<l; i++) {
+ if (text[i]=='\r') {
+ wasCR = 1;
+ newLine = 1;
+ j += text[i+1]!='\n' ? 2 : 1;
+ } else if (text[i]=='\n') {
+ newLine = 1;
+ j += wasCR ? 1 : 2;
+ wasCR = 0;
+ } else {
+ j++;
+ if (newLine) {
+ //for (;i<l && text[i]=='>';i++) j--;
+ j+=2;
+ }
+ newLine = 0;
+ wasCR = 0;
+ }
+ }
+ j+=3;
+ out = (TCHAR *)mir_alloc(sizeof(TCHAR) * j);
+ newLine = 1;
+ wasCR = 0;
+ for (i=j=0; i<l; i++) {
+ if (text[i]=='\r') {
+ wasCR = 1;
+ newLine = 1;
+ out[j++] = '\r';
+ if (text[i+1]!='\n') {
+ out[j++]='\n';
+ }
+ } else if (text[i]=='\n') {
+ newLine = 1;
+ if (!wasCR) {
+ out[j++]='\r';
+ }
+ out[j++]='\n';
+ wasCR = 0;
+ } else {
+ if (newLine) {
+ out[j++]='>';
+ out[j++]=' ';
+ //for (;i<l && text[i]=='>';i++) j--;
+ }
+ newLine = 0;
+ wasCR = 0;
+ out[j++]=text[i];
+ }
+ }
+ out[j++]='\r';
+ out[j++]='\n';
+ out[j++]='\0';
+ return out;
+}
+
+static void saveDraftMessage(HWND hwnd, HANDLE hContact, int codepage) {
+ char *textBuffer = GetRichTextEncoded(hwnd, codepage);
+ if (textBuffer != NULL) {
+ g_dat->draftList = tcmdlist_append2(g_dat->draftList, hContact, textBuffer);
+ mir_free(textBuffer);
+ } else {
+ g_dat->draftList = tcmdlist_remove2(g_dat->draftList, hContact);
+ }
+}
+
+void NotifyLocalWinEvent(HANDLE hContact, HWND hwnd, unsigned int type) {
+ MessageWindowEventData mwe = { 0 };
+ BOOL bChat = FALSE;
+ if (hContact==NULL || hwnd==NULL) return;
+ mwe.cbSize = sizeof(mwe);
+ mwe.hContact = hContact;
+ mwe.hwndWindow = hwnd;
+ mwe.szModule = SRMMMOD;
+ mwe.uType = type;
+ mwe.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+ bChat = (WindowList_Find(g_dat->hMessageWindowList, hContact) == NULL);
+ mwe.hwndInput = GetDlgItem(hwnd, bChat ? IDC_CHAT_MESSAGE : IDC_MESSAGE);
+ mwe.hwndLog = GetDlgItem(hwnd, bChat ? IDC_CHAT_LOG : IDC_LOG);
+ NotifyEventHooks(hHookWinEvt, 0, (LPARAM)&mwe);
+}
+
+static BOOL IsUtfSendAvailable(HANDLE hContact)
+{
+ char* szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if ( szProto == NULL )
+ return FALSE;
+
+ return ( CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDUTF ) ? TRUE : FALSE;
+}
+
+int RTL_Detect(WCHAR *pszwText)
+{
+ WORD *infoTypeC2;
+ int i;
+ int iLen = lstrlenW(pszwText);
+
+ infoTypeC2 = (WORD *)mir_alloc(sizeof(WORD) * (iLen + 2));
+
+ if (infoTypeC2) {
+ ZeroMemory(infoTypeC2, sizeof(WORD) * (iLen + 2));
+
+ GetStringTypeW(CT_CTYPE2, pszwText, iLen, infoTypeC2);
+
+ for(i = 0; i < iLen; i++) {
+ if (infoTypeC2[i] == C2_RIGHTTOLEFT) {
+ mir_free(infoTypeC2);
+ return 1;
+ }
+ }
+ mir_free(infoTypeC2);
+ }
+ return 0;
+}
+
+static void AddToFileList(TCHAR ***pppFiles,int *totalCount,const TCHAR* szFilename)
+{
+ *pppFiles=(TCHAR**)mir_realloc(*pppFiles,(++*totalCount+1)*sizeof(TCHAR*));
+ (*pppFiles)[*totalCount] = NULL;
+ (*pppFiles)[*totalCount-1] = mir_tstrdup( szFilename );
+
+ if ( GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY ) {
+ WIN32_FIND_DATA fd;
+ HANDLE hFind;
+ TCHAR szPath[MAX_PATH];
+ lstrcpy(szPath,szFilename);
+ lstrcat(szPath,_T("\\*"));
+ if (( hFind = FindFirstFile( szPath, &fd )) != INVALID_HANDLE_VALUE ) {
+ do {
+ if ( !lstrcmp(fd.cFileName,_T(".")) || !lstrcmp(fd.cFileName,_T(".."))) continue;
+ lstrcpy(szPath,szFilename);
+ lstrcat(szPath,_T("\\"));
+ lstrcat(szPath,fd.cFileName);
+ AddToFileList(pppFiles,totalCount,szPath);
+ }
+ while( FindNextFile( hFind,&fd ));
+ FindClose( hFind );
+} } }
+
+static void SetDialogToType(HWND hwndDlg)
+{
+ BOOL showToolbar = SendMessage(GetParent(hwndDlg), CM_GETTOOLBARSTATUS, 0, 0);
+ struct SrmmWindowData *dat = (struct SrmmWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ ParentWindowData *pdat = dat->parent;
+
+ if (pdat->flags2 & SMF2_SHOWINFOBAR) {
+ ShowWindow(dat->infobarData->hWnd, SW_SHOW);
+ } else {
+ ShowWindow(dat->infobarData->hWnd, SW_HIDE);
+ }
+ if (dat->windowData.hContact) {
+ ShowToolbarControls(hwndDlg, SIZEOF(toolbarButtons), toolbarButtons, g_dat->buttonVisibility, showToolbar ? SW_SHOW : SW_HIDE);
+ if (!DBGetContactSettingByte(dat->windowData.hContact, "CList", "NotOnList", 0)) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE);
+ }
+ if (!g_dat->smileyAddInstalled) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SMILEYS), SW_HIDE);
+ }
+ } else {
+ ShowToolbarControls(hwndDlg, SIZEOF(toolbarButtons), toolbarButtons, g_dat->buttonVisibility, SW_HIDE);
+ }
+ ShowWindow(GetDlgItem(hwndDlg, IDC_MESSAGE), SW_SHOW);
+ if (dat->windowData.hwndLog != NULL) {
+ ShowWindow (GetDlgItem(hwndDlg, IDC_LOG), SW_HIDE);
+ } else {
+ ShowWindow (GetDlgItem(hwndDlg, IDC_LOG), SW_SHOW);
+ }
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SPLITTER), SW_SHOW);
+ UpdateReadChars(hwndDlg, dat);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), GetRichTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE), dat->windowData.codePage, FALSE)?TRUE:FALSE);
+ SendMessage(hwndDlg, DM_CLISTSETTINGSCHANGED, 0, 0);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+}
+
+
+void SetStatusIcon(struct SrmmWindowData *dat) {
+ if (dat->szProto != NULL) {
+ char *szProto = dat->szProto;
+ HANDLE hContact = dat->windowData.hContact;
+
+ char* szMetaProto = (char*)CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
+ if ((INT_PTR)szMetaProto != CALLSERVICE_NOTFOUND && strcmp(dat->szProto, szMetaProto) == 0 &&
+ DBGetContactSettingByte(NULL,"CLC","Meta",0) == 0) {
+ hContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)dat->windowData.hContact, 0);
+ if (hContact != NULL) {
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+ } else {
+ hContact = dat->windowData.hContact;
+ }
+ }
+
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)dat->statusIcon, 0);
+ dat->statusIcon = LoadSkinnedProtoIcon(szProto, dat->wStatus);
+
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)dat->statusIconBig, 0);
+ dat->statusIconBig = LoadSkinnedProtoIconBig(szProto, dat->wStatus);
+ if ((int)dat->statusIconBig == CALLSERVICE_NOTFOUND) {
+ dat->statusIconBig = NULL;
+ }
+ if (dat->statusIconOverlay != NULL) DestroyIcon(dat->statusIconOverlay);
+ {
+ int index = ImageList_ReplaceIcon(g_dat->hHelperIconList, 0, dat->statusIcon);
+ dat->statusIconOverlay = ImageList_GetIcon(g_dat->hHelperIconList, index, ILD_TRANSPARENT|INDEXTOOVERLAYMASK(1));
+ }
+ }
+}
+
+void GetTitlebarIcon(struct SrmmWindowData *dat, TitleBarData *tbd) {
+ if (dat->showTyping && (g_dat->flags2 & SMF2_SHOWTYPINGWIN)) {
+ tbd->hIconNot = tbd->hIcon = GetCachedIcon("scriver_TYPING");
+ } else if (dat->showUnread && (GetActiveWindow() != dat->hwndParent || GetForegroundWindow() != dat->hwndParent)) {
+ tbd->hIcon = (g_dat->flags & SMF_STATUSICON) ? dat->statusIcon : g_dat->hMsgIcon;
+ tbd->hIconNot = (g_dat->flags & SMF_STATUSICON) ? g_dat->hMsgIcon : GetCachedIcon("scriver_OVERLAY");
+ } else {
+ tbd->hIcon = (g_dat->flags & SMF_STATUSICON) ? dat->statusIcon : g_dat->hMsgIcon;
+ tbd->hIconNot = NULL;
+ }
+ tbd->hIconBig = (g_dat->flags & SMF_STATUSICON) ? dat->statusIconBig : g_dat->hMsgIconBig;
+}
+
+HICON GetTabIcon(struct SrmmWindowData *dat) {
+ if (dat->showTyping) {
+ return GetCachedIcon("scriver_TYPING");
+ } else if (dat->showUnread != 0) {
+ return dat->statusIconOverlay;
+ }
+ return dat->statusIcon;
+}
+
+
+struct MsgEditSubclassData
+{
+ DWORD lastEnterTime;
+};
+
+static LRESULT CALLBACK LogEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL inMenu = FALSE;
+ switch (msg) {
+ case WM_MEASUREITEM:
+ MeasureMenuItem(wParam, lParam);
+ return TRUE;
+ case WM_DRAWITEM:
+ return DrawMenuItem(wParam, lParam);
+ case WM_SETCURSOR:
+ if (inMenu) {
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ return TRUE;
+ }
+ break;
+ case WM_CONTEXTMENU:
+ {
+ HMENU hMenu, hSubMenu;
+ TCHAR *pszWord;
+ POINT pt;
+ POINTL ptl;
+ int uID;
+ CHARRANGE sel, all = { 0, -1 };
+ hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ hSubMenu = GetSubMenu(hMenu, 0);
+ TranslateMenu(hSubMenu);
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) & sel);
+ if (sel.cpMin == sel.cpMax)
+ EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
+
+ if (lParam == 0xFFFFFFFF) {
+ SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM) & pt, (LPARAM) sel.cpMax);
+ ClientToScreen(hwnd, &pt);
+ } else {
+ pt.x = (short) LOWORD(lParam);
+ pt.y = (short) HIWORD(lParam);
+ }
+ ptl.x = (LONG)pt.x;
+ ptl.y = (LONG)pt.y;
+ ScreenToClient(hwnd, (LPPOINT)&ptl);
+ pszWord = GetRichTextWord(hwnd, &ptl);
+ if ( pszWord && pszWord[0] ) {
+ TCHAR szMenuText[4096];
+ mir_sntprintf( szMenuText, 4096, TranslateT("Look up \'%s\':"), pszWord );
+ ModifyMenu( hSubMenu, 5, MF_STRING|MF_BYPOSITION, 5, szMenuText );
+ SetSearchEngineIcons(hMenu, g_dat->hSearchEngineIconList);
+ }
+ else ModifyMenu( hSubMenu, 5, MF_STRING|MF_GRAYED|MF_BYPOSITION, 5, TranslateT( "No word to look up" ));
+ inMenu = TRUE;
+ uID = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);
+ inMenu = FALSE;
+ switch (uID) {
+ case IDM_COPY:
+ SendMessage(hwnd, WM_COPY, 0, 0);
+ break;
+ case IDM_COPYALL:
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & all);
+ SendMessage(hwnd, WM_COPY, 0, 0);
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & sel);
+ break;
+ case IDM_SELECTALL:
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) & all);
+ break;
+ case IDM_CLEAR:
+ SendMessage(GetParent(hwnd), DM_CLEARLOG, 0, 0);
+ break;
+ case IDM_SEARCH_GOOGLE:
+ case IDM_SEARCH_BING:
+ case IDM_SEARCH_YAHOO:
+ case IDM_SEARCH_WIKIPEDIA:
+ case IDM_SEARCH_FOODNETWORK:
+ case IDM_SEARCH_GOOGLE_MAPS:
+ case IDM_SEARCH_GOOGLE_TRANSLATE:
+ SearchWord(pszWord, uID - IDM_SEARCH_GOOGLE + SEARCHENGINE_GOOGLE);
+ PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0 );
+ break;
+ }
+ DestroyMenu(hMenu);
+ mir_free(pszWord);
+ return TRUE;
+ }
+ }
+ return CallWindowProc(OldLogEditProc, hwnd, msg, wParam, lParam);
+}
+
+static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int result = -1;
+ struct MsgEditSubclassData *dat;
+ struct SrmmWindowData *pdat;
+ CommonWindowData *windowData;
+ BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000;
+ BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
+ dat = (struct MsgEditSubclassData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ pdat=(struct SrmmWindowData *)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
+ windowData = &pdat->windowData;
+
+ result = InputAreaShortcuts(hwnd, msg, wParam, lParam, windowData);
+ if (result != -1) {
+ return result;
+ }
+
+ switch (msg) {
+ case EM_SUBCLASSED:
+ dat = (struct MsgEditSubclassData *) mir_alloc(sizeof(struct MsgEditSubclassData));
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) dat);
+ dat->lastEnterTime = 0;
+ return 0;
+
+ case WM_KEYDOWN:
+ {
+ if (wParam == VK_RETURN) {
+ if ((isCtrl != 0) ^ (0 != (g_dat->flags & SMF_SENDONENTER))) {
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ if (g_dat->flags & SMF_SENDONDBLENTER) {
+ if (dat->lastEnterTime + ENTERCLICKTIME < GetTickCount())
+ dat->lastEnterTime = GetTickCount();
+ else {
+ SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0);
+ SendMessage(hwnd, WM_KEYUP, VK_BACK, 0);
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ }
+ }
+ else
+ dat->lastEnterTime = 0;
+ if (((wParam == VK_INSERT && (GetKeyState(VK_SHIFT) & 0x8000)) || (wParam == 'V' && (GetKeyState(VK_CONTROL) & 0x8000))) &&
+ !(GetKeyState(VK_MENU) & 0x8000))
+ {
+ SendMessage(hwnd, WM_PASTE, 0, 0);
+ return 0;
+ }
+
+ }
+ break;
+ //fall through
+ case WM_MOUSEWHEEL:
+ if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_VSCROLL) == 0) {
+ SendMessage(GetDlgItem(GetParent(hwnd), IDC_LOG), WM_MOUSEWHEEL, wParam, lParam);
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_KILLFOCUS:
+ dat->lastEnterTime = 0;
+ break;
+ case WM_SYSCHAR:
+ dat->lastEnterTime = 0;
+ if ((wParam == 's' || wParam == 'S') && isAlt) {
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ break;
+ case WM_PASTE:
+ if (IsClipboardFormatAvailable(CF_HDROP))
+ {
+ if (OpenClipboard(hwnd))
+ {
+ HANDLE hDrop = GetClipboardData(CF_HDROP);
+ if (hDrop)
+ SendMessage(hwnd, WM_DROPFILES, (WPARAM)hDrop, 0);
+ CloseClipboard();
+ }
+ }
+ else
+ SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0);
+ return 0;
+ case WM_DROPFILES:
+ SendMessage(GetParent(hwnd), WM_DROPFILES, wParam, lParam);
+ return 0;
+ case WM_CONTEXTMENU:
+ InputAreaContextMenu(hwnd, wParam, lParam, pdat->windowData.hContact);
+ return TRUE;
+ case EM_UNSUBCLASSED:
+ mir_free(dat);
+ return 0;
+ }
+ return CallWindowProc(OldMessageEditProc, hwnd, msg, wParam, lParam);
+}
+
+static void SubclassMessageEdit(HWND hwnd) {
+ OldMessageEditProc = (WNDPROC) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) MessageEditSubclassProc);
+ SendMessage(hwnd, EM_SUBCLASSED, 0, 0);
+}
+
+static void UnsubclassMessageEdit(HWND hwnd) {
+ SendMessage(hwnd, EM_UNSUBCLASSED, 0, 0);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) OldMessageEditProc);
+}
+
+static void SubclassLogEdit(HWND hwnd) {
+ OldLogEditProc = (WNDPROC) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) LogEditSubclassProc);
+ SendMessage(hwnd, EM_SUBCLASSED, 0, 0);
+}
+
+static void UnsubclassLogEdit(HWND hwnd) {
+ SendMessage(hwnd, EM_UNSUBCLASSED, 0, 0);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) OldLogEditProc);
+}
+
+static void MessageDialogResize(HWND hwndDlg, struct SrmmWindowData *dat, int w, int h) {
+ HDWP hdwp;
+ ParentWindowData *pdat = dat->parent;
+ int hSplitterPos = dat->splitterPos, toolbarHeight = pdat->flags2&SMF2_SHOWTOOLBAR ? IsToolbarVisible(SIZEOF(toolbarButtons), g_dat->buttonVisibility) ? dat->toolbarSize.cy : dat->toolbarSize.cy / 3 : 0;
+ int hSplitterMinTop = toolbarHeight + dat->windowData.minLogBoxHeight, hSplitterMinBottom = dat->windowData.minEditBoxHeight;
+ int infobarHeight = INFO_BAR_INNER_HEIGHT;
+ int avatarWidth = 0, avatarHeight = 0;
+ int toolbarWidth = w;
+ int messageEditWidth = w - 2;
+ int logY, logH;
+
+ if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) {
+ infobarHeight = 0;
+ }
+ hSplitterPos = dat->desiredInputAreaHeight + SPLITTER_HEIGHT + 3;
+ if (h - hSplitterPos - INFO_BAR_HEIGHT< hSplitterMinTop) {
+ hSplitterPos = h - hSplitterMinTop - INFO_BAR_HEIGHT;
+ }
+ if (hSplitterPos < avatarHeight) {
+ hSplitterPos = avatarHeight;
+ }
+ if (hSplitterPos < hSplitterMinBottom) {
+ hSplitterPos = hSplitterMinBottom;
+ }
+ if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) {
+ if (dat->avatarPic && (g_dat->flags&SMF_AVATAR)) {
+ avatarWidth = BOTTOM_RIGHT_AVATAR_HEIGHT;
+ avatarHeight = toolbarHeight + hSplitterPos - 2;
+ if (avatarHeight < BOTTOM_RIGHT_AVATAR_HEIGHT) {
+ avatarHeight = BOTTOM_RIGHT_AVATAR_HEIGHT;
+ hSplitterPos = avatarHeight - toolbarHeight + 2;
+ } else {
+ avatarHeight = BOTTOM_RIGHT_AVATAR_HEIGHT;
+ }
+ avatarWidth = avatarHeight;
+ if (avatarWidth > BOTTOM_RIGHT_AVATAR_HEIGHT && avatarWidth > w/4) {
+ avatarWidth = w /4;
+ }
+ if ((toolbarWidth - avatarWidth - 2) < dat->toolbarSize.cx) {
+ avatarWidth = toolbarWidth - dat->toolbarSize.cx - 2;
+ }
+ toolbarWidth -= avatarWidth + 2;
+ messageEditWidth -= avatarWidth + 1;
+ }
+ }
+
+ dat->splitterPos = hSplitterPos;
+
+ logY = infobarHeight;
+ logH = h-hSplitterPos-toolbarHeight - infobarHeight;
+ hdwp = BeginDeferWindowPos(15);
+ hdwp = DeferWindowPos(hdwp, dat->infobarData->hWnd, 0, 1, 0, w - 2, infobarHeight - 2, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_LOG), 0, 1, logY, w-2, logH, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_MESSAGE), 0, 1, h - hSplitterPos + SPLITTER_HEIGHT, messageEditWidth, hSplitterPos - SPLITTER_HEIGHT - 1, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_AVATAR), 0, w-avatarWidth - 1, h - (avatarHeight + avatarWidth) / 2 - 1, avatarWidth, avatarWidth, SWP_NOZORDER);
+
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_SPLITTER), 0, 0, h - hSplitterPos-1, toolbarWidth, SPLITTER_HEIGHT, SWP_NOZORDER);
+ hdwp = ResizeToolbar(hwndDlg, hdwp, toolbarWidth, h - hSplitterPos - toolbarHeight + 1, toolbarHeight, SIZEOF(toolbarButtons), toolbarButtons, g_dat->buttonVisibility);
+
+ /*
+ if (hSplitterPos - SPLITTER_HEIGHT - toolbarHeight - 2< dat->avatarHeight) {
+ hSplitterPos = dat->avatarHeight + SPLITTER_HEIGHT + toolbarHeight + 2;
+ }
+ dat->splitterPos = hSplitterPos;
+ hdwp = BeginDeferWindowPos(12);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_LOG), 0, 0, 0, w-vSplitterPos, h-hSplitterPos, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_MESSAGE), 0, 0, h - hSplitterPos + SPLITTER_HEIGHT, w, hSplitterPos - SPLITTER_HEIGHT - toolbarHeight -2, SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_SPLITTER), 0, 0, h - hSplitterPos-1, w, SPLITTER_HEIGHT + 1, SWP_NOZORDER);
+ if (dat->avatarHeight + 1 < hSplitterPos - toolbarHeight) {
+ aPos = h - (hSplitterPos + toolbarHeight + dat->avatarHeight - 1) / 2;
+ } else {
+ aPos = h - (hSplitterPos + toolbarHeight + dat->avatarHeight + 1) / 2;
+ }
+ vPos = h - toolbarHeight;
+ hdwp = ResizeToolbar(hwndDlg, hdwp, w, vPos, toolbarHeight, SIZEOF(buttonControls),
+ buttonControls, buttonWidth, buttonSpacing, buttonAlignment, g_dat->buttonVisibility);
+
+*/
+ EndDeferWindowPos(hdwp);
+ if (dat->windowData.hwndLog != NULL) {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_SETPOS;
+ ieWindow.parent = hwndDlg;
+ ieWindow.hwnd = dat->windowData.hwndLog;
+ ieWindow.x = 0;
+ ieWindow.y = logY;
+ ieWindow.cx = w;
+ ieWindow.cy = logH;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ } else {
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_LOG), NULL, NULL, RDW_INVALIDATE);
+ }
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_MESSAGE), NULL, NULL, RDW_INVALIDATE);
+
+ RefreshInfobar(dat->infobarData);
+
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_AVATAR), NULL, NULL, RDW_INVALIDATE);
+}
+
+static void UpdateReadChars(HWND hwndDlg, struct SrmmWindowData * dat)
+{
+ if (dat->parent->hwndActive == hwndDlg) {
+ TCHAR szText[256];
+ StatusBarData sbd;
+ int len = GetRichTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE), dat->windowData.codePage, FALSE);
+ sbd.iItem = 1;
+ sbd.iFlags = SBDF_TEXT | SBDF_ICON;
+ sbd.hIcon = NULL;
+ sbd.pszText = szText;
+ mir_sntprintf(szText, SIZEOF(szText), _T("%d"), len);
+ SendMessage(dat->hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)hwndDlg);
+ }
+}
+
+void ShowAvatar(HWND hwndDlg, struct SrmmWindowData *dat)
+{
+ INT_PTR res = CallService(MS_AV_GETAVATARBITMAP, (WPARAM)dat->windowData.hContact, 0);
+ dat->ace = res != CALLSERVICE_NOTFOUND ? (AVATARCACHEENTRY*)res : NULL;
+ dat->avatarPic = (dat->ace != NULL && (dat->ace->dwFlags & AVS_HIDEONCLIST) == 0) ? dat->ace->hbmPic : NULL;
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+
+ RefreshInfobar(dat->infobarData);
+
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_AVATAR), NULL, NULL, RDW_INVALIDATE);
+}
+
+static BOOL IsTypingNotificationSupported(struct SrmmWindowData *dat) {
+ DWORD typeCaps;
+ if (!dat->windowData.hContact)
+ return FALSE;
+ if (!dat->szProto)
+ return FALSE;
+ typeCaps = CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_4, 0);
+ if (!(typeCaps & PF4_SUPPORTTYPING))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL IsTypingNotificationEnabled(struct SrmmWindowData *dat) {
+ DWORD protoStatus;
+ DWORD protoCaps;
+ if (!DBGetContactSettingByte(dat->windowData.hContact, SRMMMOD, SRMSGSET_TYPING, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)))
+ return FALSE;
+ protoStatus = CallProtoService(dat->szProto, PS_GETSTATUS, 0, 0);
+ if (protoStatus < ID_STATUS_ONLINE)
+ return FALSE;
+ protoCaps = CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_1, 0);
+ if (protoCaps & PF1_VISLIST && DBGetContactSettingWord(dat->windowData.hContact, dat->szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE)
+ return FALSE;
+ if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && DBGetContactSettingWord(dat->windowData.hContact, dat->szProto, "ApparentMode", 0) != ID_STATUS_ONLINE)
+ return FALSE;
+ if (DBGetContactSettingByte(dat->windowData.hContact, "CList", "NotOnList", 0)
+ && !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGUNKNOWN, SRMSGDEFSET_TYPINGUNKNOWN))
+ return FALSE;
+ return TRUE;
+}
+
+// Don't send to protocols who don't support typing
+// Don't send to users who are unchecked in the typing notification options
+// Don't send to protocols that are offline
+// Don't send to users who are not visible and
+// Don't send to users who are not on the visible list when you are in invisible mode.
+static void NotifyTyping(struct SrmmWindowData *dat, int mode) {
+ if (!IsTypingNotificationSupported(dat)) {
+ return;
+ }
+ if (!IsTypingNotificationEnabled(dat)) {
+ return;
+ }
+ // End user check
+ dat->nTypeMode = mode;
+ CallService(MS_PROTO_SELFISTYPING, (WPARAM) dat->windowData.hContact, dat->nTypeMode);
+}
+
+static INT_PTR CALLBACK ConfirmSendAllDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ RECT rcParent, rcChild;
+ TranslateDialogDefault( hwndDlg );
+ GetWindowRect(GetParent(hwndDlg), &rcParent);
+ GetWindowRect(hwndDlg, &rcChild);
+ rcChild.bottom -= rcChild.top;
+ rcChild.right -= rcChild.left;
+ rcParent.bottom -= rcParent.top;
+ rcParent.right -= rcParent.left;
+ rcChild.left = rcParent.left + (rcParent.right - rcChild.right) / 2;
+ rcChild.top = rcParent.top + (rcParent.bottom - rcChild.bottom) / 2;
+ MoveWindow(hwndDlg, rcChild.left, rcChild.top, rcChild.right, rcChild.bottom, FALSE);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDYES:
+ case IDNO:
+ case IDCANCEL:
+ {
+ int result = LOWORD(wParam);
+ if (IsDlgButtonChecked(hwndDlg, IDC_REMEMBER)) {
+ result |= 0x10000;
+ }
+ EndDialog(hwndDlg, result);
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HMENU hToolbarMenu;
+ struct SrmmWindowData *dat;
+ dat = (struct SrmmWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ if (!dat && msg!=WM_INITDIALOG) return FALSE;
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ int len = 0;
+ int notifyUnread = 0;
+ RECT minEditInit;
+ NewMessageWindowLParam *newData = (NewMessageWindowLParam *) lParam;
+ //TranslateDialogDefault(hwndDlg);
+ dat = (struct SrmmWindowData *) mir_alloc(sizeof(struct SrmmWindowData));
+ ZeroMemory(dat, sizeof(struct SrmmWindowData));
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dat);
+ dat->windowData.hContact = newData->hContact;
+ NotifyLocalWinEvent(dat->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_OPENING);
+// SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETTEXTMODE, TM_PLAINTEXT, 0);
+
+ dat->hwnd = hwndDlg;
+ dat->hwndParent = GetParent(hwndDlg);
+ dat->parent = (ParentWindowData *) GetWindowLongPtr(dat->hwndParent, GWLP_USERDATA);
+ dat->windowData.hwndLog = NULL;
+ dat->szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) dat->windowData.hContact, 0);
+ dat->avatarPic = 0;
+ if (dat->windowData.hContact && dat->szProto != NULL)
+ dat->wStatus = DBGetContactSettingWord(dat->windowData.hContact, dat->szProto, "Status", ID_STATUS_OFFLINE);
+ else
+ dat->wStatus = ID_STATUS_OFFLINE;
+ dat->hDbEventFirst = NULL;
+ dat->hDbEventLast = NULL;
+ dat->hDbUnreadEventFirst = NULL;
+ dat->messagesInProgress = 0;
+ dat->nTypeSecs = 0;
+ dat->nLastTyping = 0;
+ dat->showTyping = 0;
+ dat->showUnread = 0;
+ dat->sendAllConfirm = 0;
+ dat->nTypeMode = PROTOTYPE_SELFTYPING_OFF;
+ SetTimer(hwndDlg, TIMERID_TYPE, 1000, NULL);
+ dat->lastMessage = 0;
+ dat->lastEventType = -1;
+ dat->lastEventTime = time(NULL);
+ dat->startTime = time(NULL);
+ dat->flags = 0;
+ if (DBGetContactSettingByte(dat->windowData.hContact, SRMMMOD, "UseRTL", (BYTE) 0)) {
+ dat->flags |= SMF_RTL;
+ }
+ dat->flags |= ServiceExists(MS_IEVIEW_WINDOW) ? g_dat->flags & SMF_USEIEVIEW : 0;
+ {
+ PARAFORMAT2 pf2;
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_RTLPARA;
+ if (!(dat->flags & SMF_RTL)) {
+ pf2.wEffects = 0;
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE) & ~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR));
+ } else {
+ pf2.wEffects = PFE_RTLPARA;
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ /* Workaround to make Richedit display RTL messages correctly */
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_RTLPARA | PFM_OFFSETINDENT | PFM_RIGHTINDENT;
+ pf2.wEffects = PFE_RTLPARA;
+ pf2.dxStartIndent = 30;
+ pf2.dxRightIndent = 30;
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ pf2.dwMask = PFM_RTLPARA;
+ pf2.wEffects = 0;
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ if (dat->flags & SMF_RTL) {
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR);
+ } else {
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE) & ~WS_EX_LEFTSCROLLBAR);
+ }
+ }
+ dat->windowData.codePage = DBGetContactSettingWord(dat->windowData.hContact, SRMMMOD, "CodePage", (WORD) CP_ACP);
+ dat->ace = NULL;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MESSAGE), &minEditInit);
+ dat->windowData.minEditBoxHeight = minEditInit.bottom - minEditInit.top;
+ dat->windowData.minLogBoxHeight = dat->windowData.minEditBoxHeight;
+ dat->toolbarSize.cy = TOOLBAR_HEIGHT;
+ dat->toolbarSize.cx = GetToolbarWidth(SIZEOF(toolbarButtons), toolbarButtons);
+ if (dat->splitterPos == -1) {
+ dat->splitterPos = dat->windowData.minEditBoxHeight;
+ }
+ WindowList_Add(g_dat->hMessageWindowList, hwndDlg, dat->windowData.hContact);
+
+ if (newData->szInitialText) {
+ if (newData->isWchar)
+ SetDlgItemText(hwndDlg, IDC_MESSAGE, (TCHAR *)newData->szInitialText);
+ else
+ SetDlgItemTextA(hwndDlg, IDC_MESSAGE, newData->szInitialText);
+ } else if (g_dat->flags & SMF_SAVEDRAFTS) {
+ TCmdList *draft = tcmdlist_get2(g_dat->draftList, dat->windowData.hContact);
+ if (draft != NULL) {
+ len = SetRichTextEncoded(GetDlgItem(hwndDlg, IDC_MESSAGE), draft->szCmd, dat->windowData.codePage);
+ }
+ PostMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), EM_SETSEL, len, len);
+ }
+
+ SendMessage(hwndDlg, DM_CHANGEICONS, 0, 0);
+ // Make them flat buttons
+ {
+ int i;
+ for (i = 0; i < SIZEOF(toolbarButtons) ; i++)
+ SendMessage(GetDlgItem(hwndDlg, toolbarButtons[i].controlId), BUTTONSETASFLATBTN, TRUE, 0);
+ }
+ SendMessage(GetDlgItem(hwndDlg, IDC_ADD), BUTTONADDTOOLTIP, (WPARAM) Translate("Add Contact Permanently to List"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_USERMENU), BUTTONADDTOOLTIP, (WPARAM) Translate("User Menu"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_DETAILS), BUTTONADDTOOLTIP, (WPARAM) Translate("View User's Details"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_HISTORY), BUTTONADDTOOLTIP, (WPARAM) Translate("View User's History"), 0);
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_QUOTE), BUTTONADDTOOLTIP, (WPARAM) Translate("Quote Text"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_SMILEYS), BUTTONADDTOOLTIP, (WPARAM) Translate("Insert Emoticon"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDOK), BUTTONADDTOOLTIP, (WPARAM) Translate("Send Message"), 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETOLECALLBACK, 0, (LPARAM) & reOleCallback);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_KEYEVENTS);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETLANGOPTIONS, 0, (LPARAM) SendDlgItemMessage(hwndDlg, IDC_LOG, EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST));
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
+ /* duh, how come we didnt use this from the start? */
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETLANGOPTIONS, 0, (LPARAM) SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETOLECALLBACK, 0, (LPARAM) & reOleCallback2);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE);
+ if (dat->windowData.hContact) {
+ if (dat->szProto) {
+ int nMax;
+ nMax = CallProtoService(dat->szProto, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, (LPARAM) dat->windowData.hContact);
+ if (nMax)
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_LIMITTEXT, (WPARAM) nMax, 0);
+ }
+ }
+ /* get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF */
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_LIMITTEXT, (WPARAM) sizeof(TCHAR) * 0x7FFFFFFF, 0);
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_LOG));
+ SubclassLogEdit(GetDlgItem(hwndDlg, IDC_LOG));
+ SubclassMessageEdit(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ dat->infobarData = CreateInfobar(hwndDlg, dat);
+ if (dat->flags & SMF_USEIEVIEW) {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_CREATE;
+ ieWindow.dwFlags = 0;
+ ieWindow.dwMode = IEWM_SCRIVER;
+ ieWindow.parent = hwndDlg;
+ ieWindow.x = 0;
+ ieWindow.y = 0;
+ ieWindow.cx = 200;
+ ieWindow.cy = 300;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ dat->windowData.hwndLog = ieWindow.hwnd;
+ if (dat->windowData.hwndLog == NULL) {
+ dat->flags ^= SMF_USEIEVIEW;
+ }
+ }
+ if (dat->windowData.hContact) {
+ int historyMode = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY);
+ // This finds the first message to display, it works like shit
+ dat->hDbEventFirst = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) dat->windowData.hContact, 0);
+ if (dat->hDbEventFirst != NULL) {
+ DBEVENTINFO dbei = { 0 };
+ dbei.cbSize = sizeof(dbei);
+ CallService(MS_DB_EVENT_GET, (WPARAM) dat->hDbEventFirst, (LPARAM) & dbei);
+ if (DbEventIsMessageOrCustom(&dbei) && !(dbei.flags & DBEF_READ) && !(dbei.flags & DBEF_SENT)) {
+ notifyUnread = 1;
+ }
+ }
+ switch (historyMode) {
+ case LOADHISTORY_COUNT:
+ {
+ int i;
+ HANDLE hPrevEvent;
+ DBEVENTINFO dbei = { 0 };
+ dbei.cbSize = sizeof(dbei);
+ for (i = DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADCOUNT, SRMSGDEFSET_LOADCOUNT); i > 0; i--) {
+ if (dat->hDbEventFirst == NULL)
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) dat->windowData.hContact, 0);
+ else
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) dat->hDbEventFirst, 0);
+ if (hPrevEvent == NULL)
+ break;
+ dbei.cbBlob = 0;
+ dat->hDbEventFirst = hPrevEvent;
+ CallService(MS_DB_EVENT_GET, (WPARAM) dat->hDbEventFirst, (LPARAM) & dbei);
+ if (!DbEventIsShown(&dbei, dat))
+ i++;
+ }
+ break;
+ }
+ case LOADHISTORY_TIME:
+ {
+ HANDLE hPrevEvent;
+ DBEVENTINFO dbei = { 0 };
+ DWORD firstTime;
+
+ dbei.cbSize = sizeof(dbei);
+ if (dat->hDbEventFirst == NULL) {
+ dbei.timestamp = time(NULL);
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) dat->windowData.hContact, 0);
+ } else {
+ CallService(MS_DB_EVENT_GET, (WPARAM) dat->hDbEventFirst, (LPARAM) & dbei);
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) dat->hDbEventFirst, 0);
+ }
+ firstTime = dbei.timestamp - 60 * DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADTIME, SRMSGDEFSET_LOADTIME);
+ for (;;) {
+ if (hPrevEvent == NULL)
+ break;
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM) hPrevEvent, (LPARAM) & dbei);
+ if (dbei.timestamp < firstTime)
+ break;
+ if (DbEventIsShown(&dbei, dat))
+ dat->hDbEventFirst = hPrevEvent;
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) hPrevEvent, 0);
+ }
+ break;
+ }
+ }
+ }
+ SendMessage(dat->hwndParent, CM_ADDCHILD, (WPARAM) hwndDlg, (LPARAM) dat->windowData.hContact);
+ {
+ DBEVENTINFO dbei = { 0 };
+ HANDLE hdbEvent;
+
+ dbei.cbSize = sizeof(dbei);
+ hdbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) dat->windowData.hContact, 0);
+ if (hdbEvent) {
+ do {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ CallService(MS_DB_EVENT_GET, (WPARAM) hdbEvent, (LPARAM) & dbei);
+ if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ dat->lastMessage = dbei.timestamp;
+ break;
+ }
+ }
+ while ((hdbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) hdbEvent, 0)));
+ }
+ }
+ SendMessage(hwndDlg, DM_OPTIONSAPPLIED, 0, 0);
+ SendMessage(GetParent(hwndDlg), CM_POPUPWINDOW, (WPARAM) (newData->flags & NMWLP_INCOMING), (LPARAM) hwndDlg);
+ if (notifyUnread) {
+ if (GetForegroundWindow() != dat->hwndParent || dat->parent->hwndActive != hwndDlg) {
+ dat->showUnread = 1;
+ SendMessage(hwndDlg, DM_UPDATEICON, 0, 0);
+ SetTimer(hwndDlg, TIMERID_UNREAD, TIMEOUT_UNREAD, NULL);
+ }
+ SendMessage(dat->hwndParent, CM_STARTFLASHING, 0, 0);
+ }
+ dat->messagesInProgress = ReattachSendQueueItems(hwndDlg, dat->windowData.hContact);
+ if (dat->messagesInProgress > 0) {
+ SendMessage(hwndDlg, DM_SHOWMESSAGESENDING, 0, 0);
+ }
+ NotifyLocalWinEvent(dat->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_OPEN);
+ return TRUE;
+ }
+ case DM_GETCONTEXTMENU:
+ {
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) dat->windowData.hContact, 0);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)hMenu);
+ return TRUE;
+ }
+ case WM_CONTEXTMENU:
+ if (dat->hwndParent == (HWND) wParam) {
+ POINT pt;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) dat->windowData.hContact, 0);
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+ }
+ break;
+ case WM_LBUTTONDBLCLK:
+ SendMessage(dat->hwndParent, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ break;
+ case WM_RBUTTONUP:
+ {
+ int i;
+ POINT pt;
+ MENUITEMINFO mii;
+ hToolbarMenu = CreatePopupMenu();
+ for (i = 0; i < SIZEOF(toolbarButtons); i++) {
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE | MIIM_DATA | MIIM_BITMAP;
+ mii.fType = MFT_STRING;
+ mii.fState = (g_dat->buttonVisibility & (1<< i)) ? MFS_CHECKED : MFS_UNCHECKED;
+ mii.wID = i + 1;
+ mii.dwItemData = (ULONG_PTR)g_dat->hButtonIconList;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ mii.dwTypeData = TranslateTS((toolbarButtons[i].name));
+ InsertMenuItem(hToolbarMenu, i, TRUE, &mii);
+ }
+// TranslateMenu(hToolbarMenu);
+ pt.x = (short) LOWORD(GetMessagePos());
+ pt.y = (short) HIWORD(GetMessagePos());
+ i = TrackPopupMenu(hToolbarMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL);
+ if (i > 0) {
+ g_dat->buttonVisibility ^= (1 << (i - 1));
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_BUTTONVISIBILITY, g_dat->buttonVisibility);
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ }
+ DestroyMenu(hToolbarMenu);
+ return TRUE;
+ }
+ case WM_DROPFILES:
+ if (dat->szProto==NULL) break;
+ if (!(CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_1,0)&PF1_FILESEND)) break;
+ if (dat->wStatus==ID_STATUS_OFFLINE) break;
+ if (dat->windowData.hContact!=NULL) {
+ TCHAR szFilename[MAX_PATH];
+ HDROP hDrop = (HDROP)wParam;
+ int fileCount = DragQueryFile(hDrop,-1,NULL,0), totalCount = 0, i;
+ TCHAR** ppFiles = NULL;
+ for ( i=0; i < fileCount; i++ ) {
+ DragQueryFile(hDrop, i, szFilename, SIZEOF(szFilename));
+ AddToFileList(&ppFiles, &totalCount, szFilename);
+ }
+ CallServiceSync(MS_FILE_SENDSPECIFICFILEST, (WPARAM)dat->windowData.hContact, (LPARAM)ppFiles);
+ for(i=0;ppFiles[i];i++) mir_free(ppFiles[i]);
+ mir_free(ppFiles);
+ }
+ break;
+
+ case DM_AVATARCHANGED:
+ ShowAvatar(hwndDlg, dat);
+ break;
+
+ case DM_GETAVATAR:
+ {
+ PROTO_AVATAR_INFORMATIONT ai = { sizeof(ai), dat->windowData.hContact };
+ CallProtoService(dat->szProto, PS_GETAVATARINFOT, GAIF_FORCE, (LPARAM)&ai);
+ ShowAvatar(hwndDlg, dat);
+ break;
+ }
+ case DM_TYPING:
+ dat->nTypeSecs = (int) lParam > 0 ? (int) lParam : 0;
+ break;
+ case DM_CHANGEICONS:
+ SendDlgItemMessage(hwndDlg, IDC_ADD, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_ADD"));
+ SendDlgItemMessage(hwndDlg, IDC_DETAILS, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_USERDETAILS"));
+ SendDlgItemMessage(hwndDlg, IDC_HISTORY, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_HISTORY"));
+ SendDlgItemMessage(hwndDlg, IDC_QUOTE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_QUOTE"));
+ SendDlgItemMessage(hwndDlg, IDC_SMILEYS, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_SMILEY"));
+ SendDlgItemMessage(hwndDlg, IDOK, BM_SETIMAGE, IMAGE_ICON, (LPARAM) GetCachedIcon("scriver_SEND"));
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SetStatusIcon(dat);
+
+ case DM_UPDATEICON:
+ {
+ TitleBarData tbd = {0};
+ TabControlData tcd;
+ tbd.iFlags = TBDF_ICON;
+ GetTitlebarIcon(dat, &tbd);
+ SendMessage(dat->hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)hwndDlg);
+ tcd.iFlags = TCDF_ICON;
+ tcd.hIcon = GetTabIcon(dat);
+ SendMessage(dat->hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)hwndDlg);
+ SendDlgItemMessage(hwndDlg, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (LPARAM)dat->statusIcon);
+ }
+ break;
+ case DM_UPDATETABCONTROL:
+ {
+ TabControlData tcd;
+ tcd.iFlags = TCDF_TEXT | TCDF_ICON;
+ tcd.hIcon = GetTabIcon(dat);
+ tcd.pszText = GetTabName((HANDLE *)dat->windowData.hContact);
+ SendMessage(dat->hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)hwndDlg);
+ mir_free(tcd.pszText);
+ }
+ break;
+ case DM_UPDATETITLEBAR:
+ {
+ TitleBarData tbd = {0};
+ tbd.iFlags = TBDF_TEXT | TBDF_ICON;
+ GetTitlebarIcon(dat, &tbd);
+ tbd.pszText = GetWindowTitle((HANDLE *)dat->windowData.hContact, dat->szProto);
+ SendMessage(dat->hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)hwndDlg);
+ mir_free(tbd.pszText);
+ }
+ break;
+
+ case DM_CLISTSETTINGSCHANGED:
+ {
+ if ((HANDLE)wParam == dat->windowData.hContact) {
+ if (dat->windowData.hContact && dat->szProto) {
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+ char idbuf[128];
+ char buf[128];
+ GetContactUniqueId(dat, idbuf, sizeof(idbuf));
+ mir_snprintf(buf, sizeof(buf), Translate("User Menu - %s"), idbuf);
+ SendMessage(GetDlgItem(hwndDlg, IDC_USERMENU), BUTTONADDTOOLTIP, (WPARAM) buf, 0);
+
+ if (!cws || (!strcmp(cws->szModule, dat->szProto) && !strcmp(cws->szSetting, "Status"))) {
+ DWORD wStatus;
+ wStatus = DBGetContactSettingWord( dat->windowData.hContact, dat->szProto, "Status", ID_STATUS_OFFLINE);
+ // log status change - should be moved to a separate place
+ if (dat->wStatus != wStatus && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, SRMSGDEFSET_SHOWSTATUSCH)) {
+ DBEVENTINFO dbei;
+ TCHAR buffer[512];
+ char blob[2048];
+ HANDLE hNewEvent;
+ int iLen;
+ TCHAR *szOldStatus = mir_tstrdup((TCHAR *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM) dat->wStatus, GSMDF_TCHAR));
+ TCHAR *szNewStatus = mir_tstrdup((TCHAR *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM) wStatus, GSMDF_TCHAR));
+ if (wStatus == ID_STATUS_OFFLINE) {
+ iLen = mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("signed off (was %s)"), szOldStatus);
+ SendMessage(hwndDlg, DM_TYPING, 0, 0);
+ }
+ else if (dat->wStatus == ID_STATUS_OFFLINE) {
+ iLen = mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("signed on (%s)"), szNewStatus);
+ }
+ else {
+ iLen = mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("is now %s (was %s)"), szNewStatus, szOldStatus);
+ }
+ mir_free(szOldStatus);
+ mir_free(szNewStatus);
+
+ {
+ int ansiLen = WideCharToMultiByte(CP_ACP, 0, buffer, -1, blob, sizeof(blob), 0, 0);
+ memcpy( blob+ansiLen, buffer, sizeof(TCHAR)*(iLen+1));
+ dbei.cbBlob = ansiLen + sizeof(TCHAR)*(iLen+1);
+ }
+
+ //iLen = strlen(buffer) + 1;
+ //MultiByteToWideChar(CP_ACP, 0, buffer, iLen, (LPWSTR) & buffer[iLen], iLen);
+ dbei.cbSize = sizeof(dbei);
+ dbei.pBlob = (PBYTE) blob;
+ // dbei.cbBlob = (strlen(buffer) + 1) * (sizeof(TCHAR) + 1);
+ dbei.eventType = EVENTTYPE_STATUSCHANGE;
+ dbei.flags = 0;
+ dbei.timestamp = time(NULL);
+ dbei.szModule = dat->szProto;
+ hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM) dat->windowData.hContact, (LPARAM) & dbei);
+ if (dat->hDbEventFirst == NULL) {
+ dat->hDbEventFirst = hNewEvent;
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ }
+ }
+ dat->wStatus = wStatus;
+ }
+ SetStatusIcon(dat);
+ SendMessage(hwndDlg, DM_UPDATEICON, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETABCONTROL, 0, 0);
+ ShowAvatar(hwndDlg, dat);
+ }
+ }
+ break;
+ }
+ case DM_OPTIONSAPPLIED:
+ {
+ PARAFORMAT2 pf2;
+ memset(&pf2, 0, sizeof(pf2));
+ CHARFORMAT2 cf2;
+ memset(&cf2, 0, sizeof(cf2));
+ LOGFONT lf;
+ COLORREF colour;
+ dat->flags &= ~SMF_USEIEVIEW;
+ dat->flags |= ServiceExists(MS_IEVIEW_WINDOW) ? g_dat->flags & SMF_USEIEVIEW : 0;
+ if (dat->flags & SMF_USEIEVIEW && dat->windowData.hwndLog == NULL) {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_CREATE;
+ ieWindow.dwFlags = 0;
+ ieWindow.dwMode = IEWM_SCRIVER;
+ ieWindow.parent = hwndDlg;
+ ieWindow.x = 0;
+ ieWindow.y = 0;
+ ieWindow.cx = 200;
+ ieWindow.cy = 300;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ dat->windowData.hwndLog = ieWindow.hwnd;
+ if (dat->windowData.hwndLog == NULL) {
+ dat->flags ^= SMF_USEIEVIEW;
+ }
+ } else if (!(dat->flags & SMF_USEIEVIEW) && dat->windowData.hwndLog != NULL) {
+ if (dat->windowData.hwndLog != NULL) {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_DESTROY;
+ ieWindow.hwnd = dat->windowData.hwndLog;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ }
+ dat->windowData.hwndLog = NULL;
+ }
+
+ SendMessage(hwndDlg, DM_GETAVATAR, 0, 0);
+ SetDialogToType(hwndDlg);
+
+ colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETBKGNDCOLOR, 0, colour);
+ colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETBKGNDCOLOR, 0, colour);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_MESSAGE), NULL, FALSE);
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, &colour, FALSE);
+ cf2.cbSize = sizeof(cf2);
+ cf2.dwMask = CFM_COLOR | CFM_FACE | CFM_CHARSET | CFM_SIZE | CFM_WEIGHT | CFM_BOLD | CFM_ITALIC;
+ cf2.crTextColor = colour;
+ cf2.bCharSet = lf.lfCharSet;
+ _tcsncpy(cf2.szFaceName, lf.lfFaceName, LF_FACESIZE);
+ cf2.dwEffects = ((lf.lfWeight >= FW_BOLD) ? CFE_BOLD : 0) | (lf.lfItalic ? CFE_ITALIC : 0);
+ cf2.wWeight = (WORD)lf.lfWeight;
+ cf2.bPitchAndFamily = lf.lfPitchAndFamily;
+ cf2.yHeight = abs(lf.lfHeight) * 1440 / g_dat->logPixelSY;
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&cf2);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETLANGOPTIONS, 0, (LPARAM) SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
+
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_OFFSET;
+ pf2.dxOffset = (g_dat->flags & SMF_INDENTTEXT) ? g_dat->indentSize * 1440 / g_dat->logPixelSX : 0;
+ SetDlgItemText(hwndDlg, IDC_LOG, _T(""));
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETLANGOPTIONS, 0, (LPARAM) SendDlgItemMessage(hwndDlg, IDC_LOG, EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST));
+
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATETABCONTROL, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_REQUESTRESIZE, 0, 0);
+ SetupInfobar(dat->infobarData);
+ break;
+ }
+ case DM_USERNAMETOCLIP:
+ {
+ char buf[128];
+ HGLOBAL hData;
+
+ if (dat->windowData.hContact) {
+ GetContactUniqueId(dat, buf, sizeof(buf));
+ if (!OpenClipboard(hwndDlg) || !lstrlenA(buf)) break;
+ EmptyClipboard();
+ hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(buf) + 1);
+ lstrcpyA((LPSTR)GlobalLock(hData), buf);
+ GlobalUnlock(hData);
+ SetClipboardData(CF_TEXT, hData);
+ CloseClipboard();
+ }
+ break;
+ }
+ case DM_SWITCHINFOBAR:
+ case DM_SWITCHTOOLBAR:
+ SetDialogToType(hwndDlg);
+// SendMessage(dat->hwndParent, DM_SWITCHTOOLBAR, 0, 0);
+ break;
+ case DM_GETCODEPAGE:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, dat->windowData.codePage);
+ return TRUE;
+ case DM_SETCODEPAGE:
+ dat->windowData.codePage = (int) lParam;
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ break;
+ case DM_SWITCHTYPING:
+ if (IsTypingNotificationSupported(dat)) {
+ StatusIconData sid = {0};
+ sid.cbSize = sizeof(sid);
+ sid.szModule = SRMMMOD;
+ sid.dwId = 1;
+ {
+ BYTE typingNotify = (DBGetContactSettingByte(dat->windowData.hContact, SRMMMOD, SRMSGSET_TYPING,
+ DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)));
+ DBWriteContactSettingByte(dat->windowData.hContact, SRMMMOD, SRMSGSET_TYPING, (BYTE)!typingNotify);
+ sid.flags = typingNotify ? MBF_DISABLED : 0;
+ }
+ ModifyStatusIcon((WPARAM)dat->windowData.hContact, (LPARAM) &sid);
+ }
+ break;
+ case DM_SWITCHRTL:
+ {
+ PARAFORMAT2 pf2;
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_RTLPARA;
+ dat->flags ^= SMF_RTL;
+ if (dat->flags&SMF_RTL) {
+ pf2.wEffects = PFE_RTLPARA;
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR);
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR);
+ } else {
+ pf2.wEffects = 0;
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_MESSAGE),GWL_EXSTYLE) &~ (WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR));
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE,GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG),GWL_EXSTYLE) &~ (WS_EX_LEFTSCROLLBAR));
+ }
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ }
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ break;
+ case DM_GETWINDOWSTATE:
+ {
+ UINT state = 0;
+
+ state |= MSG_WINDOW_STATE_EXISTS;
+ if (IsWindowVisible(hwndDlg))
+ state |= MSG_WINDOW_STATE_VISIBLE;
+ if (GetForegroundWindow()==dat->hwndParent)
+ state |= MSG_WINDOW_STATE_FOCUS;
+ if (IsIconic(dat->hwndParent))
+ state |= MSG_WINDOW_STATE_ICONIC;
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, state);
+ return TRUE;
+
+ }
+ case DM_ACTIVATE:
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) != WA_ACTIVE)
+ break;
+ //fall through
+ case WM_MOUSEACTIVATE:
+ if (dat->hDbUnreadEventFirst != NULL) {
+ HANDLE hDbEvent = dat->hDbUnreadEventFirst;
+ dat->hDbUnreadEventFirst = NULL;
+ while (hDbEvent != NULL) {
+ DBEVENTINFO dbei;
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) & dbei);
+ if (!(dbei.flags & DBEF_SENT) && (DbEventIsMessageOrCustom(&dbei) || dbei.eventType == EVENTTYPE_URL)) {
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM) dat->windowData.hContact, (LPARAM) hDbEvent);
+ }
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hDbEvent, 0);
+ }
+ }
+ if (dat->showUnread) {
+ dat->showUnread = 0;
+ KillTimer(hwndDlg, TIMERID_UNREAD);
+ SendMessage(hwndDlg, DM_UPDATEICON, 0, 0);
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ SendMessage(dat->hwndParent, WM_LBUTTONDOWN, wParam, lParam);
+ return TRUE;
+ case DM_SETFOCUS:
+ if (lParam == WM_MOUSEACTIVATE) {
+ HWND hLog;
+ RECT rc;
+ POINT pt;
+ GetCursorPos(&pt);
+ if (dat->windowData.hwndLog != NULL) {
+ hLog = dat->windowData.hwndLog;
+ } else {
+ hLog = GetDlgItem(hwndDlg, IDC_LOG);
+ }
+ GetWindowRect(hLog, &rc);
+ if (pt.x >= rc.left && pt.x <= rc.right && pt.y >= rc.top && pt.y <=rc.bottom) {
+ // SetFocus(hLog);
+ return TRUE;
+ }
+ }
+ if (g_dat->hFocusWnd == hwndDlg) {
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ }
+ return TRUE;
+ case WM_SETFOCUS:
+ SendMessage(dat->hwndParent, CM_ACTIVATECHILD, 0, (LPARAM)hwndDlg);
+ g_dat->hFocusWnd = hwndDlg;
+ PostMessage(hwndDlg, DM_SETFOCUS, 0, 0);
+ return TRUE;
+ case DM_SETPARENT:
+ dat->hwndParent = (HWND) lParam;
+ dat->parent = (ParentWindowData *) GetWindowLongPtr(dat->hwndParent, GWLP_USERDATA);
+ SetParent(hwndDlg, dat->hwndParent);
+ return TRUE;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *mmi = (MINMAXINFO *) lParam;
+ mmi->ptMinTrackSize.x = dat->toolbarSize.cx + BOTTOM_RIGHT_AVATAR_HEIGHT;
+ mmi->ptMinTrackSize.y = dat->windowData.minLogBoxHeight + dat->toolbarSize.cy + dat->windowData.minEditBoxHeight + max(INFO_BAR_HEIGHT, BOTTOM_RIGHT_AVATAR_HEIGHT - dat->toolbarSize.cy) + 5;
+ return 0;
+ }
+ case WM_SIZE:
+ {
+ if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED) {
+ RECT rc;
+ int dlgWidth, dlgHeight;
+ dlgWidth = LOWORD(lParam);
+ dlgHeight = HIWORD(lParam);
+ /*if (dlgWidth == 0 && dlgHeight ==0) */{
+ GetClientRect(hwndDlg, &rc);
+ dlgWidth = rc.right - rc.left;
+ dlgHeight = rc.bottom - rc.top;
+ }
+ MessageDialogResize(hwndDlg, dat, dlgWidth, dlgHeight);
+ }
+ return TRUE;
+ }
+ case DM_SPLITTERMOVED:
+ {
+ POINT pt;
+ RECT rc;
+ RECT rcLog;
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SPLITTER)) {
+ int oldSplitterY;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_LOG), &rcLog);
+ GetClientRect(hwndDlg, &rc);
+ pt.x = 0;
+ pt.y = wParam;
+ ScreenToClient(hwndDlg, &pt);
+ oldSplitterY = dat->splitterPos;
+ dat->splitterPos = rc.bottom - pt.y;
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ }
+ break;
+ }
+ case DM_REMAKELOG:
+ dat->lastEventType = -1;
+ if (wParam == 0 || (HANDLE) wParam == dat->windowData.hContact) {
+ //StreamInEvents(hwndDlg, dat->hDbEventFirst, 0, 0);
+ StreamInEvents(hwndDlg, dat->hDbEventFirst, -1, 0);
+ }
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_LOG), NULL, FALSE);
+ break;
+ case DM_APPENDTOLOG: //takes wParam=hDbEvent
+ StreamInEvents(hwndDlg, (HANDLE) wParam, 1, 1);
+ break;
+ case DM_SCROLLLOGTOBOTTOM:
+ if (dat->windowData.hwndLog == NULL) {
+ SCROLLINFO si = { 0 };
+ if ((GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG), GWL_STYLE) & WS_VSCROLL) == 0)
+ break;
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
+ if (GetScrollInfo(GetDlgItem(hwndDlg, IDC_LOG), SB_VERT, &si)) {
+ if (GetDlgItem(hwndDlg, IDC_LOG) != GetFocus()) {
+// if (si.nPos + si.nPage >= si.nMax) {
+ si.fMask = SIF_POS;
+ si.nPos = si.nMax - si.nPage + 1;
+ SetScrollInfo(GetDlgItem(hwndDlg, IDC_LOG), SB_VERT, &si, TRUE);
+ PostMessage(GetDlgItem(hwndDlg, IDC_LOG), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
+ }
+ }
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_LOG), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+ } else {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_SCROLLBOTTOM;
+ ieWindow.hwnd = dat->windowData.hwndLog;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ }
+ break;
+ case HM_DBEVENTADDED:
+ if ((HANDLE) wParam == dat->windowData.hContact)
+ {
+ DBEVENTINFO dbei = { 0 };
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, lParam, (LPARAM) & dbei);
+ if (dat->hDbEventFirst == NULL)
+ dat->hDbEventFirst = (HANDLE) lParam;
+ if (DbEventIsShown(&dbei, dat)) {
+ int heFlags = HistoryEvents_GetFlags(dbei.eventType);
+ if (heFlags != -1 && (heFlags & HISTORYEVENTS_FLAG_DEFAULT))
+ heFlags = -1;
+
+ if (DbEventIsMessageOrCustom(&dbei) && !(dbei.flags & (DBEF_SENT))) {
+ /* store the event when the container is hidden so that clist notifications can be removed */
+ if (!IsWindowVisible(GetParent(hwndDlg)) && dat->hDbUnreadEventFirst == NULL)
+ dat->hDbUnreadEventFirst = (HANDLE) lParam;
+ dat->lastMessage = dbei.timestamp;
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ if (GetForegroundWindow()==dat->hwndParent && dat->parent->hwndActive == hwndDlg)
+ SkinPlaySound("RecvMsgActive");
+ else SkinPlaySound("RecvMsgInactive");
+ if ((g_dat->flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(dat->hwndParent) || GetActiveWindow() != dat->hwndParent) && IsWindowVisible(dat->hwndParent)) {
+ SendMessage(dat->hwndParent, CM_ACTIVATECHILD, 0, (LPARAM) hwndDlg);
+ }
+ if (IsAutoPopup(dat->windowData.hContact)) {
+ SendMessage(GetParent(hwndDlg), CM_POPUPWINDOW, (WPARAM) 1, (LPARAM) hwndDlg);
+ }
+ }
+ if ((HANDLE) lParam != dat->hDbEventFirst && (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, lParam, 0) == NULL)
+ SendMessage(hwndDlg, DM_APPENDTOLOG, lParam, 0);
+ else
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ if (!(dbei.flags & DBEF_SENT) && dbei.eventType != EVENTTYPE_STATUSCHANGE && dbei.eventType != EVENTTYPE_JABBER_CHATSTATES && dbei.eventType != EVENTTYPE_JABBER_PRESENCE && (heFlags == -1 || (heFlags & HISTORYEVENTS_FLAG_FLASH_MSG_WINDOW))) {
+ if (GetActiveWindow() != dat->hwndParent || GetForegroundWindow() != dat->hwndParent || dat->parent->hwndActive != hwndDlg) {
+ dat->showUnread = 1;
+ SendMessage(hwndDlg, DM_UPDATEICON, 0, 0);
+ SetTimer(hwndDlg, TIMERID_UNREAD, TIMEOUT_UNREAD, NULL);
+ }
+ SendMessage(dat->hwndParent, CM_STARTFLASHING, 0, 0);
+ }
+ }
+ }
+ break;
+ case DM_UPDATESTATUSBAR:
+ if (dat->parent->hwndActive == hwndDlg) {
+ TCHAR szText[256];
+ StatusBarData sbd= {0};
+ StatusIconData sid = {0};
+ sbd.iFlags = SBDF_TEXT | SBDF_ICON;
+ if (dat->messagesInProgress && (g_dat->flags & SMF_SHOWPROGRESS)) {
+ sbd.hIcon = GetCachedIcon("scriver_DELIVERING");
+ sbd.pszText = szText;
+ mir_sntprintf(szText, SIZEOF(szText), TranslateT("Sending in progress: %d message(s) left..."), dat->messagesInProgress);
+ } else if (dat->nTypeSecs) {
+ TCHAR *szContactName = GetNickname(dat->windowData.hContact, dat->szProto);
+ sbd.hIcon = GetCachedIcon("scriver_TYPING");
+ sbd.pszText = szText;
+ mir_sntprintf(szText, SIZEOF(szText), TranslateT("%s is typing a message..."), szContactName);
+ mir_free(szContactName);
+ dat->nTypeSecs--;
+ } else if (dat->lastMessage) {
+ TCHAR date[64], time[64];
+ tmi.printTimeStamp(NULL, dat->lastMessage, _T("d"), date, SIZEOF(date), 0);
+ tmi.printTimeStamp(NULL, dat->lastMessage, _T("t"), time, SIZEOF(time), 0);
+ mir_sntprintf(szText, SIZEOF(szText), TranslateT("Last message received on %s at %s."), date, time);
+ sbd.pszText = szText;
+ } else {
+ sbd.pszText = _T("");
+ }
+ SendMessage(dat->hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)hwndDlg);
+ UpdateReadChars(hwndDlg, dat);
+ sid.cbSize = sizeof(sid);
+ sid.szModule = SRMMMOD;
+ sid.flags = MBF_DISABLED;
+ ModifyStatusIcon((WPARAM)dat->windowData.hContact, (LPARAM) &sid);
+ sid.dwId = 1;
+ if (IsTypingNotificationSupported(dat) && g_dat->flags2 & SMF2_SHOWTYPINGSWITCH) {
+ sid.flags = (DBGetContactSettingByte(dat->windowData.hContact, SRMMMOD, SRMSGSET_TYPING,
+ DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW))) ? 0 : MBF_DISABLED;
+ } else {
+ sid.flags = MBF_HIDDEN;
+ }
+ ModifyStatusIcon((WPARAM)dat->windowData.hContact, (LPARAM) &sid);
+ }
+ break;
+ case DM_CLEARLOG:
+ // IEVIew MOD Begin
+ if (dat->windowData.hwndLog != NULL) {
+ IEVIEWEVENT event;
+ ZeroMemory(&event, sizeof(event));
+ event.cbSize = sizeof(event);
+ event.iType = IEE_CLEAR_LOG;
+ event.dwFlags = ((dat->flags & SMF_RTL) ? IEEF_RTL : 0);
+ event.hwnd = dat->windowData.hwndLog;
+ event.hContact = dat->windowData.hContact;
+ event.codepage = dat->windowData.codePage;
+ event.pszProto = dat->szProto;
+ CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
+ }
+ // IEVIew MOD End
+ SetDlgItemText(hwndDlg, IDC_LOG, _T(""));
+ dat->hDbEventFirst = NULL;
+ dat->lastEventType = -1;
+ break;
+ case WM_TIMER:
+ if (wParam == TIMERID_MSGSEND) {
+ ReportSendQueueTimeouts(hwndDlg);
+ } else if (wParam == TIMERID_TYPE) {
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON && GetTickCount() - dat->nLastTyping > TIMEOUT_TYPEOFF) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+ if (dat->showTyping) {
+ if (dat->nTypeSecs) {
+ dat->nTypeSecs--;
+ }
+ else {
+ dat->showTyping = 0;
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATEICON, 0, 0);
+ }
+ }
+ else {
+ if (dat->nTypeSecs) {
+ dat->showTyping = 1;
+ SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATEICON, 0, 0);
+ }
+ }
+ } else if (wParam == TIMERID_UNREAD) {
+ TabControlData tcd;
+ tcd.iFlags = TCDF_ICON;
+ if (!dat->showTyping) {
+ dat->showUnread++;
+ if (dat->showUnread & 1) {
+ tcd.hIcon = dat->statusIconOverlay;
+ } else {
+ tcd.hIcon = dat->statusIcon;
+ }
+ SendMessage(dat->hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)hwndDlg);
+ }
+ }
+ break;
+ case DM_SENDMESSAGE:
+ if (lParam) {
+ MessageSendQueueItem *msi = (MessageSendQueueItem *)lParam;
+ MessageSendQueueItem *item = CreateSendQueueItem(hwndDlg);
+ item->hContact = dat->windowData.hContact;
+ item->proto = mir_strdup(dat->szProto);
+ item->flags = msi->flags;
+ item->codepage = dat->windowData.codePage;
+ if ( IsUtfSendAvailable( dat->windowData.hContact )) {
+ char* szMsgUtf;
+ szMsgUtf = mir_utf8encodeW( (TCHAR *)&msi->sendBuffer[strlen(msi->sendBuffer) + 1] );
+ item->flags &= ~PREF_UNICODE;
+ if (!szMsgUtf) {
+ break;
+ }
+ if (*szMsgUtf == 0) {
+ mir_free(szMsgUtf);
+ break;
+ }
+ item->sendBufferSize = (int)strlen(szMsgUtf) + 1;
+ item->sendBuffer = szMsgUtf;
+ item->flags |= PREF_UTF;
+ } else {
+ item->sendBufferSize = msi->sendBufferSize;
+ item->sendBuffer = (char *) mir_alloc(msi->sendBufferSize);
+ memcpy(item->sendBuffer, msi->sendBuffer, msi->sendBufferSize);
+ }
+ SendMessage(hwndDlg, DM_STARTMESSAGESENDING, 0, 0);
+ SendSendQueueItem(item);
+ }
+ break;
+ case DM_STARTMESSAGESENDING:
+ dat->messagesInProgress++;
+ case DM_SHOWMESSAGESENDING:
+ SetTimer(hwndDlg, TIMERID_MSGSEND, 1000, NULL);
+ if (g_dat->flags & SMF_SHOWPROGRESS) {
+ SendMessage(dat->hwnd, DM_UPDATESTATUSBAR, 0, 0);
+ }
+ break;
+ case DM_STOPMESSAGESENDING:
+ if (dat->messagesInProgress>0) {
+ dat->messagesInProgress--;
+ if (g_dat->flags & SMF_SHOWPROGRESS) {
+ SendMessage(dat->hwnd, DM_UPDATESTATUSBAR, 0, 0);
+ }
+ }
+ if (dat->messagesInProgress == 0) {
+ KillTimer(hwndDlg, TIMERID_MSGSEND);
+ }
+ break;
+ case DM_SHOWERRORMESSAGE:
+ if (lParam) {
+ ErrorWindowData *ewd = (ErrorWindowData *) lParam;
+ SendMessage(hwndDlg, DM_STOPMESSAGESENDING, 0, 0);
+ ewd->queueItem->hwndErrorDlg = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGSENDERROR), hwndDlg, ErrorDlgProc, (LPARAM) ewd);//hwndDlg
+ }
+ break;
+ case DM_ERRORDECIDED:
+ {
+ MessageSendQueueItem *item = (MessageSendQueueItem *) lParam;
+ item->hwndErrorDlg = NULL;
+ switch (wParam) {
+ case MSGERROR_CANCEL:
+ RemoveSendQueueItem(item);
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ break;
+ case MSGERROR_RETRY:
+ SendMessage(hwndDlg, DM_STARTMESSAGESENDING, 0, 0);
+ SendSendQueueItem(item);
+ break;
+ }
+ }
+ break;
+ case WM_MEASUREITEM:
+ if (!MeasureMenuItem(wParam, lParam)) {
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ }
+ return TRUE;
+
+ case WM_DRAWITEM:
+ if (!DrawMenuItem(wParam, lParam)) {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+ if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_AVATAR)) {
+ RECT rect;
+ HDC hdcMem = CreateCompatibleDC(dis->hDC);
+ int avatarWidth = 0;
+ int avatarHeight = 0;
+ int itemWidth = dis->rcItem.right - dis->rcItem.left + 1;
+ int itemHeight = dis->rcItem.bottom - dis->rcItem.top + 1;
+ HBITMAP hbmMem = CreateCompatibleBitmap(dis->hDC, itemWidth, itemHeight);
+ hbmMem = (HBITMAP) SelectObject(hdcMem, hbmMem);
+ rect.top = 0;
+ rect.left = 0;
+ rect.right = itemWidth - 1;
+ rect.bottom = itemHeight - 1;
+ FillRect(hdcMem, &rect, GetSysColorBrush(COLOR_BTNFACE));
+
+ if (dat->avatarPic && (g_dat->flags&SMF_AVATAR)) {
+ BITMAP bminfo;
+ GetObject(dat->avatarPic, sizeof(bminfo), &bminfo);
+ if ( bminfo.bmWidth != 0 && bminfo.bmHeight != 0 ) {
+ AVATARDRAWREQUEST adr;
+ avatarHeight = itemHeight;
+ avatarWidth = bminfo.bmWidth * avatarHeight / bminfo.bmHeight;
+ if (avatarWidth > itemWidth) {
+ avatarWidth = itemWidth;
+ avatarHeight = bminfo.bmHeight * avatarWidth / bminfo.bmWidth;
+ }
+ ZeroMemory(&adr, sizeof(adr));
+ adr.cbSize = sizeof (AVATARDRAWREQUEST);
+ adr.hContact = dat->windowData.hContact;
+ adr.hTargetDC = hdcMem;
+ adr.rcDraw.left = (itemWidth - avatarWidth) / 2;
+ adr.rcDraw.top = (itemHeight - avatarHeight) / 2;
+ adr.rcDraw.right = avatarWidth - 1;
+ adr.rcDraw.bottom = avatarHeight - 1;
+ adr.dwFlags = AVDRQ_DRAWBORDER | AVDRQ_HIDEBORDERONTRANSPARENCY;
+
+ CallService(MS_AV_DRAWAVATAR, (WPARAM)0, (LPARAM)&adr);
+ }
+ }
+ BitBlt(dis->hDC, 0, 0, itemWidth, itemHeight, hdcMem, 0, 0, SRCCOPY);
+ hbmMem = (HBITMAP) SelectObject(hdcMem, hbmMem);
+ DeleteObject(hbmMem);
+ DeleteDC(hdcMem);
+ return TRUE;
+ }
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ }
+ case WM_COMMAND:
+ if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM) dat->windowData.hContact))
+ break;
+ switch (LOWORD(wParam)) {
+ case IDC_SENDALL:
+ {
+ int result;
+ if (dat->sendAllConfirm == 0) {
+ result = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CONFIRM_SENDALL), hwndDlg, ConfirmSendAllDlgProc, (LPARAM)hwndDlg);
+ if (result & 0x10000) {
+ dat->sendAllConfirm = result;
+ }
+ } else {
+ result = dat->sendAllConfirm;
+ }
+ if (LOWORD(result) != IDYES) {
+ break;
+ }
+
+ }
+ case IDOK:
+ //this is a 'send' button
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDOK)))
+ break;
+ //if (GetKeyState(VK_CTRL) & 0x8000) { // copy user name
+ //SendMessage(hwndDlg, DM_USERNAMETOCLIP, 0, 0);
+ //}
+ if (dat->windowData.hContact != NULL) {
+ GETTEXTEX gt = {0};
+ PARAFORMAT2 pf2;
+ MessageSendQueueItem msi = { 0 };
+ int bufSize;
+ int ansiBufSize = GetRichTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE), dat->windowData.codePage, TRUE) + 1;
+ bufSize = ansiBufSize;
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_RTLPARA;
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_GETPARAFORMAT, 0, (LPARAM)&pf2);
+ if (pf2.wEffects & PFE_RTLPARA)
+ msi.flags |= PREF_RTL;
+ bufSize += GetRichTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE), 1200, TRUE) + 2;
+
+ msi.sendBufferSize = bufSize;
+ msi.sendBuffer = (char *) mir_alloc(msi.sendBufferSize);
+ msi.flags |= PREF_TCHAR;
+
+ gt.flags = GT_USECRLF;
+ gt.cb = ansiBufSize;
+ gt.codepage = dat->windowData.codePage;
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_GETTEXTEX, (WPARAM) >, (LPARAM) msi.sendBuffer);
+ gt.cb = bufSize - ansiBufSize;
+ gt.codepage = 1200;
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_GETTEXTEX, (WPARAM) >, (LPARAM) &msi.sendBuffer[ansiBufSize]);
+ if ( RTL_Detect((wchar_t *)&msi.sendBuffer[ansiBufSize] ))
+ msi.flags |= PREF_RTL;
+
+ if (msi.sendBuffer[0] == 0) {
+ mir_free (msi.sendBuffer);
+ break;
+ }
+ {
+ /* Store messaging history */
+ char *msgText = GetRichTextEncoded(GetDlgItem(hwndDlg, IDC_MESSAGE), dat->windowData.codePage);
+ TCmdList *cmdListNew = tcmdlist_last(dat->windowData.cmdList);
+ while (cmdListNew != NULL && cmdListNew->temporary) {
+ dat->windowData.cmdList = tcmdlist_remove(dat->windowData.cmdList, cmdListNew);
+ cmdListNew = tcmdlist_last(dat->windowData.cmdList);
+ }
+ if (msgText != NULL) {
+ dat->windowData.cmdList = tcmdlist_append(dat->windowData.cmdList, msgText, 20, FALSE);
+ mir_free(msgText);
+ }
+ dat->windowData.cmdListCurrent = NULL;
+ }
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON)
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+
+ SetDlgItemText(hwndDlg, IDC_MESSAGE, _T(""));
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOMIN, SRMSGDEFSET_AUTOMIN))
+ ShowWindow(dat->hwndParent, SW_MINIMIZE);
+ if (LOWORD(wParam) == IDC_SENDALL) {
+ SendMessage(dat->hwndParent, DM_SENDMESSAGE, 0, (LPARAM) &msi);
+ } else {
+ SendMessage(hwndDlg, DM_SENDMESSAGE, 0, (LPARAM) &msi);
+ }
+ mir_free (msi.sendBuffer);
+ }
+ return TRUE;
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ case IDC_USERMENU:
+ {
+ if (GetKeyState(VK_SHIFT) & 0x8000) { // copy user name
+ SendMessage(hwndDlg, DM_USERNAMETOCLIP, 0, 0);
+ } else {
+ RECT rc;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) dat->windowData.hContact, 0);
+ GetWindowRect(GetDlgItem(hwndDlg, LOWORD(wParam)), &rc);
+ TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+ }
+ }
+ break;
+ case IDC_HISTORY:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM) dat->windowData.hContact, 0);
+ break;
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG, (WPARAM) dat->windowData.hContact, 0);
+ break;
+ case IDC_SMILEYS:
+ if (g_dat->smileyAddInstalled) {
+ SMADD_SHOWSEL3 smaddInfo;
+ RECT rc;
+ smaddInfo.cbSize = sizeof(SMADD_SHOWSEL3);
+ smaddInfo.hwndParent = dat->hwndParent;
+ smaddInfo.hwndTarget = GetDlgItem(hwndDlg, IDC_MESSAGE);
+ smaddInfo.targetMessage = EM_REPLACESEL;
+ smaddInfo.targetWParam = TRUE;
+ smaddInfo.Protocolname = dat->szProto;
+ if (dat->szProto!=NULL && strcmp(dat->szProto,"MetaContacts")==0) {
+ HANDLE hContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) dat->windowData.hContact, 0);
+ if (hContact!=NULL) {
+ smaddInfo.Protocolname = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ }
+ }
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_SMILEYS), &rc);
+ smaddInfo.Direction = 0;
+ smaddInfo.xPosition = rc.left;
+ smaddInfo.yPosition = rc.bottom;
+ smaddInfo.hContact = dat->windowData.hContact;
+ CallService(MS_SMILEYADD_SHOWSELECTION, 0, (LPARAM) &smaddInfo);
+ }
+ break;
+ case IDC_QUOTE:
+ {
+ DBEVENTINFO dbei = { 0 };
+ SETTEXTEX st;
+ TCHAR *buffer = NULL;
+ st.flags = ST_SELECTION;
+ st.codepage = 1200;
+
+ if (dat->hDbEventLast==NULL) break;
+ if (dat->windowData.hwndLog != NULL) {
+ buffer = GetIEViewSelection(dat);
+ } else {
+ buffer = GetRichEditSelection(GetDlgItem(hwndDlg, IDC_LOG));
+ }
+ if (buffer!=NULL) {
+ TCHAR *quotedBuffer = GetQuotedTextW(buffer);
+ SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), EM_SETTEXTEX, (WPARAM) &st, (LPARAM)quotedBuffer);
+ mir_free(quotedBuffer);
+ mir_free(buffer);
+ } else {
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM) dat->hDbEventLast, 0);
+ if (dbei.cbBlob == 0xFFFFFFFF) break;
+ dbei.pBlob = (PBYTE) mir_alloc(dbei.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM) dat->hDbEventLast, (LPARAM) & dbei);
+ if (DbEventIsMessageOrCustom(&dbei) || dbei.eventType == EVENTTYPE_STATUSCHANGE) {
+ TCHAR *buffer = DbGetEventTextT( &dbei, CP_ACP );
+ if (buffer!=NULL) {
+ TCHAR *quotedBuffer = GetQuotedTextW(buffer);
+ SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), EM_SETTEXTEX, (WPARAM) &st, (LPARAM)quotedBuffer);
+ mir_free(quotedBuffer);
+ mir_free(buffer);
+ }
+ }
+ mir_free(dbei.pBlob);
+ }
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ break;
+ }
+ case IDC_ADD:
+ {
+ ADDCONTACTSTRUCT acs = { 0 };
+
+ acs.handle = dat->windowData.hContact;
+ acs.handleType = HANDLE_CONTACT;
+ acs.szProto = 0;
+ CallService(MS_ADDCONTACT_SHOW, (WPARAM) hwndDlg, (LPARAM) & acs);
+ }
+ if (!DBGetContactSettingByte(dat->windowData.hContact, "CList", "NotOnList", 0)) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE);
+ }
+ case IDC_MESSAGE:
+ if (HIWORD(wParam) == EN_CHANGE) {
+ int len = GetRichTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE), dat->windowData.codePage, FALSE);
+ dat->windowData.cmdListCurrent = NULL;
+ UpdateReadChars(hwndDlg, dat);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), len != 0);
+ if (!(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) {
+ dat->nLastTyping = GetTickCount();
+ if (len != 0) {
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_OFF) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_ON);
+ }
+ } else {
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR pNmhdr;
+ pNmhdr = (LPNMHDR)lParam;
+ switch (pNmhdr->idFrom) {
+ case IDC_LOG:
+ switch (pNmhdr->code) {
+ case EN_MSGFILTER:
+ {
+ int result = InputAreaShortcuts(GetDlgItem(hwndDlg, IDC_MESSAGE), ((MSGFILTER *) lParam)->msg, ((MSGFILTER *) lParam)->wParam, ((MSGFILTER *) lParam)->lParam, &dat->windowData);
+ if (result != -1) {
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ }
+ switch (((MSGFILTER *) lParam)->msg) {
+ case WM_CHAR:
+ if (!(GetKeyState(VK_CONTROL) & 0x8000)) {
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), ((MSGFILTER *) lParam)->msg, ((MSGFILTER *) lParam)->wParam, ((MSGFILTER *) lParam)->lParam);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ }
+ return TRUE;
+ case WM_LBUTTONDOWN:
+ {
+ HCURSOR hCur = GetCursor();
+ if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE)
+ || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) {
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ }
+ case WM_MOUSEMOVE:
+ {
+ HCURSOR hCur = GetCursor();
+ if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE)
+ || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE))
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ break;
+ }
+ case WM_RBUTTONUP:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ case EN_LINK:
+ switch (((ENLINK *) lParam)->msg) {
+ case WM_SETCURSOR:
+ SetCursor(hCurHyperlinkHand);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ if (HandleLinkClick(g_hInst, hwndDlg, GetDlgItem(hwndDlg, IDC_MESSAGE),(ENLINK*)lParam)) {
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ }
+ }
+ break;
+ case IDC_MESSAGE:
+ switch (((NMHDR *) lParam)->code) {
+ case EN_MSGFILTER:
+ switch (((MSGFILTER *) lParam)->msg) {
+ case WM_RBUTTONUP:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ case EN_REQUESTRESIZE:
+ {
+ REQRESIZE *rr = (REQRESIZE *)lParam;
+ int height = rr->rc.bottom - rr->rc.top + 1;
+ if (height < g_dat->minInputAreaHeight) {
+ height = g_dat->minInputAreaHeight;
+ }
+ if (dat->desiredInputAreaHeight != height) {
+ dat->desiredInputAreaHeight = height;
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ PostMessage(hwndDlg, DM_SCROLLLOGTOBOTTOM, 0, 0);
+ }
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case WM_CHAR:
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), msg, wParam, lParam);
+ break;
+ case WM_DESTROY:
+ NotifyLocalWinEvent(dat->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_CLOSING);
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)dat->statusIcon, 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)dat->statusIconBig , 0);
+ if (dat->statusIconOverlay != NULL) DestroyIcon(dat->statusIconOverlay);
+ dat->statusIcon = NULL;
+ dat->statusIconOverlay = NULL;
+ ReleaseSendQueueItems(hwndDlg);
+ if (g_dat->flags & SMF_SAVEDRAFTS) {
+ saveDraftMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), dat->windowData.hContact, dat->windowData.codePage);
+ } else {
+ g_dat->draftList = tcmdlist_remove2(g_dat->draftList, dat->windowData.hContact);
+ }
+ tcmdlist_free(dat->windowData.cmdList);
+ WindowList_Remove(g_dat->hMessageWindowList, hwndDlg);
+ UnsubclassMessageEdit(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ UnsubclassLogEdit(GetDlgItem(hwndDlg, IDC_LOG));
+ {
+ HFONT hFont;
+ hFont = (HFONT) SendDlgItemMessage(hwndDlg, IDC_MESSAGE, WM_GETFONT, 0, 0);
+ if (hFont != NULL && hFont != (HFONT) SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0))
+ DeleteObject(hFont);
+ }
+ DBWriteContactSettingByte(dat->windowData.hContact, SRMMMOD, "UseRTL", (BYTE) ((dat->flags & SMF_RTL) ? 1 : 0));
+ DBWriteContactSettingWord(dat->windowData.hContact, SRMMMOD, "CodePage", (WORD) dat->windowData.codePage);
+ if (dat->windowData.hContact && (g_dat->flags & SMF_DELTEMP)) {
+ if (DBGetContactSettingByte(dat->windowData.hContact, "CList", "NotOnList", 0)) {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)dat->windowData.hContact, 0);
+ }
+ }
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
+ SendMessage(dat->hwndParent, CM_REMOVECHILD, 0, (LPARAM) hwndDlg);
+ if (dat->windowData.hwndLog != NULL) {
+ IEVIEWWINDOW ieWindow;
+ ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+ ieWindow.iType = IEW_DESTROY;
+ ieWindow.hwnd = dat->windowData.hwndLog;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ }
+ NotifyLocalWinEvent(dat->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_CLOSE);
+ mir_free(dat);
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/Scriver/src/msglog.cpp b/plugins/Scriver/src/msglog.cpp new file mode 100644 index 0000000000..bb768cbb95 --- /dev/null +++ b/plugins/Scriver/src/msglog.cpp @@ -0,0 +1,1208 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+
+#define MIRANDA_0_5
+
+#define LOGICON_MSG_IN 0
+#define LOGICON_MSG_OUT 1
+#define LOGICON_MSG_NOTICE 2
+
+extern int RTL_Detect(WCHAR *pszwText);
+static int logPixelSY;
+static PBYTE pLogIconBmpBits[3];
+static int logIconBmpSize[SIZEOF(pLogIconBmpBits)];
+static HIMAGELIST g_hImageList;
+
+#define STREAMSTAGE_HEADER 0
+#define STREAMSTAGE_EVENTS 1
+#define STREAMSTAGE_TAIL 2
+#define STREAMSTAGE_STOP 3
+
+typedef struct EventDataStruct {
+ int cbSize;
+ int iType;
+ DWORD dwFlags;
+ const char *fontName;
+ int fontSize;
+ int fontStyle;
+ COLORREF color;
+ union {
+ char *pszNick; // Nick, usage depends on type of event
+ wchar_t *pszNickW; // Nick - Unicode
+ TCHAR *pszNickT;
+ };
+ union {
+ char *pszText; // Text, usage depends on type of event
+ wchar_t *pszTextW; // Text - Unicode
+ TCHAR *pszTextT;
+ };
+ union {
+ char *pszText2; // Text, usage depends on type of event
+ wchar_t *pszText2W; // Text - Unicode
+ TCHAR *pszText2T;
+ };
+ DWORD time;
+ DWORD eventType;
+ int codePage;
+ BOOL custom;
+ struct EventDataStruct *next;
+}EventData;
+
+struct LogStreamData {
+ int stage;
+ HANDLE hContact;
+ HANDLE hDbEvent, hDbEventLast;
+ char *buffer;
+ int bufferOffset, bufferLen;
+ int eventsToInsert;
+ int isFirst;
+ struct SrmmWindowData *dlgDat;
+ struct GlobalMessageData *gdat;
+ EventData *events;
+};
+
+TCHAR *GetNickname(HANDLE hContact, const char* szProto) {
+ char * szBaseNick;
+ TCHAR *szName = NULL;
+ CONTACTINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+ ci.szProto = (char *)szProto;
+ ci.dwFlag = CNF_DISPLAY;
+ if (IsUnicodeMIM()) {
+ ci.dwFlag |= CNF_UNICODE;
+ }
+
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ if (ci.type == CNFT_ASCIIZ) {
+ if (ci.pszVal) {
+ if (IsUnicodeMIM()) {
+ if (!_tcscmp((TCHAR *)ci.pszVal, TranslateW(_T("'(Unknown Contact)'")))) {
+ ci.dwFlag &= ~CNF_UNICODE;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ szName = a2t((char *)ci.pszVal);
+ }
+ } else {
+ szName = mir_tstrdup((TCHAR *)ci.pszVal);
+ }
+ } else {
+ szName = a2t((char *)ci.pszVal);
+ }
+
+ mir_free(ci.pszVal);
+ if (szName != NULL) {
+ return szName;
+ }
+ }
+ }
+ }
+ szBaseNick = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0);
+ if (szBaseNick != NULL) {
+ int len;
+ len = (int)strlen(szBaseNick) + 1;
+ szName = (TCHAR *) mir_alloc(len * 2);
+ MultiByteToWideChar(CP_ACP, 0, szBaseNick, -1, szName, len);
+ szName[len - 1] = 0;
+ return szName;
+ }
+ return mir_tstrdup(TranslateT("Unknown Contact"));
+}
+
+int DbEventIsCustomForMsgWindow(DBEVENTINFO *dbei)
+{
+ DBEVENTTYPEDESCR* et = ( DBEVENTTYPEDESCR* )CallService( MS_DB_EVENT_GETTYPE, ( WPARAM )dbei->szModule, ( LPARAM )dbei->eventType );
+ return et && ( et->flags & DETF_MSGWINDOW );
+}
+
+int DbEventIsMessageOrCustom(DBEVENTINFO* dbei)
+{
+ return dbei->eventType == EVENTTYPE_MESSAGE || DbEventIsCustomForMsgWindow(dbei);
+}
+
+int DbEventIsShown(DBEVENTINFO * dbei, struct SrmmWindowData *dat)
+{
+ int heFlags;
+
+ switch (dbei->eventType) {
+ case EVENTTYPE_MESSAGE:
+ return 1;
+ case EVENTTYPE_STATUSCHANGE:
+ case EVENTTYPE_JABBER_CHATSTATES:
+ case EVENTTYPE_JABBER_PRESENCE:
+ if (!DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, SRMSGDEFSET_SHOWSTATUSCH)) {
+// if (dbei->flags & DBEF_READ)
+ return 0;
+ }
+ return 1;
+ case EVENTTYPE_FILE:
+ case EVENTTYPE_URL:
+// if (dat->hwndLog != NULL)
+ return 1;
+ }
+
+ heFlags = HistoryEvents_GetFlags(dbei->eventType);
+ if (heFlags != -1)
+ return (heFlags & HISTORYEVENTS_FLAG_SHOW_IM_SRMM) == HISTORYEVENTS_FLAG_SHOW_IM_SRMM;
+ return DbEventIsCustomForMsgWindow(dbei);
+}
+
+EventData *getEventFromDB(struct SrmmWindowData *dat, HANDLE hContact, HANDLE hDbEvent) {
+ DBEVENTINFO dbei = { 0 };
+ EventData *event;
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM) hDbEvent, 0);
+ if (dbei.cbBlob == -1) return NULL;
+ dbei.pBlob = (PBYTE) mir_alloc(dbei.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) & dbei);
+ if (!DbEventIsShown(&dbei, dat)) {
+ mir_free(dbei.pBlob);
+ return NULL;
+ }
+ event = (EventData *) mir_alloc(sizeof(EventData));
+ memset(event, 0, sizeof(EventData));
+ event->custom = DbEventIsCustomForMsgWindow(&dbei);
+ if (!(dbei.flags & DBEF_SENT) && (dbei.eventType == EVENTTYPE_MESSAGE || dbei.eventType == EVENTTYPE_URL || event->custom)) {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM) hContact, (LPARAM) hDbEvent);
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM) hContact, (LPARAM) hDbEvent);
+ } else if (dbei.eventType == EVENTTYPE_STATUSCHANGE || dbei.eventType == EVENTTYPE_JABBER_CHATSTATES ||
+ dbei.eventType == EVENTTYPE_JABBER_PRESENCE) {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM) hContact, (LPARAM) hDbEvent);
+ }
+ event->eventType = event->custom ? EVENTTYPE_MESSAGE : dbei.eventType;
+ event->dwFlags = (dbei.flags & DBEF_READ ? IEEDF_READ : 0) | (dbei.flags & DBEF_SENT ? IEEDF_SENT : 0) | (dbei.flags & DBEF_RTL ? IEEDF_RTL : 0);
+ event->dwFlags |= IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2;
+
+ if ( dat->flags & SMF_RTL) {
+ event->dwFlags |= IEEDF_RTL;
+ }
+ event->time = dbei.timestamp;
+ event->pszNick = NULL;
+ event->codePage = dat->windowData.codePage;
+
+ if (event->dwFlags & IEEDF_SENT) {
+ event->pszNickT = GetNickname(NULL, dat->szProto);
+ } else {
+ event->pszNickT = GetNickname(hContact, dat->szProto);
+ }
+
+ if (event->eventType == EVENTTYPE_FILE) {
+ char* filename = ((char *)dbei.pBlob) + sizeof(DWORD);
+ char* descr = filename + lstrlenA( filename ) + 1;
+ event->pszTextT = DbGetEventStringT(&dbei, filename);
+ if ( *descr != 0 ) {
+ event->pszText2T = DbGetEventStringT(&dbei, descr);
+ }
+ } else {
+ event->pszTextT = DbGetEventTextT( &dbei, dat->windowData.codePage );
+ }
+ if ( !(dat->flags & SMF_RTL)) {
+ if ( RTL_Detect(event->pszTextT)) {
+ event->dwFlags |= IEEDF_RTL;
+ }
+ }
+
+ mir_free(dbei.pBlob);
+ return event;
+}
+
+static EventData *GetTestEvent(DWORD flags)
+{
+ EventData *event = (EventData *) mir_alloc(sizeof(EventData));
+ memset(event, 0, sizeof(EventData));
+ event->eventType = EVENTTYPE_MESSAGE;
+ event->dwFlags = IEEDF_READ | flags;
+ event->dwFlags |= IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2;
+ event->time = time(NULL);
+ event->codePage = CP_ACP;
+ return event;
+}
+
+static EventData *GetTestEvents()
+{
+ EventData *event, *firstEvent, *prevEvent;
+ firstEvent = prevEvent = event = GetTestEvent(IEEDF_SENT);
+ event->pszNickT = mir_tstrdup(_T("Me"));
+ event->pszTextT = mir_tstrdup(_T("O Lord, bless this Thy hand grenade that with it Thou mayest blow Thine enemies"));
+ event = GetTestEvent(IEEDF_SENT);
+ event->pszNickT = mir_tstrdup(_T("Me"));
+ event->pszTextT = mir_tstrdup(_T("to tiny bits, in Thy mercy"));
+ prevEvent->next = event;
+ prevEvent = event;
+ event = GetTestEvent(0);
+ event->pszNickT = mir_tstrdup(_T("My Contact"));
+ event->pszTextT = mir_tstrdup(_T("Lorem ipsum dolor sit amet,"));
+ prevEvent->next = event;
+ prevEvent = event;
+ event = GetTestEvent(0);
+ event->pszNickT = mir_tstrdup(_T("My Contact"));
+ event->pszTextT = mir_tstrdup(_T("consectetur adipisicing elit"));
+ prevEvent->next = event;
+ prevEvent = event;
+ return firstEvent;
+}
+
+static void freeEvent(EventData *event) {
+ if (event->pszNickT != NULL) mir_free (event->pszNickT);
+ if (event->pszTextT != NULL) mir_free (event->pszTextT);
+ if (event->pszText2T != NULL) mir_free (event->pszText2T);
+ mir_free(event);
+}
+
+static int AppendUnicodeOrAnsiiToBufferL(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, WCHAR * line, int maxLen, BOOL isAnsii)
+{
+ int textCharsCount = 0;
+ char *d;
+ int wasEOL = 0;
+ WCHAR *maxLine = line + maxLen;
+ int lineLen = (int)wcslen(line) * 9 + 8;
+ if (*cbBufferEnd + lineLen > *cbBufferAlloced) {
+ cbBufferAlloced[0] += (lineLen + 1024 - lineLen % 1024);
+ *buffer = (char *) mir_realloc(*buffer, *cbBufferAlloced);
+ }
+
+ d = *buffer + *cbBufferEnd;
+ if (isAnsii) {
+ strcpy(d, "{");
+ d++;
+ } else {
+ strcpy(d, "{\\uc1 ");
+ d += 6;
+ }
+
+ for (; *line && (maxLen < 0 || line < maxLine); line++, textCharsCount++) {
+ wasEOL = 0;
+ if (*line == '\r' && line[1] == '\n') {
+ CopyMemory(d, "\\line ", 6);
+ wasEOL = 1;
+ d += 6;
+ line++;
+ }
+ else if (*line == '\n') {
+ CopyMemory(d, "\\line ", 6);
+ wasEOL = 1;
+ d += 6;
+ }
+ else if (*line == '\t') {
+ CopyMemory(d, "\\tab ", 5);
+ d += 5;
+ }
+ else if (*line == '\\' || *line == '{' || *line == '}') {
+ *d++ = '\\';
+ *d++ = (char) *line;
+ }
+ else if (*line < 128) {
+ *d++ = (char) *line;
+ }
+ else if (isAnsii) {
+ d += sprintf(d, "\\'%02x", (*line) & 0xFF);
+ }
+ else {
+ d += sprintf(d, "\\u%d ?", *line);
+ }
+ }
+ if (wasEOL) {
+ CopyMemory(d, " ", 1);
+ d++;
+ }
+ strcpy(d, "}");
+ d++;
+
+ *cbBufferEnd = (int) (d - *buffer);
+ return textCharsCount;
+}
+
+static int AppendAnsiToBufferL(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, const char * line, int maxLen)
+{
+ WCHAR *wline = a2w(line, maxLen);
+ int i = AppendUnicodeOrAnsiiToBufferL(buffer, cbBufferEnd, cbBufferAlloced, wline, maxLen, TRUE);
+ mir_free(wline);
+ return i;
+}
+
+static int AppendUnicodeToBufferL(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, WCHAR * line, int maxLen)
+{
+ return AppendUnicodeOrAnsiiToBufferL(buffer, cbBufferEnd, cbBufferAlloced, line, maxLen, FALSE);
+}
+
+static int AppendAnsiToBuffer(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, const char * line)
+{
+ return AppendAnsiToBufferL(buffer, cbBufferEnd, cbBufferAlloced, line, -1);
+}
+
+static int AppendUnicodeToBuffer(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, WCHAR * line)
+{
+ return AppendUnicodeToBufferL(buffer, cbBufferEnd, cbBufferAlloced, line, -1);
+}
+
+static int AppendTToBuffer(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, TCHAR * line)
+{
+ return AppendUnicodeToBuffer(buffer, cbBufferEnd, cbBufferAlloced, line);
+}
+
+//mir_free() the return value
+static char *CreateRTFHeader(struct SrmmWindowData *dat, struct GlobalMessageData *gdat)
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd;
+ int i;
+ LOGFONT lf;
+ COLORREF colour;
+ HDC hdc;
+ int charset = 0;
+ BOOL forceCharset = FALSE;
+
+ hdc = GetDC(NULL);
+ logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ bufferEnd = 0;
+ bufferAlloced = 1024;
+ buffer = (char *) mir_alloc(bufferAlloced);
+ buffer[0] = '\0';
+ if (dat->flags & SMF_RTL)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced,"{\\rtf1\\ansi\\deff0{\\fonttbl");
+ else
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\rtf1\\ansi\\deff0{\\fonttbl");
+ for (i = 0; i < fontOptionsListSize; i++) {
+ LoadMsgDlgFont(i, &lf, NULL, FALSE);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\f%u\\fnil\\fcharset%u " TCHAR_STR_PARAM ";}", i,
+ (!forceCharset) ? lf.lfCharSet : charset, lf.lfFaceName);
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}{\\colortbl ");
+ for (i = 0; i < fontOptionsListSize; i++) {
+ LoadMsgDlgFont(i, NULL, &colour, FALSE);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ }
+ if (GetSysColorBrush(COLOR_HOTLIGHT) == NULL)
+ colour = RGB(0, 0, 255);
+ else
+ colour = GetSysColor(COLOR_HOTLIGHT);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INCOMINGBKGCOLOUR, SRMSGDEFSET_INCOMINGBKGCOLOUR);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_OUTGOINGBKGCOLOUR, SRMSGDEFSET_OUTGOINGBKGCOLOUR);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ colour = gdat->logLineColour;
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}");
+// AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\li30\\ri30\\fi0\\tx0");
+ return buffer;
+}
+
+//mir_free() the return value
+static char *CreateRTFTail()
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd;
+
+ bufferEnd = 0;
+ bufferAlloced = 1024;
+ buffer = (char *) mir_alloc(bufferAlloced);
+ buffer[0] = '\0';
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}");
+ return buffer;
+}
+
+//return value is static
+static char *SetToStyle(int style)
+{
+ static char szStyle[128];
+ LOGFONT lf;
+
+ LoadMsgDlgFont(style, &lf, NULL, FALSE);
+ wsprintfA(szStyle, "\\f%u\\cf%u\\b%d\\i%d\\fs%u", style, style, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / logPixelSY);
+ return szStyle;
+}
+
+// mode: 0 - date & time, 1 - date, 2 - time
+
+TCHAR *TimestampToString(DWORD dwFlags, time_t check, int mode)
+{
+ static TCHAR szResult[512];
+ TCHAR str[80];
+ TCHAR format[20];
+
+ szResult[0] = '\0';
+ format[0] = '\0';
+ if ((mode == 0 || mode == 1) && (dwFlags & SMF_SHOWDATE)) {
+ struct tm tm_now, tm_today;
+ time_t now = time(NULL);
+ time_t today;
+ tm_now = *localtime(&now);
+ tm_today = tm_now;
+ tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0;
+ today = mktime(&tm_today);
+
+ if (dwFlags & SMF_RELATIVEDATE && check >= today) {
+ lstrcpy(szResult, TranslateT("Today"));
+ if (mode == 0) {
+ lstrcat(szResult, _T(","));
+ }
+ } else if (dwFlags & SMF_RELATIVEDATE && check > (today - 86400)) {
+ lstrcpy(szResult, TranslateT("Yesterday"));
+ if (mode == 0) {
+ lstrcat(szResult, _T(","));
+ }
+ } else {
+ if (dwFlags & SMF_LONGDATE)
+ lstrcpy(format, _T("D"));
+ else
+ lstrcpy(format, _T("d"));
+ }
+ }
+ if (mode == 0 || mode == 2) {
+ if (mode == 0 && (dwFlags & SMF_SHOWDATE)) {
+ lstrcat(format, _T(" "));
+ }
+ lstrcat(format, (dwFlags & SMF_SHOWSECONDS) ? _T("s") : _T("t"));
+ }
+ if (format[0] != '\0') {
+ tmi.printTimeStamp(NULL, check, format, str, SIZEOF(str), 0);
+ _tcsncat(szResult, str, 500);
+ }
+ return szResult;
+}
+
+int isSameDate(time_t time1, time_t time2)
+{
+ struct tm tm_t1, tm_t2;
+ tm_t1 = *localtime((time_t *)(&time1));
+ tm_t2 = *localtime((time_t *)(&time2));
+ if (tm_t1.tm_year == tm_t2.tm_year && tm_t1.tm_mon == tm_t2.tm_mon
+ && tm_t1.tm_mday == tm_t2.tm_mday) {
+ return 1;
+ }
+ return 0;
+}
+
+static int DetectURL(wchar_t *text, BOOL firstChar) {
+ wchar_t c;
+ struct prefix_s {
+ wchar_t *text;
+ int length;
+ } prefixes[12] = {
+ {L"http:", 5},
+ {L"file:", 5},
+ {L"mailto:", 7},
+ {L"ftp:", 4},
+ {L"https:", 6},
+ {L"gopher:", 7},
+ {L"nntp:", 5},
+ {L"prospero:", 9},
+ {L"telnet:", 7},
+ {L"news:", 5},
+ {L"wais:", 5},
+ {L"www.", 4}
+ };
+ c = firstChar ? ' ' : text[-1];
+ if (!((c >= '0' && c<='9') || (c >= 'A' && c<='Z') || (c >= 'a' && c<='z'))) {
+ int found = 0;
+ int i, len = 0;
+ int prefixlen = SIZEOF(prefixes);
+ for (i = 0; i < prefixlen; i++) {
+ if (!wcsncmp(text, prefixes[i].text, prefixes[i].length)) {
+ len = prefixes[i].length;
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ for (; text[len]!='\n' && text[len]!='\r' && text[len]!='\t' && text[len]!=' ' && text[len]!='\0'; len++);
+ for (; len > 0; len --) {
+ if ((text[len-1] >= '0' && text[len-1]<='9') || iswalpha(text[len-1])) {
+ break;
+ }
+ }
+ return len;
+ }
+ }
+ return 0;
+}
+
+static void AppendWithCustomLinks(EventData *event, int style, char **buffer, int *bufferEnd, int *bufferAlloced) {
+ int lasttoken = 0;
+ int laststart = 0;
+ int j, len;
+ WCHAR *wText;
+ BOOL isAnsii = (event->dwFlags & IEEDF_UNICODE_TEXT) == 0;
+
+ if ( event->pszText == NULL )
+ return;
+
+ if (isAnsii) {
+ len = (int)strlen(event->pszText);
+ wText = a2w(event->pszText, len);
+ } else {
+ wText = event->pszTextW;
+ len = (int)wcslen(event->pszTextW);
+ }
+ for (j = 0; j < len ; j++) {
+ int newtoken = 0;
+ int l = DetectURL(wText + j, j==0);
+ if (l > 0) {
+ newtoken = 1;
+ }
+ if (j == 0) {
+ lasttoken = newtoken;
+ }
+ if (newtoken != lasttoken) {
+ if (lasttoken == 0) {
+ AppendToBuffer(buffer, bufferEnd, bufferAlloced, "%s ", SetToStyle(style));
+ } else {
+ AppendToBuffer(buffer, bufferEnd, bufferAlloced, "%s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYURL : MSGFONTID_YOURURL));
+ }
+ AppendUnicodeOrAnsiiToBufferL(buffer, bufferEnd, bufferAlloced, wText + laststart, j - laststart, isAnsii);
+ laststart = j;
+ lasttoken = newtoken;
+ }
+ }
+ if (len - laststart > 0) {
+ if (lasttoken == 0) {
+ AppendToBuffer(buffer, bufferEnd, bufferAlloced, "%s ", SetToStyle(style));
+ } else {
+ AppendToBuffer(buffer, bufferEnd, bufferAlloced, "%s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYURL : MSGFONTID_YOURURL));
+ }
+ AppendUnicodeOrAnsiiToBufferL(buffer, bufferEnd, bufferAlloced, wText + laststart, len - laststart, isAnsii);
+ }
+ if (isAnsii) {
+ mir_free(wText);
+ }
+}
+
+//mir_free() the return value
+static char *CreateRTFFromEvent(struct SrmmWindowData *dat, EventData *event, struct GlobalMessageData *gdat, struct LogStreamData *streamData)
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd;
+ int style, showColon = 0;
+ int isGroupBreak = TRUE;
+ int highlight = 0;
+ int heFlags = -1;
+ bufferEnd = 0;
+ bufferAlloced = 1024;
+ buffer = (char *) mir_alloc(bufferAlloced);
+ buffer[0] = '\0';
+
+ heFlags = HistoryEvents_GetFlags((WORD) event->eventType);
+ if (heFlags != -1 && (heFlags & HISTORYEVENTS_FLAG_DEFAULT))
+ heFlags = -1;
+
+ if ((gdat->flags & SMF_GROUPMESSAGES) && event->dwFlags == LOWORD(dat->lastEventType)
+ && event->eventType == EVENTTYPE_MESSAGE && HIWORD(dat->lastEventType) == EVENTTYPE_MESSAGE
+ && (isSameDate(event->time, dat->lastEventTime))
+// && ((dbei.timestamp - dat->lastEventTime) < 86400)
+ && ((((int)event->time < dat->startTime) == (dat->lastEventTime < dat->startTime)) || !(event->dwFlags & IEEDF_READ))) {
+ isGroupBreak = FALSE;
+ }
+ if (!streamData->isFirst && !dat->isMixed) {
+ if (isGroupBreak || gdat->flags & SMF_MARKFOLLOWUPS) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\par");
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\line");
+ }
+ }
+ if (event->dwFlags & IEEDF_RTL) {
+ dat->isMixed = 1;
+ }
+ if (!streamData->isFirst && isGroupBreak && (gdat->flags & SMF_DRAWLINES)) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\sl-1\\slmult0\\highlight%d\\cf%d\\fs1 \\par\\sl0", fontOptionsListSize + 4, fontOptionsListSize + 4);
+ }
+ if ( streamData->isFirst ) {
+ if (event->dwFlags & IEEDF_RTL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\rtlpar");
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\ltrpar");
+ }
+ } else {
+ if (event->dwFlags & IEEDF_RTL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\rtlpar");
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\ltrpar");
+ }
+ }
+ if (event->eventType == EVENTTYPE_MESSAGE) {
+ highlight = fontOptionsListSize + 2 + ((event->dwFlags & IEEDF_SENT) ? 1 : 0);
+ } else {
+ highlight = fontOptionsListSize + 1;
+ }
+
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\highlight%d\\cf%d", highlight , highlight );
+ if (!streamData->isFirst && dat->isMixed) {
+ if (isGroupBreak) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\sl-1 \\par\\sl0");
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\sl-1 \\line\\sl0");
+ }
+ }
+ streamData->isFirst = FALSE;
+ if (dat->isMixed) {
+ if (event->dwFlags & IEEDF_RTL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\ltrch\\rtlch");
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\rtlch\\ltrch");
+ }
+ }
+ if (gdat->flags&SMF_SHOWICONS && isGroupBreak) {
+ int i = LOGICON_MSG_NOTICE;
+
+ switch (event->eventType) {
+ case EVENTTYPE_MESSAGE:
+ if (event->dwFlags & IEEDF_SENT) {
+ i = LOGICON_MSG_OUT;
+ }
+ else {
+ i = LOGICON_MSG_IN;
+ }
+ break;
+ case EVENTTYPE_JABBER_CHATSTATES:
+ case EVENTTYPE_JABBER_PRESENCE:
+ case EVENTTYPE_STATUSCHANGE:
+ case EVENTTYPE_URL:
+ case EVENTTYPE_FILE:
+ i = LOGICON_MSG_NOTICE;
+ break;
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\fs1 ");
+ while (bufferAlloced - bufferEnd < logIconBmpSize[i])
+ bufferAlloced += 1024;
+ buffer = (char *) mir_realloc(buffer, bufferAlloced);
+ CopyMemory(buffer + bufferEnd, pLogIconBmpBits[i], logIconBmpSize[i]);
+ bufferEnd += logIconBmpSize[i];
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " ");
+ }
+ if (gdat->flags&SMF_SHOWTIME && (event->eventType != EVENTTYPE_MESSAGE ||
+ (gdat->flags & SMF_MARKFOLLOWUPS || isGroupBreak || !(gdat->flags & SMF_GROUPMESSAGES)))) {
+ TCHAR * timestampString = NULL;
+ if (gdat->flags & SMF_GROUPMESSAGES && event->eventType == EVENTTYPE_MESSAGE) {
+ if (isGroupBreak) {
+ if (!(gdat->flags & SMF_MARKFOLLOWUPS)) {
+ timestampString = TimestampToString(gdat->flags, event->time, 0);
+ } else if (gdat->flags & SMF_SHOWDATE)
+ timestampString = TimestampToString(gdat->flags, event->time, 1);
+ } else if (gdat->flags & SMF_MARKFOLLOWUPS) {
+ timestampString = TimestampToString(gdat->flags, event->time, 2);
+ }
+ } else
+ timestampString = TimestampToString(gdat->flags, event->time, 0);
+ if (timestampString != NULL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYTIME : MSGFONTID_YOURTIME));
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, timestampString);
+ }
+ if (event->eventType != EVENTTYPE_MESSAGE) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s: ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON));
+ }
+ showColon = 1;
+ }
+ if ((!(gdat->flags&SMF_HIDENAMES) && event->eventType == EVENTTYPE_MESSAGE && isGroupBreak) || event->eventType == EVENTTYPE_STATUSCHANGE || event->eventType == EVENTTYPE_JABBER_CHATSTATES || event->eventType == EVENTTYPE_JABBER_PRESENCE || (heFlags != -1 && (heFlags & HISTORYEVENTS_FLAG_EXPECT_CONTACT_NAME_BEFORE))) {
+ if (event->eventType == EVENTTYPE_MESSAGE) {
+ if (showColon) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " %s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYNAME : MSGFONTID_YOURNAME));
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYNAME : MSGFONTID_YOURNAME));
+ }
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", SetToStyle(MSGFONTID_NOTICE));
+ }
+
+ if (event->dwFlags & IEEDF_UNICODE_NICK) {
+ AppendUnicodeToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszNickW);
+ } else {
+ AppendAnsiToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszNick);
+ }
+
+ showColon = 1;
+ if (event->eventType == EVENTTYPE_MESSAGE && gdat->flags & SMF_GROUPMESSAGES) {
+ if (gdat->flags & SMF_MARKFOLLOWUPS) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\par");
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\line");
+ }
+ showColon = 0;
+ }
+ }
+
+ if (gdat->flags&SMF_SHOWTIME && gdat->flags & SMF_GROUPMESSAGES && gdat->flags & SMF_MARKFOLLOWUPS
+ && event->eventType == EVENTTYPE_MESSAGE && isGroupBreak) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " %s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYTIME : MSGFONTID_YOURTIME));
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, TimestampToString(gdat->flags, event->time, 2));
+ showColon = 1;
+ }
+ if (showColon && event->eventType == EVENTTYPE_MESSAGE) {
+ if (event->dwFlags & IEEDF_RTL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\~%s: ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON));
+ } else {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s: ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON));
+ }
+ }
+ switch (event->eventType) {
+ case EVENTTYPE_MESSAGE:
+ if (gdat->flags & SMF_MSGONNEWLINE && showColon) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\line");
+ }
+ style = event->dwFlags & IEEDF_SENT ? MSGFONTID_MYMSG : MSGFONTID_YOURMSG;
+ AppendWithCustomLinks(event, style, &buffer, &bufferEnd, &bufferAlloced);
+ /*
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", SetToStyle(event->dwFlags & IEEDF_SENT ? MSGFONTID_MYMSG : MSGFONTID_YOURMSG));
+ if (event->dwFlags & IEEDF_UNICODE_TEXT) {
+ AppendUnicodeToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszTextW);
+ } else {
+ AppendAnsiToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszText);
+ }
+ */
+ break;
+ case EVENTTYPE_JABBER_CHATSTATES:
+ case EVENTTYPE_JABBER_PRESENCE:
+ case EVENTTYPE_STATUSCHANGE:
+ case EVENTTYPE_URL:
+ case EVENTTYPE_FILE:
+ {
+ style = MSGFONTID_NOTICE;
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", SetToStyle(style));
+ if (event->eventType == EVENTTYPE_FILE) {
+ if (event->dwFlags & IEEDF_SENT) {
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, TranslateT("File sent"));
+ } else {
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, TranslateT("File received"));
+ }
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, _T(":"));
+ } else if (event->eventType == EVENTTYPE_URL) {
+ if (event->dwFlags & IEEDF_SENT) {
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, TranslateT("URL sent"));
+ } else {
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, TranslateT("URL received"));
+ }
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, _T(":"));
+ }
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, _T(" "));
+
+ if (event->dwFlags & IEEDF_UNICODE_TEXT) {
+ AppendUnicodeToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszTextW);
+ } else {
+ AppendAnsiToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszText);
+ }
+ if (event->pszText2W != NULL) {
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, _T(" ("));
+ if (event->dwFlags & IEEDF_UNICODE_TEXT2) {
+ AppendUnicodeToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszText2W);
+ } else {
+ AppendAnsiToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszText2);
+ }
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, _T(")"));
+ }
+ break;
+ }
+ default:
+ {
+ char *rtfMessage;
+
+ if (heFlags == -1)
+ break;
+
+ if (heFlags & HISTORYEVENTS_FLAG_EXPECT_CONTACT_NAME_BEFORE)
+ AppendTToBuffer(&buffer, &bufferEnd, &bufferAlloced, _T(" "));
+
+ style = MSGFONTID_NOTICE;
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s ", SetToStyle(style));
+
+ rtfMessage = HistoryEvents_GetRichText(streamData->hDbEvent, NULL);
+ if (rtfMessage != NULL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, rtfMessage);
+ } else if (event->dwFlags & IEEDF_UNICODE_TEXT) {
+ AppendUnicodeToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszTextW);
+ } else {
+ AppendAnsiToBuffer(&buffer, &bufferEnd, &bufferAlloced, event->pszText);
+ }
+ HistoryEvents_ReleaseText(rtfMessage);
+
+ break;
+ }
+ }
+ if (dat->isMixed) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\par");
+ }
+ dat->lastEventTime = event->time;
+ dat->lastEventType = MAKELONG(event->dwFlags, event->eventType);
+ return buffer;
+}
+
+static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+{
+ struct LogStreamData *dat = (struct LogStreamData *) dwCookie;
+
+ if (dat->buffer == NULL) {
+ dat->bufferOffset = 0;
+ switch (dat->stage) {
+ case STREAMSTAGE_HEADER:
+ dat->buffer = CreateRTFHeader(dat->dlgDat, dat->gdat);
+ dat->stage = STREAMSTAGE_EVENTS;
+ break;
+ case STREAMSTAGE_EVENTS:
+ if (dat->events != NULL) {
+ EventData *event = dat->events;
+ dat->buffer = NULL;
+ dat->buffer = CreateRTFFromEvent(dat->dlgDat, event, dat->gdat, dat);
+ dat->events = event->next;
+ freeEvent(event);
+ } else if (dat->eventsToInsert) {
+ do {
+ EventData *event = getEventFromDB(dat->dlgDat, dat->hContact, dat->hDbEvent);
+ dat->buffer = NULL;
+ if (event != NULL) {
+ dat->buffer = CreateRTFFromEvent(dat->dlgDat, event, dat->gdat, dat);
+ freeEvent(event);
+ }
+ if (dat->buffer)
+ dat->hDbEventLast = dat->hDbEvent;
+ dat->hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) dat->hDbEvent, 0);
+ if (--dat->eventsToInsert == 0)
+ break;
+ } while (dat->buffer == NULL && dat->hDbEvent);
+ }
+ if (dat->buffer) {
+ break;
+ }
+ dat->stage = STREAMSTAGE_TAIL;
+ //fall through
+ case STREAMSTAGE_TAIL:
+ dat->buffer = CreateRTFTail();
+ dat->stage = STREAMSTAGE_STOP;
+ break;
+ case STREAMSTAGE_STOP:
+ *pcb = 0;
+ return 0;
+ }
+ dat->bufferLen = lstrlenA(dat->buffer);
+ }
+ *pcb = min(cb, dat->bufferLen - dat->bufferOffset);
+ CopyMemory(pbBuff, dat->buffer + dat->bufferOffset, *pcb);
+ dat->bufferOffset += *pcb;
+ if (dat->bufferOffset == dat->bufferLen) {
+ mir_free(dat->buffer);
+ dat->buffer = NULL;
+ }
+ return 0;
+}
+/*
+#ifndef CFE_LINK
+#define CFE_LINK 32
+#endif
+
+
+static const CLSID IID_ITextDocument=
+{ 0x8CC497C0,0xA1DF,0x11CE,
+ { 0x80,0x98, 0x00,0xAA,
+ 0x00,0x47,0xBE,0x5D} };
+
+void AutoURLDetect(HWND hwnd, CHARRANGE* sel) {
+ CHARFORMAT2 cf;
+ long cnt;
+ BSTR btxt = 0;
+ CHARRANGE oldSel;
+ LOGFONT lf;
+ COLORREF colour;
+
+ IRichEditOle* RichEditOle;
+ ITextDocument* TextDocument;
+ ITextRange* TextRange;
+ ITextSelection* TextSelection;
+
+ LoadMsgDlgFont(MSGFONTID_MYMSG, &lf, &colour);
+
+ SendMessage(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle);
+ if (RichEditOle->lpVtbl->QueryInterface(RichEditOle, &IID_ITextDocument, (void**)&TextDocument) != S_OK)
+ {
+ RichEditOle->lpVtbl->Release(RichEditOle);
+ return;
+ }
+ // retrieve text range
+ if (TextDocument->lpVtbl->Range(TextDocument,sel->cpMin, sel->cpMax, &TextRange) != S_OK)
+ {
+ TextDocument->lpVtbl->Release(TextDocument);
+ RichEditOle->lpVtbl->Release(RichEditOle);
+ return;
+ }
+
+ // retrieve text to parse for URLs
+ if (TextRange->lpVtbl->GetText(TextRange, &btxt) != S_OK)
+ {
+ TextRange->lpVtbl->Release(TextRange);
+ TextDocument->lpVtbl->Release(TextDocument);
+ RichEditOle->lpVtbl->Release(RichEditOle);
+ return;
+ }
+
+ TextRange->lpVtbl->Release(TextRange);
+
+ // disable screen updates
+
+ TextDocument->lpVtbl->Freeze(TextDocument, &cnt);
+
+ TextDocument->lpVtbl->GetSelection(TextDocument, &TextSelection);
+
+ cf.cbSize = sizeof(cf);
+ cf.dwMask = CFM_LINK | CFM_COLOR | CFM_UNDERLINE | CFM_BOLD | CFM_ITALIC | CFM_FACE | CFM_SIZE;
+ cf.dwEffects = CFE_UNDERLINE | (lf.lfWeight >= FW_BOLD ? CFE_BOLD : 0) | (lf.lfItalic ? CFE_ITALIC : 0);
+ _tcsncpy(cf.szFaceName, lf.lfFaceName, SIZEOF(cf.szFaceName));
+ cf.crTextColor = RGB(255,255,255);//colour;
+ cf.yHeight = 20 * lf.lfHeight;
+
+ //text = GetRichEditSelection(hwnd);
+ if (btxt!=NULL) {
+ int cpMin = sel->cpMin;
+ int cpMax = sel->cpMax;
+ int i, j, len = _tcslen(btxt);
+ for (j = 0; j < len ; j++) {
+ int l = DetectURL(btxt+j);
+ if (l > 0) {
+ sel->cpMin = cpMin + j;
+ sel->cpMax = cpMin + j + l;
+ TextSelection->lpVtbl->SetRange(TextSelection, cpMin + j, cpMin + j + l);
+ SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ j+= l-1;
+ }
+ }
+ }
+ TextSelection->lpVtbl->SetRange(TextSelection,oldSel.cpMin, oldSel.cpMax);
+ TextSelection->lpVtbl->Release(TextSelection);
+ TextDocument->lpVtbl->Unfreeze(TextDocument,&cnt);
+ SysFreeString(btxt);
+ TextDocument->lpVtbl->Release(TextDocument);
+ RichEditOle->lpVtbl->Release(RichEditOle);
+ UpdateWindow(hwnd);
+}
+*/
+void StreamInTestEvents(HWND hEditWnd, struct GlobalMessageData *gdat)
+{
+ EDITSTREAM stream = { 0 };
+ struct LogStreamData streamData = { 0 };
+ struct SrmmWindowData dat = { 0 };
+ streamData.isFirst = TRUE;
+ streamData.events = GetTestEvents();
+ streamData.dlgDat = &dat;
+ streamData.gdat = gdat;
+ stream.pfnCallback = LogStreamInEvents;
+ stream.dwCookie = (DWORD_PTR) & streamData;
+ SendMessage(hEditWnd, EM_STREAMIN, SF_RTF, (LPARAM) & stream);
+ SendMessage(hEditWnd, EM_HIDESELECTION, FALSE, 0);
+}
+void StreamInEvents(HWND hwndDlg, HANDLE hDbEventFirst, int count, int fAppend)
+{
+ FINDTEXTEXA fi;
+ EDITSTREAM stream = { 0 };
+ struct LogStreamData streamData = { 0 };
+ struct SrmmWindowData *dat = (struct SrmmWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ CHARRANGE oldSel, sel;
+
+// IEVIew MOD Begin
+ if (dat->windowData.hwndLog != NULL) {
+ IEVIEWEVENT event;
+ IEVIEWWINDOW ieWindow;
+ ZeroMemory(&event, sizeof(event));
+ event.cbSize = sizeof(event);
+ event.dwFlags = ((dat->flags & SMF_RTL) ? IEEF_RTL : 0);
+ event.hwnd = dat->windowData.hwndLog;
+ event.hContact = dat->windowData.hContact;
+ event.codepage = dat->windowData.codePage;
+ event.pszProto = dat->szProto;
+ if (!fAppend) {
+ event.iType = IEE_CLEAR_LOG;
+ CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
+ }
+ event.iType = IEE_LOG_DB_EVENTS;
+ event.hDbEventFirst = hDbEventFirst;
+ event.count = count;
+ CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
+ dat->hDbEventLast = event.hDbEventFirst != NULL ? event.hDbEventFirst : dat->hDbEventLast;
+
+ ZeroMemory(&ieWindow, sizeof(ieWindow));
+ ieWindow.cbSize = sizeof(ieWindow);
+ ieWindow.iType = IEW_SCROLLBOTTOM;
+ ieWindow.hwnd = dat->windowData.hwndLog;
+ CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+ return;
+ }
+// IEVIew MOD End
+
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_HIDESELECTION, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXGETSEL, 0, (LPARAM) & oldSel);
+ streamData.hContact = dat->windowData.hContact;
+ streamData.hDbEvent = hDbEventFirst;
+ streamData.hDbEventLast = dat->hDbEventLast;
+ streamData.dlgDat = dat;
+ streamData.eventsToInsert = count;
+ streamData.isFirst = fAppend ? GetRichTextLength(GetDlgItem(hwndDlg, IDC_LOG), dat->windowData.codePage, FALSE) == 0 : 1;
+ streamData.gdat = g_dat;
+ stream.pfnCallback = LogStreamInEvents;
+ stream.dwCookie = (DWORD_PTR) & streamData;
+ sel.cpMin = 0;
+ if (fAppend) {
+ GETTEXTLENGTHEX gtxl = {0};
+ gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS;
+ gtxl.codepage = 1200;
+ gtxl.codepage = 1200;
+ fi.chrg.cpMin = SendDlgItemMessage(hwndDlg, IDC_LOG, EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0);
+ sel.cpMin = sel.cpMax = GetRichTextLength(GetDlgItem(hwndDlg, IDC_LOG), dat->windowData.codePage, FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXSETSEL, 0, (LPARAM) & sel);
+ } else {
+ SendDlgItemMessage(hwndDlg, IDC_LOG, WM_SETREDRAW, FALSE, 0);
+ SetDlgItemText(hwndDlg, IDC_LOG, _T(""));
+ sel.cpMin = 0;
+ sel.cpMax = GetRichTextLength(GetDlgItem(hwndDlg, IDC_LOG), dat->windowData.codePage, FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXSETSEL, 0, (LPARAM) & sel);
+ fi.chrg.cpMin = 0;
+ dat->isMixed = 0;
+ }
+//SFF_SELECTION |
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_STREAMIN, fAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM) & stream);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXSETSEL, 0, (LPARAM) & oldSel);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_HIDESELECTION, FALSE, 0);
+ if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) {
+ SMADD_RICHEDIT3 smre;
+ smre.cbSize = sizeof(SMADD_RICHEDIT3);
+ smre.hwndRichEditControl = GetDlgItem(hwndDlg, IDC_LOG);
+ smre.Protocolname = dat->szProto;
+ if (dat->szProto!=NULL && strcmp(dat->szProto,"MetaContacts")==0) {
+ HANDLE hContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) dat->windowData.hContact, 0);
+ if (hContact!=NULL) {
+ smre.Protocolname = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ }
+ }
+ if (fi.chrg.cpMin > 0) {
+ sel.cpMin = fi.chrg.cpMin;
+ sel.cpMax = -1;
+ smre.rangeToReplace = &sel;
+ } else {
+ smre.rangeToReplace = NULL;
+ }
+ //smre.rangeToReplace = NULL;
+ smre.disableRedraw = TRUE;
+ smre.hContact = dat->windowData.hContact;
+ smre.flags = 0;
+ CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM) &smre);
+ }
+// if (GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LOG), GWL_STYLE) & WS_VSCROLL)
+ {
+ int len;
+ len = GetRichTextLength(GetDlgItem(hwndDlg, IDC_LOG), dat->windowData.codePage, FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETSEL, len - 1, len - 1);
+ }
+ if (!fAppend) {
+ SendDlgItemMessage(hwndDlg, IDC_LOG, WM_SETREDRAW, TRUE, 0);
+ }
+ dat->hDbEventLast = streamData.hDbEventLast;
+ PostMessage(hwndDlg, DM_SCROLLLOGTOBOTTOM, 0, 0);
+}
+
+#define RTFPICTHEADERMAXSIZE 78
+void LoadMsgLogIcons(void)
+{
+ HICON hIcon = NULL;
+ HBITMAP hBmp, hoBmp;
+ HDC hdc, hdcMem;
+ BITMAPINFOHEADER bih = { 0 };
+ int widthBytes, i;
+ RECT rc;
+ HBRUSH hBrush;
+ HBRUSH hBkgBrush;
+ HBRUSH hInBkgBrush;
+ HBRUSH hOutBkgBrush;
+ int rtfHeaderSize;
+ PBYTE pBmpBits;
+
+ g_hImageList = ImageList_Create(10, 10, IsWinVerXPPlus()? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, sizeof(pLogIconBmpBits) / sizeof(pLogIconBmpBits[0]), 0);
+ hBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR));
+ hInBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INCOMINGBKGCOLOUR, SRMSGDEFSET_INCOMINGBKGCOLOUR));
+ hOutBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_OUTGOINGBKGCOLOUR, SRMSGDEFSET_OUTGOINGBKGCOLOUR));
+ bih.biSize = sizeof(bih);
+ bih.biBitCount = 24;
+ bih.biCompression = BI_RGB;
+ bih.biHeight = 10;
+ bih.biPlanes = 1;
+ bih.biWidth = 10;
+ widthBytes = ((bih.biWidth * bih.biBitCount + 31) >> 5) * 4;
+ rc.top = rc.left = 0;
+ rc.right = bih.biWidth;
+ rc.bottom = bih.biHeight;
+ hdc = GetDC(NULL);
+ hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight);
+ hdcMem = CreateCompatibleDC(hdc);
+ pBmpBits = (PBYTE) mir_alloc(widthBytes * bih.biHeight);
+ hBrush = hBkgBrush;
+ for (i = 0; i < sizeof(pLogIconBmpBits) / sizeof(pLogIconBmpBits[0]); i++) {
+ switch (i) {
+ case LOGICON_MSG_IN:
+ ImageList_AddIcon(g_hImageList, GetCachedIcon("scriver_INCOMING"));
+ hIcon = ImageList_GetIcon(g_hImageList, LOGICON_MSG_IN, ILD_NORMAL);
+ hBrush = hInBkgBrush;
+ break;
+ case LOGICON_MSG_OUT:
+ ImageList_AddIcon(g_hImageList, GetCachedIcon("scriver_OUTGOING"));
+ hIcon = ImageList_GetIcon(g_hImageList, LOGICON_MSG_OUT, ILD_NORMAL);
+ hBrush = hOutBkgBrush;
+ break;
+ case LOGICON_MSG_NOTICE:
+ ImageList_AddIcon(g_hImageList, GetCachedIcon("scriver_NOTICE"));
+ hIcon = ImageList_GetIcon(g_hImageList, LOGICON_MSG_NOTICE, ILD_NORMAL);
+ //hBrush = hInBkgBrush;
+ hBrush = hBkgBrush;
+ break;
+ }
+ pLogIconBmpBits[i] = (PBYTE) mir_alloc(RTFPICTHEADERMAXSIZE + (bih.biSize + widthBytes * bih.biHeight) * 2);
+ //I can't seem to get binary mode working. No matter.
+ rtfHeaderSize = sprintf((char *)pLogIconBmpBits[i], "{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes1\\wbmwidthbytes%u\\picw%u\\pich%u ", bih.biBitCount, widthBytes, (UINT) bih.biWidth, (UINT)bih.biHeight);
+ hoBmp = (HBITMAP) SelectObject(hdcMem, hBmp);
+ FillRect(hdcMem, &rc, hBrush);
+ DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, NULL, DI_NORMAL);
+ SelectObject(hdcMem, hoBmp);
+ GetDIBits(hdc, hBmp, 0, bih.biHeight, pBmpBits, (BITMAPINFO *) & bih, DIB_RGB_COLORS);
+ DestroyIcon(hIcon);
+ {
+ int n;
+ for (n = 0; n < sizeof(BITMAPINFOHEADER); n++)
+ sprintf((char *)pLogIconBmpBits[i] + rtfHeaderSize + n * 2, "%02X", ((PBYTE) & bih)[n]);
+ for (n = 0; n < widthBytes * bih.biHeight; n += 4)
+ sprintf((char *)pLogIconBmpBits[i] + rtfHeaderSize + (bih.biSize + n) * 2, "%02X%02X%02X%02X", pBmpBits[n], pBmpBits[n + 1], pBmpBits[n + 2], pBmpBits[n + 3]);
+ }
+ logIconBmpSize[i] = rtfHeaderSize + (bih.biSize + widthBytes * bih.biHeight) * 2 + 1;
+ pLogIconBmpBits[i][logIconBmpSize[i] - 1] = '}';
+ }
+ mir_free(pBmpBits);
+ DeleteDC(hdcMem);
+ DeleteObject(hBmp);
+ ReleaseDC(NULL, hdc);
+ DeleteObject(hBkgBrush);
+ DeleteObject(hInBkgBrush);
+ DeleteObject(hOutBkgBrush);
+}
+
+void FreeMsgLogIcons(void)
+{
+ int i;
+ for (i = 0; i < sizeof(pLogIconBmpBits) / sizeof(pLogIconBmpBits[0]); i++)
+ mir_free(pLogIconBmpBits[i]);
+ ImageList_RemoveAll(g_hImageList);
+ ImageList_Destroy(g_hImageList);
+}
diff --git a/plugins/Scriver/src/msgoptions.cpp b/plugins/Scriver/src/msgoptions.cpp new file mode 100644 index 0000000000..f688efc50a --- /dev/null +++ b/plugins/Scriver/src/msgoptions.cpp @@ -0,0 +1,1113 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "chat/chat.h"
+extern CREOleCallback reOleCallback;
+extern void ChangeStatusIcons();
+extern void LoadInfobarFonts();
+
+static INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK DlgProcLogOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK DlgProcTabsOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK DlgProcLayoutOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcOptions1(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcOptions2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+typedef struct TabDefStruct {
+ DLGPROC dlgProc;
+ DWORD dlgId;
+ const char *tabName;
+} TabDef;
+
+static const TabDef tabPages[] = {
+ {DlgProcOptions, IDD_OPT_MSGDLG, LPGEN("General")},
+ {DlgProcTabsOptions, IDD_OPT_MSGTABS, LPGEN("Tabs")},
+ {DlgProcLayoutOptions, IDD_OPT_LAYOUT, LPGEN("Layout")},
+ {DlgProcLogOptions, IDD_OPT_MSGLOG, LPGEN("Event Log")},
+ {DlgProcOptions1, IDD_OPTIONS1, LPGEN("Group Chat")},
+ {DlgProcOptions2, IDD_OPTIONS2, LPGEN("Group Chat Log")}
+ };
+
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+
+typedef struct FontOptionsListStruct
+{
+ const TCHAR *szDescr;
+ COLORREF defColour;
+ const TCHAR *szDefFace;
+ BYTE defStyle;
+ char defSize;
+ const TCHAR *szBkgName;
+}FontOptionsList;
+
+static const FontOptionsList fontOptionsList[] = {
+ {LPGENT("Outgoing messages"), RGB(106, 106, 106), _T("Arial"), 0, -12, LPGENT("Outgoing background")},
+ {LPGENT("Incoming messages"), RGB(0, 0, 0), _T("Arial"), 0, -12, LPGENT("Incoming background")},
+ {LPGENT("Outgoing name"), RGB(89, 89, 89), _T("Arial"), FONTF_BOLD, -12, LPGENT("Outgoing background")},
+ {LPGENT("Outgoing time"), RGB(0, 0, 0), _T("Terminal"), FONTF_BOLD, -9, LPGENT("Outgoing background")},
+ {LPGENT("Outgoing colon"), RGB(89, 89, 89), _T("Arial"), 0, -11, LPGENT("Outgoing background")},
+ {LPGENT("Incoming name"), RGB(215, 0, 0), _T("Arial"), FONTF_BOLD, -12, LPGENT("Incoming background")},
+ {LPGENT("Incoming time"), RGB(0, 0, 0), _T("Terminal"), FONTF_BOLD, -9, LPGENT("Incoming background")},
+ {LPGENT("Incoming colon"), RGB(215, 0, 0), _T("Arial"), 0, -11, LPGENT("Incoming background")},
+ {LPGENT("Message area"), RGB(0, 0, 0), _T("Arial"), 0, -12, LPGENT("Input area background")},
+ {LPGENT("Notices"), RGB(90, 90, 160), _T("Arial"), 0, -12, LPGENT("Incoming background")},
+ {LPGENT("Outgoing URL"), RGB(0, 0, 255), _T("Arial"), 0, -12, LPGENT("Outgoing background")},
+ {LPGENT("Incoming URL"), RGB(0, 0, 255), _T("Arial"), 0, -12, LPGENT("Incoming background")},
+ {LPGENT("Infobar contact name"), RGB(0, 0, 0), _T("Arial"), FONTF_BOLD, -19, LPGENT("Infobar background")},
+ {LPGENT("Infobar status message"), RGB(50, 50, 50), _T("Arial"), FONTF_ITALIC, -11, LPGENT("Infobar background")}
+};
+
+int fontOptionsListSize = SIZEOF(fontOptionsList);
+
+//remeber to put these in the Translate( ) template file too
+static const FontOptionsList chatFontOptionsList[] = {
+ {LPGENT("Timestamp"), RGB(50, 50, 240), _T("Terminal"), 0, -8, LPGENT("Background")},
+ {LPGENT("Others nicknames"), RGB(0, 0, 0), _T("Verdana"), FONTF_BOLD, -13, LPGENT("Background")},
+ {LPGENT("Your nickname"), RGB(0, 0, 0), _T("Verdana"), FONTF_BOLD, -13, LPGENT("Background")},
+ {LPGENT("User has joined"), RGB(90, 160, 90), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("User has left"), RGB(160, 160, 90), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("User has disconnected"), RGB(160, 90, 90), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("User kicked ..."), RGB(100, 100, 100), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("User is now known as ..."), RGB(90, 90, 160), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Notice from user"), RGB(160, 130, 60), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Incoming message"), RGB(90, 90, 90), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Outgoing message"), RGB(90, 90, 90), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("The topic is ..."), RGB(70, 70, 160), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Information messages"), RGB(130, 130, 195), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("User enables status for ..."), RGB(70, 150, 70), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("User disables status for ..."), RGB(150, 70, 70), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Action message"), RGB(160, 90, 160), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Highlighted message"), RGB(180, 150, 80), _T("Verdana"), 0, -13, LPGENT("Background")},
+ {LPGENT("Message typing area"), RGB(0, 0, 40), _T("Verdana"), 0, -14, LPGENT("Message background")},
+ {LPGENT("User list members (online)"), RGB(0,0, 0), _T("Verdana"), 0, -12, LPGENT("User list background")},
+ {LPGENT("User list members (away)"), RGB(170, 170, 170), _T("Verdana"), 0, -12, LPGENT("User list background")},
+};
+
+struct ColourOptionsList
+{
+ const TCHAR *szName;
+ const char *szSettingName;
+ COLORREF defColour;
+ int systemColor;
+}
+
+static const colourOptionsList[] = {
+ {LPGENT("Background"), SRMSGSET_BKGCOLOUR, 0, COLOR_WINDOW},
+ {LPGENT("Input area background"), SRMSGSET_INPUTBKGCOLOUR, 0, COLOR_WINDOW},
+ {LPGENT("Incoming background"), SRMSGSET_INCOMINGBKGCOLOUR, 0, COLOR_WINDOW},
+ {LPGENT("Outgoing background"), SRMSGSET_OUTGOINGBKGCOLOUR, 0, COLOR_WINDOW},
+ {LPGENT("Infobar background"), SRMSGSET_INFOBARBKGCOLOUR, 0, COLOR_3DLIGHT},
+};
+
+
+int Chat_FontsChanged(WPARAM wParam,LPARAM lParam);
+
+
+int FontServiceFontsChanged(WPARAM wParam, LPARAM lParam)
+{
+ LoadMsgLogIcons();
+ LoadInfobarFonts();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ Chat_FontsChanged(wParam, lParam);
+ return 0;
+}
+
+static BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont)
+{
+ return DEFAULT_CHARSET;
+}
+
+void RegisterFontServiceFonts() {
+ int i;
+ char szTemp[100];
+ FontIDT fid = {0};
+ ColourIDT cid = {0};
+ fid.cbSize = sizeof(FontIDT);
+ mir_sntprintf(fid.group, SIZEOF(fid.group), _T("%s"), LPGENT("Messaging"));
+ mir_sntprintf(fid.backgroundGroup, SIZEOF(fid.backgroundGroup), _T("%s"), LPGENT("Messaging"));
+ strncpy(fid.dbSettingsGroup, (SRMMMOD), SIZEOF(fid.dbSettingsGroup));
+ fid.flags = FIDF_DEFAULTVALID | FIDF_DEFAULTVALID;
+ for (i = 0; i < SIZEOF(fontOptionsList); i++) {
+ fid.order = i;
+ mir_snprintf(szTemp, SIZEOF(szTemp), "SRMFont%d", i);
+ strncpy(fid.prefix, szTemp, SIZEOF(fid.prefix));
+ _tcsncpy(fid.name, fontOptionsList[i].szDescr, SIZEOF(fid.name));
+ fid.deffontsettings.colour = fontOptionsList[i].defColour;
+ fid.deffontsettings.size = fontOptionsList[i].defSize;
+ fid.deffontsettings.style = fontOptionsList[i].defStyle;
+ fid.deffontsettings.charset = MsgDlgGetFontDefaultCharset(fontOptionsList[i].szDefFace);
+ _tcsncpy(fid.deffontsettings.szFace, fontOptionsList[i].szDefFace, SIZEOF(fid.deffontsettings.szFace));
+ _tcsncpy(fid.backgroundName, fontOptionsList[i].szBkgName, SIZEOF(fid.backgroundName));
+ FontRegisterT(&fid);
+ }
+ cid.cbSize = sizeof(ColourIDT);
+ mir_sntprintf(cid.group, SIZEOF(cid.group), _T("%s"), LPGENT("Messaging"));
+ strncpy(cid.dbSettingsGroup, (SRMMMOD), SIZEOF(fid.dbSettingsGroup));
+ cid.flags = 0;
+ for (i = 0; i < SIZEOF(colourOptionsList); i++) {
+ cid.order = i;
+ _tcsncpy(cid.name, colourOptionsList[i].szName, SIZEOF(cid.name));
+ if (colourOptionsList[i].systemColor != -1) {
+ cid.defcolour = GetSysColor(colourOptionsList[i].systemColor);
+ } else {
+ cid.defcolour = colourOptionsList[i].defColour;
+ }
+ strncpy(cid.setting, colourOptionsList[i].szSettingName, SIZEOF(cid.setting));
+ ColourRegisterT(&cid);
+ }
+}
+
+void RegisterChatFonts( void )
+{
+ FontIDT fid = {0};
+ ColourIDT colourid;
+ char idstr[10];
+ int index = 0, i;
+ fid.cbSize = sizeof(FontIDT);
+ mir_sntprintf(fid.group, SIZEOF(fid.group), _T("%s/%s"), LPGENT("Messaging"), LPGENT("Group Chats"));
+ mir_sntprintf(fid.backgroundGroup, SIZEOF(fid.backgroundGroup), _T("%s/%s"), LPGENT("Messaging"), LPGENT("Group Chats"));
+ strncpy(fid.dbSettingsGroup, "ChatFonts", sizeof(fid.dbSettingsGroup));
+ fid.flags = FIDF_ALLOWREREGISTER | FIDF_DEFAULTVALID | FIDF_NEEDRESTART;
+ for (i = 0; i < SIZEOF(chatFontOptionsList); i++) {
+ if (i == 17) continue;
+ fid.order = index++;
+ sprintf(idstr, "Font%d", i);
+ strncpy(fid.prefix, idstr, sizeof(fid.prefix));
+ _tcsncpy(fid.name, chatFontOptionsList[i].szDescr, SIZEOF(fid.name));
+ fid.deffontsettings.colour = chatFontOptionsList[i].defColour;
+ fid.deffontsettings.size = chatFontOptionsList[i].defSize;
+ fid.deffontsettings.style = chatFontOptionsList[i].defStyle;
+ fid.deffontsettings.charset = MsgDlgGetFontDefaultCharset(fontOptionsList[i].szDefFace);
+ _tcsncpy(fid.deffontsettings.szFace, chatFontOptionsList[i].szDefFace, SIZEOF(fid.deffontsettings.szFace));
+ _tcsncpy(fid.backgroundName, chatFontOptionsList[i].szBkgName, SIZEOF(fid.backgroundName));
+ FontRegisterT(&fid);
+ }
+
+ colourid.cbSize = sizeof(ColourIDT);
+ colourid.order = 0;
+ strncpy(colourid.dbSettingsGroup, "Chat", sizeof(colourid.dbSettingsGroup));
+
+ strncpy(colourid.setting, "ColorLogBG", SIZEOF(colourid.setting));
+ _tcsncpy(colourid.name, LPGENT("Background"), SIZEOF(colourid.name));
+ mir_sntprintf(colourid.group, SIZEOF(colourid.group), _T("%s/%s"), LPGENT("Messaging"), LPGENT("Group Chats"));
+ colourid.defcolour = GetSysColor(COLOR_WINDOW);
+ ColourRegisterT(&colourid);
+
+ strncpy(colourid.setting, "ColorNicklistBG", SIZEOF(colourid.setting));
+ _tcsncpy(colourid.name, LPGENT("User list background"), SIZEOF(colourid.name));
+ colourid.defcolour = GetSysColor(COLOR_WINDOW);
+ ColourRegisterT(&colourid);
+
+ strncpy(colourid.setting, "ColorNicklistLines", SIZEOF(colourid.setting));
+ _tcsncpy(colourid.name, LPGENT("User list lines"), SIZEOF(colourid.name));
+ colourid.defcolour = GetSysColor(COLOR_INACTIVEBORDER);
+ ColourRegisterT(&colourid);
+
+ strncpy(colourid.setting, "ColorNicklistSelectedBG", SIZEOF(colourid.setting));
+ _tcsncpy(colourid.name, LPGENT("User list background (selected)"), SIZEOF(colourid.name));
+ colourid.defcolour = GetSysColor(COLOR_HIGHLIGHT);
+ ColourRegisterT(&colourid);
+}
+
+int IconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ ReleaseIcons();
+ LoadGlobalIcons();
+ FreeMsgLogIcons();
+ LoadMsgLogIcons();
+ ChangeStatusIcons();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_REMAKELOG, 0, 0);
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_CHANGEICONS, 0, 1);
+ Chat_IconsChanged(wParam, lParam);
+ return 0;
+}
+
+int SmileySettingsChanged(WPARAM wParam, LPARAM lParam)
+{
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_REMAKELOG, wParam, 0);
+ Chat_SmileyOptionsChanged(wParam, lParam);
+ return 0;
+}
+
+void LoadMsgDlgFont(int i, LOGFONT * lf, COLORREF * colour, BOOL chatMode)
+{
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+ const char * module = chatMode ? "ChatFonts" : SRMMMOD;
+ const char * prefix = chatMode ? "Font" : "SRMFont";
+ const FontOptionsList * fontList = chatMode ? chatFontOptionsList : fontOptionsList;
+
+ if (colour) {
+ wsprintfA(str, "%s%dCol", prefix, i);
+ *colour = DBGetContactSettingDword(NULL, module, str, fontList[i].defColour);
+ }
+ if (lf) {
+ wsprintfA(str, "%s%dSize", prefix, i);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, module, str, fontList[i].defSize);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "%s%dSty", prefix, i);
+ style = DBGetContactSettingByte(NULL, module, str, fontList[i].defStyle);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = 0;
+ lf->lfStrikeOut = 0;
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "%s%d", prefix, i);
+ if (DBGetContactSettingTString(NULL, module, str, &dbv))
+ lstrcpy(lf->lfFaceName, fontList[i].szDefFace);
+ else {
+ _tcsncpy(lf->lfFaceName, dbv.ptszVal, SIZEOF(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ wsprintfA(str, "%s%dSet", prefix, i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, module, str, MsgDlgGetFontDefaultCharset(lf->lfFaceName));
+ }
+}
+
+struct CheckBoxValues_t
+{
+ DWORD style;
+ const TCHAR* szDescr;
+};
+
+static const struct CheckBoxValues_t statusValues[] =
+{
+ { MODEF_OFFLINE, LPGENT("Offline") },
+ { PF2_ONLINE, LPGENT("Online") },
+ { PF2_SHORTAWAY, LPGENT("Away") },
+ { PF2_LONGAWAY, LPGENT("NA") },
+ { PF2_LIGHTDND, LPGENT("Occupied") },
+ { PF2_HEAVYDND, LPGENT("DND") },
+ { PF2_FREECHAT, LPGENT("Free for chat") },
+ { PF2_INVISIBLE, LPGENT("Invisible") },
+ { PF2_OUTTOLUNCH, LPGENT("Out to lunch") },
+ { PF2_ONTHEPHONE, LPGENT("On the phone") }
+};
+
+static void FillCheckBoxTree(HWND hwndTree, const struct CheckBoxValues_t *values, int nValues, DWORD style)
+{
+ TVINSERTSTRUCT tvis;
+ int i;
+
+ tvis.hParent = NULL;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
+ for (i = 0; i < nValues; i++) {
+ tvis.item.lParam = values[i].style;
+ tvis.item.pszText = TranslateTS(values[i].szDescr);
+ tvis.item.stateMask = TVIS_STATEIMAGEMASK;
+ tvis.item.state = INDEXTOSTATEIMAGEMASK((style & tvis.item.lParam) != 0 ? 2 : 1);
+ TreeView_InsertItem( hwndTree, &tvis );
+} }
+
+static DWORD MakeCheckBoxTreeFlags(HWND hwndTree)
+{
+ DWORD flags = 0;
+ TVITEM tvi;
+
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE;
+ tvi.hItem = TreeView_GetRoot(hwndTree);
+ while (tvi.hItem) {
+ TreeView_GetItem(hwndTree, &tvi);
+ if (((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2))
+ flags |= tvi.lParam;
+ tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem);
+ }
+ return flags;
+}
+
+static int changed = 0;
+
+static void ApplyChanges(int i) {
+ changed &= ~i;
+ if (changed == 0) {
+ ReloadGlobals();
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, TRUE);
+ }
+}
+
+static void MarkChanges(int i, HWND hWnd) {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ changed |= i;
+}
+
+static INT_PTR CALLBACK DlgProcTabsOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ int limitLength;
+ int bChecked;
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_USETABS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USETABS, SRMSGDEFSET_USETABS));
+ CheckDlgButton(hwndDlg, IDC_TABSATBOTTOM, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TABSATBOTTOM, SRMSGDEFSET_TABSATBOTTOM));
+ CheckDlgButton(hwndDlg, IDC_SWITCHTOACTIVE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SWITCHTOACTIVE, SRMSGDEFSET_SWITCHTOACTIVE));
+ CheckDlgButton(hwndDlg, IDC_LIMITNAMES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITNAMES, SRMSGDEFSET_LIMITNAMES));
+ limitLength = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITNAMESLEN, SRMSGDEFSET_LIMITNAMESLEN);
+ (int)SetDlgItemInt(hwndDlg, IDC_LIMITNAMESLEN, limitLength >= SRMSGSET_LIMITNAMESLEN_MIN ? limitLength : SRMSGDEFSET_LIMITNAMESLEN, FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_LIMITTABS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITTABS, SRMSGDEFSET_LIMITTABS));
+ limitLength = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITTABSNUM, SRMSGDEFSET_LIMITTABSNUM);
+ SetDlgItemInt(hwndDlg, IDC_LIMITTABSNUM, limitLength >= 1 ? limitLength : 1, FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_LIMITCHATSTABS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITCHATSTABS, SRMSGDEFSET_LIMITCHATSTABS));
+ limitLength = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITCHATSTABSNUM, SRMSGDEFSET_LIMITCHATSTABSNUM);
+ SetDlgItemInt(hwndDlg, IDC_LIMITCHATSTABSNUM, limitLength >= 1 ? limitLength : 1, FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_SEPARATECHATSCONTAINERS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SEPARATECHATSCONTAINERS, SRMSGDEFSET_SEPARATECHATSCONTAINERS));
+
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TABSATBOTTOM), bChecked );
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SWITCHTOACTIVE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITNAMES), bChecked );
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SEPARATECHATSCONTAINERS), bChecked );
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITTABS), bChecked );
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS) && IsDlgButtonChecked(hwndDlg, IDC_LIMITNAMES);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITNAMESLEN), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHARS), bChecked);
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS) && IsDlgButtonChecked(hwndDlg, IDC_LIMITTABS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITTABSNUM), bChecked );
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS) && IsDlgButtonChecked(hwndDlg, IDC_SEPARATECHATSCONTAINERS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITCHATSTABS), bChecked );
+ bChecked = bChecked && IsDlgButtonChecked(hwndDlg, IDC_LIMITCHATSTABS);;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITCHATSTABSNUM), bChecked );
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_USETABS:
+ {
+ int bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SWITCHTOACTIVE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TABSATBOTTOM), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITNAMES), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SEPARATECHATSCONTAINERS), bChecked );
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITTABS), bChecked);
+ }
+ case IDC_LIMITTABS:
+ {
+ int bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS) && IsDlgButtonChecked(hwndDlg, IDC_LIMITTABS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITTABSNUM), bChecked);
+ }
+ case IDC_SEPARATECHATSCONTAINERS:
+ {
+ int bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS) && IsDlgButtonChecked(hwndDlg, IDC_SEPARATECHATSCONTAINERS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITCHATSTABS), bChecked);
+ }
+ case IDC_LIMITCHATSTABS:
+ {
+ int bChecked = IsDlgButtonChecked(hwndDlg, IDC_USETABS) && IsDlgButtonChecked(hwndDlg, IDC_SEPARATECHATSCONTAINERS) &&
+ IsDlgButtonChecked(hwndDlg, IDC_LIMITCHATSTABS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITCHATSTABSNUM), bChecked);
+ }
+ case IDC_LIMITNAMES:
+ {
+ int bChecked = IsDlgButtonChecked(hwndDlg, IDC_LIMITNAMES) && IsDlgButtonChecked(hwndDlg, IDC_USETABS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITNAMESLEN), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHARS), bChecked);
+ }
+ break;
+ case IDC_LIMITNAMESLEN:
+ case IDC_LIMITTABSNUM:
+ case IDC_LIMITCHATSTABSNUM:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0;
+ break;
+ }
+ MarkChanges(8, hwndDlg);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ int limitLength;
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_USETABS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_USETABS));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_TABSATBOTTOM, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TABSATBOTTOM));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITNAMES, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LIMITNAMES));
+ (limitLength = GetDlgItemInt(hwndDlg, IDC_LIMITNAMESLEN, NULL, TRUE)) >= SRMSGSET_LIMITNAMESLEN_MIN ? GetDlgItemInt(hwndDlg, IDC_LIMITNAMESLEN, NULL, TRUE) : SRMSGSET_LIMITNAMESLEN_MIN;
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITNAMESLEN, limitLength);
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITTABS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LIMITTABS));
+ limitLength = GetDlgItemInt(hwndDlg, IDC_LIMITTABSNUM, NULL, TRUE) >= 1 ? GetDlgItemInt(hwndDlg, IDC_LIMITTABSNUM, NULL, TRUE) : 1;
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITTABSNUM, limitLength);
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITCHATSTABS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LIMITCHATSTABS));
+ limitLength = GetDlgItemInt(hwndDlg, IDC_LIMITCHATSTABSNUM, NULL, TRUE) >= 1 ? GetDlgItemInt(hwndDlg, IDC_LIMITCHATSTABSNUM, NULL, TRUE) : 1;
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_LIMITCHATSTABSNUM, limitLength);
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SWITCHTOACTIVE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SWITCHTOACTIVE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SEPARATECHATSCONTAINERS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SEPARATECHATSCONTAINERS));
+
+ ApplyChanges(8);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK DlgProcLayoutOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ char str[10];
+ int bChecked;
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUSBAR, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSBAR, SRMSGDEFSET_SHOWSTATUSBAR));
+ CheckDlgButton(hwndDlg, IDC_SHOWTITLEBAR, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTITLEBAR, SRMSGDEFSET_SHOWTITLEBAR));
+ CheckDlgButton(hwndDlg, IDC_SHOWTOOLBAR, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWBUTTONLINE, SRMSGDEFSET_SHOWBUTTONLINE));
+ CheckDlgButton(hwndDlg, IDC_SHOWINFOBAR, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWINFOBAR, SRMSGDEFSET_SHOWINFOBAR));
+ CheckDlgButton(hwndDlg, IDC_TRANSPARENCY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USETRANSPARENCY, SRMSGDEFSET_USETRANSPARENCY));
+ SendDlgItemMessage(hwndDlg,IDC_ATRANSPARENCYVALUE,TBM_SETRANGE, FALSE, MAKELONG(0,255));
+ SendDlgItemMessage(hwndDlg,IDC_ATRANSPARENCYVALUE,TBM_SETPOS, TRUE, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_ACTIVEALPHA, SRMSGDEFSET_ACTIVEALPHA));
+ SendDlgItemMessage(hwndDlg,IDC_ITRANSPARENCYVALUE,TBM_SETRANGE, FALSE, MAKELONG(0,255));
+ SendDlgItemMessage(hwndDlg,IDC_ITRANSPARENCYVALUE,TBM_SETPOS, TRUE, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_INACTIVEALPHA, SRMSGDEFSET_INACTIVEALPHA));
+ sprintf(str,"%d%%",(int)(100*SendDlgItemMessage(hwndDlg,IDC_ATRANSPARENCYVALUE,TBM_GETPOS,0,0)/255));
+ SetDlgItemTextA(hwndDlg, IDC_ATRANSPARENCYPERC, str);
+ sprintf(str,"%d%%",(int)(100*SendDlgItemMessage(hwndDlg,IDC_ITRANSPARENCYVALUE,TBM_GETPOS,0,0)/255));
+ SetDlgItemTextA(hwndDlg, IDC_ITRANSPARENCYPERC, str);
+ SetDlgItemInt(hwndDlg, IDC_INPUTLINES, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_AUTORESIZELINES, SRMSGDEFSET_AUTORESIZELINES), FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_INPUTLINESSPIN, UDM_SETRANGE, 0, MAKELONG(100, 1));
+ SendDlgItemMessage(hwndDlg, IDC_INPUTLINESSPIN, UDM_SETPOS, 0, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_AUTORESIZELINES, SRMSGDEFSET_AUTORESIZELINES));
+
+ if (pSetLayeredWindowAttributes == NULL) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCY), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ATRANSPARENCYVALUE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ATRANSPARENCYPERC), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITRANSPARENCYVALUE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITRANSPARENCYPERC), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT1), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT2), FALSE);
+ } else {
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENCY);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ATRANSPARENCYVALUE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ATRANSPARENCYPERC), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITRANSPARENCYVALUE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITRANSPARENCYPERC), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT1), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT2), bChecked);
+ }
+
+ CheckDlgButton(hwndDlg, IDC_STATUSWIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON));
+ CheckDlgButton(hwndDlg, IDC_SHOWPROGRESS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWPROGRESS, SRMSGDEFSET_SHOWPROGRESS));
+ CheckDlgButton(hwndDlg, IDC_AVATARSUPPORT, g_dat->flags&SMF_AVATAR);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_TRANSPARENCY:
+ if (pSetLayeredWindowAttributes != NULL) {
+ int bChecked = IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENCY);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ATRANSPARENCYVALUE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ATRANSPARENCYPERC), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITRANSPARENCYVALUE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITRANSPARENCYPERC), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT1), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENCYTEXT2), bChecked);
+ }
+ break;
+
+ case IDC_INPUTLINES:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0;
+ break;
+ }
+ MarkChanges(16, hwndDlg);
+ break;
+ case WM_HSCROLL:
+ { char str[10];
+ sprintf(str,"%d%%",(int)(100*SendDlgItemMessage(hwndDlg,IDC_ATRANSPARENCYVALUE,TBM_GETPOS,0,0)/256));
+ SetDlgItemTextA(hwndDlg, IDC_ATRANSPARENCYPERC, str);
+ sprintf(str,"%d%%",(int)(100*SendDlgItemMessage(hwndDlg,IDC_ITRANSPARENCYVALUE,TBM_GETPOS,0,0)/256));
+ SetDlgItemTextA(hwndDlg, IDC_ITRANSPARENCYPERC, str);
+ MarkChanges(16, hwndDlg);
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ UINT lines;
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSBAR, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUSBAR));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTITLEBAR, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWTITLEBAR));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWBUTTONLINE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWTOOLBAR));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWINFOBAR, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWINFOBAR));
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_USETRANSPARENCY, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENCY));
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_ACTIVEALPHA, SendDlgItemMessage(hwndDlg,IDC_ATRANSPARENCYVALUE,TBM_GETPOS,0,0));
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_INACTIVEALPHA, SendDlgItemMessage(hwndDlg,IDC_ITRANSPARENCYVALUE,TBM_GETPOS,0,0));
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_STATUSWIN));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWPROGRESS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWPROGRESS));
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_AVATARENABLE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT));
+
+ lines = GetDlgItemInt(hwndDlg, IDC_INPUTLINES, NULL, FALSE);
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_AUTORESIZELINES, lines ? lines : SRMSGDEFSET_AUTORESIZELINES);
+ LoadInfobarFonts();
+
+ ApplyChanges(16);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DWORD msgTimeout;
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_POPLIST), GWL_STYLE, (GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_POPLIST), GWL_STYLE) & ~WS_BORDER) | TVS_NOHSCROLL | TVS_CHECKBOXES);
+ FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_POPLIST), statusValues, sizeof(statusValues) / sizeof(statusValues[0]),
+ DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_POPFLAGS, SRMSGDEFSET_POPFLAGS));
+ CheckDlgButton(hwndDlg, IDC_AUTOPOPUP, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOPOPUP, SRMSGDEFSET_AUTOPOPUP));
+ CheckDlgButton(hwndDlg, IDC_STAYMINIMIZED, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STAYMINIMIZED, SRMSGDEFSET_STAYMINIMIZED));
+ CheckDlgButton(hwndDlg, IDC_AUTOMIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOMIN, SRMSGDEFSET_AUTOMIN));
+ CheckDlgButton(hwndDlg, IDC_SAVEDRAFTS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEDRAFTS, SRMSGDEFSET_SAVEDRAFTS));
+
+ CheckDlgButton(hwndDlg, IDC_DELTEMP, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DELTEMP, SRMSGDEFSET_DELTEMP));
+ msgTimeout = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT);
+ SetDlgItemInt(hwndDlg, IDC_SECONDS, msgTimeout >= SRMSGSET_MSGTIMEOUT_MIN ? msgTimeout / 1000 : SRMSGDEFSET_MSGTIMEOUT / 1000, FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_SAVEPERCONTACT, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT));
+ CheckDlgButton(hwndDlg, IDC_CASCADE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE));
+ CheckDlgButton(hwndDlg, IDC_SENDONENTER, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER));
+ CheckDlgButton(hwndDlg, IDC_SENDONDBLENTER, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER));
+ CheckDlgButton(hwndDlg, IDC_STATUSWIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON));
+
+ CheckDlgButton(hwndDlg, IDC_HIDECONTAINERS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDECONTAINERS, SRMSGDEFSET_HIDECONTAINERS));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STAYMINIMIZED), IsDlgButtonChecked(hwndDlg, IDC_AUTOPOPUP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_POPLIST), IsDlgButtonChecked(hwndDlg, IDC_AUTOPOPUP));
+
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_AUTOPOPUP:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STAYMINIMIZED), IsDlgButtonChecked(hwndDlg, IDC_AUTOPOPUP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_POPLIST), IsDlgButtonChecked(hwndDlg, IDC_AUTOPOPUP));
+ break;
+ case IDC_AUTOMIN:
+ break;
+ case IDC_SECONDS:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0;
+ break;
+ case IDC_SENDONENTER:
+ CheckDlgButton(hwndDlg, IDC_SENDONDBLENTER, BST_UNCHECKED);
+ break;
+ case IDC_SENDONDBLENTER:
+ CheckDlgButton(hwndDlg, IDC_SENDONENTER, BST_UNCHECKED);
+ break;
+ case IDC_CASCADE:
+ CheckDlgButton(hwndDlg, IDC_SAVEPERCONTACT, BST_UNCHECKED);
+ break;
+ case IDC_SAVEPERCONTACT:
+ CheckDlgButton(hwndDlg, IDC_CASCADE, BST_UNCHECKED);
+ break;
+ }
+ MarkChanges(2, hwndDlg);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case IDC_POPLIST:
+ if (((LPNMHDR) lParam)->code == NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x = (short) LOWORD(GetMessagePos());
+ hti.pt.y = (short) HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR) lParam)->hwndFrom, &hti.pt);
+ if (TreeView_HitTest(((LPNMHDR) lParam)->hwndFrom, &hti))
+ if (hti.flags & TVHT_ONITEMSTATEICON) {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvi.hItem = hti.hItem;
+ TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1;
+ TreeView_SetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ MarkChanges(2, hwndDlg);
+ }
+ } else if (((LPNMHDR) lParam)->code == TVN_KEYDOWN) {
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE) {
+ MarkChanges(2, hwndDlg);
+ }
+ }
+ break;
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ DWORD msgTimeout;
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_POPFLAGS, MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_POPLIST)));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOPOPUP, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOPOPUP));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_STAYMINIMIZED, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_STAYMINIMIZED));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOMIN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOMIN));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEDRAFTS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEDRAFTS));
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_DELTEMP, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DELTEMP));
+ msgTimeout = GetDlgItemInt(hwndDlg, IDC_SECONDS, NULL, TRUE) >= SRMSGSET_MSGTIMEOUT_MIN / 1000 ? GetDlgItemInt(hwndDlg, IDC_SECONDS, NULL, TRUE) * 1000 : SRMSGDEFSET_MSGTIMEOUT;
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, msgTimeout);
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SENDONENTER));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SENDONDBLENTER));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPERCONTACT));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CASCADE));
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDECONTAINERS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_HIDECONTAINERS));
+
+ ApplyChanges(2);
+
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static void ShowPreview(HWND hwndDlg)
+{
+ struct GlobalMessageData gdat = { 0 };
+ PARAFORMAT2 pf2;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_SHOWLOGICONS) ? SMF_SHOWICONS : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_SHOWNAMES) ? 0 : SMF_HIDENAMES;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES) ? SMF_SHOWTIME : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_SHOWSECONDS) ? SMF_SHOWSECONDS : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES) ? SMF_SHOWDATE : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_USELONGDATE) ? SMF_LONGDATE : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_USERELATIVEDATE) ? SMF_RELATIVEDATE : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_GROUPMESSAGES) ? SMF_GROUPMESSAGES : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_MARKFOLLOWUPS) ? SMF_MARKFOLLOWUPS : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_MESSAGEONNEWLINE) ? SMF_MSGONNEWLINE : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_DRAWLINES) ? SMF_DRAWLINES : 0;
+ gdat.flags |= IsDlgButtonChecked(hwndDlg, IDC_INDENTTEXT) ? SMF_INDENTTEXT : 0;
+ gdat.logLineColour = SendDlgItemMessage(hwndDlg, IDC_LINECOLOUR, CPM_GETCOLOUR, 0, 0);
+ gdat.indentSize = (int) SendDlgItemMessage(hwndDlg, IDC_INDENTSPIN, UDM_GETPOS, 0, 0);
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_OFFSET;
+ pf2.dxOffset = (gdat.flags & SMF_INDENTTEXT) ? gdat.indentSize * 1440 /g_dat->logPixelSX : 0;
+ SetDlgItemText(hwndDlg, IDC_LOG, _T(""));
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ StreamInTestEvents(GetDlgItem(hwndDlg, IDC_LOG), &gdat);
+}
+
+static INT_PTR CALLBACK DlgProcLogOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_LOG));
+ switch (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY)) {
+ case LOADHISTORY_UNREAD:
+ CheckDlgButton(hwndDlg, IDC_LOADUNREAD, BST_CHECKED);
+ break;
+ case LOADHISTORY_COUNT:
+ CheckDlgButton(hwndDlg, IDC_LOADCOUNT, BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTSPIN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTTEXT2), TRUE);
+ break;
+ case LOADHISTORY_TIME:
+ CheckDlgButton(hwndDlg, IDC_LOADTIME, BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMEN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMESPIN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STMINSOLD), TRUE);
+ break;
+ }
+ SendDlgItemMessage(hwndDlg, IDC_LOADCOUNTSPIN, UDM_SETRANGE, 0, MAKELONG(100, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LOADCOUNTSPIN, UDM_SETPOS, 0, DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADCOUNT, SRMSGDEFSET_LOADCOUNT));
+ SendDlgItemMessage(hwndDlg, IDC_LOADTIMESPIN, UDM_SETRANGE, 0, MAKELONG(12 * 60, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LOADTIMESPIN, UDM_SETPOS, 0, DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADTIME, SRMSGDEFSET_LOADTIME));
+
+ CheckDlgButton(hwndDlg, IDC_SHOWLOGICONS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, SRMSGDEFSET_SHOWLOGICONS));
+ CheckDlgButton(hwndDlg, IDC_SHOWNAMES, !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, SRMSGDEFSET_HIDENAMES));
+ CheckDlgButton(hwndDlg, IDC_SHOWTIMES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, SRMSGDEFSET_SHOWTIME));
+ CheckDlgButton(hwndDlg, IDC_SHOWSECONDS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECONDS, SRMSGDEFSET_SHOWSECONDS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSECONDS), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWDATES), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ CheckDlgButton(hwndDlg, IDC_SHOWDATES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, SRMSGDEFSET_SHOWDATE));
+ CheckDlgButton(hwndDlg, IDC_USELONGDATE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USELONGDATE, SRMSGDEFSET_USELONGDATE));
+ CheckDlgButton(hwndDlg, IDC_USERELATIVEDATE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USERELATIVEDATE, SRMSGDEFSET_USERELATIVEDATE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_USELONGDATE), IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES) && IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_USERELATIVEDATE), IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES) && IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+
+ if (!ServiceExists(MS_IEVIEW_WINDOW)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_USEIEVIEW), FALSE);
+ }
+ CheckDlgButton(hwndDlg, IDC_USEIEVIEW, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USEIEVIEW, SRMSGDEFSET_USEIEVIEW));
+
+ CheckDlgButton(hwndDlg, IDC_GROUPMESSAGES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_GROUPMESSAGES, SRMSGDEFSET_GROUPMESSAGES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MARKFOLLOWUPS), IsDlgButtonChecked(hwndDlg, IDC_GROUPMESSAGES));
+ CheckDlgButton(hwndDlg, IDC_MARKFOLLOWUPS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_MARKFOLLOWUPS, SRMSGDEFSET_MARKFOLLOWUPS));
+ CheckDlgButton(hwndDlg, IDC_MESSAGEONNEWLINE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_MESSAGEONNEWLINE, SRMSGDEFSET_MESSAGEONNEWLINE));
+ CheckDlgButton(hwndDlg, IDC_DRAWLINES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DRAWLINES, SRMSGDEFSET_DRAWLINES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LINECOLOUR), IsDlgButtonChecked(hwndDlg, IDC_DRAWLINES));
+
+ CheckDlgButton(hwndDlg, IDC_INDENTTEXT, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_INDENTTEXT, SRMSGDEFSET_INDENTTEXT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_INDENTSIZE), IsDlgButtonChecked(hwndDlg, IDC_INDENTTEXT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_INDENTSPIN), IsDlgButtonChecked(hwndDlg, IDC_INDENTTEXT));
+ SendDlgItemMessage(hwndDlg, IDC_INDENTSPIN, UDM_SETRANGE, 0, MAKELONG(999, 0));
+ SendDlgItemMessage(hwndDlg, IDC_INDENTSPIN, UDM_SETPOS, 0, DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_INDENTSIZE, SRMSGDEFSET_INDENTSIZE));
+
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUSCHANGES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, SRMSGDEFSET_SHOWSTATUSCH));
+
+ SendDlgItemMessage(hwndDlg, IDC_LINECOLOUR, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_LINECOLOUR, SRMSGDEFSET_LINECOLOUR));
+ {
+ PARAFORMAT2 pf2;
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_OFFSETINDENT | PFM_RIGHTINDENT;
+ pf2.dxStartIndent = 30;
+ pf2.dxRightIndent = 30;
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETOLECALLBACK, 0, (LPARAM) & reOleCallback);
+ }
+ ShowPreview(hwndDlg);
+ return TRUE;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_FONTSCOLORS:
+ {
+ OPENOPTIONSDIALOG ood;
+ ood.cbSize = sizeof(ood);
+ ood.pszGroup = "Customize";
+ ood.pszPage = "Fonts & Colors";
+ ood.pszTab = NULL;
+ CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood );
+ }
+ break;
+ case IDC_LOADCOUNT:
+ case IDC_LOADTIME:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTN), IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTSPIN), IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTTEXT2), IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMEN), IsDlgButtonChecked(hwndDlg, IDC_LOADTIME));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_LOADTIME));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STMINSOLD), IsDlgButtonChecked(hwndDlg, IDC_LOADTIME));
+ break;
+ case IDC_SHOWTIMES:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSECONDS), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWDATES), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ case IDC_SHOWDATES:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_USELONGDATE), IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES) && IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_USERELATIVEDATE), IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES) && IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ case IDC_SHOWNAMES:
+ case IDC_SHOWSECONDS:
+ case IDC_USELONGDATE:
+ case IDC_USERELATIVEDATE:
+ case IDC_LINECOLOUR:
+ case IDC_MARKFOLLOWUPS:
+ case IDC_SHOWLOGICONS:
+ case IDC_MESSAGEONNEWLINE:
+ ShowPreview(hwndDlg);
+ break;
+ case IDC_GROUPMESSAGES:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MARKFOLLOWUPS), IsDlgButtonChecked(hwndDlg, IDC_GROUPMESSAGES));
+ ShowPreview(hwndDlg);
+ break;
+ case IDC_DRAWLINES:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LINECOLOUR), IsDlgButtonChecked(hwndDlg, IDC_DRAWLINES));
+ ShowPreview(hwndDlg);
+ break;
+ case IDC_INDENTTEXT:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_INDENTSIZE), IsDlgButtonChecked(hwndDlg, IDC_INDENTTEXT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_INDENTSPIN), IsDlgButtonChecked(hwndDlg, IDC_INDENTTEXT));
+ ShowPreview(hwndDlg);
+ break;
+ case IDC_INDENTSIZE:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return TRUE;
+ ShowPreview(hwndDlg);
+ break;
+ case IDC_LOADCOUNTN:
+ case IDC_LOADTIMEN:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return TRUE;
+ break;
+ }
+ MarkChanges(4, hwndDlg);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ if (IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT))
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, LOADHISTORY_COUNT);
+ else if (IsDlgButtonChecked(hwndDlg, IDC_LOADTIME))
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, LOADHISTORY_TIME);
+ else
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, LOADHISTORY_UNREAD);
+ DBWriteContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADCOUNT, (WORD) SendDlgItemMessage(hwndDlg, IDC_LOADCOUNTSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADTIME, (WORD) SendDlgItemMessage(hwndDlg, IDC_LOADTIMESPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWLOGICONS));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, (BYTE) ! IsDlgButtonChecked(hwndDlg, IDC_SHOWNAMES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECONDS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSECONDS));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_USELONGDATE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_USELONGDATE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_USERELATIVEDATE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_USERELATIVEDATE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUSCHANGES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_GROUPMESSAGES, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_GROUPMESSAGES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_MARKFOLLOWUPS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MARKFOLLOWUPS));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_MESSAGEONNEWLINE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MESSAGEONNEWLINE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_DRAWLINES, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DRAWLINES));
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_LINECOLOUR, SendDlgItemMessage(hwndDlg, IDC_LINECOLOUR, CPM_GETCOLOUR, 0, 0));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_USEIEVIEW, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_USEIEVIEW));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_INDENTTEXT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_INDENTTEXT));
+ DBWriteContactSettingWord(NULL, SRMMMOD, SRMSGSET_INDENTSIZE, (WORD) SendDlgItemMessage(hwndDlg, IDC_INDENTSPIN, UDM_GETPOS, 0, 0));
+
+ FreeMsgLogIcons();
+ LoadMsgLogIcons();
+ ApplyChanges(4);
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static void ResetCList(HWND hwndDlg)
+{
+ int i;
+
+ if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_DISABLEGROUPS && !DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT))
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) FALSE, 0);
+ else
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETHIDEEMPTYGROUPS, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETGREYOUTFLAGS, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETLEFTMARGIN, 2, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKBITMAP, 0, (LPARAM) (HBITMAP) NULL);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETINDENT, 10, 0);
+ for (i = 0; i <= FONTID_MAX; i++)
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT));
+}
+
+static void RebuildList(HWND hwndDlg, HANDLE hItemNew, HANDLE hItemUnknown)
+{
+ HANDLE hContact, hItem;
+ BYTE defType = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW);
+
+ if (hItemNew && defType) {
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItemNew, 1);
+ }
+ if (hItemUnknown && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGUNKNOWN, SRMSGDEFSET_TYPINGUNKNOWN)) {
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItemUnknown, 1);
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0);
+ if (hItem && DBGetContactSettingByte(hContact, SRMMMOD, SRMSGSET_TYPING, defType)) {
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItem, 1);
+ }
+ } while ((hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)));
+}
+
+static void SaveList(HWND hwndDlg, HANDLE hItemNew, HANDLE hItemUnknown)
+{
+ HANDLE hContact, hItem;
+
+ if (hItemNew) {
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, (BYTE)(SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItemNew, 0) ? 1 : 0));
+ }
+ if (hItemUnknown) {
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGUNKNOWN, (BYTE)(SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItemUnknown, 0) ? 1 : 0));
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0);
+ if (hItem) {
+ DBWriteContactSettingByte(hContact, SRMMMOD, SRMSGSET_TYPING, (BYTE)(SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItem, 0) ? 1 : 0));
+ }
+ } while ((hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)));
+}
+
+static INT_PTR CALLBACK DlgProcTypeOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HANDLE hItemNew, hItemUnknown;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ CLCINFOITEM cii = { 0 };
+ cii.cbSize = sizeof(cii);
+ cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX;
+ cii.pszText = (TCHAR *)TranslateT("** New contacts **");
+ hItemNew = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM) & cii);
+ cii.pszText = (TCHAR *)TranslateT("** Unknown contacts **");
+ hItemUnknown = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM) & cii);
+ }
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE) | (CLS_SHOWHIDDEN) | (CLS_NOHIDEOFFLINE));
+ ResetCList(hwndDlg);
+ RebuildList(hwndDlg, hItemNew, hItemUnknown);
+ CheckDlgButton(hwndDlg, IDC_SHOWNOTIFY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPING, SRMSGDEFSET_SHOWTYPING));
+ CheckDlgButton(hwndDlg, IDC_TYPEWIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGWIN, SRMSGDEFSET_SHOWTYPINGWIN));
+ CheckDlgButton(hwndDlg, IDC_TYPETRAY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGNOWIN, SRMSGDEFSET_SHOWTYPINGNOWIN));
+ CheckDlgButton(hwndDlg, IDC_NOTIFYTRAY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, SRMSGDEFSET_SHOWTYPINGCLIST));
+ CheckDlgButton(hwndDlg, IDC_NOTIFYBALLOON, !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, SRMSGDEFSET_SHOWTYPINGCLIST));
+ CheckDlgButton(hwndDlg, IDC_TYPINGSWITCH, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGSWITCH, SRMSGDEFSET_SHOWTYPINGSWITCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEWIN), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPETRAY), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY));
+ if (!ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), FALSE);
+ CheckDlgButton(hwndDlg, IDC_NOTIFYTRAY, BST_CHECKED);
+ SetWindowText(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), TranslateT("Show balloon popup (unsupported system)"));
+ }
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_TYPETRAY:
+ if (IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY)) {
+ if (!ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), TRUE);
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), TRUE);
+ }
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), FALSE);
+ }
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_SHOWNOTIFY:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEWIN), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPETRAY), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY)
+ && ServiceExists(MS_CLIST_SYSTRAY_NOTIFY));
+ //fall-thru
+ case IDC_TYPEWIN:
+ case IDC_NOTIFYTRAY:
+ case IDC_NOTIFYBALLOON:
+ case IDC_TYPINGSWITCH:
+ MarkChanges(4, hwndDlg);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((NMHDR *) lParam)->idFrom) {
+ case IDC_CLIST:
+ switch (((NMHDR *) lParam)->code) {
+ case CLN_OPTIONSCHANGED:
+ ResetCList(hwndDlg);
+ break;
+ case CLN_CHECKCHANGED:
+ MarkChanges(4, hwndDlg);
+ break;
+ }
+ break;
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ SaveList(hwndDlg, hItemNew, hItemUnknown);
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPING, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGWIN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TYPEWIN));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGNOWIN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NOTIFYTRAY));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGSWITCH, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TYPINGSWITCH));
+ ReloadGlobals();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ }
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+int OptInitialise(WPARAM wParam, LPARAM lParam)
+{
+ DWORD i;
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.position = 910000000;
+ odp.hInstance = g_hInst;
+ odp.pszTitle = LPGEN("Message Sessions");
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.nIDBottomSimpleControl = 0;
+ for (i = 0; i < SIZEOF(tabPages); i++) {
+ odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId);
+ odp.pfnDlgProc = tabPages[i].dlgProc;
+ odp.pszTab = (char*)tabPages[i].tabName;
+ Options_AddPage(wParam, &odp);
+ }
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGTYPE);
+ odp.pszGroup = LPGEN("Message Sessions");
+ odp.pszTitle = LPGEN("Typing Notify");
+ odp.pfnDlgProc = DlgProcTypeOptions;
+ odp.pszTab = NULL;
+ Options_AddPage(wParam, &odp);
+
+ return 0;
+}
diff --git a/plugins/Scriver/src/msgs.cpp b/plugins/Scriver/src/msgs.cpp new file mode 100644 index 0000000000..0971cfa0eb --- /dev/null +++ b/plugins/Scriver/src/msgs.cpp @@ -0,0 +1,697 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "statusicon.h"
+
+HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand, hDragCursor;
+
+HANDLE hMsgMenuItem, hHookWinEvt=NULL, hHookWinPopup=NULL;;
+
+extern HWND GetParentWindow(HANDLE hContact, BOOL bChat);
+
+PSLWA pSetLayeredWindowAttributes;
+
+#define EVENTTYPE_SCRIVER 2010
+#define SCRIVER_DB_GETEVENTTEXT "Scriver/GetText"
+
+static int SRMMStatusToPf2(int status)
+{
+ switch (status) {
+ case ID_STATUS_ONLINE:
+ return PF2_ONLINE;
+ case ID_STATUS_AWAY:
+ return PF2_SHORTAWAY;
+ case ID_STATUS_DND:
+ return PF2_HEAVYDND;
+ case ID_STATUS_NA:
+ return PF2_LONGAWAY;
+ case ID_STATUS_OCCUPIED:
+ return PF2_LIGHTDND;
+ case ID_STATUS_FREECHAT:
+ return PF2_FREECHAT;
+ case ID_STATUS_INVISIBLE:
+ return PF2_INVISIBLE;
+ case ID_STATUS_ONTHEPHONE:
+ return PF2_ONTHEPHONE;
+ case ID_STATUS_OUTTOLUNCH:
+ return PF2_OUTTOLUNCH;
+ case ID_STATUS_OFFLINE:
+ return MODEF_OFFLINE;
+ }
+ return 0;
+}
+
+int IsAutoPopup(HANDLE hContact) {
+ if (g_dat->flags & SMF_AUTOPOPUP) {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (strcmp(szProto, "MetaContacts") == 0 ) {
+ hContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)hContact, 0);
+ if (hContact != NULL) {
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+ }
+ }
+ if (szProto && (g_dat->openFlags & SRMMStatusToPf2(CallProtoService(szProto, PS_GETSTATUS, 0, 0)))) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static INT_PTR ReadMessageCommand(WPARAM wParam, LPARAM lParam)
+{
+ NewMessageWindowLParam newData = { 0 };
+ HWND hwndExisting;
+ HWND hParent;
+
+ hwndExisting = WindowList_Find(g_dat->hMessageWindowList, ((CLISTEVENT *) lParam)->hContact);
+ if (hwndExisting == NULL) {
+ newData.hContact = ((CLISTEVENT *) lParam)->hContact;
+ hParent = GetParentWindow(newData.hContact, FALSE);
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), hParent, DlgProcMessage, (LPARAM) & newData);
+ } else {
+ SendMessage(GetParent(hwndExisting), CM_POPUPWINDOW, 0, (LPARAM) hwndExisting);
+ }
+ return 0;
+}
+
+static int MessageEventAdded(WPARAM wParam, LPARAM lParam)
+{
+ DBEVENTINFO dbei = {0};
+ HWND hwnd;
+
+ dbei.cbSize = sizeof(dbei);
+ CallService(MS_DB_EVENT_GET, lParam, (LPARAM) & dbei);
+ if (dbei.eventType == EVENTTYPE_MESSAGE && (dbei.flags & DBEF_READ))
+ return 0;
+ hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam);
+ if (hwnd) {
+ SendMessage(hwnd, HM_DBEVENTADDED, wParam, lParam);
+ }
+ if (dbei.flags & DBEF_SENT || !DbEventIsMessageOrCustom(&dbei))
+ return 0;
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, wParam, (LPARAM) 1);
+ /* does a window for the contact exist? */
+ if (hwnd == NULL) {
+ /* new message */
+ SkinPlaySound("AlertMsg");
+ if (IsAutoPopup((HANDLE) wParam)) {
+ HWND hParent;
+ NewMessageWindowLParam newData = { 0 };
+ newData.hContact = (HANDLE) wParam;
+ hParent = GetParentWindow(newData.hContact, FALSE);
+ newData.flags = NMWLP_INCOMING;
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), hParent, DlgProcMessage, (LPARAM) & newData);
+ return 0;
+ }
+ }
+ if (hwnd == NULL || !IsWindowVisible(GetParent(hwnd)))
+ {
+ CLISTEVENT cle = {0};
+ TCHAR *contactName;
+ TCHAR toolTip[256];
+
+ cle.cbSize = sizeof(cle);
+ cle.flags = CLEF_TCHAR;
+ cle.hContact = (HANDLE) wParam;
+ cle.hDbEvent = (HANDLE) lParam;
+ cle.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ cle.pszService = "SRMsg/ReadMessage";
+ contactName = (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wParam, GCDNF_TCHAR);
+ mir_sntprintf(toolTip, SIZEOF(toolTip), TranslateT("Message from %s"), contactName);
+ cle.ptszTooltip = toolTip;
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM) & cle);
+ }
+ return 0;
+}
+
+static INT_PTR SendMessageCommandW(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+ NewMessageWindowLParam newData = { 0 };
+
+ {
+ /* does the HCONTACT's protocol support IM messages? */
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (szProto) {
+ if (!CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND)
+ return 1;
+ }
+ else {
+ /* unknown contact */
+ return 1;
+ } //if
+ }
+
+ if ((hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam))) {
+ if (lParam) {
+ HWND hEdit;
+ hEdit = GetDlgItem(hwnd, IDC_MESSAGE);
+ SendMessage(hEdit, EM_SETSEL, -1, SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0));
+/*
+ SETTEXTEX st;
+ st.flags = ST_SELECTION;
+ st.codepage = 1200;
+ SendMessage(hEdit, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)lParam);
+*/
+ SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM) (TCHAR *) lParam);
+ }
+ SendMessage(GetParent(hwnd), CM_POPUPWINDOW, 0, (LPARAM) hwnd);
+ } else {
+ HWND hParent;
+ newData.hContact = (HANDLE) wParam;
+ newData.szInitialText = (const char *) lParam;
+ newData.isWchar = 1;
+ hParent = GetParentWindow(newData.hContact, FALSE);
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), hParent, DlgProcMessage, (LPARAM) & newData);
+ }
+ return 0;
+}
+
+static INT_PTR SendMessageCommand(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+ NewMessageWindowLParam newData = { 0 };
+
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ //logInfo("Show message window for: %s (%s)", CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wParam, 0), szProto);
+ if (szProto) {
+ /* does the HCONTACT's protocol support IM messages? */
+ if (!CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND)
+ return 1;
+ }
+ else {
+ /* unknown contact */
+ return 1;
+ } //if
+ }
+
+ if ((hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam))) {
+ if (lParam) {
+ HWND hEdit;
+ hEdit = GetDlgItem(hwnd, IDC_MESSAGE);
+ SendMessage(hEdit, EM_SETSEL, -1, SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0));
+/*
+ SETTEXTEX st;
+ st.flags = ST_SELECTION;
+ st.codepage = CP_ACP;
+ SendMessage(hEdit, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)lParam);
+*/
+ SendMessageA(hEdit, EM_REPLACESEL, FALSE, (LPARAM) (char *) lParam);
+ }
+ SendMessage(GetParent(hwnd), CM_POPUPWINDOW, 0, (LPARAM) hwnd);
+ } else {
+ HWND hParent;
+ newData.hContact = (HANDLE) wParam;
+ newData.szInitialText = (const char *) lParam;
+ newData.isWchar = 0;
+ hParent = GetParentWindow(newData.hContact, FALSE);
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), hParent, DlgProcMessage, (LPARAM) & newData);
+ }
+ return 0;
+}
+
+static INT_PTR TypingMessageCommand(WPARAM wParam, LPARAM lParam)
+{
+ CLISTEVENT *cle = (CLISTEVENT *) lParam;
+
+ if (!cle)
+ return 0;
+ SendMessageCommand((WPARAM) cle->hContact, 0);
+ return 0;
+}
+
+static int TypingMessage(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+
+ if (!(g_dat->flags2&SMF2_SHOWTYPING))
+ return 0;
+ if ((hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam))) {
+ SendMessage(hwnd, DM_TYPING, 0, lParam);
+ } else if ((int) lParam && (g_dat->flags2&SMF2_SHOWTYPINGTRAY)) {
+ TCHAR szTip[256];
+
+ mir_sntprintf(szTip, SIZEOF(szTip), TranslateT("%s is typing a message"), (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wParam, GCDNF_TCHAR));
+ if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY) && !(g_dat->flags2&SMF2_SHOWTYPINGCLIST)) {
+ MIRANDASYSTRAYNOTIFY tn;
+ tn.szProto = NULL;
+ tn.cbSize = sizeof(tn);
+ tn.tszInfoTitle = TranslateT("Typing Notification");
+ tn.tszInfo = szTip;
+ tn.dwInfoFlags = NIIF_INFO | NIIF_INTERN_UNICODE;
+ tn.uTimeout = 1000 * 4;
+ CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM) & tn);
+ }
+ else {
+ CLISTEVENT cle = {0};
+
+ cle.cbSize = sizeof(cle);
+ cle.hContact = (HANDLE) wParam;
+ cle.hDbEvent = (HANDLE) 1;
+ cle.flags = CLEF_ONLYAFEW | CLEF_TCHAR;
+ cle.hIcon = GetCachedIcon("scriver_TYPING");
+ cle.pszService = "SRMsg/TypingMessage";
+ cle.ptszTooltip = szTip;
+ CallServiceSync(MS_CLIST_REMOVEEVENT, wParam, (LPARAM) 1);
+ CallServiceSync(MS_CLIST_ADDEVENT, wParam, (LPARAM) & cle);
+ }
+ }
+ return 0;
+}
+
+static int MessageSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+ char *szProto;
+
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (lstrcmpA(cws->szModule, "CList") && (szProto == NULL || lstrcmpA(cws->szModule, szProto)))
+ return 0;
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_CLISTSETTINGSCHANGED, wParam, lParam);
+ return 0;
+}
+
+static int ContactDeleted(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+
+ if ((hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam))) {
+ SendMessage(hwnd, WM_CLOSE, 0, 0);
+ }
+ return 0;
+}
+
+static void RestoreUnreadMessageAlerts(void)
+{
+ CLISTEVENT cle = { 0 };
+ DBEVENTINFO dbei = { 0 };
+ TCHAR toolTip[256];
+ int windowAlreadyExists;
+ HANDLE hDbEvent, hContact;
+
+ dbei.cbSize = sizeof(dbei);
+ cle.cbSize = sizeof(cle);
+ cle.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ cle.pszService = "SRMsg/ReadMessage";
+ cle.flags = CLEF_TCHAR;
+ cle.ptszTooltip = toolTip;
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) {
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) hContact, 0);
+ while (hDbEvent) {
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) & dbei);
+ if (!(dbei.flags & (DBEF_SENT | DBEF_READ)) && DbEventIsMessageOrCustom(&dbei)) {
+ windowAlreadyExists = WindowList_Find(g_dat->hMessageWindowList, hContact) != NULL;
+ if (windowAlreadyExists)
+ continue;
+
+ if (IsAutoPopup(hContact) && !windowAlreadyExists) {
+ HWND hParent;
+ NewMessageWindowLParam newData = { 0 };
+ newData.hContact = hContact;
+ newData.flags = NMWLP_INCOMING;
+ hParent = GetParentWindow(newData.hContact, FALSE);
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), hParent, DlgProcMessage, (LPARAM) & newData);
+// CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), NULL, DlgProcMessage, (LPARAM) & newData);
+ }
+ else {
+ cle.hContact = hContact;
+ cle.hDbEvent = hDbEvent;
+ mir_sntprintf(toolTip, SIZEOF(toolTip), TranslateT("Message from %s"), (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR));
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM) & cle);
+ }
+ }
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hDbEvent, 0);
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+}
+
+static INT_PTR GetWindowAPI(WPARAM wParam, LPARAM lParam)
+{
+ return PLUGIN_MAKE_VERSION(0,0,0,3);
+}
+
+static INT_PTR GetWindowClass(WPARAM wParam, LPARAM lParam)
+{
+ char *szBuf = (char*)wParam;
+ int size = (int)lParam;
+ mir_snprintf(szBuf, size, "Scriver");
+ return 0;
+}
+
+static INT_PTR GetWindowData(WPARAM wParam, LPARAM lParam)
+{
+ MessageWindowInputData *mwid = (MessageWindowInputData*)wParam;
+ MessageWindowData *mwd = (MessageWindowData*)lParam;
+ HWND hwnd;
+
+ if (mwid == NULL || mwd == NULL) return 1;
+ if (mwid->cbSize != sizeof(MessageWindowInputData) || mwd->cbSize != sizeof(SrmmWindowData)) return 1;
+ if (mwid->hContact == NULL) return 1;
+ if (mwid->uFlags != MSG_WINDOW_UFLAG_MSG_BOTH) return 1;
+ hwnd = WindowList_Find(g_dat->hMessageWindowList, mwid->hContact);
+ if (hwnd == NULL)
+ hwnd = SM_FindWindowByContact(mwid->hContact);
+ mwd->uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+ mwd->hwndWindow = hwnd;
+ mwd->local = 0;
+ mwd->uState = SendMessage(hwnd, DM_GETWINDOWSTATE, 0, 0);
+ return 0;
+}
+
+static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+ if ( hContact ) {
+ char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(CLISTMENUITEM);
+ clmi.flags = CMIM_FLAGS | CMIF_DEFAULT | CMIF_HIDDEN;
+
+ if ( szProto ) {
+ // leave this menu item hidden for chats
+ if ( !DBGetContactSettingByte( hContact, szProto, "ChatRoom", 0 ))
+ if ( CallProtoService( szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND )
+ clmi.flags &= ~CMIF_HIDDEN;
+ }
+
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMsgMenuItem, ( LPARAM )&clmi );
+ }
+ return 0;
+}
+
+static int AvatarChanged(WPARAM wParam, LPARAM lParam) {
+ if (wParam == 0) { // protocol picture has changed...
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_AVATARCHANGED, wParam, lParam);
+ } else {
+ HWND hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE)wParam);
+ SendMessage(hwnd, DM_AVATARCHANGED, wParam, lParam);
+ }
+ return 0;
+}
+
+static void RegisterStatusIcons() {
+ StatusIconData sid;
+ sid.cbSize = sizeof(sid);
+ sid.szModule = SRMMMOD;
+
+ sid.dwId = 1;
+ sid.hIcon = CopyIcon(GetCachedIcon("scriver_TYPING"));
+ sid.hIconDisabled = CopyIcon(GetCachedIcon("scriver_TYPINGOFF"));
+ sid.flags = MBF_HIDDEN;
+ sid.szTooltip = NULL;
+ AddStickyStatusIcon((WPARAM) 0, (LPARAM) &sid);
+}
+
+void ChangeStatusIcons() {
+ StatusIconData sid;
+ sid.cbSize = sizeof(sid);
+ sid.szModule = SRMMMOD;
+ sid.dwId = 0;
+ sid.hIcon = CopyIcon(GetCachedIcon("scriver_UNICODEON"));
+ sid.hIconDisabled = CopyIcon(GetCachedIcon("scriver_UNICODEOFF"));
+ sid.flags = 0;
+ sid.szTooltip = NULL;
+ ModifyStatusIcon((WPARAM)NULL, (LPARAM) &sid);
+
+ sid.dwId = 1;
+ sid.hIcon = CopyIcon(GetCachedIcon("scriver_TYPING"));
+ sid.hIconDisabled = CopyIcon(GetCachedIcon("scriver_TYPINGOFF"));
+ sid.flags = MBF_HIDDEN;
+ sid.szTooltip = NULL;
+ ModifyStatusIcon((WPARAM)NULL, (LPARAM) &sid);
+}
+
+int StatusIconPressed(WPARAM wParam, LPARAM lParam) {
+// HANDLE hContact = (HANDLE) wParam;
+ StatusIconClickData *sicd = (StatusIconClickData *) lParam;
+ HWND hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE)wParam);
+ if (hwnd == NULL) {
+ hwnd = SM_FindWindowByContact((HANDLE)wParam);
+
+ }
+ if (hwnd != NULL) {
+ if (!strcmp(SRMMMOD, sicd->szModule)) {
+ if (sicd->dwId == 0 && g_dat->hMenuANSIEncoding) {
+ if (sicd->flags & MBCF_RIGHTBUTTON) {
+ int codePage = (int) SendMessage(hwnd, DM_GETCODEPAGE, 0, 0);
+ if (codePage != 1200) {
+ int i, iSel;
+ for (i = 0; i < GetMenuItemCount(g_dat->hMenuANSIEncoding); i++) {
+ CheckMenuItem (g_dat->hMenuANSIEncoding, i, MF_BYPOSITION | MF_UNCHECKED);
+ }
+ if (codePage == CP_ACP) {
+ CheckMenuItem(g_dat->hMenuANSIEncoding, 0, MF_BYPOSITION | MF_CHECKED);
+ } else {
+ CheckMenuItem(g_dat->hMenuANSIEncoding, codePage, MF_BYCOMMAND | MF_CHECKED);
+ }
+ iSel = TrackPopupMenu(g_dat->hMenuANSIEncoding, TPM_RETURNCMD, sicd->clickLocation.x, sicd->clickLocation.y, 0, GetParent(hwnd), NULL);
+ if (iSel >= 500) {
+ if (iSel == 500) iSel = CP_ACP;
+ SendMessage(hwnd, DM_SETCODEPAGE, 0, iSel);
+ }
+ }
+ }
+ } else {
+ SendMessage(hwnd, DM_SWITCHTYPING, 0, 0);
+ }
+ }
+ }
+ return 0;
+}
+
+
+static int OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ CLISTMENUITEM mi;
+ ReloadGlobals();
+ RegisterIcons();
+ RegisterFontServiceFonts();
+ RegisterKeyBindings();
+ LoadGlobalIcons();
+ LoadMsgLogIcons();
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.position = -2000090000;
+ if ( ServiceExists( MS_SKIN2_GETICONBYHANDLE )) {
+ mi.flags = CMIF_ICONFROMICOLIB | CMIF_DEFAULT;
+ mi.icolibItem = LoadSkinnedIconHandle( SKINICON_EVENT_MESSAGE );
+ }
+ else {
+ mi.flags = CMIF_DEFAULT;
+ mi.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ }
+ mi.pszName = LPGEN("&Message");
+ mi.pszService = MS_MSG_SENDMESSAGE;
+ hMsgMenuItem = Menu_AddContactMenuItem(&mi);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)mi.hIcon, 0);
+
+ HookEvent_Ex(ME_SMILEYADD_OPTIONSCHANGED, SmileySettingsChanged);
+ HookEvent_Ex(ME_IEVIEW_OPTIONSCHANGED, SmileySettingsChanged);
+ HookEvent_Ex(ME_AV_AVATARCHANGED, AvatarChanged);
+ HookEvent_Ex(ME_FONT_RELOAD, FontServiceFontsChanged);
+ HookEvent_Ex(ME_MSG_ICONPRESSED, StatusIconPressed);
+
+ RestoreUnreadMessageAlerts();
+ Chat_ModulesLoaded(wParam, lParam);
+ RegisterStatusIcons();
+ return 0;
+}
+
+int OnSystemPreshutdown(WPARAM wParam, LPARAM lParam)
+{
+ Chat_PreShutdown(wParam, lParam);
+ WindowList_BroadcastAsync(g_dat->hMessageWindowList, WM_CLOSE, 0, 0);
+ DeinitStatusIcons();
+ return 0;
+}
+
+int OnUnloadModule(void)
+{
+ Chat_Unload();
+ DestroyCursor(hCurSplitNS);
+ DestroyCursor(hCurHyperlinkHand);
+ DestroyCursor(hCurSplitWE);
+ DestroyCursor(hDragCursor);
+ UnhookEvents_Ex();
+ DestroyServices_Ex();
+ DestroyHookableEvent(hHookWinEvt);
+ DestroyHookableEvent(hHookWinPopup);
+ ReleaseIcons();
+ FreeMsgLogIcons();
+ FreeLibrary(GetModuleHandleA("riched20.dll"));
+ OleUninitialize();
+ RichUtil_Unload();
+ FreeGlobals();
+ return 0;
+}
+
+int OnLoadModule(void) {
+ HMODULE hDLL = 0;
+ if (LoadLibraryA("riched20.dll") == NULL) {
+ if (IDYES !=
+ MessageBox(0,
+ TranslateT
+ ("Miranda could not load the built-in message module, riched20.dll is missing. If you are using Windows 95 or WINE please make sure you have riched20.dll installed. Press 'Yes' to continue loading Miranda."),
+ TranslateT("Information"), MB_YESNO | MB_ICONINFORMATION))
+ return 1;
+ return 0;
+ }
+ hDLL = GetModuleHandle(_T("user32"));
+ pSetLayeredWindowAttributes = (PSLWA) GetProcAddress(hDLL,"SetLayeredWindowAttributes");
+
+ InitGlobals();
+ RichUtil_Load();
+ OleInitialize(NULL);
+ InitStatusIcons();
+
+ HookEvent_Ex(ME_OPT_INITIALISE, OptInitialise);
+ HookEvent_Ex(ME_DB_EVENT_ADDED, MessageEventAdded);
+ HookEvent_Ex(ME_DB_CONTACT_SETTINGCHANGED, MessageSettingChanged);
+ HookEvent_Ex(ME_DB_CONTACT_DELETED, ContactDeleted);
+ HookEvent_Ex(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+ HookEvent_Ex(ME_SKIN_ICONSCHANGED, IconsChanged);
+ HookEvent_Ex(ME_PROTO_CONTACTISTYPING, TypingMessage);
+ HookEvent_Ex(ME_SYSTEM_PRESHUTDOWN, OnSystemPreshutdown);
+ HookEvent_Ex(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu);
+
+ CreateServiceFunction_Ex(MS_MSG_SENDMESSAGE, SendMessageCommand);
+ CreateServiceFunction_Ex(MS_MSG_SENDMESSAGEW, SendMessageCommandW);
+ CreateServiceFunction_Ex(MS_MSG_GETWINDOWAPI, GetWindowAPI);
+ CreateServiceFunction_Ex(MS_MSG_GETWINDOWCLASS, GetWindowClass);
+ CreateServiceFunction_Ex(MS_MSG_GETWINDOWDATA, GetWindowData);
+ CreateServiceFunction_Ex("SRMsg/ReadMessage", ReadMessageCommand);
+ CreateServiceFunction_Ex("SRMsg/TypingMessage", TypingMessageCommand);
+
+ hHookWinEvt = CreateHookableEvent(ME_MSG_WINDOWEVENT);
+ hHookWinPopup = CreateHookableEvent(ME_MSG_WINDOWPOPUP);
+ SkinAddNewSoundEx("RecvMsgActive", LPGEN("Instant messages"), LPGEN("Incoming (Focused Window)"));
+ SkinAddNewSoundEx("RecvMsgInactive", LPGEN("Instant messages"), LPGEN("Incoming (Unfocused Window)"));
+ SkinAddNewSoundEx("AlertMsg", LPGEN("Instant messages"), LPGEN("Incoming (New Session)"));
+ SkinAddNewSoundEx("SendMsg", LPGEN("Instant messages"), LPGEN("Outgoing"));
+ hCurSplitNS = LoadCursor(NULL, IDC_SIZENS);
+ hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE);
+ hCurHyperlinkHand = LoadCursor(NULL, IDC_HAND);
+ if (hCurHyperlinkHand == NULL)
+ hCurHyperlinkHand = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_HYPERLINKHAND));
+ hDragCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DRAGCURSOR));
+
+
+ Chat_Load();
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+CREOleCallback reOleCallback, reOleCallback2;
+
+STDMETHODIMP CREOleCallback::QueryInterface(REFIID riid, LPVOID * ppvObj)
+{
+ if (IsEqualIID(riid, IID_IRichEditOleCallback)) {
+ *ppvObj = this;
+ AddRef();
+ return S_OK;
+ }
+ *ppvObj = NULL;
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG) CREOleCallback::AddRef()
+{
+ if (refCount == 0) {
+ if (S_OK != StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &pictStg))
+ pictStg = NULL;
+ nextStgId = 0;
+ }
+ return ++refCount;
+}
+
+STDMETHODIMP_(ULONG) CREOleCallback::Release()
+{
+ if (--refCount == 0) {
+ if (pictStg)
+ pictStg->Release();
+ }
+ return refCount;
+}
+
+STDMETHODIMP CREOleCallback::ContextSensitiveHelp(BOOL fEnterMode)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CREOleCallback::DeleteObject(LPOLEOBJECT lpoleobj)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CREOleCallback::GetClipboardData(CHARRANGE * lpchrg, DWORD reco, LPDATAOBJECT * lplpdataobj)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CREOleCallback::GetContextMenu(WORD seltype, LPOLEOBJECT lpoleobj, CHARRANGE * lpchrg, HMENU * lphmenu)
+{
+ return E_INVALIDARG;
+}
+
+STDMETHODIMP CREOleCallback::GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CREOleCallback::GetInPlaceContext(LPOLEINPLACEFRAME * lplpFrame, LPOLEINPLACEUIWINDOW * lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+ return E_INVALIDARG;
+}
+
+STDMETHODIMP CREOleCallback::GetNewStorage(LPSTORAGE * lplpstg)
+{
+ WCHAR szwName[64];
+ char szName[64];
+ wsprintfA(szName, "s%u", nextStgId++);
+ MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, SIZEOF(szwName));
+ if (pictStg == NULL)
+ return STG_E_MEDIUMFULL;
+ return pictStg->CreateStorage(szwName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, lplpstg);
+}
+
+STDMETHODIMP CREOleCallback::QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT * lpcfFormat, DWORD reco, BOOL fReally, HGLOBAL hMetaPict)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CREOleCallback::QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CREOleCallback::ShowContainerUI(BOOL fShow)
+{
+ return S_OK;
+}
\ No newline at end of file diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h new file mode 100644 index 0000000000..e17c63897d --- /dev/null +++ b/plugins/Scriver/src/msgs.h @@ -0,0 +1,428 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef SRMM_MSGS_H
+#define SRMM_MSGS_H
+
+#include <richedit.h>
+#include <richole.h>
+#include "sendqueue.h"
+#include "infobar.h"
+#define MSGERROR_CANCEL 0
+#define MSGERROR_RETRY 1
+#define MSGERROR_DONE 2
+
+typedef DWORD (WINAPI *PSLWA)(HWND, DWORD, BYTE, DWORD);
+extern PSLWA pSetLayeredWindowAttributes;
+
+typedef struct ToolbarButtonStruct
+{
+ TCHAR *name;
+ UINT controlId;
+ int alignment;
+ int spacing;
+ int width;
+}ToolbarButton;
+
+typedef struct ErrorWindowDataStruct
+{
+ TCHAR* szName;
+ TCHAR* szDescription;
+ TCHAR* szText;
+ MessageSendQueueItem* queueItem;
+ HWND hwndParent;
+} ErrorWindowData;
+
+typedef struct TabCtrlDataStruct
+{
+ int lastClickTime;
+ WPARAM clickWParam;
+ LPARAM clickLParam;
+ POINT mouseLBDownPos;
+ HIMAGELIST hDragImageList;
+ int bDragging;
+ int bDragged;
+ int destTab;
+ int srcTab;
+} TabCtrlData;
+
+typedef struct ParentWindowDataStruct
+{
+ HWND hwnd;
+ HANDLE hContact;
+ struct ParentWindowDataStruct *prev;
+ struct ParentWindowDataStruct *next;
+ int childrenCount;
+ HWND hwndActive;
+ HWND hwndStatus;
+ HWND hwndTabs;
+ DWORD flags2;
+ RECT childRect;
+ POINT mouseLBDownPos;
+ int mouseLBDown;
+ int nFlash;
+ int nFlashMax;
+ int bMinimized;
+ int bVMaximized;
+ int bTopmost;
+ int windowWasCascaded;
+ TabCtrlData *tabCtrlDat;
+ BOOL isChat;
+}ParentWindowData;
+
+typedef struct MessageWindowTabDataStruct
+{
+ HWND hwnd;
+ HANDLE hContact;
+ char *szProto;
+ ParentWindowData *parent;
+ HICON hIcon;
+}MessageWindowTabData;
+
+#define NMWLP_INCOMING 1
+
+typedef struct NewMessageWindowLParamStruct
+{
+ HANDLE hContact;
+ BOOL isChat;
+ int isWchar;
+ const char *szInitialText;
+ int flags;
+} NewMessageWindowLParam;
+
+#define CWDF_RTF_INPUT 1
+
+typedef struct CommonWindowDataStruct {
+ HANDLE hContact;
+ TCmdList *cmdList;
+ TCmdList *cmdListCurrent;
+ int codePage;
+ DWORD flags;
+ HWND hwndLog;
+ int minLogBoxHeight;
+ int minEditBoxHeight;
+}CommonWindowData;
+
+struct SrmmWindowData
+{
+ HWND hwnd;
+ int tabId;
+ ParentWindowData *parent;
+ HWND hwndParent;
+ HANDLE hDbEventFirst, hDbEventLast, hDbUnreadEventFirst;
+ int splitterPos;
+ int desiredInputAreaHeight;
+ SIZE toolbarSize;
+ int windowWasCascaded;
+ int nTypeSecs;
+ int nTypeMode;
+ HBITMAP avatarPic;
+ DWORD nLastTyping;
+ int showTyping;
+ int showUnread;
+ DWORD lastMessage;
+ char *szProto;
+ WORD wStatus;
+ time_t startTime;
+ time_t lastEventTime;
+ int lastEventType;
+ DWORD flags;
+ int messagesInProgress;
+ struct avatarCacheEntry *ace;
+ int isMixed;
+ int sendAllConfirm;
+ HICON statusIcon;
+ HICON statusIconBig;
+ HICON statusIconOverlay;
+ CommonWindowData windowData;
+ InfobarWindowData* infobarData;
+};
+
+
+#define HM_DBEVENTADDED (WM_USER+10)
+#define DM_REMAKELOG (WM_USER+11)
+#define DM_CASCADENEWWINDOW (WM_USER+13)
+#define DM_OPTIONSAPPLIED (WM_USER+14)
+#define DM_SPLITTERMOVED (WM_USER+15)
+#define DM_APPENDTOLOG (WM_USER+17)
+#define DM_ERRORDECIDED (WM_USER+18)
+#define DM_SCROLLLOGTOBOTTOM (WM_USER+19)
+#define DM_TYPING (WM_USER+20)
+#define DM_UPDATELASTMESSAGE (WM_USER+22)
+#define DM_USERNAMETOCLIP (WM_USER+23)
+#define DM_CHANGEICONS (WM_USER+24)
+#define DM_UPDATEICON (WM_USER+25)
+#define DM_GETAVATAR (WM_USER+27)
+#define HM_ACKEVENT (WM_USER+29)
+
+#define DM_SENDMESSAGE (WM_USER+30)
+#define DM_STARTMESSAGESENDING (WM_USER+31)
+#define DM_SHOWMESSAGESENDING (WM_USER+32)
+#define DM_STOPMESSAGESENDING (WM_USER+33)
+#define DM_SHOWERRORMESSAGE (WM_USER+34)
+
+#define DM_CLEARLOG (WM_USER+46)
+#define DM_SWITCHSTATUSBAR (WM_USER+47)
+#define DM_SWITCHTOOLBAR (WM_USER+48)
+#define DM_SWITCHTITLEBAR (WM_USER+49)
+#define DM_SWITCHINFOBAR (WM_USER+50)
+#define DM_SWITCHRTL (WM_USER+51)
+#define DM_SWITCHTYPING (WM_USER+53)
+#define DM_MESSAGESENDING (WM_USER+54)
+#define DM_GETWINDOWSTATE (WM_USER+55)
+#define DM_STATUSICONCHANGE (WM_USER+56)
+
+#define DM_MYAVATARCHANGED (WM_USER+62)
+#define DM_PROTOAVATARCHANGED (WM_USER+63)
+#define DM_AVATARCHANGED (WM_USER+64)
+
+#define EM_SUBCLASSED (WM_USER+0x101)
+#define EM_UNSUBCLASSED (WM_USER+0x102)
+
+#define EVENTTYPE_JABBER_CHATSTATES 2000
+#define EVENTTYPE_JABBER_PRESENCE 2001
+#define EVENTTYPE_STATUSCHANGE 25368
+
+struct CREOleCallback : public IRichEditOleCallback
+{
+ CREOleCallback() : refCount(0) {}
+ unsigned refCount;
+ IStorage *pictStg;
+ int nextStgId;
+
+ STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * lplpObj);
+ STDMETHOD_(ULONG,AddRef) (THIS);
+ STDMETHOD_(ULONG,Release) (THIS);
+
+ STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);
+ STDMETHOD(GetNewStorage) (LPSTORAGE FAR * lplpstg);
+ STDMETHOD(GetInPlaceContext) (LPOLEINPLACEFRAME FAR * lplpFrame, LPOLEINPLACEUIWINDOW FAR * lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo);
+ STDMETHOD(ShowContainerUI) (BOOL fShow);
+ STDMETHOD(QueryInsertObject) (LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp);
+ STDMETHOD(DeleteObject) (LPOLEOBJECT lpoleobj);
+ STDMETHOD(QueryAcceptData) (LPDATAOBJECT lpdataobj, CLIPFORMAT FAR * lpcfFormat, DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
+ STDMETHOD(GetClipboardData) (CHARRANGE FAR * lpchrg, DWORD reco, LPDATAOBJECT FAR * lplpdataobj);
+ STDMETHOD(GetDragDropEffect) (BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect);
+ STDMETHOD(GetContextMenu) (WORD seltype, LPOLEOBJECT lpoleobj, CHARRANGE FAR * lpchrg, HMENU FAR * lphmenu) ;
+};
+
+INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+int DbEventIsShown(DBEVENTINFO * dbei, struct SrmmWindowData *dat);
+int DbEventIsCustomForMsgWindow(DBEVENTINFO *dbei);
+int DbEventIsMessageOrCustom(DBEVENTINFO *dbei);
+int safe_wcslen(wchar_t *msg, int maxLen);
+void StreamInEvents(HWND hwndDlg, HANDLE hDbEventFirst, int count, int fAppend);
+void LoadMsgLogIcons(void);
+void FreeMsgLogIcons(void);
+TCHAR *GetNickname(HANDLE hContact, const char* szProto);
+int IsAutoPopup(HANDLE hContact);
+
+#define MSGFONTID_MYMSG 0
+#define MSGFONTID_YOURMSG 1
+#define MSGFONTID_MYNAME 2
+#define MSGFONTID_MYTIME 3
+#define MSGFONTID_MYCOLON 4
+#define MSGFONTID_YOURNAME 5
+#define MSGFONTID_YOURTIME 6
+#define MSGFONTID_YOURCOLON 7
+#define MSGFONTID_MESSAGEAREA 8
+#define MSGFONTID_NOTICE 9
+#define MSGFONTID_MYURL 10
+#define MSGFONTID_YOURURL 11
+#define MSGFONTID_INFOBAR_NAME 12
+#define MSGFONTID_INFOBAR_STATUS 13
+
+void LoadMsgDlgFont(int i, LOGFONT * lf, COLORREF * colour, BOOL chatMode);
+extern int fontOptionsListSize;
+
+#define LOADHISTORY_UNREAD 0
+#define LOADHISTORY_COUNT 1
+#define LOADHISTORY_TIME 2
+
+#define SRMMMOD "SRMM"
+
+#define SRMSGSET_USETABS "UseTabs"
+#define SRMSGDEFSET_USETABS 1
+#define SRMSGSET_TABSATBOTTOM "TabsPosition"
+#define SRMSGDEFSET_TABSATBOTTOM 0
+#define SRMSGSET_LIMITNAMES "LimitNamesOnTabs"
+#define SRMSGDEFSET_LIMITNAMES 1
+#define SRMSGSET_LIMITNAMESLEN "LimitNamesLength"
+#define SRMSGDEFSET_LIMITNAMESLEN 20
+#define SRMSGSET_LIMITNAMESLEN_MIN 0
+#define SRMSGSET_SEPARATECHATSCONTAINERS "SeparateChatsContainers"
+#define SRMSGDEFSET_SEPARATECHATSCONTAINERS 0
+#define SRMSGSET_LIMITTABS "LimitTabs"
+#define SRMSGDEFSET_LIMITTABS 0
+#define SRMSGSET_LIMITTABSNUM "LimitTabsNum"
+#define SRMSGDEFSET_LIMITTABSNUM 10
+#define SRMSGSET_LIMITCHATSTABS "LimitChatsTabs"
+#define SRMSGDEFSET_LIMITCHATSTABS 0
+#define SRMSGSET_LIMITCHATSTABSNUM "LimitChatsTabsNum"
+#define SRMSGDEFSET_LIMITCHATSTABSNUM 10
+
+#define SRMSGSET_CASCADE "Cascade"
+#define SRMSGDEFSET_CASCADE 1
+#define SRMSGSET_SAVEPERCONTACT "SavePerContact"
+#define SRMSGDEFSET_SAVEPERCONTACT 0
+#define SRMSGSET_SHOWTITLEBAR "ShowTitleBar"
+#define SRMSGDEFSET_SHOWTITLEBAR 1
+#define SRMSGSET_SHOWSTATUSBAR "ShowStatusBar"
+#define SRMSGDEFSET_SHOWSTATUSBAR 1
+#define SRMSGSET_SHOWINFOBAR "ShowInfoBar"
+#define SRMSGDEFSET_SHOWINFOBAR 1
+#define SRMSGSET_TOPMOST "Topmost"
+#define SRMSGDEFSET_TOPMOST 0
+#define SRMSGSET_POPFLAGS "PopupFlags"
+#define SRMSGDEFSET_POPFLAGS 0
+#define SRMSGSET_SHOWBUTTONLINE "ShowButtonLine"
+#define SRMSGDEFSET_SHOWBUTTONLINE 1
+#define SRMSGSET_SHOWINFOLINE "ShowInfoLine"
+#define SRMSGDEFSET_SHOWINFOLINE 1
+#define SRMSGSET_SHOWPROGRESS "ShowProgress"
+#define SRMSGDEFSET_SHOWPROGRESS 0
+#define SRMSGSET_AUTOPOPUP "AutoPopupMsg"
+#define SRMSGDEFSET_AUTOPOPUP 0
+#define SRMSGSET_STAYMINIMIZED "StayMinimized"
+#define SRMSGDEFSET_STAYMINIMIZED 0
+#define SRMSGSET_SWITCHTOACTIVE "SwitchToActiveTab"
+#define SRMSGDEFSET_SWITCHTOACTIVE 0
+#define SRMSGSET_AUTOMIN "AutoMin"
+#define SRMSGDEFSET_AUTOMIN 0
+#define SRMSGSET_AUTOCLOSE "AutoClose"
+#define SRMSGDEFSET_AUTOCLOSE 0
+#define SRMSGSET_SENDONENTER "SendOnEnter"
+#define SRMSGDEFSET_SENDONENTER 1
+#define SRMSGSET_SENDONDBLENTER "SendOnDblEnter"
+#define SRMSGDEFSET_SENDONDBLENTER 0
+#define SRMSGSET_STATUSICON "UseStatusWinIcon"
+#define SRMSGDEFSET_STATUSICON 0
+#define SRMSGSET_SENDBUTTON "UseSendButton"
+#define SRMSGDEFSET_SENDBUTTON 0
+#define SRMSGSET_CHARCOUNT "ShowCharCount"
+#define SRMSGDEFSET_CHARCOUNT 0
+#define SRMSGSET_CTRLSUPPORT "SupportCtrlUpDn"
+#define SRMSGDEFSET_CTRLSUPPORT 1
+#define SRMSGSET_DELTEMP "DeleteTempCont"
+#define SRMSGDEFSET_DELTEMP 0
+#define SRMSGSET_MSGTIMEOUT "MessageTimeout"
+#define SRMSGDEFSET_MSGTIMEOUT 10000
+#define SRMSGSET_MSGTIMEOUT_MIN 4000 // minimum value (4 seconds)
+#define SRMSGSET_FLASHCOUNT "FlashMax"
+#define SRMSGDEFSET_FLASHCOUNT 3
+
+#define SRMSGSET_LOADHISTORY "LoadHistory"
+#define SRMSGDEFSET_LOADHISTORY LOADHISTORY_UNREAD
+#define SRMSGSET_LOADCOUNT "LoadCount"
+#define SRMSGDEFSET_LOADCOUNT 10
+#define SRMSGSET_LOADTIME "LoadTime"
+#define SRMSGDEFSET_LOADTIME 10
+
+#define SRMSGSET_USELONGDATE "UseLongDate"
+#define SRMSGDEFSET_USELONGDATE 0
+#define SRMSGSET_SHOWSECONDS "ShowSeconds"
+#define SRMSGDEFSET_SHOWSECONDS 1
+#define SRMSGSET_USERELATIVEDATE "UseRelativeDate"
+#define SRMSGDEFSET_USERELATIVEDATE 0
+
+#define SRMSGSET_GROUPMESSAGES "GroupMessages"
+#define SRMSGDEFSET_GROUPMESSAGES 0
+#define SRMSGSET_MARKFOLLOWUPS "MarkFollowUps"
+#define SRMSGDEFSET_MARKFOLLOWUPS 0
+#define SRMSGSET_MESSAGEONNEWLINE "MessageOnNewLine"
+#define SRMSGDEFSET_MESSAGEONNEWLINE 0
+#define SRMSGSET_DRAWLINES "DrawLines"
+#define SRMSGDEFSET_DRAWLINES 0
+#define SRMSGSET_LINECOLOUR "LineColour"
+#define SRMSGDEFSET_LINECOLOUR GetSysColor(COLOR_WINDOW)
+
+#define SRMSGSET_INDENTTEXT "IndentText"
+#define SRMSGDEFSET_INDENTTEXT 0
+#define SRMSGSET_INDENTSIZE "IndentSize"
+#define SRMSGDEFSET_INDENTSIZE 0
+
+#define SRMSGSET_SHOWLOGICONS "ShowLogIcon"
+#define SRMSGDEFSET_SHOWLOGICONS 1
+#define SRMSGSET_HIDENAMES "HideNames"
+#define SRMSGDEFSET_HIDENAMES 1
+#define SRMSGSET_SHOWTIME "ShowTime"
+#define SRMSGDEFSET_SHOWTIME 1
+#define SRMSGSET_SHOWDATE "ShowDate"
+#define SRMSGDEFSET_SHOWDATE 0
+#define SRMSGSET_SHOWSTATUSCH "ShowStatusChanges"
+#define SRMSGDEFSET_SHOWSTATUSCH 1
+#define SRMSGSET_BKGCOLOUR "BkgColour"
+#define SRMSGDEFSET_BKGCOLOUR GetSysColor(COLOR_WINDOW)
+#define SRMSGSET_INPUTBKGCOLOUR "InputBkgColour"
+#define SRMSGDEFSET_INPUTBKGCOLOUR GetSysColor(COLOR_WINDOW)
+#define SRMSGSET_INCOMINGBKGCOLOUR "IncomingBkgColour"
+#define SRMSGDEFSET_INCOMINGBKGCOLOUR GetSysColor(COLOR_WINDOW)
+#define SRMSGSET_OUTGOINGBKGCOLOUR "OutgoingBkgColour"
+#define SRMSGDEFSET_OUTGOINGBKGCOLOUR GetSysColor(COLOR_WINDOW)
+#define SRMSGSET_INFOBARBKGCOLOUR "InfobarBkgColour"
+#define SRMSGDEFSET_INFOBARBKGCOLOUR GetSysColor(COLOR_BTNFACE)
+
+#define SRMSGSET_USEIEVIEW "UseIEView"
+#define SRMSGDEFSET_USEIEVIEW 1
+
+
+#define SRMSGSET_TYPING "SupportTyping"
+#define SRMSGSET_TYPINGNEW "DefaultTyping"
+#define SRMSGDEFSET_TYPINGNEW 1
+#define SRMSGSET_TYPINGUNKNOWN "UnknownTyping"
+#define SRMSGDEFSET_TYPINGUNKNOWN 0
+#define SRMSGSET_SHOWTYPING "ShowTyping"
+#define SRMSGDEFSET_SHOWTYPING 1
+#define SRMSGSET_SHOWTYPINGWIN "ShowTypingWin"
+#define SRMSGDEFSET_SHOWTYPINGWIN 1
+#define SRMSGSET_SHOWTYPINGNOWIN "ShowTypingTray"
+#define SRMSGDEFSET_SHOWTYPINGNOWIN 0
+#define SRMSGSET_SHOWTYPINGCLIST "ShowTypingClist"
+#define SRMSGDEFSET_SHOWTYPINGCLIST 1
+#define SRMSGSET_SHOWTYPINGSWITCH "ShowTypingSwitch"
+#define SRMSGDEFSET_SHOWTYPINGSWITCH 1
+
+#define SRMSGSET_AVATARENABLE "AvatarEnable"
+#define SRMSGDEFSET_AVATARENABLE 1
+
+#define SRMSGSET_USETRANSPARENCY "UseTransparency"
+#define SRMSGDEFSET_USETRANSPARENCY 0
+#define SRMSGSET_ACTIVEALPHA "ActiveAlpha"
+#define SRMSGDEFSET_ACTIVEALPHA 0
+#define SRMSGSET_INACTIVEALPHA "InactiveAlpha"
+#define SRMSGDEFSET_INACTIVEALPHA 0
+#define SRMSGSET_WINDOWTITLE "WindowTitle"
+#define SRMSGSET_SAVEDRAFTS "SaveDrafts"
+#define SRMSGDEFSET_SAVEDRAFTS 0
+#define SRMSGSET_BUTTONVISIBILITY "ButtonVisibility"
+#define SRMSGDEFSET_BUTTONVISIBILITY 0xFFFF
+#define SRMSGSET_CHATBUTTONVISIBILITY "ChatButtonVisibility"
+#define SRMSGDEFSET_CHATBUTTONVISIBILITY 0xFFFF
+
+#define SRMSGSET_HIDECONTAINERS "HideContainers"
+#define SRMSGDEFSET_HIDECONTAINERS 0
+
+#define SRMSGSET_AUTORESIZELINES "AutoResizeLines"
+#define SRMSGDEFSET_AUTORESIZELINES 2
+#endif
diff --git a/plugins/Scriver/src/msgtimedout.cpp b/plugins/Scriver/src/msgtimedout.cpp new file mode 100644 index 0000000000..4a63acfa3a --- /dev/null +++ b/plugins/Scriver/src/msgtimedout.cpp @@ -0,0 +1,88 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "msgs.h"
+
+
+INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ ErrorWindowData *ewd = (ErrorWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ //if (ewd==NULL && msg!=WM_INITDIALOG) return FALSE;
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ RECT rc, rcParent;
+ TCHAR szText[2048];
+ ewd = (ErrorWindowData *) lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) ewd);
+ TranslateDialogDefault(hwndDlg);
+ ShowWindow(GetParent(ewd->hwndParent), SW_RESTORE);
+ if (ewd != NULL) {
+ if (ewd->szDescription) {
+ SetDlgItemText(hwndDlg, IDC_ERRORTEXT, ewd->szDescription);
+ } else {
+ SetDlgItemText(hwndDlg, IDC_ERRORTEXT, TranslateT("An unknown error has occured."));
+ }
+ if (ewd->szText) {
+ SETTEXTEX st = {0};
+ st.flags = ST_DEFAULT;
+ st.codepage = 1200;
+
+ SendDlgItemMessage(hwndDlg, IDC_MSGTEXT, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)ewd->szText);
+ }
+ if (ewd->szName) {
+ mir_sntprintf(szText, SIZEOF(szText), _T("%s - %s"), TranslateT("Send Error"), ewd->szName);
+ } else {
+ mir_sntprintf(szText, SIZEOF(szText), _T("%s"), TranslateT("Send Error"));
+ }
+ SetWindowText(hwndDlg, szText);
+ GetWindowRect(hwndDlg, &rc);
+ GetWindowRect(GetParent(ewd->hwndParent), &rcParent);
+ SetWindowPos(hwndDlg, HWND_TOP, rcParent.left + (rcParent.right - rcParent.left - rc.right + rc.left) / 2, rcParent.top + (rcParent.bottom - rcParent.top - rc.bottom + rc.top) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ }
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ SendMessage(ewd->hwndParent, DM_ERRORDECIDED, MSGERROR_RETRY, (LPARAM) ewd->queueItem);
+ DestroyWindow(hwndDlg);
+ break;
+ case IDCANCEL:
+ SendMessage(ewd->hwndParent, DM_ERRORDECIDED, MSGERROR_CANCEL, (LPARAM) ewd->queueItem);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
+ mir_free(ewd->szName);
+ mir_free(ewd->szDescription);
+ mir_free(ewd->szText);
+ mir_free(ewd);
+ break;
+
+ }
+ return FALSE;
+
+}
diff --git a/plugins/Scriver/src/msgwindow.cpp b/plugins/Scriver/src/msgwindow.cpp new file mode 100644 index 0000000000..a59e0482e8 --- /dev/null +++ b/plugins/Scriver/src/msgwindow.cpp @@ -0,0 +1,1654 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "commonheaders.h"
+#include "statusicon.h"
+#include "chat/chat.h"
+
+extern HCURSOR hDragCursor;
+extern ITaskbarList3 * pTaskbarInterface;
+
+#define SB_CHAR_WIDTH 40
+#define SB_SENDING_WIDTH 25
+#define SB_UNICODE_WIDTH 18
+
+#define TIMERID_FLASHWND 1
+#define TIMEOUT_FLASHWND 900
+
+static WNDPROC OldTabCtrlProc;
+static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+extern TCHAR *GetNickname(HANDLE hContact, const char* szProto);
+
+void SubclassTabCtrl(HWND hwnd) {
+ OldTabCtrlProc = (WNDPROC) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) TabCtrlProc);
+ SendMessage(hwnd, EM_SUBCLASSED, 0, 0);
+}
+
+void UnsubclassTabCtrl(HWND hwnd) {
+ SendMessage(hwnd, EM_UNSUBCLASSED, 0, 0);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) OldTabCtrlProc);
+}
+
+static const TCHAR *titleTokenNames[] = {_T("%name%"), _T("%status%"), _T("%statusmsg%"), _T("%account%")};
+
+TCHAR* GetWindowTitle(HANDLE *hContact, const char *szProto)
+{
+ int isTemplate;
+ int i, j, len;
+ TCHAR* tokens[4] = {0};
+ int tokenLen[4] = {0};
+ TCHAR *p, *tmplt, *title;
+ char *accModule;
+ TCHAR *pszNewTitleEnd = mir_tstrdup(TranslateT("Message Session"));
+ isTemplate = 0;
+ if (hContact && szProto) {
+ tokens[0] = GetNickname(hContact, szProto);
+ tokenLen[0] = lstrlen(tokens[0]);
+ tokens[1] = mir_tstrdup((TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto ?
+ DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE) : ID_STATUS_OFFLINE, GSMDF_TCHAR));
+ tokenLen[1] = lstrlen(tokens[1]);
+ tokens[2] = DBGetStringT(hContact, "CList", "StatusMsg");
+ if (tokens[2] != NULL) {
+ tokenLen[2] = (int)lstrlen(tokens[2]);
+ for (i = j = 0; i < tokenLen[2]; i++) {
+ if (tokens[2][i] == '\r') {
+ continue;
+ } else if (tokens[2][i] == '\n') {
+ tokens[2][j++] = ' ';
+ } else {
+ tokens[2][j++] = tokens[2][i];
+ }
+ }
+ tokens[2][j] = '\0';
+ tokenLen[2] = j;
+ }
+
+ accModule = (char *) CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM) hContact, 0);
+ if (accModule != NULL) {
+ PROTOACCOUNT* proto = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)accModule);
+ if (proto != NULL) {
+ tokens[3] = mir_tstrdup(proto->tszAccountName);
+ tokenLen[3] = lstrlen(tokens[3]);
+ }
+ }
+ tmplt = DBGetStringT(NULL, SRMMMOD, SRMSGSET_WINDOWTITLE);
+ if (tmplt != NULL) {
+ isTemplate = 1;
+ } else {
+ if (g_dat->flags & SMF_STATUSICON) {
+ tmplt = _T("%name% - ");
+ } else {
+ tmplt = _T("%name% (%status%) : ");
+ }
+ }
+ } else {
+ tmplt = _T("");
+ }
+ for (len = 0, p = tmplt; *p; p++, len++) {
+ if (*p == '%') {
+ for (i = 0; i < SIZEOF(titleTokenNames); i ++) {
+ int tnlen = (int)_tcslen(titleTokenNames[i]);
+ if (!_tcsncmp(p, titleTokenNames[i], tnlen)) {
+ len += tokenLen[i] - 1;
+ p += tnlen - 1;
+ break;
+ }
+ }
+ }
+ }
+ if (!isTemplate) {
+ len += lstrlen(pszNewTitleEnd);
+ }
+ title = (TCHAR *)mir_alloc(sizeof(TCHAR) * (len + 1));
+ for (len = 0, p = tmplt; *p; p++) {
+ if (*p == '%') {
+ for (i = 0; i < SIZEOF(titleTokenNames); i ++) {
+ int tnlen = lstrlen(titleTokenNames[i]);
+ if (!_tcsncmp(p, titleTokenNames[i], tnlen)) {
+ if (tokens[i] != NULL) {
+ memcpy(title+len, tokens[i], sizeof(TCHAR) * tokenLen[i]);
+ len += tokenLen[i];
+ }
+ p += tnlen - 1;
+ break;
+ }
+ }
+ if (i < SIZEOF(titleTokenNames)) continue;
+ }
+ title[len++] = *p;
+ }
+ if (!isTemplate) {
+ memcpy(title+len, pszNewTitleEnd, sizeof(TCHAR) * lstrlen(pszNewTitleEnd));
+ len += lstrlen(pszNewTitleEnd);
+ }
+ title[len] = '\0';
+ if (isTemplate) {
+ mir_free(tmplt);
+ }
+ for (i = 0; i < SIZEOF(titleTokenNames); i ++) {
+ mir_free(tokens[i]);
+ }
+ mir_free(pszNewTitleEnd);
+ return title;
+}
+
+TCHAR* GetTabName(HANDLE *hContact)
+{
+ if (hContact) {
+ return GetNickname(hContact, NULL);
+ }
+ return NULL;
+}
+
+static int GetChildCount(ParentWindowData *dat) {
+ return TabCtrl_GetItemCount(dat->hwndTabs);
+}
+
+static void GetChildWindowRect(ParentWindowData *dat, RECT *rcChild)
+{
+ RECT rc, rcStatus, rcTabs;
+ GetClientRect(dat->hwnd, &rc);
+ GetClientRect(dat->hwndTabs, &rcTabs);
+ TabCtrl_AdjustRect(dat->hwndTabs, FALSE, &rcTabs);
+ rcStatus.top = rcStatus.bottom = 0;
+ if (dat->flags2 & SMF2_SHOWSTATUSBAR) {
+ GetWindowRect(dat->hwndStatus, &rcStatus);
+ }
+ rcChild->left = 0;
+ rcChild->right = rc.right;
+ if (dat->flags2 & SMF2_TABSATBOTTOM) {
+ rcChild->top = 2;
+ if ((dat->flags2 & SMF2_USETABS && !(dat->flags2 & SMF2_HIDEONETAB)) || (dat->childrenCount > 1)) {
+ rcChild->bottom = rcTabs.bottom + 4;
+ } else {
+ rcChild->bottom = rc.bottom - rc.top - (rcStatus.bottom - rcStatus.top);
+ }
+ } else {
+ if ((dat->flags2 & SMF2_USETABS && !(dat->flags2 & SMF2_HIDEONETAB)) || (dat->childrenCount > 1)) {
+ rcChild->top = rcTabs.top;
+ } else {
+ rcChild->top = 2;//rcTabs.top - 2;
+ }
+ rcChild->bottom = rc.bottom - rc.top - (rcStatus.bottom - rcStatus.top);
+ }
+}
+
+static int GetTabFromHWND(ParentWindowData *dat, HWND child)
+{
+ MessageWindowTabData * mwtd;
+ TCITEM tci;
+ int l, i;
+ l = TabCtrl_GetItemCount(dat->hwndTabs);
+ for (i = 0; i < l; i++) {
+ ZeroMemory(&tci, sizeof(TCITEM));
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(dat->hwndTabs, i, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd->hwnd == child) {
+ return i;
+ }
+ }
+ return -1;
+
+}
+
+static MessageWindowTabData * GetChildFromTab(HWND hwndTabs, int tabId)
+{
+ TCITEM tci;
+ ZeroMemory(&tci, sizeof(TCITEM));
+ tci.mask = TCIF_PARAM;
+ if (TabCtrl_GetItem(hwndTabs, tabId, &tci)) {
+ return (MessageWindowTabData *) tci.lParam;
+ }
+ return NULL;
+}
+
+static MessageWindowTabData * GetChildFromHWND(ParentWindowData *dat, HWND hwnd)
+{
+ MessageWindowTabData * mwtd;
+ TCITEM tci;
+ int l, i;
+ l = TabCtrl_GetItemCount(dat->hwndTabs);
+ for (i = 0; i < l; i++) {
+ ZeroMemory(&tci, sizeof(TCITEM));
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(dat->hwndTabs, i, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd->hwnd == hwnd) {
+ return mwtd;
+ }
+ }
+ return NULL;
+}
+
+static void GetMinimunWindowSize(ParentWindowData *dat, SIZE *size)
+{
+ MINMAXINFO mmi;
+ RECT rc, rcWindow;
+ int i, minW = 216, minH = 80;
+ GetWindowRect(dat->hwnd, &rcWindow);
+ GetChildWindowRect(dat, &rc);
+ for (i=0;i<dat->childrenCount;i++) {
+ MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i);
+ SendMessage(mwtd->hwnd, WM_GETMINMAXINFO, 0, (LPARAM) &mmi);
+ if (i==0 || mmi.ptMinTrackSize.x > minW) minW = mmi.ptMinTrackSize.x;
+ if (i==0 || mmi.ptMinTrackSize.y > minH) minH = mmi.ptMinTrackSize.y;
+ }
+ if (dat->bMinimized) {
+ size->cx = minW;
+ size->cy = minH;
+ } else {
+ size->cx = minW + (rcWindow.right - rcWindow.left) - (rc.right - rc.left);
+ size->cy = minH + (rcWindow.bottom - rcWindow.top) - (rc.bottom - rc.top);
+ }
+}
+
+static void SetupStatusBar(ParentWindowData *dat)
+{
+ int statusIconNum = GetStatusIconsCount(dat->hContact);
+ int statwidths[4];
+ RECT rc;
+ GetClientRect(dat->hwnd, &rc);
+ statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_UNICODE_WIDTH - 2 * (statusIconNum > 0) - statusIconNum * (GetSystemMetrics(SM_CXSMICON) + 2);
+ statwidths[1] = rc.right - rc.left - SB_UNICODE_WIDTH - 2 * (statusIconNum > 0) - statusIconNum * (GetSystemMetrics(SM_CXSMICON) + 2);
+ statwidths[2] = rc.right - rc.left - SB_UNICODE_WIDTH;
+ statwidths[3] = -1;
+ SendMessage(dat->hwndStatus, SB_SETPARTS, 4, (LPARAM) statwidths);
+ SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, (LPARAM)0);
+ SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_NOBORDERS) | 3, (LPARAM)0);
+}
+
+static int AddOrReplaceIcon(HIMAGELIST hList, int prevIndex, HICON hIcon) {
+ int usageIdx = -1;
+ int i;
+ for (i = 0; i < g_dat->tabIconListUsageSize; i++) {
+ if (!g_dat->tabIconListUsage[i].used && usageIdx == -1) {
+ usageIdx = i;
+ }
+ if (g_dat->tabIconListUsage[i].index == prevIndex) {
+ usageIdx = i;
+ break;
+ }
+ }
+ if (usageIdx == -1) {
+ usageIdx = g_dat->tabIconListUsageSize;
+ g_dat->tabIconListUsage = (ImageListUsageEntry*) mir_realloc(g_dat->tabIconListUsage, sizeof(ImageListUsageEntry) * (g_dat->tabIconListUsageSize + 1));
+ g_dat->tabIconListUsageSize++;
+ } else {
+ prevIndex = g_dat->tabIconListUsage[usageIdx].index;
+ }
+ g_dat->tabIconListUsage[usageIdx].used = 1;
+ g_dat->tabIconListUsage[usageIdx].index = (int) ImageList_ReplaceIcon(hList, prevIndex, hIcon);
+ return g_dat->tabIconListUsage[usageIdx].index;
+}
+
+static void ReleaseIcon(int index) {
+ int i;
+ for (i = 0; i < g_dat->tabIconListUsageSize; i++) {
+ if (g_dat->tabIconListUsage[i].index == index) {
+ g_dat->tabIconListUsage[i].used = 0;
+ }
+ }
+}
+
+static void ActivateChild(ParentWindowData *dat, HWND child) {
+ int i;
+ RECT rcChild;
+ GetChildWindowRect(dat, &rcChild);
+ SetWindowPos(child, HWND_TOP, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, SWP_NOSIZE);
+
+ i = GetTabFromHWND(dat, child);
+ if ( i == -1 )
+ return;
+ else {
+ MessageWindowTabData *mwtd;
+ if (( mwtd = GetChildFromTab(dat->hwndTabs, i)) == NULL )
+ return;
+
+ dat->hContact = mwtd->hContact;
+ if (child != dat->hwndActive) {
+ HWND prev = dat->hwndActive;
+ dat->hwndActive = child;
+ SetupStatusBar(dat);
+ SendMessage(dat->hwndActive, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(dat->hwndActive, DM_UPDATETITLEBAR, 0, 0);
+ SendMessage(dat->hwnd, WM_SIZE, 0, 0);
+ ShowWindow(dat->hwndActive, SW_SHOWNOACTIVATE);
+ SendMessage(dat->hwndActive, DM_SCROLLLOGTOBOTTOM, 0, 0);
+ if (prev!=NULL) ShowWindow(prev, SW_HIDE);
+ } else {
+ SendMessage(dat->hwnd, WM_SIZE, 0, 0);
+ }
+ TabCtrl_SetCurSel(dat->hwndTabs, i);
+ SendMessage(dat->hwndActive, DM_ACTIVATE, WA_ACTIVE, 0);
+ }
+}
+
+static void UpdateTabsPadding(ParentWindowData *dat)
+{
+ if (dat->childrenCount > 1) {
+// ws |= 0x2000; //TCS_OWNERDRAWFIXED
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 12, GetSystemMetrics(SM_CYEDGE) + 1);
+ } else {
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 4, GetSystemMetrics(SM_CYEDGE) + 1);
+ }
+}
+
+static void AddChild(ParentWindowData *dat, HWND hwnd, HANDLE hContact)
+{
+ TCITEM tci;
+ int tabId;
+ MessageWindowTabData *mwtd = (MessageWindowTabData *) mir_alloc(sizeof(MessageWindowTabData));
+ mwtd->hwnd = hwnd;
+ mwtd->hContact = hContact;
+ mwtd->szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ mwtd->parent = dat;
+ dat->childrenCount++;
+ tci.mask = TCIF_PARAM | TCIF_IMAGE | TCIF_TEXT;
+ tci.lParam = (LPARAM) mwtd;
+ tci.iImage = -1;
+ tci.pszText = _T("");
+ tabId = TabCtrl_InsertItem(dat->hwndTabs, dat->childrenCount-1, &tci);
+// ActivateChild(dat, mdat->hwnd);
+ UpdateTabsPadding(dat);
+ SetWindowPos(mwtd->hwnd, HWND_TOP, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, SWP_HIDEWINDOW);
+ SendMessage(dat->hwnd, WM_SIZE, 0, 0);
+
+ if (MyEnableThemeDialogTexture)
+ MyEnableThemeDialogTexture(hwnd, ETDT_ENABLETAB);
+}
+
+static void RemoveChild(ParentWindowData *dat, HWND child)
+{
+ int tab = GetTabFromHWND(dat, child);
+ if (tab >= 0) {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM | TCIF_IMAGE;
+ TabCtrl_GetItem(dat->hwndTabs, tab, &tci);
+ TabCtrl_DeleteItem(dat->hwndTabs, tab);
+ mir_free((MessageWindowTabData *) tci.lParam);
+ dat->childrenCount--;
+ if (child == dat->hwndActive) {
+ if (tab == TabCtrl_GetItemCount(dat->hwndTabs)) tab--;
+ if (tab >=0 ) {
+ ActivateChild(dat, GetChildFromTab(dat->hwndTabs, tab)->hwnd);
+ }
+ else
+ dat->hwndActive = NULL;
+ }
+ UpdateTabsPadding(dat);
+ ReleaseIcon(tci.iImage);
+ }
+}
+
+static void CloseOtherChilden(ParentWindowData *dat, HWND child)
+{
+ int i;
+ ActivateChild(dat, child);
+ for (i=dat->childrenCount-1;i>=0;i--) {
+ MessageWindowTabData *mwtd = GetChildFromTab(dat->hwndTabs, i);
+ if (mwtd != NULL && mwtd->hwnd != child) {
+ SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0);
+ }
+ }
+ UpdateTabsPadding(dat);
+ ActivateChild(dat, child);
+}
+
+static void ActivateNextChild(ParentWindowData *dat, HWND child)
+{
+ int i = GetTabFromHWND(dat, child);
+ int l = TabCtrl_GetItemCount(dat->hwndTabs);
+ i = (i+1) % l;
+ ActivateChild(dat, GetChildFromTab(dat->hwndTabs, i)->hwnd);
+}
+
+static void ActivatePrevChild(ParentWindowData *dat, HWND child)
+{
+ int i = GetTabFromHWND(dat, child);
+ int l = TabCtrl_GetItemCount(dat->hwndTabs);
+ i = (i+l-1) % l;
+ ActivateChild(dat, GetChildFromTab(dat->hwndTabs, i)->hwnd);
+}
+
+static void ActivateChildByIndex(ParentWindowData *dat, int index)
+{
+ int l = TabCtrl_GetItemCount(dat->hwndTabs);
+ if (index < l) {
+ MessageWindowTabData *mwtd = GetChildFromTab(dat->hwndTabs, index);
+ if (mwtd != NULL) {
+ ActivateChild(dat, mwtd->hwnd);
+ }
+ }
+}
+
+static void SetContainerWindowStyle(ParentWindowData *dat)
+{
+ DWORD ws;
+ RECT rc;
+ if (!(dat->flags2 & SMF2_SHOWSTATUSBAR)) {
+ ShowWindow(dat->hwndStatus, SW_HIDE);
+ } else {
+ ShowWindow(dat->hwndStatus, SW_SHOW);
+ }
+ ws = GetWindowLongPtr(dat->hwnd, GWL_STYLE) & ~(WS_CAPTION);
+ if (dat->flags2 & SMF2_SHOWTITLEBAR) {
+ ws |= WS_CAPTION;
+ }
+ SetWindowLongPtr(dat->hwnd, GWL_STYLE, ws);
+
+ ws = GetWindowLongPtr(dat->hwnd, GWL_EXSTYLE)& ~WS_EX_LAYERED;
+ ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0;
+ SetWindowLongPtr(dat->hwnd , GWL_EXSTYLE , ws);
+ if (dat->flags2 & SMF2_USETRANSPARENCY) {
+ pSetLayeredWindowAttributes(dat->hwnd, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA);
+ }
+
+ ws = GetWindowLongPtr(dat->hwndTabs, GWL_STYLE) & ~(TCS_BOTTOM | 0x2000);
+ if (dat->flags2 & SMF2_TABSATBOTTOM) {
+ ws |= TCS_BOTTOM;
+ }
+ ws |= 0x2000; //TCS_OWNERDRAWFIXED
+ if (dat->childrenCount > 1) {
+// ws |= 0x2000; //TCS_OWNERDRAWFIXED
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 12, GetSystemMetrics(SM_CYEDGE) + 1);
+ } else {
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 4, GetSystemMetrics(SM_CYEDGE) + 1);
+ }
+ SetWindowLongPtr(dat->hwndTabs, GWL_STYLE, ws);
+ GetWindowRect(dat->hwnd, &rc);
+ SetWindowPos(dat->hwnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
+}
+
+INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ DWORD ws;
+ ParentWindowData *dat;
+ dat = (ParentWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ if (!dat && msg!=WM_INITDIALOG) return FALSE;
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ HMENU hMenu;
+ HANDLE hSContact;
+ int savePerContact = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT);
+ NewMessageWindowLParam *newData = (NewMessageWindowLParam *) lParam;
+ dat = (ParentWindowData *) mir_alloc(sizeof(ParentWindowData));
+ dat->hContact = newData->hContact;
+ dat->nFlash = 0;
+ dat->nFlashMax = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_FLASHCOUNT, SRMSGDEFSET_FLASHCOUNT);
+ dat->childrenCount = 0;
+ dat->hwnd = hwndDlg;
+ dat->mouseLBDown = 0;
+ dat->windowWasCascaded = 0;
+ dat->bMinimized = 0;
+ dat->bVMaximized = 0;
+ dat->flags2 = g_dat->flags2;
+ dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL);
+ dat->isChat = newData->isChat;
+ SendMessage(dat->hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0);
+ //SetupStatusBar(dat);
+ dat->hwndTabs = GetDlgItem(hwndDlg, IDC_TABS);
+ dat->hwndActive = NULL;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dat);
+ if (g_dat->hTabIconList != NULL) {
+ TabCtrl_SetImageList(dat->hwndTabs, g_dat->hTabIconList);
+ }
+ dat->next = NULL;
+ if (!newData->isChat) {
+ dat->prev = g_dat->lastParent;
+ g_dat->lastParent = dat;
+ } else {
+ dat->prev = g_dat->lastChatParent;
+ g_dat->lastChatParent = dat;
+ }
+ if (dat->prev != NULL) {
+ dat->prev->next = dat;
+ }
+ WindowList_Add(g_dat->hParentWindowList, hwndDlg, hwndDlg);
+ SubclassTabCtrl(dat->hwndTabs);
+
+ SetContainerWindowStyle(dat);
+
+// hSContact = !(dat->flags2 & SMF2_USETABS) && savePerContact ? dat->hContact : NULL;
+ hSContact = savePerContact ? dat->hContact : NULL;
+ dat->bTopmost = DBGetContactSettingByte(hSContact, SRMMMOD, SRMSGSET_TOPMOST, SRMSGDEFSET_TOPMOST);
+ if (ScriverRestoreWindowPosition(hwndDlg, hSContact, SRMMMOD, (newData->isChat && !savePerContact) ? "chat" : "", 0, SW_HIDE)) {
+ SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW);
+ }
+// if (!(dat->flags2 & SMF2_USETABS)) {
+ if (!savePerContact && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE))
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM) &dat->windowWasCascaded);
+ // }
+ hMenu = GetSystemMenu( hwndDlg, FALSE );
+ InsertMenu( hMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, NULL );
+ if (dat->bTopmost) {
+ InsertMenu( hMenu, 0, MF_BYPOSITION | MF_ENABLED | MF_CHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top"));
+ SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ } else {
+ InsertMenu( hMenu, 0, MF_BYPOSITION | MF_ENABLED | MF_UNCHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top"));
+ }
+ }
+ return TRUE;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *mmi = (MINMAXINFO *) lParam;
+ SIZE size;
+ if (dat->bVMaximized) {
+ MONITORINFO mi;
+ HMONITOR hMonitor;
+ WINDOWPLACEMENT wp;
+ RECT rcDesktop;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(hwndDlg, &wp);
+ hMonitor = MonitorFromRect(&wp.rcNormalPosition, MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfo(hMonitor, &mi);
+ rcDesktop = mi.rcWork;
+ mmi->ptMaxSize.x = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
+ mmi->ptMaxSize.y = rcDesktop.bottom - rcDesktop.top;
+ mmi->ptMaxPosition.x = wp.rcNormalPosition.left;
+ if (IsIconic(hwndDlg)) {
+ mmi->ptMaxPosition.y = rcDesktop.top;
+ } else {
+ mmi->ptMaxPosition.y = 0;
+ }
+ }
+ GetMinimunWindowSize(dat, &size);
+ mmi->ptMinTrackSize.x = size.cx;
+ mmi->ptMinTrackSize.y = size.cy;
+ return FALSE;
+ }
+
+ case WM_SIZE:
+ if (wParam == SIZE_MINIMIZED) {
+ dat->bMinimized = 1;
+ }
+ if (IsIconic(hwndDlg)) {
+ MoveWindow(dat->hwndActive, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, TRUE);
+ } else {
+// }
+// if (!IsIconic(hwndDlg)) {
+ RECT rc, rcStatus, rcChild, rcWindow;
+ SIZE size;
+ dat->bMinimized = 0;
+ GetClientRect(hwndDlg, &rc);
+ GetWindowRect(hwndDlg, &rcWindow);
+ rcStatus.top = rcStatus.bottom = 0;
+ if (dat->flags2 & SMF2_SHOWSTATUSBAR) {
+ GetWindowRect(dat->hwndStatus, &rcStatus);
+ SetupStatusBar(dat);
+ }
+ MoveWindow(dat->hwndTabs, 0, 2, (rc.right - rc.left), (rc.bottom - rc.top) - (rcStatus.bottom - rcStatus.top) - 2, FALSE);
+ RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE);
+ GetMinimunWindowSize(dat, &size);
+ if ((rcWindow.bottom-rcWindow.top) < size.cy || (rcWindow.right-rcWindow.left) < size.cx) {
+ if ((rcWindow.bottom-rcWindow.top) < size.cy) {
+ rcWindow.bottom = rcWindow.top + size.cy;
+ }
+ if ((rcWindow.right-rcWindow.left) < size.cx) {
+ rcWindow.right = rcWindow.left + size.cx;
+ }
+ MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE);
+ }
+ GetChildWindowRect(dat, &rcChild);
+ memcpy(&dat->childRect, &rcChild, sizeof(RECT));
+ MoveWindow(dat->hwndActive, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE);
+ RedrawWindow(GetDlgItem(dat->hwndActive, IDC_LOG), NULL, NULL, RDW_INVALIDATE);
+ if (dat->flags2 & SMF2_SHOWSTATUSBAR) {
+ SendMessage(dat->hwndStatus, WM_SIZE, 0, 0);
+ RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
+ }
+ }
+ return FALSE;
+ case WM_SETFOCUS:
+ if (dat->hwndActive != NULL) {
+ SetFocus(dat->hwndActive);
+ }
+ return TRUE;
+ case WM_CLOSE:
+ if (g_dat->flags2 & SMF2_HIDECONTAINERS && dat->childrenCount > 0) {
+ ShowWindow(hwndDlg, SW_HIDE);
+ } else {
+ DestroyWindow(hwndDlg);
+ }
+ return TRUE;
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+ if (dat && dat->hwndActive && dis->hwndItem == dat->hwndStatus) {
+ MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive);
+ if (mwtd != NULL) {
+ DrawStatusIcons(mwtd->hContact, dis->hDC, dis->rcItem, 2);
+ }
+ return TRUE;
+ } else if (dis->hwndItem == dat->hwndTabs) {
+ DrawTab(dat, dat->hwndTabs, wParam, lParam);
+ return TRUE;
+ }
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ }
+ case WM_COMMAND:
+ if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM) dat->hContact)) {
+ break;
+ }
+ switch (LOWORD(wParam)) {
+ case IDCANCEL:
+ //DestroyWindow(hwndDlg);
+ return TRUE;
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ NMHDR* pNMHDR = (NMHDR*) lParam;
+ if (pNMHDR->hwndFrom == dat->hwndTabs) {
+ switch (pNMHDR->code) {
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci = {0};
+ int iSel = TabCtrl_GetCurSel(dat->hwndTabs);
+ tci.mask = TCIF_PARAM;
+ if (TabCtrl_GetItem(dat->hwndTabs, iSel, &tci)) {
+ MessageWindowTabData * mwtd = (MessageWindowTabData *) tci.lParam;
+ ActivateChild(dat, mwtd->hwnd);
+ SetFocus(dat->hwndActive);
+ }
+ }
+ break;
+ case NM_RCLICK:
+ {
+ TCHITTESTINFO thinfo;
+ int tabId, x, y;
+ GetCursorPos(&thinfo.pt);
+ x = thinfo.pt.x;
+ y = thinfo.pt.y;
+ ScreenToClient(dat->hwndTabs, &thinfo.pt);
+ tabId = TabCtrl_HitTest(dat->hwndTabs, &thinfo);
+ if (tabId != -1) {
+ HMENU hMenu, hSubMenu, hUserMenu;
+ BOOL menuResult;
+ MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, tabId);
+ hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ hSubMenu = GetSubMenu(hMenu, 3);
+ TranslateMenu(hSubMenu);
+ hUserMenu = (HMENU) SendMessage(mwtd->hwnd, DM_GETCONTEXTMENU, 0, 0);
+ if (hUserMenu != NULL) {
+ InsertMenu(hSubMenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR)hUserMenu, TranslateT("User Menu"));
+ InsertMenu(hSubMenu, 1, MF_SEPARATOR | MF_BYPOSITION, 0, 0);
+ }
+ menuResult = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, x, y, 0, hwndDlg, NULL);
+ switch (menuResult) {
+ case IDM_CLOSETAB:
+ SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0);
+ break;
+ case IDM_CLOSEOTHERTABS:
+ CloseOtherChilden(dat, mwtd->hwnd);
+ break;
+ default:
+ CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuResult), MPCF_CONTACTMENU), (LPARAM) mwtd->hContact);
+ }
+ if (hUserMenu != NULL) {
+ DestroyMenu(hUserMenu);
+ }
+ DestroyMenu(hMenu);
+ }
+ }
+ break;
+ }
+ } else if (pNMHDR->hwndFrom == dat->hwndStatus) {
+ switch (pNMHDR->code) {
+ case NM_CLICK:
+// case NM_RCLICK:
+ {
+ NMMOUSE *nm=(NMMOUSE*)lParam;
+ RECT rc;
+ SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 2, (LPARAM)&rc);
+ if (nm->pt.x >= rc.left) {
+ MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive);
+ if (mwtd != NULL) {
+ CheckStatusIconClick(mwtd->hContact, dat->hwndStatus, nm->pt, rc, 2, (pNMHDR->code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0));
+ }
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
+ break;
+ case WM_DROPFILES:
+ SendMessage(dat->hwndActive, WM_DROPFILES, wParam, lParam);
+ break;
+ case WM_TIMER:
+ if (wParam == TIMERID_FLASHWND) {
+ if (dat->nFlash < 2 * dat->nFlashMax) {
+ FlashWindow(hwndDlg, TRUE);
+ dat->nFlash++;
+ } else {// || ((GetActiveWindow() == hwndDlg) && (GetForegroundWindow() == hwndDlg))) {
+ KillTimer(hwndDlg, TIMERID_FLASHWND);
+ FlashWindow(hwndDlg, FALSE);
+ }
+ }
+ break;
+ case WM_CONTEXTMENU:
+ if (dat->hwndStatus && dat->hwndStatus == (HWND) wParam) {
+ RECT rc;
+ POINT pt, pt2;
+ GetCursorPos(&pt);
+ pt2.x = pt.x;
+ pt2.y = pt.y;
+ ScreenToClient(dat->hwndStatus, &pt);
+
+ SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 2, (LPARAM)&rc);
+ if (pt.x >= rc.left) {
+ MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive);
+ if (mwtd != NULL) {
+ CheckStatusIconClick(mwtd->hContact, dat->hwndStatus, pt, rc, 2, MBCF_RIGHTBUTTON);
+ }
+ break;
+ } else
+ SendMessage(dat->hwndActive, WM_CONTEXTMENU, (WPARAM)hwndDlg, 0);
+ }
+ break;
+ case WM_ACTIVATE:
+
+ if (LOWORD(wParam) == WA_INACTIVE) {
+ ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED;
+ ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0;
+ SetWindowLongPtr(hwndDlg , GWL_EXSTYLE , ws);
+ if (dat->flags2 & SMF2_USETRANSPARENCY) {
+ pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA);
+// RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ }
+ break;
+ }
+ if (dat->hwndActive != NULL) {
+ ActivateChild(dat, dat->hwndActive);
+ g_dat->hFocusWnd = dat->hwndActive;
+ PostMessage(dat->hwndActive, DM_SETFOCUS, 0, msg);
+ }
+ if (KillTimer(hwndDlg, TIMERID_FLASHWND)) {
+ FlashWindow(hwndDlg, FALSE);
+ dat->nFlash = 0;
+ }
+ ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED;
+ ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0;
+ SetWindowLongPtr(hwndDlg , GWL_EXSTYLE , ws);
+ if (dat->flags2 & SMF2_USETRANSPARENCY) {
+ pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->activeAlpha), LWA_ALPHA);
+// RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ if (!IsZoomed(hwndDlg)) {
+ POINT pt;
+ GetCursorPos(&pt);
+ // dat->mouseLBDown = 1;
+ // GetCursorPos(&dat->mouseLBDownPos);
+ return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ // SetCapture(hwndDlg);
+
+ }
+ break;
+ case WM_MOVING:
+ if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
+ int snapPixels = 10;
+ RECT rcDesktop;
+ RECT *pRect = (RECT *)lParam;
+ POINT pt;
+ MONITORINFO mi;
+ HMONITOR hMonitor = MonitorFromRect(pRect, MONITOR_DEFAULTTONEAREST);
+ SIZE szSize = {pRect->right-pRect->left,pRect->bottom-pRect->top};
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfo(hMonitor, &mi);
+ GetCursorPos(&pt);
+// SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0);
+ rcDesktop = mi.rcWork;
+ pRect->left = pt.x-dat->mouseLBDownPos.x;
+ pRect->top = pt.y-dat->mouseLBDownPos.y;
+ pRect->right = pRect->left+szSize.cx;
+ pRect->bottom = pRect->top+szSize.cy;
+ if (pRect->top < rcDesktop.top+snapPixels && pRect->top > rcDesktop.top-snapPixels) {
+ pRect->top = rcDesktop.top;
+ pRect->bottom = rcDesktop.top + szSize.cy;
+ }
+ if (pRect->left < rcDesktop.left+snapPixels && pRect->left > rcDesktop.left-snapPixels) {
+ pRect->left = rcDesktop.left;
+ pRect->right = rcDesktop.left + szSize.cx;
+ }
+ if (pRect->right < rcDesktop.right+snapPixels && pRect->right > rcDesktop.right-snapPixels) {
+ pRect->right = rcDesktop.right;
+ pRect->left = rcDesktop.right - szSize.cx;
+ }
+ if (pRect->bottom < rcDesktop.bottom+snapPixels && pRect->bottom > rcDesktop.bottom-snapPixels) {
+ pRect->bottom = rcDesktop.bottom;
+ pRect->top = rcDesktop.bottom - szSize.cy;
+ }
+ }
+ break;
+ case WM_SYSCOMMAND:
+ if ((wParam & 0xFFF0) == SC_MAXIMIZE) {
+ if (GetKeyState(VK_CONTROL) & 0x8000) {
+ dat->bVMaximized = 1;
+ } else {
+ dat->bVMaximized = 0;
+ }
+ }
+ else if ((wParam & 0xFFF0) == SC_MOVE) {
+ RECT rc;
+ GetWindowRect(hwndDlg, &rc);
+ dat->mouseLBDownPos.x = LOWORD(lParam) - rc.left;
+ dat->mouseLBDownPos.y = HIWORD(lParam) - rc.top;
+ } else if (wParam == IDM_TOPMOST) {
+ HMENU hMenu = GetSystemMenu(hwndDlg, FALSE);
+ if (dat->bTopmost) {
+ CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_UNCHECKED);
+ SetWindowPos(hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ dat->bTopmost = FALSE;
+ } else {
+ CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_CHECKED);
+ SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ dat->bTopmost = TRUE;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ {
+ WINDOWPLACEMENT wp = { 0 };
+ HANDLE hContact;
+ int i;
+ char szSettingName[64];
+ char *szNamePrefix;
+ int savePerContact = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT);
+ for (i=dat->childrenCount;--i>=0;) {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM | TCIF_IMAGE;
+ TabCtrl_GetItem(dat->hwndTabs, i, &tci);
+ TabCtrl_DeleteItem(dat->hwndTabs, i);
+ mir_free((MessageWindowTabData *) tci.lParam);
+ ReleaseIcon(tci.iImage);
+ }
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
+ WindowList_Remove(g_dat->hParentWindowList, hwndDlg);
+ if (savePerContact)
+// if (!(dat->flags2 & SMF2_USETABS) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT))
+ hContact = dat->hContact;
+ else
+ hContact = NULL;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(hwndDlg, &wp);
+ szNamePrefix = (!savePerContact && dat->isChat) ? "chat" : "";
+ if (!dat->windowWasCascaded) {
+ wsprintfA(szSettingName,"%sx",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.left);
+ wsprintfA(szSettingName,"%sy",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.top);
+ }
+ wsprintfA(szSettingName,"%swidth",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.right - wp.rcNormalPosition.left);
+ wsprintfA(szSettingName,"%sheight",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
+ DBWriteContactSettingByte(hContact, SRMMMOD, SRMSGSET_TOPMOST, (BYTE)dat->bTopmost);
+ if (g_dat->lastParent == dat) {
+ g_dat->lastParent = dat->prev;
+ }
+ if (g_dat->lastChatParent == dat) {
+ g_dat->lastChatParent = dat->prev;
+ }
+ if (dat->prev != NULL) {
+ dat->prev->next = dat->next;
+ }
+ if (dat->next != NULL) {
+ dat->next->prev = dat->prev;
+ }
+ UnsubclassTabCtrl(dat->hwndTabs);
+ mir_free(dat);
+ }
+ break;
+ case DM_ERRORDECIDED:
+ break;
+ case CM_STARTFLASHING:
+ if ((GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg)) {// && !(g_dat->flags2 & SMF2_STAYMINIMIZED)) {
+ dat->nFlash = 0;
+ SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL);
+ }
+ break;
+ case CM_POPUPWINDOW:
+ EnableWindow(hwndDlg, TRUE);
+ if (wParam) { /* incoming message */
+ if (g_dat->flags & SMF_STAYMINIMIZED) {
+ if (!IsWindowVisible(hwndDlg)) {
+ ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE);
+ }
+ if (dat->childrenCount == 1 ||
+ ((g_dat->flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) {
+ SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM) lParam);
+ }
+ } else {
+ if (IsIconic(hwndDlg)) {
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ } else {
+ ShowWindow(hwndDlg, SW_SHOWNA);
+ }
+ if (dat->childrenCount == 1 ||
+ ((g_dat->flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) {
+ SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM)lParam);
+ }
+ SetWindowPos(hwndDlg, HWND_TOP, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
+ //SetForegroundWindow(hwndDlg);
+ }
+ } else { /* outgoing message */
+ if (IsIconic(hwndDlg)) {
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ } else {
+ ShowWindow(hwndDlg, SW_SHOW);
+ }
+ SetForegroundWindow(hwndDlg);
+ SetFocus((HWND) lParam);
+ }
+ break;
+ case CM_REMOVECHILD:
+ {
+ RemoveChild(dat, (HWND) lParam);
+ if (dat->childrenCount != 0) {
+ SetFocus(dat->hwndActive);
+ } else {
+ PostMessage(hwndDlg, WM_CLOSE, 0, 0);
+ }
+ }
+ return TRUE;
+ case CM_ADDCHILD:
+ {
+ AddChild(dat, (HWND)wParam, (HANDLE)lParam);
+ }
+ return TRUE;
+ case CM_ACTIVATECHILD:
+// if ((HWND) lParam != dat->hwndActive) {
+ ActivateChild(dat, (HWND) lParam);
+// }
+ return TRUE;
+ case CM_ACTIVATEPREV:
+ ActivatePrevChild(dat, (HWND) lParam);
+ SetFocus(dat->hwndActive);
+ return TRUE;
+ case CM_ACTIVATENEXT:
+ ActivateNextChild(dat, (HWND) lParam);
+ SetFocus(dat->hwndActive);
+ return TRUE;
+ case CM_ACTIVATEBYINDEX:
+ ActivateChildByIndex(dat, (int) lParam);
+ SetFocus(dat->hwndActive);
+ return TRUE;
+ case CM_GETCHILDCOUNT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetChildCount(dat));
+ return TRUE;
+ case CM_GETACTIVECHILD:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)dat->hwndActive);
+ return TRUE;
+ case CM_GETTOOLBARSTATUS:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(dat->flags2 & SMF2_SHOWTOOLBAR) != 0);
+ return TRUE;
+ case DM_SENDMESSAGE:
+ {
+ int i;
+ for (i=0;i<dat->childrenCount;i++) {
+ MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i);
+ SendMessage(mwtd->hwnd, DM_SENDMESSAGE, wParam, lParam);
+ }
+ }
+ break;
+ case DM_OPTIONSAPPLIED:
+ {
+ dat->flags2 = g_dat->flags2;
+ SetContainerWindowStyle(dat);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ //RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ break;
+ }
+ case CM_UPDATETITLEBAR:
+ {
+ HWND hwnd = (HWND) lParam;
+ TitleBarData *tbd = (TitleBarData *) wParam;
+ if (tbd != NULL && dat->hwndActive == hwnd) {
+ if (tbd->iFlags & TBDF_TEXT) {
+ TCHAR oldtitle[256];
+ GetWindowText(hwndDlg, oldtitle, SIZEOF(oldtitle));
+ if (lstrcmp(tbd->pszText, oldtitle)) { //swt() flickers even if the title hasn't actually changed
+ SetWindowText(hwndDlg, tbd->pszText);
+ //SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ }
+ }
+ if (tbd->iFlags & TBDF_ICON) {
+ SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM) tbd->hIcon);
+ if (tbd->hIconBig != NULL) {
+ SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) tbd->hIconBig);
+ }
+ if (pTaskbarInterface)
+ pTaskbarInterface->SetOverlayIcon(hwndDlg, tbd->hIconNot, L"");
+ }
+ }
+ break;
+ }
+ case CM_UPDATESTATUSBAR:
+ {
+ HWND hwnd = (HWND) lParam;
+ StatusBarData *sbd = (StatusBarData *) wParam;
+ if (sbd != NULL) {
+ if ((sbd->iFlags & SBDF_TEXT) && dat->hwndActive == hwnd) {
+ SendMessage(dat->hwndStatus, SB_SETTEXT, sbd->iItem, (LPARAM) sbd->pszText);
+ }
+ if ((sbd->iFlags & SBDF_ICON) && dat->hwndActive == hwnd) {
+ SendMessage(dat->hwndStatus, SB_SETICON, sbd->iItem, (LPARAM) sbd->hIcon);
+ }
+ RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
+ }
+ break;
+ }
+ case DM_STATUSICONCHANGE:
+ SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, (LPARAM)0);
+ SetupStatusBar(dat);
+ RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
+ break;
+ case CM_UPDATETABCONTROL:
+ {
+ TCHAR *ptszTemp = NULL;
+ TabControlData *tcd = (TabControlData *) wParam;
+ int tabId = GetTabFromHWND(dat, (HWND) lParam);
+ if (tabId >= 0 && tcd != NULL) {
+ TCITEM tci;
+ tci.mask = 0;
+ if (tcd->iFlags & TCDF_TEXT) {
+ tci.mask |= TCIF_TEXT;
+ tci.pszText = tcd->pszText;
+ if (g_dat->flags2 & SMF2_LIMITNAMES) {
+ TCHAR * ltext = limitText(tcd->pszText, g_dat->limitNamesLength);
+ if (ltext != tcd->pszText)
+ {
+ tci.pszText = ptszTemp = ltext;
+ }
+ }
+ }
+ if (tcd->iFlags & TCDF_ICON) {
+ int iconIdx = -1;
+ if (tcd->hIcon != NULL) {
+ TCITEM tci2;
+ tci2.mask = TCIF_IMAGE;
+ TabCtrl_GetItem(dat->hwndTabs, tabId, &tci2);
+ iconIdx = AddOrReplaceIcon(g_dat->hTabIconList, tci2.iImage, tcd->hIcon);
+ }
+ tci.mask |= TCIF_IMAGE;
+ tci.iImage = iconIdx;
+ }
+ TabCtrl_SetItem(dat->hwndTabs, tabId, &tci);
+ }
+ mir_free(ptszTemp);
+ break;
+ }
+ case DM_SWITCHINFOBAR:
+ {
+ int i;
+ dat->flags2 ^= SMF2_SHOWINFOBAR;
+ for (i=0;i<dat->childrenCount;i++) {
+ MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i);
+ SendMessage(mwtd->hwnd, DM_SWITCHINFOBAR, 0, 0);
+ }
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ }
+ break;
+ case DM_SWITCHSTATUSBAR:
+ dat->flags2 ^= SMF2_SHOWSTATUSBAR;
+ if (!(dat->flags2 & SMF2_SHOWSTATUSBAR)) {
+ ShowWindow(dat->hwndStatus, SW_HIDE);
+ } else {
+ ShowWindow(dat->hwndStatus, SW_SHOW);
+ }
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ break;
+ case DM_SWITCHTOOLBAR:
+ {
+ int i;
+ dat->flags2 ^= SMF2_SHOWTOOLBAR;
+ for (i=0;i<dat->childrenCount;i++) {
+ MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i);
+ SendMessage(mwtd->hwnd, DM_SWITCHTOOLBAR, 0, 0);
+ }
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ }
+ break;
+ case DM_SWITCHTITLEBAR:
+ {
+ RECT rc;
+ dat->flags2 ^= SMF2_SHOWTITLEBAR;
+ ws = GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~(WS_CAPTION);
+ if (dat->flags2 & SMF2_SHOWTITLEBAR) {
+ ws |= WS_CAPTION;
+ }
+ SetWindowLongPtr(hwndDlg, GWL_STYLE, ws);
+ GetWindowRect(hwndDlg, &rc);
+ SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
+// SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ break;
+ case DM_CASCADENEWWINDOW:
+ if ((HWND) wParam == hwndDlg)
+ break;
+ {
+ RECT rcThis, rcNew;
+ GetWindowRect(hwndDlg, &rcThis);
+ GetWindowRect((HWND) wParam, &rcNew);
+ if (abs(rcThis.left - rcNew.left) < 3 && abs(rcThis.top - rcNew.top) < 3) {
+ int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
+ SetWindowPos((HWND) wParam, 0, rcNew.left + offset, rcNew.top + offset, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ *(int *) lParam = 1;
+ }
+ }
+ break;
+ //case DM_MESSAGESENDING:
+ // dat->messagesInProgress += wParam ? -1 : 1;
+ // if (dat->messagesInProgress < 0) dat->messagesInProgress = 0;
+ // break;
+ }
+ return FALSE;
+}
+
+static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+ TabCtrlData *tcdat;
+ TCITEM tci;
+ LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam;
+ int iTabIndex = lpDIS->itemID;
+ tcdat = (TabCtrlData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (iTabIndex >= 0) {
+ HANDLE hTheme = NULL;
+ int tstate;
+ TCHAR szLabel[1024];
+ tci.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_STATE;
+ tci.pszText = szLabel;
+ tci.cchTextMax = SIZEOF(szLabel);
+ tci.dwStateMask = TCIS_HIGHLIGHTED;
+ if (TabCtrl_GetItem(hwnd, iTabIndex, &tci)) {
+ IMAGEINFO info;
+ RECT rIcon = lpDIS->rcItem;
+ RECT rect = lpDIS->rcItem;
+ RECT rectTab = lpDIS->rcItem;
+ int bSelected = lpDIS->itemState & ODS_SELECTED;
+ int atTop = (GetWindowLongPtr(hwnd, GWL_STYLE) & TCS_BOTTOM) == 0;
+ UINT dwFormat;
+ if (!MyIsAppThemed || !MyIsAppThemed()) {
+ FillRect(lpDIS->hDC, &rect, GetSysColorBrush(COLOR_BTNFACE));
+ }
+ else
+ {
+ if (lpDIS->itemState & ODS_SELECTED)
+ tstate = TTIS_SELECTED;
+ else if (lpDIS->itemState & ODS_FOCUS)
+ tstate = TTIS_FOCUSED;
+ else if (lpDIS->itemState & ODS_HOTLIGHT)
+ tstate = TTIS_HOT;
+ else
+ tstate = TTIS_NORMAL;
+
+ if (!bSelected)
+ InflateRect(&rectTab, 1, 1);
+
+ hTheme = MyOpenThemeData(hwnd, L"TAB");
+ if (MyIsThemeBackgroundPartiallyTransparent(hTheme, TABP_TABITEM, tstate))
+ MyDrawThemeParentBackground(hwnd, lpDIS->hDC, &rectTab);
+ MyDrawThemeBackground(hTheme, lpDIS->hDC, TABP_TABITEM, tstate, &rectTab, NULL);
+ }
+ if (atTop) {
+ dwFormat = DT_SINGLELINE|DT_TOP|DT_CENTER|DT_NOPREFIX|DT_NOCLIP;
+ rIcon.top = rect.top + GetSystemMetrics(SM_CYEDGE);
+ if (tci.iImage >= 0) {
+ rIcon.left = rect.left + GetSystemMetrics(SM_CXEDGE) + (bSelected ? 6 : 2);
+ ImageList_GetImageInfo(g_dat->hTabIconList, tci.iImage, &info);
+ ImageList_DrawEx(g_dat->hTabIconList, tci.iImage, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rect.left = rIcon.left + (info.rcImage.right - info.rcImage.left);
+ }
+ if (dat->childrenCount > 1) {
+ ImageList_GetImageInfo(g_dat->hButtonIconList, 0, &info);
+ rIcon.left = rect.right - GetSystemMetrics(SM_CXEDGE) - (bSelected ? 6 : 2) - (info.rcImage.right - info.rcImage.left);
+ ImageList_DrawEx(g_dat->hButtonIconList, 0, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rect.right = rIcon.left - 1;
+ }
+ rect.top += GetSystemMetrics(SM_CYEDGE) + 2;
+ } else {
+ dwFormat = DT_SINGLELINE|DT_BOTTOM|DT_CENTER|DT_NOPREFIX|DT_NOCLIP;
+ rIcon.left = rect.left + GetSystemMetrics(SM_CXEDGE) + (bSelected ? 6 : 2);
+ if (tci.iImage >= 0) {
+ ImageList_GetImageInfo(g_dat->hTabIconList, tci.iImage, &info);
+ rIcon.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top) - 1;
+ ImageList_DrawEx(g_dat->hTabIconList, tci.iImage, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rect.left = rIcon.left + (info.rcImage.right - info.rcImage.left);
+ }
+ if (dat->childrenCount > 1) {
+ ImageList_GetImageInfo(g_dat->hButtonIconList, 0, &info);
+ rIcon.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top) - 2;
+ rIcon.left = rect.right - GetSystemMetrics(SM_CXEDGE) - (bSelected ? 6 : 2) - (info.rcImage.right - info.rcImage.left);
+ ImageList_DrawEx(g_dat->hButtonIconList, 0, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ rect.right = rIcon.left - 1;
+ }
+ rect.bottom -= GetSystemMetrics(SM_CYEDGE) + 2;
+ }
+ if (hTheme) {
+
+ MyDrawThemeText(hTheme, lpDIS->hDC, TABP_TABITEM, tstate, szLabel, -1, dwFormat, 0, &rect);
+
+ }
+ else
+ DrawText(lpDIS->hDC, szLabel, -1, &rect, dwFormat);
+ if (tcdat->bDragged && iTabIndex == tcdat->destTab && iTabIndex != tcdat->srcTab) {
+ RECT hlRect = lpDIS->rcItem;
+ if (bSelected) {
+ hlRect.bottom-=GetSystemMetrics(SM_CYEDGE);
+ hlRect.top+=GetSystemMetrics(SM_CYEDGE);
+ hlRect.left+=GetSystemMetrics(SM_CXEDGE);
+ hlRect.right-=GetSystemMetrics(SM_CXEDGE);
+ } else {
+ if (atTop) {
+ hlRect.top += GetSystemMetrics(SM_CYEDGE);;
+ hlRect.bottom += GetSystemMetrics(SM_CYEDGE);;
+ } else {
+ hlRect.top -= GetSystemMetrics(SM_CYEDGE);;
+ hlRect.bottom -= GetSystemMetrics(SM_CYEDGE);;
+ }
+ }
+ FrameRect(lpDIS->hDC, &hlRect, GetSysColorBrush(COLOR_HIGHLIGHT));
+ hlRect.left++;
+ hlRect.top++;
+ hlRect.right--;
+ hlRect.bottom--;
+ FrameRect(lpDIS->hDC, &hlRect, GetSysColorBrush(COLOR_HIGHLIGHT));
+ }
+ if (hTheme) MyCloseThemeData(hTheme);
+ }
+ }
+}
+
+BOOL CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TabCtrlData *dat;
+ dat = (TabCtrlData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ switch(msg) {
+ case EM_SUBCLASSED:
+ dat = (TabCtrlData *) mir_alloc(sizeof(TabCtrlData));
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) dat);
+ dat->bDragging = FALSE;
+ dat->bDragged = FALSE;
+ dat->srcTab = -1;
+ dat->destTab = -1;
+ return 0;
+ case WM_MBUTTONDOWN:
+ {
+ TCITEM tci;
+ int tabId;
+ MessageWindowTabData *mwtd;
+ TCHITTESTINFO thinfo;
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ tabId = TabCtrl_HitTest(hwnd, &thinfo);
+ if (tabId >= 0) {
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(hwnd, tabId, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd != NULL) {
+ SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0);
+ dat->srcTab = -1;
+ }
+ }
+ return 0;
+ }
+ case WM_LBUTTONDBLCLK:
+ {
+ TCHITTESTINFO thinfo;
+ int tabId;
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ tabId = TabCtrl_HitTest(hwnd, &thinfo);
+ if (tabId >=0 && tabId == dat->srcTab) {
+ SendMessage(GetChildFromTab(hwnd, tabId)->hwnd, WM_CLOSE, 0, 0);
+ dat->srcTab = -1;
+ }
+ dat->destTab = -1;
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ if (!dat->bDragging) {
+ TCHITTESTINFO thinfo;
+ FILETIME ft;
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ dat->srcTab = TabCtrl_HitTest(hwnd, &thinfo);
+ GetSystemTimeAsFileTime(&ft);
+ if (dat->srcTab >=0 ) {
+ dat->bDragging = TRUE;
+ dat->bDragged = FALSE;
+ dat->clickLParam = lParam;
+ dat->clickWParam = wParam;
+ dat->lastClickTime = ft.dwLowDateTime;
+ dat->mouseLBDownPos.x = thinfo.pt.x;
+ dat->mouseLBDownPos.y = thinfo.pt.y;
+ SetCapture(hwnd);
+ }
+ return 0;
+ }
+ break;
+ case WM_CAPTURECHANGED:
+ case WM_LBUTTONUP:
+ if (dat->bDragging) {
+ TCHITTESTINFO thinfo;
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ if (dat->bDragged) {
+ ImageList_DragLeave(GetDesktopWindow());
+ ImageList_EndDrag();
+ ImageList_Destroy(dat->hDragImageList);
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ dat->destTab = TabCtrl_HitTest(hwnd, &thinfo);
+ if (thinfo.flags != TCHT_NOWHERE && dat->destTab != dat->srcTab) {
+ NMHDR nmh;
+ TCHAR sBuffer[501];
+ TCITEM item;
+ int curSel;
+ curSel = TabCtrl_GetCurSel(hwnd);
+ item.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_TEXT;
+ item.pszText = sBuffer;
+ item.cchTextMax = SIZEOF(sBuffer);
+ TabCtrl_GetItem(hwnd, dat->srcTab, &item);
+ sBuffer[SIZEOF(sBuffer)-1] = '\0';
+ if (curSel == dat->srcTab) {
+ curSel = dat->destTab;
+ } else {
+ if (curSel > dat->srcTab && curSel <= dat->destTab) {
+ curSel--;
+ } else if (curSel < dat->srcTab && curSel >= dat->destTab) {
+ curSel++;
+ }
+ }
+ TabCtrl_DeleteItem(hwnd, dat->srcTab);
+ TabCtrl_InsertItem(hwnd, dat->destTab, &item );
+ TabCtrl_SetCurSel(hwnd, curSel);
+ dat->destTab = -1;
+ nmh.hwndFrom = hwnd;
+ nmh.idFrom = GetDlgCtrlID(hwnd);
+ nmh.code = TCN_SELCHANGE;
+ SendMessage(GetParent(hwnd), WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh);
+ UpdateWindow(hwnd);
+ } else if (thinfo.flags == TCHT_NOWHERE) {
+ MessageWindowTabData *mwtd;
+ TCITEM tci;
+ POINT pt;
+ NewMessageWindowLParam newData = { 0 };
+ dat->destTab = -1;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(hwnd, dat->srcTab, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd != NULL) {
+ HWND hChild = mwtd->hwnd;
+ HANDLE hContact = mwtd->hContact;
+ HWND hParent;
+ GetCursorPos(&pt);
+ hParent = WindowFromPoint(pt);
+ while (GetParent(hParent) != NULL) {
+ hParent = GetParent(hParent);
+ }
+ hParent = WindowList_Find(g_dat->hParentWindowList, hParent);
+ if ((hParent != NULL && hParent != GetParent(hwnd)) || (hParent == NULL && mwtd->parent->childrenCount > 1 && (GetKeyState(VK_CONTROL) & 0x8000))) {
+ if (hParent == NULL) {
+ MONITORINFO mi;
+ HMONITOR hMonitor;
+ RECT rc, rcDesktop;
+ newData.hContact = hContact;
+ hParent = (HWND)CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGWIN), NULL, DlgProcParentWindow, (LPARAM) & newData);
+ GetWindowRect(hParent, &rc);
+ rc.right = (rc.right - rc.left);
+ rc.bottom = (rc.bottom - rc.top);
+ rc.left = pt.x - rc.right / 2;
+ rc.top = pt.y - rc.bottom / 2;
+ hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfo(hMonitor, &mi);
+ rcDesktop = mi.rcWork;
+ if (rc.left < rcDesktop.left) {
+ rc.left = rcDesktop.left;
+ }
+ if (rc.top < rcDesktop.top) {
+ rc.top = rcDesktop.top;
+ }
+ MoveWindow(hParent, rc.left, rc.top, rc.right, rc.bottom, FALSE);
+
+ }
+ NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_CLOSING);
+ NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_CLOSE);
+ SetParent(hChild, hParent);
+ SendMessage(GetParent(hwnd), CM_REMOVECHILD, 0, (LPARAM) hChild);
+ SendMessage(hChild, DM_SETPARENT, 0, (LPARAM) hParent);
+ SendMessage(hParent, CM_ADDCHILD, (WPARAM)hChild, (LPARAM) hContact);
+ SendMessage(hChild, DM_UPDATETABCONTROL, 0, 0);
+ SendMessage(hParent, CM_ACTIVATECHILD, 0, (LPARAM) hChild);
+ NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_OPENING);
+ NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_OPEN);
+ ShowWindow(hParent, SW_SHOWNA);
+ EnableWindow(hParent, TRUE);
+ }
+ }
+ } else {
+ dat->destTab = -1;
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+ }
+ } else if (dat->srcTab >= 0 && TabCtrl_GetItemCount(hwnd) > 1) {
+ IMAGEINFO info;
+ POINT pt;
+ RECT rect;
+ int atTop = (GetWindowLongPtr(hwnd, GWL_STYLE) & TCS_BOTTOM) == 0;
+ TabCtrl_GetItemRect(hwnd, dat->srcTab, &rect);
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+ ImageList_GetImageInfo(g_dat->hButtonIconList, 0, &info);
+ rect.left = rect.right - (info.rcImage.right - info.rcImage.left) - 6;
+ if (!atTop) {
+ rect.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top);
+ }
+ if (pt.x >= rect.left && pt.x < rect.left + (info.rcImage.right - info.rcImage.left) && pt.y >= rect.top && pt.y < rect.top + (info.rcImage.bottom - info.rcImage.top)) {
+ HBITMAP hOldBitmap, hBmp;
+ COLORREF color1, color2;
+ HDC hdc = GetDC(NULL);
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ pt.x -= rect.left;
+ pt.y -= rect.top;
+ hBmp = CreateCompatibleBitmap(hdc, info.rcImage.right - info.rcImage.left + 1, info.rcImage.bottom - info.rcImage.top + 1);
+ hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBmp);
+ SetPixel(hdcMem, pt.x, pt.y, 0x000000);
+ ImageList_DrawEx(g_dat->hButtonIconList, 0, hdcMem, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ color1 = GetPixel(hdcMem, pt.x, pt.y);
+ SetPixel(hdcMem, pt.x, pt.y, 0xFFFFFF);
+ ImageList_DrawEx(g_dat->hButtonIconList, 0, hdcMem, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ color2 = GetPixel(hdcMem, pt.x, pt.y);
+ SelectObject(hdcMem, hOldBitmap);
+ DeleteDC(hdcMem);
+ DeleteObject(hBmp);
+ ReleaseDC(NULL, hdc);
+ if (color1 != 0x000000 || color2 != 0xFFFFFF) {
+ SendMessage(GetChildFromTab(hwnd, dat->srcTab)->hwnd, WM_CLOSE, 0, 0);
+ dat->srcTab = -1;
+ }
+ } else {
+ SendMessage(hwnd, WM_LBUTTONDOWN, dat->clickWParam, dat->clickLParam);
+ }
+ } else {
+ SendMessage(hwnd, WM_LBUTTONDOWN, dat->clickWParam, dat->clickLParam);
+ }
+ dat->bDragged = FALSE;
+ dat->bDragging = FALSE;
+ dat->destTab = -1;
+ ReleaseCapture();
+ }
+ break;
+ case WM_MOUSEMOVE:
+ if (wParam & MK_LBUTTON) {
+ if (dat->bDragging) {
+ FILETIME ft;
+ TCHITTESTINFO thinfo;
+ GetSystemTimeAsFileTime(&ft);
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ if (!dat->bDragged) {
+ if ((abs(thinfo.pt.x-dat->mouseLBDownPos.x)<3 && abs(thinfo.pt.y-dat->mouseLBDownPos.y)<3)
+ || (ft.dwLowDateTime - dat->lastClickTime) < 10*1000*150)
+ break;
+ }
+ if (!dat->bDragged) {
+ POINT pt;
+ RECT rect;
+ RECT rect2;
+ HDC hDC, hMemDC;
+ HBITMAP hBitmap, hOldBitmap;
+ HBRUSH hBrush = CreateSolidBrush(RGB(255,0,254));
+ GetCursorPos(&pt);
+ TabCtrl_GetItemRect(hwnd, dat->srcTab, &rect);
+ rect.right -= rect.left-1;
+ rect.bottom -= rect.top-1;
+ rect2.left = 0; rect2.right = rect.right; rect2.top = 0; rect2.bottom = rect.bottom;
+ dat->hDragImageList = ImageList_Create(rect.right, rect.bottom, ILC_COLOR | ILC_MASK, 0, 1);
+ hDC = GetDC(hwnd);
+ hMemDC = CreateCompatibleDC(hDC);
+ hBitmap = CreateCompatibleBitmap(hDC, rect.right, rect.bottom);
+ hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
+ FillRect(hMemDC, &rect2, hBrush);
+ SetWindowOrgEx (hMemDC, rect.left, rect.top, NULL);
+ SendMessage(hwnd, WM_PRINTCLIENT, (WPARAM)hMemDC, PRF_CLIENT);
+ SelectObject(hMemDC, hOldBitmap);
+ ImageList_AddMasked(dat->hDragImageList, hBitmap, RGB(255,0,254));
+ DeleteObject(hBitmap);
+ DeleteObject(hBrush);
+ ReleaseDC(hwnd, hDC);
+ DeleteDC(hMemDC);
+ ImageList_BeginDrag(dat->hDragImageList, 0, dat->mouseLBDownPos.x - rect.left, dat->mouseLBDownPos.y - rect.top);
+ ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y);
+ SetCursor(hDragCursor);
+ dat->mouseLBDownPos.x = thinfo.pt.x;
+ dat->mouseLBDownPos.y = thinfo.pt.y;
+ } else {
+ TCHITTESTINFO thinfo;
+ POINT pt;
+ int newDest;
+ GetCursorPos(&pt);
+ thinfo.pt = pt;
+ ScreenToClient(hwnd, &thinfo.pt);
+ newDest = TabCtrl_HitTest(hwnd, &thinfo);
+ if (thinfo.flags == TCHT_NOWHERE) {
+ newDest = -1;
+ }
+ if (newDest != dat->destTab) {
+ dat->destTab = newDest;
+ ImageList_DragLeave(GetDesktopWindow());
+ RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
+ ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y);
+ } else {
+ ImageList_DragMove(pt.x, pt.y);
+ }
+ }
+ dat->bDragged = TRUE;
+ return 0;
+ }
+ }
+ break;
+ case EM_UNSUBCLASSED:
+ mir_free(dat);
+ return 0;
+ }
+ return CallWindowProc(OldTabCtrlProc, hwnd, msg, wParam, lParam);
+}
+
+
+int ScriverRestoreWindowPosition(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix, int flags, int showCmd)
+{
+ RECT rcDesktop;
+ WINDOWPLACEMENT wp;
+ char szSettingName[64];
+ int x,y;
+ MONITORINFO mi;
+ HMONITOR hMonitor;
+// SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0);
+ wp.length=sizeof(wp);
+ GetWindowPlacement(hwnd,&wp);
+ wsprintfA(szSettingName,"%sx",szNamePrefix);
+ x=DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ wsprintfA(szSettingName,"%sy",szNamePrefix);
+ y=(int)DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ if (x==-1) return 1;
+ if (flags&RWPF_NOSIZE) {
+ OffsetRect(&wp.rcNormalPosition,x-wp.rcNormalPosition.left,y-wp.rcNormalPosition.top);
+ } else {
+ wp.rcNormalPosition.left=x;
+ wp.rcNormalPosition.top=y;
+ wsprintfA(szSettingName,"%swidth",szNamePrefix);
+ wp.rcNormalPosition.right=wp.rcNormalPosition.left+DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ wsprintfA(szSettingName,"%sheight",szNamePrefix);
+ wp.rcNormalPosition.bottom=wp.rcNormalPosition.top+DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ }
+ wp.flags=0;
+ wp.showCmd = showCmd;
+
+ hMonitor = MonitorFromRect(&wp.rcNormalPosition, MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfo(hMonitor, &mi);
+ rcDesktop = mi.rcWork;
+ if (wp.rcNormalPosition.left > rcDesktop.right || wp.rcNormalPosition.top > rcDesktop.bottom
+ || wp.rcNormalPosition.right < rcDesktop.left || wp.rcNormalPosition.bottom < rcDesktop.top) return 1;
+ SetWindowPlacement(hwnd,&wp);
+ return 0;
+}
+
+HWND GetParentWindow(HANDLE hContact, BOOL bChat) {
+ NewMessageWindowLParam newData = { 0 };
+ newData.hContact = hContact;
+ newData.isChat = bChat;
+ if (g_dat->flags2 & SMF2_USETABS) {
+ if (!bChat || !(g_dat->flags2 & SMF2_SEPARATECHATSCONTAINERS)) {
+ if (g_dat->lastParent != NULL) {
+ int tabsNum = (int) SendMessage(g_dat->lastParent->hwnd, CM_GETCHILDCOUNT, 0, 0);
+ if (!(g_dat->flags2 & SMF2_LIMITTABS) || tabsNum < g_dat->limitTabsNum) {
+ return g_dat->lastParent->hwnd;
+ }
+ }
+ } else {
+ if (g_dat->lastChatParent != NULL) {
+ int tabsNum = (int) SendMessage(g_dat->lastChatParent->hwnd, CM_GETCHILDCOUNT, 0, 0);
+ if (!(g_dat->flags2 & SMF2_LIMITCHATSTABS) || tabsNum < g_dat->limitChatsTabsNum) {
+ return g_dat->lastChatParent->hwnd;
+ }
+ }
+ }
+ }
+ if (!(g_dat->flags2 & SMF2_SEPARATECHATSCONTAINERS)) {
+ newData.isChat =FALSE;
+ }
+ return CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGWIN), NULL, DlgProcParentWindow, (LPARAM) & newData);
+}
diff --git a/plugins/Scriver/src/msgwindow.h b/plugins/Scriver/src/msgwindow.h new file mode 100644 index 0000000000..3d560550e0 --- /dev/null +++ b/plugins/Scriver/src/msgwindow.h @@ -0,0 +1,97 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef MSGWINDOW_H
+#define MSGWINDOW_H
+
+/* container services */
+#define CM_ADDCHILD (WM_USER+0x180)
+#define CM_REMOVECHILD (WM_USER+0x181)
+#define CM_ACTIVATECHILD (WM_USER+0x182)
+#define CM_ACTIVATEPREV (WM_USER+0x183)
+#define CM_ACTIVATENEXT (WM_USER+0x184)
+#define CM_ACTIVATEBYINDEX (WM_USER+0x185)
+
+#define CM_GETCHILDCOUNT (WM_USER+0x188)
+#define CM_GETACTIVECHILD (WM_USER+0x189)
+#define CM_GETFLAGS (WM_USER+0x18A)
+
+#define CM_UPDATETITLEBAR (WM_USER+0x190)
+#define CM_UPDATESTATUSBAR (WM_USER+0x191)
+#define CM_UPDATETABCONTROL (WM_USER+0x192)
+#define CM_STARTFLASHING (WM_USER+0x1A0)
+#define CM_POPUPWINDOW (WM_USER+0x1A1)
+
+#define CM_GETTOOLBARSTATUS (WM_USER+0x1A2)
+
+/* child window services */
+#define DM_UPDATETITLEBAR (WM_USER+0x200)
+#define DM_UPDATESTATUSBAR (WM_USER+0x201)
+#define DM_UPDATETABCONTROL (WM_USER+0x202)
+#define DM_SETPARENT (WM_USER+0x203)
+#define DM_ACTIVATE (WM_USER+0x206)
+#define DM_GETCONTEXTMENU (WM_USER+0x207)
+#define DM_GETCODEPAGE (WM_USER+0x208)
+#define DM_SETCODEPAGE (WM_USER+0x209)
+#define DM_SETFOCUS (WM_USER+0x20A)
+#define DM_CLISTSETTINGSCHANGED (WM_USER+0x20B)
+
+#define SBDF_TEXT 1
+#define SBDF_ICON 2
+
+typedef struct StatusBarDataStruct
+{
+ int iItem;
+ int iFlags;
+ TCHAR *pszText;
+ HICON hIcon;
+} StatusBarData;
+
+#define TBDF_TEXT 1
+#define TBDF_ICON 2
+
+typedef struct TitleBarDataStruct
+{
+ int iFlags;
+ TCHAR *pszText;
+ HICON hIcon;
+ HICON hIconBig;
+ HICON hIconNot;
+} TitleBarData;
+
+#define TCDF_TEXT 1
+#define TCDF_ICON 2
+
+typedef struct TabControlDataStruct
+{
+ int iFlags;
+ TCHAR *pszText;
+// int iconIdx;
+ HICON hIcon;
+} TabControlData;
+
+extern TCHAR* GetWindowTitle(HANDLE *hContact, const char *szProto);
+extern TCHAR* GetTabName(HANDLE *hContact);
+extern HWND GetParentWindow(HANDLE hContact, BOOL bChat);
+extern void NotifyLocalWinEvent(HANDLE hContact, HWND hwnd, unsigned int type);
+
+#endif
diff --git a/plugins/Scriver/src/multimon.h b/plugins/Scriver/src/multimon.h new file mode 100644 index 0000000000..aedd943da4 --- /dev/null +++ b/plugins/Scriver/src/multimon.h @@ -0,0 +1,383 @@ +//#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
+
+//=============================================================================
+//
+// MULTIMON
+// stub module that "stubs" multiple monitor APIs on pre-Memphis Win32 OSes
+//
+// By using this header your code will work unchanged on Win95,
+// you will get back correct values from GetSystemMetrics() for new metrics
+// and the new APIs will act like only one display is present.
+//
+// exactly one source must include this with COMPILE_MULTIMON_STUBS defined
+//
+//=============================================================================
+
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif /* __cplusplus */
+
+//
+// if we are building on Win95/NT4 headers we need to declare this stuff ourselves
+//
+#ifndef SM_SAMEDISPLAYFORMAT
+#define SM_SAMEDISPLAYFORMAT 81
+#endif
+
+#ifndef SM_CMONITORS
+#ifndef MONITORINFOF_PRIMARY
+
+#define SM_XVIRTUALSCREEN 76
+#define SM_YVIRTUALSCREEN 77
+#define SM_CXVIRTUALSCREEN 78
+#define SM_CYVIRTUALSCREEN 79
+#define SM_CMONITORS 80
+
+DECLARE_HANDLE(HMONITOR);
+
+typedef struct tagMONITORINFO
+{
+ DWORD cbSize;
+ RECT rcMonitor;
+ RECT rcWork;
+ DWORD dwFlags;
+} MONITORINFO, *LPMONITORINFO;
+
+#define CCHDEVICENAME 32
+#endif // SM_CMONITORS
+
+#define MONITORINFOF_PRIMARY 0x00000001
+
+#ifndef MONITOR_DEFAULTTONULL
+#define MONITOR_DEFAULTTONULL 0x00000000
+#endif
+#ifndef MONITOR_DEFAULTTOPRIMARY
+#define MONITOR_DEFAULTTOPRIMARY 0x00000001
+#endif
+#ifndef MONITOR_DEFAULTTONEAREST
+#define MONITOR_DEFAULTTONEAREST 0x00000002
+#endif
+
+typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
+
+ #ifdef __cplusplus
+ typedef struct tagMONITORINFOEX : public tagMONITORINFO
+ {
+ TCHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEX, *LPMONITORINFOEX;
+ #else
+ typedef struct
+ {
+ MONITORINFO;
+ TCHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEX, *LPMONITORINFOEX;
+ #endif
+
+
+#ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
+
+typedef struct {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD StateFlags;
+} DISPLAY_DEVICE;
+
+#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
+#define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
+#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
+#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
+
+#endif
+#endif
+#define DISPLAY_DEVICE_VGA 0x00000010
+
+#ifndef ENUM_CURRENT_SETTINGS
+#define ENUM_CURRENT_SETTINGS ((DWORD)-1)
+#define ENUM_REGISTRY_SETTINGS ((DWORD)-2)
+#endif
+
+#undef GetMonitorInfo
+#undef GetSystemMetrics
+#undef MonitorFromWindow
+#undef MonitorFromRect
+#undef MonitorFromPoint
+#undef EnumDisplayMonitors
+#undef EnumDisplayDevices
+
+//
+// define this to compile the stubs
+// otherwise you get the declarations
+//
+#ifdef COMPILE_MULTIMON_STUBS
+
+ //---------------------------------------------------------------------------
+ //
+ // Implement the API stubs.
+ //
+ //---------------------------------------------------------------------------
+
+ int (WINAPI* g_pfnGetSystemMetrics)(int);
+ HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, BOOL);
+ HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, BOOL);
+ HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, BOOL);
+ BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO);
+ BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT,
+ MONITORENUMPROC, LPARAM);
+ BOOL (WINAPI *g_pfnEnumDisplayDevices)(LPVOID, int,
+ DISPLAY_DEVICE *,DWORD);
+
+ BOOL InitMultipleMonitorStubs(void)
+ {
+ HMODULE hUser32;
+ static BOOL fInitDone;
+
+ if (fInitDone)
+ {
+ return g_pfnGetMonitorInfo != NULL;
+ }
+
+ if ((hUser32 = GetModuleHandle(TEXT("USER32"))) &&
+ (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) &&
+ (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) &&
+ (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) &&
+ (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) &&
+ (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) &&
+ (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoW")) &&
+ (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) &&
+ (GetSystemMetrics(SM_CXVIRTUALSCREEN) >= GetSystemMetrics(SM_CXSCREEN)) &&
+ (GetSystemMetrics(SM_CYVIRTUALSCREEN) >= GetSystemMetrics(SM_CYSCREEN)))
+ {
+ fInitDone = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ g_pfnGetSystemMetrics = NULL;
+ g_pfnMonitorFromWindow = NULL;
+ g_pfnMonitorFromRect = NULL;
+ g_pfnMonitorFromPoint = NULL;
+ g_pfnGetMonitorInfo = NULL;
+ g_pfnEnumDisplayMonitors = NULL;
+ g_pfnEnumDisplayDevices = NULL;
+
+ fInitDone = TRUE;
+ return FALSE;
+ }
+ }
+
+ //---------------------------------------------------------------------------
+ //
+ // "stubbed" implementations of Monitor APIs that work with the primary // display
+ //
+ //---------------------------------------------------------------------------
+
+ int WINAPI
+ xGetSystemMetrics(int nIndex)
+ {
+ if (InitMultipleMonitorStubs())
+ return g_pfnGetSystemMetrics(nIndex);
+
+ switch (nIndex)
+ {
+ case SM_CMONITORS:
+ case SM_SAMEDISPLAYFORMAT:
+ return 1;
+
+ case SM_XVIRTUALSCREEN:
+ case SM_YVIRTUALSCREEN:
+ return 0;
+
+ case SM_CXVIRTUALSCREEN:
+ nIndex = SM_CXSCREEN;
+ break;
+
+ case SM_CYVIRTUALSCREEN:
+ nIndex = SM_CYSCREEN;
+ break;
+ }
+
+ return GetSystemMetrics(nIndex);
+ }
+
+ #define xPRIMARY_MONITOR ((HMONITOR)0x42)
+
+ HMONITOR WINAPI
+ xMonitorFromRect(LPCRECT lprcScreenCoords, UINT uFlags)
+ {
+ if (InitMultipleMonitorStubs())
+ return g_pfnMonitorFromRect(lprcScreenCoords, uFlags);
+
+ if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
+ ((lprcScreenCoords->right > 0) &&
+ (lprcScreenCoords->bottom > 0) &&
+ (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
+ (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
+ {
+ return xPRIMARY_MONITOR;
+ }
+
+ return NULL;
+ }
+
+ HMONITOR WINAPI
+ xMonitorFromWindow(HWND hWnd, UINT uFlags)
+ {
+ RECT rc;
+
+ if (InitMultipleMonitorStubs())
+ return g_pfnMonitorFromWindow(hWnd, uFlags);
+
+ if (uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
+ return xPRIMARY_MONITOR;
+
+ if (GetWindowRect(hWnd, &rc))
+ return xMonitorFromRect(&rc, uFlags);
+
+ return NULL;
+ }
+
+ HMONITOR WINAPI
+ xMonitorFromPoint(POINT ptScreenCoords, UINT uFlags)
+ {
+ if (InitMultipleMonitorStubs())
+ return g_pfnMonitorFromPoint(ptScreenCoords, uFlags);
+
+ if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
+ ((ptScreenCoords.x >= 0) &&
+ (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
+ (ptScreenCoords.y >= 0) &&
+ (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
+ {
+ return xPRIMARY_MONITOR;
+ }
+
+ return NULL;
+ }
+
+ BOOL WINAPI
+ xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
+ {
+ RECT rcWork;
+
+ if (InitMultipleMonitorStubs())
+ return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
+
+ if ((hMonitor == xPRIMARY_MONITOR) && lpMonitorInfo &&
+ (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0))
+ {
+ lpMonitorInfo->rcMonitor.left = 0;
+ lpMonitorInfo->rcMonitor.top = 0;
+ lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
+ lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
+ lpMonitorInfo->rcWork = rcWork;
+ lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
+
+ if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
+ lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice,
+ TEXT("DISPLAY"));
+
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ BOOL WINAPI
+ xEnumDisplayMonitors(
+ HDC hdc,
+ LPCRECT lprcIntersect,
+ MONITORENUMPROC lpfnEnumProc,
+ LPARAM lData)
+ {
+ RECT rcCallback, rcLimit;
+
+ if (InitMultipleMonitorStubs())
+ return g_pfnEnumDisplayMonitors(hdc, lprcIntersect, lpfnEnumProc,
+ lData);
+
+ if (!lpfnEnumProc)
+ return FALSE;
+
+ rcLimit.left = 0;
+ rcLimit.top = 0;
+ rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
+ rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
+
+ if (hdc)
+ {
+ RECT rcClip;
+ HWND hWnd;
+
+ if ((hWnd = WindowFromDC(hdc)) == NULL)
+ return FALSE;
+
+ switch (GetClipBox(hdc, &rcClip))
+ {
+ default:
+ MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2);
+ if (IntersectRect(&rcCallback, &rcClip, &rcLimit))
+ break;
+ //fall thru
+ case NULLREGION:
+ return TRUE;
+ case ERROR:
+ return FALSE;
+ }
+
+ rcLimit = rcCallback;
+ }
+
+ if (!lprcIntersect ||
+ IntersectRect(&rcCallback, lprcIntersect, &rcLimit))
+ {
+ lpfnEnumProc(xPRIMARY_MONITOR, hdc, &rcCallback, lData);
+ }
+
+ return TRUE;
+ }
+
+ BOOL WINAPI
+ xEnumDisplayDevices(LPVOID lpReserved, int iDeviceNum,
+DISPLAY_DEVICE * pDisplayDevice, DWORD dwFlags)
+ {
+ if (InitMultipleMonitorStubs())
+ return g_pfnEnumDisplayDevices(lpReserved, iDeviceNum,
+ pDisplayDevice, dwFlags);
+
+ return FALSE;
+ }
+
+ #undef xPRIMARY_MONITOR
+ #undef COMPILE_MULTIMON_STUBS
+
+#else // COMPILE_MULTIMON_STUBS
+
+ extern int WINAPI xGetSystemMetrics(int);
+ extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT);
+ extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT);
+ extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT);
+ extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
+ extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC,
+ LPARAM);
+ extern BOOL WINAPI xEnumDisplayDevices(LPVOID, int, DISPLAY_DEVICE *,DWORD);
+
+#endif // COMPILE_MULTIMON_STUBS
+
+//
+// build defines that replace the regular APIs with our versions
+//
+#define GetSystemMetrics xGetSystemMetrics
+#define MonitorFromWindow xMonitorFromWindow
+#define MonitorFromRect xMonitorFromRect
+#define MonitorFromPoint xMonitorFromPoint
+#define GetMonitorInfo xGetMonitorInfo
+#define EnumDisplayMonitors xEnumDisplayMonitors
+#define EnumDisplayDevices xEnumDisplayDevices
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+//#endif /* !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) */
\ No newline at end of file diff --git a/plugins/Scriver/src/resource.h b/plugins/Scriver/src/resource.h new file mode 100644 index 0000000000..07ea9a6546 --- /dev/null +++ b/plugins/Scriver/src/resource.h @@ -0,0 +1,254 @@ +#define IDD_MSGWIN 100
+#define IDD_MSG 101
+#define IDD_MSGSENDERROR 102
+#define IDD_CONFIRM_SENDALL 103
+#define IDD_INFOBAR 104
+#define IDD_OPT_MSGDLG 111
+#define IDD_OPT_MSGLOG 112
+#define IDD_OPT_MSGTYPE 114
+#define IDD_OPT_MSGTABS 115
+#define IDD_OPT_LAYOUT 116
+#define IDI_ADDCONTACT 120
+#define IDI_USERDETAILS 121
+#define IDI_HISTORY 122
+#define IDI_SEND 123
+#define IDI_SMILEY 125
+#define IDI_TYPING 126
+#define IDI_UNICODEON 127
+#define IDI_UNICODEOFF 128
+#define IDI_TIMESTAMP 129
+#define IDI_QUOTE 130
+#define IDI_INCOMING 132
+#define IDI_OUTGOING 133
+#define IDI_NOTICE 134
+#define IDI_CLOSEX 135
+
+#define IDI_GOOGLE 140
+#define IDI_BING 141
+#define IDI_WIKIPEDIA 142
+#define IDI_GOOGLE_MAPS 143
+#define IDI_GOOGLE_TRANSLATE 144
+#define IDI_YAHOO 145
+#define IDI_FOODNETWORK 146
+
+#define IDR_CONTEXT 180
+
+/* chat dll */
+#define IDD_CHANNEL 401
+#define IDD_OPTIONS1 402
+#define IDD_OPTIONS2 403
+#define IDD_FILTER 405
+#define IDD_OPTIONSPOPUP 406
+#define IDI_BUNDERLINE 420
+#define IDI_BBOLD 421
+#define IDI_BITALICS 422
+#define IDI_TOPICBUT 424
+#define IDI_BKGCOLOR 425
+#define IDI_CHANMGR 426
+#define IDI_COLOR 427
+#define IDI_FILTER 428
+#define IDI_NICKLIST 430
+#define IDI_JOIN 431
+#define IDI_PART 432
+#define IDI_QUIT 433
+#define IDI_KICK 434
+#define IDI_NICK 435
+#define IDI_CHAT_NOTICE 436
+#define IDI_TOPIC 439
+#define IDI_INFO 440
+#define IDI_ADDSTATUS 441
+#define IDI_REMSTATUS 442
+#define IDI_ACTION 443
+#define IDR_MENU 451
+#define IDD_COLORCHOOSER 452
+#define IDI_STATUS3 453
+#define IDI_STATUS2 454
+#define IDI_STATUS4 455
+#define IDI_STATUS1 456
+#define IDI_STATUS0 457
+#define IDI_STATUS5 458
+#define IDI_OVERLAY 460
+#define IDI_NICKLIST2 461
+#define IDI_FILTER2 462
+#define IDI_TYPINGOFF 463
+
+#define IDC_HYPERLINKHAND 600
+#define IDC_DRAGCURSOR 601
+
+#define IDC_TABS 1000
+#define IDC_LOG 1001
+#define IDC_MESSAGE 1002
+#define IDC_AUTOPOPUP 1003
+#define IDC_AUTOMIN 1005
+#define IDC_STAYMINIMIZED 1006
+#define IDC_SWITCHTOACTIVE 1007
+#define IDC_SEPARATECHATSCONTAINERS 1008
+#define IDC_LIMITTABS 1010
+#define IDC_LIMITTABSNUM 1011
+#define IDC_LIMITCHATSTABS 1012
+#define IDC_LIMITCHATSTABSNUM 1013
+#define IDC_SPLITTER 1017
+#define IDC_SHOWNAMES 1020
+#define IDC_USETABS 1022
+#define IDC_SHOWSECONDS 1023
+#define IDC_USELONGDATE 1024
+#define IDC_USERELATIVEDATE 1025
+#define IDC_USEIEVIEW 1026
+#define IDC_FONTSCOLORS 1027
+#define IDC_SHOWLOGICONS 1032
+#define IDC_SHOWTIMES 1033
+#define IDC_SHOWDATES 1034
+#define IDC_CLIST 1035
+#define IDC_SHOWSTATUSCHANGES 1035
+#define IDC_GROUPMESSAGES 1036
+#define IDC_SAVEPERCONTACT 1037
+#define IDC_LOADCOUNTN 1039
+#define IDC_LOADCOUNTSPIN 1040
+#define IDC_SHOWINFOLINE 1041
+#define IDC_SHOWSTATUSBAR 1041
+#define IDC_SHOWTOOLBAR 1042
+#define IDC_LOADUNREAD 1043
+#define IDC_SENDONENTER 1043
+#define IDC_LOADCOUNT 1044
+#define IDC_SENDONDBLENTER 1044
+#define IDC_LOADTIMEN 1045
+#define IDC_LOADTIMESPIN 1046
+#define IDC_LOADTIME 1047
+#define IDC_SHOWTITLEBAR 1050
+#define IDC_STMINSOLD 1051
+#define IDC_SHOWPROGRESS 1052
+#define IDC_SHOWINFOBAR 1053
+#define IDC_DETAILS 1069
+#define IDC_ADD 1070
+#define IDC_USERMENU 1071
+#define IDC_QUOTE 1072
+#define IDC_HISTORY 1080
+#define IDC_SMILEYS 1081
+#define IDC_REMEMBER 1082
+#define IDC_INFOBAR_NAME 1090
+#define IDC_INFOBAR_STATUS 1091
+#define IDC_STMSGLOGGROUP 1442
+#define IDC_ERRORTEXT 1596
+#define IDC_MSGTEXT 1597
+#define IDC_SHOWNOTIFY 1600
+#define IDC_STATUSWIN 1601
+#define IDC_TYPEWIN 1602
+#define IDC_CHARCOUNT 1603
+#define IDC_TYPETRAY 1603
+#define IDC_TABSATBOTTOM 1603
+#define IDC_CASCADE 1604
+#define IDC_SECONDS 1605
+#define IDC_NOTIFYTRAY 1606
+#define IDC_NOTIFYBALLOON 1607
+#define IDC_DELTEMP 1609
+#define IDC_AVATARSUPPORT 1611
+#define IDC_LIMITNAMES 1615
+#define IDC_TRANSPARENCY 1616
+#define IDC_MARKFOLLOWUPS 1617
+#define IDC_MESSAGEONNEWLINE 1618
+#define IDC_ATRANSPARENCYVALUE 1619
+#define IDC_ATRANSPARENCYPERC 1620
+#define IDC_ITRANSPARENCYVALUE 1621
+#define IDC_ITRANSPARENCYPERC 1622
+#define IDC_SENDALL 1624
+#define IDC_TRANSPARENCYTEXT1 1627
+#define IDC_TRANSPARENCYTEXT2 1628
+#define IDC_DRAWLINES 1629
+#define IDC_LINECOLOUR 1630
+#define IDC_SAVEDRAFTS 1631
+#define IDC_POPLIST 1632
+#define IDC_LIMITNAMESLEN 1633
+#define IDC_CHARS 1634
+#define IDC_INDENTTEXT 1635
+#define IDC_INDENTSIZE 1636
+#define IDC_INDENTSPIN 1637
+#define IDC_HIDECONTAINERS 1638
+#define IDC_ORIGINALAVATARH 1639
+#define IDC_TYPINGSWITCH 1640
+#define IDC_LOADCOUNTTEXT2 1641
+#define IDC_CHAT_NICKROWTEXT2 1642
+#define IDC_CHAT_LIMITTEXT2 1643
+#define IDC_INFOBAR 1644
+#define IDC_AVATAR 1645
+#define IDC_XSTATUSICON 1646
+#define IDC_INPUTLINES 1647
+#define IDC_INPUTLINESSPIN 1648
+#define IDM_CUT 40000
+#define IDM_COPY 40001
+#define IDM_PASTE 40002
+#define IDM_UNDO 40003
+#define IDM_DELETE 40004
+#define IDM_REDO 40005
+#define IDM_PASTESEND 40006
+#define IDM_COPYALL 40011
+#define IDM_SELECTALL 40012
+#define IDM_CLEAR 40013
+#define IDM_OPENLINK 40014
+#define IDM_COPYLINK 40016
+#define IDM_CLOSETAB 40020
+#define IDM_CLOSEOTHERTABS 40021
+#define IDM_TOPMOST 40040
+#define IDM_SEARCH_GOOGLE 40080
+#define IDM_SEARCH_BING 40081
+#define IDM_SEARCH_WIKIPEDIA 40082
+#define IDM_SEARCH_GOOGLE_MAPS 40083
+#define IDM_SEARCH_GOOGLE_TRANSLATE 40084
+#define IDM_SEARCH_YAHOO 40085
+#define IDM_SEARCH_FOODNETWORK 40086
+/* chat.dll resources */
+
+#define IDC_CHAT_LOG 5005
+#define IDC_CHAT_SPLITTERX 5006
+#define IDC_CHAT_SMILEY 5007
+#define IDC_CHAT_SPLITTERY 5008
+#define IDC_CHAT_MESSAGE 5009
+#define IDC_CHAT_BOLD 5010
+#define IDC_CHAT_ITALICS 5011
+#define IDC_CHAT_UNDERLINE 5012
+#define IDC_CHAT_FILTER 5013
+#define IDC_CHAT_CHANMGR 5014
+#define IDC_CHAT_SHOWNICKLIST 5016
+#define IDC_CHAT_COLOR 5017
+#define IDC_CHAT_BKGCOLOR 5019
+#define IDC_CHAT_FONTSIZE 5020
+#define IDC_CHAT_CHECKBOXES 5021
+#define IDC_CHAT_HISTORY 5022
+#define IDC_CHAT_NICKROW 5024
+#define IDC_CHAT_LOGLIMIT 5024
+#define IDC_CHAT_SPIN1 5028
+#define IDC_CHAT_SPIN2 5029
+#define IDC_CHAT_SPIN3 5030
+#define IDC_CHAT_HIGHLIGHTWORDS 5040
+#define IDC_CHAT_INSTAMP 5041
+#define IDC_CHAT_OUTSTAMP 5043
+#define IDC_CHAT_TIMESTAMP 5046
+#define IDC_CHAT_LOGDIRCHOOSE 5047
+#define IDC_CHAT_LOGDIRECTORY 5048
+#define IDC_CHAT_LIMIT 5050
+#define IDC_CHAT_LOGTIMESTAMP 5051
+#define IDC_CHAT_GROUP 5057
+#define IDC_CHAT_RADIO1 5061
+#define IDC_CHAT_RADIO2 5062
+#define IDC_CHAT_RADIO3 5063
+#define IDC_CHAT_TEXT 5064
+#define IDC_CHAT_BKG 5065
+#define IDC_CHAT_TIMEOUT 5067
+#define IDC_CHAT_HIGHLIGHT 5068
+#define IDC_CHAT_TEXTO 5069
+#define IDC_CHAT_LOGGING 5069
+#define IDC_CHAT_COLORTEXT 5070
+#define IDC_CHAT_LIST 5072
+#define IDC_CHAT_1 5075
+#define IDC_CHAT_2 5076
+#define IDC_CHAT_3 5077
+#define IDC_CHAT_4 5078
+#define IDC_CHAT_5 5079
+#define IDC_CHAT_6 5080
+#define IDC_CHAT_7 5081
+#define IDC_CHAT_8 5082
+#define IDC_CHAT_9 5083
+#define IDC_CHAT_10 5084
+#define IDC_CHAT_11 5085
+#define ID_MESS 50001
+#define ID_COPYALL 50006
+#define ID_Menu 50026
diff --git a/plugins/Scriver/src/richutil.cpp b/plugins/Scriver/src/richutil.cpp new file mode 100644 index 0000000000..8c562b060c --- /dev/null +++ b/plugins/Scriver/src/richutil.cpp @@ -0,0 +1,264 @@ +/*
+Copyright 2000-2010 Miranda IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "richutil.h"
+
+/*
+ To initialize this library, call:
+ RichUtil_Load();
+ Before the application exits, call:
+ RichUtil_Unload();
+
+ Then to use the library (it draws the xp border around it), you need
+ to make sure you control has the WS_EX_STATICEDGE flag. Then you just
+ subclass it with:
+ RichUtil_SubClass(hwndEdit);
+
+ If no xptheme is present, the window isn't subclassed the SubClass function
+ just returns. And if WS_EX_STATICEDGE isn't present, the subclass does nothing.
+ Otherwise it removes the border and draws it by itself.
+*/
+
+static SortedList sListInt;
+
+static int RichUtil_CmpVal(void *p1, void *p2)
+{
+ TRichUtil *tp1 = (TRichUtil*)p1;
+ TRichUtil *tp2 = (TRichUtil*)p2;
+ return (int)((INT_PTR)tp1->hwnd - (INT_PTR)tp2->hwnd);
+}
+
+// UxTheme Stuff
+HMODULE mTheme;
+
+HANDLE (WINAPI *MyOpenThemeData)(HWND, LPCWSTR);
+HRESULT (WINAPI *MyCloseThemeData)(HANDLE);
+BOOL (WINAPI *MyIsThemeActive)(VOID);
+HRESULT (WINAPI *MyDrawThemeBackground)(HANDLE, HDC, int, int, LPCRECT, LPCRECT);
+HRESULT (WINAPI *MyGetThemeBackgroundContentRect)(HANDLE, HDC, int, int, LPCRECT, LPRECT);
+HRESULT (WINAPI *MyDrawThemeParentBackground)(HWND, HDC, LPRECT);
+BOOL (WINAPI *MyIsThemeBackgroundPartiallyTransparent)(HANDLE, int, int);
+HRESULT (WINAPI *MyDrawThemeText)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, LPCRECT);
+HRESULT (WINAPI *MyEnableThemeDialogTexture)(HWND, DWORD);
+BOOL (WINAPI *MyIsAppThemed)(VOID);
+
+static CRITICAL_SECTION csRich;
+
+static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+static void RichUtil_ClearUglyBorder(TRichUtil *ru);
+
+void RichUtil_Load(void)
+{
+ sListInt.increment = 10;
+ sListInt.sortFunc = RichUtil_CmpVal;
+
+ mTheme = IsWinVerXPPlus() ? GetModuleHandleA("uxtheme") : 0;
+
+ InitializeCriticalSection(&csRich);
+ if (!mTheme) return;
+
+ MyOpenThemeData = (HANDLE (WINAPI *)(HWND, LPCWSTR))GetProcAddress(mTheme, "OpenThemeData");
+ MyCloseThemeData = (HRESULT (WINAPI *)(HANDLE))GetProcAddress(mTheme, "CloseThemeData");
+ MyIsThemeActive = (BOOL (WINAPI *)())GetProcAddress(mTheme, "IsThemeActive");
+ MyIsAppThemed = (BOOL (WINAPI *)(VOID))GetProcAddress(mTheme, "IsAppThemed");
+ MyDrawThemeBackground = (HRESULT (WINAPI *)(HANDLE, HDC, int, int, const RECT*, const RECT *))GetProcAddress(mTheme, "DrawThemeBackground");
+ MyGetThemeBackgroundContentRect = (HRESULT (WINAPI *)(HANDLE, HDC, int, int, const RECT *, RECT *))GetProcAddress(mTheme, "GetThemeBackgroundContentRect");
+ MyDrawThemeParentBackground = (HRESULT (WINAPI *)(HWND, HDC, RECT*))GetProcAddress(mTheme, "DrawThemeParentBackground");
+ MyIsThemeBackgroundPartiallyTransparent = (BOOL (WINAPI *)(HANDLE, int, int))GetProcAddress(mTheme, "IsThemeBackgroundPartiallyTransparent");
+ MyDrawThemeText = (HRESULT (WINAPI *)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, const RECT *))GetProcAddress(mTheme, "DrawThemeText");
+ MyEnableThemeDialogTexture = (HRESULT (WINAPI *)(HWND, DWORD))GetProcAddress(mTheme, "EnableThemeDialogTexture");
+ if (!MyOpenThemeData ||
+ !MyCloseThemeData ||
+ !MyIsThemeActive ||
+ !MyDrawThemeBackground ||
+ !MyGetThemeBackgroundContentRect ||
+ !MyDrawThemeParentBackground ||
+ !MyIsThemeBackgroundPartiallyTransparent)
+ {
+ FreeLibrary(mTheme);
+ mTheme = NULL;
+ }
+}
+
+void RichUtil_Unload(void)
+{
+ List_Destroy(&sListInt);
+ DeleteCriticalSection(&csRich);
+ if (mTheme)
+ FreeLibrary(mTheme);
+}
+
+int RichUtil_SubClass(HWND hwndEdit)
+{
+ if (IsWindow(hwndEdit))
+ {
+ int idx;
+
+ TRichUtil *ru = (TRichUtil*)mir_calloc(sizeof(TRichUtil));
+
+ ru->hwnd = hwndEdit;
+ ru->hasUglyBorder = 0;
+
+ EnterCriticalSection(&csRich);
+ if (!List_GetIndex(&sListInt, ru, &idx))
+ List_Insert(&sListInt, ru, idx);
+ LeaveCriticalSection(&csRich);
+
+ ru->origProc = (WNDPROC)SetWindowLongPtr(ru->hwnd, GWLP_WNDPROC, (LONG_PTR)&RichUtil_Proc);
+ RichUtil_ClearUglyBorder(ru);
+ return 1;
+ }
+ return 0;
+}
+
+static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TRichUtil *ru = NULL, tru;
+ int idx;
+
+ tru.hwnd = hwnd;
+
+ EnterCriticalSection(&csRich);
+ if (List_GetIndex(&sListInt, &tru, &idx))
+ ru = (TRichUtil*)sListInt.items[idx];
+ LeaveCriticalSection(&csRich);
+
+ switch(msg)
+ {
+ case WM_THEMECHANGED:
+ case WM_STYLECHANGED:
+ {
+ RichUtil_ClearUglyBorder(ru);
+ break;
+ }
+
+ case WM_NCPAINT:
+ {
+ LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+ if (ru->hasUglyBorder && MyIsThemeActive())
+ {
+ HANDLE hTheme = MyOpenThemeData(ru->hwnd, L"EDIT");
+
+ if (hTheme)
+ {
+ RECT rcBorder;
+ RECT rcClient;
+ int nState;
+ HDC hdc = GetWindowDC(ru->hwnd);
+
+ GetWindowRect(hwnd, &rcBorder);
+ rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top;
+ rcBorder.left = rcBorder.top = 0;
+ CopyRect(&rcClient, &rcBorder);
+ rcClient.left += ru->rect.left;
+ rcClient.top += ru->rect.top;
+ rcClient.right -= ru->rect.right;
+ rcClient.bottom -= ru->rect.bottom;
+ ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
+
+ if (MyIsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
+ MyDrawThemeParentBackground(hwnd, hdc, &rcBorder);
+
+ if (!IsWindowEnabled(hwnd))
+ nState = ETS_DISABLED;
+ else if (SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY)
+ nState = ETS_READONLY;
+ else nState = ETS_NORMAL;
+
+ MyDrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL);
+ MyCloseThemeData(hTheme);
+ ReleaseDC(hwnd, hdc);
+ return 0;
+ }
+ }
+ return ret;
+ }
+ case WM_NCCALCSIZE:
+ {
+ LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+ NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam;
+
+ if (ru->hasUglyBorder && MyIsThemeActive())
+ {
+ HANDLE hTheme = MyOpenThemeData(hwnd, L"EDIT");
+
+ if (hTheme)
+ {
+ RECT rcClient ={0};
+ HDC hdc = GetDC(GetParent(hwnd));
+
+ if (MyGetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK)
+ {
+ ru->rect.left = rcClient.left-ncsParam->rgrc[0].left;
+ ru->rect.top = rcClient.top-ncsParam->rgrc[0].top;
+ ru->rect.right = ncsParam->rgrc[0].right-rcClient.right;
+ ru->rect.bottom = ncsParam->rgrc[0].bottom-rcClient.bottom;
+ ncsParam->rgrc[0] = rcClient;
+
+ MyCloseThemeData(hTheme);
+ ReleaseDC(GetParent(hwnd), hdc);
+ return WVR_REDRAW;
+ }
+ ReleaseDC(GetParent(hwnd), hdc);
+ MyCloseThemeData(hTheme);
+ }
+ }
+ return ret;
+ }
+
+ case WM_ENABLE:
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME);
+ break;
+
+ case WM_GETDLGCODE:
+ return CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam) & ~DLGC_HASSETSEL;
+
+ case WM_NCDESTROY:
+ {
+ LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+
+ if (IsWindow(hwnd))
+ {
+ if ((WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC) == &RichUtil_Proc)
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ru->origProc);
+ }
+
+ EnterCriticalSection(&csRich);
+ List_Remove(&sListInt, idx);
+ LeaveCriticalSection(&csRich);
+
+ mir_free(ru);
+ return ret;
+ }
+ }
+ return CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+}
+
+static void RichUtil_ClearUglyBorder(TRichUtil *ru)
+{
+ if (mTheme && MyIsThemeActive() && GetWindowLongPtr(ru->hwnd, GWL_EXSTYLE) & WS_EX_STATICEDGE)
+ {
+ ru->hasUglyBorder = 1;
+ SetWindowLongPtr(ru->hwnd, GWL_EXSTYLE, GetWindowLongPtr(ru->hwnd, GWL_EXSTYLE) ^ WS_EX_STATICEDGE);
+ }
+ // Redraw window since the style may have changed
+ SetWindowPos(ru->hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ RedrawWindow(ru->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME);
+}
diff --git a/plugins/Scriver/src/richutil.h b/plugins/Scriver/src/richutil.h new file mode 100644 index 0000000000..75ecea16a3 --- /dev/null +++ b/plugins/Scriver/src/richutil.h @@ -0,0 +1,52 @@ +/*
+SRMM
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef SRMM_RICHUTIL_H
+#define SRMM_RICHUTIL_H
+
+#define RWinVerMajor() LOBYTE(LOWORD(GetVersion()))
+#define RIsWinVerXPPlus() (RWinVerMajor()>=5 && LOWORD(GetVersion())!=5)
+
+typedef struct {
+ HWND hwnd;
+ RECT rect;
+ int hasUglyBorder;
+ WNDPROC origProc;
+} TRichUtil;
+
+void RichUtil_Load();
+void RichUtil_Unload();
+int RichUtil_SubClass(HWND hwndEdit);
+
+extern HMODULE mTheme;
+extern BOOL (WINAPI *MyIsAppThemed)(VOID);
+extern BOOL (WINAPI *MyIsThemeActive)();
+extern BOOL (WINAPI *MyIsThemeBackgroundPartiallyTransparent)(HANDLE,int,int);
+extern HANDLE (WINAPI *MyOpenThemeData)(HWND,LPCWSTR);
+extern HRESULT (WINAPI *MyCloseThemeData)(HANDLE);
+extern HRESULT (WINAPI *MyDrawThemeBackground)(HANDLE,HDC,int,int,const RECT*,const RECT *);
+extern HRESULT (WINAPI *MyGetThemeBackgroundContentRect)(HANDLE,HDC,int,int,const RECT *,RECT *);
+extern HRESULT (WINAPI *MyDrawThemeParentBackground)(HWND,HDC,RECT*);
+extern HRESULT (WINAPI *MyDrawThemeText)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, const RECT *);
+extern HRESULT (WINAPI *MyEnableThemeDialogTexture)(HWND, DWORD);
+
+#endif
diff --git a/plugins/Scriver/src/sendqueue.cpp b/plugins/Scriver/src/sendqueue.cpp new file mode 100644 index 0000000000..1a85d67d4f --- /dev/null +++ b/plugins/Scriver/src/sendqueue.cpp @@ -0,0 +1,222 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+
+static MessageSendQueueItem *global_sendQueue = NULL;
+static CRITICAL_SECTION queueMutex;
+static char *MsgServiceName(HANDLE hContact)
+{
+
+ char szServiceName[100];
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto == NULL)
+ return PSS_MESSAGE;
+
+ mir_snprintf(szServiceName, sizeof(szServiceName), "%s%sW", szProto, PSS_MESSAGE);
+ if (ServiceExists(szServiceName))
+ return PSS_MESSAGE "W";
+
+ return PSS_MESSAGE;
+}
+
+TCHAR * GetSendBufferMsg(MessageSendQueueItem *item) {
+ TCHAR *szMsg = NULL;
+ size_t len = strlen(item->sendBuffer);
+
+ if (item->flags & PREF_UTF) {
+ szMsg = mir_utf8decodeW(item->sendBuffer);
+ } else {
+ szMsg = (TCHAR *)mir_alloc(item->sendBufferSize - len - 1);
+ memcpy(szMsg, item->sendBuffer + len + 1, item->sendBufferSize - len - 1);
+ }
+
+ return szMsg;
+}
+
+void InitSendQueue() {
+ InitializeCriticalSection(&queueMutex);
+}
+
+void DestroySendQueue() {
+ DeleteCriticalSection(&queueMutex);
+}
+
+MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender) {
+ MessageSendQueueItem *item = (MessageSendQueueItem *) mir_alloc(sizeof(MessageSendQueueItem));
+ EnterCriticalSection(&queueMutex);
+ ZeroMemory(item, sizeof(MessageSendQueueItem));
+ item->hwndSender = hwndSender;
+ item->next = global_sendQueue;
+ if (global_sendQueue != NULL) {
+ global_sendQueue->prev = item;
+ }
+ global_sendQueue = item;
+ LeaveCriticalSection(&queueMutex);
+ return item;
+}
+
+MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, HANDLE hContact) {
+ MessageSendQueueItem *item, *found = NULL;
+ EnterCriticalSection(&queueMutex);
+ for (item = global_sendQueue; item != NULL; item = item->next) {
+ if (item->hwndSender == hwndSender && item->hContact == hContact && item->hwndErrorDlg == NULL) {
+ found = item;
+ }
+ }
+ LeaveCriticalSection(&queueMutex);
+ return found;
+}
+
+MessageSendQueueItem* FindSendQueueItem(HANDLE hContact, HANDLE hSendId) {
+ MessageSendQueueItem *item;
+ EnterCriticalSection(&queueMutex);
+ for (item = global_sendQueue; item != NULL; item = item->next) {
+ if (item->hContact == hContact && item->hSendId == hSendId) {
+ break;
+ }
+ }
+ LeaveCriticalSection(&queueMutex);
+ return item;
+}
+
+BOOL RemoveSendQueueItem(MessageSendQueueItem* item) {
+ BOOL result = TRUE;
+ HWND hwndSender = item->hwndSender;
+// logInfo(" removing [%s] next: [%s] prev: [%s]", item->sendBuffer, item->next != NULL ? item->next->sendBuffer : "", item->prev != NULL ? item->prev->sendBuffer : "");
+ EnterCriticalSection(&queueMutex);
+ if (item->prev != NULL) {
+ item->prev->next = item->next;
+ } else {
+ global_sendQueue = item->next;
+ }
+ if (item->next != NULL) {
+ item->next->prev = item->prev;
+ }
+ if (item->sendBuffer) {
+ mir_free(item->sendBuffer);
+ }
+ if (item->proto) {
+ mir_free(item->proto);
+ }
+ mir_free(item);
+ for (item = global_sendQueue; item != NULL; item = item->next) {
+ if (item->hwndSender == hwndSender) {
+ result = FALSE;
+ }
+ }
+ LeaveCriticalSection(&queueMutex);
+ return result;
+}
+
+void ReportSendQueueTimeouts(HWND hwndSender) {
+ MessageSendQueueItem *item, *item2;
+ int timeout = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT);
+ EnterCriticalSection(&queueMutex);
+ for (item = global_sendQueue; item != NULL; item = item2) {
+ item2 = item->next;
+// logInfo(" item in the queue [%s] next: [%s] prev: [%s]", item->sendBuffer, item->next != NULL ? item->next->sendBuffer : "", item->prev != NULL ? item->prev->sendBuffer : "");
+ if (item->timeout < timeout) {
+ item->timeout += 1000;
+ if (item->timeout >= timeout) {
+ if (item->hwndSender == hwndSender && item->hwndErrorDlg == NULL) {
+ if (hwndSender != NULL) {
+ ErrorWindowData *ewd = (ErrorWindowData *) mir_alloc(sizeof(ErrorWindowData));
+ ewd->szName = GetNickname(item->hContact, item->proto);
+ ewd->szDescription = mir_tstrdup(TranslateT("The message send timed out."));
+ ewd->szText = GetSendBufferMsg(item);
+ ewd->hwndParent = hwndSender;
+ ewd->queueItem = item;
+ PostMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)ewd);
+ } else {
+ /* TODO: Handle errors outside messaging window in a better way */
+ RemoveSendQueueItem(item);
+ }
+ }
+ }
+ }
+ }
+ LeaveCriticalSection(&queueMutex);
+}
+
+void ReleaseSendQueueItems(HWND hwndSender) {
+ MessageSendQueueItem *item;
+ EnterCriticalSection(&queueMutex);
+ for (item = global_sendQueue; item != NULL; item = item->next) {
+ if (item->hwndSender == hwndSender) {
+ item->hwndSender = NULL;
+ if (item->hwndErrorDlg != NULL) {
+ DestroyWindow(item->hwndErrorDlg);
+ }
+ item->hwndErrorDlg = NULL;
+ }
+ }
+ LeaveCriticalSection(&queueMutex);
+}
+
+int ReattachSendQueueItems(HWND hwndSender, HANDLE hContact) {
+ int count = 0;
+ MessageSendQueueItem *item;
+ EnterCriticalSection(&queueMutex);
+ for (item = global_sendQueue; item != NULL; item = item->next) {
+ if (item->hContact == hContact && item->hwndSender == NULL) {
+ item->hwndSender = hwndSender;
+ item->timeout = 0;
+ count++;
+// logInfo(" reattaching [%s]", item->sendBuffer);
+ }
+ }
+ LeaveCriticalSection(&queueMutex);
+ return count;
+}
+
+
+void RemoveAllSendQueueItems() {
+ MessageSendQueueItem *item, *item2;
+ EnterCriticalSection(&queueMutex);
+ for (item = global_sendQueue; item != NULL; item = item2) {
+ item2 = item->next;
+ RemoveSendQueueItem(item);
+ }
+ LeaveCriticalSection(&queueMutex);
+}
+
+void SendSendQueueItem(MessageSendQueueItem* item) {
+ EnterCriticalSection(&queueMutex);
+ item->timeout = 0;
+// logInfo(" sending item [%s] next: [%s] prev: [%s]", item->sendBuffer, item->next != NULL ? item->next->sendBuffer : "", item->prev != NULL ? item->prev->sendBuffer : "");
+ if (item->prev != NULL) {
+ item->prev->next = item->next;
+ if (item->next != NULL) {
+ item->next->prev = item->prev;
+ }
+ item->next = global_sendQueue;
+ item->prev = NULL;
+ if (global_sendQueue != NULL) {
+ global_sendQueue->prev = item;
+ }
+ global_sendQueue = item;
+ }
+// logInfo(" item sent [%s] next: [%s] prev: [%s]", item->sendBuffer, item->next != NULL ? item->next->sendBuffer : "", item->prev != NULL ? item->prev->sendBuffer : "");
+ LeaveCriticalSection(&queueMutex);
+ item->hSendId = (HANDLE) CallContactService(item->hContact, MsgServiceName(item->hContact), item->flags, (LPARAM) item->sendBuffer);
+}
diff --git a/plugins/Scriver/src/sendqueue.h b/plugins/Scriver/src/sendqueue.h new file mode 100644 index 0000000000..e92de4293b --- /dev/null +++ b/plugins/Scriver/src/sendqueue.h @@ -0,0 +1,58 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef SRMM_SENDQUEUE_H
+#define SRMM_SENDQUEUE_H
+
+#include "msgs.h"
+
+typedef struct MessageSendQueueItemStruct
+{
+ HWND hwndSender;
+ HANDLE hContact;
+ char * proto;
+ HANDLE hSendId;
+ int timeout;
+ char * sendBuffer;
+ int sendBufferSize;
+ int codepage;
+ int flags;
+ HWND hwndErrorDlg;
+ struct MessageSendQueueItemStruct *prev;
+ struct MessageSendQueueItemStruct *next;
+}MessageSendQueueItem;
+
+void InitSendQueue();
+void DestroySendQueue();
+MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender);
+TCHAR * GetSendBufferMsg(MessageSendQueueItem *item);
+MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, HANDLE hContact);
+MessageSendQueueItem* FindSendQueueItem(HANDLE hContact, HANDLE hSendId);
+BOOL RemoveSendQueueItem(MessageSendQueueItem* item);
+void ReportSendQueueTimeouts(HWND hwndSender);
+void ReleaseSendQueueItems(HWND hwndSender);
+int ReattachSendQueueItems(HWND hwndSender, HANDLE hContact);
+void RemoveAllSendQueueItems();
+void SendSendQueueItem(MessageSendQueueItem* item);
+
+#endif
diff --git a/plugins/Scriver/src/srmm.cpp b/plugins/Scriver/src/srmm.cpp new file mode 100644 index 0000000000..8d98416ddd --- /dev/null +++ b/plugins/Scriver/src/srmm.cpp @@ -0,0 +1,83 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+
+int OnLoadModule(void);
+int OnUnloadModule(void);
+
+TIME_API tmi;
+
+
+HINSTANCE g_hInst;
+int hLangpack;
+
+ITaskbarList3 * pTaskbarInterface;
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+ "Scriver",
+ PLUGIN_MAKE_VERSION(2, 10, 0, 2),
+ "Scriver - send and receive instant messages.",
+ "Miranda IM Development Team",
+ "the_leech@users.berlios.de",
+ "Copyright (c) 2000-2012 Miranda IM Project",
+ "http://nightly.miranda.im/",
+ UNICODE_AWARE,
+ {0x84636f78, 0x2057, 0x4302, { 0x8a, 0x65, 0x23, 0xa1, 0x6d, 0x46, 0x84, 0x4c }} //{84636F78-2057-4302-8A65-23A16D46844C}
+};
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ g_hInst = hinstDLL;
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRMM, MIID_CHAT, MIID_LAST};
+
+extern "C" __declspec(dllexport) int Load(void)
+{
+
+
+ // set the memory manager
+ mir_getTMI(&tmi);
+ mir_getLP( &pluginInfo );
+
+ if (IsWinVer7Plus())
+ CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, (void**)&pTaskbarInterface);
+
+ InitSendQueue();
+ return OnLoadModule();
+}
+
+extern "C" __declspec(dllexport) int Unload(void)
+{
+ DestroySendQueue();
+ if (pTaskbarInterface)
+ pTaskbarInterface->Release();
+ return OnUnloadModule();
+}
diff --git a/plugins/Scriver/src/statusicon.cpp b/plugins/Scriver/src/statusicon.cpp new file mode 100644 index 0000000000..6b053b8adc --- /dev/null +++ b/plugins/Scriver/src/statusicon.cpp @@ -0,0 +1,258 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+#include "statusicon.h"
+
+struct StatusIconListNode {
+ StatusIconData sid;
+ struct StatusIconListNode *next;
+};
+
+HANDLE hHookIconPressedEvt;
+static struct StatusIconListNode *status_icon_list = 0;
+static int status_icon_list_size = 0;
+
+static INT_PTR AddStatusIcon(WPARAM wParam, LPARAM lParam) {
+ StatusIconData *sid = (StatusIconData *)lParam;
+ struct StatusIconListNode *siln = (struct StatusIconListNode *)mir_alloc(sizeof(struct StatusIconListNode));
+
+ siln->sid.cbSize = sid->cbSize;
+ siln->sid.szModule = mir_strdup(sid->szModule);
+ siln->sid.dwId = sid->dwId;
+ siln->sid.hIcon = sid->hIcon;
+ siln->sid.hIconDisabled = sid->hIconDisabled;
+ siln->sid.flags = sid->flags;
+ if (sid->szTooltip) siln->sid.szTooltip = mir_strdup(sid->szTooltip);
+ else siln->sid.szTooltip = 0;
+
+ siln->next = status_icon_list;
+ status_icon_list = siln;
+ status_icon_list_size++;
+
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
+ return 0;
+}
+
+INT_PTR AddStickyStatusIcon(WPARAM wParam, LPARAM lParam) {
+ StatusIconData *sid = (StatusIconData *)lParam;
+ struct StatusIconListNode *siln = (struct StatusIconListNode *)mir_alloc(sizeof(struct StatusIconListNode));
+ struct StatusIconListNode *siln2 = status_icon_list;
+
+ siln->sid.cbSize = sid->cbSize;
+ siln->sid.szModule = mir_strdup(sid->szModule);
+ siln->sid.dwId = sid->dwId;
+ siln->sid.hIcon = sid->hIcon;
+ siln->sid.hIconDisabled = sid->hIconDisabled;
+ siln->sid.flags = sid->flags;
+ if (sid->szTooltip) siln->sid.szTooltip = mir_strdup(sid->szTooltip);
+ else siln->sid.szTooltip = 0;
+ siln->next = NULL;
+
+ while(siln2 && siln2->next) {
+ siln2 = siln2->next;
+ }
+ if (siln2) {
+ siln2->next = siln;
+ } else {
+ status_icon_list = siln;
+ }
+
+ status_icon_list_size++;
+
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
+ return 0;
+}
+
+static INT_PTR RemoveStatusIcon(WPARAM wParam, LPARAM lParam) {
+ StatusIconData *sid = (StatusIconData *)lParam;
+ struct StatusIconListNode *current = status_icon_list, *prev = 0;
+
+ while(current) {
+ if (strcmp(current->sid.szModule, sid->szModule) == 0 && current->sid.dwId == sid->dwId) {
+ if (prev) prev->next = current->next;
+ else status_icon_list = current->next;
+
+ status_icon_list_size--;
+
+ mir_free(current->sid.szModule);
+ ReleaseIconSmart(current->sid.hIcon);
+ ReleaseIconSmart(current->sid.hIconDisabled);
+ mir_free(current->sid.szTooltip);
+ mir_free(current);
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
+ return 0;
+ }
+
+ prev = current;
+ current = current->next;
+ }
+
+ return 1;
+}
+
+static void RemoveAllStatusIcons(void) {
+ struct StatusIconListNode *current;
+
+ while(status_icon_list) {
+ current = status_icon_list;
+ status_icon_list = status_icon_list->next;
+ status_icon_list_size--;
+
+ mir_free(current->sid.szModule);
+ DestroyIcon(current->sid.hIcon);
+ if (current->sid.hIconDisabled) DestroyIcon(current->sid.hIconDisabled);
+ if (current->sid.szTooltip) mir_free(current->sid.szTooltip);
+ mir_free(current);
+ }
+
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
+}
+
+INT_PTR ModifyStatusIcon(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+
+ StatusIconData *sid = (StatusIconData *)lParam;
+ struct StatusIconListNode *current = status_icon_list;
+
+ while(current) {
+ if (strcmp(current->sid.szModule, sid->szModule) == 0 && current->sid.dwId == sid->dwId) {
+ if (!hContact) {
+ current->sid.flags = sid->flags;
+ if (sid->hIcon) {
+ ReleaseIconSmart(current->sid.hIcon);
+ current->sid.hIcon = sid->hIcon;
+ }
+ if (sid->hIconDisabled) {
+ ReleaseIconSmart(current->sid.hIconDisabled);
+ current->sid.hIconDisabled = sid->hIconDisabled;
+ }
+ if (sid->szTooltip) {
+ if (current->sid.szTooltip) mir_free(current->sid.szTooltip);
+ current->sid.szTooltip = mir_strdup(sid->szTooltip);
+ }
+
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
+ } else {
+ char buff[256];
+ HWND hwnd;
+ sprintf(buff, "SRMMStatusIconFlags%d", (int)sid->dwId);
+ DBWriteContactSettingByte(hContact, sid->szModule, buff, (BYTE)sid->flags);
+ hwnd = WindowList_Find(g_dat->hMessageWindowList, hContact);
+ if (hwnd == NULL) {
+ hwnd = SM_FindWindowByContact(hContact);
+ }
+ if (hwnd != NULL) {
+ PostMessage(GetParent(hwnd), DM_STATUSICONCHANGE, 0, 0);
+ }
+ }
+ return 0;
+ }
+
+ current = current->next;
+ }
+
+ return 1;
+}
+
+void DrawStatusIcons(HANDLE hContact, HDC hDC, RECT r, int gap) {
+ struct StatusIconListNode *current = status_icon_list;
+ HICON hIcon;
+ char buff[256];
+ int flags;
+ int x = r.left;
+ while(current) {
+ sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
+ flags = DBGetContactSettingByte(hContact, current->sid.szModule, buff, current->sid.flags);
+ if (!(flags & MBF_HIDDEN)) {
+ if ((flags & MBF_DISABLED) && current->sid.hIconDisabled) hIcon = current->sid.hIconDisabled;
+ else hIcon = current->sid.hIcon;
+
+ SetBkMode(hDC, TRANSPARENT);
+ DrawIconEx(hDC, x, (r.top + r.bottom - GetSystemMetrics(SM_CYSMICON)) >> 1, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL);
+
+ x += GetSystemMetrics(SM_CYSMICON) + gap;
+ }
+ current = current->next;
+ }
+}
+
+void CheckStatusIconClick(HANDLE hContact, HWND hwndFrom, POINT pt, RECT r, int gap, int click_flags) {
+ StatusIconClickData sicd;
+ struct StatusIconListNode *current = status_icon_list;
+ unsigned int iconNum = (pt.x - r.left) / (GetSystemMetrics(SM_CXSMICON) + gap) + 1;
+ int flags;
+ char buff[256];
+
+ while(current) {
+ sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
+ flags = DBGetContactSettingByte(hContact, current->sid.szModule, buff, current->sid.flags);
+ if (!(flags & MBF_HIDDEN)) iconNum--;
+ if (iconNum == 0) break;
+ current = current->next;
+ }
+
+ if (current) {
+ ClientToScreen(hwndFrom, &pt);
+ sicd.cbSize = sizeof(StatusIconClickData);
+ sicd.clickLocation = pt;
+ sicd.dwId = current->sid.dwId;
+ sicd.szModule = current->sid.szModule;
+ sicd.flags = click_flags;
+ NotifyEventHooks(hHookIconPressedEvt, (WPARAM)hContact, (LPARAM)&sicd);
+ }
+}
+
+
+HANDLE hServiceIcon[3];
+int InitStatusIcons() {
+ hServiceIcon[0] = CreateServiceFunction(MS_MSG_ADDICON, AddStatusIcon);
+ hServiceIcon[1] = CreateServiceFunction(MS_MSG_REMOVEICON, RemoveStatusIcon);
+ hServiceIcon[2] = CreateServiceFunction(MS_MSG_MODIFYICON, ModifyStatusIcon);
+ hHookIconPressedEvt = CreateHookableEvent(ME_MSG_ICONPRESSED);
+ return 0;
+}
+
+int DeinitStatusIcons() {
+ int i;
+ DestroyHookableEvent(hHookIconPressedEvt);
+ for(i = 0; i < 3; i++) DestroyServiceFunction(hServiceIcon[i]);
+ RemoveAllStatusIcons();
+ return 0;
+}
+
+INT_PTR GetStatusIconsCount(HANDLE hContact) {
+ char buff[256];
+ int count = 0;
+ int flags;
+ struct StatusIconListNode *current = status_icon_list;
+ while(current) {
+ sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
+ flags = DBGetContactSettingByte(hContact, current->sid.szModule, buff, current->sid.flags);
+ if (!(flags & MBF_HIDDEN)) {
+ count ++;
+ }
+ current = current->next;
+ }
+ return count;
+// return status_icon_list_size;
+}
diff --git a/plugins/Scriver/src/statusicon.h b/plugins/Scriver/src/statusicon.h new file mode 100644 index 0000000000..d7333129c6 --- /dev/null +++ b/plugins/Scriver/src/statusicon.h @@ -0,0 +1,36 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef _STATUS_ICON_INC
+#define _STATUS_ICON_INC
+
+#include <windows.h>
+
+int InitStatusIcons();
+int DeinitStatusIcons();
+
+INT_PTR GetStatusIconsCount(HANDLE hContact);
+void DrawStatusIcons(HANDLE hContact, HDC hdc, RECT r, int gap);
+void CheckStatusIconClick(HANDLE hContact, HWND hwndFrom, POINT pt, RECT rc, int gap, int flags);
+INT_PTR AddStickyStatusIcon(WPARAM wParam, LPARAM lParam);
+INT_PTR ModifyStatusIcon(WPARAM wParam, LPARAM lParam);
+#endif
diff --git a/plugins/Scriver/src/utils.cpp b/plugins/Scriver/src/utils.cpp new file mode 100644 index 0000000000..3551119adc --- /dev/null +++ b/plugins/Scriver/src/utils.cpp @@ -0,0 +1,652 @@ +/*
+Scriver
+
+Copyright 2000-2012 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "commonheaders.h"
+
+#ifndef TTI_NONE
+#define TTI_NONE 0
+#endif
+
+static unsigned hookNum = 0;
+static unsigned serviceNum = 0;
+static HANDLE* hHooks = NULL;
+static HANDLE* hServices = NULL;
+
+HANDLE HookEvent_Ex(const char *name, MIRANDAHOOK hook) {
+ hookNum ++;
+ hHooks = (HANDLE *) mir_realloc(hHooks, sizeof(HANDLE) * (hookNum));
+ hHooks[hookNum - 1] = HookEvent(name, hook);
+ return hHooks[hookNum - 1] ;
+}
+
+HANDLE CreateServiceFunction_Ex(const char *name, MIRANDASERVICE service) {
+ serviceNum++;
+ hServices = (HANDLE *) mir_realloc(hServices, sizeof(HANDLE) * (serviceNum));
+ hServices[serviceNum - 1] = CreateServiceFunction(name, service);
+ return hServices[serviceNum - 1] ;
+}
+
+void UnhookEvents_Ex() {
+ unsigned i;
+ for (i=0; i<hookNum ; ++i) {
+ if (hHooks[i] != NULL) {
+ UnhookEvent(hHooks[i]);
+ }
+ }
+ mir_free(hHooks);
+ hookNum = 0;
+ hHooks = NULL;
+}
+
+void DestroyServices_Ex() {
+ unsigned i;
+ for (i=0; i<serviceNum; ++i) {
+ if (hServices[i] != NULL) {
+ DestroyServiceFunction(hServices[i]);
+ }
+ }
+ mir_free(hServices);
+ serviceNum = 0;
+ hServices = NULL;
+}
+
+
+int safe_wcslen(wchar_t *msg, int maxLen) {
+ int i;
+ for (i = 0; i < maxLen; i++) {
+ if (msg[i] == (wchar_t)0)
+ return i;
+ }
+ return 0;
+}
+
+TCHAR *a2tcp(const char *text, int cp) {
+ if ( text != NULL ) {
+ int cbLen = MultiByteToWideChar( cp, 0, text, -1, NULL, 0 );
+ TCHAR* result = ( TCHAR* )mir_alloc( sizeof(TCHAR)*( cbLen+1 ));
+ if ( result == NULL )
+ return NULL;
+ MultiByteToWideChar(cp, 0, text, -1, result, cbLen);
+ return result;
+ }
+ return NULL;
+}
+
+char* u2a( const wchar_t* src, int codepage ) {
+ int cbLen = WideCharToMultiByte( codepage, 0, src, -1, NULL, 0, NULL, NULL );
+ char* result = ( char* )mir_alloc( cbLen+1 );
+ if ( result == NULL )
+ return NULL;
+
+ WideCharToMultiByte( codepage, 0, src, -1, result, cbLen, NULL, NULL );
+ result[ cbLen ] = 0;
+ return result;
+}
+
+wchar_t* a2u( const char* src, int codepage ) {
+ int cbLen = MultiByteToWideChar( codepage, 0, src, -1, NULL, 0 );
+ wchar_t* result = ( wchar_t* )mir_alloc( sizeof(wchar_t)*(cbLen+1));
+ if ( result == NULL )
+ return NULL;
+ MultiByteToWideChar( codepage, 0, src, -1, result, cbLen );
+ result[ cbLen ] = 0;
+ return result;
+}
+
+TCHAR *a2t(const char *text) {
+ if ( text == NULL )
+ return NULL;
+ return a2tcp(text, CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ));
+}
+
+char* t2a( const TCHAR* src ) {
+return u2a( src, CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ));
+}
+
+char* t2acp( const TCHAR* src, int codepage ) {
+ return u2a( src, codepage );
+}
+
+wchar_t *a2w(const char *src, int len) {
+ wchar_t *wline;
+ int i;
+ if (len <0) {
+ len = (int)strlen(src);
+ }
+ wline = (wchar_t *)mir_alloc(2 * (len + 1));
+ for (i = 0; i < len; i ++) {
+ wline[i] = src[i];
+ }
+ wline[i] = 0;
+ return wline;
+}
+
+static int mimFlags = 0;
+
+enum MIMFLAGS {
+ MIM_CHECKED = 1,
+ MIM_UNICODE = 2
+};
+
+int IsUnicodeMIM() {
+ if (!(mimFlags & MIM_CHECKED)) {
+ char str[512];
+ mimFlags = MIM_CHECKED;
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)500, (LPARAM)(char*)str);
+ if (strstr(str, "Unicode")) {
+ mimFlags |= MIM_UNICODE;
+ }
+ }
+ return (mimFlags & MIM_UNICODE) != 0;
+}
+
+const char *filename = "scriver.log";
+
+void logInfo(const char *fmt, ...) {
+ SYSTEMTIME time;
+ char *str;
+ va_list vararg;
+ int strsize;
+ FILE *flog=fopen(filename,"at");
+ if (flog!=NULL) {
+ GetLocalTime(&time);
+ va_start(vararg, fmt);
+ str = (char *) malloc(strsize=2048);
+ while (_vsnprintf(str, strsize, fmt, vararg) == -1)
+ str = (char *) realloc(str, strsize+=2048);
+ va_end(vararg);
+ fprintf(flog,"%04d-%02d-%02d %02d:%02d:%02d,%03d [%s]",time.wYear,time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond,time.wMilliseconds, "INFO");
+ fprintf(flog," %s\n",str);
+ free(str);
+ fclose(flog);
+ }
+}
+
+int GetRichTextLength(HWND hwnd, int codepage, BOOL inBytes) {
+ GETTEXTLENGTHEX gtl;
+ gtl.codepage = codepage;
+ if (inBytes) {
+ gtl.flags = GTL_NUMBYTES;
+ } else {
+ gtl.flags = GTL_NUMCHARS;
+ }
+ gtl.flags |= GTL_PRECISE | GTL_USECRLF;
+ return (int) SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0);
+}
+
+
+TCHAR *GetRichText(HWND hwnd, int codepage) {
+ GETTEXTEX gt = {0};
+ TCHAR *textBuffer = NULL;
+ int textBufferSize;
+ codepage = 1200;
+ textBufferSize = GetRichTextLength(hwnd, codepage, TRUE);
+ if (textBufferSize > 0) {
+ textBufferSize += sizeof(TCHAR);
+ textBuffer = (TCHAR *) mir_alloc(textBufferSize);
+ gt.cb = textBufferSize;
+ gt.flags = GT_USECRLF;
+ gt.codepage = codepage;
+ SendMessage(hwnd, EM_GETTEXTEX, (WPARAM) >, (LPARAM) textBuffer);
+ }
+ return textBuffer;
+}
+
+char *GetRichTextEncoded(HWND hwnd, int codepage) {
+ TCHAR *textBuffer = GetRichText(hwnd, codepage);
+ char *textUtf = NULL;
+ if (textBuffer != NULL) {
+ textUtf = mir_utf8encodeW(textBuffer);
+ mir_free(textBuffer);
+ }
+ return textUtf;
+}
+
+int SetRichTextEncoded(HWND hwnd, const char *text, int codepage) {
+ TCHAR *textToSet;
+ SETTEXTEX st;
+ st.flags = ST_DEFAULT;
+ st.codepage = 1200;
+ textToSet = mir_utf8decodeW(text);
+ SendMessage(hwnd, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)textToSet);
+ mir_free(textToSet);
+ return GetRichTextLength(hwnd, st.codepage, FALSE);
+}
+
+int SetRichTextRTF(HWND hwnd, const char *text) {
+ SETTEXTEX st;
+ st.flags = ST_DEFAULT;
+ st.codepage = CP_ACP;
+ SendMessage(hwnd, EM_SETTEXTEX, (WPARAM) &st, (LPARAM)text);
+ return GetRichTextLength(hwnd, st.codepage, FALSE);
+}
+
+static DWORD CALLBACK RichTextStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+{
+ static DWORD dwRead;
+ char ** ppText = (char **) dwCookie;
+
+ if (*ppText == NULL) {
+ *ppText = (char *)mir_alloc(cb + 1);
+ memcpy(*ppText, pbBuff, cb);
+ (*ppText)[cb] = 0;
+ *pcb = cb;
+ dwRead = cb;
+ }
+ else {
+ char *p = (char *)mir_alloc(dwRead + cb + 1);
+ memcpy(p, *ppText, dwRead);
+ memcpy(p+dwRead, pbBuff, cb);
+ p[dwRead + cb] = 0;
+ mir_free(*ppText);
+ *ppText = p;
+ *pcb = cb;
+ dwRead += cb;
+ }
+
+ return 0;
+}
+
+char* GetRichTextRTF(HWND hwnd)
+{
+ EDITSTREAM stream;
+ char* pszText = NULL;
+ DWORD dwFlags;
+
+ if (hwnd == 0)
+ return NULL;
+
+ ZeroMemory(&stream, sizeof(stream));
+ stream.pfnCallback = RichTextStreamCallback;
+ stream.dwCookie = (DWORD_PTR) &pszText; // pass pointer to pointer
+ dwFlags = SF_RTFNOOBJS | SFF_PLAINRTF | SF_USECODEPAGE | (CP_UTF8 << 16);
+ SendMessage(hwnd, EM_STREAMOUT, dwFlags, (LPARAM) & stream);
+ return pszText; // pszText contains the text
+}
+
+void rtrimText(TCHAR *text)
+{
+ static TCHAR szTrimString[] = _T(":;,.!?\'\"><()[]- \r\n");
+ int iLen = lstrlen(text)-1;
+ while(iLen >= 0 && _tcschr(szTrimString, text[iLen])) {
+ text[iLen] = _T('\0');
+ iLen--;
+ }
+}
+
+TCHAR *limitText(TCHAR *text, int limit)
+{
+ int len = lstrlen(text);
+ if (len > g_dat->limitNamesLength)
+ {
+ TCHAR *ptszTemp = (TCHAR *)mir_alloc(sizeof(TCHAR) * (limit + 4));
+ _tcsncpy(ptszTemp, text, limit + 1);
+ _tcsncpy(ptszTemp + limit, _T("..."), 4);
+ return ptszTemp;
+ }
+ return text;
+}
+TCHAR *GetRichTextWord(HWND hwnd, POINTL *ptl)
+{
+ TCHAR* pszWord = NULL;
+ long iCharIndex, start, end, iRes;
+ pszWord = GetRichEditSelection(hwnd);
+ if (pszWord == NULL) {
+ iCharIndex = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)ptl);
+ if (iCharIndex >= 0)
+ {
+ start = SendMessage(hwnd, EM_FINDWORDBREAK, WB_LEFT, iCharIndex);//-iChars;
+ end = SendMessage(hwnd, EM_FINDWORDBREAK, WB_RIGHT, iCharIndex);//-iChars;
+ if (end - start > 0)
+ {
+ TEXTRANGE tr;
+ CHARRANGE cr;
+ ZeroMemory(&tr, sizeof(TEXTRANGE));
+ pszWord = (TCHAR *)mir_alloc(sizeof(TCHAR) * (end - start + 1));
+ cr.cpMin = start;
+ cr.cpMax = end;
+ tr.chrg = cr;
+ tr.lpstrText = pszWord;
+ iRes = SendMessage(hwnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
+ if (iRes <= 0)
+ {
+ mir_free(pszWord);
+ pszWord = NULL;
+ }
+ }
+ }
+ }
+ if (pszWord != NULL)
+ {
+ rtrimText(pszWord);
+ }
+ return pszWord;
+}
+
+static DWORD CALLBACK StreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+{
+ MessageSendQueueItem * msi = (MessageSendQueueItem *) dwCookie;
+ msi->sendBuffer = (char *)mir_realloc(msi->sendBuffer, msi->sendBufferSize + cb + 2);
+ memcpy (msi->sendBuffer + msi->sendBufferSize, pbBuff, cb);
+ msi->sendBufferSize += cb;
+ *((TCHAR *)(msi->sendBuffer+msi->sendBufferSize)) = '\0';
+ *pcb = cb;
+ return 0;
+}
+
+TCHAR *GetRichEditSelection(HWND hwnd)
+{
+ CHARRANGE sel;
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);
+ if (sel.cpMin!=sel.cpMax) {
+ MessageSendQueueItem msi;
+ EDITSTREAM stream;
+ DWORD dwFlags = 0;
+ ZeroMemory(&stream, sizeof(stream));
+ stream.pfnCallback = StreamOutCallback;
+ stream.dwCookie = (DWORD_PTR) &msi;
+ dwFlags = SF_TEXT|SF_UNICODE|SFF_SELECTION;
+ msi.sendBuffer = NULL;
+ msi.sendBufferSize = 0;
+ SendMessage(hwnd, EM_STREAMOUT, (WPARAM)dwFlags, (LPARAM) & stream);
+ return (TCHAR *)msi.sendBuffer;
+ }
+ return NULL;
+}
+
+void AppendToBuffer(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, const char *fmt, ...)
+{
+ va_list va;
+ int charsDone;
+
+ va_start(va, fmt);
+ for (;;) {
+ charsDone = _vsnprintf(*buffer + *cbBufferEnd, *cbBufferAlloced - *cbBufferEnd, fmt, va);
+ if (charsDone >= 0)
+ break;
+ *cbBufferAlloced += 1024;
+ *buffer = (char *) mir_realloc(*buffer, *cbBufferAlloced);
+ }
+ va_end(va);
+ *cbBufferEnd += charsDone;
+}
+
+
+int MeasureMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ LPMEASUREITEMSTRUCT mis = (LPMEASUREITEMSTRUCT) lParam;
+ if (mis->itemData != (ULONG_PTR) g_dat->hButtonIconList && mis->itemData != (ULONG_PTR) g_dat->hSearchEngineIconList && mis->itemData != (ULONG_PTR) g_dat->hChatButtonIconList) {
+ return FALSE;
+ }
+ mis->itemWidth = max(0, GetSystemMetrics(SM_CXSMICON) - GetSystemMetrics(SM_CXMENUCHECK) + 4);
+ mis->itemHeight = GetSystemMetrics(SM_CYSMICON) + 2;
+ return TRUE;
+}
+
+int DrawMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ int y;
+ int id;
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+ if (dis->itemData != (ULONG_PTR) g_dat->hButtonIconList && dis->itemData != (ULONG_PTR) g_dat->hSearchEngineIconList && dis->itemData != (ULONG_PTR) g_dat->hChatButtonIconList) {
+ return FALSE;
+ }
+ id = dis->itemID;
+ if (id >= IDM_SEARCH_GOOGLE) {
+ id -= IDM_SEARCH_GOOGLE;
+ }
+ y = (dis->rcItem.bottom - dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2 + 1;
+ if (dis->itemState & ODS_SELECTED) {
+ if (dis->itemState & ODS_CHECKED) {
+ RECT rc;
+ rc.left = 2;
+ rc.right = GetSystemMetrics(SM_CXSMICON) + 2;
+ rc.top = y;
+ rc.bottom = rc.top + GetSystemMetrics(SM_CYSMICON) + 2;
+ FillRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ ImageList_DrawEx((HIMAGELIST)dis->itemData, id, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_DEFAULT, ILD_SELECTED);
+ } else
+ ImageList_DrawEx((HIMAGELIST)dis->itemData, id, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_DEFAULT, ILD_FOCUS);
+ } else {
+ if (dis->itemState & ODS_CHECKED) {
+ HBRUSH hBrush;
+ RECT rc;
+ COLORREF menuCol, hiliteCol;
+ rc.left = 0;
+ rc.right = GetSystemMetrics(SM_CXSMICON) + 4;
+ rc.top = y - 2;
+ rc.bottom = rc.top + GetSystemMetrics(SM_CYSMICON) + 4;
+ DrawEdge(dis->hDC, &rc, BDR_SUNKENOUTER, BF_RECT);
+ InflateRect(&rc, -1, -1);
+ menuCol = GetSysColor(COLOR_MENU);
+ hiliteCol = GetSysColor(COLOR_3DHIGHLIGHT);
+ hBrush = CreateSolidBrush(RGB
+ ((GetRValue(menuCol) + GetRValue(hiliteCol)) / 2, (GetGValue(menuCol) + GetGValue(hiliteCol)) / 2,
+ (GetBValue(menuCol) + GetBValue(hiliteCol)) / 2));
+ FillRect(dis->hDC, &rc, hBrush);
+ DeleteObject(hBrush);
+ ImageList_DrawEx((HIMAGELIST)dis->itemData, id, dis->hDC, 2, y, 0, 0, CLR_NONE, GetSysColor(COLOR_MENU), ILD_BLEND25);
+ } else
+ ImageList_DrawEx((HIMAGELIST)dis->itemData, id, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ }
+ return TRUE;
+}
+
+// Code taken from http://www.geekhideout.com/urlcode.shtml
+
+/* Converts an integer value to its hex character*/
+char to_hex(char code) {
+ static char hex[] = "0123456789abcdef";
+ return hex[code & 15];
+}
+
+/* Returns a url-encoded version of str */
+/* IMPORTANT: be sure to free() the returned string after use */
+char *url_encode(char *str) {
+ char *pstr = str, *buf = (char *)mir_alloc(strlen(str) * 3 + 1), *pbuf = buf;
+ while (*pstr) {
+ if ( (48 <= *pstr && *pstr <= 57) ||//0-9
+ (65 <= *pstr && *pstr <= 90) ||//ABC...XYZ
+ (97 <= *pstr && *pstr <= 122) ||//abc...xyz
+ *pstr == '-' || *pstr == '_' || *pstr == '.')
+ *pbuf++ = *pstr;
+ else if (*pstr == ' ')
+ *pbuf++ = '+';
+ else
+ *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+ pstr++;
+ }
+ *pbuf = '\0';
+ return buf;
+}
+
+void SearchWord(TCHAR * word, int engine)
+{
+ char szURL[4096];
+ if (word && word[0]) {
+ char *wordUTF = mir_utf8encodeT(word);
+ //char *wordURL = (char *)CallService(MS_NETLIB_URLENCODE, 0, (LPARAM)wordUTF);
+ char *wordURL = url_encode(wordUTF);
+ switch (engine) {
+ case SEARCHENGINE_WIKIPEDIA:
+ mir_snprintf( szURL, sizeof( szURL ), "http://en.wikipedia.org/wiki/%s", wordURL );
+ break;
+ case SEARCHENGINE_YAHOO:
+ mir_snprintf( szURL, sizeof( szURL ), "http://search.yahoo.com/search?p=%s&ei=UTF-8", wordURL );
+ break;
+ case SEARCHENGINE_FOODNETWORK:
+ mir_snprintf( szURL, sizeof( szURL ), "http://search.foodnetwork.com/search/delegate.do?fnSearchString=%s", wordURL );
+ break;
+ case SEARCHENGINE_BING:
+ mir_snprintf( szURL, sizeof( szURL ), "http://www.bing.com/search?q=%s&form=OSDSRC", wordURL );
+ break;
+ case SEARCHENGINE_GOOGLE_MAPS:
+ mir_snprintf( szURL, sizeof( szURL ), "http://maps.google.com/maps?q=%s&ie=utf-8&oe=utf-8", wordURL );
+ break;
+ case SEARCHENGINE_GOOGLE_TRANSLATE:
+ mir_snprintf( szURL, sizeof( szURL ), "http://translate.google.com/?q=%s&ie=utf-8&oe=utf-8", wordURL );
+ break;
+ case SEARCHENGINE_GOOGLE:
+ default:
+ mir_snprintf( szURL, sizeof( szURL ), "http://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", wordURL );
+ break;
+ }
+// HeapFree(GetProcessHeap(), 0, wordURL);
+ mir_free(wordUTF);
+ mir_free(wordURL);
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) szURL);
+ }
+}
+
+void SetSearchEngineIcons(HMENU hMenu, HIMAGELIST hImageList) {
+ int i;
+ for (i=0; i<IDI_FOODNETWORK - IDI_GOOGLE + 1; i++) {
+ MENUITEMINFO minfo = {0};
+ minfo.cbSize = sizeof(minfo);
+// minfo.fMask = MIIM_FTYPE | MIIM_ID;
+// GetMenuItemInfo(hMenu, IDM_SEARCH_GOOGLE + i, FALSE, &minfo);
+ minfo.fMask = MIIM_BITMAP | MIIM_DATA;
+ minfo.hbmpItem = HBMMENU_CALLBACK;
+ //minfo.fType = MFT_STRING;
+ //minfo.wID = IDM_SEARCH_GOOGLE + i;
+ minfo.dwItemData = (ULONG_PTR) hImageList;
+ SetMenuItemInfo(hMenu, IDM_SEARCH_GOOGLE + i, FALSE, &minfo);
+ }
+}
+
+void GetContactUniqueId(struct SrmmWindowData *dat, char *buf, int maxlen) {
+ CONTACTINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = dat->windowData.hContact;
+ ci.szProto = dat->szProto;
+ ci.dwFlag = CNF_UNIQUEID;
+ buf[0] = 0;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_snprintf(buf, maxlen, "%s", ci.pszVal);
+ mir_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(buf, maxlen, "%u", ci.dVal);
+ break;
+ }
+ }
+}
+
+HWND CreateToolTip(HWND hwndParent, LPTSTR ptszText, LPTSTR ptszTitle, RECT* rect)
+{
+ TOOLINFO ti = { 0 };
+ HWND hwndTT;
+ hwndTT = CreateWindowEx(WS_EX_TOPMOST,
+ TOOLTIPS_CLASS, NULL,
+ WS_POPUP | TTS_NOPREFIX,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ hwndParent, NULL, g_hInst, NULL);
+
+ SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS | TTF_CENTERTIP;
+ ti.hwnd = hwndParent;
+ ti.hinst = g_hInst;
+ ti.lpszText = ptszText;
+ ti.rect = *rect;
+ SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ SendMessage(hwndTT, TTM_SETTITLE, TTI_NONE, (LPARAM)ptszTitle);
+ return hwndTT;
+}
+
+void SetToolTipText(HWND hwndParent, HWND hwndTT, LPTSTR ptszText, LPTSTR ptszTitle) {
+ TOOLINFO ti = { 0 };
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.hinst = g_hInst;
+ ti.hwnd = hwndParent;
+ ti.lpszText = ptszText;
+ SendMessage(hwndTT, TTM_UPDATETIPTEXT, 0, (LPARAM) (LPTOOLINFO) &ti);
+ SendMessage(hwndTT, TTM_SETTITLE, TTI_NONE, (LPARAM)ptszTitle);
+}
+
+void SetToolTipRect(HWND hwndParent, HWND hwndTT, RECT* rect)
+{
+ TOOLINFO ti = { 0 };
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.hinst = g_hInst;
+ ti.hwnd = hwndParent;
+ ti.rect = *rect;
+ SendMessage(hwndTT, TTM_NEWTOOLRECT, 0, (LPARAM) (LPTOOLINFO) &ti);
+}
+
+/* toolbar-related stuff, to be moved to a separate file */
+
+HDWP ResizeToolbar(HWND hwnd, HDWP hdwp, int width, int vPos, int height, int cControls, const ToolbarButton * buttons, int controlVisibility)
+{
+ int i;
+ int lPos = 0;
+ int rPos = width;
+ for (i = 0; i < cControls ; i++) {
+ if (!buttons[i].alignment && (controlVisibility & (1 << i))) {
+ lPos += buttons[i].spacing;
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, buttons[i].controlId), 0, lPos, vPos, buttons[i].width, height, SWP_NOZORDER);
+ lPos += buttons[i].width;
+ }
+ }
+ for (i = cControls - 1; i >=0; i--) {
+ if (buttons[i].alignment && (controlVisibility & (1 << i))) {
+ rPos -= buttons[i].spacing + buttons[i].width;
+ hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, buttons[i].controlId), 0, rPos, vPos, buttons[i].width, height, SWP_NOZORDER);
+ }
+ }
+ return hdwp;
+}
+
+void ShowToolbarControls(HWND hwndDlg, int cControls, const ToolbarButton* buttons, int controlVisibility, int state)
+{
+ int i;
+ for (i = 0; i < cControls; i++)
+ ShowWindow(GetDlgItem(hwndDlg, buttons[i].controlId), (controlVisibility & (1 << i)) ? state : SW_HIDE);
+}
+
+int GetToolbarWidth(int cControls, const ToolbarButton * buttons)
+{
+ int i, w = 0;
+ for (i = 0; i < cControls; i++) {
+// if (g_dat->buttonVisibility & (1 << i)) {
+ if (buttons[i].controlId != IDC_SMILEYS || g_dat->smileyAddInstalled) {
+ w += buttons[i].width + buttons[i].spacing;
+ }
+// }
+ }
+ return w;
+}
+
+BOOL IsToolbarVisible(int cControls, int visibilityFlags)
+{
+ int i;
+ for (i = 0; i < cControls; i++) {
+ if (visibilityFlags & (1 << i)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/plugins/Scriver/src/utils.h b/plugins/Scriver/src/utils.h new file mode 100644 index 0000000000..0d3b3ab4e1 --- /dev/null +++ b/plugins/Scriver/src/utils.h @@ -0,0 +1,72 @@ +/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef UTILS_H
+#define UTILS_H
+
+enum SEARCHENGINES {
+ SEARCHENGINE_GOOGLE = 1,
+ SEARCHENGINE_BING = 2,
+ SEARCHENGINE_WIKIPEDIA = 3,
+ SEARCHENGINE_GOOGLE_MAPS = 4,
+ SEARCHENGINE_GOOGLE_TRANSLATE = 5,
+ SEARCHENGINE_YAHOO = 6,
+ SEARCHENGINE_FOODNETWORK=7
+};
+
+HANDLE HookEvent_Ex(const char *name, MIRANDAHOOK hook);
+HANDLE CreateServiceFunction_Ex(const char *name, MIRANDASERVICE service);
+extern void UnhookEvents_Ex();
+extern void DestroyServices_Ex();
+extern int IsUnicodeMIM();
+extern int safe_wcslen(wchar_t *msg, int maxLen) ;
+extern TCHAR *a2t(const char *text);
+extern TCHAR *a2tcp(const char *text, int cp);
+extern char* t2a(const TCHAR* src);
+extern char* t2acp(const TCHAR* src, int cp);
+extern char* u2a( const wchar_t* src, int codepage );
+extern wchar_t* a2u( const char* src, int codepage );
+extern wchar_t *a2w(const char *src, int len);
+extern TCHAR *limitText(TCHAR *text, int limit);
+extern void logInfo(const char *fmt, ...);
+extern int GetRichTextLength(HWND hwnd, int codepage, BOOL inBytes);
+extern TCHAR* GetRichText(HWND hwnd, int codepage);
+extern TCHAR *GetRichEditSelection(HWND hwnd);
+extern char* GetRichTextRTF(HWND hwnd);
+extern char* GetRichTextEncoded(HWND hwnd, int codepage);
+extern TCHAR *GetRichTextWord(HWND hwnd, POINTL *pt);
+extern int SetRichTextRTF(HWND hwnd, const char *text);
+extern int SetRichTextEncoded(HWND hwnd, const char *text, int codepage);
+extern void SearchWord(TCHAR * word, int engine);
+extern HDWP ResizeToolbar(HWND hwnd, HDWP hdwp, int width, int vPos, int height, int cControls, const ToolbarButton * buttons, int controlVisibility);
+extern void ShowToolbarControls(HWND hwndDlg, int cControls, const ToolbarButton * buttons, int controlVisibility, int state);
+extern void AppendToBuffer(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, const char *fmt, ...);
+extern int MeasureMenuItem(WPARAM wParam, LPARAM lParam);
+extern int DrawMenuItem(WPARAM wParam, LPARAM lParam);
+extern void SetSearchEngineIcons(HMENU hMenu, HIMAGELIST hImageList);
+extern void GetContactUniqueId(struct SrmmWindowData *dat, char *buf, int maxlen);
+HWND CreateToolTip(HWND hwndParent, LPTSTR ptszText, LPTSTR ptszTitle, RECT *rect);
+void SetToolTipText(HWND hwndParent, HWND hwndTT, LPTSTR ptszText, LPTSTR ptszTitle);
+void SetToolTipRect(HWND hwndParent, HWND hwndTT, RECT* rect);
+int GetToolbarWidth(int cControls, const ToolbarButton * buttons);
+BOOL IsToolbarVisible(int cControls, int visibilityFlags);
+#endif
|