void CSteamProto::OnGotRsaKey(const HttpResponse *response) { if (!CheckResponse(response)) return; // load rsa key parts JSONNode root = JSONNode::parse(response->pData); if (!root) return; if (!root["success"].as_bool()) return; std::string modulus = root["publickey_mod"].as_string(); // exponent "010001" is used as constant in CSteamProto::RsaEncrypt //std::string exponent = root["publickey_exp"].as_string(); std::string timestamp = root["timestamp"].as_string(); // encrcrypt password ptrA base64RsaEncryptedPassword; ptrA szPassword(getStringA("Password")); DWORD error = 0; DWORD encryptedSize = 0; if ((error = RsaEncrypt(modulus.c_str(), szPassword, NULL, encryptedSize)) != 0) { debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error); return; } BYTE *encryptedPassword = (BYTE*)mir_calloc(encryptedSize); if ((error = RsaEncrypt(modulus.c_str(), szPassword, encryptedPassword, encryptedSize)) != 0) { debugLogA("CSteamProto::OnGotRsaKey: encryption error (%lu)", error); return; } base64RsaEncryptedPassword = mir_base64_encode(encryptedPassword, encryptedSize); mir_free(encryptedPassword); // run authorization request T2Utf username(getTStringA("Username")); ptrA twoFactorCode(getStringA("TwoFactorCode")); if (!twoFactorCode) twoFactorCode = mir_strdup(""); ptrA guardId(getStringA("GuardId")); if (!guardId) guardId = mir_strdup(""); ptrA guardCode(getStringA("GuardCode")); if (!guardCode) guardCode = mir_strdup(""); ptrA captchaId(getStringA("CaptchaId")); if (!captchaId) captchaId = mir_strdup("-1"); ptrA captchaText(getStringA("CaptchaText")); if (!captchaText) captchaText = mir_strdup(""); PushRequest( new AuthorizationRequest(username, base64RsaEncryptedPassword, timestamp.c_str(), twoFactorCode, guardCode, guardId, captchaId, captchaText), &CSteamProto::OnAuthorization); }
void __cdecl PopulateModuleTreeThreadFunc(LPVOID di) { TVINSERTSTRUCT tvi; HWND hwnd2Tree = GetDlgItem(hwnd2mainWindow, IDC_MODULES); char SelectedModule[256] = {0}; char SelectedSetting[256] = {0}; MCONTACT hSelectedContact = hRestore; MCONTACT hContact; HTREEITEM contact, contactsRoot; int count; // item lParams ModuleTreeInfoStruct *lParam; // module list ModSetLinkLinkItem *module; ModuleSettingLL modlist; hRestore = NULL; if (!hwnd2Tree) { msg(Translate("Module tree not found"), modFullname); return; } Select = 0; switch ((int)di) { case 1: // restore after rebuild if (HTREEITEM item = TreeView_GetSelection(hwnd2Tree)) { TVITEM tvi = {0}; tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT; tvi.pszText = SelectedModule; tvi.cchTextMax = 255; tvi.hItem = item; TreeView_GetItem(hwnd2Tree, &tvi); if (tvi.lParam) { ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)tvi.lParam; hSelectedContact = mtis->hContact; if (mtis->type == CONTACT) SelectedModule[0] = 0; Select = 1; } } break; case 2: // restore saved if (GetValue(NULL, modname, "LastModule", SelectedModule, SIZEOF(SelectedModule))) { hSelectedContact = db_get_dw(NULL, modname, "LastContact", (DWORD)INVALID_HANDLE_VALUE); if (hSelectedContact != INVALID_CONTACT_ID) Select = 1; GetValue(NULL, modname, "LastSetting", SelectedSetting, SIZEOF(SelectedSetting)); } break; case 3: // restore from user menu case 4: // jump from user menu if (hSelectedContact && hSelectedContact != INVALID_CONTACT_ID) Select = 1; break; } if ((int)di != 4) { // do not rebuild on just going to another setting if (!EnumModules(&modlist)) { msg(Translate("Error loading module list"), modFullname); return; } // remove all items (incase there are items there... freeTree(hwnd2Tree, 0); TreeView_DeleteAllItems(hwnd2Tree); TreeView_SelectItem(hwnd2Tree, 0); //image list TreeView_SetImageList(hwnd2Tree, himl, TVSIL_NORMAL); /// contact root item contacts_mtis.type = CONTACT_ROOT_ITEM; tvi.item.lParam = (LPARAM)&contacts_mtis; tvi.hParent = NULL; tvi.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_STATE | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvi.item.state = TVIS_BOLD; tvi.item.stateMask = TVIS_BOLD; tvi.item.cChildren = 1; tvi.hInsertAfter = TVI_FIRST; tvi.item.pszText = Translate("Contacts"); tvi.item.iImage = 3; tvi.item.iSelectedImage = 3; contactsRoot = TreeView_InsertItem(hwnd2Tree, &tvi); // add the settings item settings_mtis.type = STUB; tvi.item.lParam = (LPARAM)&settings_mtis; tvi.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvi.item.cChildren = 1; tvi.hParent = NULL; tvi.hInsertAfter = TVI_FIRST; tvi.item.pszText = Translate("Settings"); tvi.item.iImage = 0; tvi.item.iSelectedImage = 0; contact = TreeView_InsertItem(hwnd2Tree, &tvi); // to fix bug with CHANGE NOTIFY on window activation TreeView_SelectItem(hwnd2Tree, contact); settings_mtis.type = CONTACT; hContact = 0; module = modlist.first; while (module) { if (!IsModuleEmpty(hContact, module->name)) { tvi.hParent = contact; tvi.hInsertAfter = TVI_SORT; tvi.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; tvi.item.pszText = module->name; lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); lParam->hContact = hContact; tvi.item.iImage = 1; tvi.item.iSelectedImage = 2; lParam->type = KNOWN_MODULE; tvi.item.lParam = (LPARAM)lParam; TreeView_InsertItem(hwnd2Tree, &tvi); } module = (ModSetLinkLinkItem *)module->next; } if (db_get_b(NULL, modname, "ExpandSettingsOnOpen", 0)) TreeView_Expand(hwnd2Tree, contact, TVE_EXPAND); if (Select && hSelectedContact == NULL) { int hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule); if (hItem != -1) { TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem); TreeView_Expand(hwnd2Tree, hItem, TVE_EXPAND); if (SelectedSetting[0]) SelectSetting(SelectedSetting); } Select = 0; } count = doContacts(hwnd2Tree, contactsRoot, &modlist, Select ? hSelectedContact : NULL, SelectedModule, SelectedSetting); Select = 0; doItems(hwnd2Tree, &modlist, count); FreeModuleSettingLL(&modlist); } if (Select) { int hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule); if (hItem != -1) { TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem); TreeView_Expand(hwnd2Tree, hItem, TVE_EXPAND); if (SelectedSetting[0]) SelectSetting(SelectedSetting); } } populating = 0; }
int doContacts(HWND hwnd2Tree, HTREEITEM contactsRoot, ModuleSettingLL *modlist, MCONTACT hSelectedContact, char *SelectedModule, char *SelectedSetting) { TVINSERTSTRUCT tvi; HTREEITEM contact; ModuleTreeInfoStruct *lParam; ModSetLinkLinkItem *module; int count = CallService(MS_DB_CONTACT_GETCOUNT, 0, 0); int itemscount = 0; int loaded, i = 0, icon = 0; HWND hwnd = GetParent(hwnd2Tree); int hItem = -1; SetWindowText(hwnd2mainWindow, Translate("Loading contacts...")); tvi.hInsertAfter = TVI_SORT; tvi.item.cChildren = 1; for (MCONTACT hContact = db_find_first(); hContact && hwnd2mainWindow; hContact = db_find_next(hContact)) { char szProto[100]; if (DBGetContactSettingStringStatic(hContact, "Protocol", "p", szProto, SIZEOF(szProto))) { icon = GetProtoIcon(szProto); loaded = (icon != DEF_ICON); } else { icon = DEF_ICON; loaded = 0; } i++; // filter if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED)) continue; // add the contact lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); lParam->hContact = hContact; lParam->type = CONTACT; tvi.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvi.item.lParam = (LPARAM)lParam; tvi.hParent = contactsRoot; if (hSelectedContact != hContact) lParam->type |= EMPTY; // contacts name DBVARIANT dbv = {0}; WCHAR nick[256]; WCHAR protoW[256]; // unicode proto if (szProto) a2u(szProto, protoW, SIZEOF(protoW)); else protoW[0] = 0; if (!szProto || !loaded) { tvi.item.iSelectedImage = (tvi.item.iImage = 4); if (protoW) { if (Order) mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)"); else mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)"); } else wcscpy(nick, nick_unknownW); } else { tvi.item.iSelectedImage = (tvi.item.iImage = icon); //GetProtoIcon(szProto, 7)); if (Order) mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1)); else mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW); } tvi.item.pszText = (char *)nick; contact = TreeView_InsertItemW(hwnd2Tree, &tvi); itemscount++; if (hSelectedContact == hContact) { module = modlist->first; while (module && hwnd2mainWindow) { if (module->name[0] && !IsModuleEmpty(hContact, module->name)) { tvi.hParent = contact; tvi.hInsertAfter = TVI_SORT; tvi.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; tvi.item.pszText = module->name; lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); lParam->hContact = hContact; tvi.item.iImage = 1; tvi.item.iSelectedImage = 2; lParam->type = KNOWN_MODULE; tvi.item.lParam = (LPARAM)lParam; TreeView_InsertItem(hwnd2Tree, &tvi); } module = (ModSetLinkLinkItem *)module->next; } hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule); } } if (hItem != -1) { TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem); TreeView_Expand(hwnd2Tree, hItem, TVE_EXPAND); if (SelectedSetting[0]) SelectSetting(SelectedSetting); } return itemscount; }
static LRESULT CALLBACK _AniAva_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ANIAVA_WINDOWINFO * dat=NULL; if (msg==WM_TIMER || msg==WM_DESTROY || (msg>AAM_FIRST && msg<AAM_LAST) ) dat=(ANIAVA_WINDOWINFO *)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch (msg) { case AAM_REMOVEAVATAR: if (dat->ptFromPoint.x==(int)wParam) return 0xDEAD; //need to destroy window else if (dat->ptFromPoint.x>(int)wParam) dat->ptFromPoint.x-=(int)lParam; return 0; case AAM_PAUSE: dat->bPaused++; return 0; case AAM_RESUME: dat->bPaused--; if (dat->bPaused) return 0; if (dat->bPended) { if ( !IMMEDIATE_DRAW ) _AniAva_RenderAvatar(dat); } dat->bPended=FALSE; return 0; case AAM_STOP: if (dat->bPlaying) { dat->bPlaying=FALSE; KillTimer(hwnd,2); ShowWindow(hwnd, SW_HIDE); } return 0; case AAM_SETAVATAR: { ANIAVATARIMAGEINFO *paaii=(ANIAVATARIMAGEINFO*)wParam; _AniAva_Clear_ANIAVA_WINDOWINFO(dat); dat->nFramesCount=paaii->nFramesCount; dat->delaysInterval=paaii->pFrameDelays; dat->sizeAvatar=paaii->szSize; dat->ptFromPoint=paaii->ptImagePos; dat->currentFrame=0; dat->bPlaying=FALSE; return MAKELONG(dat->sizeAvatar.cx,dat->sizeAvatar.cy); } case AAM_SETPOSITION: { ANIAVA_POSINFO * papi=(ANIAVA_POSINFO *)lParam; if (!dat->delaysInterval) return 0; if (!papi) return 0; dat->rcPos=papi->rcPos; dat->overlayIconIdx=papi->idxOverlay; dat->bAlpha=papi->bAlpha; free(papi); if (!dat->bPlaying) { dat->bPlaying=TRUE; ShowWindow(hwnd,SW_SHOWNA); dat->currentFrame=0; KillTimer(hwnd,2); SetTimer(hwnd,2,dat->delaysInterval[0],NULL); } if ( !IMMEDIATE_DRAW ) _AniAva_RenderAvatar(dat); return 0; } case AAM_SETPARENT: if ( IMMEDIATE_DRAW ) return 0; dat->bOrderTop=((HWND)wParam!=GetDesktopWindow()); SetParent(hwnd,(HWND)wParam); if (dat->bOrderTop) { SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_ASYNCWINDOWPOS); } else { LONG exStyle; exStyle=GetWindowLong(pcli->hwndContactList,GWL_EXSTYLE); SetWindowPos(pcli->hwndContactList,hwnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/); if (!(exStyle&WS_EX_TOPMOST)) SetWindowPos(pcli->hwndContactList,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/); } return 0; case AAM_REDRAW: if ( IMMEDIATE_DRAW ) return 0; if ( wParam ) { if (dat->bOrderTop) { SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_ASYNCWINDOWPOS); } else { LONG exStyle; exStyle=GetWindowLong(pcli->hwndContactList,GWL_EXSTYLE); SetWindowPos(pcli->hwndContactList,hwnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/); if (!(exStyle&WS_EX_TOPMOST)) SetWindowPos(pcli->hwndContactList,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE/*|SWP_ASYNCWINDOWPOS*/); } } _AniAva_RenderAvatar( dat ); return 0; case AAM_RENDER: { HDC hdc = ( HDC )wParam; RECT* rect = ( RECT* )lParam; _AniAva_RenderAvatar( dat, hdc, rect ); } return 0; case AAM_SELFDESTROY: return DestroyWindow(hwnd); case WM_CREATE: { LONG exStyle; ANIAVA_WINDOWINFO * dat = (ANIAVA_WINDOWINFO *) mir_calloc(sizeof (ANIAVA_WINDOWINFO)); SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)dat); dat->hWindow=hwnd; //ShowWindow(dat->hWindow,SW_SHOW); //change layered mode exStyle=GetWindowLongPtr(dat->hWindow,GWL_EXSTYLE); exStyle|=WS_EX_LAYERED; SetWindowLong(dat->hWindow,GWL_EXSTYLE,exStyle); exStyle=GetWindowLong(dat->hWindow,GWL_STYLE); exStyle&=~WS_POPUP; exStyle|=WS_CHILD; SetWindowLong(dat->hWindow,GWL_STYLE,exStyle); break; } case WM_TIMER: { if (!IsWindowVisible(hwnd)) { DestroyWindow(hwnd); return 0; } dat->currentFrame++; if (dat->currentFrame>=dat->nFramesCount) dat->currentFrame=0; if ( !IMMEDIATE_DRAW ) _AniAva_RenderAvatar( dat ); else _AniAva_InvalidateParent( dat ); KillTimer(hwnd,2); SetTimer(hwnd,2,dat->delaysInterval[dat->currentFrame]+1,NULL); return 0; } case WM_DESTROY: { _AniAva_Clear_ANIAVA_WINDOWINFO(dat); mir_free(dat); SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)NULL); break; } } return DefWindowProc(hwnd, msg, wParam, lParam); }
BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix) { if (gce == 0 || si == 0 || gce->bIsMe || si->iType == GCW_SERVER) return FALSE; TWindowData *dat = NULL; FLASH_PARAMS *params = (FLASH_PARAMS*)mir_calloc(sizeof(FLASH_PARAMS)); params->hContact = si->hContact; params->bInactive = TRUE; if (si->hWnd && si->dat) { dat = si->dat; if ((si->hWnd == si->dat->pContainer->hwndActive) && GetForegroundWindow() == si->dat->pContainer->hwnd) params->bInactive = FALSE; } params->bActiveTab = params->bMustFlash = params->bMustAutoswitch = FALSE; params->iEvent = gce->pDest->iType; WPARAM wParamForHighLight = 0; bool bFlagUnread = false; if (bHighlight) { gce->pDest->iType |= GC_EVENT_HIGHLIGHT; params->sound = "ChatHighlight"; if (db_get_b(si->hContact, "CList", "Hidden", 0) != 0) db_unset(si->hContact, "CList", "Hidden"); if (params->bInactive) { bFlagUnread = true; DoTrayIcon(si, gce); } if (g_Settings.bCreateWindowOnHighlight && dat == NULL) wParamForHighLight = 1; if (dat && g_Settings.bAnnoyingHighlight && params->bInactive && dat->pContainer->hwnd != GetForegroundWindow()) { wParamForHighLight = 2; params->hWnd = dat->hwnd; } if (dat || !nen_options.iMUCDisable) DoPopup(si, gce); if (params->bInactive && si && si->hWnd) SendMessage(si->hWnd, GC_SETMESSAGEHIGHLIGHT, 0, (LPARAM)si); if (g_Settings.bFlashWindowHighlight && params->bInactive) params->bMustFlash = TRUE; params->bMustAutoswitch = TRUE; params->hNotifyIcon = pci->hIcons[ICON_HIGHLIGHT]; } else { // do blinking icons in tray if (params->bInactive || !g_Settings.bTrayIconInactiveOnly) { DoTrayIcon(si, gce); if (params->iEvent == GC_EVENT_MESSAGE) bFlagUnread = true; } // stupid thing to not create multiple popups for a QUIT event for instance if (bManyFix == 0) { // do popups if (dat || !nen_options.iMUCDisable) DoPopup(si, gce); // do sounds and flashing switch (params->iEvent) { case GC_EVENT_JOIN: params->sound = "ChatJoin"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_JOIN]; break; case GC_EVENT_PART: params->sound = "ChatPart"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_PART]; break; case GC_EVENT_QUIT: params->sound = "ChatQuit"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_QUIT]; break; case GC_EVENT_ADDSTATUS: case GC_EVENT_REMOVESTATUS: params->sound = "ChatMode"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[params->iEvent == GC_EVENT_ADDSTATUS ? ICON_ADDSTATUS : ICON_REMSTATUS]; break; case GC_EVENT_KICK: params->sound = "ChatKick"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_KICK]; break; case GC_EVENT_MESSAGE: params->sound = "ChatMessage"; if (params->bInactive && !(si->wState & STATE_TALK)) { si->wState |= STATE_TALK; db_set_w(si->hContact, si->pszModule, "ApparentMode", (LPARAM)(WORD) 40071); } break; case GC_EVENT_ACTION: params->sound = "ChatAction"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_ACTION]; break; case GC_EVENT_NICK: params->sound = "ChatNick"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_NICK]; break; case GC_EVENT_NOTICE: params->sound = "ChatNotice"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_NOTICE]; break; case GC_EVENT_TOPIC: params->sound = "ChatTopic"; if (params->bInactive) params->hNotifyIcon = pci->hIcons[ICON_TOPIC]; break; } } else { switch (params->iEvent) { case GC_EVENT_JOIN: params->hNotifyIcon = pci->hIcons[ICON_JOIN]; break; case GC_EVENT_PART: params->hNotifyIcon = pci->hIcons[ICON_PART]; break; case GC_EVENT_QUIT: params->hNotifyIcon = pci->hIcons[ICON_QUIT]; break; case GC_EVENT_KICK: params->hNotifyIcon = pci->hIcons[ICON_KICK]; break; case GC_EVENT_ACTION: params->hNotifyIcon = pci->hIcons[ICON_ACTION]; break; case GC_EVENT_NICK: params->hNotifyIcon = pci->hIcons[ICON_NICK]; break; case GC_EVENT_NOTICE: params->hNotifyIcon = pci->hIcons[ICON_NOTICE]; break; case GC_EVENT_TOPIC: params->hNotifyIcon = pci->hIcons[ICON_TOPIC]; break; case GC_EVENT_ADDSTATUS: params->hNotifyIcon = pci->hIcons[ICON_ADDSTATUS]; break; case GC_EVENT_REMOVESTATUS: params->hNotifyIcon = pci->hIcons[ICON_REMSTATUS]; break; } } if (params->iEvent == GC_EVENT_MESSAGE) { params->bMustAutoswitch = TRUE; if (g_Settings.bFlashWindow) params->bMustFlash = TRUE; params->hNotifyIcon = pci->hIcons[ICON_MESSAGE]; } } if (dat && bFlagUnread) { dat->dwUnread++; if (dat->pWnd) dat->pWnd->Invalidate(); } PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_MUCFLASHWORKER, wParamForHighLight, (LPARAM)params); return TRUE; }
HANDLE MraMrimProxyCreate() { MRA_MRIMPROXY_DATA *pmmpd = (MRA_MRIMPROXY_DATA*)mir_calloc(sizeof(MRA_MRIMPROXY_DATA)); return (HANDLE)pmmpd; }
void CSteamProto::PollingThread(void*) { debugLog(_T("CSteamProto::PollingThread: entering")); ptrA token(getStringA("TokenSecret")); ptrA umqId(getStringA("UMQID")); UINT32 messageId = getDword("MessageID", 0); int errors = 0; bool breaked = false; while (!isTerminated && !breaked && errors < POLLING_ERRORS_LIMIT) { PollRequest *request = new PollRequest(token, umqId, messageId, IdleSeconds()); request->nlc = m_pollingConnection; HttpResponse *response = request->Send(m_hNetlibUser); delete request; if (!ResponseHttpOk(response)) { errors++; } else { ptrA body((char*)mir_calloc(response->dataLength + 2)); mir_strncpy(body, response->pData, response->dataLength + 1); JSONROOT root(body); if (root == NULL) { errors++; } else { errors = 0; JSONNode *node = json_get(root, "error"); if (node) { ptrT error(json_as_string(node)); if (!lstrcmpi(error, _T("OK"))) { node = json_get(root, "messagelast"); messageId = json_as_int(node); node = json_get(root, "messages"); JSONNode *nroot = json_as_array(node); if (nroot != NULL) { ParsePollData(nroot); json_delete(nroot); } m_pollingConnection = response->nlc; } /*else if (!lstrcmpi(error, _T("Not Logged On"))) // 'else' below will handle this error, we don't need this particular check right now { if (!IsOnline()) { // need to relogin debugLog(_T("CSteamProto::PollingThread: not logged on")); SetStatus(ID_STATUS_OFFLINE); } breaked = true; }*/ else if (lstrcmpi(error, _T("Timeout"))) { // something wrong debugLog(_T("CSteamProto::PollingThread: %s (%d)"), error, response->resultCode); // token has expired if (response->resultCode == HTTP_CODE_UNAUTHORIZED) delSetting("TokenSecret"); // too low timeout? node = json_get(root, "sectimeout"); int timeout = json_as_int(node); if (timeout < STEAM_API_TIMEOUT) debugLog(_T("CSteamProto::PollingThread: Timeout is too low (%d)"), timeout); breaked = true; } } } } delete response; } setDword("MessageID", messageId); m_hPollingThread = NULL; debugLog(_T("CSteamProto::PollingThread: leaving")); if (!isTerminated) { debugLog(_T("CSteamProto::PollingThread: unexpected termination; switching protocol to offline")); SetStatus(ID_STATUS_OFFLINE); } }
//wparam=MenuObjectHandle //lparam=PMO_MenuItem //return MenuItemHandle PMO_IntMenuItem MO_AddNewMenuItem( HANDLE menuobjecthandle, PMO_MenuItem pmi ) { if ( !bIsGenMenuInited || pmi == NULL || pmi->cbSize != sizeof( TMO_MenuItem )) return NULL; //old mode if ( !( pmi->flags & CMIF_ROOTHANDLE )) return MO_AddOldNewMenuItem( menuobjecthandle, pmi ); EnterCriticalSection( &csMenuHook ); int objidx = GetMenuObjbyId( (int)menuobjecthandle ); if ( objidx == -1 ) { LeaveCriticalSection( &csMenuHook ); return NULL; } TIntMenuObject* pmo = g_menus[objidx]; TMO_IntMenuItem* p = ( TMO_IntMenuItem* )mir_calloc( sizeof( TMO_IntMenuItem )); p->parent = pmo; p->signature = MENUITEM_SIGNATURE; p->iCommand = GetNextObjectMenuItemId(); p->mi = *pmi; p->iconId = -1; p->OverrideShow = TRUE; p->originalPosition = pmi->position; #if defined( _UNICODE ) if ( pmi->flags & CMIF_UNICODE ) p->mi.ptszName = mir_tstrdup(( pmi->flags & CMIF_KEEPUNTRANSLATED ) ? pmi->ptszName : TranslateTS( pmi->ptszName )); else { if ( pmi->flags & CMIF_KEEPUNTRANSLATED ) p->mi.ptszName = mir_a2u(pmi->pszName); else p->mi.ptszName = LangPackPcharToTchar( pmi->pszName ); } #else p->mi.ptszName = mir_strdup(( pmi->flags & CMIF_KEEPUNTRANSLATED ) ? pmi->ptszName : Translate( pmi->ptszName )); #endif if ( pmi->hIcon != NULL && !bIconsDisabled ) { if ( pmi->flags & CMIF_ICONFROMICOLIB ) { HICON hIcon = IcoLib_GetIconByHandle( pmi->hIcolibItem, false ); p->iconId = ImageList_AddIcon( pmo->m_hMenuIcons, hIcon ); p->hIcolibItem = pmi->hIcolibItem; IconLib_ReleaseIcon( hIcon, 0 ); } else { HANDLE hIcolibItem = IcoLib_IsManaged( pmi->hIcon ); if ( hIcolibItem ) { p->iconId = ImageList_AddIcon( pmo->m_hMenuIcons, pmi->hIcon ); p->hIcolibItem = hIcolibItem; } else p->iconId = ImageList_AddIcon( pmo->m_hMenuIcons, pmi->hIcon ); } } if ( p->mi.root == HGENMENU_ROOT ) p->mi.root = NULL; PMO_IntMenuItem pRoot = ( p->mi.root != NULL ) ? MO_GetIntMenuItem( p->mi.root ) : NULL; if ( pRoot ) p->owner = &pRoot->submenu; else p->owner = &pmo->m_items; if ( !p->owner->first ) p->owner->first = p; if ( p->owner->last ) p->owner->last->next = p; p->owner->last = p; LeaveCriticalSection( &csMenuHook ); return p; }
static INT_PTR AddStatusMenuItem(WPARAM wParam, LPARAM lParam) { CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam; TMO_MenuItem tmi; if (!cli.pfnConvertMenu(mi, &tmi)) return 0; // for new style menus the pszPopupName contains the root menu handle PMO_IntMenuItem pRoot = NULL; if (mi->flags & CMIF_ROOTHANDLE) pRoot = MO_GetIntMenuItem(mi->hParentMenu); // for old style menus the pszPopupName really means the popup name else { MenuProto *mp = FindProtocolMenu(mi->pszContactOwner); if (mp && mi->pszPopupName) { if (mp->pMenu) { TCHAR *ptszName = (mi->flags & CMIF_UNICODE) ? mir_tstrdup(mi->ptszPopupName) : mir_a2t(mi->pszPopupName); pRoot = MO_RecursiveWalkMenu(mp->pMenu->submenu.first, FindRoot, ptszName); mir_free(ptszName); } if (pRoot == NULL) { TMO_MenuItem tmi = { 0 }; tmi.cbSize = sizeof(tmi); tmi.flags = (mi->flags & CMIF_UNICODE) | CMIF_ROOTHANDLE; tmi.position = 1001; tmi.root = mp->pMenu; tmi.hIcon = NULL; tmi.pszName = mi->pszPopupName; pRoot = MO_AddNewMenuItem(hStatusMenuObject, &tmi); } tmi.flags |= CMIF_ROOTHANDLE; tmi.root = pRoot; } } if (wParam) { int *res = (int*)wParam; *res = (int)pRoot; } // owner data StatusMenuExecParam *smep = NULL; if (mi->pszService) { smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); smep->custom = TRUE; smep->svc = mir_strdup(mi->pszService); { char *buf = mir_strdup(mi->pszService); int i = 0; while (buf[i] != '\0' && buf[i] != '/') i++; buf[i] = '\0'; smep->proto = mir_strdup(buf); mir_free(buf); } tmi.ownerdata = smep; } PMO_IntMenuItem menuHandle = MO_AddNewMenuItem(hStatusMenuObject, &tmi); if (smep) smep->hMenuItem = menuHandle; char buf[MAX_PATH + 64]; char *p = (pRoot) ? mir_t2a(pRoot->mi.ptszName) : NULL; mir_snprintf(buf, SIZEOF(buf), "%s/%s", (p) ? p : "", mi->pszService ? mi->pszService : ""); mir_free(p); MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); return (INT_PTR)menuHandle; }
static int BuildTree(HWND hwndDlg,int MenuObjectId, BOOL bReread) { char menuItemName[256],MenuNameItems[256]; char buf[256]; FreeTreeData( hwndDlg ); TreeView_DeleteAllItems(GetDlgItem(hwndDlg,IDC_MENUITEMS)); int menupos = GetMenuObjbyId( MenuObjectId ); if ( menupos == -1 ) return FALSE; TIntMenuObject* pimo = g_menus[menupos]; if ( pimo->m_items.first == NULL ) return FALSE; mir_snprintf( MenuNameItems, sizeof(MenuNameItems), "%s_Items", pimo->Name ); int count = 0; { for ( PMO_IntMenuItem p = pimo->m_items.first; p != NULL; p = p->next ) if ( p->mi.root == ( HGENMENU )-1 || p->mi.root == NULL ) count++; } lpMenuItemOptData *PDar = ( lpMenuItemOptData* )mir_alloc( sizeof( lpMenuItemOptData )*count ); count = 0; { for ( PMO_IntMenuItem p = pimo->m_items.first; p != NULL; p = p->next ) { if ( p->mi.root != ( HGENMENU )-1 && p->mi.root != NULL ) continue; MenuItemOptData *PD = ( MenuItemOptData* )mir_calloc( sizeof( MenuItemOptData )); GetMenuItemName( p, menuItemName, sizeof( menuItemName )); { DBVARIANT dbv; mir_snprintf(buf, SIZEOF(buf), "%s_name", menuItemName); if ( !DBGetContactSettingTString( NULL, MenuNameItems, buf, &dbv )) { PD->name = mir_tstrdup( dbv.ptszVal ); DBFreeVariant( &dbv ); } else PD->name = mir_tstrdup( p->mi.ptszName ); } PD->pimi = p; PD->defname = mir_tstrdup( p->mi.ptszName ); mir_snprintf( buf, SIZEOF(buf), "%s_visible", menuItemName ); PD->show = DBGetContactSettingByte( NULL, MenuNameItems, buf, 1 ); if ( bReread ) { mir_snprintf( buf, SIZEOF(buf), "%s_pos", menuItemName ); PD->pos = DBGetContactSettingDword( NULL, MenuNameItems, buf, 1 ); } else PD->pos = ( PD->pimi ) ? PD->pimi->originalPosition : 0; PD->id = p->iCommand; if ( p->UniqName ) PD->uniqname = mir_strdup( p->UniqName ); PDar[ count ] = PD; count++; } } qsort( PDar, count, sizeof( lpMenuItemOptData ), sortfunc ); SendDlgItemMessage(hwndDlg, IDC_MENUITEMS, WM_SETREDRAW, FALSE, 0); int lastpos = 0; bool first = TRUE; TVINSERTSTRUCT tvis; tvis.hParent = NULL; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; for ( int i=0; i < count; i++ ) { if ( PDar[i]->pos - lastpos >= SEPARATORPOSITIONINTERVAL ) { MenuItemOptData *PD = ( MenuItemOptData* )mir_calloc( sizeof( MenuItemOptData )); PD->id = -1; PD->name = mir_tstrdup( STR_SEPARATOR ); PD->pos = PDar[i]->pos - 1; PD->show = TRUE; tvis.item.lParam = ( LPARAM )PD; tvis.item.pszText = PD->name; tvis.item.iImage = tvis.item.iSelectedImage = PD->show; SendDlgItemMessage(hwndDlg, IDC_MENUITEMS, TVM_INSERTITEM, 0, (LPARAM)&tvis); } tvis.item.lParam = ( LPARAM )PDar[i]; tvis.item.pszText = PDar[i]->name; tvis.item.iImage = tvis.item.iSelectedImage = PDar[i]->show; HTREEITEM hti = (HTREEITEM)SendDlgItemMessage(hwndDlg, IDC_MENUITEMS, TVM_INSERTITEM, 0, (LPARAM)&tvis); if ( first ) { TreeView_SelectItem(GetDlgItem(hwndDlg,IDC_MENUITEMS),hti); first=FALSE; } lastpos = PDar[i]->pos; } SendDlgItemMessage( hwndDlg, IDC_MENUITEMS, WM_SETREDRAW, TRUE, 0 ); mir_free( PDar ); ShowWindow( GetDlgItem( hwndDlg, IDC_NOTSUPPORTWARNING ),( pimo->m_bUseUserDefinedItems ) ? SW_HIDE : SW_SHOW ); EnableWindow( GetDlgItem( hwndDlg, IDC_MENUITEMS ), pimo->m_bUseUserDefinedItems ); EnableWindow( GetDlgItem( hwndDlg, IDC_INSERTSEPARATOR ), pimo->m_bUseUserDefinedItems ); return 1; }
LRESULT CALLBACK ContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { struct ClcData *dat = (struct ClcData*)GetWindowLongPtr(hwnd,0); if ( msg >= CLM_FIRST && msg < CLM_LAST ) return pcli->pfnProcessExternalMessages(hwnd,dat,msg,wParam,lParam); switch (msg) { case WM_CREATE: dat = (struct ClcData*)mir_calloc( sizeof(struct ClcData)); SetWindowLong(hwnd,0,(LPARAM)dat); InitDisplayNameCache(&dat->lCLCContactsCache); break; case INTM_ICONCHANGED: { struct ClcContact *contact=NULL; struct ClcGroup *group=NULL; int recalcScrollBar=0,shouldShow; HANDLE hSelItem=NULL; struct ClcContact *selcontact=NULL; pdisplayNameCacheEntry cacheEntry = GetContactFullCacheEntry((HANDLE)wParam); WORD status; int NeedResort=0; char *szProto = cacheEntry->szProto; if(szProto==NULL) status=ID_STATUS_OFFLINE; else status=cacheEntry->status; shouldShow=(GetWindowLong(hwnd,GWL_STYLE)&CLS_SHOWHIDDEN || !cacheEntry->Hidden) && (!pcli->pfnIsHiddenMode(dat,status)||cacheEntry->noHiddenOffline || CallService(MS_CLIST_GETCONTACTICON,wParam,0)!=LOWORD(lParam)); //this means an offline msg is flashing, so the contact should be shown if(!FindItem(hwnd,dat,(HANDLE)wParam,&contact,&group,NULL)) { if(shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) { if(dat->selection>=0 && GetRowByIndex(dat,dat->selection,&selcontact,NULL)!=-1) hSelItem=pcli->pfnContactToHItem(selcontact); AddContactToTree(hwnd,dat,(HANDLE)wParam,0,0); NeedResort=1; recalcScrollBar=1; FindItem(hwnd,dat,(HANDLE)wParam,&contact,NULL,NULL); if (contact) { contact->iImage=(WORD)lParam; pcli->pfnNotifyNewContact(hwnd,(HANDLE)wParam); dat->NeedResort=1; } } } else { //item in list already DWORD style=GetWindowLong(hwnd,GWL_STYLE); if(contact->iImage== (WORD)lParam) break; if (sortByStatus) dat->NeedResort=1; if(!shouldShow && !(style&CLS_NOHIDEOFFLINE) && (style&CLS_HIDEOFFLINE || group->hideOffline)) { if(dat->selection>=0 && GetRowByIndex(dat,dat->selection,&selcontact,NULL)!=-1) hSelItem=pcli->pfnContactToHItem(selcontact); RemoveItemFromGroup(hwnd,group,contact,0); recalcScrollBar=1; dat->NeedResort=1; } else { int oldflags; contact->iImage=(WORD)lParam; oldflags=contact->flags; if(!pcli->pfnIsHiddenMode(dat,status)||cacheEntry->noHiddenOffline) contact->flags|=CONTACTF_ONLINE; else contact->flags&=~CONTACTF_ONLINE; if (oldflags!=contact->flags) dat->NeedResort=1; } } if(hSelItem) { struct ClcGroup *selgroup; if(FindItem(hwnd,dat,hSelItem,&selcontact,&selgroup,NULL)) dat->selection=GetRowsPriorTo(&dat->list,selgroup,li.List_IndexOf((SortedList*)&selgroup->cl, selcontact)); else dat->selection=-1; } SortClcByTimer(hwnd); if(recalcScrollBar) RecalcScrollBar(hwnd,dat); goto LBL_Exit; } case INTM_STATUSMSGCHANGED: { struct ClcContact *contact=NULL; struct ClcGroup *group=NULL; DBVARIANT dbv; if (!(dat->style&CLS_SHOWSTATUSMESSAGES)) break; if(FindItem(hwnd,dat,(HANDLE)wParam,&contact,&group,NULL) && contact!=NULL) { contact->flags &= ~CONTACTF_STATUSMSG; if (!DBGetContactSettingTString((HANDLE)wParam, "CList", "StatusMsg", &dbv)) { int j; if (dbv.ptszVal==NULL||_tcslen(dbv.ptszVal)==0) break; lstrcpyn(contact->szStatusMsg, dbv.ptszVal, SIZEOF(contact->szStatusMsg)); for (j=(int)_tcslen(contact->szStatusMsg)-1;j>=0;j--) { if (contact->szStatusMsg[j]=='\r' || contact->szStatusMsg[j]=='\n' || contact->szStatusMsg[j]=='\t') { contact->szStatusMsg[j] = ' '; } } DBFreeVariant(&dbv); if (_tcslen(contact->szStatusMsg)>0) { contact->flags |= CONTACTF_STATUSMSG; dat->NeedResort=TRUE; } } } InvalidateRect(hwnd,NULL,TRUE); SortClcByTimer(hwnd); RecalcScrollBar(hwnd,dat); goto LBL_Exit; } case WM_TIMER: if (wParam==TIMERID_DELAYEDREPAINT) { KillTimer(hwnd,TIMERID_DELAYEDREPAINT); InvalidateRect(hwnd,NULL,FALSE); break; } if ( wParam == TIMERID_SUBEXPAND) { KillTimer(hwnd,TIMERID_SUBEXPAND); if (hitcontact) { if (hitcontact->SubExpanded) hitcontact->SubExpanded=0; else hitcontact->SubExpanded=1; DBWriteContactSettingByte(hitcontact->hContact,"CList","Expanded",hitcontact->SubExpanded); } hitcontact=NULL; dat->NeedResort=1; SortCLC(hwnd,dat,1); RecalcScrollBar(hwnd,dat); break; } break; case WM_DESTROY: FreeDisplayNameCache(&dat->lCLCContactsCache); stopStatusUpdater = 1; break; } { LRESULT res = saveContactListControlWndProc(hwnd, msg, wParam, lParam); switch (msg) { case WM_CREATE: mir_forkthread(StatusUpdaterThread,0); break; } return res; } LBL_Exit: return DefWindowProc(hwnd, msg, wParam, lParam); }
static INT_PTR CALLBACK helpDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) { HELPDLGDATA *dat = (HELPDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch(msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); { hwndHelpDialog = hwndDlg; dat = (HELPDLGDATA*)mir_calloc(sizeof(HELPDLGDATA)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->vhs = (VARHELPINFO *)lParam; // set tabs int tabCount = 0; RECT rcTabs, rcParent; HWND hTab = GetDlgItem(hwndDlg, IDC_TABS); GetWindowRect(hTab, &rcTabs); GetWindowRect(hwndDlg, &rcParent); TCITEM tci = { 0 }; HWND hPage, hShow = 0; if (dat->vhs->flags&VHF_TOKENS) { // token tab tci.mask = TCIF_TEXT | TCIF_PARAM; tci.pszText = TranslateT("Tokens"); hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TOKENS_DIALOG), hwndDlg, tokenHelpDlgProc, (LPARAM)GetParent(hwndDlg)); EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); tci.lParam = (LPARAM)hPage; MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2 * iFrameX, (rcTabs.bottom - rcTabs.top) - 2 * iFrameY, TRUE); ShowWindow(hPage, SW_HIDE); TabCtrl_InsertItem(hTab, tabCount++, &tci); hShow = hShow == 0 ? hPage : hShow; } if (dat->vhs->flags&VHF_INPUT) { // input tab tci.mask = TCIF_TEXT | TCIF_PARAM; tci.pszText = TranslateT("Input"); dat->hwndInputDlg = hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_INPUT_DIALOG), hwndDlg, inputDlgProc, (LPARAM)GetParent(hwndDlg)); EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); tci.lParam = (LPARAM)hPage; MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2 * iFrameX, (rcTabs.bottom - rcTabs.top) - 2 * iFrameY, TRUE); ShowWindow(hPage, SW_HIDE); TabCtrl_InsertItem(hTab, tabCount++, &tci); hShow = hShow == 0 ? hPage : hShow; if ((dat->vhs->fi != NULL) && (dat->vhs->fi->szFormat != NULL)) { if (dat->vhs->fi->flags & FIF_UNICODE) SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)dat->vhs->fi->tszFormat); else { WCHAR *wszFormatString = mir_a2t(dat->vhs->fi->szFormat); SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)wszFormatString); mir_free(wszFormatString); } } else if (dat->vhs->hwndCtrl != NULL) { TCHAR *tszText = Hlp_GetWindowText(dat->vhs->hwndCtrl); if (tszText != NULL) { SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)tszText); mir_free(tszText); } } if (dat->vhs->fi != NULL || dat->vhs->hwndCtrl != NULL) { SetDlgItemText(hwndDlg, IDC_CANCEL, TranslateT("Cancel")); ShowWindow(GetDlgItem(hwndDlg, IDC_OK), SW_SHOW); } } if ((dat->vhs->flags&VHF_SUBJECT) || ((dat->vhs->flags&VHF_INPUT) && (((dat->vhs->fi != NULL) && (dat->vhs->fi->hContact != NULL)) || (dat->vhs->flags&VHF_SETLASTSUBJECT)))) { // subject window is created, but not necessarily shown dat->hwndSubjectDlg = hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CLIST_DIALOG), hwndDlg, clistDlgProc, (LPARAM)GetParent(hwndDlg)); EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2 * iFrameX, (rcTabs.bottom - rcTabs.top) - 2 * iFrameY, TRUE); ShowWindow(hPage, SW_HIDE); if ((dat->vhs->fi != NULL) && (dat->vhs->fi->hContact != NULL)) SendMessage(hwndDlg, VARM_SETSUBJECT, (WPARAM)dat->vhs->fi->hContact, 0); else if (dat->vhs->flags&VHF_SETLASTSUBJECT) SendMessage(hwndDlg, VARM_SETSUBJECT, (WPARAM)INVALID_HANDLE_VALUE, 0); if (dat->vhs->flags&VHF_SUBJECT) { // create subject tab tci.lParam = (LPARAM)hPage; tci.mask = TCIF_TEXT | TCIF_PARAM; tci.pszText = TranslateT("%subject%"); TabCtrl_InsertItem(hTab, tabCount++, &tci); hShow = hShow == 0 ? hPage : hShow; } } if ((dat->vhs->flags&VHF_EXTRATEXT) || ((dat->vhs->flags&VHF_INPUT) && (dat->vhs->fi != NULL) && (dat->vhs->fi->tszExtraText != NULL))) { // extratext window is created, but not necessarily shown dat->hwndExtraTextDlg = hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EXTRATEXT_DIALOG), hwndDlg, extratextDlgProc, (LPARAM)GetParent(hwndDlg)); EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2 * iFrameX, (rcTabs.bottom - rcTabs.top) - 2 * iFrameY, TRUE); ShowWindow(hPage, SW_HIDE); if ((dat->vhs->fi != NULL) && (dat->vhs->fi->tszExtraText != NULL)) { if (dat->vhs->fi->flags & FIF_UNICODE) SendMessage(hwndDlg, VARM_SETEXTRATEXT, 0, (LPARAM)dat->vhs->fi->tszExtraText); else { WCHAR *wszSource = mir_a2t(dat->vhs->fi->szExtraText); SendMessage(hwndDlg, VARM_SETEXTRATEXT, 0, (LPARAM)wszSource); mir_free(wszSource); } } if (dat->vhs->flags&VHF_EXTRATEXT) { // create extratext tab tci.mask = TCIF_TEXT | TCIF_PARAM; tci.pszText = TranslateT("%extratext%"); tci.lParam = (LPARAM)hPage; TabCtrl_InsertItem(hTab, tabCount++, &tci); hShow = hShow == 0 ? hPage : hShow; } } if (dat->vhs->flags&VHF_HELP) { // helpinfo tab tci.mask = TCIF_TEXT | TCIF_PARAM; tci.pszText = TranslateT("Help"); hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_HELPINFO_DIALOG), hwndDlg, helpInfoDlgProc, (LPARAM)GetParent(hwndDlg)); EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); tci.lParam = (LPARAM)hPage; MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2 * iFrameX, (rcTabs.bottom - rcTabs.top) - 2 * iFrameY, TRUE); ShowWindow(hPage, SW_HIDE); TabCtrl_InsertItem(hTab, tabCount++, &tci); hShow = hShow == 0 ? hPage : hShow; } Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, MODULENAME, "help"); SetWindowText(hwndDlg, TranslateT("Variables Help")); ShowWindow(hShow, SW_SHOW); break; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_OK: if ((dat->vhs->fi != NULL) && (!(dat->vhs->flags&VHF_DONTFILLSTRUCT))) { int len = SendMessage(hwndDlg, VARM_GETINPUTTEXTLENGTH, 0, 0); if (len > 0) { if ((dat->vhs->fi != NULL) && (!(dat->vhs->flags&VHF_DONTFILLSTRUCT))) { if (dat->vhs->fi->flags&FIF_UNICODE) { dat->vhs->fi->tszFormat = (TCHAR*)mir_calloc((len + 1)*sizeof(WCHAR)); SendMessage(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len + 1, (LPARAM)dat->vhs->fi->tszFormat); } else { dat->vhs->fi->szFormat = (char*)mir_calloc(len + 1); SendMessageA(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len + 1, (LPARAM)dat->vhs->fi->szFormat); } } } } if (dat->vhs->hwndCtrl != NULL) { int len = SendMessage(hwndDlg, VARM_GETINPUTTEXTLENGTH, 0, 0); if (len > 0) { TCHAR *tszText; tszText = (TCHAR*)mir_calloc((len + 1)*sizeof(TCHAR)); if (tszText != NULL) { SendMessage(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len + 1, (LPARAM)tszText); SetWindowText(dat->vhs->hwndCtrl, tszText); mir_free(tszText); } } SendMessage(GetParent(dat->vhs->hwndCtrl), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(dat->vhs->hwndCtrl), EN_CHANGE), (LPARAM)dat->vhs->hwndCtrl); } if ((dat->vhs->flags&VHF_FULLFILLSTRUCT) && (dat->vhs->fi != NULL)) { int len = SendMessage(hwndDlg, VARM_GETEXTRATEXTLENGTH, 0, 0); if (len > 0) { if (dat->vhs->fi->flags&FIF_UNICODE) { dat->vhs->fi->tszExtraText = (TCHAR*)mir_calloc((len + 1)*sizeof(WCHAR)); SendMessage(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len + 1, (LPARAM)dat->vhs->fi->tszExtraText); } else { dat->vhs->fi->szExtraText = (char*)mir_calloc(len + 1); SendMessageA(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len + 1, (LPARAM)dat->vhs->fi->szExtraText); } } dat->vhs->fi->hContact = (MCONTACT)SendMessage(hwndDlg, VARM_GETSUBJECT, 0, 0); } // fall through case IDC_CANCEL: if (GetParent(hwndDlg) == NULL) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, 0); break; } break; case VARM_SETSUBJECT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndSubjectDlg, VARM_SETSUBJECT, wParam, lParam)); return TRUE; case VARM_GETSUBJECT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndSubjectDlg, VARM_GETSUBJECT, wParam, lParam)); return TRUE; case VARM_SETEXTRATEXT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndExtraTextDlg, VARM_SETEXTRATEXT, wParam, lParam)); return TRUE; case VARM_GETEXTRATEXTLENGTH: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndExtraTextDlg, VARM_GETEXTRATEXTLENGTH, wParam, lParam)); return TRUE; case VARM_GETEXTRATEXT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndExtraTextDlg, VARM_GETEXTRATEXT, wParam, lParam)); return TRUE; case VARM_SETINPUTTEXT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndInputDlg, VARM_SETINPUTTEXT, wParam, lParam)); return TRUE; case VARM_GETINPUTTEXTLENGTH: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndInputDlg, VARM_GETINPUTTEXTLENGTH, wParam, lParam)); return TRUE; case VARM_GETINPUTTEXT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendMessage(dat->hwndInputDlg, VARM_GETINPUTTEXT, wParam, lParam)); return TRUE; case VARM_GETDIALOG: switch (wParam) { case VHF_INPUT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)dat->hwndInputDlg); return TRUE; } break; case WM_GETMINMAXINFO: { int i, count; TCITEM tci; RECT rcParent; HWND hTab; MINMAXINFO pageMinMax; GetWindowRect(hwndDlg, &rcParent); // defaults ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 400; ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 400; hTab = GetDlgItem(hwndDlg, IDC_TABS); tci.mask = TCIF_PARAM; count = TabCtrl_GetItemCount(hTab); // return the largest of all pages for (i = 0; i < count; i++) { TabCtrl_GetItem(hTab, i, &tci); memset(&pageMinMax, 0, sizeof(pageMinMax)); SendMessage((HWND)tci.lParam, WM_GETMINMAXINFO, wParam, (LPARAM)&pageMinMax); ((MINMAXINFO*)lParam)->ptMinTrackSize.x = max(((MINMAXINFO*)lParam)->ptMinTrackSize.x, pageMinMax.ptMinTrackSize.x); ((MINMAXINFO*)lParam)->ptMinTrackSize.y = max(((MINMAXINFO*)lParam)->ptMinTrackSize.y, pageMinMax.ptMinTrackSize.y); } } break; case WM_SIZE: if (!IsIconic(hwndDlg)) { UTILRESIZEDIALOG urd = { 0 }; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lParam = 0; // ! uses ANSI version ! urd.lpTemplate = MAKEINTRESOURCEA(IDD_HELP_DIALOG); urd.pfnResizer = helpDialogResize; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); SendMessage(hwndDlg, WM_MOVE, 0, 0); RECT rcTabs, rcParent; HWND hTab = GetDlgItem(hwndDlg, IDC_TABS); GetWindowRect(hTab, &rcTabs); GetWindowRect(hwndDlg, &rcParent); TCITEM tci; tci.mask = TCIF_PARAM; int count = TabCtrl_GetItemCount(hTab); for (int i = 0; i < count; i++) { TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), i, &tci); MoveWindow((HWND)tci.lParam, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2 * iFrameX, (rcTabs.bottom - rcTabs.top) - 2 * iFrameY, TRUE); } } break; case WM_NOTIFY: if ((((NMHDR*)lParam)->idFrom == IDC_TABS)) { if (((NMHDR*)lParam)->code == TCN_SELCHANGING) { TCITEM tci; tci.mask = TCIF_PARAM; TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS)), &tci); ShowWindow((HWND)tci.lParam, SW_HIDE); } else if (((NMHDR*)lParam)->code == TCN_SELCHANGE) { TCITEM tci; tci.mask = TCIF_PARAM; TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS)), &tci); ShowWindow((HWND)tci.lParam, SW_SHOW); } } break; case WM_CLOSE: if (GetParent(hwndDlg) == NULL) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, 0); break; case WM_DESTROY: Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, "help"); HWND hTab = GetDlgItem(hwndDlg, IDC_TABS); TCITEM tci; tci.mask = TCIF_PARAM; int count = TabCtrl_GetItemCount(hTab); for (int i = 0; i < count; i++) { TabCtrl_GetItem(hTab, i, &tci); if (((HWND)tci.lParam != dat->hwndSubjectDlg) && ((HWND)tci.lParam != dat->hwndExtraTextDlg)) DestroyWindow((HWND)tci.lParam); } // these windows might have been created, but not inserted as tabs if (IsWindow(dat->hwndSubjectDlg)) DestroyWindow(dat->hwndSubjectDlg); if (IsWindow(dat->hwndExtraTextDlg)) DestroyWindow(dat->hwndExtraTextDlg); mir_free(dat); dat = NULL; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; } return FALSE; }
static INT_PTR CALLBACK inputDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) { static INPUTDLGDATA *dat = (INPUTDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); processTokenListMessage(hwndDlg, msg, wParam, lParam); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); dat = (INPUTDLGDATA*)mir_alloc(sizeof(INPUTDLGDATA)); memset(dat, 0, sizeof(INPUTDLGDATA)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); // splitter things dat->splitterPos = (INT_PTR)db_get_dw(NULL, MODULENAME, SETTING_SPLITTERPOS, -1); { RECT rc; POINT pt; GetWindowRect(GetDlgItem(hwndDlg, IDC_SPLITTER), &rc); pt.y = (rc.top + rc.bottom) / 2; pt.x = 0; ScreenToClient(hwndDlg, &pt); dat->originalSplitterPos = pt.y; if (dat->splitterPos == -1) dat->splitterPos = dat->originalSplitterPos; GetWindowRect(GetDlgItem(hwndDlg, IDC_SHOWHELP), &rc); mir_subclassWindow(GetDlgItem(hwndDlg, IDC_SPLITTER), SplitterSubclassProc); GetWindowRect(GetDlgItem(hwndDlg, IDC_TESTSTRING), &rc); dat->minInputSize.x = rc.right - rc.left; dat->minInputSize.y = rc.bottom - rc.top; GetWindowRect(GetDlgItem(hwndDlg, IDC_RESULT), &rc); dat->minResultSize.x = rc.right - rc.left; dat->minResultSize.y = rc.bottom - rc.top; } dat->hwndHelpDlg = GetParent(hwndDlg); SendMessage(hwndDlg, VARM_PARSE, 0, 0); SetTimer(hwndDlg, IDT_PARSE, 1000, NULL); SetFocus(GetDlgItem(hwndDlg, IDC_TESTSTRING)); break; case DM_SPLITTERMOVED: { POINT pt; RECT rc, rcTeststring, rcResult; int oldSplitterY; if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SPLITTER)) { GetClientRect(hwndDlg, &rc); pt.x = 0; pt.y = wParam; ScreenToClient(hwndDlg, &pt); oldSplitterY = dat->splitterPos; dat->splitterPos = rc.bottom - pt.y + 223; GetWindowRect(GetDlgItem(hwndDlg, IDC_TESTSTRING), &rcTeststring); GetWindowRect(GetDlgItem(hwndDlg, IDC_RESULT), &rcResult); if ((((rcTeststring.bottom - rcTeststring.top) - (dat->splitterPos - oldSplitterY)) < dat->minInputSize.y) || (((rcResult.bottom - rcResult.top) + (dat->splitterPos - oldSplitterY)) < dat->minResultSize.y)) dat->splitterPos = oldSplitterY; } } SendMessage(hwndDlg, WM_SIZE, 0, 0); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_TESTSTRING: if (HIWORD(wParam) == EN_CHANGE) SendMessage(hwndDlg, VARM_PARSE, 0, 0); break; } break; case WM_GETMINMAXINFO: { RECT rc, rcTeststring; GetWindowRect(GetParent(hwndDlg), &rc); GetWindowRect(GetDlgItem(hwndDlg, IDC_TESTSTRING), &rcTeststring); ((MINMAXINFO*)lParam)->ptMinTrackSize.y = (rc.bottom - rc.top) - (((rcTeststring.bottom - rcTeststring.top) - dat->minResultSize.y)); } break; case WM_SIZE: if (!IsIconic(hwndDlg)) { UTILRESIZEDIALOG urd = { 0 }; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lParam = (LPARAM)dat; urd.lpTemplate = MAKEINTRESOURCEA(IDD_INPUT_DIALOG); urd.pfnResizer = inputDialogResize; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); } SendMessage(hwndDlg, WM_MOVE, 0, 0); break; case WM_SHOWWINDOW: if (wParam) SendMessage(hwndDlg, VARM_PARSE, 0, 0); break; case WM_NOTIFY: break; case VARM_PARSE: { TCHAR *string = Hlp_GetDlgItemText(hwndDlg, IDC_TESTSTRING), *extraText; int len = SendMessage(GetParent(hwndDlg), VARM_GETEXTRATEXTLENGTH, 0, 0); if (len > 0) { extraText = (TCHAR*)mir_calloc((len + 1)* sizeof(TCHAR)); SendMessage(GetParent(hwndDlg), VARM_GETEXTRATEXT, (WPARAM)len + 1, (LPARAM)extraText); } else extraText = NULL; if (string != NULL) { TCHAR *newString = variables_parsedup(string, extraText, (MCONTACT)SendMessage(GetParent(hwndDlg), VARM_GETSUBJECT, 0, 0)); if (newString != NULL) { TCHAR *oldString = Hlp_GetDlgItemText(hwndDlg, IDC_RESULT); if (oldString == NULL || _tcscmp(oldString, newString)) SetDlgItemText(hwndDlg, IDC_RESULT, newString); mir_free(newString); if (oldString != NULL) mir_free(oldString); } mir_free(string); } } break; case VARM_SETINPUTTEXT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendDlgItemMessage(hwndDlg, IDC_TESTSTRING, WM_SETTEXT, wParam, lParam)); return TRUE; case VARM_GETINPUTTEXTLENGTH: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SendDlgItemMessage(hwndDlg, IDC_TESTSTRING, WM_GETTEXTLENGTH, wParam, lParam)); return TRUE; case VARM_GETINPUTTEXT: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, GetDlgItemText(hwndDlg, IDC_TESTSTRING, (LPWSTR)lParam, wParam)); return TRUE; case WM_TIMER: SendMessage(hwndDlg, VARM_PARSE, 0, 0); break; case WM_DESTROY: KillTimer(hwndDlg, IDT_PARSE); if (dat == NULL) break; db_set_dw(NULL, MODULENAME, SETTING_SPLITTERPOS, dat->splitterPos); mir_free(dat); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; } return FALSE; }
INT_PTR CALLBACK DlgProcFileTransfer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { FileDlgData *dat = (FileDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); dat = (FileDlgData*)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hNotifyEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_RECVEVENT); dat->transferStatus.currentFileNumber = -1; if (dat->send) { if (db_mc_isMeta(dat->hContact)) dat->hContact = db_mc_getMostOnline(dat->hContact); dat->fs = (HANDLE)CallContactService(dat->hContact, PSS_FILE, (WPARAM)dat->szMsg, (LPARAM)dat->files); SetFtStatus(hwndDlg, LPGENT("Request sent, waiting for acceptance..."), FTS_TEXT); SetOpenFileButtonStyle(GetDlgItem(hwndDlg, IDC_OPENFILE), 1); dat->waitingForAcceptance = 1; // hide "open" button since it may cause potential access violations... ShowWindow(GetDlgItem(hwndDlg, IDC_OPENFILE), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_OPENFOLDER), SW_HIDE); } else { //recv CreateDirectoryTreeT(dat->szSavePath); dat->fs = (HANDLE)CallContactService(dat->hContact, PSS_FILEALLOW, (WPARAM)dat->fs, (LPARAM)dat->szSavePath); dat->transferStatus.tszWorkingDir = mir_tstrdup(dat->szSavePath); if (db_get_b(dat->hContact, "CList", "NotOnList", 0)) dat->resumeBehaviour = FILERESUME_ASK; else dat->resumeBehaviour = db_get_b(NULL, "SRFile", "IfExists", FILERESUME_ASK); SetFtStatus(hwndDlg, LPGENT("Waiting for connection..."), FTS_TEXT); } /* check we actually got an fs handle back from the protocol */ if (!dat->fs) { SetFtStatus(hwndDlg, LPGENT("Unable to initiate transfer."), FTS_TEXT); dat->waitingForAcceptance = 0; } { LOGFONT lf; HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CONTACTNAME, WM_GETFONT, 0, 0); GetObject(hFont, sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_CONTACTNAME, WM_SETFONT, (WPARAM)hFont, 0); SHFILEINFO shfi = { 0 }; SHGetFileInfo(_T(""), FILE_ATTRIBUTE_DIRECTORY, &shfi, sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_ICON | SHGFI_SMALLICON); dat->hIconFolder = shfi.hIcon; } dat->hIcon = NULL; { char *szProto = GetContactProto(dat->hContact); WORD status = db_get_w(dat->hContact, szProto, "Status", ID_STATUS_ONLINE); SendDlgItemMessage(hwndDlg, IDC_CONTACT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_LoadProtoIcon(szProto, status)); } SendDlgItemMessage(hwndDlg, IDC_CONTACT, BUTTONADDTOOLTIP, (WPARAM)LPGEN("Contact menu"), 0); SendDlgItemMessage(hwndDlg, IDC_CONTACT, BUTTONSETASFLATBTN, TRUE, 0); Button_SetIcon_IcoLib(hwndDlg, IDC_OPENFILE, SKINICON_OTHER_DOWNARROW, LPGEN("Open...")); SendDlgItemMessage(hwndDlg, IDC_OPENFILE, BUTTONSETASPUSHBTN, TRUE, 0); SendDlgItemMessage(hwndDlg, IDC_OPENFOLDER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)dat->hIconFolder); SendDlgItemMessage(hwndDlg, IDC_OPENFOLDER, BUTTONADDTOOLTIP, (WPARAM)LPGEN("Open folder"), 0); SendDlgItemMessage(hwndDlg, IDC_OPENFOLDER, BUTTONSETASFLATBTN, TRUE, 0); Button_SetIcon_IcoLib(hwndDlg, IDCANCEL, SKINICON_OTHER_DELETE, LPGEN("Cancel")); SetDlgItemText(hwndDlg, IDC_CONTACTNAME, pcli->pfnGetContactDisplayName(dat->hContact, 0)); if (!dat->waitingForAcceptance) SetTimer(hwndDlg, 1, 1000, NULL); return TRUE; case WM_TIMER: memmove(dat->bytesRecvedHistory + 1, dat->bytesRecvedHistory, sizeof(dat->bytesRecvedHistory) - sizeof(dat->bytesRecvedHistory[0])); dat->bytesRecvedHistory[0] = dat->transferStatus.totalProgress; if (dat->bytesRecvedHistorySize < _countof(dat->bytesRecvedHistory)) dat->bytesRecvedHistorySize++; { TCHAR szSpeed[32], szTime[32], szDisplay[96]; SYSTEMTIME st; ULARGE_INTEGER li; FILETIME ft; GetSensiblyFormattedSize((dat->bytesRecvedHistory[0] - dat->bytesRecvedHistory[dat->bytesRecvedHistorySize - 1]) / dat->bytesRecvedHistorySize, szSpeed, _countof(szSpeed), 0, 1, NULL); if (dat->bytesRecvedHistory[0] == dat->bytesRecvedHistory[dat->bytesRecvedHistorySize - 1]) mir_tstrcpy(szTime, _T("??:??:??")); else { li.QuadPart = BIGI(10000000)*(dat->transferStatus.currentFileSize - dat->transferStatus.currentFileProgress)*dat->bytesRecvedHistorySize / (dat->bytesRecvedHistory[0] - dat->bytesRecvedHistory[dat->bytesRecvedHistorySize - 1]); ft.dwHighDateTime = li.HighPart; ft.dwLowDateTime = li.LowPart; FileTimeToSystemTime(&ft, &st); GetTimeFormat(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, &st, NULL, szTime, _countof(szTime)); } if (dat->bytesRecvedHistory[0] != dat->bytesRecvedHistory[dat->bytesRecvedHistorySize - 1]) { li.QuadPart = BIGI(10000000)*(dat->transferStatus.totalBytes - dat->transferStatus.totalProgress)*dat->bytesRecvedHistorySize / (dat->bytesRecvedHistory[0] - dat->bytesRecvedHistory[dat->bytesRecvedHistorySize - 1]); ft.dwHighDateTime = li.HighPart; ft.dwLowDateTime = li.LowPart; FileTimeToSystemTime(&ft, &st); GetTimeFormat(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, &st, NULL, szTime, _countof(szTime)); } mir_sntprintf(szDisplay, _T("%s/%s (%s %s)"), szSpeed, TranslateT("sec"), szTime, TranslateT("remaining")); SetDlgItemText(hwndDlg, IDC_ALLSPEED, szDisplay); } break; case WM_MEASUREITEM: return Menu_MeasureItem((LPMEASUREITEMSTRUCT)lParam); case WM_DRAWITEM: return Menu_DrawItem((LPDRAWITEMSTRUCT)lParam); case WM_FT_CLEANUP: if (!dat->fs) { PostMessage(GetParent(hwndDlg), WM_FT_REMOVE, 0, (LPARAM)hwndDlg); DestroyWindow(hwndDlg); } break; case WM_COMMAND: if (!dat) break; if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)) break; switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: PostMessage(GetParent(hwndDlg), WM_FT_REMOVE, 0, (LPARAM)hwndDlg); DestroyWindow(hwndDlg); break; case IDC_CONTACT: { RECT rc; HMENU hMenu = Menu_BuildContactMenu(dat->hContact); GetWindowRect((HWND)lParam, &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; case IDC_TRANSFERCOMPLETED: if (dat->transferStatus.currentFileNumber <= 1 && CheckVirusScanned(hwndDlg, dat, 0)) { ShellExecute(NULL, NULL, dat->files[0], NULL, NULL, SW_SHOW); break; } case IDC_OPENFOLDER: { TCHAR *path = dat->transferStatus.tszWorkingDir; if (!path || !path[0]) { path = NEWTSTR_ALLOCA(dat->transferStatus.tszCurrentFile); TCHAR *p = _tcsrchr(path, '\\'); if (p) *p = 0; } if (path) ShellExecute(NULL, _T("open"), path, NULL, NULL, SW_SHOW); } break; case IDC_OPENFILE: TCHAR **files; if (dat->send) { if (dat->files == NULL) files = dat->transferStatus.ptszFiles; else files = dat->files; } else files = dat->files; HMENU hMenu = CreatePopupMenu(); AppendMenu(hMenu, MF_STRING, 1, TranslateT("Open folder")); AppendMenu(hMenu, MF_SEPARATOR, 0, 0); if (files && *files) { int limit; TCHAR *pszFilename, *pszNewFileName; if (dat->send) limit = dat->transferStatus.totalFiles; else limit = dat->transferStatus.currentFileNumber; // Loop over all transfered files and add them to the menu for (int i = 0; i < limit; i++) { pszFilename = _tcsrchr(files[i], '\\'); if (pszFilename == NULL) pszFilename = files[i]; else pszFilename++; if (pszFilename) { size_t cbFileNameLen = mir_tstrlen(pszFilename); pszNewFileName = (TCHAR*)mir_alloc(cbFileNameLen * 2 * sizeof(TCHAR)); TCHAR *p = pszNewFileName; for (size_t pszlen = 0; pszlen < cbFileNameLen; pszlen++) { *p++ = pszFilename[pszlen]; if (pszFilename[pszlen] == '&') *p++ = '&'; } *p = '\0'; AppendMenu(hMenu, MF_STRING, i + 10, pszNewFileName); mir_free(pszNewFileName); } } } RECT rc; GetWindowRect((HWND)lParam, &rc); CheckDlgButton(hwndDlg, IDC_OPENFILE, BST_CHECKED); int ret = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_RIGHTALIGN, rc.right, rc.bottom, 0, hwndDlg, NULL); CheckDlgButton(hwndDlg, IDC_OPENFILE, BST_UNCHECKED); DestroyMenu(hMenu); if (ret == 1) { TCHAR *path = dat->transferStatus.tszWorkingDir; if (!path || !path[0]) { path = NEWTSTR_ALLOCA(dat->transferStatus.tszCurrentFile); TCHAR *p = _tcsrchr(path, '\\'); if (p) *p = 0; } if (path) ShellExecute(NULL, _T("open"), path, NULL, NULL, SW_SHOW); } else if (ret && CheckVirusScanned(hwndDlg, dat, ret)) ShellExecute(NULL, NULL, files[ret - 10], NULL, NULL, SW_SHOW); } break; case M_FILEEXISTSDLGREPLY: EnableWindow(hwndDlg, TRUE); { PROTOFILERESUME *pfr = (PROTOFILERESUME*)lParam; TCHAR *szOriginalFilename = (TCHAR*)wParam; char *szProto = GetContactProto(dat->hContact); switch (pfr->action) { case FILERESUME_CANCEL: if (dat->fs) CallContactService(dat->hContact, PSS_FILECANCEL, (WPARAM)dat->fs, 0); dat->fs = NULL; mir_free(szOriginalFilename); if (pfr->szFilename) mir_free((char*)pfr->szFilename); mir_free(pfr); return 0; case FILERESUME_RESUMEALL: case FILERESUME_OVERWRITEALL: dat->resumeBehaviour = pfr->action; pfr->action &= ~FILERESUMEF_ALL; break; case FILERESUME_RENAMEALL: pfr->action = FILERESUME_RENAME; { TCHAR *pszExtension, *pszFilename; if ((pszFilename = _tcsrchr(szOriginalFilename, '\\')) == NULL) pszFilename = szOriginalFilename; if ((pszExtension = _tcsrchr(pszFilename + 1, '.')) == NULL) pszExtension = pszFilename + mir_tstrlen(pszFilename); if (pfr->szFilename) mir_free((TCHAR*)pfr->szFilename); size_t size = (pszExtension - szOriginalFilename) + 21 + mir_tstrlen(pszExtension); pfr->szFilename = (TCHAR*)mir_alloc(sizeof(TCHAR)*size); for (int i = 1;; i++) { mir_sntprintf((TCHAR*)pfr->szFilename, size, _T("%.*s (%u)%s"), pszExtension - szOriginalFilename, szOriginalFilename, i, pszExtension); if (_taccess(pfr->szFilename, 0) != 0) break; } } break; } mir_free(szOriginalFilename); CallProtoService(szProto, PS_FILERESUME, (WPARAM)dat->fs, (LPARAM)pfr); if (pfr->szFilename) mir_free((char*)pfr->szFilename); mir_free(pfr); } break; case HM_RECVEVENT: { ACKDATA *ack = (ACKDATA*)lParam; if (ack->hProcess != dat->fs) break; if (ack->type != ACKTYPE_FILE) break; if (ack->hContact != dat->hContact) break; if (dat->waitingForAcceptance) { SetTimer(hwndDlg, 1, 1000, NULL); dat->waitingForAcceptance = 0; } switch (ack->result) { case ACKRESULT_SENTREQUEST: SetFtStatus(hwndDlg, LPGENT("Decision sent"), FTS_TEXT); break; case ACKRESULT_CONNECTING: SetFtStatus(hwndDlg, LPGENT("Connecting..."), FTS_TEXT); break; case ACKRESULT_CONNECTPROXY: SetFtStatus(hwndDlg, LPGENT("Connecting to proxy..."), FTS_TEXT); break; case ACKRESULT_CONNECTED: SetFtStatus(hwndDlg, LPGENT("Connected"), FTS_TEXT); break; case ACKRESULT_LISTENING: SetFtStatus(hwndDlg, LPGENT("Waiting for connection..."), FTS_TEXT); break; case ACKRESULT_INITIALISING: SetFtStatus(hwndDlg, LPGENT("Initializing..."), FTS_TEXT); break; case ACKRESULT_NEXTFILE: SetFtStatus(hwndDlg, LPGENT("Moving to next file..."), FTS_TEXT); SetDlgItemTextA(hwndDlg, IDC_FILENAME, ""); if (dat->transferStatus.currentFileNumber == 1 && dat->transferStatus.totalFiles > 1 && !dat->send) SetOpenFileButtonStyle(GetDlgItem(hwndDlg, IDC_OPENFILE), 1); if (dat->transferStatus.currentFileNumber != -1 && dat->files && !dat->send && db_get_b(NULL, "SRFile", "UseScanner", VIRUSSCAN_DISABLE) == VIRUSSCAN_DURINGDL) { if (GetFileAttributes(dat->files[dat->transferStatus.currentFileNumber])&FILE_ATTRIBUTE_DIRECTORY) PostMessage(hwndDlg, M_VIRUSSCANDONE, dat->transferStatus.currentFileNumber, 0); else { virusscanthreadstartinfo *vstsi; vstsi = (struct virusscanthreadstartinfo*)mir_alloc(sizeof(struct virusscanthreadstartinfo)); vstsi->hwndReply = hwndDlg; vstsi->szFile = mir_tstrdup(dat->files[dat->transferStatus.currentFileNumber]); vstsi->returnCode = dat->transferStatus.currentFileNumber; forkthread((void(*)(void*))RunVirusScannerThread, 0, vstsi); } } break; case ACKRESULT_FILERESUME: UpdateProtoFileTransferStatus(&dat->transferStatus, (PROTOFILETRANSFERSTATUS*)ack->lParam); { PROTOFILETRANSFERSTATUS *fts = &dat->transferStatus; SetFilenameControls(hwndDlg, dat, fts); if (_taccess(fts->tszCurrentFile, 0)) break; SetFtStatus(hwndDlg, LPGENT("File already exists"), FTS_TEXT); if (dat->resumeBehaviour == FILERESUME_ASK) { TDlgProcFileExistsParam param = { hwndDlg, fts }; ShowWindow(hwndDlg, SW_SHOWNORMAL); CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_FILEEXISTS), hwndDlg, DlgProcFileExists, (LPARAM)¶m); EnableWindow(hwndDlg, FALSE); } else { PROTOFILERESUME *pfr = (PROTOFILERESUME*)mir_alloc(sizeof(PROTOFILERESUME)); pfr->action = dat->resumeBehaviour; pfr->szFilename = NULL; PostMessage(hwndDlg, M_FILEEXISTSDLGREPLY, (WPARAM)mir_tstrdup(fts->tszCurrentFile), (LPARAM)pfr); } } SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 1); return TRUE; case ACKRESULT_DATA: { PROTOFILETRANSFERSTATUS *fts = (PROTOFILETRANSFERSTATUS*)ack->lParam; TCHAR str[64], str2[64], szSizeDone[32], szSizeTotal[32];//, *contactName; if (dat->fileVirusScanned == NULL) dat->fileVirusScanned = (int*)mir_calloc(sizeof(int) * fts->totalFiles); // This needs to be here - otherwise we get holes in the files array if (!dat->send) { if (dat->files == NULL) dat->files = (TCHAR**)mir_calloc((fts->totalFiles + 1) * sizeof(TCHAR*)); if (fts->currentFileNumber < fts->totalFiles && dat->files[fts->currentFileNumber] == NULL) dat->files[fts->currentFileNumber] = PFTS_StringToTchar(fts->flags, fts->tszCurrentFile); } /* HACK: for 0.3.3, limit updates to around 1.1 ack per second */ if (fts->totalProgress != fts->totalBytes && GetTickCount() < (dat->dwTicks + 650)) break; // the last update was less than a second ago! dat->dwTicks = GetTickCount(); // Update local transfer status with data from protocol UpdateProtoFileTransferStatus(&dat->transferStatus, fts); fts = &dat->transferStatus; bool firstTime = false; if ((GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ALLFILESPROGRESS), GWL_STYLE) & WS_VISIBLE) == 0) { SetFtStatus(hwndDlg, (fts->flags & PFTS_SENDING) ? LPGENT("Sending...") : LPGENT("Receiving..."), FTS_PROGRESS); SetFilenameControls(hwndDlg, dat, fts); firstTime = true; } const unsigned long lastPos = SendDlgItemMessage(hwndDlg, IDC_ALLFILESPROGRESS, PBM_GETPOS, 0, 0); const unsigned long nextPos = fts->totalBytes ? (BIGI(100) * fts->totalProgress / fts->totalBytes) : 0; if (lastPos != nextPos || firstTime) { SendDlgItemMessage(hwndDlg, IDC_ALLFILESPROGRESS, PBM_SETPOS, nextPos, 0); mir_sntprintf(str, _T("%u%%"), nextPos); SetDlgItemText(hwndDlg, IDC_ALLPRECENTS, str); } int units; GetSensiblyFormattedSize(fts->totalBytes, szSizeTotal, _countof(szSizeTotal), 0, 1, &units); GetSensiblyFormattedSize(fts->totalProgress, szSizeDone, _countof(szSizeDone), units, 0, NULL); mir_sntprintf(str, _T("%s/%s"), szSizeDone, szSizeTotal); str2[0] = 0; GetDlgItemText(hwndDlg, IDC_ALLTRANSFERRED, str2, _countof(str2)); if (mir_tstrcmp(str, str2)) SetDlgItemText(hwndDlg, IDC_ALLTRANSFERRED, str); } break; case ACKRESULT_SUCCESS: case ACKRESULT_FAILED: case ACKRESULT_DENIED: HideProgressControls(hwndDlg); KillTimer(hwndDlg, 1); if (!dat->send) SetOpenFileButtonStyle(GetDlgItem(hwndDlg, IDC_OPENFILE), 1); SetDlgItemText(hwndDlg, IDCANCEL, TranslateT("Close")); if (dat->hNotifyEvent) UnhookEvent(dat->hNotifyEvent); dat->hNotifyEvent = NULL; if (ack->result == ACKRESULT_DENIED) { dat->fs = NULL; /* protocol will free structure */ SkinPlaySound("FileDenied"); SetFtStatus(hwndDlg, LPGENT("File transfer denied"), FTS_TEXT); } else if (ack->result == ACKRESULT_FAILED) { dat->fs = NULL; /* protocol will free structure */ SkinPlaySound("FileFailed"); SetFtStatus(hwndDlg, LPGENT("File transfer failed"), FTS_TEXT); } else { SkinPlaySound("FileDone"); if (dat->send) { dat->fs = NULL; /* protocol will free structure */ SetFtStatus(hwndDlg, LPGENT("Transfer completed."), FTS_TEXT); DBEVENTINFO dbei = { 0 }; FillSendData(dat, dbei); db_event_add(dat->hContact, &dbei); if (dbei.pBlob) mir_free(dbei.pBlob); dat->files = NULL; //protocol library frees this } else { SetFtStatus(hwndDlg, (dat->transferStatus.totalFiles == 1) ? LPGENT("Transfer completed, open file.") : LPGENT("Transfer completed, open folder."), FTS_OPEN); int useScanner = db_get_b(NULL, "SRFile", "UseScanner", VIRUSSCAN_DISABLE); if (useScanner != VIRUSSCAN_DISABLE) { struct virusscanthreadstartinfo *vstsi; vstsi = (struct virusscanthreadstartinfo*)mir_alloc(sizeof(struct virusscanthreadstartinfo)); vstsi->hwndReply = hwndDlg; if (useScanner == VIRUSSCAN_DURINGDL) { vstsi->returnCode = dat->transferStatus.currentFileNumber; if (GetFileAttributes(dat->files[dat->transferStatus.currentFileNumber])&FILE_ATTRIBUTE_DIRECTORY) { PostMessage(hwndDlg, M_VIRUSSCANDONE, vstsi->returnCode, 0); mir_free(vstsi); vstsi = NULL; } else vstsi->szFile = mir_tstrdup(dat->files[dat->transferStatus.currentFileNumber]); } else { vstsi->szFile = mir_tstrdup(dat->transferStatus.tszWorkingDir); vstsi->returnCode = -1; } SetFtStatus(hwndDlg, LPGENT("Scanning for viruses..."), FTS_TEXT); if (vstsi) forkthread((void(*)(void*))RunVirusScannerThread, 0, vstsi); } else dat->fs = NULL; /* protocol will free structure */ dat->transferStatus.currentFileNumber = dat->transferStatus.totalFiles; } // else dat->send } // else ack->result PostMessage(GetParent(hwndDlg), WM_FT_COMPLETED, ack->result, (LPARAM)hwndDlg); break; } // switch ack->result } // case HM_RECVEVENT break; case M_VIRUSSCANDONE: { int done = 1; if ((int)wParam == -1) { for (int i = 0; i < dat->transferStatus.totalFiles; i++) dat->fileVirusScanned[i] = 1; } else { dat->fileVirusScanned[wParam] = 1; for (int i = 0; i < dat->transferStatus.totalFiles; i++) if (!dat->fileVirusScanned[i]) { done = 0; break; } } if (done) { dat->fs = NULL; /* protocol will free structure */ SetFtStatus(hwndDlg, LPGENT("Transfer and virus scan complete"), FTS_TEXT); } } break; case WM_SIZE: Utils_ResizeDialog(hwndDlg, hInst, MAKEINTRESOURCEA(IDD_FILETRANSFERINFO), FileTransferDlgResizer); RedrawWindow(GetDlgItem(hwndDlg, IDC_ALLTRANSFERRED), NULL, NULL, RDW_INVALIDATE | RDW_NOERASE); RedrawWindow(GetDlgItem(hwndDlg, IDC_ALLSPEED), NULL, NULL, RDW_INVALIDATE | RDW_NOERASE); RedrawWindow(GetDlgItem(hwndDlg, IDC_CONTACTNAME), NULL, NULL, RDW_INVALIDATE | RDW_NOERASE); RedrawWindow(GetDlgItem(hwndDlg, IDC_STATUS), NULL, NULL, RDW_INVALIDATE | RDW_NOERASE); break; case WM_DESTROY: KillTimer(hwndDlg, 1); HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_CONTACTNAME, WM_GETFONT, 0, 0); DeleteObject(hFont); Button_FreeIcon_IcoLib(hwndDlg, IDC_CONTACT); Button_FreeIcon_IcoLib(hwndDlg, IDC_OPENFILE); Button_FreeIcon_IcoLib(hwndDlg, IDCANCEL); FreeFileDlgData(dat); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; } return FALSE; }
INT_PTR CALLBACK FindWindowDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwnd); SendMessage(GetDlgItem(hwnd, IDC_SBAR), SB_SETTEXT, 0, (LPARAM)Translate("Enter a string to search the database for")); CheckDlgButton(hwnd, IDC_MODNAME, 1); CheckDlgButton(hwnd, IDC_SETTINGNAME, 1); CheckDlgButton(hwnd, IDC_SETTINGVALUE, 1); CheckDlgButton(hwnd, IDC_FOUND, 1); SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGEDIT))); SetWindowLongPtr(GetDlgItem(hwnd, IDC_REPLACE), GWLP_USERDATA, 0); SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 0); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: SetWindowLongPtr(GetDlgItem(hwnd, IDC_REPLACE), GWLP_USERDATA, 1); case IDC_SEARCH: if (GetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA)) // stop the search SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 0); else { char text[256]; char replace[256] = ""; if (!GetDlgItemText(hwnd, IDC_TEXT, text, SIZEOF(text))) break; if (GetWindowLongPtr(GetDlgItem(hwnd, IDC_REPLACE), GWLP_USERDATA) && !GetDlgItemText(hwnd, IDC_REPLACE, replace, SIZEOF(replace)) && !IsDlgButtonChecked(hwnd, IDC_ENTIRELY)) break; if (!IsDlgButtonChecked(hwnd, IDC_MODNAME) && !IsDlgButtonChecked(hwnd, IDC_SETTINGNAME) && !IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE)) break; FindInfo *fi = (FindInfo*)mir_calloc(sizeof(FindInfo)); if (!fi) break; fi->hwnd = GetDlgItem(hwnd, IDC_LIST); fi->options = (IsDlgButtonChecked(hwnd, IDC_CASESENSITIVE) ? FW_CASE : 0) | (IsDlgButtonChecked(hwnd, IDC_EXACT) ? FW_EXACT : 0) | (IsDlgButtonChecked(hwnd, IDC_MODNAME) ? FW_MODNAME : 0) | (IsDlgButtonChecked(hwnd, IDC_SETTINGNAME) ? FW_SETNAME : 0) | (IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE) ? FW_SETVAL : 0); if (GetWindowLongPtr(GetDlgItem(hwnd, IDC_REPLACE), GWLP_USERDATA)) { if (IsDlgButtonChecked(hwnd, IDC_FOUND)) fi->mode = RW_FOUND; else if (IsDlgButtonChecked(hwnd, IDC_MODNAME2)) fi->mode = RW_MODULE; else if (IsDlgButtonChecked(hwnd, IDC_SETTINGNAME2)) fi->mode = RW_SETNAME; else if (IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE2)) fi->mode = RW_SETVAL; if (IsDlgButtonChecked(hwnd, IDC_ENTIRELY)) fi->mode |= RW_FULL; fi->replace = mir_tstrdup(replace); SetWindowText(GetDlgItem(hwnd, IDOK), Translate("Stop")); EnableWindow(GetDlgItem(hwnd, IDC_SEARCH), 0); if (IsDlgButtonChecked(hwnd, IDC_CASESENSITIVE)) fi->mode |= RW_CASE; } else { SetWindowText(GetDlgItem(hwnd, IDC_SEARCH), Translate("Stop")); EnableWindow(GetDlgItem(hwnd, IDOK), 0); } fi->text = mir_tstrdup(text); SendDlgItemMessage(hwnd, IDC_LIST, LB_RESETCONTENT, 0, 0); SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 1); EnableWindow(GetDlgItem(hwnd, IDCANCEL), 0); forkthread(FindSettings, 0, fi); } break; case IDCANCEL: DestroyWindow(hwnd); break; case IDC_LIST: if (HIWORD(wParam) == LBN_DBLCLK) { int i = SendDlgItemMessage(hwnd, IDC_LIST, LB_GETCURSEL, 0, 0); ItemInfo *ii = (ItemInfo*)SendDlgItemMessage(hwnd, IDC_LIST, LB_GETITEMDATA, i, 0); if (!ii) break; SendMessage(GetParent(hwnd), WM_FINDITEM, (WPARAM)ii, 0); } break; } break; case WM_GETMINMAXINFO: { MINMAXINFO *mmi = (MINMAXINFO*)lParam; mmi->ptMinTrackSize.x = 520; mmi->ptMinTrackSize.y = 300; } return 0; case WM_SIZE: { UTILRESIZEDIALOG urd; ZeroMemory(&urd, sizeof(urd)); urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwnd; urd.lpTemplate = MAKEINTRESOURCE(IDD_FIND); urd.pfnResizer = FindDialogResize; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); } break; case WM_DESTROY: freeItems(hwnd); break; } return 0; }
void RebuildMenuOrder(void) { BYTE bHideStatusMenu = db_get_b(NULL, "CLUI", "DontHideStatusMenu", 0); // cool perversion, though //clear statusmenu RecursiveDeleteMenu(hStatusMenu); //status menu if (hStatusMenuObject != 0) { CallService(MO_REMOVEMENUOBJECT, (WPARAM)hStatusMenuObject, 0); mir_free(hStatusMainMenuHandles); mir_free(hStatusMenuHandles); } hStatusMenuObject = MO_CreateMenuObject("StatusMenu", LPGEN("Status menu"), "StatusMenuCheckService", "StatusMenuExecService"); MO_SetOptionsMenuObject(hStatusMenuObject, OPT_MENUOBJECT_SET_FREE_SERVICE, (INT_PTR)"CLISTMENUS/FreeOwnerDataStatusMenu"); hStatusMainMenuHandles = (PMO_IntMenuItem*)mir_calloc(SIZEOF(statusModeList) * sizeof(PMO_IntMenuItem*)); hStatusMainMenuHandlesCnt = SIZEOF(statusModeList); hStatusMenuHandles = (tStatusMenuHandles*)mir_calloc(sizeof(tStatusMenuHandles)*accounts.getCount()); hStatusMenuHandlesCnt = accounts.getCount(); FreeMenuProtos(); for (int s = 0; s < accounts.getCount(); s++) { int i = cli.pfnGetAccountIndexByPos(s); if (i == -1) continue; PROTOACCOUNT *pa = accounts[i]; int pos = 0; if (!bHideStatusMenu && !cli.pfnGetProtocolVisibility(pa->szModuleName)) continue; DWORD flags = pa->ppro->GetCaps(PFLAGNUM_2, 0) & ~pa->ppro->GetCaps(PFLAGNUM_5, 0); HICON ic; TCHAR tbuf[256]; //adding root TMO_MenuItem tmi = { 0 }; tmi.cbSize = sizeof(tmi); tmi.flags = CMIF_TCHAR | CMIF_ROOTHANDLE | CMIF_KEEPUNTRANSLATED; tmi.position = pos++; tmi.hIcon = ic = (HICON)CallProtoServiceInt(NULL, pa->szModuleName, PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0); if (Proto_IsAccountLocked(pa) && cli.bDisplayLocked) { mir_sntprintf(tbuf, SIZEOF(tbuf), TranslateT("%s (locked)"), pa->tszAccountName); tmi.ptszName = tbuf; } else tmi.ptszName = pa->tszAccountName; //owner data StatusMenuExecParam *smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); smep->proto = mir_strdup(pa->szModuleName); tmi.ownerdata = smep; PMO_IntMenuItem rootmenu = MO_AddNewMenuItem(hStatusMenuObject, &tmi); memset(&tmi, 0, sizeof(tmi)); tmi.cbSize = sizeof(tmi); tmi.flags = CMIF_TCHAR | CMIF_ROOTHANDLE | CMIF_KEEPUNTRANSLATED; tmi.root = rootmenu; tmi.position = pos++; tmi.hIcon = ic; //owner data smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); smep->proto = mir_strdup(pa->szModuleName); tmi.ownerdata = smep; if (Proto_IsAccountLocked(pa)) tmi.flags |= CMIF_CHECKED; if ((tmi.flags & CMIF_CHECKED) && cli.bDisplayLocked) { mir_sntprintf(tbuf, SIZEOF(tbuf), TranslateT("%s (locked)"), pa->tszAccountName); tmi.ptszName = tbuf; } else tmi.ptszName = pa->tszAccountName; PMO_IntMenuItem menuHandle = MO_AddNewMenuItem(hStatusMenuObject, &tmi); ((StatusMenuExecParam*)tmi.ownerdata)->protoindex = (int)menuHandle; MO_ModifyMenuItem(menuHandle, &tmi); cli.menuProtos = (MenuProto*)mir_realloc(cli.menuProtos, sizeof(MenuProto)*(cli.menuProtoCount + 1)); memset(&(cli.menuProtos[cli.menuProtoCount]), 0, sizeof(MenuProto)); cli.menuProtos[cli.menuProtoCount].pMenu = rootmenu; cli.menuProtos[cli.menuProtoCount].szProto = mir_strdup(pa->szModuleName); cli.menuProtoCount++; char buf[256]; mir_snprintf(buf, SIZEOF(buf), "RootProtocolIcon_%s", pa->szModuleName); MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); DestroyIcon(ic); pos += 500000; for (int j = 0; j < SIZEOF(statusModeList); j++) { if (!(flags & statusModePf2List[j])) continue; // adding memset(&tmi, 0, sizeof(tmi)); tmi.cbSize = sizeof(tmi); tmi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; if (statusModeList[j] == ID_STATUS_OFFLINE) tmi.flags |= CMIF_CHECKED; tmi.root = rootmenu; tmi.position = pos++; tmi.ptszName = cli.pfnGetStatusModeDescription(statusModeList[j], GSMDF_UNTRANSLATED); tmi.hIcon = LoadSkinProtoIcon(pa->szModuleName, statusModeList[j]); // owner data StatusMenuExecParam *smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); smep->custom = FALSE; smep->status = statusModeList[j]; smep->protoindex = i; smep->proto = mir_strdup(pa->szModuleName); tmi.ownerdata = smep; hStatusMenuHandles[i].protoindex = i; hStatusMenuHandles[i].protostatus[j] = statusModeList[j]; hStatusMenuHandles[i].menuhandle[j] = MO_AddNewMenuItem(hStatusMenuObject, &tmi); char buf[256]; mir_snprintf(buf, SIZEOF(buf), "ProtocolIcon_%s_%s", pa->szModuleName, tmi.pszName); MO_SetOptionsMenuItem(hStatusMenuHandles[i].menuhandle[j], OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); IcoLib_ReleaseIcon(tmi.hIcon, 0); } } NotifyEventHooks(cli.hPreBuildStatusMenuEvent, 0, 0); int pos = 200000; // add to root menu for (int j = 0; j < SIZEOF(statusModeList); j++) { for (int i = 0; i < accounts.getCount(); i++) { PROTOACCOUNT *pa = accounts[i]; if (!bHideStatusMenu && !cli.pfnGetProtocolVisibility(pa->szModuleName)) continue; DWORD flags = pa->ppro->GetCaps(PFLAGNUM_2, 0) & ~pa->ppro->GetCaps(PFLAGNUM_5, 0); if (!(flags & statusModePf2List[j])) continue; TMO_MenuItem tmi = { sizeof(tmi) }; tmi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; if (statusModeList[j] == ID_STATUS_OFFLINE) tmi.flags |= CMIF_CHECKED; tmi.hIcon = LoadSkinIcon(skinIconStatusList[j]); tmi.position = pos++; tmi.hotKey = MAKELPARAM(MOD_CONTROL, '0' + j); //owner data StatusMenuExecParam *smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); smep->status = statusModeList[j]; tmi.ownerdata = smep; { TCHAR buf[256], hotkeyName[100]; WORD hotKey = GetHotkeyValue(statusHotkeys[j]); HotkeyToName(hotkeyName, SIZEOF(hotkeyName), HIBYTE(hotKey), LOBYTE(hotKey)); mir_sntprintf(buf, SIZEOF(buf), _T("%s\t%s"), cli.pfnGetStatusModeDescription(statusModeList[j], 0), hotkeyName); tmi.ptszName = buf; tmi.hotKey = MAKELONG(HIBYTE(hotKey), LOBYTE(hotKey)); hStatusMainMenuHandles[j] = MO_AddNewMenuItem(hStatusMenuObject, &tmi); } char buf[256]; mir_snprintf(buf, SIZEOF(buf), "Root2ProtocolIcon_%s_%s", pa->szModuleName, tmi.pszName); MO_SetOptionsMenuItem(hStatusMainMenuHandles[j], OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); IcoLib_ReleaseIcon(tmi.hIcon, 0); break; } } BuildStatusMenu(0, 0); }
int ContactStatusChanged(MCONTACT hContact, WORD oldStatus, WORD newStatus) { if (opt.LogToDB && (!opt.LogToDB_WinOpen || CheckMsgWnd(hContact))) { wchar_t stzStatusText[MAX_SECONDLINE] = { 0 }; GetStatusText(hContact, newStatus, oldStatus, stzStatusText); T2Utf blob(stzStatusText); DBEVENTINFO dbei = {}; dbei.cbBlob = (DWORD)mir_strlen(blob) + 1; dbei.pBlob = (PBYTE)blob; dbei.eventType = EVENTTYPE_STATUSCHANGE; dbei.flags = DBEF_READ | DBEF_UTF; dbei.timestamp = (DWORD)time(0); dbei.szModule = MODULE; MEVENT hDBEvent = db_event_add(hContact, &dbei); if (opt.LogToDB_WinOpen && opt.LogToDB_Remove) { DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT)); dbevent->hContact = hContact; dbevent->hDBEvent = hDBEvent; eventListStatus.insert(dbevent); } } bool bEnablePopup = true, bEnableSound = true; char *szProto = GetContactProto(hContact); int myStatus = Proto_GetStatus(szProto); if (!mir_strcmp(szProto, META_PROTO)) { //this contact is Meta MCONTACT hSubContact = db_mc_getMostOnline(hContact); char *szSubProto = GetContactProto(hSubContact); if (szSubProto == nullptr) return 0; if (newStatus == ID_STATUS_OFFLINE) { // read last online proto for metacontact if exists, // to avoid notifying when meta went offline but default contact's proto still online DBVARIANT dbv; if (!db_get_s(hContact, szProto, "LastOnline", &dbv)) { szSubProto = NEWSTR_ALLOCA(dbv.pszVal); db_free(&dbv); } } else db_set_s(hContact, szProto, "LastOnline", szSubProto); if (db_get_b(0, MODULE, szSubProto, 1) == 0) return 0; szProto = szSubProto; } else { if (myStatus == ID_STATUS_OFFLINE || db_get_b(0, MODULE, szProto, 1) == 0) return 0; } if (!opt.FromOffline || oldStatus != ID_STATUS_OFFLINE) { // Either it wasn't a change from Offline or we didn't enable that. char buff[8]; mir_snprintf(buff, "%d", newStatus); if (db_get_b(0, MODULE, buff, 1) == 0) return 0; // "Notify when a contact changes to one of..." is unchecked } if (SkipHiddenContact(hContact)) return 0; // check if that proto from which we received statuschange notification, isn't in autodisable list if (opt.AutoDisable) { char statusIDs[12], statusIDp[12]; mir_snprintf(statusIDs, "s%d", myStatus); mir_snprintf(statusIDp, "p%d", myStatus); bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : TRUE; bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : TRUE; } if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) { int wStatus = Proto_GetStatus(szProto); wchar_t str[MAX_SECONDLINE] = { 0 }; if (opt.ShowStatus) GetStatusText(hContact, newStatus, oldStatus, str); if (opt.ReadAwayMsg && wStatus != ID_STATUS_INVISIBLE && StatusHasAwayMessage(szProto, newStatus)) db_set_ws(hContact, MODULE, "LastPopupText", str); PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA)); pdp->oldStatus = oldStatus; pdp->newStatus = newStatus; pdp->hAwayMsgHook = nullptr; pdp->hAwayMsgProcess = nullptr; ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, newStatus), newStatus, str, pdp); } if (opt.BlinkIcon && !opt.TempDisabled) { HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, newStatus) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE); wchar_t str[256]; mir_snwprintf(str, TranslateT("%s is now %s"), Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText); BlinkIcon(hContact, hIcon, str); } if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) { if (oldStatus == ID_STATUS_OFFLINE) PlayChangeSound(hContact, StatusListEx[ID_STATUS_FROMOFFLINE].lpzSkinSoundName); else PlayChangeSound(hContact, StatusList[Index(newStatus)].lpzSkinSoundName); } if (opt.LogToFile) { wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime)); GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate)); mir_snwprintf(stzText, TranslateT("%s, %s. %s changed status to %s (was %s)\r\n"), stzDate, stzTime, Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText, StatusList[Index(oldStatus)].lpzStandardText); LogToFile(stzText); } return 0; }
static INT_PTR CALLBACK ConsoleDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_INITDIALOG: { TCHAR title[MAX_PATH]; TCHAR name[MAX_PATH] = {0}; TCHAR path[MAX_PATH] = {0}; hTabs = GetDlgItem(hwndDlg, IDC_TABS); //TabCtrl_SetMinTabWidth(hTabs, 100); // restore position Utils_RestoreWindowPositionEx(hwndDlg,RWPF_HIDDEN,NULL,"Console","Console"); CallService(MS_DB_GETPROFILENAMET,(WPARAM)SIZEOF(name),(LPARAM)name); CallService(MS_DB_GETPROFILEPATHT,(WPARAM)SIZEOF(path),(LPARAM)path); mir_sntprintf(title, SIZEOF(title), _T("%s - %s\\%s"), TranslateT("Miranda Console"), path, name); SetWindowText(hwndDlg, title); SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)hIcons[0]); hwndConsole = hwndDlg; SendMessage(hwndDlg, HM_ADD, 0, 0); PostMessage(hwndDlg, WM_SIZE, 0, 0); break; } case HM_DUMP: { // lParam = DUMPMSG int idx; LOGWIN *lw; LOGWIN lw2; DUMPMSG *dumpMsg = (DUMPMSG*)lParam; if (!pActive) { mir_free(dumpMsg); break; } if (!gSingleMode) { lw2.Module = dumpMsg->szModule; if (!List_GetIndex(&lModules, &lw2, &idx)) SendMessage(hwndDlg, HM_ADD, (WPARAM)idx, (LPARAM)dumpMsg->szModule); lw = (LOGWIN*)lModules.items[idx]; } else lw = pActive; if (lw->hwnd) SendMessage(lw->hwnd, HM_DUMP, wParam, lParam); else PostMessage(hwndDlg, HM_DUMP, wParam, lParam); // loop msg until window will be ready return TRUE; } case HM_ADD: { // wParam = index, lParam = module name LOGWIN *lw; COLORREF col; TCITEM tci = {0}; int idx = (int)wParam; char *str = (char*)lParam; if (!str) str = ""; // startup window lw = (LOGWIN*)mir_calloc( sizeof(LOGWIN)); lw->Module = (char*)mir_strdup(str); List_Insert(&lModules, lw, idx); if (!gSingleMode && lParam) { tci.mask = TCIF_PARAM | TCIF_TEXT; tci.lParam = (LPARAM)lw; tci.pszText = mir_a2u(lw->Module); idx = TabCtrl_InsertItem(hTabs, tabCount, &tci); mir_free(tci.pszText); tabCount++; } GetClientRect(hTabs, &rcTabs); TabCtrl_AdjustRect(hTabs, FALSE, &rcTabs); CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_LOG), hwndDlg, LogDlgProc, (LPARAM)lw); ShowWindow(lw->hwnd, (tabCount > 1)?SW_HIDE:SW_SHOWNOACTIVATE); if (pActive) { col = ListView_GetBkColor(pActive->hList); ListView_SetBkColor(lw->hList, col); ListView_SetTextBkColor(lw->hList, col); col = ListView_GetTextColor(pActive->hList); ListView_SetTextColor(lw->hList, col); if (hfLogFont) SendMessage(lw->hList, WM_SETFONT, (WPARAM)hfLogFont, TRUE); } // hide startup window if (tabCount == 1) { ShowWindow(pActive->hwnd, SW_HIDE); PostMessage(pActive->hwnd, WM_CLOSE, 0, 0); pActive = lw; } if (!pActive) pActive = lw; return TRUE; } case HM_REMOVE: { // lParam = LOGWIN LOGWIN *lw = (LOGWIN*)lParam; if (!lw) break; if (lw == pActive) { int tab = TabCtrl_GetCurSel(hTabs); if (tab >= 0) { TCITEM tci={0}; TabCtrl_DeleteItem(hTabs, tab); tabCount--; if (tabCount) { tab--; if (tab < 0 ) tab = 0; TabCtrl_SetCurSel(hTabs, tab); tci.mask = TCIF_PARAM; TabCtrl_GetItem(hTabs, tab, &tci); pActive = (LOGWIN*)tci.lParam; SendMessage(pActive->hwnd, WM_SIZE, 0, 0); ScrollDown(pActive); ShowWindow(pActive->hwnd, SW_SHOWNOACTIVATE); SetFocus(pActive->hList); } else pActive = NULL; } } List_RemovePtr(&lModules, lw); mir_free(lw->Module); mir_free(lw); return TRUE; } case HM_SETFONT: { // wParam = font, lParam = font color int i; LOGWIN *lw; for ( i = 0; i < lModules.realCount; i++ ) { lw = (LOGWIN*)lModules.items[i]; ListView_SetTextColor(lw->hList, (COLORREF)lParam); if (wParam) SendMessage(lw->hList, WM_SETFONT, wParam, TRUE); } return TRUE; } case HM_SETCOLOR: { // wParam = font, lParam = background color int i; LOGWIN *lw; for ( i = 0; i < lModules.realCount; i++ ) { lw = (LOGWIN*)lModules.items[i]; ListView_SetBkColor(lw->hList, (COLORREF)lParam); ListView_SetTextBkColor(lw->hList, (COLORREF)lParam); if (wParam) SendMessage(lw->hList, WM_SETFONT, wParam, TRUE); } return TRUE; } case HM_PAUSEALL: { // lParam = 1 to pause, 0 to start int i; LOGWIN *lw; for ( i = 0; i < lModules.realCount; i++ ) { lw = (LOGWIN*)lModules.items[i]; if (lw->Paused != (int)lParam) SendMessage(lw->hwnd, WM_COMMAND, IDC_PAUSE, 0); } return TRUE; } case HM_RESTART: { if (pActive) { pActive = NULL; PostMessage(hwndDlg, HM_RESTART, 0, 0); return TRUE; } // close all tabs if (!lParam) { LOGWIN *lw; TabCtrl_DeleteAllItems(hTabs); while ( lModules.realCount ) { lw = (LOGWIN*)lModules.items[0]; SendMessage(lw->hwnd, WM_CLOSE, 0, 0); } tabCount = 0; PostMessage(hwndDlg, HM_RESTART, 0, 1); return TRUE; } LoadSettings(); SendMessage(hwndDlg, HM_ADD, 0, 0); PostMessage(hwndDlg, WM_SIZE, 0, 0); return TRUE; } case WM_SETFOCUS: if (pActive) { SetFocus(pActive->hList); } return TRUE; case WM_NOTIFY: switch(wParam) { case IDC_TABS: { LPNMHDR lpnmhdr = (LPNMHDR)lParam; if (lpnmhdr->code == TCN_SELCHANGE) { int newTab = TabCtrl_GetCurSel(hTabs); if (newTab >= 0 ) { TCITEM tci={0}; HWND hOld = pActive->hwnd; tci.mask = TCIF_PARAM; if (!TabCtrl_GetItem(hTabs, newTab, &tci)) break; pActive = (LOGWIN*)tci.lParam; SendMessage(pActive->hwnd, WM_SIZE, 0, 0); ScrollDown(pActive); ShowWindow(hOld, SW_HIDE); ShowWindow(pActive->hwnd, SW_SHOWNOACTIVATE); SetFocus(pActive->hList); } else SendMessage(pActive->hwnd, WM_SIZE, 0, 0); } break; } } break; case WM_SIZE: { UTILRESIZEDIALOG urd={0}; urd.cbSize=sizeof(urd); urd.hInstance=hInst; urd.hwndDlg=hwndDlg; urd.lpTemplate=MAKEINTRESOURCEA(IDD_CONSOLE); urd.pfnResizer=ConsoleResize; CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); GetClientRect(hTabs, &rcTabs); TabCtrl_AdjustRect(hTabs, FALSE, &rcTabs); if ( pActive ) SendMessage(pActive->hwnd, WM_SIZE, 0, 0); break; } case WM_GETMINMAXINFO: { MINMAXINFO *mmi=(MINMAXINFO*)lParam; mmi->ptMinTrackSize.x=400; mmi->ptMinTrackSize.y=200; break; } case WM_CLOSE: if ( lParam != 1 ) { Utils_SaveWindowPosition(hwndDlg,NULL,"Console","Console"); ShowConsole(0); return TRUE; } else DestroyWindow(hwndDlg); break; case WM_DESTROY: pActive = NULL; if (hfLogFont) DeleteObject(hfLogFont); PostQuitMessage(0); break; } return FALSE; }
static INT_PTR NetlibRegisterUser(WPARAM,LPARAM lParam) { NETLIBUSER *nlu=(NETLIBUSER*)lParam; struct NetlibUser *thisUser; if(nlu==NULL || nlu->cbSize!=sizeof(NETLIBUSER) || nlu->szSettingsModule==NULL || (!(nlu->flags&NUF_NOOPTIONS) && nlu->szDescriptiveName==NULL) || (nlu->flags&NUF_HTTPGATEWAY && (nlu->pfnHttpGatewayInit==NULL))) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } thisUser = (struct NetlibUser*)mir_calloc(sizeof(struct NetlibUser)); thisUser->handleType = NLH_USER; thisUser->user = *nlu; EnterCriticalSection(&csNetlibUser); if (netlibUser.getIndex(thisUser) >= 0) { LeaveCriticalSection(&csNetlibUser); mir_free(thisUser); SetLastError(ERROR_DUP_NAME); return 0; } LeaveCriticalSection(&csNetlibUser); if (nlu->szDescriptiveName) { thisUser->user.ptszDescriptiveName = (thisUser->user.flags&NUF_UNICODE ? mir_u2t((WCHAR*)nlu->ptszDescriptiveName) : mir_a2t(nlu->szDescriptiveName)); } if((thisUser->user.szSettingsModule=mir_strdup(nlu->szSettingsModule))==NULL || (nlu->szDescriptiveName && thisUser->user.ptszDescriptiveName ==NULL) || (nlu->szHttpGatewayUserAgent && (thisUser->user.szHttpGatewayUserAgent=mir_strdup(nlu->szHttpGatewayUserAgent))==NULL)) { mir_free(thisUser); SetLastError(ERROR_OUTOFMEMORY); return 0; } if (nlu->szHttpGatewayHello) thisUser->user.szHttpGatewayHello=mir_strdup(nlu->szHttpGatewayHello); else thisUser->user.szHttpGatewayHello=NULL; thisUser->settings.cbSize=sizeof(NETLIBUSERSETTINGS); thisUser->settings.useProxy=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLUseProxy",0); thisUser->settings.proxyType=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLProxyType",PROXYTYPE_SOCKS5); if(thisUser->user.flags&NUF_NOHTTPSOPTION && thisUser->settings.proxyType==PROXYTYPE_HTTPS) thisUser->settings.proxyType=PROXYTYPE_HTTP; if(!(thisUser->user.flags&(NUF_HTTPCONNS|NUF_HTTPGATEWAY)) && thisUser->settings.proxyType==PROXYTYPE_HTTP) { thisUser->settings.useProxy=0; thisUser->settings.proxyType=PROXYTYPE_SOCKS5; } thisUser->settings.szProxyServer=GetNetlibUserSettingString(thisUser->user.szSettingsModule,"NLProxyServer",0); thisUser->settings.wProxyPort=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLProxyPort",1080); thisUser->settings.useProxyAuth=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLUseProxyAuth",0); thisUser->settings.szProxyAuthUser=GetNetlibUserSettingString(thisUser->user.szSettingsModule,"NLProxyAuthUser",0); thisUser->settings.szProxyAuthPassword=GetNetlibUserSettingString(thisUser->user.szSettingsModule,"NLProxyAuthPassword",1); thisUser->settings.dnsThroughProxy=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLDnsThroughProxy",1); thisUser->settings.specifyIncomingPorts=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLSpecifyIncomingPorts",0); thisUser->settings.szIncomingPorts=GetNetlibUserSettingString(thisUser->user.szSettingsModule,"NLIncomingPorts",0); thisUser->settings.specifyOutgoingPorts=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLSpecifyOutgoingPorts",0); thisUser->settings.szOutgoingPorts=GetNetlibUserSettingString(thisUser->user.szSettingsModule,"NLOutgoingPorts",0); thisUser->settings.enableUPnP=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLEnableUPnP",1); //default to on thisUser->settings.validateSSL=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLValidateSSL",0); thisUser->toLog=GetNetlibUserSettingInt(thisUser->user.szSettingsModule,"NLlog",1); EnterCriticalSection(&csNetlibUser); netlibUser.insert(thisUser); LeaveCriticalSection(&csNetlibUser); return (INT_PTR)thisUser; }
INT_PTR CALLBACK DlgProcRecvFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { FileDlgData *dat = (FileDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); { TCHAR szPath[450]; CLISTEVENT* cle = (CLISTEVENT*)lParam; dat = (FileDlgData*)mir_calloc(sizeof(FileDlgData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hContact = cle->hContact; dat->hDbEvent = cle->hDbEvent; dat->hNotifyEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_RECVEVENT); dat->hPreshutdownEvent = HookEventMessage(ME_SYSTEM_PRESHUTDOWN, hwndDlg, M_PRESHUTDOWN); dat->dwTicks = GetTickCount(); EnumChildWindows(hwndDlg, ClipSiblingsChildEnumProc, 0); Window_SetSkinIcon_IcoLib(hwndDlg, SKINICON_EVENT_FILE); Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact permanently to list")); Button_SetIcon_IcoLib(hwndDlg, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View user's details")); Button_SetIcon_IcoLib(hwndDlg, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View user's history")); Button_SetIcon_IcoLib(hwndDlg, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User menu")); TCHAR *contactName = pcli->pfnGetContactDisplayName(dat->hContact, 0); SetDlgItemText(hwndDlg, IDC_FROM, contactName); GetContactReceivedFilesDir(dat->hContact, szPath, _countof(szPath), TRUE); SetDlgItemText(hwndDlg, IDC_FILEDIR, szPath); SHAutoComplete(GetWindow(GetDlgItem(hwndDlg, IDC_FILEDIR), GW_CHILD), 1); for (int i = 0; i < MAX_MRU_DIRS; i++) { char idstr[32]; mir_snprintf(idstr, "MruDir%d", i); DBVARIANT dbv; if (db_get_ts(NULL, "SRFile", idstr, &dbv)) break; SendDlgItemMessage(hwndDlg, IDC_FILEDIR, CB_ADDSTRING, 0, (LPARAM)dbv.ptszVal); db_free(&dbv); } db_event_markRead(dat->hContact, dat->hDbEvent); DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(dat->hDbEvent); if (dbei.cbBlob > 4 && dbei.cbBlob <= 8196) { dbei.pBlob = (PBYTE)alloca(dbei.cbBlob + 1); db_event_get(dat->hDbEvent, &dbei); dbei.pBlob[dbei.cbBlob] = 0; dat->fs = cle->lParam ? (HANDLE)cle->lParam : (HANDLE)*(PDWORD)dbei.pBlob; char *str = (char*)dbei.pBlob + 4; ptrT ptszFileName(DbGetEventStringT(&dbei, str)); SetDlgItemText(hwndDlg, IDC_FILENAMES, ptszFileName); unsigned len = (unsigned)mir_strlen(str) + 1; if (len + 4 < dbei.cbBlob) { str += len; ptrT ptszDescription(DbGetEventStringT(&dbei, str)); SetDlgItemText(hwndDlg, IDC_MSG, ptszDescription); } } else DestroyWindow(hwndDlg); TCHAR datetimestr[64]; TimeZone_PrintTimeStamp(NULL, dbei.timestamp, _T("t d"), datetimestr, _countof(datetimestr), 0); SetDlgItemText(hwndDlg, IDC_DATE, datetimestr); ptrT info(Contact_GetInfo(CNF_UNIQUEID, dat->hContact)); SetDlgItemText(hwndDlg, IDC_NAME, (info) ? info : contactName); if (db_get_b(dat->hContact, "CList", "NotOnList", 0)) { RECT rcBtn1, rcBtn2, rcDateCtrl; GetWindowRect(GetDlgItem(hwndDlg, IDC_ADD), &rcBtn1); GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rcBtn2); GetWindowRect(GetDlgItem(hwndDlg, IDC_DATE), &rcDateCtrl); SetWindowPos(GetDlgItem(hwndDlg, IDC_DATE), 0, 0, 0, rcDateCtrl.right - rcDateCtrl.left - (rcBtn2.left - rcBtn1.left), rcDateCtrl.bottom - rcDateCtrl.top, SWP_NOZORDER | SWP_NOMOVE); } else if (db_get_b(NULL, "SRFile", "AutoAccept", 0)) { //don't check auto-min here to fix BUG#647620 PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, IDOK)); } if (!db_get_b(dat->hContact, "CList", "NotOnList", 0)) ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); } return TRUE; case WM_MEASUREITEM: return Menu_MeasureItem((LPMEASUREITEMSTRUCT)lParam); case WM_DRAWITEM: { LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_PROTOCOL)) { char *szProto = GetContactProto(dat->hContact); if (szProto) { HICON hIcon = (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); if (hIcon) { DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); DestroyIcon(hIcon); } } } } return Menu_DrawItem((LPDRAWITEMSTRUCT)lParam); case WM_COMMAND: if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)) break; switch (LOWORD(wParam)) { case IDC_FILEDIRBROWSE: { TCHAR szDirName[MAX_PATH], szExistingDirName[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_FILEDIR, szDirName, _countof(szDirName)); GetLowestExistingDirName(szDirName, szExistingDirName, _countof(szExistingDirName)); if (BrowseForFolder(hwndDlg, szExistingDirName)) SetDlgItemText(hwndDlg, IDC_FILEDIR, szExistingDirName); } break; case IDOK: { //most recently used directories TCHAR szRecvDir[MAX_PATH], szDefaultRecvDir[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_FILEDIR, szRecvDir, _countof(szRecvDir)); RemoveInvalidPathChars(szRecvDir); GetContactReceivedFilesDir(NULL, szDefaultRecvDir, _countof(szDefaultRecvDir), TRUE); if (_tcsnicmp(szRecvDir, szDefaultRecvDir, mir_tstrlen(szDefaultRecvDir))) { char idstr[32]; int i; DBVARIANT dbv; for (i = MAX_MRU_DIRS-2;i>=0;i--) { mir_snprintf(idstr, "MruDir%d", i); if (db_get_ts(NULL, "SRFile", idstr, &dbv)) continue; mir_snprintf(idstr, "MruDir%d", i+1); db_set_ts(NULL, "SRFile", idstr, dbv.ptszVal); db_free(&dbv); } db_set_ts(NULL, "SRFile", idstr, szRecvDir); } } EnableWindow(GetDlgItem(hwndDlg, IDC_FILENAMES), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_MSG), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_FILEDIR), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_FILEDIRBROWSE), FALSE); GetDlgItemText(hwndDlg, IDC_FILEDIR, dat->szSavePath, _countof(dat->szSavePath)); GetDlgItemText(hwndDlg, IDC_FILE, dat->szFilenames, _countof(dat->szFilenames)); GetDlgItemText(hwndDlg, IDC_MSG, dat->szMsg, _countof(dat->szMsg)); dat->hwndTransfer = FtMgr_AddTransfer(dat); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); //check for auto-minimize here to fix BUG#647620 if (db_get_b(NULL, "SRFile", "AutoAccept", 0) && db_get_b(NULL, "SRFile", "AutoMin", 0)) { ShowWindow(hwndDlg, SW_HIDE); ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); } DestroyWindow(hwndDlg); break; case IDCANCEL: if (dat->fs) CallContactService(dat->hContact, PSS_FILEDENY, (WPARAM)dat->fs, (LPARAM)TranslateT("Canceled")); dat->fs = NULL; /* the protocol will free the handle */ DestroyWindow(hwndDlg); break; case IDC_ADD: { ADDCONTACTSTRUCT acs = { 0 }; acs.hContact = dat->hContact; acs.handleType = HANDLE_CONTACT; acs.szProto = ""; CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); if (!db_get_b(dat->hContact, "CList", "NotOnList", 0)) ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); } break; case IDC_USERMENU: { RECT rc; GetWindowRect((HWND)lParam, &rc); HMENU hMenu = Menu_BuildContactMenu(dat->hContact); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)dat->hContact, 0); break; case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)dat->hContact, 0); break; } break; case HM_RECVEVENT: { ACKDATA *ack = (ACKDATA*)lParam; if ((ack == NULL) || (ack->hProcess != dat->fs) || (ack->type != ACKTYPE_FILE) || (ack->hContact != dat->hContact)) break; if (ack->result == ACKRESULT_DENIED || ack->result == ACKRESULT_FAILED) { EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_FILEDIR), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_FILEDIRBROWSE), FALSE); SetDlgItemText(hwndDlg, IDC_MSG, TranslateT("This file transfer has been canceled by the other side")); SkinPlaySound("FileDenied"); FlashWindow(hwndDlg, TRUE); } else if (ack->result != ACKRESULT_FILERESUME) { SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), (LPARAM)GetDlgItem(hwndDlg, IDCANCEL)); } } break; case WM_DESTROY: Window_FreeIcon_IcoLib(hwndDlg); Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); Button_FreeIcon_IcoLib(hwndDlg, IDC_DETAILS); Button_FreeIcon_IcoLib(hwndDlg, IDC_HISTORY); Button_FreeIcon_IcoLib(hwndDlg, IDC_USERMENU); FreeFileDlgData(dat); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; } return FALSE; }
INT_PTR CALLBACK DlgProcSendFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { struct FileDlgData *dat; dat=(struct FileDlgData*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { struct FileSendData *fsd=(struct FileSendData*)lParam; dat=(struct FileDlgData*)mir_calloc(sizeof(struct FileDlgData)); SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LONG_PTR)dat); dat->hContact=fsd->hContact; dat->send=1; dat->hPreshutdownEvent=HookEventMessage(ME_SYSTEM_PRESHUTDOWN,hwndDlg,M_PRESHUTDOWN); dat->fs=NULL; dat->dwTicks=GetTickCount(); TranslateDialogDefault(hwndDlg); EnumChildWindows(hwndDlg,ClipSiblingsChildEnumProc,0); OldSendEditProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_MSG),GWLP_WNDPROC,(LONG_PTR)SendEditSubclassProc); Window_SetIcon_IcoLib(hwndDlg, SKINICON_EVENT_FILE); Button_SetIcon_IcoLib(hwndDlg, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View User's Details")); Button_SetIcon_IcoLib(hwndDlg, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View User's History")); Button_SetIcon_IcoLib(hwndDlg, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User Menu")); EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); if(fsd->ppFiles!=NULL && fsd->ppFiles[0]!=NULL) { int totalCount,i; for(totalCount=0;fsd->ppFiles[totalCount];totalCount++); dat->files = ( TCHAR** )mir_alloc( sizeof(TCHAR*)*(totalCount+1)); // Leaks for(i=0;i<totalCount;i++) dat->files[i] = mir_tstrdup( fsd->ppFiles[i] ); dat->files[totalCount]=NULL; SetFileListAndSizeControls(hwndDlg,dat); } { char *szProto; TCHAR* contactName = cli.pfnGetContactDisplayName( dat->hContact, 0 ); SetDlgItemText(hwndDlg,IDC_TO,contactName); szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0); if (szProto) { CONTACTINFO ci; int hasName = 0; char buf[128]; ZeroMemory(&ci,sizeof(ci)); ci.cbSize = sizeof(ci); ci.hContact = dat->hContact; ci.szProto = szProto; ci.dwFlag = CNF_UNIQUEID; if (!CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&ci)) { switch(ci.type) { case CNFT_ASCIIZ: hasName = 1; mir_snprintf(buf, SIZEOF(buf), "%s", ci.pszVal); mir_free(ci.pszVal); break; case CNFT_DWORD: hasName = 1; mir_snprintf(buf, SIZEOF(buf),"%u",ci.dVal); break; } } if ( hasName ) SetDlgItemTextA(hwndDlg,IDC_NAME,buf); else SetDlgItemText(hwndDlg,IDC_NAME,contactName); } } if ( fsd->ppFiles == NULL ) { EnableWindow(hwndDlg, FALSE); dat->closeIfFileChooseCancelled=1; PostMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_CHOOSE,BN_CLICKED),(LPARAM)GetDlgItem(hwndDlg,IDC_CHOOSE)); } return TRUE; } case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); case WM_DRAWITEM: { LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam; if(dis->hwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) { char *szProto; szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)dat->hContact,0); if (szProto) { HICON hIcon = (HICON)CallProtoService(szProto,PS_LOADICON,PLI_PROTOCOL|PLIF_SMALL,0); if (hIcon) { DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL); DestroyIcon(hIcon); } } } } return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); case M_FILECHOOSEDONE: if( lParam != 0 ) { FilenameToFileList( hwndDlg, dat, ( TCHAR* )lParam ); mir_free(( TCHAR* )lParam ); dat->closeIfFileChooseCancelled = 0; } else if(dat->closeIfFileChooseCancelled) DestroyWindow(hwndDlg); EnableWindow(hwndDlg,TRUE); break; case WM_COMMAND: if(CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU),(LPARAM)dat->hContact)) break; switch (LOWORD(wParam)) { case IDC_CHOOSE: EnableWindow(hwndDlg,FALSE); //GetOpenFileName() creates its own message queue which prevents any incoming events being processed forkthread(ChooseFilesThread,0,hwndDlg); break; case IDOK: EnableWindow(GetDlgItem(hwndDlg,IDC_FILENAME),FALSE); EnableWindow(GetDlgItem(hwndDlg,IDC_MSG),FALSE); EnableWindow(GetDlgItem(hwndDlg,IDC_CHOOSE),FALSE); GetDlgItemText(hwndDlg,IDC_FILEDIR,dat->szSavePath,SIZEOF(dat->szSavePath)); GetDlgItemText(hwndDlg,IDC_FILE,dat->szFilenames,SIZEOF(dat->szFilenames)); GetDlgItemText(hwndDlg,IDC_MSG,dat->szMsg,SIZEOF(dat->szMsg)); dat->hwndTransfer = FtMgr_AddTransfer(dat); SetWindowLongPtr( hwndDlg, GWLP_USERDATA, 0); DestroyWindow(hwndDlg); return TRUE; case IDCANCEL: DestroyWindow(hwndDlg); return TRUE; case IDC_USERMENU: { RECT rc; HMENU hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)dat->hContact,0); GetWindowRect((HWND)lParam,&rc); TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); DestroyMenu(hMenu); break; } case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)dat->hContact,0); return TRUE; case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)dat->hContact,0); return TRUE; } break; case WM_DESTROY: Window_FreeIcon_IcoLib(hwndDlg); Button_FreeIcon_IcoLib(hwndDlg,IDC_DETAILS); Button_FreeIcon_IcoLib(hwndDlg,IDC_HISTORY); Button_FreeIcon_IcoLib(hwndDlg,IDC_USERMENU); if ( dat ) FreeFileDlgData( dat ); SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_MSG),GWLP_WNDPROC,(LONG_PTR)OldSendEditProc); return TRUE; } return FALSE; }
LRESULT CALLBACK fnContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ClcGroup *group; ClcContact *contact; DWORD hitFlags; int hit; ClcData *dat = (struct ClcData *) GetWindowLongPtr(hwnd, 0); if (msg >= CLM_FIRST && msg < CLM_LAST) return cli.pfnProcessExternalMessages(hwnd, dat, msg, wParam, lParam); switch (msg) { case WM_CREATE: WindowList_Add(hClcWindowList, hwnd, NULL); cli.pfnRegisterFileDropping(hwnd); if (dat == NULL) { dat = (struct ClcData *) mir_calloc(sizeof(struct ClcData)); SetWindowLongPtr(hwnd, 0, (LONG_PTR)dat); } { for (int i = 0; i <= FONTID_MAX; i++) dat->fontInfo[i].changed = 1; } dat->selection = -1; dat->iconXSpace = 20; dat->checkboxSize = 13; dat->dragAutoScrollHeight = 30; dat->iDragItem = -1; dat->iInsertionMark = -1; dat->insertionMarkHitHeight = 5; dat->iHotTrack = -1; dat->infoTipTimeout = db_get_w(NULL, "CLC", "InfoTipHoverTime", 750); dat->extraColumnSpacing = 20; dat->list.cl.increment = 30; dat->needsResort = 1; cli.pfnLoadClcOptions(hwnd, dat, TRUE); if (!IsWindowVisible(hwnd)) SetTimer(hwnd, TIMERID_REBUILDAFTER, 10, NULL); else { cli.pfnRebuildEntireList(hwnd, dat); NMCLISTCONTROL nm; nm.hdr.code = CLN_LISTREBUILT; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm); } break; case INTM_SCROLLBARCHANGED: if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CONTACTLIST) { if (dat->noVScrollbar) ShowScrollBar(hwnd, SB_VERT, FALSE); else cli.pfnRecalcScrollBar(hwnd, dat); } break; case INTM_RELOADOPTIONS: cli.pfnLoadClcOptions(hwnd, dat, FALSE); cli.pfnSaveStateAndRebuildList(hwnd, dat); break; case WM_THEMECHANGED: cli.pfnInvalidateRect(hwnd, NULL, FALSE); break; case WM_SIZE: cli.pfnEndRename(hwnd, dat, 1); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); cli.pfnRecalcScrollBar(hwnd, dat); { // creating imagelist containing blue line for highlight RECT rc; GetClientRect(hwnd, &rc); if (rc.right == 0) break; rc.bottom = dat->rowHeight; HDC hdc = GetDC(hwnd); int depth = GetDeviceCaps(hdc, BITSPIXEL); if (depth < 16) depth = 16; HBITMAP hBmp = CreateBitmap(rc.right, rc.bottom, 1, depth, NULL); HBITMAP hBmpMask = CreateBitmap(rc.right, rc.bottom, 1, 1, NULL); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); HBRUSH hBrush = CreateSolidBrush(dat->useWindowsColours ? GetSysColor(COLOR_HIGHLIGHT) : dat->selBkColour); FillRect(hdcMem, &rc, hBrush); DeleteObject(hBrush); HBITMAP hoMaskBmp = (HBITMAP)SelectObject(hdcMem, hBmpMask); FillRect(hdcMem, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); SelectObject(hdcMem, hoMaskBmp); SelectObject(hdcMem, hoBmp); DeleteDC(hdcMem); ReleaseDC(hwnd, hdc); if (dat->himlHighlight) ImageList_Destroy(dat->himlHighlight); dat->himlHighlight = ImageList_Create(rc.right, rc.bottom, ILC_COLOR32 | ILC_MASK, 1, 1); ImageList_Add(dat->himlHighlight, hBmp, hBmpMask); DeleteObject(hBmpMask); DeleteObject(hBmp); } break; case WM_SYSCOLORCHANGE: SendMessage(hwnd, WM_SIZE, 0, 0); break; case WM_GETDLGCODE: if (lParam) { MSG *msg = (MSG *)lParam; if (msg->message == WM_KEYDOWN) { if (msg->wParam == VK_TAB) return 0; if (msg->wParam == VK_ESCAPE && dat->hwndRenameEdit == NULL && dat->szQuickSearch[0] == 0) return 0; } if (msg->message == WM_CHAR) { if (msg->wParam == '\t') return 0; if (msg->wParam == 27 && dat->hwndRenameEdit == NULL && dat->szQuickSearch[0] == 0) return 0; } } return DLGC_WANTMESSAGE; case WM_KILLFOCUS: KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); case WM_SETFOCUS: case WM_ENABLE: cli.pfnInvalidateRect(hwnd, NULL, FALSE); break; case WM_GETFONT: return (LRESULT)dat->fontInfo[FONTID_CONTACTS].hFont; case INTM_GROUPSCHANGED: { DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *)lParam; if (dbcws->value.type == DBVT_ASCIIZ || dbcws->value.type == DBVT_UTF8) { int groupId = atoi(dbcws->szSetting) + 1; TCHAR szFullName[512]; int i, eq; //check name of group and ignore message if just being expanded/collapsed if (cli.pfnFindItem(hwnd, dat, groupId | HCONTACT_ISGROUP, &contact, &group, NULL)) { mir_tstrcpy(szFullName, contact->szText); while (group->parent) { for (i = 0; i < group->parent->cl.count; i++) if (group->parent->cl.items[i]->group == group) break; if (i == group->parent->cl.count) { szFullName[0] = '\0'; break; } group = group->parent; size_t nameLen = mir_tstrlen(group->cl.items[i]->szText); if (mir_tstrlen(szFullName) + 1 + nameLen > _countof(szFullName)) { szFullName[0] = '\0'; break; } memmove(szFullName + 1 + nameLen, szFullName, sizeof(TCHAR)*(mir_tstrlen(szFullName) + 1)); memcpy(szFullName, group->cl.items[i]->szText, sizeof(TCHAR)*nameLen); szFullName[nameLen] = '\\'; } if (dbcws->value.type == DBVT_ASCIIZ) { WCHAR* wszGrpName = mir_a2u(dbcws->value.pszVal + 1); eq = !mir_tstrcmp(szFullName, wszGrpName); mir_free(wszGrpName); } else { char* szGrpName = NEWSTR_ALLOCA(dbcws->value.pszVal + 1); WCHAR* wszGrpName; Utf8Decode(szGrpName, &wszGrpName); eq = !mir_tstrcmp(szFullName, wszGrpName); mir_free(wszGrpName); } if (eq && (contact->group->hideOffline != 0) == ((dbcws->value.pszVal[0] & GROUPF_HIDEOFFLINE) != 0)) break; //only expanded has changed: no action reqd } } cli.pfnSaveStateAndRebuildList(hwnd, dat); } break; case INTM_NAMEORDERCHANGED: cli.pfnInitAutoRebuild(hwnd); break; case INTM_CONTACTADDED: cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 1); cli.pfnNotifyNewContact(hwnd, wParam); SortClcByTimer(hwnd); break; case INTM_CONTACTDELETED: cli.pfnDeleteItemFromTree(hwnd, wParam); SortClcByTimer(hwnd); break; case INTM_HIDDENCHANGED: { DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *)lParam; if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN) break; if (dbcws->value.type == DBVT_DELETED || dbcws->value.bVal == 0) { if (cli.pfnFindItem(hwnd, dat, wParam, NULL, NULL, NULL)) break; cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 1); cli.pfnNotifyNewContact(hwnd, wParam); } else cli.pfnDeleteItemFromTree(hwnd, wParam); dat->needsResort = 1; SortClcByTimer(hwnd); } break; case INTM_GROUPCHANGED: { WORD iExtraImage[EXTRA_ICON_COUNT]; BYTE flags = 0; if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) memset(iExtraImage, 0xFF, sizeof(iExtraImage)); else { memcpy(iExtraImage, contact->iExtraImage, sizeof(iExtraImage)); flags = contact->flags; } cli.pfnDeleteItemFromTree(hwnd, wParam); if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN || !db_get_b(wParam, "CList", "Hidden", 0)) { NMCLISTCONTROL nm; cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 1); if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) { memcpy(contact->iExtraImage, iExtraImage, sizeof(iExtraImage)); if (flags & CONTACTF_CHECKED) contact->flags |= CONTACTF_CHECKED; } nm.hdr.code = CLN_CONTACTMOVED; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; nm.hItem = (HANDLE)wParam; SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm); dat->needsResort = 1; } } SetTimer(hwnd, TIMERID_REBUILDAFTER, 1, NULL); break; case INTM_ICONCHANGED: { int recalcScrollBar = 0, shouldShow; WORD status; MCONTACT hSelItem = NULL; ClcContact *selcontact = NULL; char *szProto = GetContactProto(wParam); if (szProto == NULL) status = ID_STATUS_OFFLINE; else status = db_get_w(wParam, szProto, "Status", ID_STATUS_OFFLINE); // this means an offline msg is flashing, so the contact should be shown DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); shouldShow = (style & CLS_SHOWHIDDEN || !db_get_b(wParam, "CList", "Hidden", 0)) && (!cli.pfnIsHiddenMode(dat, status) || CallService(MS_CLIST_GETCONTACTICON, wParam, 0) != lParam); contact = NULL; group = NULL; if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, &group, NULL)) { if (shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) { if (dat->selection >= 0 && cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1) hSelItem = (MCONTACT)cli.pfnContactToHItem(selcontact); cli.pfnAddContactToTree(hwnd, dat, wParam, (style & CLS_CONTACTLIST) == 0, 0); recalcScrollBar = 1; cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL); if (contact) { contact->iImage = (WORD)lParam; cli.pfnNotifyNewContact(hwnd, wParam); dat->needsResort = 1; } } } else { // item in list already if (contact->iImage == (WORD)lParam) break; if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) { if (dat->selection >= 0 && cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1) hSelItem = (MCONTACT)cli.pfnContactToHItem(selcontact); cli.pfnRemoveItemFromGroup(hwnd, group, contact, (style & CLS_CONTACTLIST) == 0); recalcScrollBar = 1; } else { contact->iImage = (WORD)lParam; if (!cli.pfnIsHiddenMode(dat, status)) contact->flags |= CONTACTF_ONLINE; else contact->flags &= ~CONTACTF_ONLINE; } dat->needsResort = 1; } if (hSelItem) { ClcGroup *selgroup; if (cli.pfnFindItem(hwnd, dat, hSelItem, &selcontact, &selgroup, NULL)) dat->selection = cli.pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact)); else dat->selection = -1; } SortClcByTimer(hwnd); } break; case INTM_NAMECHANGED: if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) break; mir_tstrncpy(contact->szText, cli.pfnGetContactDisplayName(wParam, 0), _countof(contact->szText)); dat->needsResort = 1; SortClcByTimer(hwnd); break; case INTM_PROTOCHANGED: if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) break; contact->proto = GetContactProto(wParam); cli.pfnInvalidateDisplayNameCacheEntry(wParam); mir_tstrncpy(contact->szText, cli.pfnGetContactDisplayName(wParam, 0), _countof(contact->szText)); SortClcByTimer(hwnd); break; case INTM_NOTONLISTCHANGED: if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) break; if (contact->type == CLCIT_CONTACT) { DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *)lParam; if (dbcws->value.type == DBVT_DELETED || dbcws->value.bVal == 0) contact->flags &= ~CONTACTF_NOTONLIST; else contact->flags |= CONTACTF_NOTONLIST; cli.pfnInvalidateRect(hwnd, NULL, FALSE); } break; case INTM_INVALIDATE: cli.pfnInvalidateRect(hwnd, NULL, FALSE); break; case INTM_APPARENTMODECHANGED: if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) { char *szProto = GetContactProto(wParam); if (szProto == NULL) break; WORD apparentMode = db_get_w(wParam, szProto, "ApparentMode", 0); contact->flags &= ~(CONTACTF_INVISTO | CONTACTF_VISTO); if (apparentMode == ID_STATUS_OFFLINE) contact->flags |= CONTACTF_INVISTO; else if (apparentMode == ID_STATUS_ONLINE) contact->flags |= CONTACTF_VISTO; else if (apparentMode) contact->flags |= CONTACTF_VISTO | CONTACTF_INVISTO; cli.pfnInvalidateRect(hwnd, NULL, FALSE); } break; case INTM_SETINFOTIPHOVERTIME: dat->infoTipTimeout = wParam; break; case INTM_IDLECHANGED: if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) { char *szProto = GetContactProto(wParam); if (szProto == NULL) break; contact->flags &= ~CONTACTF_IDLE; if (db_get_dw(wParam, szProto, "IdleTS", 0)) contact->flags |= CONTACTF_IDLE; cli.pfnInvalidateRect(hwnd, NULL, FALSE); } break; case WM_PRINTCLIENT: cli.pfnPaintClc(hwnd, dat, (HDC)wParam, NULL); break; case WM_NCPAINT: if (wParam != 1) { POINT ptTopLeft = { 0, 0 }; HRGN hClientRgn; ClientToScreen(hwnd, &ptTopLeft); hClientRgn = CreateRectRgn(0, 0, 1, 1); CombineRgn(hClientRgn, (HRGN)wParam, NULL, RGN_COPY); OffsetRgn(hClientRgn, -ptTopLeft.x, -ptTopLeft.y); InvalidateRgn(hwnd, hClientRgn, FALSE); DeleteObject(hClientRgn); UpdateWindow(hwnd); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); /* we get so many cli.pfnInvalidateRect()'s that there is no point painting, Windows in theory shouldn't queue up WM_PAINTs in this case but it does so we'll just ignore them */ if (IsWindowVisible(hwnd)) cli.pfnPaintClc(hwnd, dat, hdc, &ps.rcPaint); EndPaint(hwnd, &ps); } break; case WM_VSCROLL: cli.pfnEndRename(hwnd, dat, 1); cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); { int desty = dat->yScroll, noSmooth = 0; RECT clRect; GetClientRect(hwnd, &clRect); switch (LOWORD(wParam)) { case SB_LINEUP: desty -= dat->rowHeight; break; case SB_LINEDOWN: desty += dat->rowHeight; break; case SB_PAGEUP: desty -= clRect.bottom - dat->rowHeight; break; case SB_PAGEDOWN: desty += clRect.bottom - dat->rowHeight; break; case SB_BOTTOM: desty = 0x7FFFFFFF; break; case SB_TOP: desty = 0; break; case SB_THUMBTRACK: desty = HIWORD(wParam); noSmooth = 1; break; //noone has more than 4000 contacts, right? default: return 0; } cli.pfnScrollTo(hwnd, dat, desty, noSmooth); } break; case WM_MOUSEWHEEL: cli.pfnEndRename(hwnd, dat, 1); cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); { UINT scrollLines; if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, FALSE)) scrollLines = 3; cli.pfnScrollTo(hwnd, dat, dat->yScroll - (short)HIWORD(wParam) * dat->rowHeight * (signed)scrollLines / WHEEL_DELTA, 0); } return 0; case WM_KEYDOWN: { int selMoved = 0; int changeGroupExpand = 0; int pageSize; cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); if (CallService(MS_CLIST_MENUPROCESSHOTKEY, wParam, MPCF_CONTACTMENU)) break; { RECT clRect; GetClientRect(hwnd, &clRect); pageSize = clRect.bottom / dat->rowHeight; } switch (wParam) { case VK_DOWN: dat->selection++; selMoved = 1; break; case VK_UP: dat->selection--; selMoved = 1; break; case VK_PRIOR: dat->selection -= pageSize; selMoved = 1; break; case VK_NEXT: dat->selection += pageSize; selMoved = 1; break; case VK_HOME: dat->selection = 0; selMoved = 1; break; case VK_END: dat->selection = cli.pfnGetGroupContentsCount(&dat->list, 1) - 1; selMoved = 1; break; case VK_LEFT: changeGroupExpand = 1; break; case VK_RIGHT: changeGroupExpand = 2; break; case VK_RETURN: cli.pfnDoSelectionDefaultAction(hwnd, dat); dat->szQuickSearch[0] = 0; if (dat->filterSearch) cli.pfnSaveStateAndRebuildList(hwnd, dat); return 0; case VK_F2: cli.pfnBeginRenameSelection(hwnd, dat); return 0; case VK_DELETE: cli.pfnDeleteFromContactList(hwnd, dat); return 0; default: { NMKEY nmkey; nmkey.hdr.hwndFrom = hwnd; nmkey.hdr.idFrom = GetDlgCtrlID(hwnd); nmkey.hdr.code = NM_KEYDOWN; nmkey.nVKey = wParam; nmkey.uFlags = HIWORD(lParam); if (SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nmkey)) return 0; } } if (changeGroupExpand) { if (!dat->filterSearch) dat->szQuickSearch[0] = 0; hit = cli.pfnGetRowByIndex(dat, dat->selection, &contact, &group); if (hit != -1) { if (changeGroupExpand == 1 && contact->type == CLCIT_CONTACT) { if (group == &dat->list) return 0; dat->selection = cli.pfnGetRowsPriorTo(&dat->list, group, -1); selMoved = 1; } else { if (contact->type == CLCIT_GROUP) cli.pfnSetGroupExpand(hwnd, dat, contact->group, changeGroupExpand == 2); return 0; } } else return 0; } if (selMoved) { if (!dat->filterSearch) dat->szQuickSearch[0] = 0; if (dat->selection >= cli.pfnGetGroupContentsCount(&dat->list, 1)) dat->selection = cli.pfnGetGroupContentsCount(&dat->list, 1) - 1; if (dat->selection < 0) dat->selection = 0; cli.pfnInvalidateRect(hwnd, NULL, FALSE); cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); UpdateWindow(hwnd); return 0; } } break; case WM_CHAR: cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); if (wParam == 27) //escape dat->szQuickSearch[0] = 0; else if (wParam == '\b' && dat->szQuickSearch[0]) dat->szQuickSearch[mir_tstrlen(dat->szQuickSearch) - 1] = '\0'; else if (wParam < ' ') break; else if (wParam == ' ' && dat->szQuickSearch[0] == '\0' && GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CHECKBOXES) { NMCLISTCONTROL nm; if (cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL) == -1) break; if (contact->type != CLCIT_CONTACT) break; contact->flags ^= CONTACTF_CHECKED; if (contact->type == CLCIT_GROUP) cli.pfnSetGroupChildCheckboxes(contact->group, contact->flags & CONTACTF_CHECKED); cli.pfnRecalculateGroupCheckboxes(hwnd, dat); cli.pfnInvalidateRect(hwnd, NULL, FALSE); nm.hdr.code = CLN_CHECKCHANGED; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm); } else { TCHAR szNew[2]; szNew[0] = (TCHAR)wParam; szNew[1] = '\0'; if (mir_tstrlen(dat->szQuickSearch) >= _countof(dat->szQuickSearch) - 1) { MessageBeep(MB_OK); break; } mir_tstrcat(dat->szQuickSearch, szNew); } if (dat->filterSearch) cli.pfnSaveStateAndRebuildList(hwnd, dat); if (dat->szQuickSearch[0]) { int index; index = cli.pfnFindRowByText(hwnd, dat, dat->szQuickSearch, 1); if (index != -1) dat->selection = index; else { MessageBeep(MB_OK); dat->szQuickSearch[mir_tstrlen(dat->szQuickSearch) - 1] = '\0'; cli.pfnSaveStateAndRebuildList(hwnd, dat); } cli.pfnInvalidateRect(hwnd, NULL, FALSE); cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); } else cli.pfnInvalidateRect(hwnd, NULL, FALSE); break; case WM_SYSKEYDOWN: cli.pfnEndRename(hwnd, dat, 1); cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); dat->iHotTrack = -1; cli.pfnInvalidateRect(hwnd, NULL, FALSE); ReleaseCapture(); if (wParam == VK_F10 && GetKeyState(VK_SHIFT) & 0x8000) break; SendMessage(GetParent(hwnd), msg, wParam, lParam); return 0; case WM_TIMER: switch (wParam) { case TIMERID_RENAME: cli.pfnBeginRenameSelection(hwnd, dat); break; case TIMERID_DRAGAUTOSCROLL: cli.pfnScrollTo(hwnd, dat, dat->yScroll + dat->dragAutoScrolling * dat->rowHeight * 2, 0); break; case TIMERID_INFOTIP: { CLCINFOTIP it; RECT clRect; POINT ptClientOffset = { 0 }; KillTimer(hwnd, wParam); GetCursorPos(&it.ptCursor); ScreenToClient(hwnd, &it.ptCursor); if (it.ptCursor.x != dat->ptInfoTip.x || it.ptCursor.y != dat->ptInfoTip.y) break; GetClientRect(hwnd, &clRect); it.rcItem.left = 0; it.rcItem.right = clRect.right; hit = cli.pfnHitTest(hwnd, dat, it.ptCursor.x, it.ptCursor.y, &contact, NULL, NULL); if (hit == -1) break; if (contact->type != CLCIT_GROUP && contact->type != CLCIT_CONTACT) break; ClientToScreen(hwnd, &it.ptCursor); ClientToScreen(hwnd, &ptClientOffset); it.isTreeFocused = GetFocus() == hwnd; it.rcItem.top = cli.pfnGetRowTopY(dat, hit) - dat->yScroll; it.rcItem.bottom = it.rcItem.top + cli.pfnGetRowHeight(dat, hit); OffsetRect(&it.rcItem, ptClientOffset.x, ptClientOffset.y); it.isGroup = contact->type == CLCIT_GROUP; it.hItem = (contact->type == CLCIT_GROUP) ? (HANDLE)contact->groupId : (HANDLE)contact->hContact; it.cbSize = sizeof(it); dat->hInfoTipItem = cli.pfnContactToHItem(contact); NotifyEventHooks(hShowInfoTipEvent, 0, (LPARAM)& it); break; } case TIMERID_REBUILDAFTER: KillTimer(hwnd, TIMERID_REBUILDAFTER); cli.pfnInvalidateRect(hwnd, NULL, FALSE); cli.pfnSaveStateAndRebuildList(hwnd, dat); break; case TIMERID_DELAYEDRESORTCLC: KillTimer(hwnd, TIMERID_DELAYEDRESORTCLC); cli.pfnInvalidateRect(hwnd, NULL, FALSE); cli.pfnSortCLC(hwnd, dat, 1); cli.pfnRecalcScrollBar(hwnd, dat); break; } break; case WM_MBUTTONDOWN: case WM_LBUTTONDOWN: if (GetFocus() != hwnd) SetFocus(hwnd); cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_INFOTIP); KillTimer(hwnd, TIMERID_RENAME); cli.pfnEndRename(hwnd, dat, 1); dat->ptDragStart.x = (short)LOWORD(lParam); dat->ptDragStart.y = (short)HIWORD(lParam); if (!dat->filterSearch) dat->szQuickSearch[0] = 0; hit = cli.pfnHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), &contact, &group, &hitFlags); if (hit != -1) { if (hit == dat->selection && hitFlags & CLCHT_ONITEMLABEL && dat->exStyle & CLS_EX_EDITLABELS) { SetCapture(hwnd); dat->iDragItem = dat->selection; dat->dragStage = DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME; dat->dragAutoScrolling = 0; break; } } if (hit != -1 && contact->type == CLCIT_GROUP) { if (hitFlags & CLCHT_ONITEMICON) { ClcGroup *selgroup; ClcContact *selcontact; dat->selection = cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, &selgroup); cli.pfnSetGroupExpand(hwnd, dat, contact->group, -1); if (dat->selection != -1) { dat->selection = cli.pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact)); if (dat->selection == -1) dat->selection = cli.pfnGetRowsPriorTo(&dat->list, contact->group, -1); } cli.pfnInvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); break; } } if (hit != -1 && hitFlags & CLCHT_ONITEMCHECK) { NMCLISTCONTROL nm; contact->flags ^= CONTACTF_CHECKED; if (contact->type == CLCIT_GROUP) cli.pfnSetGroupChildCheckboxes(contact->group, contact->flags & CONTACTF_CHECKED); cli.pfnRecalculateGroupCheckboxes(hwnd, dat); cli.pfnInvalidateRect(hwnd, NULL, FALSE); nm.hdr.code = CLN_CHECKCHANGED; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)&nm); } if (!(hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMLABEL | CLCHT_ONITEMCHECK))) { NMCLISTCONTROL nm; nm.hdr.code = NM_CLICK; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; if (hit == -1) nm.hItem = NULL; else nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); nm.iColumn = hitFlags & CLCHT_ONITEMEXTRA ? HIBYTE(HIWORD(hitFlags)) : -1; nm.pt = dat->ptDragStart; SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm); } if (hitFlags & (CLCHT_ONITEMCHECK | CLCHT_ONITEMEXTRA)) break; dat->selection = hit; cli.pfnInvalidateRect(hwnd, NULL, FALSE); if (dat->selection != -1) cli.pfnEnsureVisible(hwnd, dat, hit, 0); UpdateWindow(hwnd); if (dat->selection != -1 && (contact->type == CLCIT_CONTACT || contact->type == CLCIT_GROUP) && !(hitFlags & (CLCHT_ONITEMEXTRA | CLCHT_ONITEMCHECK))) { SetCapture(hwnd); dat->iDragItem = dat->selection; dat->dragStage = DRAGSTAGE_NOTMOVED; dat->dragAutoScrolling = 0; } break; case WM_MOUSEMOVE: if (dat->iDragItem == -1) { int iOldHotTrack = dat->iHotTrack; if (dat->hwndRenameEdit != NULL) break; if (GetKeyState(VK_MENU) & 0x8000 || GetKeyState(VK_F10) & 0x8000) break; dat->iHotTrack = cli.pfnHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), NULL, NULL, NULL); if (iOldHotTrack != dat->iHotTrack) { if (iOldHotTrack == -1) SetCapture(hwnd); else if (dat->iHotTrack == -1) ReleaseCapture(); if (dat->exStyle & CLS_EX_TRACKSELECT) { cli.pfnInvalidateItem(hwnd, dat, iOldHotTrack); cli.pfnInvalidateItem(hwnd, dat, dat->iHotTrack); } cli.pfnHideInfoTip(hwnd, dat); } KillTimer(hwnd, TIMERID_INFOTIP); if (wParam == 0 && dat->hInfoTipItem == NULL) { dat->ptInfoTip.x = (short)LOWORD(lParam); dat->ptInfoTip.y = (short)HIWORD(lParam); SetTimer(hwnd, TIMERID_INFOTIP, dat->infoTipTimeout, NULL); } break; } if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_NOTMOVED && !(dat->exStyle & CLS_EX_DISABLEDRAGDROP)) { if (abs((short)LOWORD(lParam) - dat->ptDragStart.x) >= GetSystemMetrics(SM_CXDRAG) || abs((short)HIWORD(lParam) - dat->ptDragStart.y) >= GetSystemMetrics(SM_CYDRAG)) dat->dragStage = (dat->dragStage & ~DRAGSTAGEM_STAGE) | DRAGSTAGE_ACTIVE; } if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) { HCURSOR hNewCursor; RECT clRect; POINT pt; int target; GetClientRect(hwnd, &clRect); pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); hNewCursor = LoadCursor(NULL, IDC_NO); cli.pfnInvalidateRect(hwnd, NULL, FALSE); if (dat->dragAutoScrolling) { KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL); dat->dragAutoScrolling = 0; } target = cli.pfnGetDropTargetInformation(hwnd, dat, pt); if (dat->dragStage & DRAGSTAGEF_OUTSIDE && target != DROPTARGET_OUTSIDE) { cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); NMCLISTCONTROL nm; nm.hdr.code = CLN_DRAGSTOP; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm); dat->dragStage &= ~DRAGSTAGEF_OUTSIDE; } switch (target) { case DROPTARGET_ONSELF: case DROPTARGET_ONCONTACT: break; case DROPTARGET_ONGROUP: hNewCursor = LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER)); break; case DROPTARGET_INSERTION: hNewCursor = LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER)); break; case DROPTARGET_OUTSIDE: { NMCLISTCONTROL nm; if (pt.x >= 0 && pt.x < clRect.right && ((pt.y < 0 && pt.y > -dat->dragAutoScrollHeight) || (pt.y >= clRect.bottom && pt.y < clRect.bottom + dat->dragAutoScrollHeight))) { if (!dat->dragAutoScrolling) { if (pt.y < 0) dat->dragAutoScrolling = -1; else dat->dragAutoScrolling = 1; SetTimer(hwnd, TIMERID_DRAGAUTOSCROLL, dat->scrollTime, NULL); } SendMessage(hwnd, WM_TIMER, TIMERID_DRAGAUTOSCROLL, 0); } dat->dragStage |= DRAGSTAGEF_OUTSIDE; cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); nm.hdr.code = CLN_DRAGGING; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); nm.pt = pt; if (SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm)) return 0; } break; default: cli.pfnGetRowByIndex(dat, dat->iDragItem, NULL, &group); if (group->parent) hNewCursor = LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER)); break; } SetCursor(hNewCursor); } break; case WM_LBUTTONUP: if (dat->iDragItem == -1) break; SetCursor((HCURSOR)GetClassLongPtr(hwnd, GCLP_HCURSOR)); if (dat->exStyle & CLS_EX_TRACKSELECT) { dat->iHotTrack = cli.pfnHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), NULL, NULL, NULL); if (dat->iHotTrack == -1) ReleaseCapture(); } else ReleaseCapture(); KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL); if (dat->dragStage == (DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME)) SetTimer(hwnd, TIMERID_RENAME, GetDoubleClickTime(), NULL); else if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) { POINT pt = { LOWORD(lParam), HIWORD(lParam) }; int target = cli.pfnGetDropTargetInformation(hwnd, dat, pt); switch (target) { case DROPTARGET_ONSELF: case DROPTARGET_ONCONTACT: break; case DROPTARGET_ONGROUP: { ClcContact *contactn, *contacto; cli.pfnGetRowByIndex(dat, dat->selection, &contactn, NULL); cli.pfnGetRowByIndex(dat, dat->iDragItem, &contacto, NULL); if (contacto->type == CLCIT_CONTACT) //dropee is a contact CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)contacto->hContact, contactn->groupId); else if (contacto->type == CLCIT_GROUP) { //dropee is a group TCHAR szNewName[120]; mir_sntprintf(szNewName, _countof(szNewName), _T("%s\\%s"), cli.pfnGetGroupName(contactn->groupId, NULL), contacto->szText); cli.pfnRenameGroup(contacto->groupId, szNewName); } } break; case DROPTARGET_INSERTION: cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); { ClcContact *destcontact; ClcGroup *destgroup; if (cli.pfnGetRowByIndex(dat, dat->iInsertionMark, &destcontact, &destgroup) == -1 || destgroup != contact->group->parent) CallService(MS_CLIST_GROUPMOVEBEFORE, contact->groupId, 0); else { if (destcontact->type == CLCIT_GROUP) destgroup = destcontact->group; CallService(MS_CLIST_GROUPMOVEBEFORE, contact->groupId, destgroup->groupId); } } break; case DROPTARGET_OUTSIDE: cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); { NMCLISTCONTROL nm; nm.hdr.code = CLN_DROPPED; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.flags = 0; nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); nm.pt = pt; SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)& nm); } break; default: cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, &group); if (!group->parent) break; if (contact->type == CLCIT_GROUP) { //dropee is a group TCHAR szNewName[120]; mir_tstrncpy(szNewName, contact->szText, _countof(szNewName)); cli.pfnRenameGroup(contact->groupId, szNewName); } else if (contact->type == CLCIT_CONTACT) //dropee is a contact CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)contact->hContact, 0); } } cli.pfnInvalidateRect(hwnd, NULL, FALSE); dat->iDragItem = -1; dat->iInsertionMark = -1; break; case WM_LBUTTONDBLCLK: ReleaseCapture(); dat->iHotTrack = -1; cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_RENAME); KillTimer(hwnd, TIMERID_INFOTIP); dat->selection = cli.pfnHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), &contact, NULL, &hitFlags); cli.pfnInvalidateRect(hwnd, NULL, FALSE); if (dat->selection != -1) cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); if (!(hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMLABEL))) break; UpdateWindow(hwnd); cli.pfnDoSelectionDefaultAction(hwnd, dat); dat->szQuickSearch[0] = 0; if (dat->filterSearch) cli.pfnSaveStateAndRebuildList(hwnd, dat); break; case WM_CONTEXTMENU: cli.pfnEndRename(hwnd, dat, 1); cli.pfnHideInfoTip(hwnd, dat); KillTimer(hwnd, TIMERID_RENAME); KillTimer(hwnd, TIMERID_INFOTIP); if (GetFocus() != hwnd) SetFocus(hwnd); dat->iHotTrack = -1; if (!dat->filterSearch) dat->szQuickSearch[0] = 0; { POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; if (pt.x == -1 && pt.y == -1) { dat->selection = cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL); if (dat->selection != -1) cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); pt.x = dat->iconXSpace + 15; pt.y = cli.pfnGetRowTopY(dat, dat->selection) - dat->yScroll + (int)(cli.pfnGetRowHeight(dat, dat->selection) * .7); hitFlags = (dat->selection == -1) ? CLCHT_NOWHERE : CLCHT_ONITEMLABEL; } else { ScreenToClient(hwnd, &pt); dat->selection = cli.pfnHitTest(hwnd, dat, pt.x, pt.y, &contact, NULL, &hitFlags); } cli.pfnInvalidateRect(hwnd, NULL, FALSE); if (dat->selection != -1) cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); UpdateWindow(hwnd); if (dat->selection != -1 && hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMCHECK | CLCHT_ONITEMLABEL)) { HMENU hMenu; if (contact->type == CLCIT_GROUP) hMenu = cli.pfnBuildGroupPopupMenu(contact->group); else if (contact->type == CLCIT_CONTACT) hMenu = Menu_BuildContactMenu(contact->hContact); else return 0; ClientToScreen(hwnd, &pt); TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); DestroyMenu(hMenu); } else //call parent for new group/hide offline menu SendMessage(GetParent(hwnd), WM_CONTEXTMENU, wParam, lParam); } return 0; case WM_MEASUREITEM: return Menu_MeasureItem((LPMEASUREITEMSTRUCT)lParam); case WM_DRAWITEM: return Menu_DrawItem((LPDRAWITEMSTRUCT)lParam); case WM_COMMAND: hit = cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL); if (hit == -1) break; if (contact->type == CLCIT_CONTACT) if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)contact->hContact)) break; switch (LOWORD(wParam)) { case POPUP_NEWSUBGROUP: if (contact->type != CLCIT_GROUP) break; SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS); CallService(MS_CLIST_GROUPCREATE, contact->groupId, 0); break; case POPUP_RENAMEGROUP: cli.pfnBeginRenameSelection(hwnd, dat); break; case POPUP_DELETEGROUP: if (contact->type != CLCIT_GROUP) break; CallService(MS_CLIST_GROUPDELETE, contact->groupId, 0); break; case POPUP_GROUPHIDEOFFLINE: if (contact->type != CLCIT_GROUP) break; CallService(MS_CLIST_GROUPSETFLAGS, contact->groupId, MAKELPARAM(contact->group->hideOffline ? 0 : GROUPF_HIDEOFFLINE, GROUPF_HIDEOFFLINE)); break; } break; case WM_DESTROY: cli.pfnHideInfoTip(hwnd, dat); for (int i = 0; i <= FONTID_MAX; i++) if (!dat->fontInfo[i].changed) DeleteObject(dat->fontInfo[i].hFont); if (dat->himlHighlight) ImageList_Destroy(dat->himlHighlight); if (dat->hwndRenameEdit) DestroyWindow(dat->hwndRenameEdit); if (dat->hBmpBackground) DeleteObject(dat->hBmpBackground); cli.pfnFreeGroup(&dat->list); mir_free(dat); cli.pfnUnregisterFileDropping(hwnd); WindowList_Remove(hClcWindowList, hwnd); } return DefWindowProc(hwnd, msg, wParam, lParam); }
static int _AniAva_LoadAvatarFromImage(TCHAR * szFileName, int width, int height, ANIAVATARIMAGEINFO * pRetAII) { ANIAVA_INFO aai={0}; ANIAVA_INFO * paai=NULL; BOOL fNeedInsertToList=FALSE; int idx=0; aai.tcsFilename=szFileName; aai.FrameSize.cx=width; aai.FrameSize.cy=height; if (!li.List_GetIndex(AniAva.AniAvatarList,(void*)&aai,&idx)) idx=-1; if (idx==-1) //item not present in list { HBITMAP hBitmap=NULL; HDC hTempDC; HBITMAP hOldBitmap; HDC hNewDC; HBITMAP hNewBmp; HBITMAP hNewOldBmp; int newWidth; int newHeight; paai=(ANIAVA_INFO *)mir_calloc(sizeof(ANIAVA_INFO)); paai->tcsFilename=mir_tstrdup(szFileName); paai->dwAvatarUniqId=rand(); fNeedInsertToList=TRUE; //get image strip GDIPlus_ExtractAnimatedGIF(szFileName, width, height, &hBitmap, &(paai->pFrameDelays), &(paai->nFrameCount), &(paai->FrameSize)); //copy image to temp DC hTempDC=CreateCompatibleDC(NULL); hOldBitmap=(HBITMAP)SelectObject(hTempDC,hBitmap); //lets create hNewDC /* newWidth=max(paai->FrameSize.cx*paai->nFrameCount,AniAva.width); newHeight=AniAva.height+paai->FrameSize.cy; */ newWidth=AniAva.width+paai->FrameSize.cx*paai->nFrameCount; newHeight=max(paai->FrameSize.cy,AniAva.height); hNewDC=CreateCompatibleDC(NULL); hNewBmp=ske_CreateDIB32(newWidth,newHeight); hNewOldBmp=(HBITMAP)SelectObject(hNewDC,hNewBmp); _AniAva_PausePainting(); GdiFlush(); // copy from old and from new strip BitBlt(hNewDC,0,0,AniAva.width,AniAva.height,AniAva.hAniAvaDC,0,0, SRCCOPY); BitBlt(hNewDC,AniAva.width,0,paai->FrameSize.cx*paai->nFrameCount,paai->FrameSize.cy,hTempDC,0,0, SRCCOPY); paai->nStripTop=AniAva.width; GdiFlush(); //remove temp DC SelectObject(hTempDC,hOldBitmap); DeleteObject(hNewBmp); DeleteDC(hTempDC); DeleteObject(hBitmap); //delete old _AniAva_RemoveAniAvaDC(&AniAva); //setNewDC; AniAva.hAniAvaDC =hNewDC; AniAva.hAniAvaBitmap =hNewBmp; AniAva.hAniAvaOldBitmap =hNewOldBmp; AniAva.width =newWidth; AniAva.height =newHeight; GdiFlush(); _AniAva_ResumePainting(); } else { paai=(ANIAVA_INFO *)AniAva.AniAvatarList->items[idx]; } if (paai) { paai->nRefCount++; pRetAII->nFramesCount=paai->nFrameCount; pRetAII->pFrameDelays=paai->pFrameDelays; pRetAII->ptImagePos.x=paai->nStripTop; pRetAII->ptImagePos.y=0; pRetAII->szSize=paai->FrameSize; if (fNeedInsertToList) { //add to list int idx=AniAva.AniAvatarList->realCount; li.List_GetIndex(AniAva.AniAvatarList, paai,&idx); li.List_Insert(AniAva.AniAvatarList, (void*)paai, idx); } return paai->dwAvatarUniqId; } return 0; }
static INT_PTR CALLBACK FtMgrDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { struct TFtMgrData *dat = (struct TFtMgrData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { TCITEM tci = {0}; HWND hwndTab = GetDlgItem(hwnd, IDC_TABS); TranslateDialogDefault(hwnd); Window_SetIcon_IcoLib(hwnd, SKINICON_EVENT_FILE); dat = (struct TFtMgrData *)mir_calloc(sizeof(struct TFtMgrData)); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); dat->hhkPreshutdown = HookEventMessage(ME_SYSTEM_PRESHUTDOWN, hwnd, M_PRESHUTDOWN); dat->hwndIncoming = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FTPAGE), hwnd, FtMgrPageDlgProc); dat->hwndOutgoing = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FTPAGE), hwnd, FtMgrPageDlgProc); ShowWindow(dat->hwndIncoming, SW_SHOW); tci.mask = TCIF_PARAM|TCIF_TEXT; tci.pszText = TranslateT("Incoming"); tci.lParam = (LPARAM)dat->hwndIncoming; TabCtrl_InsertItem(hwndTab, 0, &tci); tci.pszText = TranslateT("Outgoing"); tci.lParam = (LPARAM)dat->hwndOutgoing; TabCtrl_InsertItem(hwndTab, 1, &tci); // Utils_RestoreWindowPosition(hwnd, NULL, "SRFile", "FtMgrDlg_"); SAVEWINDOWPOS swp; swp.hwnd = hwnd; swp.hContact = NULL; swp.szModule = "SRFile"; swp.szNamePrefix = "FtMgrDlg_"; CallService(MS_UTILS_RESTOREWINDOWPOSITION, RWPF_NOACTIVATE, (LPARAM)&swp); // Fall through to setup initial placement } case WM_SIZE: { RECT rc, rcButton; HDWP hdwp; HWND hwndTab = GetDlgItem(hwnd, IDC_TABS); GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rcButton); OffsetRect(&rcButton, -rcButton.left, -rcButton.top); GetClientRect(hwnd, &rc); InflateRect(&rc, -6, -6); hdwp = BeginDeferWindowPos(3); hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, IDC_CLEAR), NULL, rc.left, rc.bottom-rcButton.bottom, 0, 0, SWP_NOZORDER|SWP_NOSIZE); hdwp = DeferWindowPos(hdwp, GetDlgItem(hwnd, IDCANCEL), NULL, rc.right-rcButton.right, rc.bottom-rcButton.bottom, 0, 0, SWP_NOZORDER|SWP_NOSIZE); rc.bottom -= rcButton.bottom + 5; hdwp = DeferWindowPos(hdwp, hwndTab, NULL, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, SWP_NOZORDER); EndDeferWindowPos(hdwp); GetWindowRect(hwndTab, &rc); MapWindowPoints(NULL, hwnd, (LPPOINT)&rc, 2); TabCtrl_AdjustRect(hwndTab, FALSE, &rc); InflateRect(&rc, -5, -5); hdwp = BeginDeferWindowPos(2); hdwp = DeferWindowPos(hdwp, dat->hwndIncoming, HWND_TOP, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, 0); hdwp = DeferWindowPos(hdwp, dat->hwndOutgoing, HWND_TOP, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, 0); EndDeferWindowPos(hdwp); break; } case WM_MOUSEWHEEL: if (IsWindowVisible(dat->hwndIncoming)) SendMessage(dat->hwndIncoming, msg, wParam, lParam); if (IsWindowVisible(dat->hwndOutgoing)) SendMessage(dat->hwndOutgoing, msg, wParam, lParam); break; case WM_FT_SELECTPAGE: { TCITEM tci = {0}; HWND hwndTab = GetDlgItem(hwnd, IDC_TABS); if (TabCtrl_GetCurSel(hwndTab) == (int)wParam) break; tci.mask = TCIF_PARAM; TabCtrl_GetItem(hwndTab, TabCtrl_GetCurSel(hwndTab), &tci); ShowWindow((HWND)tci.lParam, SW_HIDE); TabCtrl_SetCurSel(hwndTab, wParam); TabCtrl_GetItem(hwndTab, TabCtrl_GetCurSel(hwndTab), &tci); ShowWindow((HWND)tci.lParam, SW_SHOW); } break; case WM_GETMINMAXINFO: { LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam; lpmmi->ptMinTrackSize.x = 300; lpmmi->ptMinTrackSize.y = 400; return 0; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: PostMessage(hwnd, WM_CLOSE , 0, 0); break; case IDC_CLEAR: PostMessage(dat->hwndIncoming, WM_FT_CLEANUP, 0, 0); PostMessage(dat->hwndOutgoing, WM_FT_CLEANUP, 0, 0); break; } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_TABS: { HWND hwndTab = GetDlgItem(hwnd, IDC_TABS); switch (((LPNMHDR)lParam)->code) { case TCN_SELCHANGING: { TCITEM tci = {0}; tci.mask = TCIF_PARAM; TabCtrl_GetItem(hwndTab, TabCtrl_GetCurSel(hwndTab), &tci); ShowWindow((HWND)tci.lParam, SW_HIDE); break; } case TCN_SELCHANGE: { TCITEM tci = {0}; tci.mask = TCIF_PARAM; TabCtrl_GetItem(hwndTab, TabCtrl_GetCurSel(hwndTab), &tci); ShowWindow((HWND)tci.lParam, SW_SHOW); break; } } break; } } break; case M_PRESHUTDOWN: SendMessage(dat->hwndIncoming, M_PRESHUTDOWN, 0, 0); SendMessage(dat->hwndOutgoing, M_PRESHUTDOWN, 0, 0); DestroyWindow(hwnd); break; case WM_CLOSE: ShowWindow(hwnd, SW_HIDE); if (db_get_b(NULL, "SRFile", "AutoClear", 1)) { PostMessage(dat->hwndIncoming, WM_FT_CLEANUP, 0, 0); PostMessage(dat->hwndOutgoing, WM_FT_CLEANUP, 0, 0); } return TRUE; /* Disable default IDCANCEL notification */ case WM_DESTROY: UnhookEvent(dat->hhkPreshutdown); Window_FreeIcon_IcoLib(hwnd); DestroyWindow(dat->hwndIncoming); DestroyWindow(dat->hwndOutgoing); mir_free(dat); SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); Utils_SaveWindowPosition(hwnd, NULL, "SRFile", "FtMgrDlg_"); break; case WM_ACTIVATE: dat->errorState = TBPF_NOPROGRESS; wParam = 1; break; case WM_SHOWWINDOW: if ( !wParam) { // hiding KillTimer(hwnd, 1); break; } lParam = 0; case WM_TIMER: if (pTaskbarInterface) { SetTimer(hwnd, 1, 400, NULL); if ((lParam == ACKRESULT_FAILED) || (lParam == ACKRESULT_DENIED)) dat->errorState = TBPF_ERROR; TFtProgressData prg = {0}; SendMessage(dat->hwndIncoming, M_CALCPROGRESS, (WPARAM)&prg, 0); SendMessage(dat->hwndOutgoing, M_CALCPROGRESS, (WPARAM)&prg, 0); if (dat->errorState) { pTaskbarInterface->SetProgressState(hwnd, dat->errorState); if ( !prg.run) pTaskbarInterface->SetProgressValue(hwnd, 1, 1); } else if (prg.run) pTaskbarInterface->SetProgressState(hwnd, TBPF_NORMAL); else if (prg.init || prg.scan) pTaskbarInterface->SetProgressState(hwnd, TBPF_INDETERMINATE); else { pTaskbarInterface->SetProgressState(hwnd, TBPF_NOPROGRESS); KillTimer(hwnd, 1); } if (prg.run) pTaskbarInterface->SetProgressValue(hwnd, prg.totalProgress, prg.totalBytes); } break; } return FALSE; }
INT_PTR CALLBACK AddContactDlgProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) { AddDialogParam *acs = (AddDialogParam*)GetWindowLongPtr(hdlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: acs = new AddDialogParam(); acs->handleType = HANDLE_SEARCHRESULT; SetWindowLongPtr(hdlg, GWLP_USERDATA, (LONG_PTR)acs); Utils_RestoreWindowPositionNoSize(hdlg, NULL, "AddContact", ""); TranslateDialogDefault(hdlg); SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon(ICON_ADD,1)); SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon(ICON_ADD)); HookEventMessage(ME_SKIN2_ICONSCHANGED, hdlg, DM_ADDCONTACT_CHANGEICONS); HookEventMessage(ME_PROTO_ACCLISTCHANGED, hdlg, DM_ADDCONTACT_CHANGEACCLIST); { TCHAR *szGroup; for (int i = 1; (szGroup = pcli->pfnGetGroupName(i, NULL)) != NULL; i++) { int id = SendDlgItemMessage(hdlg, IDC_GROUP, CB_ADDSTRING, 0, (LPARAM)szGroup); SendDlgItemMessage(hdlg, IDC_GROUP, CB_SETITEMDATA, (WPARAM)id, (LPARAM)i); } } SendDlgItemMessage(hdlg, IDC_GROUP, CB_INSERTSTRING, 0, (LPARAM)TranslateT("None")); SendDlgItemMessage(hdlg, IDC_GROUP, CB_SETCURSEL, 0, 0); { ptrA szProto(db_get_sa(NULL, "AddContact", "LastProto")); if (szProto) acs->proto = szProto; } if (AddContactDlgAccounts(hdlg, acs)) { // By default check these checkboxes CheckDlgButton(hdlg, IDC_ADDED, BST_CHECKED); CheckDlgButton(hdlg, IDC_AUTH, BST_CHECKED); AddContactDlgOpts(hdlg, acs->proto); EnableWindow(GetDlgItem(hdlg, IDOK), FALSE); } break; case WM_COMMAND: switch (LOWORD(wparam)) { case IDC_USERID: if (HIWORD(wparam) == EN_CHANGE) { TCHAR szUserId[256]; if (GetDlgItemText(hdlg, IDC_USERID, szUserId, SIZEOF(szUserId))) { if (!IsWindowEnabled(GetDlgItem(hdlg, IDOK))) EnableWindow(GetDlgItem(hdlg, IDOK), TRUE); } else if (IsWindowEnabled(GetDlgItem(hdlg, IDOK))) EnableWindow(GetDlgItem(hdlg, IDOK), FALSE); } break; case IDC_PROTO: if (HIWORD(wparam) == CBN_SELCHANGE || HIWORD(wparam) == CBN_SELENDOK) { acs->proto = (char*)SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETCURSEL, 0, 0), 0); // TODO remember last setting for each proto? AddContactDlgOpts(hdlg, acs->proto); } break; case IDC_ADDTEMP: AddContactDlgOpts(hdlg, acs->proto, TRUE); break; case IDC_AUTH: { DWORD flags = CallProtoService(acs->proto, PS_GETCAPS, PFLAGNUM_4, 0); if (flags & PF4_NOCUSTOMAUTH) { EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), FALSE); EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), FALSE); } else { EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), IsDlgButtonChecked(hdlg, IDC_AUTH)); EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), IsDlgButtonChecked(hdlg, IDC_AUTH)); } } break; case IDOK: { TCHAR szUserId[256]; GetDlgItemText(hdlg, IDC_USERID, szUserId, SIZEOF(szUserId)); if (*rtrimt(szUserId) == 0 || (strstr(acs->proto, "GG") && _tcstoul(szUserId, NULL, 10) > INT_MAX) || // Gadu-Gadu protocol ((CallProtoService(acs->proto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_NUMERICUSERID) && !_tcstoul(szUserId, NULL, 10))) { MessageBox(NULL, TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."), TranslateT("Add contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); break; } PROTOSEARCHRESULT *psr; if (strstr(acs->proto, "TLEN")) { // Tlen protocol if (_tcschr(szUserId, '@') == NULL) { MessageBox(NULL, TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."), TranslateT("Add contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); break; } psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(TLEN_SEARCH_RESULT)); psr->cbSize = sizeof(TLEN_SEARCH_RESULT); mir_snprintf(((TLEN_SEARCH_RESULT*)psr)->jid, SIZEOF(((TLEN_SEARCH_RESULT*)psr)->jid), "%S", szUserId); } else { psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(PROTOSEARCHRESULT)); psr->cbSize = sizeof(PROTOSEARCHRESULT); } psr->flags = PSR_TCHAR; psr->id = mir_tstrdup(szUserId); acs->psr = psr; HANDLE hContact = (HANDLE)CallProtoService(acs->proto, PS_ADDTOLIST, IsDlgButtonChecked(hdlg, IDC_ADDTEMP) ? PALF_TEMPORARY : 0, (LPARAM)acs->psr); if (hContact == NULL) { MessageBox(NULL, TranslateT("The contact cannot be added to your contact list. If you are not logged into the selected account, please try to do so. Also, make sure the contact ID is entered correctly."), TranslateT("Add contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); break; } TCHAR szHandle[256]; if (GetDlgItemText(hdlg, IDC_MYHANDLE, szHandle, SIZEOF(szHandle))) db_set_ts(hContact, "CList", "MyHandle", szHandle); int item = SendDlgItemMessage(hdlg, IDC_GROUP, CB_GETCURSEL, 0, 0); if (item > 0) { item = SendDlgItemMessage(hdlg, IDC_GROUP, CB_GETITEMDATA, item, 0); CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, item); } if (!IsDlgButtonChecked(hdlg, IDC_ADDTEMP)) { db_unset(hContact, "CList", "NotOnList"); if (IsDlgButtonChecked(hdlg, IDC_ADDED)) CallContactService(hContact, PSS_ADDED, 0, 0); if (IsDlgButtonChecked(hdlg, IDC_AUTH)) { DWORD flags = CallProtoService(acs->proto, PS_GETCAPS, PFLAGNUM_4, 0); if (flags & PF4_NOCUSTOMAUTH) CallContactService(hContact, PSS_AUTHREQUESTT, 0, 0); else { TCHAR szReason[512]; GetDlgItemText(hdlg, IDC_AUTHREQ, szReason, SIZEOF(szReason)); CallContactService(hContact, PSS_AUTHREQUESTT, 0, (LPARAM)szReason); } } } if (GetAsyncKeyState(VK_CONTROL)) CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, (LPARAM)(const char*)NULL); } // fall through case IDCANCEL: if (GetParent(hdlg) == NULL) DestroyWindow(hdlg); else EndDialog(hdlg, 0); } break; case WM_CLOSE: /* if there is no parent for the dialog, its a modeless dialog and can't be killed using EndDialog() */ if (GetParent(hdlg) == NULL) DestroyWindow(hdlg); else EndDialog(hdlg, 0); break; case DM_ADDCONTACT_CHANGEICONS: Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon(ICON_ADD, 1))); Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon(ICON_ADD))); break; case DM_ADDCONTACT_CHANGEACCLIST: AddContactDlgAccounts(hdlg, acs); break; case WM_DESTROY: hAddDlg = NULL; Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_BIG, 0)); Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_SMALL, 0)); ImageList_Destroy((HIMAGELIST)SendDlgItemMessage(hdlg, IDC_PROTO, CBEM_GETIMAGELIST, 0, 0)); if (acs) { db_set_s(NULL, "AddContact", "LastProto", acs->proto); if (acs->psr) { mir_free(acs->psr->nick); mir_free(acs->psr->firstName); mir_free(acs->psr->lastName); mir_free(acs->psr->email); mir_free(acs->psr); } delete acs; } Utils_SaveWindowPosition(hdlg, NULL, "AddContact", ""); break; } return FALSE; }
int UpdateValues(WPARAM hContact, LPARAM lparam) { // to make this code faster if (!hContact) return 0; DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *)lparam; char *szProto = GetContactProto(hContact); if (cws->value.type == DBVT_DWORD && !strcmp(cws->szSetting, "LastSeen") && !mir_strcmp(cws->szModule, szProto)) { DBWriteTimeTS(cws->value.dVal, hContact); HWND hwnd = WindowList_Find(g_pUserInfo, hContact); if (hwnd != NULL) SendMessage(hwnd, WM_REFRESH_UI, hContact, 0); return 0; } BOOL isIdleEvent = includeIdle ? (strcmp(cws->szSetting, "IdleTS") == 0) : 0; if (strcmp(cws->szSetting, "Status") && strcmp(cws->szSetting, "StatusTriger") && (isIdleEvent == 0)) return 0; if (!strcmp(cws->szModule, S_MOD)) { // here we will come when Settings/SeenModule/StatusTriger is changed WORD prevStatus = db_get_w(hContact, S_MOD, "OldStatus", ID_STATUS_OFFLINE); if (includeIdle) { if (db_get_b(hContact, S_MOD, "OldIdle", 0)) prevStatus &= 0x7FFF; else prevStatus |= 0x8000; } if ((cws->value.wVal | 0x8000) <= ID_STATUS_OFFLINE) { // avoid repeating the offline status if ((prevStatus | 0x8000) <= ID_STATUS_OFFLINE) return 0; db_set_b(hContact, S_MOD, "Offline", 1); { char str[MAXMODULELABELLENGTH + 9]; mir_snprintf(str, "OffTime-%s", szProto); DWORD t = db_get_dw(NULL, S_MOD, str, 0); if (!t) t = time(NULL); DBWriteTimeTS(t, hContact); } if (!db_get_b(NULL, S_MOD, "IgnoreOffline", 1)) { if (g_bFileActive) FileWrite(hContact); char *sProto = GetContactProto(hContact); if (CallProtoService(sProto, PS_GETSTATUS, 0, 0) > ID_STATUS_OFFLINE) { myPlaySound(hContact, ID_STATUS_OFFLINE, prevStatus); if (db_get_b(NULL, S_MOD, "UsePopups", 0)) ShowPopup(hContact, sProto, ID_STATUS_OFFLINE); } if (db_get_b(NULL, S_MOD, "KeepHistory", 0)) HistoryWrite(hContact); if (db_get_b(hContact, S_MOD, "OnlineAlert", 0)) ShowHistory(hContact, 1); } } else { if (cws->value.wVal == prevStatus && !db_get_b(hContact, S_MOD, "Offline", 0)) return 0; DBWriteTimeTS(time(NULL), hContact); if (g_bFileActive) FileWrite(hContact); if (prevStatus != cws->value.wVal) myPlaySound(hContact, cws->value.wVal, prevStatus); if (db_get_b(NULL, S_MOD, "UsePopups", 0)) if (prevStatus != cws->value.wVal) ShowPopup(hContact, GetContactProto(hContact), cws->value.wVal | 0x8000); if (db_get_b(NULL, S_MOD, "KeepHistory", 0)) HistoryWrite(hContact); if (db_get_b(hContact, S_MOD, "OnlineAlert", 0)) ShowHistory(hContact, 1); db_set_b(hContact, S_MOD, "Offline", 0); } } else if (hContact && IsWatchedProtocol(cws->szModule) && !db_get_b(hContact, cws->szModule, "ChatRoom", false)) { // here we will come when <User>/<module>/Status is changed or it is idle event and if <module> is watched if (CallProtoService(cws->szModule, PS_GETSTATUS, 0, 0) > ID_STATUS_OFFLINE) { mir_cslock lck(csContacts); logthread_info *p = arContacts.find((logthread_info*)&hContact); if (p == NULL) { p = (logthread_info*)mir_calloc(sizeof(logthread_info)); p->hContact = hContact; mir_strncpy(p->sProtoName, cws->szModule, _countof(p->sProtoName)); arContacts.insert(p); mir_forkthread(waitThread, p); } p->currStatus = isIdleEvent ? db_get_w(hContact, cws->szModule, "Status", ID_STATUS_OFFLINE) : cws->value.wVal; } } return 0; }
void moduleListWM_NOTIFY(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)// hwnd here is to the main window, NOT the treview { switch (((NMHDR *)lParam)->code) { case TVN_ITEMEXPANDINGA: case TVN_ITEMEXPANDINGW: if (populating && ((LPNMTREEVIEW)lParam)->action == TVE_EXPAND) { ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)((LPNMTREEVIEW)lParam)->itemNew.lParam; if (mtis && (mtis->type == (CONTACT | EMPTY))) { TVINSERTSTRUCT tvi; HTREEITEM item = {0}; ModuleTreeInfoStruct *_lParam; HWND hwnd2Tree = GetDlgItem(hwnd2mainWindow, IDC_MODULES); ModSetLinkLinkItem *module; ModuleSettingLL modlist; MCONTACT hContact = mtis->hContact; mtis->type = CONTACT; if (!EnumModules(&modlist)) { msg(Translate("Error loading module list"), modFullname); break; } module = modlist.first; while (module && hwnd2mainWindow) { if (module->name[0] && !IsModuleEmpty(hContact, module->name)) { tvi.hParent = ((LPNMTREEVIEW)lParam)->itemNew.hItem; tvi.hInsertAfter = TVI_SORT; tvi.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; tvi.item.pszText = module->name; _lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct)); _lParam->hContact = hContact; tvi.item.iImage = 5; tvi.item.iSelectedImage = 6; _lParam->type = KNOWN_MODULE; tvi.item.lParam = (LPARAM)_lParam; TreeView_InsertItem(hwnd2Tree, &tvi); } module = (ModSetLinkLinkItem *)module->next; } FreeModuleSettingLL(&modlist); } } break; case TVN_SELCHANGEDA: case TVN_SELCHANGEDW: { ModuleTreeInfoStruct *mtis; LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; TVITEM tvi = {0}; char text[264]; MCONTACT hContact; HWND hwnd2Settings = GetDlgItem(hwnd, IDC_SETTINGS); tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT; tvi.hItem = pnmtv->itemNew.hItem; tvi.pszText = text; tvi.cchTextMax = 264; TreeView_GetItem(pnmtv->hdr.hwndFrom, &tvi); if (tvi.lParam) { mtis = (ModuleTreeInfoStruct *)tvi.lParam; hContact = mtis->hContact; if (mtis->type == STUB) break; if (populating) Select = 0; if (mtis->type == MODULE) { SettingListInfo *info = (SettingListInfo *)GetWindowLongPtr(hwnd2Settings, GWLP_USERDATA); BOOL refresh = 1; if (info) { if (info->hContact == hContact && !mir_strcmp(info->module, text)) refresh = 0; } if (refresh) PopulateSettings(hwnd2Settings, hContact, text); } else if (((mtis->type & CONTACT) == CONTACT && hContact) || (mtis->type == CONTACT_ROOT_ITEM && !hContact)) { char data[32], szProto[256]; int index, loaded, multi = 0; LVITEM lvi = {0}; lvi.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; lvi.iImage = 6; ClearListview(hwnd2Settings); SetWindowLongPtr(hwnd2Settings, GWLP_USERDATA, 0); if (himl2) ListView_SetImageList(hwnd2Settings, himl2, LVSIL_SMALL); if (mtis->type == CONTACT_ROOT_ITEM && !hContact) { multi = 1; hContact = db_find_first(); } while (hContact && hwnd2mainWindow) { if (multi) { // filter if (GetValue(hContact, "Protocol", "p", szProto, SIZEOF(szProto))) loaded = IsProtocolLoaded(szProto); else loaded = 0; if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED)) { hContact = db_find_next(hContact); continue; } } lvi.iItem = 0; lvi.pszText = (char *)GetContactName(hContact, NULL, FALSE); index = ListView_InsertItem(hwnd2Settings, &lvi); mir_snprintf(data, SIZEOF(data), "0x%08X (%ld)", hContact, hContact); ListView_SetItemText(hwnd2Settings, index, 1, data); ListView_SetItemText(hwnd2Settings, index, 2, Translate("HANDLE")); ListView_SetItemText(hwnd2Settings, index, 3, "0x0004 (4)"); if (!multi) break; hContact = db_find_next(hContact); } } else ClearListview(hwnd2Settings); } else // clear any settings that may be there... ClearListview(hwnd2Settings); } break; //TVN_SELCHANGED: case NM_RCLICK: if (((NMHDR *)lParam)->code == NM_RCLICK) moduleListRightClick(hwnd, wParam, lParam); break; case TVN_BEGINLABELEDITA: // subclass it.. case TVN_BEGINLABELEDITW: { LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam; ModuleTreeInfoStruct *mtis = (ModuleTreeInfoStruct *)ptvdi->item.lParam; HWND hwnd2Edit = TreeView_GetEditControl(GetDlgItem(hwnd, IDC_MODULES)); if (!mtis->type || (mtis->type == CONTACT)) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); break; } mir_subclassWindow(hwnd2Edit, ModuleTreeLabelEditSubClassProc); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); } break; case TVN_ENDLABELEDITA: case TVN_ENDLABELEDITW: LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam; TVITEM tvi = {0}; char text[264]; char *newtext; ModuleTreeInfoStruct *mtis; tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM; tvi.hItem = ptvdi->item.hItem; tvi.pszText = text; tvi.cchTextMax = 264; TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); mtis = (ModuleTreeInfoStruct *)ptvdi->item.lParam; newtext = u2a((WCHAR *)ptvdi->item.pszText); if (!newtext // edit control failed || !mtis->type // its a root item || mtis->type == CONTACT // its a contact || *newtext == 0) // empty string SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); else { if (mir_strcmp(tvi.pszText, newtext)) { renameModule(tvi.pszText, newtext, mtis->hContact); findAndRemoveDuplicates(((LPNMHDR)lParam)->hwndFrom, mtis->hContact, newtext); if (TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi)) { tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvi.iImage = 1; tvi.iSelectedImage = 2; TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); PopulateSettings(GetDlgItem(hwnd, IDC_SETTINGS), mtis->hContact, newtext); } } SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); } mir_free(newtext); break; } }
INT_PTR CALLBACK FindWindowDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: SendDlgItemMessage(hwnd, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)TranslateT("Enter a string to search the database for")); CheckDlgButton(hwnd, IDC_MODNAME, BST_CHECKED); CheckDlgButton(hwnd, IDC_SETTINGNAME, BST_CHECKED); CheckDlgButton(hwnd, IDC_SETTINGVALUE, BST_CHECKED); CheckDlgButton(hwnd, IDC_FOUND, BST_CHECKED); SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(ICO_REGEDIT))); SetWindowLongPtr(GetDlgItem(hwnd, IDC_REPLACE), GWLP_USERDATA, 0); SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 0); SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_APPWINDOW); // taskbar icon TranslateDialogDefault(hwnd); ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST), 32 | LVS_EX_LABELTIP); // LVS_EX_GRIDLINES loadListSettings(GetDlgItem(hwnd, IDC_LIST), csResultList); Utils_RestoreWindowPositionNoMove(hwnd, NULL, modname, "Search_"); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDC_SEARCH: if (GetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA)) // stop the search SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 0); else { TCHAR text[FLD_SIZE]; TCHAR replace[FLD_SIZE] = {0}; if (!GetDlgItemText(hwnd, IDC_TEXT, text, _countof(text)) && !IsDlgButtonChecked(hwnd, IDC_EXACT)) break; // empty replace is done only for exact match or entire replace if (LOWORD(wParam) == IDOK && !GetDlgItemText(hwnd, IDC_REPLACE, replace, _countof(replace)) && (!IsDlgButtonChecked(hwnd, IDC_ENTIRELY) && !IsDlgButtonChecked(hwnd, IDC_EXACT))) break; if (BST_UNCHECKED == IsDlgButtonChecked(hwnd, IDC_MODNAME) && BST_UNCHECKED == IsDlgButtonChecked(hwnd, IDC_SETTINGNAME) && BST_UNCHECKED == IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE)) break; FindInfo *fi = (FindInfo*)mir_calloc(sizeof(FindInfo)); if (!fi) break; fi->hwnd = GetDlgItem(hwnd, IDC_LIST); fi->options = (IsDlgButtonChecked(hwnd, IDC_CASESENSITIVE) ? F_CASE : 0) | (IsDlgButtonChecked(hwnd, IDC_EXACT) ? F_EXACT : 0) | (IsDlgButtonChecked(hwnd, IDC_MODNAME) ? F_MODNAME : 0) | (IsDlgButtonChecked(hwnd, IDC_SETTINGNAME) ? F_SETNAME : 0) | (IsDlgButtonChecked(hwnd, IDC_SETTINGVALUE) ? F_SETVAL : 0); if (LOWORD(wParam) == IDOK) { if (IsDlgButtonChecked(hwnd, IDC_ENTIRELY)) fi->options |= F_ENTIRE; fi->replace = mir_tstrdup(replace); SetDlgItemText(hwnd, IDOK, TranslateT("Stop")); EnableWindow(GetDlgItem(hwnd, IDC_SEARCH), 0); } else { SetDlgItemText(hwnd, IDC_SEARCH, TranslateT("Stop")); EnableWindow(GetDlgItem(hwnd, IDOK), 0); } fi->search = mir_tstrdup(text); ListView_DeleteAllItems(fi->hwnd); SetWindowLongPtr(GetDlgItem(hwnd, IDC_SEARCH), GWLP_USERDATA, 1); EnableWindow(GetDlgItem(hwnd, IDCANCEL), 0); mir_forkthread(FindSettings, fi); } break; case IDCANCEL: DestroyWindow(hwnd); break; } break; case WM_GETMINMAXINFO: { MINMAXINFO *mmi = (MINMAXINFO*)lParam; mmi->ptMinTrackSize.x = 610; mmi->ptMinTrackSize.y = 300; } return 0; case WM_SIZE: Utils_ResizeDialog(hwnd, hInst, MAKEINTRESOURCEA(IDD_FIND), FindDialogResize); break; case WM_NOTIFY: if (LOWORD(wParam) != IDC_LIST) break; switch (((NMHDR*)lParam)->code) { case NM_DBLCLK: { LVHITTESTINFO hti; LVITEM lvi; HWND hwndResults = GetDlgItem(hwnd, IDC_LIST); hti.pt = ((NMLISTVIEW*)lParam)->ptAction; if (ListView_SubItemHitTest(hwndResults, &hti) > -1) { if (hti.flags&LVHT_ONITEM) { lvi.mask = LVIF_PARAM; lvi.iItem = hti.iItem; lvi.iSubItem = 0; if (ListView_GetItem(hwndResults, &lvi)) { ItemInfo ii = {0}; ii.hContact = (MCONTACT)lvi.lParam; ListView_GetItemTextA(hwndResults, hti.iItem, 2, ii.module, _countof(ii.module)); ListView_GetItemTextA(hwndResults, hti.iItem, 3, ii.setting, _countof(ii.setting)); if (ii.setting[0]) ii.type = FW_SETTINGNAME; else if (ii.module[0]) ii.type = FW_MODULE; SendMessage(hwnd2mainWindow, WM_FINDITEM, (WPARAM)&ii, 0); } } } break; } case LVN_COLUMNCLICK: { LPNMLISTVIEW lv = (LPNMLISTVIEW)lParam; ColumnsSortParams params; params.hList = GetDlgItem(hwnd, IDC_LIST); params.column = lv->iSubItem; params.last = lastColumn; ListView_SortItemsEx(params.hList, ColumnsCompare, (LPARAM)¶ms); lastColumn = (params.column == lastColumn) ? -1 : params.column; break; } } // switch break; case WM_DESTROY: ListView_DeleteAllItems(GetDlgItem(hwnd, IDC_LIST)); saveListSettings(GetDlgItem(hwnd, IDC_LIST), csResultList); Utils_SaveWindowPosition(hwnd, NULL, modname, "Search_"); break; } return 0; }
int CAimProto::receiving_file(file_transfer *ft, HANDLE hServerPacketRecver, NETLIBPACKETRECVER &packetRecv) { debugLogA("P2P: Entered file receiving thread."); bool failed = true; bool failed_conn = false; bool accepted_file = false; int fid = -1; oft2 *oft = NULL; ft->pfts.tszWorkingDir = mir_utf8decodeT(ft->file); //start listen for packets stuff for (;;) { int recvResult = packetRecv.bytesAvailable - packetRecv.bytesUsed; if (recvResult <= 0) recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)&packetRecv); if (recvResult == 0) { debugLogA("P2P: File transfer connection Error: 0"); break; } if (recvResult == SOCKET_ERROR) { failed_conn = true; debugLogA("P2P: File transfer connection Error: -1"); break; } if (recvResult > 0) { if (!accepted_file) { if (recvResult < 0x100) continue; oft2* recv_ft = (oft2*)&packetRecv.buffer[packetRecv.bytesUsed]; unsigned short pkt_len = _htons(recv_ft->length); if (recvResult < pkt_len) continue; packetRecv.bytesUsed += pkt_len; unsigned short type = _htons(recv_ft->type); if (type == 0x0101) { debugLogA("P2P: Buddy Ready to begin transfer."); oft = (oft2*)mir_realloc(oft, pkt_len); memcpy(oft, recv_ft, pkt_len); memcpy(oft->icbm_cookie, ft->icbm_cookie, 8); int buflen = pkt_len - 0x100 + 64; char *buf = (char*)mir_calloc(buflen + 2); unsigned short enc; ft->pfts.currentFileSize = _htonl(recv_ft->size); ft->pfts.totalBytes = _htonl(recv_ft->total_size); ft->pfts.currentFileTime = _htonl(recv_ft->mod_time); memcpy(buf, recv_ft->filename, buflen); enc = _htons(recv_ft->encoding); TCHAR *name; if (enc == 2) { wchar_t* wbuf = (wchar_t*)buf; wcs_htons(wbuf); for (wchar_t *p = wbuf; *p; ++p) { if (*p == 1) *p = '\\'; } name = mir_u2t(wbuf); } else { for (char *p = buf; *p; ++p) { if (*p == 1) *p = '\\'; } name = mir_a2t(buf); } mir_free(buf); TCHAR fname[256]; mir_sntprintf(fname, _T("%s%s"), ft->pfts.tszWorkingDir, name); mir_free(name); mir_free(ft->pfts.tszCurrentFile); ft->pfts.tszCurrentFile = mir_tstrdup(fname); ResetEvent(ft->hResumeEvent); if (ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, ft, (LPARAM)&ft->pfts)) WaitForSingleObject(ft->hResumeEvent, INFINITE); if (ft->pfts.tszCurrentFile) { TCHAR* dir = get_dir(ft->pfts.tszCurrentFile); CreateDirectoryTreeT(dir); mir_free(dir); oft->type = _htons(ft->pfts.currentFileProgress ? 0x0205 : 0x0202); const int flag = ft->pfts.currentFileProgress ? 0 : _O_TRUNC; fid = _topen(ft->pfts.tszCurrentFile, _O_CREAT | _O_WRONLY | _O_BINARY | flag, _S_IREAD | _S_IWRITE); if (fid < 0) { report_file_error(fname); break; } accepted_file = ft->pfts.currentFileProgress == 0; if (ft->pfts.currentFileProgress) { bool the_same; oft->recv_bytes = _htonl(ft->pfts.currentFileProgress); oft->recv_checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile)); the_same = oft->size == oft->recv_bytes && oft->checksum == oft->recv_checksum; if (the_same) { ft->pfts.totalProgress += ft->pfts.currentFileProgress; oft->type = _htons(0x0204); _close(fid); ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); ++ft->pfts.currentFileNumber; ft->pfts.currentFileProgress = 0; } } } else { oft->type = _htons(0x0204); ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); ++ft->pfts.currentFileNumber; ft->pfts.currentFileProgress = 0; } if (Netlib_Send(ft->hConn, (char*)oft, pkt_len, 0) == SOCKET_ERROR) break; if (ft->pfts.currentFileNumber >= ft->pfts.totalFiles && _htons(oft->type) == 0x0204) { failed = false; break; } } else if (type == 0x0106) { oft = (oft2*)mir_realloc(oft, pkt_len); memcpy(oft, recv_ft, pkt_len); ft->pfts.currentFileProgress = _htonl(oft->recv_bytes); ft->pfts.totalProgress += ft->pfts.currentFileProgress; _lseeki64(fid, ft->pfts.currentFileProgress, SEEK_SET); accepted_file = true; oft->type = _htons(0x0207); if (Netlib_Send(ft->hConn, (char*)oft, pkt_len, 0) == SOCKET_ERROR) break; } else break; } else { packetRecv.bytesUsed = packetRecv.bytesAvailable; _write(fid, packetRecv.buffer, packetRecv.bytesAvailable); ft->pfts.currentFileProgress += packetRecv.bytesAvailable; ft->pfts.totalProgress += packetRecv.bytesAvailable; ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts); if (ft->pfts.currentFileSize == ft->pfts.currentFileProgress) { oft->type = _htons(0x0204); oft->recv_bytes = _htonl(ft->pfts.currentFileProgress); oft->recv_checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile)); debugLogA("P2P: We got the file successfully"); Netlib_Send(ft->hConn, (char*)oft, _htons(oft->length), 0); if (_htons(oft->num_files_left) == 1) { failed = false; break; } else { accepted_file = false; _close(fid); ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); ++ft->pfts.currentFileNumber; ft->pfts.currentFileProgress = 0; } } } } } if (accepted_file) _close(fid); mir_free(oft); ft->success = !failed; return failed ? (failed_conn ? 1 : 2) : 0; }
INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam) { NETLIBBIND *nlb = (NETLIBBIND*)lParam; struct NetlibUser *nlu = (struct NetlibUser*)wParam; struct NetlibBoundPort *nlbp; SOCKADDR_IN sin; int foundPort = 0; UINT dwThreadId; if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_INCOMING) || nlb == NULL || nlb->pfnNewConnection == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if (nlb->cbSize != sizeof(NETLIBBIND) && nlb->cbSize != NETLIBBIND_SIZEOF_V2 && nlb->cbSize != NETLIBBIND_SIZEOF_V1) { return 0; } nlbp = (NetlibBoundPort*)mir_calloc(sizeof(NetlibBoundPort)); nlbp->handleType = NLH_BOUNDPORT; nlbp->nlu = nlu; nlbp->pfnNewConnectionV2 = nlb->pfnNewConnectionV2; nlbp->s = socket(AF_INET, SOCK_STREAM, 0); nlbp->pExtra = (nlb->cbSize != NETLIBBIND_SIZEOF_V1) ? nlb->pExtra : NULL; if (nlbp->s == INVALID_SOCKET) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError()); mir_free(nlbp); return 0; } sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = 0; /* if the netlib user wanted a free port given in the range, then they better have given wPort==0, let's hope so */ if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0) { if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, &nlu->outportnum)) { NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified"); SetLastError(WSAEADDRINUSE); } else foundPort = 1; } else { /* if ->wPort==0 then they'll get any free port, otherwise they'll be asking for whatever was in nlb->wPort*/ if (nlb->wPort != 0) { NetlibLogf(nlu,"%s %d: trying to bind port %d, this 'feature' can be abused, please be sure you want to allow it.",__FILE__,__LINE__,nlb->wPort); sin.sin_port = htons(nlb->wPort); } if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0) foundPort = 1; } if (!foundPort) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"bind",WSAGetLastError()); closesocket(nlbp->s); mir_free(nlbp); return 0; } if (listen(nlbp->s, 5)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"listen",WSAGetLastError()); closesocket(nlbp->s); mir_free(nlbp); return 0; } { int len; DWORD extIP; ZeroMemory(&sin,sizeof(sin)); len = sizeof(sin); if (getsockname(nlbp->s,(SOCKADDR *)&sin,&len)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"getsockname",WSAGetLastError()); closesocket(nlbp->s); mir_free(nlbp); return 0; } nlb->wPort = ntohs(sin.sin_port); nlbp->wPort = nlb->wPort; nlb->dwInternalIP = ntohl(sin.sin_addr.S_un.S_addr); if (nlb->dwInternalIP == 0) { char hostname[64]; struct hostent *he; gethostname(hostname, SIZEOF(hostname)); he = gethostbyname(hostname); if (he && he->h_addr_list[0]) nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr_list[0]); } if (nlu->settings.enableUPnP && NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, nlb->cbSize > NETLIBBIND_SIZEOF_V2)) { NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n", nlb->wPort, nlbp->wExPort); if (nlb->cbSize > NETLIBBIND_SIZEOF_V2) { nlb->wExPort = nlbp->wExPort; nlb->dwExternalIP = extIP; } } else { if (nlu->settings.enableUPnP) NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort); else NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort); nlbp->wExPort = 0; if (nlb->cbSize > NETLIBBIND_SIZEOF_V2) { nlb->wExPort = nlb->wPort; nlb->dwExternalIP = nlb->dwInternalIP; } } } nlbp->hThread = (HANDLE)forkthreadex(NULL, 0, NetlibBindAcceptThread, 0, nlbp, &dwThreadId); return (INT_PTR)nlbp; }