From f0ce988dc9622e7b15736001124d73834653955e Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 11 Feb 2023 13:32:29 +0300 Subject: fix for occasional crash in file receive dialog --- src/core/stdfile/src/file.cpp | 6 +- src/core/stdfile/src/file.h | 20 +- src/core/stdfile/src/filerecvdlg.cpp | 398 ++++++++++++++++++----------------- 3 files changed, 222 insertions(+), 202 deletions(-) diff --git a/src/core/stdfile/src/file.cpp b/src/core/stdfile/src/file.cpp index 254cbbebd7..4bda297d0c 100644 --- a/src/core/stdfile/src/file.cpp +++ b/src/core/stdfile/src/file.cpp @@ -81,18 +81,18 @@ static INT_PTR GetReceivedFilesFolder(WPARAM wParam, LPARAM lParam) static INT_PTR RecvFileCommand(WPARAM, LPARAM lParam) { - CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_FILERECV), NULL, DlgProcRecvFile, lParam); + LaunchRecvDialog((CLISTEVENT *)lParam); return 0; } -void PushFileEvent(MCONTACT hContact, MEVENT hdbe, LPARAM lParam) +static void PushFileEvent(MCONTACT hContact, MEVENT hdbe, LPARAM lParam) { CLISTEVENT cle = {}; cle.hContact = hContact; cle.hDbEvent = hdbe; cle.lParam = lParam; if (g_plugin.bAutoAccept && Contact::OnList(hContact)) { - CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_FILERECV), NULL, DlgProcRecvFile, (LPARAM)&cle); + LaunchRecvDialog(&cle); } else { Skin_PlaySound("RecvFile"); diff --git a/src/core/stdfile/src/file.h b/src/core/stdfile/src/file.h index 60e38c907f..e586ba645d 100644 --- a/src/core/stdfile/src/file.h +++ b/src/core/stdfile/src/file.h @@ -86,27 +86,33 @@ void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts); void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src); void UpdateProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src); int SRFile_GetRegValue(HKEY hKeyBase, const wchar_t *szSubKey, const wchar_t *szValue, wchar_t *szOutput, int cbOutput); -//filesenddlg.c + +// filesenddlg.c INT_PTR CALLBACK DlgProcSendFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//filerecv.c -INT_PTR CALLBACK DlgProcRecvFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +// filerecv.c +void LaunchRecvDialog(CLISTEVENT *cle); void RemoveInvalidFilenameChars(wchar_t *tszString); void RemoveInvalidPathChars(wchar_t *tszString); void GetContactReceivedFilesDir(MCONTACT hContact, wchar_t *szDir, int cchDir, BOOL substVars); void GetReceivedFilesDir(wchar_t *szDir, int cchDir); int BrowseForFolder(HWND hwnd, wchar_t *szPath); -//fileexistsdlg.c + +// fileexistsdlg.c struct TDlgProcFileExistsParam { HWND hwndParent; PROTOFILETRANSFERSTATUS *fts; }; INT_PTR CALLBACK DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//filexferdlg.c + +// filexferdlg.c INT_PTR CALLBACK DlgProcFileTransfer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//fileopts.c + +// fileopts.c int FileOptInitialise(WPARAM wParam, LPARAM lParam); -//ftmanager.c + +// ftmanager.c #define WM_FT_ADD (WM_USER+701) #define WM_FT_RESIZE (WM_USER+702) #define WM_FT_REMOVE (WM_USER+703) diff --git a/src/core/stdfile/src/filerecvdlg.cpp b/src/core/stdfile/src/filerecvdlg.cpp index b784e09c24..8a0b0fd0dc 100644 --- a/src/core/stdfile/src/filerecvdlg.cpp +++ b/src/core/stdfile/src/filerecvdlg.cpp @@ -176,230 +176,244 @@ void GetReceivedFilesDir(wchar_t *szDir, int cchDir) mir_wstrncpy(szDir, tszTemp, cchDir); } -INT_PTR CALLBACK DlgProcRecvFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +class CRecvFileDlg : public CDlgBase { - FileDlgData *dat = (FileDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - wchar_t szPath[450]; - CLISTEVENT* cle = (CLISTEVENT*)lParam; - - dat = new 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_SetSkin_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact permanently to list")); - Button_SetSkin_IcoLib(hwndDlg, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View user's details")); - Button_SetSkin_IcoLib(hwndDlg, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View user's history")); - Button_SetSkin_IcoLib(hwndDlg, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User menu")); - - wchar_t *contactName = Clist_GetContactDisplayName(dat->hContact); - 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); + FileDlgData *dat; + LPARAM m_lParam; + + CCtrlButton btnCancel, btnBrowse, btnAdd, btnUserMenu, btnDetails, btnHistory; + +public: + CRecvFileDlg(CLISTEVENT *cle) : + CDlgBase(g_plugin, IDD_FILERECV), + btnAdd(this, IDC_ADD), + btnCancel(this, IDCANCEL), + btnBrowse(this, IDC_FILEDIRBROWSE), + btnDetails(this, IDC_DETAILS), + btnHistory(this, IDC_HISTORY), + btnUserMenu(this, IDC_USERMENU) + { + dat = new FileDlgData(); + dat->hContact = cle->hContact; + dat->hDbEvent = cle->hDbEvent; + dat->dwTicks = GetTickCount(); + m_lParam = cle->lParam; + + btnAdd.OnClick = Callback(this, &CRecvFileDlg::onClick_Add); + btnCancel.OnClick = Callback(this, &CRecvFileDlg::onClick_Cancel); + btnBrowse.OnClick = Callback(this, &CRecvFileDlg::onClick_Browse); + btnDetails.OnClick = Callback(this, &CRecvFileDlg::onClick_Details); + btnHistory.OnClick = Callback(this, &CRecvFileDlg::onClick_History); + btnUserMenu.OnClick = Callback(this, &CRecvFileDlg::onClick_UserMenu); + } - DBVARIANT dbv; - if (g_plugin.getWString(idstr, &dbv)) - break; - SendDlgItemMessage(hwndDlg, IDC_FILEDIR, CB_ADDSTRING, 0, (LPARAM)dbv.pwszVal); - db_free(&dbv); - } + bool OnInitDialog() override + { + dat->hNotifyEvent = HookEventMessage(ME_PROTO_ACK, m_hwnd, HM_RECVEVENT); + dat->hPreshutdownEvent = HookEventMessage(ME_SYSTEM_PRESHUTDOWN, m_hwnd, M_PRESHUTDOWN); - db_event_markRead(dat->hContact, dat->hDbEvent); + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)dat); - DB::EventInfo dbei; - dbei.cbBlob = -1; - if (!db_event_get(dat->hDbEvent, &dbei)) { - dat->fs = cle->lParam ? (HANDLE)cle->lParam : (HANDLE)*(PDWORD)dbei.pBlob; + EnumChildWindows(m_hwnd, ClipSiblingsChildEnumProc, 0); - char *str = (char*)dbei.pBlob + 4; - ptrW ptszFileName(DbEvent_GetString(&dbei, str)); - SetDlgItemText(hwndDlg, IDC_FILENAMES, ptszFileName); + Window_SetSkinIcon_IcoLib(m_hwnd, SKINICON_EVENT_FILE); + Button_SetSkin_IcoLib(m_hwnd, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact permanently to list")); + Button_SetSkin_IcoLib(m_hwnd, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View user's details")); + Button_SetSkin_IcoLib(m_hwnd, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View user's history")); + Button_SetSkin_IcoLib(m_hwnd, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User menu")); - unsigned len = (unsigned)mir_strlen(str) + 1; - if (len + 4 < dbei.cbBlob) { - str += len; - ptrW pwszDescription(DbEvent_GetString(&dbei, str)); - SetDlgItemText(hwndDlg, IDC_MSG, pwszDescription); - } - } - else DestroyWindow(hwndDlg); + wchar_t *contactName = Clist_GetContactDisplayName(dat->hContact); + SetDlgItemText(m_hwnd, IDC_FROM, contactName); - wchar_t datetimestr[64]; - TimeZone_PrintTimeStamp(NULL, dbei.timestamp, L"t d", datetimestr, _countof(datetimestr), 0); - SetDlgItemText(hwndDlg, IDC_DATE, datetimestr); + wchar_t szPath[450]; + GetContactReceivedFilesDir(dat->hContact, szPath, _countof(szPath), TRUE); + SetDlgItemText(m_hwnd, IDC_FILEDIR, szPath); + SHAutoComplete(GetWindow(GetDlgItem(m_hwnd, IDC_FILEDIR), GW_CHILD), 1); - ptrW info(Contact::GetInfo(CNF_UNIQUEID, dat->hContact)); - SetDlgItemText(hwndDlg, IDC_NAME, (info) ? info : contactName); + for (int i = 0; i < MAX_MRU_DIRS; i++) { + char idstr[32]; + mir_snprintf(idstr, "MruDir%d", i); - if (!Contact::OnList(dat->hContact)) { - 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 (g_plugin.bAutoAccept) { - //don't check auto-min here to fix BUG#647620 - PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, IDOK)); - } - if (Contact::OnList(dat->hContact)) - ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); - } - return TRUE; - - case WM_MEASUREITEM: - return Menu_MeasureItem(lParam); - - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; - if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_PROTOCOL)) { - char *szProto = Proto_GetBaseAccountName(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, nullptr, DI_NORMAL); - DestroyIcon(hIcon); - } - } - } + DBVARIANT dbv; + if (g_plugin.getWString(idstr, &dbv)) + break; + SendDlgItemMessage(m_hwnd, IDC_FILEDIR, CB_ADDSTRING, 0, (LPARAM)dbv.pwszVal); + db_free(&dbv); } - return Menu_DrawItem(lParam); - case WM_COMMAND: - if (Clist_MenuProcessCommand(LOWORD(wParam), MPCF_CONTACTMENU, dat->hContact)) - break; + db_event_markRead(dat->hContact, dat->hDbEvent); - switch (LOWORD(wParam)) { - case IDC_FILEDIRBROWSE: - { - wchar_t szDirName[MAX_PATH], szExistingDirName[MAX_PATH]; + DB::EventInfo dbei; + dbei.cbBlob = -1; + if (db_event_get(dat->hDbEvent, &dbei)) + return false; - GetDlgItemText(hwndDlg, IDC_FILEDIR, szDirName, _countof(szDirName)); - GetLowestExistingDirName(szDirName, szExistingDirName, _countof(szExistingDirName)); - if (BrowseForFolder(hwndDlg, szExistingDirName)) - SetDlgItemText(hwndDlg, IDC_FILEDIR, szExistingDirName); - } - break; + dat->fs = m_lParam ? (HANDLE)m_lParam : (HANDLE)*(PDWORD)dbei.pBlob; - case IDOK: - { //most recently used directories - wchar_t szRecvDir[MAX_PATH], szDefaultRecvDir[MAX_PATH]; - GetDlgItemText(hwndDlg, IDC_FILEDIR, szRecvDir, _countof(szRecvDir)); - RemoveInvalidPathChars(szRecvDir); - GetContactReceivedFilesDir(NULL, szDefaultRecvDir, _countof(szDefaultRecvDir), TRUE); - if (wcsnicmp(szRecvDir, szDefaultRecvDir, mir_wstrlen(szDefaultRecvDir))) { - char idstr[32]; - int i; - DBVARIANT dbv; - for (i = MAX_MRU_DIRS-2;i>=0;i--) { - mir_snprintf(idstr, "MruDir%d", i); - if (g_plugin.getWString(idstr, &dbv)) continue; - mir_snprintf(idstr, "MruDir%d", i+1); - g_plugin.setWString(idstr, dbv.pwszVal); - db_free(&dbv); - } - g_plugin.setWString(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)); - FtMgr_AddTransfer(dat); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); - //check for auto-minimize here to fix BUG#647620 - if (g_plugin.bAutoAccept && g_plugin.bAutoMin) { - ShowWindow(hwndDlg, SW_HIDE); - ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); - } - DestroyWindow(hwndDlg); - break; + char *str = (char *)dbei.pBlob + 4; + ptrW ptszFileName(DbEvent_GetString(&dbei, str)); + SetDlgItemText(m_hwnd, IDC_FILENAMES, ptszFileName); - case IDCANCEL: - if (dat->fs) ProtoChainSend(dat->hContact, PSS_FILEDENY, (WPARAM)dat->fs, (LPARAM)TranslateT("Canceled")); - dat->fs = nullptr; /* the protocol will free the handle */ - DestroyWindow(hwndDlg); - break; + int len = (int)mir_strlen(str) + 1; + if (len + 4 < dbei.cbBlob) { + str += len; + ptrW pwszDescription(DbEvent_GetString(&dbei, str)); + SetDlgItemText(m_hwnd, IDC_MSG, pwszDescription); + } - case IDC_ADD: - Contact::Add(dat->hContact, hwndDlg); + wchar_t datetimestr[64]; + TimeZone_PrintTimeStamp(NULL, dbei.timestamp, L"t d", datetimestr, _countof(datetimestr), 0); + SetDlgItemText(m_hwnd, IDC_DATE, datetimestr); - if (Contact::OnList(dat->hContact)) - ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); - break; + ptrW info(Contact::GetInfo(CNF_UNIQUEID, dat->hContact)); + SetDlgItemText(m_hwnd, IDC_NAME, (info) ? info : contactName); - 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); + if (!Contact::OnList(dat->hContact)) { + RECT rcBtn1, rcBtn2, rcDateCtrl; + GetWindowRect(GetDlgItem(m_hwnd, IDC_ADD), &rcBtn1); + GetWindowRect(GetDlgItem(m_hwnd, IDC_USERMENU), &rcBtn2); + GetWindowRect(GetDlgItem(m_hwnd, IDC_DATE), &rcDateCtrl); + SetWindowPos(GetDlgItem(m_hwnd, IDC_DATE), 0, 0, 0, rcDateCtrl.right - rcDateCtrl.left - (rcBtn2.left - rcBtn1.left), rcDateCtrl.bottom - rcDateCtrl.top, SWP_NOZORDER | SWP_NOMOVE); + } + else if (g_plugin.bAutoAccept) { + //don't check auto-min here to fix BUG#647620 + PostMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)GetDlgItem(m_hwnd, IDOK)); + } + if (Contact::OnList(dat->hContact)) + btnAdd.Hide(); + return true; + } + + bool OnApply() override + { + // most recently used directories + wchar_t szRecvDir[MAX_PATH], szDefaultRecvDir[MAX_PATH]; + GetDlgItemText(m_hwnd, IDC_FILEDIR, szRecvDir, _countof(szRecvDir)); + RemoveInvalidPathChars(szRecvDir); + GetContactReceivedFilesDir(NULL, szDefaultRecvDir, _countof(szDefaultRecvDir), TRUE); + if (wcsnicmp(szRecvDir, szDefaultRecvDir, mir_wstrlen(szDefaultRecvDir))) { + char idstr[32]; + int i; + DBVARIANT dbv; + for (i = MAX_MRU_DIRS - 2; i >= 0; i--) { + mir_snprintf(idstr, "MruDir%d", i); + if (g_plugin.getWString(idstr, &dbv)) continue; + mir_snprintf(idstr, "MruDir%d", i + 1); + g_plugin.setWString(idstr, dbv.pwszVal); + db_free(&dbv); } - break; + g_plugin.setWString(idstr, szRecvDir); + } - case IDC_DETAILS: - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)dat->hContact, 0); - break; + EnableWindow(GetDlgItem(m_hwnd, IDC_FILENAMES), FALSE); + EnableWindow(GetDlgItem(m_hwnd, IDC_MSG), FALSE); + EnableWindow(GetDlgItem(m_hwnd, IDC_FILEDIR), FALSE); + EnableWindow(GetDlgItem(m_hwnd, IDC_FILEDIRBROWSE), FALSE); + + GetDlgItemText(m_hwnd, IDC_FILEDIR, dat->szSavePath, _countof(dat->szSavePath)); + GetDlgItemText(m_hwnd, IDC_FILE, dat->szFilenames, _countof(dat->szFilenames)); + GetDlgItemText(m_hwnd, IDC_MSG, dat->szMsg, _countof(dat->szMsg)); + FtMgr_AddTransfer(dat); + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); + + // check for auto-minimize here to fix BUG#647620 + if (g_plugin.bAutoAccept && g_plugin.bAutoMin) { + ShowWindow(m_hwnd, SW_HIDE); + ShowWindow(m_hwnd, SW_SHOWMINNOACTIVE); + } + return true; + } + + void OnDestroy() override + { + Window_FreeIcon_IcoLib(m_hwnd); + Button_FreeIcon_IcoLib(m_hwnd, IDC_ADD); + Button_FreeIcon_IcoLib(m_hwnd, IDC_DETAILS); + Button_FreeIcon_IcoLib(m_hwnd, IDC_HISTORY); + Button_FreeIcon_IcoLib(m_hwnd, IDC_USERMENU); + + delete dat; + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); + } - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)dat->hContact, 0); + INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override + { + switch (msg) { + case WM_COMMAND: + if (Clist_MenuProcessCommand(LOWORD(wParam), MPCF_CONTACTMENU, dat->hContact)) + return 1; break; - } - break; - case HM_RECVEVENT: - { - ACKDATA *ack = (ACKDATA*)lParam; + case HM_RECVEVENT: + ACKDATA *ack = (ACKDATA *)lParam; if ((ack == nullptr) || (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")); + EnableWindow(GetDlgItem(m_hwnd, IDOK), FALSE); + EnableWindow(GetDlgItem(m_hwnd, IDC_FILEDIR), FALSE); + EnableWindow(GetDlgItem(m_hwnd, IDC_FILEDIRBROWSE), FALSE); + SetDlgItemText(m_hwnd, IDC_MSG, TranslateT("This file transfer has been canceled by the other side")); Skin_PlaySound("FileDenied"); - FlashWindow(hwndDlg, TRUE); + FlashWindow(m_hwnd, TRUE); } - else if (ack->result != ACKRESULT_FILERESUME) - { - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), (LPARAM)GetDlgItem(hwndDlg, IDCANCEL)); + else if (ack->result != ACKRESULT_FILERESUME) { + SendMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), (LPARAM)GetDlgItem(m_hwnd, IDCANCEL)); } + break; } - 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); + return CDlgBase::DlgProc(msg, wParam, lParam); + } - delete dat; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); - break; + void onClick_Browse(CCtrlButton *) + { + wchar_t szDirName[MAX_PATH], szExistingDirName[MAX_PATH]; + + GetDlgItemText(m_hwnd, IDC_FILEDIR, szDirName, _countof(szDirName)); + GetLowestExistingDirName(szDirName, szExistingDirName, _countof(szExistingDirName)); + if (BrowseForFolder(m_hwnd, szExistingDirName)) + SetDlgItemText(m_hwnd, IDC_FILEDIR, szExistingDirName); } - return FALSE; + + void onClick_Cancel(CCtrlButton *) + { + if (dat->fs) { + ProtoChainSend(dat->hContact, PSS_FILEDENY, (WPARAM)dat->fs, (LPARAM)TranslateT("Canceled")); + dat->fs = nullptr; /* the protocol will free the handle */ + } + } + + void onClick_Add(CCtrlButton *) + { + Contact::Add(dat->hContact, m_hwnd); + + if (Contact::OnList(dat->hContact)) + ShowWindow(GetDlgItem(m_hwnd, IDC_ADD), SW_HIDE); + } + + void onClick_UserMenu(CCtrlButton *pButton) + { + RECT rc; + GetWindowRect(pButton->GetHwnd(), &rc); + HMENU hMenu = Menu_BuildContactMenu(dat->hContact); + TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, m_hwnd, NULL); + DestroyMenu(hMenu); + } + + void onClick_Details(CCtrlButton *) + { + CallService(MS_USERINFO_SHOWDIALOG, dat->hContact, 0); + } + + void onClick_History(CCtrlButton *) + { + CallService(MS_HISTORY_SHOWCONTACTHISTORY, dat->hContact, 0); + } +}; + +void LaunchRecvDialog(CLISTEVENT *cle) +{ + auto *pDlg = new CRecvFileDlg(cle); + pDlg->Show(); } -- cgit v1.2.3