diff options
author | George Hazan <ghazan@miranda.im> | 2018-01-10 18:24:43 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-01-10 18:24:43 +0300 |
commit | f099d2dab8bedfefde9ef773eb2b101012a5735a (patch) | |
tree | fb72553911ab83b6d10ddeb0a8422f8c37b003da /plugins/YAMN/src/browser | |
parent | e41640fee393d00fd536da37f98ee85265dfc303 (diff) |
double handle closing removed
Diffstat (limited to 'plugins/YAMN/src/browser')
-rw-r--r-- | plugins/YAMN/src/browser/badconnect.cpp | 238 | ||||
-rw-r--r-- | plugins/YAMN/src/browser/mailbrowser.cpp | 216 |
2 files changed, 205 insertions, 249 deletions
diff --git a/plugins/YAMN/src/browser/badconnect.cpp b/plugins/YAMN/src/browser/badconnect.cpp index d66878578e..6bc632e730 100644 --- a/plugins/YAMN/src/browser/badconnect.cpp +++ b/plugins/YAMN/src/browser/badconnect.cpp @@ -9,7 +9,7 @@ #define BADCONNECTTITLE LPGEN("%s - connection error")
#define BADCONNECTMSG LPGEN("An error occurred. Error code: %d")//is in use?
-//--------------------------------------------------------------------------------------------------
+ //--------------------------------------------------------------------------------------------------
LRESULT CALLBACK BadConnectPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
@@ -24,11 +24,11 @@ LRESULT CALLBACK BadConnectPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM si.cb = sizeof(si);
HACCOUNT ActualAccount = (HACCOUNT)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0);
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read wait\n");
+ DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read wait\n");
#endif
if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) {
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read enter\n");
+ DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read enter\n");
#endif
if (ActualAccount->BadConnectN.App != nullptr) {
WCHAR *Command;
@@ -48,13 +48,13 @@ LRESULT CALLBACK BadConnectPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM }
}
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read done\n");
+ DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read done\n");
#endif
ReadDoneFcn(ActualAccount->AccountAccessSO);
}
#ifdef DEBUG_SYNCHRO
else
- DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read enter failed\n");
+ DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read enter failed\n");
#endif
PUDeletePopup(hWnd);
}
@@ -76,108 +76,103 @@ LRESULT CALLBACK BadConnectPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM INT_PTR CALLBACK DlgProcYAMNBadConnection(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
- switch (msg)
- {
+ switch (msg) {
case WM_INITDIALOG:
- {
- BOOL ShowPopup, ShowMsg, ShowIco;
- HACCOUNT ActualAccount;
- DWORD ErrorCode;
- char* TitleStrA;
- char *Message1A = nullptr;
- wchar_t *Message1W = nullptr;
- POPUPDATAT BadConnectPopup;
-
- ActualAccount = ((struct BadConnectionParam *)lParam)->account;
- ErrorCode = ((struct BadConnectionParam *)lParam)->errcode;
+ {
+ BOOL ShowPopup, ShowMsg, ShowIco;
+ HACCOUNT ActualAccount;
+ DWORD ErrorCode;
+ char* TitleStrA;
+ char *Message1A = nullptr;
+ wchar_t *Message1W = nullptr;
+ POPUPDATAT BadConnectPopup;
+
+ ActualAccount = ((struct BadConnectionParam *)lParam)->account;
+ ErrorCode = ((struct BadConnectionParam *)lParam)->errcode;
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read wait\n");
#endif
- if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO))
- {
+ if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) {
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait failed\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read wait failed\n");
#endif
- return FALSE;
- }
+ return FALSE;
+ }
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read enter\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read enter\n");
#endif
- int size = (int)(mir_strlen(ActualAccount->Name) + mir_strlen(Translate(BADCONNECTTITLE)));
- TitleStrA = new char[size];
- mir_snprintf(TitleStrA, size, Translate(BADCONNECTTITLE), ActualAccount->Name);
-
- ShowPopup = ActualAccount->BadConnectN.Flags & YAMN_ACC_POP;
- ShowMsg = ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG;
- ShowIco = ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO;
-
- if (ShowPopup) {
- BadConnectPopup.lchIcon = g_LoadIconEx(3);
- BadConnectPopup.colorBack = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupB : GetSysColor(COLOR_BTNFACE);
- BadConnectPopup.colorText = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupT : GetSysColor(COLOR_WINDOWTEXT);
- BadConnectPopup.iSeconds = ActualAccount->BadConnectN.PopupTime;
-
- BadConnectPopup.PluginWindowProc = BadConnectPopupProc;
- BadConnectPopup.PluginData = ActualAccount;
- mir_wstrncpy(BadConnectPopup.lptzContactName, _A2T(ActualAccount->Name), _countof(BadConnectPopup.lptzContactName));
- }
+ int size = (int)(mir_strlen(ActualAccount->Name) + mir_strlen(Translate(BADCONNECTTITLE)));
+ TitleStrA = new char[size];
+ mir_snprintf(TitleStrA, size, Translate(BADCONNECTTITLE), ActualAccount->Name);
+
+ ShowPopup = ActualAccount->BadConnectN.Flags & YAMN_ACC_POP;
+ ShowMsg = ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG;
+ ShowIco = ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO;
+
+ if (ShowPopup) {
+ BadConnectPopup.lchIcon = g_LoadIconEx(3);
+ BadConnectPopup.colorBack = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupB : GetSysColor(COLOR_BTNFACE);
+ BadConnectPopup.colorText = ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopupT : GetSysColor(COLOR_WINDOWTEXT);
+ BadConnectPopup.iSeconds = ActualAccount->BadConnectN.PopupTime;
+
+ BadConnectPopup.PluginWindowProc = BadConnectPopupProc;
+ BadConnectPopup.PluginData = ActualAccount;
+ mir_wstrncpy(BadConnectPopup.lptzContactName, _A2T(ActualAccount->Name), _countof(BadConnectPopup.lptzContactName));
+ }
- if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr != nullptr) {
- Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
- SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
- wcsncpy_s(BadConnectPopup.lptzText, Message1W, _TRUNCATE);
- if (ShowPopup)
- PUAddPopupT(&BadConnectPopup);
- }
- else if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringAFcnPtr != nullptr)
- {
- Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
- SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
- wcsncpy_s(BadConnectPopup.lptzText, Message1W, _TRUNCATE);
- if (ShowPopup)
- PUAddPopupT(&BadConnectPopup);
- }
- else
- {
- Message1W = TranslateT("Unknown error");
- SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
- wcsncpy_s(BadConnectPopup.lptzText, Message1W, _TRUNCATE);
- if (ShowPopup)
- PUAddPopupT(&BadConnectPopup);
- }
+ if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr != nullptr) {
+ Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
+ SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
+ wcsncpy_s(BadConnectPopup.lptzText, Message1W, _TRUNCATE);
+ if (ShowPopup)
+ PUAddPopupT(&BadConnectPopup);
+ }
+ else if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->GetErrorStringAFcnPtr != nullptr) {
+ Message1W = ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
+ SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
+ wcsncpy_s(BadConnectPopup.lptzText, Message1W, _TRUNCATE);
+ if (ShowPopup)
+ PUAddPopupT(&BadConnectPopup);
+ }
+ else {
+ Message1W = TranslateT("Unknown error");
+ SetDlgItemText(hDlg, IDC_STATICMSG, Message1W);
+ wcsncpy_s(BadConnectPopup.lptzText, Message1W, _TRUNCATE);
+ if (ShowPopup)
+ PUAddPopupT(&BadConnectPopup);
+ }
- if (!ShowMsg && !ShowIco)
- DestroyWindow(hDlg);
+ if (!ShowMsg && !ShowIco)
+ DestroyWindow(hDlg);
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read done\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read done\n");
#endif
- ReadDoneFcn(ActualAccount->AccountAccessSO);
-
- SetWindowTextA(hDlg, TitleStrA);
- delete[] TitleStrA;
- if (Message1A != nullptr)
- delete[] Message1A;
- if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr != nullptr && Message1A != nullptr)
- ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr(Message1A);
- if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr != nullptr && Message1W != nullptr)
- ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr(Message1W);
- return 0;
- }
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ SetWindowTextA(hDlg, TitleStrA);
+ delete[] TitleStrA;
+ if (Message1A != nullptr)
+ delete[] Message1A;
+ if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr != nullptr && Message1A != nullptr)
+ ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr(Message1A);
+ if (ActualAccount->Plugin->Fcn != nullptr && ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr != nullptr && Message1W != nullptr)
+ ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr(Message1W);
+ return 0;
+ }
case WM_DESTROY:
- {
- NOTIFYICONDATA nid;
-
- memset(&nid, 0, sizeof(NOTIFYICONDATA));
- nid.cbSize = sizeof(NOTIFYICONDATA);
- nid.hWnd = hDlg;
- nid.uID = 0;
- Shell_NotifyIcon(NIM_DELETE, &nid);
- PostQuitMessage(0);
- break;
- }
- case WM_YAMN_NOTIFYICON:
- switch (lParam)
{
+ NOTIFYICONDATA nid;
+
+ memset(&nid, 0, sizeof(NOTIFYICONDATA));
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hDlg;
+ nid.uID = 0;
+ Shell_NotifyIcon(NIM_DELETE, &nid);
+ PostQuitMessage(0);
+ break;
+ }
+ case WM_YAMN_NOTIFYICON:
+ switch (lParam) {
case WM_LBUTTONDBLCLK:
ShowWindow(hDlg, SW_SHOWNORMAL);
SetForegroundWindow(hDlg);
@@ -185,8 +180,7 @@ INT_PTR CALLBACK DlgProcYAMNBadConnection(HWND hDlg, UINT msg, WPARAM wParam, LP }
return 0;
case WM_CHAR:
- switch ((wchar_t)wParam)
- {
+ switch ((wchar_t)wParam) {
case 27:
case 13:
DestroyWindow(hDlg);
@@ -194,15 +188,13 @@ INT_PTR CALLBACK DlgProcYAMNBadConnection(HWND hDlg, UINT msg, WPARAM wParam, LP }
break;
case WM_SYSCOMMAND:
- switch (wParam)
- {
+ switch (wParam) {
case SC_CLOSE:
DestroyWindow(hDlg);
}
break;
case WM_COMMAND:
- switch (LOWORD(wParam))
- {
+ switch (LOWORD(wParam)) {
case IDC_BTNOK:
DestroyWindow(hDlg);
}
@@ -220,29 +212,28 @@ void __cdecl BadConnection(void *Param) struct BadConnectionParam MyParam = *(struct BadConnectionParam *)Param;
ActualAccount = MyParam.account;
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ DebugLog(SynchroFile, "BadConnect:Incrementing \"using threads\" %x (account %x)\n", ActualAccount->UsingThreads, ActualAccount);
#endif
SCIncFcn(ActualAccount->UsingThreads);
// we will not use params in stack anymore
SetEvent(MyParam.ThreadRunningEV);
- __try
- {
+ __try {
hBadConnect = CreateDialogParam(YAMNVar.hInst, MAKEINTRESOURCE(IDD_DLGBADCONNECT), nullptr, DlgProcYAMNBadConnection, (LPARAM)&MyParam);
Window_SetIcon_IcoLib(hBadConnect, g_GetIconHandle(3));
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read wait\n");
#endif
if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) {
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait failed\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read wait failed\n");
#endif
return;
}
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read enter\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read enter\n");
#endif
if (ActualAccount->BadConnectN.Flags & YAMN_ACC_SND)
Skin_PlaySound(YAMN_CONNECTFAILSOUND);
@@ -262,13 +253,12 @@ void __cdecl BadConnection(void *Param) }
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read done\n");
+ DebugLog(SynchroFile, "BadConnect:ActualAccountSO-read done\n");
#endif
ReadDoneFcn(ActualAccount->AccountAccessSO);
UpdateWindow(hBadConnect);
- while (GetMessage(&msg, nullptr, 0, 0))
- {
+ while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@@ -277,10 +267,9 @@ void __cdecl BadConnection(void *Param) if ((ActualAccount->Plugin->Fcn != nullptr) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr != nullptr) && ActualAccount->AbleToWork)
ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr();
}
- __finally
- {
+ __finally {
#ifdef DEBUG_SYNCHRO
- DebugLog(SynchroFile,"BadConnect:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ DebugLog(SynchroFile, "BadConnect:Decrementing \"using threads\" %x (account %x)\n", ActualAccount->UsingThreads, ActualAccount);
#endif
SCDecFcn(ActualAccount->UsingThreads);
}
@@ -289,26 +278,19 @@ void __cdecl BadConnection(void *Param) INT_PTR RunBadConnectionSvc(WPARAM wParam, LPARAM lParam)
{
- //an event for successfull copy parameters to which point a pointer in stack for new thread
- HANDLE ThreadRunningEV;
+ // an event for successfull copy parameters to which point a pointer in stack for new thread
PYAMN_BADCONNECTIONPARAM Param = (PYAMN_BADCONNECTIONPARAM)wParam;
-
if ((DWORD)lParam != YAMN_BADCONNECTIONVERSION)
return 0;
- if (nullptr != (ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr)))
- {
- HANDLE NewThread;
+ HANDLE ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr);
+ Param->ThreadRunningEV = ThreadRunningEV;
- Param->ThreadRunningEV = ThreadRunningEV;
- if (nullptr != (NewThread = mir_forkthread(BadConnection, (void*)Param)))
- {
- WaitForSingleObject(ThreadRunningEV, INFINITE);
- CloseHandle(NewThread);
- }
- CloseHandle(ThreadRunningEV);
+ HANDLE NewThread = mir_forkthread(BadConnection, (void*)Param);
+ if (nullptr == NewThread)
+ return 0;
- return 1;
- }
- return 0;
+ WaitForSingleObject(ThreadRunningEV, INFINITE);
+ CloseHandle(ThreadRunningEV);
+ return 1;
}
diff --git a/plugins/YAMN/src/browser/mailbrowser.cpp b/plugins/YAMN/src/browser/mailbrowser.cpp index 58269b94af..a9f2b162ca 100644 --- a/plugins/YAMN/src/browser/mailbrowser.cpp +++ b/plugins/YAMN/src/browser/mailbrowser.cpp @@ -18,9 +18,9 @@ #define MAILBROWSERTITLE LPGEN("%s - %d new mail messages, %d total") +void __cdecl ShowEmailThread(void *Param); - //-------------------------------------------------------------------------------------------------- - //-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- char* s_MonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; bool bDate = false, bSub = false, bSize = false, bFrom = false; int PosX = 0, PosY = 0, SizeX = 460, SizeY = 100; @@ -88,12 +88,12 @@ struct CSortList int iSubItem; }; -//Retrieves HACCOUNT, whose mails are displayed in ListMails +// Retrieves HACCOUNT, whose mails are displayed in ListMails // hLM- handle of dialog window // returns handle of account inline HACCOUNT GetWindowAccount(HWND hDialog); -//Looks to mail flags and increment mail counter (e.g. if mail is new, increments the new mail counter +// Looks to mail flags and increment mail counter (e.g. if mail is new, increments the new mail counter // msgq- mail, which increments the counters // MN- counnters structure void IncrementMailCounters(HYAMNMAIL msgq, struct CMailNumbers *MN); @@ -104,7 +104,8 @@ enum UPDATE_NONE, //none update has been performed UPDATE_OK, //some changes occured, update performed }; -//Just looks for mail changes in account and update the mail browser window + +// Just looks for mail changes in account and update the mail browser window // hDlg- dialog handle // ActualAccount- account handle // nflags- flags what to do when new mail arrives @@ -112,7 +113,7 @@ enum // returns one of UPDATE_XXX value(not implemented yet) int UpdateMails(HWND hDlg, HACCOUNT ActualAccount, DWORD nflags, DWORD nnflags); -//When new mail occurs, shows window, plays sound, runs application... +// When new mail occurs, shows window, plays sound, runs application... // hDlg- dialog handle. Dialog of mailbrowser is already created and actions are performed over this window // ActualAccount- handle of account, whose mails are to be notified // MN- statistics of mails in account @@ -121,14 +122,14 @@ int UpdateMails(HWND hDlg, HACCOUNT ActualAccount, DWORD nflags, DWORD nnflags); // nnflags- flags what to do when no new mail arrives void DoMailActions(HWND hDlg, HACCOUNT ActualAccount, struct CMailNumbers *MN, DWORD nflags, DWORD nnflags); -//Looks for items in mailbrowser and if they were deleted, delete them from browser window +// Looks for items in mailbrowser and if they were deleted, delete them from browser window // hListView- handle of listview window // ActualAccount- handle of account, whose mails are show // MailNumbers- pointer to structure, in which function stores numbers of mails with some property // returns one of UPDATE_XXX value (not implemented yet) int ChangeExistingMailStatus(HWND hListView, HACCOUNT ActualAccount); -//Adds new mails to ListView and if any new, shows multi popup (every new message is new popup window created by popup plugin) +// Adds new mails to ListView and if any new, shows multi popup (every new message is new popup window created by popup plugin) // hListView- handle of listview window // ActualAccount- handle of account, whose mails are show // NewMailPopup- pointer to prepared structure for popup plugin, can be NULL if no popup show @@ -137,21 +138,21 @@ int ChangeExistingMailStatus(HWND hListView, HACCOUNT ActualAccount); // returns one of UPDATE_XXX value (not implemented yet) int AddNewMailsToListView(HWND hListView, HACCOUNT ActualAccount, DWORD nflags); -//Window callback procedure for popup window (created by popup plugin) +// Window callback procedure for popup window (created by popup plugin) LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -//Window callback procedure for popup window (created by popup plugin) +// Window callback procedure for popup window (created by popup plugin) LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -//Dialog callback procedure for mail browser +// Dialog callback procedure for mail browser INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//MailBrowser thread function creates window if needed, tray icon and plays sound +// MailBrowser thread function creates window if needed, tray icon and plays sound void __cdecl MailBrowser(void *Param); LRESULT CALLBACK ListViewSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -//Runs mail browser in new thread +// Runs mail browser in new thread INT_PTR RunMailBrowserSvc(WPARAM, LPARAM); #define YAMN_BROWSER_SHOWPOPUP 0x01 @@ -188,7 +189,6 @@ typedef struct _LVCOMPAREINFO } LVCOMPAREINFO, *LPLVCOMPAREINFO; //-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- LPARAM readItemLParam(HWND hwnd, DWORD iItem) { @@ -324,9 +324,9 @@ int UpdateMails(HWND hDlg, HACCOUNT ActualAccount, DWORD nflags, DWORD nnflags) DebugLog(SynchroFile, "UpdateMails:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "UpdateMails:ActualAccountSO-read wait failed\n"); - #endif +#endif PostMessage(hDlg, WM_DESTROY, 0, 0); return UPDATE_FAIL; @@ -339,10 +339,10 @@ int UpdateMails(HWND hDlg, HACCOUNT ActualAccount, DWORD nflags, DWORD nnflags) DebugLog(SynchroFile, "UpdateMails:ActualAccountMsgsSO-write wait\n"); #endif if (WAIT_OBJECT_0 != WaitToWriteFcn(ActualAccount->MessagesAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "UpdateMails:ActualAccountMsgsSO-write wait failed\n"); DebugLog(SynchroFile, "UpdateMails:ActualAccountSO-read done\n"); - #endif +#endif ReadDoneFcn(ActualAccount->AccountAccessSO); PostMessage(hDlg, WM_DESTROY, 0, 0); @@ -377,7 +377,7 @@ int UpdateMails(HWND hDlg, HACCOUNT ActualAccount, DWORD nflags, DWORD nnflags) //If popups will be displayed or mailbrowser window if ((((mwui != nullptr) && !(mwui->RunFirstTime)) && ( - ((nnflags & YAMN_ACC_MSGP) && !(MN.Real.BrowserUC + MN.Virtual.BrowserUC)) || + ((nnflags & YAMN_ACC_MSGP) && !(MN.Real.BrowserUC + MN.Virtual.BrowserUC)) || ((nflags & YAMN_ACC_MSGP) && (MN.Real.BrowserUC + MN.Virtual.BrowserUC)) ) ) || //if mail window was displayed before and flag YAMN_ACC_MSGP is set @@ -518,7 +518,7 @@ int AddNewMailsToListView(HWND hListView, HACCOUNT ActualAccount, DWORD nflags) if (hListView != nullptr) { fi.lParam = (LPARAM)msgq; - if (-1 != (foundi = ListView_FindItem(hListView, -1, &fi))) { // if mail is already in window + if (-1 != (foundi = ListView_FindItem(hListView, -1, &fi))) { // if mail is already in window lfoundi = foundi; continue; // do not insert any item } @@ -785,7 +785,6 @@ void DoMailActions(HWND hDlg, HACCOUNT ActualAccount, struct CMailNumbers *MN, D return; } -void __cdecl ShowEmailThread(void *Param); LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { INT_PTR PluginParam = 0; @@ -800,14 +799,7 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa memcpy(MailParam, (PINT_PTR)PluginParam, sizeof(YAMN_MAILSHOWPARAM)); hContact = MailParam->account->hContact; Account = MailParam->account; - if (nullptr != (MailParam->ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr))) { - HANDLE NewThread = mir_forkthread(ShowEmailThread, MailParam); - if (NewThread != nullptr) { - CloseHandle(NewThread); - } - CloseHandle(MailParam->ThreadRunningEV); - } - //delete MailParam; + mir_forkthread(ShowEmailThread, MailParam); } else { DBVARIANT dbv; @@ -822,13 +814,13 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa Account = (HACCOUNT)hContact; //???? - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read wait\n"); - #endif +#endif if (WAIT_OBJECT_0 == WaitToReadFcn(Account->AccountAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read enter\n"); - #endif +#endif switch (msg) { case WM_COMMAND: { @@ -840,15 +832,15 @@ LRESULT CALLBACK NewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa } break; } - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read done\n"); - #endif +#endif ReadDoneFcn(Account->AccountAccessSO); } - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO else DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read enter failed\n"); - #endif +#endif } if ((Account->NewMailN.Flags & YAMN_ACC_CONT) && !(Account->NewMailN.Flags & YAMN_ACC_CONTNOEVENT)) pcli->pfnRemoveEvent(hContact, hContact); @@ -913,13 +905,13 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l else ActualAccount = (HACCOUNT)hContact; - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read wait\n"); - #endif +#endif if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read enter\n"); - #endif +#endif switch (msg) { case WM_COMMAND: { @@ -935,15 +927,15 @@ LRESULT CALLBACK NoNewMailPopupProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM l } break; } - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read done\n"); - #endif +#endif ReadDoneFcn(ActualAccount->AccountAccessSO); } - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO else DebugLog(SynchroFile, "PopupProc:LEFTCLICK:ActualAccountSO-read enter failed\n"); - #endif +#endif PUDeletePopup(hWnd); } break; @@ -1460,9 +1452,9 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR break; if ((HACCOUNT)wParam != MailParam->account) break; - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "ShowMessage:STOPACCOUNT:sending destroy msg\n"); - #endif +#endif DestroyWindow(hDlg); } return 1; @@ -1568,7 +1560,7 @@ INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg, UINT msg, WPARAM wParam, LPAR } if (sizeNeeded && OpenClipboard(hDlg)) { EmptyClipboard(); - HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (sizeNeeded + 1)*sizeof(wchar_t)); + HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (sizeNeeded + 1) * sizeof(wchar_t)); wchar_t *buff = (wchar_t*)GlobalLock(hData); int courPos = 0; for (courRow = 0; courRow < numRows; courRow++) { @@ -1600,7 +1592,7 @@ void __cdecl ShowEmailThread(void *Param) DebugLog(SynchroFile, "ShowMessage:Incrementing \"using threads\" %x (account %x)\n", MyParam.account->UsingThreads, MyParam.account); #endif SCIncFcn(MyParam.account->UsingThreads); - SetEvent(MyParam.ThreadRunningEV); + if (MyParam.mail->MsgWindow) { //if (!BringWindowToTop(MyParam.mail->MsgWindow)) { if (!SetForegroundWindow(MyParam.mail->MsgWindow)) { @@ -1608,11 +1600,9 @@ void __cdecl ShowEmailThread(void *Param) MyParam.mail->MsgWindow = nullptr; goto CREADTEVIEWMESSAGEWINDOW; } - else { - if (IsIconic(MyParam.mail->MsgWindow)) { - OpenIcon(MyParam.mail->MsgWindow); - } - } + + if (IsIconic(MyParam.mail->MsgWindow)) + OpenIcon(MyParam.mail->MsgWindow); } else { CREADTEVIEWMESSAGEWINDOW: @@ -1632,7 +1622,7 @@ CREADTEVIEWMESSAGEWINDOW: DebugLog(SynchroFile, "ShowMessage:Decrementing \"using threads\" %x (account %x)\n", MyParam.account->UsingThreads, MyParam.account); #endif SCDecFcn(MyParam.account->UsingThreads); - delete (struct MailShowMsgWinParam *)Param; + delete (struct MailShowMsgWinParam*)Param; } INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) @@ -1721,9 +1711,9 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR if (ListView_GetColumn(GetDlgItem(hDlg, IDC_LISTMAILS), 3, &ColInfo)) SizeDate = ColInfo.cx; - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DESTROY:save window position\n"); - #endif +#endif if (!YAMNVar.Shutdown && GetWindowRect(hDlg, &coord)) //the YAMNVar.Shutdown testing is because M<iranda strange functionality at shutdown phase, when call to DBWriteContactSetting freezes calling thread { PosX = coord.left; @@ -1737,24 +1727,24 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR } KillTimer(hDlg, TIMER_FLASHING); - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DESTROY:remove window from list\n"); - #endif +#endif WindowList_Remove(YAMNVar.NewMailAccountWnd, hDlg); WindowList_Remove(YAMNVar.MessageWnds, hDlg); - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DESTROY:ActualAccountMsgsSO-write wait\n"); - #endif +#endif if (WAIT_OBJECT_0 != WaitToWriteFcn(ActualAccount->MessagesAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DESTROY:ActualAccountMsgsSO-write wait failed\n"); - #endif +#endif break; } - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DESTROY:ActualAccountMsgsSO-write enter\n"); - #endif +#endif //delete mails from queue, which are deleted from server (spam level 3 mails e.g.) for (Parser = (HYAMNMAIL)ActualAccount->Mails; Parser != nullptr; Parser = Parser->Next) { if ((Parser->Flags & YAMN_MSG_DELETED) && YAMN_MSG_SPAML(Parser->Flags, YAMN_MSG_SPAML3) && mwui->Seen) //if spaml3 was already deleted and user knows about it @@ -1767,9 +1757,9 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR //mark mails as read (remove "new" and "unseen" flags) if (mwui->Seen) SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY, 0, YAMN_MSG_NEW | YAMN_MSG_UNSEEN, 0); - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DESTROY:ActualAccountMsgsSO-write done\n"); - #endif +#endif WriteDoneFcn(ActualAccount->MessagesAccessSO); NOTIFYICONDATA nid; @@ -1819,9 +1809,9 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR UpdateParams.Flags = (struct CChangeContent *)lParam; UpdateParams.Waiting = !ThisThreadWindow; - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:CHANGECONTENT:posting UPDATEMAILS\n"); - #endif +#endif if (ThisThreadWindow) { if (!UpdateMails(hDlg, (HACCOUNT)wParam, UpdateParams.Flags->nflags, UpdateParams.Flags->nnflags)) DestroyWindow(hDlg); @@ -1829,13 +1819,13 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR else if (PostMessage(hDlg, WM_YAMN_UPDATEMAILS, wParam, (LPARAM)&UpdateParams)) //this ensures UpdateMails will execute the thread who created the browser window { if (!ThisThreadWindow) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:CHANGECONTENT:waiting for event\n"); - #endif +#endif WaitForSingleObject(UpdateParams.Copied, INFINITE); - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:CHANGECONTENT:event signaled\n"); - #endif +#endif } } @@ -1847,9 +1837,9 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR struct CUpdateMails *um = (struct CUpdateMails *)lParam; DWORD nflags, nnflags; - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:UPDATEMAILS\n"); - #endif +#endif if (nullptr == (ActualAccount = GetWindowAccount(hDlg))) return 0; @@ -1873,34 +1863,34 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR break; PostQuitMessage(0); return 1; - + case WM_YAMN_NOTIFYICON: if (nullptr == (ActualAccount = GetWindowAccount(hDlg))) break; switch (lParam) { case WM_LBUTTONDBLCLK: - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DBLCLICKICON:ActualAccountSO-read wait\n"); - #endif +#endif if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DBLCLICKICON:ActualAccountSO-read wait failed\n"); - #endif +#endif return 0; } - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DBLCLICKICON:ActualAccountSO-read enter\n"); - #endif +#endif if (ActualAccount->AbilityFlags & YAMN_ACC_BROWSE) { ShowWindow(hDlg, SW_SHOWNORMAL); SetForegroundWindow(hDlg); } else DestroyWindow(hDlg); - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:DBLCLICKICON:ActualAccountSO-read done\n"); - #endif +#endif ReadDoneFcn(ActualAccount->AccountAccessSO); break; } @@ -1919,26 +1909,15 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR ListView_GetItem(GetDlgItem(hDlg, IDC_LISTMAILS), &item); HYAMNMAIL ActualMail = (HYAMNMAIL)item.lParam; if (nullptr != ActualMail) { - //ShowEmailThread - HANDLE hThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (hThreadRunningEV != nullptr) { - PYAMN_MAILSHOWPARAM MailParam = new YAMN_MAILSHOWPARAM; - MailParam->account = GetWindowAccount(hDlg); - MailParam->mail = ActualMail; - MailParam->ThreadRunningEV = hThreadRunningEV; - HANDLE NewThread = mir_forkthread(ShowEmailThread, MailParam); - if (nullptr != NewThread) { - //WaitForSingleObject(MailParam->ThreadRunningEV,INFINITE); - CloseHandle(NewThread); - } - CloseHandle(MailParam->ThreadRunningEV); - } - //delete MailParam; + PYAMN_MAILSHOWPARAM MailParam = new YAMN_MAILSHOWPARAM; + MailParam->account = GetWindowAccount(hDlg); + MailParam->mail = ActualMail; + mir_forkthread(ShowEmailThread, MailParam); } } } break; - + case WM_SYSCOMMAND: if (nullptr == (ActualAccount = GetWindowAccount(hDlg))) break; @@ -2057,11 +2036,8 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails, YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE, 0, YAMN_MSG_DELETEOK, 1); // Create new thread which deletes marked mails. HANDLE NewThread = mir_forkthread(ActualAccount->Plugin->Fcn->DeleteMailsFcnPtr, &ParamToDeleteMails); - - if (NewThread != nullptr) { + if (NewThread != nullptr) WaitForSingleObject(ThreadRunningEV, INFINITE); - CloseHandle(NewThread); - } // Enable write-access to mails WriteDoneFcn(ActualAccount->MessagesAccessSO); @@ -2078,7 +2054,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR break; } break; - + case WM_SIZE: if (wParam == SIZE_RESTORED) { LONG x = LOWORD(lParam); //((LPRECT)lParam)->right-((LPRECT)lParam)->left; @@ -2129,9 +2105,9 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR if (nullptr != (ActualAccount = GetWindowAccount(hDlg))) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)lParam; if (WAIT_OBJECT_0 == WaitToReadFcn(ActualAccount->AccountAccessSO)) { - #ifdef DEBUG_SYNCHRO +#ifdef DEBUG_SYNCHRO DebugLog(SynchroFile, "MailBrowser:COLUMNCLICK:ActualAccountSO-read enter\n"); - #endif +#endif switch ((int)pNMListView->iSubItem) { case 0: bFrom = !bFrom; @@ -2247,7 +2223,7 @@ INT_PTR CALLBACK DlgProcYAMNMailBrowser(HWND hDlg, UINT msg, WPARAM wParam, LPAR } if (sizeNeeded && OpenClipboard(hDlg)) { EmptyClipboard(); - HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (sizeNeeded + 1)*sizeof(wchar_t)); + HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (sizeNeeded + 1) * sizeof(wchar_t)); wchar_t *buff = (wchar_t *)GlobalLock(hData); int courPos = 0; for (courRow = 0; courRow < numRows; courRow++) { @@ -2327,14 +2303,14 @@ void __cdecl MailBrowser(void *Param) SetEvent(MyParam.ThreadRunningEV); __try { - if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) { + if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) return; - } if (!(ActualAccount->AbilityFlags & YAMN_ACC_BROWSE)) { MyParam.nflags = MyParam.nflags & ~YAMN_ACC_MSG; MyParam.nnflags = MyParam.nnflags & ~YAMN_ACC_MSG; } + if (!(ActualAccount->AbilityFlags & YAMN_ACC_POPUP)) MyParam.nflags = MyParam.nflags & ~YAMN_ACC_POP; @@ -2342,6 +2318,7 @@ void __cdecl MailBrowser(void *Param) if (nullptr != (hMailBrowser = WindowList_Find(YAMNVar.NewMailAccountWnd, (UINT_PTR)ActualAccount))) WndFound = TRUE; + if ((hMailBrowser == nullptr) && ((MyParam.nflags & YAMN_ACC_MSG) || (MyParam.nflags & YAMN_ACC_ICO) || (MyParam.nnflags & YAMN_ACC_MSG))) { hMailBrowser = CreateDialogParamW(YAMNVar.hInst, MAKEINTRESOURCEW(IDD_DLGVIEWMESSAGES), nullptr, DlgProcYAMNMailBrowser, (LPARAM)&MyParam); Window_SetIcon_IcoLib(hMailBrowser, g_GetIconHandle(2)); @@ -2382,15 +2359,12 @@ INT_PTR RunMailBrowserSvc(WPARAM wParam, LPARAM lParam) //an event for successfull copy parameters to which point a pointer in stack for new thread HANDLE ThreadRunningEV = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (ThreadRunningEV != nullptr) { - Param->ThreadRunningEV = ThreadRunningEV; - HANDLE NewThread = mir_forkthread(MailBrowser, Param); - if (NewThread != nullptr) { - WaitForSingleObject(ThreadRunningEV, INFINITE); - CloseHandle(NewThread); - } - CloseHandle(ThreadRunningEV); - return 1; - } - return 0; + Param->ThreadRunningEV = ThreadRunningEV; + + HANDLE NewThread = mir_forkthread(MailBrowser, Param); + if (NewThread != nullptr) + WaitForSingleObject(ThreadRunningEV, INFINITE); + + CloseHandle(ThreadRunningEV); + return 1; } |