From f9eb107520e9dad37b06eb5c737b39d7bc15c751 Mon Sep 17 00:00:00 2001 From: Alexey Kulakov Date: Wed, 27 Jun 2012 17:22:43 +0000 Subject: Added File As Message plugin git-svn-id: http://svn.miranda-ng.org/main/trunk@655 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/FileAsMessage/IcoLib.h | 12 + plugins/FileAsMessage/base64.c | 93 ++ plugins/FileAsMessage/crc32.cpp | 29 + plugins/FileAsMessage/dialog.cpp | 1366 ++++++++++++++++++++++++++++ plugins/FileAsMessage/dialog.h | 120 +++ plugins/FileAsMessage/fileecho.dsp | 148 +++ plugins/FileAsMessage/fileecho.dsw | 29 + plugins/FileAsMessage/fileecho.opt | Bin 0 -> 54784 bytes plugins/FileAsMessage/fileecho.vcproj | 236 +++++ plugins/FileAsMessage/m_Snapping_windows.h | 42 + plugins/FileAsMessage/main.cpp | 359 ++++++++ plugins/FileAsMessage/main.h | 59 ++ plugins/FileAsMessage/main.rc | 30 + plugins/FileAsMessage/optionsdlg.cpp | 118 +++ plugins/FileAsMessage/res/abort.ico | Bin 0 -> 2550 bytes plugins/FileAsMessage/res/file.ico | Bin 0 -> 2550 bytes plugins/FileAsMessage/res/pause.ico | Bin 0 -> 2550 bytes plugins/FileAsMessage/res/play.ico | Bin 0 -> 2550 bytes plugins/FileAsMessage/res/refresh.ico | Bin 0 -> 2550 bytes plugins/FileAsMessage/resource.h | 45 + plugins/FileAsMessage/resources.rc | 156 ++++ 21 files changed, 2842 insertions(+) create mode 100644 plugins/FileAsMessage/IcoLib.h create mode 100644 plugins/FileAsMessage/base64.c create mode 100644 plugins/FileAsMessage/crc32.cpp create mode 100644 plugins/FileAsMessage/dialog.cpp create mode 100644 plugins/FileAsMessage/dialog.h create mode 100644 plugins/FileAsMessage/fileecho.dsp create mode 100644 plugins/FileAsMessage/fileecho.dsw create mode 100644 plugins/FileAsMessage/fileecho.opt create mode 100644 plugins/FileAsMessage/fileecho.vcproj create mode 100644 plugins/FileAsMessage/m_Snapping_windows.h create mode 100644 plugins/FileAsMessage/main.cpp create mode 100644 plugins/FileAsMessage/main.h create mode 100644 plugins/FileAsMessage/main.rc create mode 100644 plugins/FileAsMessage/optionsdlg.cpp create mode 100644 plugins/FileAsMessage/res/abort.ico create mode 100644 plugins/FileAsMessage/res/file.ico create mode 100644 plugins/FileAsMessage/res/pause.ico create mode 100644 plugins/FileAsMessage/res/play.ico create mode 100644 plugins/FileAsMessage/res/refresh.ico create mode 100644 plugins/FileAsMessage/resource.h create mode 100644 plugins/FileAsMessage/resources.rc (limited to 'plugins/FileAsMessage') diff --git a/plugins/FileAsMessage/IcoLib.h b/plugins/FileAsMessage/IcoLib.h new file mode 100644 index 0000000000..77e8625c61 --- /dev/null +++ b/plugins/FileAsMessage/IcoLib.h @@ -0,0 +1,12 @@ +typedef struct { + int cbSize; + char *pszSection; //section name used to group icons + char *pszDescription; //description for options dialog + char *pszName; //name to refer to icon when playing and in db + char *pszDefaultFile; //default icon file to use + int iDefaultIndex; +} SKINICONDESC; + +#define MS_SKIN2_ADDICON "Skin2/Icons/AddIcon" +#define MS_SKIN2_GETICON "Skin2/Icons/GetIcon" +#define ME_SKIN2_ICONSCHANGED "Skin2/IconsChanged" diff --git a/plugins/FileAsMessage/base64.c b/plugins/FileAsMessage/base64.c new file mode 100644 index 0000000000..220cd85027 --- /dev/null +++ b/plugins/FileAsMessage/base64.c @@ -0,0 +1,93 @@ +#define XNetlib_GetBase64DecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3) +#define XNetlib_GetBase64EncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1) + +static char base64chars[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int XNetlibBase64Encode(WPARAM wParam,LPARAM lParam) +{ + NETLIBBASE64 *nlb64=(NETLIBBASE64*)lParam; + int iIn; + char *pszOut; + PBYTE pbIn; + + if(nlb64==NULL || nlb64->pszEncoded==NULL || nlb64->pbDecoded==NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + if(nlb64->cchEncodedcbDecoded)) { + SetLastError(ERROR_BUFFER_OVERFLOW); + return 0; + } + nlb64->cchEncoded=XNetlib_GetBase64EncodedBufferSize(nlb64->cbDecoded); + for(iIn=0,pbIn=nlb64->pbDecoded,pszOut=nlb64->pszEncoded;iIncbDecoded;iIn+=3,pbIn+=3,pszOut+=4) { + pszOut[0]=base64chars[pbIn[0]>>2]; + if(nlb64->cbDecoded-iIn==1) { + pszOut[1]=base64chars[(pbIn[0]&3)<<4]; + pszOut[2]='='; + pszOut[3]='='; + pszOut+=4; + break; + } + pszOut[1]=base64chars[((pbIn[0]&3)<<4)|(pbIn[1]>>4)]; + if(nlb64->cbDecoded-iIn==2) { + pszOut[2]=base64chars[(pbIn[1]&0xF)<<2]; + pszOut[3]='='; + pszOut+=4; + break; + } + pszOut[2]=base64chars[((pbIn[1]&0xF)<<2)|(pbIn[2]>>6)]; + pszOut[3]=base64chars[pbIn[2]&0x3F]; + } + pszOut[0]='\0'; + return 1; +} + +BYTE Base64CharToInt(char c) +{ + if(c>='A' && c<='Z') return c-'A'; + if(c>='a' && c<='z') return c-'a'+26; + if(c>='0' && c<='9') return c-'0'+52; + if(c=='+') return 62; + if(c=='/') return 63; + if(c=='=') return 64; + return 255; +} + +int XNetlibBase64Decode(WPARAM wParam,LPARAM lParam) +{ + NETLIBBASE64 *nlb64=(NETLIBBASE64*)lParam; + char *pszIn; + PBYTE pbOut; + BYTE b1,b2,b3,b4; + int iIn; + + if(nlb64==NULL || nlb64->pszEncoded==NULL || nlb64->pbDecoded==NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + if(nlb64->cchEncoded&3) { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + if(nlb64->cbDecodedcchEncoded)) { + SetLastError(ERROR_BUFFER_OVERFLOW); + return 0; + } + nlb64->cbDecoded=XNetlib_GetBase64DecodedBufferSize(nlb64->cchEncoded); + for(iIn=0,pszIn=nlb64->pszEncoded,pbOut=nlb64->pbDecoded;iIncchEncoded;iIn+=4,pszIn+=4,pbOut+=3) { + b1=Base64CharToInt(pszIn[0]); + b2=Base64CharToInt(pszIn[1]); + b3=Base64CharToInt(pszIn[2]); + b4=Base64CharToInt(pszIn[3]); + if(b1==255 || b1==64 || b2==255 || b2==64 || b3==255 || b4==255) { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + pbOut[0]=(b1<<2)|(b2>>4); + if(b3==64) {nlb64->cbDecoded-=2; break;} + pbOut[1]=(b2<<4)|(b3>>2); + if(b4==64) {nlb64->cbDecoded--; break;} + pbOut[2]=b4|(b3<<6); + } + return 1; +} diff --git a/plugins/FileAsMessage/crc32.cpp b/plugins/FileAsMessage/crc32.cpp new file mode 100644 index 0000000000..e75eb6446e --- /dev/null +++ b/plugins/FileAsMessage/crc32.cpp @@ -0,0 +1,29 @@ +const ulong CRCPoly = 0xEDB88320; +ulong CRC32Table[256]; + +void InitCRC32() +{ + for (UINT32 i = 0; i < 256; i++) + { + UINT32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ CRCPoly; + else + r >>= 1; + CRC32Table[i] = r; + } +} + +const ulong INITCRC = -1L; + +inline ulong UpdateCRC32(uchar val, ulong crc) +{ + return CRC32Table[(uchar)crc^val] ^ (crc>>8); +} + +ulong memcrc32(uchar *ptr, int size, ulong crc ) +{ + while(size--) crc = UpdateCRC32(*ptr++, crc); + return crc; +} diff --git a/plugins/FileAsMessage/dialog.cpp b/plugins/FileAsMessage/dialog.cpp new file mode 100644 index 0000000000..eb76e24c15 --- /dev/null +++ b/plugins/FileAsMessage/dialog.cpp @@ -0,0 +1,1366 @@ +#include"main.h" +#include"dialog.h" +#include"resource.h" + +#include "m_Snapping_windows.h" + +#include"crc32.cpp" + +char *szFEMode[] = +{ + "Recv file", + "Send file" +}; + +#define USE_BUILDIN_BASE64 +// +// BASE64 encoding/decoding +// +#define Base64_GetDecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3) +#define Base64_GetEncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1) +#ifdef USE_BUILDIN_BASE64 +#define Base64_Encode(nlb64) CallService(MS_NETLIB_BASE64ENCODE, 0, (LPARAM)nlb64) +#define Base64_Decode(nlb64) CallService(MS_NETLIB_BASE64DECODE, 0, (LPARAM)nlb64) +#else + +static char base64chars[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#define Base64_Encode(nlb64) NetlibBase64Encode(0, (LPARAM)nlb64) +#define Base64_Decode(nlb64) NetlibBase64Decode(0, (LPARAM)nlb64) + +int NetlibBase64Encode(WPARAM wParam,LPARAM lParam) +{ + NETLIBBASE64 *nlb64=(NETLIBBASE64*)lParam; + int iIn; + char *pszOut; + PBYTE pbIn; + + if(nlb64==NULL || nlb64->pszEncoded==NULL || nlb64->pbDecoded==NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + if(nlb64->cchEncodedcbDecoded)) { + SetLastError(ERROR_BUFFER_OVERFLOW); + return 0; + } + nlb64->cchEncoded=Netlib_GetBase64EncodedBufferSize(nlb64->cbDecoded); + for(iIn=0,pbIn=nlb64->pbDecoded,pszOut=nlb64->pszEncoded;iIncbDecoded;iIn+=3,pbIn+=3,pszOut+=4) { + pszOut[0]=base64chars[pbIn[0]>>2]; + if(nlb64->cbDecoded-iIn==1) { + pszOut[1]=base64chars[(pbIn[0]&3)<<4]; + pszOut[2]='='; + pszOut[3]='='; + pszOut+=4; + break; + } + pszOut[1]=base64chars[((pbIn[0]&3)<<4)|(pbIn[1]>>4)]; + if(nlb64->cbDecoded-iIn==2) { + pszOut[2]=base64chars[(pbIn[1]&0xF)<<2]; + pszOut[3]='='; + pszOut+=4; + break; + } + pszOut[2]=base64chars[((pbIn[1]&0xF)<<2)|(pbIn[2]>>6)]; + pszOut[3]=base64chars[pbIn[2]&0x3F]; + } + pszOut[0]='\0'; + return 1; +} + +static BYTE Base64CharToInt(char c) +{ + if(c>='A' && c<='Z') return c-'A'; + if(c>='a' && c<='z') return c-'a'+26; + if(c>='0' && c<='9') return c-'0'+52; + if(c=='+') return 62; + if(c=='/') return 63; + if(c=='=') return 64; + return 255; +} + +int NetlibBase64Decode(WPARAM wParam,LPARAM lParam) +{ + NETLIBBASE64 *nlb64=(NETLIBBASE64*)lParam; + char *pszIn; + PBYTE pbOut; + BYTE b1,b2,b3,b4; + int iIn; + + if(nlb64==NULL || nlb64->pszEncoded==NULL || nlb64->pbDecoded==NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + if(nlb64->cchEncoded&3) { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + if(nlb64->cbDecodedcchEncoded)) { + SetLastError(ERROR_BUFFER_OVERFLOW); + return 0; + } + nlb64->cbDecoded=Netlib_GetBase64DecodedBufferSize(nlb64->cchEncoded); + for(iIn=0,pszIn=nlb64->pszEncoded,pbOut=nlb64->pbDecoded;iIncchEncoded;iIn+=4,pszIn+=4,pbOut+=3) { + b1=Base64CharToInt(pszIn[0]); + b2=Base64CharToInt(pszIn[1]); + b3=Base64CharToInt(pszIn[2]); + b4=Base64CharToInt(pszIn[3]); + if(b1==255 || b1==64 || b2==255 || b2==64 || b3==255 || b4==255) { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + pbOut[0]=(b1<<2)|(b2>>4); + if(b3==64) {nlb64->cbDecoded-=2; break;} + pbOut[1]=(b2<<4)|(b3>>2); + if(b4==64) {nlb64->cbDecoded--; break;} + pbOut[2]=b4|(b3<<6); + } + return 1; +} +#endif + +char* ltoax(char* s, DWORD value) +{ + if(value == 0) + { + *s++ = '0'; + } + uchar data; + int indx = 8; + while(indx && !(data = (uchar)(value >> 28) & 0x0F)) + { + value <<= 4; + indx--; + } + while(indx) + { + data = (uchar)(value >> 28) & 0x0F; + if(data > 9) data += 'A' - 10; + else data += '0'; + *s++ = data; + value <<= 4; + indx--; + } + return s; +} +uint atolx(char* &value) +{ + uint result = 0; + uchar ch; + + while( *value && (ch = *value - '0') >= 0 ) + { + if(ch > 9) + { + ch -= 'A' - '0'; + if(ch > 5) break; + ch += 10; + } + result = result * 16 + ch; + value++; + } + return result; +} + +char cCmdList[CMD_COUNT] = +{ + '?', + '+', + '-', + + '*', + + '>', + '!', + '.' +}; + +static int CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = PUGetContact(hWnd); + HWND hDlg = (HWND)PUGetPluginData(hWnd); +/* + if(hContact) + { + CLISTEVENT *lpcle; + int indx = 0; + for(;;) + { + if((lpcle = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, (WPARAM)hContact, indx)) == NULL) + break; + if(lstrcmp(lpcle->pszService, SERVICE_NAME "/FERecvFile") == 0) + { + lpcle->lParam = (LPARAM)hWnd; + break; + } + indx++; + } + } +*/ + switch(message) { + case WM_COMMAND: + { + PUDeletePopUp(hWnd); + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)0); + + if(IsWindow(hDlg)) + { + ShowWindow(hDlg, SW_SHOWNORMAL); + SetForegroundWindow(hDlg); + SetFocus(hDlg); + } + + break; + } + case WM_CONTEXTMENU: + PUDeletePopUp(hWnd); + break; + case UM_FREEPLUGINDATA: + return TRUE; //TRUE or FALSE is the same, it gets ignored. + default: + break; + } + return DefWindowProc(hWnd, message, wParam, lParam); +} +// +// Just create simple Popup for specified contact +// +void MakePopupMsg(HWND hDlg, HANDLE hContact, char *msg) +{ + HWND hFocused = GetForegroundWindow(); + if(hDlg == hFocused || hDlg == GetParent(hFocused)) return; + + POPUPDATAEX ppd; + // + //The text for the second line. You could even make something like: char lpzText[128]; lstrcpy(lpzText, "Hello world!"); It's your choice. + // + ZeroMemory(&ppd, sizeof(ppd)); //This is always a good thing to do. + ppd.lchContact = (HANDLE)hContact; //Be sure to use a GOOD handle, since this will not be checked. + ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SMALLICON)); + lstrcpy(ppd.lpzContactName, (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0)); + lstrcpy(ppd.lpzText, msg); + ppd.colorBack = GetSysColor(COLOR_INFOBK); + ppd.colorText = GetSysColor(COLOR_INFOTEXT); + ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; + ppd.PluginData = (void*)hDlg; + ppd.iSeconds = -1; + + CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); +} +// +// Get ID of string message +// +int getMsgId(char *msg) +{ + for(int indx = 0; indx < CMD_COUNT; indx++) + { + if(*msg == cCmdList[indx]) return indx; + } + return -1; +}; + +int RetrieveFileSize(char *filename) +{ + int handle = open(filename, O_RDONLY|O_BINARY,0); + if(handle != -1) + { + int size = filelength(handle); + close(handle); + return size; + } + return handle; +} + +FILEECHO::FILEECHO(HANDLE Contact) +{ + hContact = Contact; + dwSendInterval = DBGetContactSettingDword(NULL, SERVICE_NAME, "SendDelay", 6000); + //dwChunkSize = DBGetContactSettingDword(NULL, SERVICE_NAME, "ChunkSize", 5000); + + chunkMaxLen = DBGetContactSettingDword(NULL, SERVICE_NAME, "ChunkSize", 5000); + chunkCount = 0; + filename = NULL; + + rgbRecv = DBGetContactSettingDword(NULL, SERVICE_NAME, "colorRecv", RGB(64,255,64)); + rgbSent = DBGetContactSettingDword(NULL, SERVICE_NAME, "colorSent", RGB(255,255,64)); + rgbUnSent = DBGetContactSettingDword(NULL, SERVICE_NAME, "colorUnsent", RGB(128,128,128)); + rgbToSend = DBGetContactSettingDword(NULL, SERVICE_NAME, "colorTosend", RGB(192,192,192)); + asBinary = DBGetContactSettingDword(NULL, SERVICE_NAME, "base64", 1) == 0; +} + +uint controlEnabled[][2] = +{ + IDC_PLAY, + STATE_OPERATE|STATE_PAUSED|STATE_PRERECV|STATE_ACKREQ|STATE_IDLE, + IDC_STOP, + STATE_OPERATE|STATE_PAUSED|STATE_PRERECV|STATE_REQSENT|STATE_ACKREQ, +// IDC_FILENAME, +// STATE_IDLE|STATE_PRERECV|STATE_FINISHED|STATE_CANCELLED, +// IDC_BROWSE, +// STATE_IDLE|STATE_PRERECV|STATE_FINISHED|STATE_CANCELLED, +}; +/* +char *stateMsg[][2] = +{ + (char*)STATE_IDLE,"Idle", + (char*)STATE_REQSENT,"ReqSent", + (char*)STATE_PRERECV,"PreRecv", + (char*)STATE_OPERATE,"Operate", + (char*)STATE_ACKREQ,"AckReq", + (char*)STATE_CANCELLED,"Cancelled", + (char*)STATE_FINISHED,"Finished", + (char*)STATE_PAUSED,"Paused" +}; +*/ + +char *hint_controls[4] = { + "Perform", + "Pause", + "Revive a transfer", + "Stop" +}; + +void FILEECHO::setState(DWORD state) +{ + iState = state; + int indx; + + for(indx = 0; indx < ARRAY_SIZE(controlEnabled); indx++) + { + EnableWindow(GetDlgItem(hDlg, controlEnabled[indx][0]), (iState & controlEnabled[indx][1]) != 0); + } + + if(!inSend) // recv + { + int kind; + SendDlgItemMessage(hDlg, IDC_FILENAME, EM_SETREADONLY, (state != STATE_PRERECV), 0); + EnableWindow(GetDlgItem(hDlg, IDC_BROWSE), (iState & (STATE_PRERECV|STATE_FINISHED))); + //SendDlgItemMessage(hDlg, IDC_FILENAME, EM_SETREADONLY, (iState & STATE_PRERECV) == 0, 0); + //EnableWindow(GetDlgItem(hDlg, IDC_FILENAME), (iState == STATE_PRERECV)); + //EnableWindow(GetDlgItem(hDlg, IDC_FILENAME), (iState & STATE_IDLE|STATE_PRERECV|STATE_FINISHED|STATE_CANCELLED) != 0); + if(state & (STATE_IDLE|STATE_FINISHED|STATE_CANCELLED|STATE_PRERECV)) + kind = ICON_PLAY; + else + kind = ICON_REFRESH; + SendDlgItemMessage(hDlg, IDC_PLAY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[kind]); + SendDlgItemMessage(hDlg, IDC_PLAY, BUTTONADDTOOLTIP,(WPARAM)Translate(hint_controls[kind]),0); + } + else + { + SendDlgItemMessage(hDlg, IDC_FILENAME, EM_SETREADONLY, (iState & (STATE_IDLE|STATE_FINISHED|STATE_CANCELLED)) == 0, 0); + EnableWindow(GetDlgItem(hDlg, IDC_BROWSE), (iState & (STATE_IDLE|STATE_FINISHED|STATE_CANCELLED)) != 0); + //EnableWindow(GetDlgItem(hDlg, IDC_FILENAME), (iState & STATE_IDLE|STATE_PRERECV|STATE_FINISHED|STATE_CANCELLED) != 0); + switch(state) + { + case STATE_FINISHED: + case STATE_CANCELLED: + case STATE_IDLE: + case STATE_PAUSED: + EnableWindow(GetDlgItem(hDlg, IDC_PLAY), TRUE); + SendDlgItemMessage(hDlg, IDC_PLAY, BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[ICON_PLAY]); + SendDlgItemMessage(hDlg, IDC_PLAY, BUTTONADDTOOLTIP,(WPARAM)Translate(hint_controls[ICON_PLAY]),0); + break; + case STATE_OPERATE: + SendDlgItemMessage(hDlg, IDC_PLAY, BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[ICON_PAUSE]); + SendDlgItemMessage(hDlg, IDC_PLAY, BUTTONADDTOOLTIP,(WPARAM)Translate(hint_controls[ICON_PAUSE]),0); + break; + } + } + updateProgress(); +} + +void FILEECHO::updateTitle() +{ + char newtitle[256], *contactName; + + contactName=(char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); + if(iState == STATE_OPERATE && chunkCount != 0) + _snprintf(newtitle,sizeof(newtitle),"%d%% - %s: %s",chunkSent * 100 / chunkCount, Translate(szFEMode[inSend]), contactName); + else + _snprintf(newtitle,sizeof(newtitle),"%s: %s",Translate(szFEMode[inSend]), contactName); + SetWindowText(hDlg, newtitle); +} + +void BuildFreqTable(uchar *data, uint len, uint *freqTable) +{ + ZeroMemory(freqTable, 256*sizeof(uint)); + for(uint indx = 0; indx < len; indx++) + freqTable[data[indx]]++; +} + +int FILEECHO::createTransfer() +{ + uint LastError; + hFile = INVALID_HANDLE_VALUE; + hMapping = NULL; + lpData = NULL; +#ifdef DEBUG + overhead = 0; +#endif + hFile = CreateFile(filename, inSend?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), inSend?FILE_SHARE_READ:0, + NULL, inSend?OPEN_EXISTING:(DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0)?CREATE_ALWAYS:CREATE_NEW), FILE_ATTRIBUTE_NORMAL, NULL); + if(hFile == INVALID_HANDLE_VALUE && !inSend && GetLastError() == ERROR_FILE_EXISTS) + { + if(MessageBox(hDlg, Translate("File already exists. Overwrite?"), + Translate(SERVICE_TITLE), + MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) != IDYES) return 0; + hFile = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + } + if(hFile == INVALID_HANDLE_VALUE) goto createTransfer_FAILED; + if(!inSend) + { + SetFilePointer(hFile, fileSize, NULL, FILE_CURRENT); + SetEndOfFile(hFile); + } + else + fileSize = GetFileSize(hFile, NULL); + hMapping = CreateFileMapping(hFile, NULL, inSend?PAGE_READONLY:PAGE_READWRITE, + 0, fileSize, NULL); + LastError = GetLastError(); + if(hMapping == NULL) goto createTransfer_FAILED; + lpData = (uchar*)MapViewOfFile(hMapping, inSend?FILE_MAP_READ:FILE_MAP_WRITE, 0,0,0); + LastError = GetLastError(); + if(lpData == NULL) goto createTransfer_FAILED; + + if(inSend) + // + // frequency analysis of source file + // and building the table of offsets + // + { + if(asBinary) + { + uint freq_table[256]; + uchar *data; + uint len, chunk_offset, chunk_size, out_size; + int chunk_count_limit; + + codeSymb = 1; + // + // searching for symbol with lowest frequency: "codeSymb" + // + BuildFreqTable(lpData, fileSize, freq_table); + for(int indx = codeSymb+1; indx < 256; indx++) + { + if(freq_table[codeSymb] > freq_table[indx]) codeSymb = indx; + } + //DEBUG + //codeSymb = ':'; + + // + // calculating chunks sizes + // build table of chunks offsets: chunkPos + // + chunk_count_limit = 2*fileSize/chunkMaxLen+2; + chunkPos = (uint*)malloc(sizeof(uint)*chunk_count_limit); + data = lpData; + chunk_size = 0; out_size = 0; indx = 0; chunk_offset = 0; + for(len = fileSize; len; len--) + { + if(*data == 0 || *data == codeSymb) + out_size += 2; + else + out_size++; + + data++; chunk_size++; + if(out_size >= chunkMaxLen-1) + { + chunkPos[indx] = chunk_offset; chunk_offset += chunk_size; + chunk_size = 0; out_size = 0; + indx++; + } + } + chunkPos[indx++] = chunk_offset; chunkCount = indx; + chunkPos = (uint*)realloc(chunkPos, sizeof(uint)*(chunkCount+1)); + chunkPos[indx] = chunk_offset + chunk_size; + } + else + { + int EncodedMaxLen = Base64_GetEncodedBufferSize(Base64_GetDecodedBufferSize(chunkMaxLen)); + int DecodedMaxLen = Base64_GetDecodedBufferSize(EncodedMaxLen); + + codeSymb = '-'; + chunkCount = (fileSize + DecodedMaxLen - 1) / DecodedMaxLen; + chunkPos = (uint*)malloc(sizeof(uint)*(chunkCount+1)); + for(uint chunk_offset = 0, indx = 0; indx < chunkCount; indx++, chunk_offset += DecodedMaxLen) + chunkPos[indx] = chunk_offset; + chunkPos[indx] = chunkPos[indx-1] + fileSize%DecodedMaxLen; + } + } + else + chunkCount = chunkCountx; + chunkAck = (uchar*)malloc(sizeof(uchar)*chunkCount); + memset(chunkAck, 0, sizeof(uchar)*chunkCount); + + chunkIndx = 0; chunkSent = 0; + + return 1; +createTransfer_FAILED: + if(lpData != NULL) UnmapViewOfFile(lpData); + if(hMapping != NULL) CloseHandle(hMapping); + if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); + return 0; +} + +void FILEECHO::destroyTransfer() +{ + if(chunkCount) + { + chunkCount = 0; + if(inSend) + free(chunkPos); + free(chunkAck); + if(lpData != NULL) UnmapViewOfFile(lpData); + if(hMapping != NULL) CloseHandle(hMapping); + if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); + } + //setState(STATE_IDLE); + return; +} + +void FILEECHO::sendReq() +{ + + char sendbuf[MAX_PATH]; + + if(!createTransfer()) + { + SetDlgItemText(hDlg, IDC_FILESIZE, Translate("Couldn't open a file")); + return; + } + ///!!!!!!! + char *p = filename + strlen(filename); + while(p != filename && *p != '\\') + p--; + if(*p == '\\') + strcpy(filename,p+1); + + _snprintf(sendbuf, sizeof(sendbuf), Translate("Size: %d bytes"), fileSize); + SetDlgItemText(hDlg, IDC_FILESIZE, sendbuf); + _snprintf(sendbuf, sizeof(sendbuf), "?%c%c%d:%d " NOPLUGIN_MESSAGE, asBinary+'0', codeSymb, chunkCount, fileSize); + sendCmd(0, CMD_REQ, sendbuf, filename); + + SetDlgItemText(hDlg, IDC_STATUS, Translate("Request sent. Awaiting of acceptance..")); + setState(STATE_REQSENT); +} +void FILEECHO::incomeRequest(char *param) +{ + // param: filename?cCOUNT:SIZE + char buf[MAX_PATH]; + // param == &filename + char *p = strchr(param, '?'); + if(p == NULL) return; *p++ = 0; + CallService(MS_FILE_GETRECEIVEDFILESFOLDER, (WPARAM)hContact, (LPARAM)buf); + strncat(buf, param, sizeof(buf)); + if(filename) free(filename); + filename = strdup(buf); + // p == &c + if(*p == 0) return; asBinary = (*p++) != '0'; + if(*p == 0) return; codeSymb = *p++; + // p == &COUNT + if(*p == 0) return; param = strchr(p, ':'); + // param == &SIZE + if(param == NULL) return; *param++ = 0; + if(*param == 0) return; + chunkCountx = atoi(p); + fileSize = atoi(param); + + _snprintf(buf, sizeof(buf), Translate("Size: %d bytes"), fileSize); + SetDlgItemText(hDlg, IDC_FILENAME, filename); + SetDlgItemText(hDlg, IDC_FILESIZE, buf); + + setState(STATE_PRERECV); + inSend = FALSE; + + SkinPlaySound("RecvFile"); + int AutoMin = DBGetContactSettingByte(NULL,"SRFile","AutoMin",0); + if(DBGetContactSettingByte(NULL,"SRFile","AutoAccept",0) && !DBGetContactSettingByte((HANDLE)hContact,"CList","NotOnList",0)) + { + PostMessage(hDlg, WM_COMMAND, IDC_PLAY, 0); + if(AutoMin) + ShowWindow(hDlg, SW_SHOWMINIMIZED); +// ShowWindow(hDlg, SW_MINIMIZE); +// UpdateWindow(hDlg); + } +// else + if(!IsWindowVisible(hDlg) && !AutoMin) + { + CLISTEVENT cle; + ZeroMemory(&cle, sizeof(cle)); + cle.cbSize = sizeof(cle); + cle.hContact = hContact; + cle.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SMALLICON)); + cle.flags = CLEF_URGENT; + cle.hDbEvent = 0; + cle.pszService = SERVICE_NAME "/FERecvFile"; + CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); + + MakePopupMsg(hDlg, hContact, "Incoming file..."); + } +} + +void FILEECHO::cmdACCEPT() +{ + if(chunkCount == 0) return; + setState(STATE_OPERATE); + SetDlgItemText(hDlg, IDC_STATUS, Translate("Sending...")); + lastTimestamp = GetTickCount(); + //PostMessage(hDlg, WM_TIMER, 0,0); + //onSendTimer(); + SetTimer(hDlg, TIMER_SEND, dwSendInterval, 0); +} + +void FILEECHO::updateProgress() +{ + InvalidateRect(GetDlgItem(hDlg, IDC_PROGRESS), NULL, TRUE); + updateTitle(); +} +// +// called in receive mode +// used to transfer acknowledge +// +void FILEECHO::onRecvTimer() +{ + if(chunkCount == 0) return; + char *buffer = (char*)malloc(1024); + char *p = buffer; + uchar prev_value; + uint indx, jndx; + + KillTimer(hDlg, TIMER_SEND); + // + // Build response about successfully received chunks + // + indx = jndx = 0; prev_value = chunkAck[jndx]; + while(jndx < chunkCount) + { + if(chunkAck[jndx] != prev_value) + { + if(prev_value != CHUNK_ACK) + { + p = ltoax(p, indx); + if(indx != jndx-1) + { + *p++ = '-'; + p = ltoax(p, jndx-1); + } + *p++ = ','; + } + indx = jndx; + prev_value = chunkAck[jndx]; + } + jndx++; + } + if(prev_value != CHUNK_ACK) + { + p = ltoax(p, indx); + if(indx != jndx-1) + { + *p++ = '-'; + p = ltoax(p, jndx-1); + } + } + *p = 0; + if(*buffer == 0) + { + char *msg = Translate("Received successfully"); + SetDlgItemText(hDlg, IDC_STATUS, msg); + MakePopupMsg(hDlg, hContact, msg); + setState(STATE_FINISHED); + if(DBGetContactSettingByte(NULL,"SRFile","AutoClose",0)) + { + PostMessage(hDlg, WM_CLOSE, 0,0); + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)0); + } + SkinPlaySound("FileDone"); + destroyTransfer(); + buffer[0] = 'x'; buffer[1] = 0; + } + sendCmd(0, CMD_DACK, buffer); + free(buffer); + //if(iState != STATE_FINISHED) SetTimer(hDlg, TIMER_SEND, lastDelay*2, 0); +} +// +// called in sending mode +// used to data transfer and +// sending of scheduled commands +// +void FILEECHO::onSendTimer() +{ + if(chunkCount == 0) return; + // + // perform request of acknowledge, if scheduled + // + KillTimer(hDlg, TIMER_SEND); + // + // Search for next unsent chunk + // + while(chunkIndx < chunkCount && chunkAck[chunkIndx] != CHUNK_UNSENT) chunkIndx++; + if(iState == STATE_ACKREQ || chunkIndx == chunkCount) + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Requesting of missing chunks")); + setState(STATE_OPERATE); + sendCmd(0, CMD_END, "", NULL); + chunkIndx = chunkCount+1; + return; + } + if(chunkIndx > chunkCount) return; + + uchar *buffer = (uchar*)malloc(chunkMaxLen*2); + uchar *p = buffer; + uchar *data = lpData + chunkPos[chunkIndx]; + uchar *data_end = lpData + chunkPos[chunkIndx+1]; + ulong chksum = memcrc32(data, data_end - data, INITCRC); + + if(asBinary) + { + // + // Encoding data to transfer with symb. filtering + // + while(data < data_end) + { + uchar ch = *data++; + if(ch == 0) + { + *p++ = codeSymb; *p++ = '0'; + } + else if (ch == codeSymb) + { + *p++ = codeSymb; *p++ = '+'; + } + else + *p++ = ch; + } + *p = 0; + } + else + { + NETLIBBASE64 nlb; + + nlb.pbDecoded = data; + nlb.cbDecoded = data_end - data; + nlb.pszEncoded = (char*)buffer; + nlb.cchEncoded = chunkMaxLen*2; + + Base64_Encode(&nlb); + } + + char prefix[128]; + _snprintf(prefix, sizeof(prefix), "%X,%X,%X>", chunkIndx+1, chunkPos[chunkIndx], chksum); +#ifdef DEBUG + overhead += lstrlen((char*)buffer); +#endif + sendCmd(0, CMD_DATA, (char*)buffer, (char*)prefix); + chunkAck[chunkIndx] = CHUNK_SENT; + + free(buffer); + + chunkIndx++; chunkSent++; + + if(chunkIndx == chunkCount) + setState(STATE_ACKREQ); + else + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Sending...")); + updateProgress(); + } + SetTimer(hDlg, TIMER_SEND, dwSendInterval, 0); +} +void FILEECHO::cmdDATA(char *param) +{ + if(chunkCount == 0) return; + chunkIndx = atolx(param); param++; + if(chunkIndx-- == 0) return; + uint filepos = atolx(param); param++; + if(filepos >= fileSize) return; + + ulong chksum_local; + ulong chksum_remote = atolx(param); param++; + + KillTimer(hDlg, TIMER_SEND); + + // + // Decoding of incoming data + // + uchar *data = lpData + filepos; + uchar *data_end = lpData + fileSize; + if(asBinary) + { + uchar ch; + while(ch = *param++) + { + if(ch == codeSymb) + { + if((ch = *param++) == 0) goto cmdDATA_corrupted; + switch(ch) + { + case '+': + ch = codeSymb; + break; + case '0': + ch = 0; + break; + default: + goto cmdDATA_corrupted; + } + } + if(data > data_end) goto cmdDATA_corrupted; + *data++ = ch; + } + } + else + { + NETLIBBASE64 nlb; + uchar *temp_buffer; + + nlb.pszEncoded = param; + nlb.cchEncoded = strlen(param); + temp_buffer = (uchar*)malloc(nlb.cchEncoded); + nlb.pbDecoded = temp_buffer; + nlb.cbDecoded = nlb.cchEncoded; + + Base64_Decode(&nlb); + memcpy(data, temp_buffer, min(nlb.cbDecoded, data_end - data)); + data += nlb.cbDecoded; + } + // + // let's check it up + // + chksum_local = memcrc32(lpData + filepos, data - (lpData + filepos), INITCRC); + if(chksum_local == chksum_remote) + { + if(chunkAck[chunkIndx] != CHUNK_ACK) chunkSent++; + chunkAck[chunkIndx] = CHUNK_ACK; + //chunkPos[chunkIndx++] = filepos; + } + SetDlgItemText(hDlg, IDC_STATUS, Translate("Receiving...")); + updateProgress(); +cmdDATA_corrupted: + //SetTimer(hDlg, TIMER_SEND, lastDelay*2, 0); + ; +} +void FILEECHO::cmdEND() +{ + SetTimer(hDlg, TIMER_SEND, dwSendInterval, 0); +} +void FILEECHO::cmdDACK(char *param) +{ + uint indx, jndx; + + if(chunkCount == 0) return; + memset(chunkAck, CHUNK_ACK, sizeof(uchar)*chunkCount); + if(*param == 'x') + // + // All chunks has been received successfully + // + { +#ifdef DEBUG + char msg[100]; + + _snprintf(msg, sizeof(msg), "overhead: %d", overhead); + SetDlgItemText(hDlg, IDC_STATUS, msg); +#else + char *msg = Translate("Sent successfully"); + SetDlgItemText(hDlg, IDC_STATUS, msg); +#endif + SkinPlaySound("FileDone"); + destroyTransfer(); + MakePopupMsg(hDlg, hContact, msg); + setState(STATE_FINISHED); + return; + } + chunkSent = chunkCount; + // + // Mark chunks to re-transfer, + // according received info + // + // format: chunk1, chunk3-chunk10, etc.. + // + while(*param) + { + indx = atolx(param); + if(*param == '-') + { + param++; jndx = atolx(param); + } + else + jndx = indx; + if(*param == 0 || *param == ',') + { + for(uint p = indx; p <= jndx; p++) + { + if(p < chunkCount) + { + chunkAck[p] = CHUNK_UNSENT; + chunkSent--; + } + } + if(*param == ',') + param++; + } + } + updateProgress(); + + // + // retransfer some parts + // + chunkIndx = 0; + SetTimer(hDlg, TIMER_SEND, dwSendInterval, 0); +} + +void FILEECHO::perform(char *str) +{ + int msgId = getMsgId(str); + if(msgId == -1) + { + MakePopupMsg(hDlg, hContact, Translate("Unknown command for \"" SERVICE_TITLE "\" was received")); + return; + } + if(inSend) + switch(msgId) + { + case CMD_REQ: + if(MessageBox(hDlg, Translate("Incoming file request. Do you want proceed?"), + Translate(SERVICE_TITLE), MB_YESNO | MB_ICONWARNING) == IDYES) + { + SetDlgItemText(hDlg, IDC_STATUS, ""); + SendMessage(hDlg, WM_COMMAND, IDC_STOP, 0); + + incomeRequest(str+1); + updateTitle(); + break; + } + break; + case CMD_ACCEPT: + cmdACCEPT(); + break; + case CMD_CANCEL: + { + if(iState & (STATE_PRERECV|STATE_REQSENT|STATE_OPERATE|STATE_ACKREQ|STATE_PAUSED)) + { + char *msg = Translate("Cancelled by remote user"); + SetDlgItemText(hDlg, IDC_STATUS, msg); + MakePopupMsg(hDlg, hContact, msg); + destroyTransfer(); + setState(STATE_CANCELLED); + } + break; + } + case CMD_DACK: + cmdDACK(str+1); + break; + } + else + switch(msgId) + { + case CMD_CANCEL: + { + if(iState & (STATE_PRERECV|STATE_REQSENT|STATE_OPERATE|STATE_ACKREQ|STATE_PAUSED)) + { + char *msg = Translate("Cancelled by remote user"); + SetDlgItemText(hDlg, IDC_STATUS, msg); + MakePopupMsg(hDlg, hContact, msg); + destroyTransfer(); + setState(STATE_CANCELLED); + } + break; + } + case CMD_REQ: + if(chunkCount) + { + if(MessageBox(hDlg, Translate("New incoming file request. Do you want proceed?"), + Translate(SERVICE_TITLE), MB_YESNO | MB_ICONWARNING) != IDYES) + break; + //sendCmd(0, CMD_CANCEL, "", NULL); + destroyTransfer(); + } + SetDlgItemText(hDlg, IDC_STATUS, ""); + incomeRequest(str+1); + break; + case CMD_DATA: + cmdDATA(str+1); + break; + case CMD_END: + cmdEND(); + break; + }; +}; + +int FILEECHO::sendCmd(int id, int cmd, char *szParam, char *szPrefix) +{ + char *buf; + int retval; + int buflen = strlen(szServicePrefix) + strlen(szParam) + 2; + if(szPrefix != NULL) + buflen += strlen(szPrefix); + + buf = (char*)malloc(buflen); + if(szPrefix == NULL) + _snprintf(buf,buflen,"%s%c%s", szServicePrefix, cCmdList[cmd], szParam); + else + _snprintf(buf,buflen,"%s%c%s%s", szServicePrefix, cCmdList[cmd], szPrefix, szParam); + retval = CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)buf); + free(buf); + updateProgress(); + return retval; +} + + +void CreateDirectoryTree(char *szDir) +{ + DWORD dwAttributes; + char *pszLastBackslash,szTestDir[MAX_PATH]; + + lstrcpyn(szTestDir,szDir,sizeof(szTestDir)); + if((dwAttributes=GetFileAttributes(szTestDir))!=0xffffffff + && dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return; + pszLastBackslash=strrchr(szTestDir,'\\'); + if(pszLastBackslash==NULL) {GetCurrentDirectory(MAX_PATH,szDir); return;} + *pszLastBackslash='\0'; + CreateDirectoryTree(szTestDir); + CreateDirectory(szTestDir,NULL); +} + +void SubclassWnd(HWND hwnd, WNDPROC lpfnWndProc) +{ + SetWindowLong(hwnd, GWL_USERDATA, (LONG)GetWindowLong(hwnd, GWL_WNDPROC)); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG)lpfnWndProc); +} +#define CallSubclassed(hwnd, uMsg, wParam, lParam)\ + CallWindowProc((WNDPROC)GetWindowLong(hwnd, GWL_USERDATA), hwnd, uMsg, wParam, lParam) + +LRESULT CALLBACK ProgressWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_NCPAINT: + return 0; + case WM_PAINT: + { + HDC hdc; + PAINTSTRUCT ps; + RECT rc; + HRGN hrgn; + HBRUSH frameBrush = (HBRUSH)GetStockObject(BLACK_BRUSH); + struct FILEECHO *dat; + + dat = (struct FILEECHO*)GetWindowLong(GetParent(hwnd), GWL_USERDATA); + //if(dat == NULL) + // return CallSubclassed(hwnd, uMsg, wParam, lParam); + GetClientRect(hwnd, &rc); + if(dat == NULL || dat->chunkCount == 0) + { + COLORREF colour; + HBRUSH hbr; + + if(dat == NULL || dat->iState != STATE_FINISHED) + { + hbr = (HBRUSH)(COLOR_3DFACE+1); + } + else + { + colour = dat->rgbRecv; + hbr = CreateSolidBrush(colour); + } + hdc=BeginPaint(hwnd,&ps); + FillRect(hdc, &rc, hbr); + FrameRect(hdc, &rc, frameBrush); + if(hbr != (HBRUSH)(COLOR_3DFACE+1)) + DeleteObject(hbr); + EndPaint(hwnd,&ps); + return 0; + } + + hrgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); + + hdc=BeginPaint(hwnd,&ps); + SelectClipRgn(hdc, hrgn); + + RECT rc2 = rc; + //uint sliceWidth = (rc.right - rc.left) / dat->chunkCount; + float sliceWidth = (float)((float)(rc.right - rc.left) / (float)dat->chunkCount); + float dx = (float)rc2.left; + for(uint indx = 0; indx < dat->chunkCount; indx++) + { + HBRUSH hbr; + COLORREF colour; + if(dat->inSend && indx == dat->chunkIndx) + colour = dat->rgbToSend; + else + switch(dat->chunkAck[indx]) + { + case CHUNK_UNSENT: + colour = dat->rgbUnSent; + break; + case CHUNK_SENT: + colour = dat->rgbSent; + break; + case CHUNK_ACK: + colour = dat->rgbRecv; + break; + } + /* + if(indx == 5) colour = RGB(255,64,64); + else if(indx < 2) colour = RGB(64,255,64); + else if(indx < 4) colour = RGB(255,255,64); + else colour = RGB(128,128,128); + //*/ + if(indx == dat->chunkCount-1) + rc2.right = rc.right; + hbr = CreateSolidBrush(colour); + rc2.left = (int)dx; + rc2.right = (int)(dx + sliceWidth); + FillRect(hdc, &rc2, hbr); + FrameRect(hdc, &rc2, frameBrush); + DeleteObject(hbr); + dx += sliceWidth-1; + } + if(rc2.right < rc.right) + { + rc2.left = rc2.right; + rc2.right = rc.right; + FillRect(hdc, &rc2, (HBRUSH)(COLOR_3DFACE+1)); + } + //FrameRect(hdc, &rc, (HBRUSH)(COLOR_3DLIGHT+1)); + //OffsetRect(&rc, 1,1); + //FrameRect(hdc, &rc, (HBRUSH)(COLOR_BTNTEXT+1)); + //FrameRect(hdc, &rc, (HBRUSH)(COLOR_BTNTEXT+1)); + EndPaint(hwnd,&ps); + + DeleteObject(hrgn); + + return 0; + } + } + return CallSubclassed(hwnd, uMsg, wParam, lParam); +} + +LRESULT CALLBACK DialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + struct FILEECHO *dat; + + dat = (struct FILEECHO*)GetWindowLong(hDlg, GWL_USERDATA); + CallSnappingWindowProc(hDlg,uMsg,wParam,lParam); + switch( uMsg ) + { + case WM_INITDIALOG: + { + dat = (FILEECHO*)lParam; + dat->hDlg = hDlg; + + dat->updateTitle(); + + CreateStatusWindow(WS_CHILD|WS_VISIBLE, "", hDlg, IDC_STATUS); + SetWindowLong(hDlg, GWL_USERDATA, (LONG)dat); + WindowList_Add(hFileList, hDlg, dat->hContact); + SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcons[ICON_MAIN]); + SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcons[ICON_MAIN]); + SendDlgItemMessage(hDlg, IDC_STOP, BUTTONADDTOOLTIP,(WPARAM)Translate(hint_controls[ICON_STOP]),0); + + //SetDlgItemText(hDlg, IDC_FILENAME, "C:\\!Developer\\!Miranda\\miranda\\bin\\release\\emo\\biggrin.gif"); + + SubclassWnd(GetDlgItem(hDlg, IDC_PROGRESS), ProgressWndProc); + + SendDlgItemMessage(hDlg, IDC_PLAY, BUTTONSETASFLATBTN,0,0); + SendDlgItemMessage(hDlg, IDC_PLAY, BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[ICON_PLAY]); + SendDlgItemMessage(hDlg, IDC_STOP, BUTTONSETASFLATBTN,0,0); + SendDlgItemMessage(hDlg, IDC_STOP, BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[ICON_STOP]); + dat->setState(STATE_IDLE); + + //ShowWindow(hDlg, SW_HIDE); + //UpdateWindow(hDlg); + + if(dat->inSend) + PostMessage(hDlg, WM_COMMAND, IDC_BROWSE, NULL); + + return FALSE; + } + case WM_FE_MESSAGE: + { + dat->perform((char *)lParam); + delete (char *)lParam; + + return TRUE; + } + case WM_FE_SKINCHANGE: + SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcons[ICON_MAIN]); + SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcons[ICON_MAIN]); + dat->setState(dat->iState); + SendDlgItemMessage(hDlg, IDC_STOP, BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[ICON_STOP]); + + break; + case WM_FE_STATUSCHANGE: + { + char *szProto; + szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0); + if (szProto) + { + int dwStatus; + dwStatus = DBGetContactSettingWord(dat->hContact,szProto,"Status",ID_STATUS_OFFLINE); + if(dat->inSend && dwStatus != dat->contactStatus) + { + if(dat->contactStatus == ID_STATUS_OFFLINE) + { + dat->chunkIndx = dat->chunkCount; + } + else + if(dwStatus == ID_STATUS_OFFLINE) + { + if(dat->iState & (STATE_OPERATE|STATE_ACKREQ)) + { + char *msg = Translate("Paused, 'coz connection dropped"); + SetDlgItemText(hDlg, IDC_STATUS, msg); + MakePopupMsg(dat->hDlg, dat->hContact, msg); + dat->setState(STATE_PAUSED); + KillTimer(hDlg, TIMER_SEND); + } + } + } + dat->contactStatus = dwStatus; + } + return TRUE; + } + case WM_DESTROY: + WindowList_Remove(hFileList, hDlg); + delete dat; + + return TRUE; + + case WM_TIMER: + if(dat->inSend) + dat->onSendTimer(); + else + dat->onRecvTimer(); + break; + case WM_COMMAND: + switch(wParam) + { + case IDC_PLAY: + { + if(dat->iState & (STATE_IDLE|STATE_FINISHED|STATE_CANCELLED|STATE_PRERECV)) + { + int len = GetWindowTextLength(GetDlgItem(hDlg, IDC_FILENAME))+1; + if(dat->filename) free(dat->filename); + dat->filename = (char*)malloc(len); + GetDlgItemText(hDlg, IDC_FILENAME, dat->filename, len); + if(dat->inSend) + // Send offer to remote side + { + dat->sendReq(); + } + else + // Send the accept and starting to receive + { + char buff[MAX_PATH]; + char *bufname; + + GetFullPathName(dat->filename, sizeof(buff), buff, &bufname); + *bufname = 0; + CreateDirectoryTree(buff); + if(!dat->createTransfer()) + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Failed on file initialization")); + break; + } + dat->sendCmd(0, CMD_ACCEPT, ""); + dat->lastTimestamp = GetTickCount(); + SetDlgItemText(hDlg, IDC_STATUS, Translate("Receiving...")); + dat->setState(STATE_OPERATE); + } + } + else + { + if(dat->inSend) + { + if(dat->iState == STATE_OPERATE) + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Paused...")); + dat->setState(STATE_PAUSED); + KillTimer(hDlg, TIMER_SEND); + } + else + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Sending...")); + if(dat->chunkIndx < dat->chunkCount) + dat->setState(STATE_OPERATE); + else + dat->setState(STATE_ACKREQ); + PostMessage(hDlg, WM_TIMER, 0,0); + //dat->onRecvTimer(); + //SetTimer(hDlg, TIMER_SEND, dwSendInterval, NULL); + } + } + else + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Synchronizing...")); + dat->setState(STATE_ACKREQ); + PostMessage(hDlg, WM_TIMER, 0,0); + //dat->onRecvTimer(); + //SetTimer(hDlg, TIMER_SEND, dwSendInterval, 0); + } + break; + } + break; + } + case IDC_BROWSE: + { + char str[MAX_PATH]; + OPENFILENAME ofn; + + ZeroMemory(&ofn, sizeof(ofn)); + *str = 0; + GetDlgItemText(hDlg, IDC_FILENAME, str, sizeof(str)); + //ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hDlg; + //ofn.lpstrFilter = "*.*"; + ofn.lpstrFile = str; + ofn.Flags = dat->inSend?OFN_FILEMUSTEXIST:0; + ofn.lpstrTitle = dat->inSend?Translate("Select a file"):Translate("Save as"); + ofn.nMaxFile = sizeof(str); + ofn.nMaxFileTitle = MAX_PATH; + if(!GetOpenFileName(&ofn)) break; + if(!dat->inSend && dat->iState == STATE_FINISHED) break; + SetDlgItemText(hDlg, IDC_FILENAME, str); + + int size = RetrieveFileSize(str); + if(size != -1) + _snprintf(str, sizeof(str), Translate("Size: %d bytes"), size); + else + _snprintf(str, sizeof(str), Translate("Can't get a file size"), size); + SetDlgItemText(hDlg, IDC_FILESIZE, str); + + break; + } + + case IDC_STOP: + case IDCANCEL: + if(dat->iState == STATE_PRERECV) + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Cancelled by user")); + dat->sendCmd(0, CMD_CANCEL, "", NULL); + dat->setState(STATE_CANCELLED); + } + if(dat->chunkCount) + { + if(MessageBox(hDlg, Translate("Transfer is in progress. Do you really want to close?"), + Translate(SERVICE_TITLE), MB_ICONWARNING|MB_YESNO|MB_DEFBUTTON2) == IDYES) + { + SetDlgItemText(hDlg, IDC_STATUS, Translate("Cancelled by user")); + dat->setState(STATE_CANCELLED); + dat->sendCmd(0, CMD_CANCEL, "", NULL); + dat->destroyTransfer(); + if(wParam == IDCANCEL) + DestroyWindow(hDlg); + } + } + else + if(wParam == IDCANCEL) + DestroyWindow(hDlg); + break;//return TRUE; + } + break; + } + + return FALSE; +} diff --git a/plugins/FileAsMessage/dialog.h b/plugins/FileAsMessage/dialog.h new file mode 100644 index 0000000000..ab5795dc0f --- /dev/null +++ b/plugins/FileAsMessage/dialog.h @@ -0,0 +1,120 @@ +#include +#include +#include +extern HINSTANCE hInst; + +int getMsgId(char *msg); + +LRESULT CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +#ifdef _DEBUG + #define CHECKPOINT +#else + #define CHECKPOINT error +#endif + +#define TIMER_SEND 100 + +typedef unsigned int uint; +typedef unsigned char uchar; +typedef unsigned long ulong; +enum +{ + CMD_REQ, + CMD_ACCEPT, + CMD_CANCEL, + + CMD_NEXT, + + CMD_DATA, + CMD_DACK, + CMD_END, + + CMD_COUNT +}; + +extern char cFECmd[CMD_COUNT]; + +#define STATE_IDLE 0x100 // idle, no operation +#define STATE_REQSENT 0x02 // request sent, awaiting of response +#define STATE_PRERECV 0x04 // incoming request, awaiting of user +#define STATE_OPERATE 0x08 // operating mode +#define STATE_ACKREQ 0x10 // ACK-request scheduled +#define STATE_CANCELLED 0x20 // operation aborted +#define STATE_FINISHED 0x40 // ... finished successfully +#define STATE_PAUSED 0x80 // ... paused + +#define CHUNK_UNSENT 0x00 +#define CHUNK_SENT 0x01 +#define CHUNK_ACK 0x02 + +#define ICON_PLAY 0 +#define ICON_PAUSE 1 +#define ICON_REFRESH 2 +#define ICON_STOP 3 +#define ICON_MAIN 4 + +struct FILEECHO +{ +public: + HANDLE hContact; + HWND hDlg; + + bool inSend; + int iState; + int contactStatus; + + HANDLE hFile, hMapping; + uchar *lpData; + + char *filename; + uint chunkIndx; // next chunk to send + uint chunkCount; // count of chunks + uint chunkSent; + uint chunkCountx; + uint *chunkPos; // offsets of chunks in file + uchar *chunkAck; // acknowledge of incoming chunks + + uchar codeSymb; // symb for replace NUL-symb. + + uint fileSize; + uint chunkMaxLen; // limit for outgoing chunk + + DWORD lastTimestamp; + DWORD lastDelay; + bool asBinary; + + // settings + uint dwSendInterval; + //uint dwChunkSize; + + COLORREF rgbSent, rgbRecv, rgbUnSent, rgbToSend; +#ifdef DEBUG + uint overhead; +#endif + + FILEECHO(HANDLE Contact); + + void setState(DWORD state); + void updateProgress(); + void updateTitle(); + + void perform(char *str); + void cmdACCEPT(); + void cmdDACK(char *data); + void sendReq(); + int sendCmd(int id, int cmd, char *szParam, char *szPrefix = NULL); + + void cmdDATA(char *data); + void cmdEND(); + + int createTransfer(); + void destroyTransfer(); + + void onSendTimer(); + void onRecvTimer(); + void incomeRequest(char *data); + +}; + +void InitCRC32(); diff --git a/plugins/FileAsMessage/fileecho.dsp b/plugins/FileAsMessage/fileecho.dsp new file mode 100644 index 0000000000..7bf64445c3 --- /dev/null +++ b/plugins/FileAsMessage/fileecho.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="fileecho" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=fileecho - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fileecho.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fileecho.mak" CFG="fileecho - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fileecho - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "fileecho - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fileecho - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FILEECHO_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FILEECHO_EXPORTS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /dll /pdb:none /machine:I386 /out:"E:\Miranda IM\Plugins\disabled\FileAsMessage.dll" + +!ELSEIF "$(CFG)" == "fileecho - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FILEECHO_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FILEECHO_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/release/plugins/fileAsMessage.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "fileecho - Win32 Release" +# Name "fileecho - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\dialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# Begin Source File + +SOURCE=.\optionsdlg.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\dialog.h +# End Source File +# Begin Source File + +SOURCE=.\main.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\abort.ico +# End Source File +# Begin Source File + +SOURCE=.\file.ico +# End Source File +# Begin Source File + +SOURCE=.\res\pause.ico +# End Source File +# Begin Source File + +SOURCE=.\res\play.ico +# End Source File +# Begin Source File + +SOURCE=.\res\refresh.ico +# End Source File +# Begin Source File + +SOURCE=.\resources.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/plugins/FileAsMessage/fileecho.dsw b/plugins/FileAsMessage/fileecho.dsw new file mode 100644 index 0000000000..a2f435f46d --- /dev/null +++ b/plugins/FileAsMessage/fileecho.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fileecho"=".\fileecho.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/FileAsMessage/fileecho.opt b/plugins/FileAsMessage/fileecho.opt new file mode 100644 index 0000000000..c53a9eee75 Binary files /dev/null and b/plugins/FileAsMessage/fileecho.opt differ diff --git a/plugins/FileAsMessage/fileecho.vcproj b/plugins/FileAsMessage/fileecho.vcproj new file mode 100644 index 0000000000..fef4b7301e --- /dev/null +++ b/plugins/FileAsMessage/fileecho.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/FileAsMessage/m_Snapping_windows.h b/plugins/FileAsMessage/m_Snapping_windows.h new file mode 100644 index 0000000000..3aa505fe74 --- /dev/null +++ b/plugins/FileAsMessage/m_Snapping_windows.h @@ -0,0 +1,42 @@ +#ifndef SNAPPING_WINDOWS_H +#define SNAPPING_WINDOWS_H + +/* +If you want to use SnappingWindows in you plugin you should add this code in WindowProc: + +BOOL CALLBACK YouWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CallSnappingWindowProc(hwnd,msg,wParam,lParam); + // + switch (msg) + { + case:..... + ........... + } + return ...... +} + + +*/ + +struct SnapWindowProc_t +{ + HWND hWnd; + // + SIZE m_szMoveOffset; + WPARAM wParam; + LPARAM lParam; + // + int Reserved1; + int Reserved2; + int Reserved3; +}; + +#define CallSnappingWindowProc(hwnd,nMessage,wParam,lParam) {static struct SnapWindowProc_t SnapInfo;\ + if ((nMessage == WM_MOVING) || (nMessage == WM_NCLBUTTONDOWN) || (nMessage == WM_SYSCOMMAND)){\ + SnapInfo.hWnd = hwnd;\ + SnapInfo.wParam = wParam;\ + SnapInfo.lParam = lParam;\ + CallService("Utils/SnapWindowProc",(WPARAM)&SnapInfo,nMessage);}} + +#endif //SNAPPING_WINDOWS_H \ No newline at end of file diff --git a/plugins/FileAsMessage/main.cpp b/plugins/FileAsMessage/main.cpp new file mode 100644 index 0000000000..a1a9aaba3f --- /dev/null +++ b/plugins/FileAsMessage/main.cpp @@ -0,0 +1,359 @@ +#include "main.h" +#include "dialog.h" +#include "resource.h" + +#include "IcoLib.h" + +#include +#include + +PLUGINLINK *pluginLink; +PLUGININFO pluginInfo = +{ + sizeof( PLUGININFO ), + SERVICE_TITLE, + PLUGIN_MAKE_VERSION( 0,0,2,4 ), + "file tranfer by using the messaging services - as plain text", + "Denis Stanishevskiy // StDenis", + "stdenformiranda(at)fromru(dot)com", + "Copyright (c) 2004, Denis Stanishevskiy", + PLUGIN_URL, + 0, 0 +}; + +HANDLE hFileList; +HINSTANCE hInst; + +char *szServiceTitle = SERVICE_TITLE; +char *szServicePrefix = SERVICE_PREFIX; +HANDLE hHookDbSettingChange, hHookContactAdded, hHookSkinIconsChanged; + +extern LRESULT CALLBACK OptionsDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +int idIcons[5] = {IDI_PLAY, IDI_PAUSE, IDI_REFRESH, IDI_STOP, IDI_SMALLICON}; +HICON hIcons[5]; + +char *szIconId[5] = +{ + "FePlay", + "FePause", + "FeRefresh", + "FeStop", + "FeMain" +}; +char *szIconName[5] = +{ + "Play", + "Pause", + "Revive", + "Stop", + "Main" +}; +/* +char *szIconGroup[5] = +{ + "gr1", + "gr3", + "gr2", + "gr3", + "gr1" +}; +*/ +int iIconId[5] = {3,2,4,1,0}; + +// +// wParam - Section name +// lParam - Icon ID +// +int OnSkinIconsChanged(WPARAM wParam,LPARAM lParam) +{ + int indx; +/* + if(lParam == NULL) + return 0; + for(indx = 0; indx < ARRAY_SIZE(hIcons); indx++) + { + if(strcmp((char*)lParam, szIconId[indx]) == 0) + { + hIcons[indx] = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)szIconId[indx]); + break; + } + } +*/ + for(indx = 0; indx < ARRAY_SIZE(hIcons); indx++) + hIcons[indx] = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)szIconId[indx]); + + WindowList_Broadcast(hFileList, WM_FE_SKINCHANGE, 0,0); + + return 0; +} + +int OnSettingChanged(WPARAM wParam,LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam; + HWND hwnd; + + hwnd = WindowList_Find(hFileList,(HANDLE)wParam); + PostMessage(hwnd, WM_FE_STATUSCHANGE, 0,0); + //OnSkinIconsChanged(0,0); + //PostMessage(hwnd, WM_FE_SKINCHANGE, 0,0); + + return 0; +} + +int OnContactAdded(WPARAM wParam,LPARAM lParam) +{ + CallService(MS_PROTO_ADDTOCONTACT, wParam, (LPARAM)SERVICE_NAME); + return 0; +} + +int OnRecvFile(WPARAM wParam, LPARAM lParam) +{ + HWND hwnd; + CLISTEVENT *clev = (CLISTEVENT*)lParam; + + hwnd = WindowList_Find(hFileList,(HANDLE)clev->hContact); + if(IsWindow(hwnd)) + { + ShowWindow(hwnd, SW_SHOWNORMAL); + SetForegroundWindow(hwnd); + SetFocus(hwnd); + } + /* + else + { + if(hwnd != 0) WindowList_Remove(hFileList, hwnd); + FILEECHO *fe = new FILEECHO((HANDLE)clev->hContact); + fe->inSend = FALSE; + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, (DLGPROC)DialogProc, (LPARAM)fe); + if(hwnd == NULL) + { + delete fe; + return 0; + } + //SendMessage(hwnd, WM_FE_SERVICE, 0, TRUE); + ShowWindow(hwnd, SW_SHOWNORMAL); + } + */ + return 1; +} + +int OnSendFile(WPARAM wParam, LPARAM lParam) +{ + HWND hwnd; + + hwnd = WindowList_Find(hFileList,(HANDLE)wParam); + if(IsWindow(hwnd)) + { + SetForegroundWindow(hwnd); + SetFocus(hwnd); + } + else + { + if(hwnd != 0) WindowList_Remove(hFileList, hwnd); + FILEECHO *fe = new FILEECHO((HANDLE)wParam); + fe->inSend = TRUE; + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, (DLGPROC)DialogProc, (LPARAM)fe); + if(hwnd == NULL) + { + delete fe; + return 0; + } + //SendMessage(hwnd, WM_FE_SERVICE, 0, TRUE); + ShowWindow(hwnd, SW_SHOWNORMAL); + } + return 1; +} + +int OnRecvMessage( WPARAM wParam, LPARAM lParam ) +{ + CCSDATA *pccsd = (CCSDATA *)lParam; + PROTORECVEVENT *ppre = ( PROTORECVEVENT * )pccsd->lParam; + HWND hwnd; + + if(strncmp(ppre->szMessage, szServicePrefix, strlen(szServicePrefix))) + return CallService( MS_PROTO_CHAINRECV, wParam, lParam ); + + hwnd = (HWND)WindowList_Find(hFileList, (HANDLE)pccsd->hContact); + if(!IsWindow(hwnd)) + { + if(hwnd != 0) WindowList_Remove(hFileList, hwnd); + FILEECHO *fe = new FILEECHO((HANDLE)pccsd->hContact); + fe->inSend = FALSE; + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, (DLGPROC)DialogProc, (LPARAM)fe); + if(hwnd == NULL) + { + delete fe; + return 0; + } + } + char *msg = strdup(ppre->szMessage + strlen(szServicePrefix)); + PostMessage(hwnd, WM_FE_MESSAGE, (WPARAM)pccsd->hContact, (LPARAM)msg); + + return 0; +} + +int OnOptInitialise(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp, sizeof(odp)); + + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS); + odp.pszTitle = Translate(SERVICE_TITLE); + odp.pszGroup = Translate("Plugins"); + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = (DLGPROC)OptionsDlgProc; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + return 0; +} + +// +// MirandaPluginInfo() +// Called by Miranda to get Version +// +PLUGININFO *MirandaPluginInfo( DWORD dwVersion ) +{ +/* + if(MessageBox(0, + "Achtung! This plugin is technology demo only. It didn't tested carefully.\n" + "Do you want to continue usage of this plugin?", SERVICE_TITLE, + MB_YESNO) != IDYES) return 0; +//*/ + if( dwVersion < PLUGIN_MAKE_VERSION( 0,3,3,0 ))return 0; + return &pluginInfo; +} +/* +DWORD CreateSetting(char *name, DWORD defvalue) +{ + if(DBGetContactSettingDword(NULL, SERVICE_NAME, name, -1) == -1) + DBWriteContactSettingDword(NULL, SERVICE_NAME, name, defvalue); + else + defvalue = DBGetContactSettingDword(NULL, SERVICE_NAME, name, defvalue); + return defvalue; +} +*/ + +int OnModulesLoaded(WPARAM wparam,LPARAM lparam) +{ + if(!ServiceExists(MS_SKIN2_ADDICON)) + { + for(int indx = 0; indx < ARRAY_SIZE(hIcons); indx++) + hIcons[indx] = (HICON)LoadImage(hInst,MAKEINTRESOURCE(idIcons[indx]),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0); + } + else + { + int indx; + SKINICONDESC sid; + char ModuleName[MAX_PATH]; + + ZeroMemory(&sid, sizeof(sid)); + sid.cbSize = sizeof(sid); + sid.pszSection = Translate("fileAsMessage"); + GetModuleFileName(hInst, ModuleName, sizeof(ModuleName)); + for(indx = 0; indx < ARRAY_SIZE(hIcons); indx++) + { + //sid.pszSection = szIconGroup[indx]; + sid.pszName = szIconId[indx]; + sid.pszDescription = szIconName[indx]; + sid.pszDefaultFile = ModuleName; + sid.iDefaultIndex = iIconId[indx]; + CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } + for(indx = 0; indx < ARRAY_SIZE(hIcons); indx++) + hIcons[indx] = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)szIconId[indx]); + + hHookSkinIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, OnSkinIconsChanged); + } + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while(hContact) + { + if(!CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)SERVICE_NAME)) + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)SERVICE_NAME); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + + CLISTMENUITEM mi; + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(CLISTMENUITEM); + mi.position = 200011; + mi.hIcon = hIcons[ICON_MAIN]; + mi.pszName = Translate("File As Message..."); + mi.pszService = SERVICE_NAME "/FESendFile"; + mi.pszContactOwner = NULL; + mi.flags = CMIF_NOTOFFLINE; + CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, ( LPARAM )&mi); + + return 0; +} + +// +// Startup initializing +// +int Load( PLUGINLINK *link ) +{ + pluginLink = link; + + InitCRC32(); + +// for(int indx = 0; indx < ARRAY_SIZE(hIcons); indx++) +// hIcons[indx] = (HICON)LoadImage(hInst,MAKEINTRESOURCE(idIcons[indx]),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0); + + hFileList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + + //CreateServiceFunction( SERVICE_NAME PS_GETCAPS, FEGetCaps ); + CreateServiceFunction(SERVICE_NAME PSR_MESSAGE, OnRecvMessage); + CreateServiceFunction(SERVICE_NAME "/FESendFile", OnSendFile); + CreateServiceFunction(SERVICE_NAME "/FERecvFile", OnRecvFile); + + PROTOCOLDESCRIPTOR pd; + memset(&pd, 0, sizeof( PROTOCOLDESCRIPTOR)); + pd.cbSize = sizeof(PROTOCOLDESCRIPTOR); + pd.szName = SERVICE_NAME; + pd.type = PROTOTYPE_FILTER; + CallService(MS_PROTO_REGISTERMODULE, 0, ( LPARAM ) &pd); + + HookEvent(ME_OPT_INITIALISE, OnOptInitialise); + HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + hHookDbSettingChange = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnSettingChanged); + hHookContactAdded = HookEvent(ME_DB_CONTACT_ADDED, OnContactAdded); + hHookSkinIconsChanged = NULL; + + return 0; +} + +// +// Unload() +// Called by Miranda when Plugin is unloaded. +// +int Unload( void ) +{ +// if(hFileList) +// WindowList_Broadcast(hFileList, WM_CLOSE, 0,0); + if(!ServiceExists(MS_SKIN2_ADDICON)) + for(int indx = 0; indx < ARRAY_SIZE(hIcons); indx++) + DestroyIcon(hIcons[indx]); + + if(hHookSkinIconsChanged != NULL) + UnhookEvent(hHookSkinIconsChanged); + UnhookEvent(hHookDbSettingChange); + UnhookEvent(hHookContactAdded); + + return 0; +} + +// +// DllMain() +// +int WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved ) +{ + hInst = hInstance; + + if( dwReason == DLL_PROCESS_ATTACH ) + DisableThreadLibraryCalls(hInstance); + + return 1; +} diff --git a/plugins/FileAsMessage/main.h b/plugins/FileAsMessage/main.h new file mode 100644 index 0000000000..66de382a63 --- /dev/null +++ b/plugins/FileAsMessage/main.h @@ -0,0 +1,59 @@ +//#include "AggressiveOptimize.h" + +#define _WIN32_WINNT 0x0501 +#include +#include + +#include "../../include/newpluginapi.h" +#include "../../include/m_system.h" +#include "../../include/m_database.h" +#include "../../include/m_protomod.h" +#include "../../include/m_protosvc.h" +#include "../../include/m_langpack.h" +#include "../../include/m_clist.h" +#include "../../include/m_options.h" +#include "../../include/m_clui.h" +#include "../../include/m_clc.h" +#include "../../include/m_utils.h" +#include "../../include/m_skin.h" +#include "../../include/m_popup.h" +#include "../../include/m_message.h" +#include "../../include/m_button.h" +#include "../../include/m_netlib.h" +#include "../../include/m_file.h" +#include "../../include/win2k.h" + +#define ARRAY_SIZE(n) (sizeof(n)/sizeof(n[0])) + +#define MAXBUFSIZE 4096 +#define SERVICE_TITLE "file As Message" +#define SERVICE_NAME "FileAsMessage" + +#define SERVICE_PREFIX "<%fAM-0023%>" + +#define PLUGIN_URL "http://miranda-im.org/download/details.php?action=viewfile&id=1811" +#define NOPLUGIN_MESSAGE "\nIf you see this \"garbage\", probably you "\ + "have no \"fileAsMessage\" plugin installed, see "\ + PLUGIN_URL " for more information and download." +extern char *szServiceTitle; +extern char *szServicePrefix; + +#define WM_FE_MESSAGE WM_USER+100 +#define WM_FE_STATUSCHANGE WM_USER+101 +#define WM_FE_SKINCHANGE WM_USER+102 + +extern HINSTANCE hInst; +extern HANDLE hFileList; +extern HANDLE hEventNewFile; + +extern HICON hIcons[5]; + +#ifdef __cplusplus +extern "C" { +#endif +int __declspec(dllexport) Load( PLUGINLINK *link ); +int __declspec(dllexport) Unload( void ); + __declspec(dllexport) PLUGININFO *MirandaPluginInfo( DWORD dwVersion ); +#ifdef __cplusplus +} +#endif diff --git a/plugins/FileAsMessage/main.rc b/plugins/FileAsMessage/main.rc new file mode 100644 index 0000000000..73be51abff --- /dev/null +++ b/plugins/FileAsMessage/main.rc @@ -0,0 +1,30 @@ +#include "windows.h" +#include "resource.h" +IDD_OPTIONS DIALOGEX 0,0,210,164 +FONT 8,"MS Shell Dlg" +STYLE 0x50000008 +EXSTYLE 0x00010000 +BEGIN + CONTROL "Hide delay",IDC_STATIC,"Static",0x50020002,15,135,88,8,0x00000000 + CONTROL "",IDC_HIDEDELAY,"Edit",0x50010080,108,132,45,14,0x00000200 + CONTROL "ms",IDC_STATIC,"Static",0x50020000,155,117,33,8,0x00000000 + CONTROL "Show delay",IDC_STATIC,"Static",0x50020002,15,117,88,8,0x00000000 + CONTROL "",IDC_SHOWDELAY,"Edit",0x50010080,108,114,45,14,0x00000200 + CONTROL "ms",IDC_STATIC,"Static",0x50020000,155,135,40,8,0x00000000 + CONTROL "Screen position",IDC_STATIC,"Button",0x50000007,7,6,198,90,0x00000000 + CONTROL "",IDC_DISABLED,"MButtonClass",0x10010000,100,46,16,14,0x00000000 + CONTROL "",IDC_LEFT,"MButtonClass",0x10010000,14,46,16,14,0x00000000 + CONTROL "",IDC_UPLEFT,"MButtonClass",0x10010000,14,17,16,14,0x00000000 + CONTROL "",IDC_DOWNLEFT,"MButtonClass",0x10010000,14,76,16,14,0x00000000 + CONTROL "",IDC_RIGHT,"MButtonClass",0x10010000,182,46,16,14,0x00000000 + CONTROL "",IDC_UPRIGHT,"MButtonClass",0x10010000,182,17,16,14,0x00000000 + CONTROL "",IDC_DOWNRIGHT,"MButtonClass",0x10010000,182,76,16,14,0x00000000 + CONTROL "Delays",IDC_STATIC,"Button",0x50000007,8,99,198,59,0x00000000 +END +IDI_DISABLED ICON DISCARDABLE "res/Disabled.ico" +IDI_LEFT ICON DISCARDABLE "res/Left.ico" +IDI_RIGHT ICON DISCARDABLE "res/Right.ico" +IDI_UPLEFT ICON DISCARDABLE "res/LeftUp.ico" +IDI_UPRIGHT ICON DISCARDABLE "res/RightUp.ico" +IDI_DOWNLEFT ICON DISCARDABLE "res/LeftDown.ico" +IDI_DOWNRIGHT ICON DISCARDABLE "res/RightDown.ico" diff --git a/plugins/FileAsMessage/optionsdlg.cpp b/plugins/FileAsMessage/optionsdlg.cpp new file mode 100644 index 0000000000..e39c574df2 --- /dev/null +++ b/plugins/FileAsMessage/optionsdlg.cpp @@ -0,0 +1,118 @@ +#include "main.h" +#include "resource.h" + +#include + +#pragma comment(lib, "comctl32.lib") + + +DWORD settingDefault[] = +{ + RGB(64,255,64), + RGB(255,255,64), + RGB(128,128,128), + RGB(192,192,192), + + 6000, + 5000 +}; +char *settingName[] = +{ + "colorRecv", + "colorSent", + "colorUnsent", + "colorTosend", + + "SendDelay", + "ChunkSize" +}; +int settingId[] = +{ + IDC_RECV, + IDC_SENT, + IDC_UNSENT, + IDC_TOSEND, + + -IDC_SENDDELAY, + -IDC_CHUNKSIZE +}; +// +// OptionsDlgProc() +// this handles the options page +// verwaltet die Optionsseite +// +LRESULT CALLBACK OptionsDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + switch( uMsg ) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + for(int indx = 0; indx < ARRAY_SIZE(settingId); indx++) + if(settingId[indx] > 0) + SendDlgItemMessage(hwndDlg, settingId[indx], CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, SERVICE_NAME, settingName[indx], settingDefault[indx])); + else + SetDlgItemInt(hwndDlg, -settingId[indx], DBGetContactSettingDword(NULL, SERVICE_NAME, settingName[indx], settingDefault[indx]), FALSE); + + CheckDlgButton(hwndDlg, IDC_ALPHANUM, DBGetContactSettingDword(NULL, SERVICE_NAME, "base64", 1)?BST_CHECKED:BST_UNCHECKED); + + return TRUE; + + } + case WM_COMMAND: + { + if(//MAKEWPARAM(IDC_AUTO, BN_CLICKED) != wParam || + MAKEWPARAM(IDC_ALPHANUM, BN_CLICKED) != wParam) + { + for(int indx = 0; indx < ARRAY_SIZE(settingId); indx++) + { + if(LOWORD(wParam) == abs(settingId[indx])) + { + if(settingId[indx] > 0) + { + if(HIWORD(wParam) != CPN_COLOURCHANGED) return FALSE; + } + else + { + if(HIWORD(wParam) != EN_CHANGE) return FALSE; + if((HWND)lParam != GetFocus()) return FALSE; + } + } + } + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0,0); + break; + } + case WM_DESTROY: + return FALSE; + + case WM_NOTIFY: + { + if((((NMHDR*)lParam)->idFrom == 0) && (((LPNMHDR)lParam)->code == PSN_APPLY)) + { + int value; + BOOL succ; + + for(int indx = 0; indx < ARRAY_SIZE(settingId); indx++) + { + if(settingId[indx] > 0) + value = SendDlgItemMessage(hwndDlg, settingId[indx], CPM_GETCOLOUR, 0, 0); + else + { + value = GetDlgItemInt(hwndDlg, -settingId[indx], &succ, FALSE); + if(!succ) value = settingDefault[indx]; + } + DBWriteContactSettingDword(NULL,SERVICE_NAME,settingName[indx], value); + } + DBWriteContactSettingDword(NULL,SERVICE_NAME, "base64", (IsDlgButtonChecked(hwndDlg, IDC_ALPHANUM) == BST_CHECKED)?1:0); + + return TRUE; + } + break; + } + + } + + return FALSE; +} diff --git a/plugins/FileAsMessage/res/abort.ico b/plugins/FileAsMessage/res/abort.ico new file mode 100644 index 0000000000..4b92cd4d1a Binary files /dev/null and b/plugins/FileAsMessage/res/abort.ico differ diff --git a/plugins/FileAsMessage/res/file.ico b/plugins/FileAsMessage/res/file.ico new file mode 100644 index 0000000000..2649b435ef Binary files /dev/null and b/plugins/FileAsMessage/res/file.ico differ diff --git a/plugins/FileAsMessage/res/pause.ico b/plugins/FileAsMessage/res/pause.ico new file mode 100644 index 0000000000..f99a5e147a Binary files /dev/null and b/plugins/FileAsMessage/res/pause.ico differ diff --git a/plugins/FileAsMessage/res/play.ico b/plugins/FileAsMessage/res/play.ico new file mode 100644 index 0000000000..4e37108cba Binary files /dev/null and b/plugins/FileAsMessage/res/play.ico differ diff --git a/plugins/FileAsMessage/res/refresh.ico b/plugins/FileAsMessage/res/refresh.ico new file mode 100644 index 0000000000..ceb0317065 Binary files /dev/null and b/plugins/FileAsMessage/res/refresh.ico differ diff --git a/plugins/FileAsMessage/resource.h b/plugins/FileAsMessage/resource.h new file mode 100644 index 0000000000..b6a254dcf7 --- /dev/null +++ b/plugins/FileAsMessage/resource.h @@ -0,0 +1,45 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resources.rc +// +#define IDC_PLAY 1 +#define IDD_DIALOG1 101 +#define IDD_MAIN 101 +#define IDI_SMALLICON 102 +#define IDD_OPTIONS 103 +#define IDI_STOP 104 +#define IDI_PAUSE 105 +#define IDI_PLAY 106 +#define IDI_REFRESH 107 +#define IDC_FILENAME 1001 +#define IDC_BROWSE 1002 +#define IDC_STOP 1003 +#define IDC_REFRESH 1004 +#define IDC_PROGRESS 1005 +#define IDC_STATUS 1006 +#define IDC_FILESIZE 1008 +#define IDC_LIST1 1020 +#define IDC_ALPHANUM 1022 +#define IDC_HIDEDELAY 1051 +#define IDC_CHUNKSIZE 1051 +#define IDC_SHOWDELAY 1052 +#define IDC_SENDDELAY 1052 +#define IDC_SENTCOLOR 1053 +#define IDC_UNSENT 1053 +#define IDC_SENTCOLOR2 1054 +#define IDC_SENT 1054 +#define IDC_SENTCOLOR3 1055 +#define IDC_TOSEND 1055 +#define IDC_SENTCOLOR4 1056 +#define IDC_RECV 1056 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1022 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/FileAsMessage/resources.rc b/plugins/FileAsMessage/resources.rc new file mode 100644 index 0000000000..cbca7fcacc --- /dev/null +++ b/plugins/FileAsMessage/resources.rc @@ -0,0 +1,156 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAIN DIALOGEX 0, 0, 252, 75 +STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "fileAsMessage" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Filename:",IDC_STATIC,7,7,31,8 + EDITTEXT IDC_FILENAME,7,16,221,14,ES_AUTOHSCROLL + LTEXT "Size:",IDC_FILESIZE,7,32,238,8 + PUSHBUTTON "...",IDC_BROWSE,232,16,13,14 + LTEXT "",IDC_PROGRESS,43,44,202,14,0,WS_EX_STATICEDGE + CONTROL "",IDC_PLAY,"MButtonClass",WS_TABSTOP,7,44,16,14 + CONTROL "",IDC_STOP,"MButtonClass",WS_TABSTOP,25,44,16,14 +END + +IDD_OPTIONS DIALOGEX 0, 0, 241, 181 +STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_UNSENT,"ColourPicker",WS_GROUP | WS_TABSTOP,124, + 106,39,12,WS_EX_NOPARENTNOTIFY + RTEXT "Chunk size",IDC_STATIC,9,41,92,8 + EDITTEXT IDC_CHUNKSIZE,123,39,41,14,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_CLIENTEDGE + LTEXT "ms",IDC_STATIC,170,23,28,8 + RTEXT "Delays between sends",IDC_STATIC,9,23,93,8 + EDITTEXT IDC_SENDDELAY,123,20,41,14,ES_AUTOHSCROLL | NOT + WS_BORDER,WS_EX_CLIENTEDGE + LTEXT "bytes",IDC_STATIC,170,41,28,8 + GROUPBOX "Transfer settings",IDC_STATIC,5,5,230,67 + GROUPBOX "Appearance",IDC_STATIC,5,75,230,100 + CONTROL "",IDC_SENT,"ColourPicker",WS_GROUP | WS_TABSTOP,124,124, + 39,12,WS_EX_NOPARENTNOTIFY + CONTROL "",IDC_TOSEND,"ColourPicker",WS_GROUP | WS_TABSTOP,124, + 141,39,12,WS_EX_NOPARENTNOTIFY + CONTROL "",IDC_RECV,"ColourPicker",WS_GROUP | WS_TABSTOP,124,89, + 39,12,WS_EX_NOPARENTNOTIFY + RTEXT "Unsent",IDC_STATIC,15,108,86,8 + RTEXT "Sent",IDC_STATIC,15,126,86,8 + RTEXT "To send",IDC_STATIC,15,143,86,8 + RTEXT "Received",IDC_STATIC,15,91,86,8 + CONTROL "Use only alphanumeric encoding on transfer", + IDC_ALPHANUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,57, + 217,10 + LTEXT "Extra options: Events » File Transfers, ""Receiving files"" group", + IDC_STATIC,10,160,220,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_MAIN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 245 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END + + IDD_OPTIONS, DIALOG + BEGIN + RIGHTMARGIN, 221 + BOTTOMMARGIN, 163 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SMALLICON ICON DISCARDABLE "res\\file.ico" +IDI_STOP ICON DISCARDABLE "res\\abort.ico" +IDI_PAUSE ICON DISCARDABLE "res\\pause.ico" +IDI_PLAY ICON DISCARDABLE "res\\play.ico" +IDI_REFRESH ICON DISCARDABLE "res\\refresh.ico" +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + -- cgit v1.2.3