/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include extern "C" { #include #include } #include "svrmgr.h" #include #include "display.h" #include "command.h" #include "messages.h" #include "svr_window.h" #include "svr_general.h" #include "svr_security.h" #include "set_repprop.h" #include "set_createrep.h" #include "set_rename.h" #include "columns.h" #include "propcache.h" #include "action.h" #include "creds.h" /* * RESIZING WINDOWS ___________________________________________________________ * */ #define cxMIN_SERVER 75 #define cyMIN_SERVER 70 #define cxMIN_TABS 100 #define cyMIN_TABS 100 #define cxMIN_WINDOW_PREVIEW 220 #define cyMIN_WINDOW_PREVIEW 250 #define cxMIN_WINDOW 120 #define cyMIN_WINDOW 120 rwWindowData awdMain[] = { { IDC_CELL_BORDER, raSizeX, 0, 0 }, { IDC_CELL, raSizeX | raRepaint, 0, 0 }, { IDC_AFS_ID, raSizeX | raRepaint, 0, 0 }, { IDC_SERVERS, raSizeX | raSizeY, MAKELONG(cxMIN_SERVER,cyMIN_SERVER), 0 }, { IDC_COVERDLG, raSizeX | raSizeY, 0, 0 }, { IDC_ANIMATE, raMoveX, 0, 0 }, { idENDLIST, 0, 0, 0 } }; rwWindowData awdMainVert[] = { { IDC_CELL_BORDER, raSizeX, 0, 0 }, { IDC_CELL, raSizeX | raRepaint, 0, 0 }, { IDC_AFS_ID, raSizeX | raRepaint, 0, 0 }, { IDC_SERVERS, raSizeX, MAKELONG(cxMIN_SERVER,cyMIN_SERVER), 0 }, { IDC_SPLITTER_SERVER, raSizeX, 0, 0 }, { IDC_TABS, raSizeX | raSizeY, MAKELONG(cxMIN_TABS,cyMIN_TABS), 0 }, { IDC_COVERDLG, raSizeX, 0, 0 }, { IDC_ANIMATE, raMoveX, 0, 0 }, { idENDLIST, 0, 0, 0 } }; rwWindowData awdMainHorz[] = { { IDC_CELL_BORDER, raSizeX, 0, 0 }, { IDC_CELL, raSizeX | raRepaint, 0, 0 }, { IDC_AFS_ID, raSizeX | raRepaint, 0, 0 }, { IDC_SERVERS, raSizeY, MAKELONG(cxMIN_SERVER,cyMIN_SERVER), 0 }, { IDC_SPLITTER_SERVER, raSizeY, 0, 0 }, { IDC_TABS, raSizeX | raSizeY, MAKELONG(cxMIN_TABS,cyMIN_TABS), 0 }, { IDC_COVERDLG, raSizeY, 0, 0 }, { IDC_ANIMATE, raMoveX, 0, 0 }, { idENDLIST, 0, 0, 0 } }; rwWindowData awdSplitServer[] = { { IDC_CELL, raRepaint, 0, 0 }, { IDC_AFS_ID, raRepaint, 0, 0 }, { IDC_SERVERS, raSizeX | raSizeY, MAKELONG(cxMIN_SERVER,cyMIN_SERVER), 0 }, { IDC_SPLITTER_SERVER, raMoveX | raMoveY, 0, 0 }, { IDC_TABS, raMoveX | raMoveY | raSizeXB | raSizeYB, MAKELONG(cxMIN_TABS,cyMIN_TABS), 0 }, { IDC_COVERDLG, raSizeX | raSizeY, 0, 0 }, { IDC_ANIMATE, 0, 0, 0 }, { idENDLIST, 0, 0, 0 } }; /* * PROTOTYPES _________________________________________________________________ * */ void Main_OnNotifyFromDispatch (LPNOTIFYSTRUCT lpns); void Main_OnPreviewPane (BOOL fPreviewNew, BOOL fVertNew, BOOL fStoreView); DWORD WINAPI Main_OnOpenServers_ThreadProc (PVOID lp); void Main_SubclassServers (HWND hDlg); void Main_CreateTabControl (void); void Main_DeleteTabControl (void); void Main_DisplayTab (CHILDTAB iTab); void Main_RearrangeChildren (BOOL fSplitNew, BOOL fVertNew); BOOL Main_HandleDialogKeys (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp); void Main_OnKey_CtrlTab (BOOL fForward); void Main_OnKey_Tab (BOOL fForward); #ifdef DEBUG void ExportCell (void); #endif /* * ROUTINES ___________________________________________________________________ * */ static BOOL fEnforceMinimumSize = TRUE; static BOOL fNotifyChildrenForResize = TRUE; static LONG nReqWorking = 0; static int iFrameLast = 0; BOOL CALLBACK Main_DialogProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { if (HandleColumnNotify (hDlg, msg, wp, lp, (gr.fPreview && !gr.fVert) ? &gr.diHorz.viewSvr : &gr.diVert.viewSvr)) return FALSE; if (Main_HandleDialogKeys (hDlg, msg, wp, lp)) return TRUE; if (msg == WM_INITDIALOG) // get this out of the way. :) { g.hMain = hDlg; AfsAppLib_SetMainWindow (g.hMain); } switch (msg) { case WM_INITDIALOG: { LPRECT prTarget = (gr.fPreview) ? &gr.rMainPreview : &gr.rMain; if (prTarget->right == 0) GetWindowRect (g.hMain, prTarget); ResizeWindow (g.hMain, awdMain, rwaMoveToHere, prTarget); Main_SetActionMenus(); // Subclass the Servers window, so we can watch for focus changes // and context-menu requests // Main_SubclassServers (hDlg); FastList_SetTextCallback (GetDlgItem (hDlg, IDC_SERVERS), GetItemText, ((gr.fPreview && !gr.fVert) ? &gr.diHorz.viewSvr : &gr.diVert.viewSvr)); // Create the preview pane and rearrange the children of this dialog. // This also fixes the Servers display--was it in Large Icons view? // What columns were shown? // Main_OnPreviewPane (gr.fPreview, gr.fVert, FALSE); // Tell our notification dispatcher to let this window know whenever // a cell gets opened or closed (that's what the NULL does--otherwise, // an LPIDENT would go there to indicate we're interested in a // particular server etc). // NotifyMe (WHEN_CELL_OPENED, NULL, hDlg, 0); // tell me about any cell // If we weren't around when the cell was created, we might have // missed some notifications. Send a redraw just in case. // StartThread (Main_Redraw_ThreadProc, FALSE); SetTimer (hDlg, ID_DISPATCH_TIMER, 200, NULL); // do all notifications } break; case WM_DESTROY: KillTimer (hDlg, ID_DISPATCH_TIMER); break; case WM_QUERYENDSESSION: if (Action_fAnyActive()) { ShowWindow (g.hMain, SW_SHOW); if (Message (MB_ICONHAND | MB_YESNO, IDS_CANT_QUIT_TITLE, IDS_CANT_QUIT_REBOOT) != IDYES) return TRUE; } break; case WM_TIMER: if (wp == ID_DISPATCH_TIMER) { DispatchNotification_OnPump(); } break; case WM_HELP: if ((lp == 0) || (IsAncestor (g.hMain, (HWND)(((LPHELPINFO)lp)->hItemHandle)))) { WinHelp (hDlg, cszHELPFILENAME, HELP_FINDER, 0); } break; case WM_NOTIFY_FROM_DISPATCH: Main_OnNotifyFromDispatch ((LPNOTIFYSTRUCT)lp); Delete ((LPNOTIFYSTRUCT)lp); break; case WM_ENDTASK: LPTASKPACKET ptp; if ((ptp = (LPTASKPACKET)lp) != NULL) { if (ptp->idTask == taskSVR_GETWINDOWPOS) Server_Open ((LPIDENT)(ptp->lpUser), &TASKDATA(ptp)->rWindow); else if (ptp->idTask == taskSET_REPPROP_INIT) Filesets_OnEndTask_ShowReplication (ptp); else if (ptp->idTask == taskSET_RENAME_INIT) Filesets_OnEndTask_ShowRename (ptp); FreeTaskPacket (ptp); } break; case WM_OPEN_SERVERS: StartThread (Main_OnOpenServers_ThreadProc, 0); break; case WM_OPEN_SERVER: StartTask (taskSVR_GETWINDOWPOS, g.hMain, (LPIDENT)lp); break; case WM_SHOW_CREATEREP_DIALOG: Filesets_CreateReplica ((LPIDENT)wp, (LPIDENT)lp); break; case WM_SHOW_YOURSELF: if (lp || g.lpiCell) { ShowWindow (g.hMain, SW_SHOW); BringWindowToTop (g.hMain); Action_WindowToTop (TRUE); } break; case WM_OPEN_ACTIONS: Action_OpenWindow(); break; case WM_REFRESHED_CREDENTIALS: g.hCreds = (UINT_PTR)lp; UpdateDisplay_Cell(FALSE); StartTask (taskREFRESH_CREDS, NULL, g.lpiCell); break; case WM_SIZE: // if (lp==0), we're minimizing--don't call ResizeWindow(). // Action_WindowToTop ((lp) ? TRUE : FALSE); if (lp != 0) { rwWindowData *pwdResizeInfo; if (!gr.fPreview) pwdResizeInfo = awdMain; else if (gr.fVert) pwdResizeInfo = awdMainVert; else // (!gr.fVert) pwdResizeInfo = awdMainHorz; if (fNotifyChildrenForResize) ResizeWindow (hDlg, pwdResizeInfo, rwaFixupGuts); else ResizeWindow (hDlg, pwdResizeInfo, rwaJustResync); } break; case WM_ACTIVATEAPP: Action_WindowToTop ((wp) ? TRUE : FALSE); if (wp) StartTask (taskEXPIRED_CREDS); break; case WM_CONTEXTMENU: { POINT ptScreen; POINT ptClient; ptScreen.x = LOWORD(lp); ptScreen.y = HIWORD(lp); ptClient = ptScreen; ScreenToClient ((HWND)wp, &ptClient); if ((HWND)wp == GetDlgItem (g.hMain, IDC_SERVERS)) Server_ShowPopupMenu ((HWND)wp, ptClient, ptScreen); } break; case WM_COMMAND: switch (LOWORD(wp)) { case IDCANCEL: case M_EXIT: Quit (0); break; case M_DIVIDE_NONE: Main_OnPreviewPane (FALSE, gr.fVert, TRUE); UpdateDisplay_Servers (FALSE, NULL, 0); break; case M_DIVIDE_H: Main_OnPreviewPane (TRUE, FALSE, TRUE); UpdateDisplay_Servers (FALSE, NULL, 0); break; case M_DIVIDE_V: Main_OnPreviewPane (TRUE, TRUE, TRUE); UpdateDisplay_Servers (FALSE, NULL, 0); break; case M_SVR_VIEW_LARGE: Main_OnServerView (FLS_VIEW_LARGE); break; case M_SVR_VIEW_SMALL: Main_OnServerView (FLS_VIEW_SMALL); break; case M_SVR_VIEW_REPORT: Main_OnServerView (FLS_VIEW_LIST); break; case M_COLUMNS: if (!gr.fPreview) ShowColumnsDialog (hDlg, NULL); else { CHILDTAB iTab = Server_GetDisplayedTab (g.hMain); if (iTab == tabSERVICES) ShowColumnsDialog (hDlg, &gr.viewSvc); else if (iTab == tabAGGREGATES) ShowColumnsDialog (hDlg, &gr.viewAgg); else if (iTab == tabFILESETS) ShowColumnsDialog (hDlg, &gr.viewSet); else ShowColumnsDialog (hDlg, NULL); } break; case M_ACTIONS: if ((gr.fActions = !gr.fActions) == TRUE) Action_OpenWindow(); else Action_CloseWindow(); Main_SetActionMenus(); break; #ifdef DEBUG case M_EXPORT: ExportCell(); break; #endif case IDC_COVER_BUTTON: // The user must have clicked the "Try Again" or "Credentials" // button on the cover we placed over the Servers list. // Refresh the cell or obtain new credentials, as appropriate. // if (g.lpiCell) { TCHAR szButton[ cchRESOURCE ]; GetWindowText ((HWND)lp, szButton, cchRESOURCE); TCHAR szTest[ cchRESOURCE ]; GetString (szTest, IDS_ALERT_BUTTON_TRYAGAIN); if (!lstrcmp (szTest, szButton)) { StartTask (taskREFRESH, NULL, g.lpiCell); break; } GetString (szTest, IDS_ALERT_BUTTON_GETCREDS); if (!lstrcmp (szTest, szButton)) { NewCredsDialog(); break; } } break; default: StartContextCommand (g.hMain, NULL, NULL, LOWORD(wp)); break; } break; case WM_NOTIFY: switch (((LPNMHDR)lp)->code) { case TCN_SELCHANGE: { int iPage = TabCtrl_GetCurSel (GetDlgItem (g.hMain, IDC_TABS)); Main_DisplayTab ((CHILDTAB)iPage); } break; case FLN_ITEMSELECT: if (gr.fPreview) { HWND hServers = GetDlgItem (hDlg, IDC_SERVERS); LPIDENT lpi = (LPIDENT)FL_GetSelectedData (hServers); Server_SelectServer (SERVERWINDOW_PREVIEWPANE, lpi); } break; case FLN_LDBLCLICK: { HWND hServers = GetDlgItem (g.hMain, IDC_SERVERS); if (((LPNMHDR)lp)->hwndFrom == hServers) { LPIDENT lpi = (LPIDENT)FL_GetSelectedData (hServers); if (lpi && lpi->fIsServer()) { BOOL fOpenWindow; if (gr.fDoubleClickOpens == 0) fOpenWindow = FALSE; else if (gr.fDoubleClickOpens == 1) fOpenWindow = TRUE; else if (gr.fPreview) fOpenWindow = FALSE; else // (!gr.Preview) fOpenWindow = TRUE; if (!fOpenWindow) { PostMessage (hServers, WM_COMMAND, M_PROPERTIES, 0); } else // (fOpenWindow) { PostMessage (g.hMain, WM_OPEN_SERVER, 0, (LPARAM)lpi); } } } } break; } break; } return FALSE; } void Main_OnNotifyFromDispatch (LPNOTIFYSTRUCT lpns) { switch (lpns->evt) { case evtCreate: StartTask (taskOPENEDCELL, NULL, lpns->Params.lpi1); break; case evtDestroy: StartTask (taskCLOSEDCELL, NULL, lpns->Params.lpi1); break; case evtRefreshStatusEnd: case evtAlertsChanged: if (lpns->Params.lpi1 && lpns->Params.lpi1->fIsCell()) { UpdateDisplay_Cell (FALSE); } else if (lpns->Params.lpi1 && lpns->Params.lpi1->fIsServer()) { UpdateDisplay_Servers (FALSE, lpns->Params.lpi1, lpns->Params.status); } break; case evtRefreshServersEnd: if (g.lpiCell || lpns->Params.status == 0) { UpdateDisplay_Servers (FALSE, NULL, 0); } break; } } DWORD WINAPI Main_OnOpenServers_ThreadProc (PVOID lp) { AfsClass_Enter(); if (g.lpiCell != NULL) { LPCELL lpCell; if ((lpCell = g.lpiCell->OpenCell()) != NULL) { HENUM hEnum; for (LPSERVER lpServer = lpCell->ServerFindFirst (&hEnum); lpServer; lpServer = lpCell->ServerFindNext (&hEnum)) { LPSERVER_PREF lpsp; if ((lpsp = (LPSERVER_PREF)lpServer->GetUserParam()) != NULL) { if (lpsp->fOpen && !PropCache_Search (pcSERVER, lpServer->GetIdentifier())) { PostMessage (g.hMain, WM_OPEN_SERVER, 0, (LPARAM)(lpServer->GetIdentifier())); } } lpServer->Close(); } lpCell->Close(); } } AfsClass_Leave(); return 0; } DWORD WINAPI Main_Redraw_ThreadProc (PVOID lp) { BOOL fInvalidate = (BOOL)(UINT_PTR)lp; AfsClass_Enter(); if (g.lpiCell == NULL) { AfsAppLib_Uncover (GetDlgItem (g.hMain, IDC_SERVERS)); } else { TCHAR szName[ cchRESOURCE ]; g.lpiCell->GetCellName (szName); LPTSTR pszCover = FormatString (IDS_SEARCHING_FOR_SERVERS, TEXT("%s"), szName); AfsAppLib_CoverWindow (GetDlgItem (g.hMain, IDC_SERVERS), pszCover); FreeString (pszCover); } LPCELL lpCell = NULL; if (g.lpiCell != NULL) lpCell = g.lpiCell->OpenCell(); if (lpCell) { if (fInvalidate) { lpCell->Invalidate(); lpCell->RefreshAll(); } else { lpCell->RefreshStatus(); lpCell->RefreshServers(); } } else // no cell is selected; we'll have to redraw the window directly. { UpdateDisplay_Cell (TRUE); UpdateDisplay_Servers (TRUE, NULL, 0); } if (lpCell != NULL) lpCell->Close(); AfsClass_Leave(); return 0; } void Main_OnPreviewPane (BOOL fPreviewNew, BOOL fVertNew, BOOL fStoreCurrentView) { if (fStoreCurrentView) { if (gr.fPreview && !gr.fVert) FL_StoreView (GetDlgItem (g.hMain, IDC_SERVERS), &gr.diHorz.viewSvr); else FL_StoreView (GetDlgItem (g.hMain, IDC_SERVERS), &gr.diVert.viewSvr); if (gr.fPreview) GetWindowRect (g.hMain, &gr.rMainPreview); else GetWindowRect (g.hMain, &gr.rMain); } // If switching from having a preview pane to not (or vice-versa), // and we have an alterate gr.rMain* to switch to, resize the window. // if (IsWindowVisible (g.hMain)) { RECT rNow; GetWindowRect (g.hMain, &rNow); LPRECT prTarget = (fPreviewNew) ? &gr.rMainPreview : &gr.rMain; if (prTarget->right == 0) { *prTarget = rNow; if (gr.fPreview && gr.fVert) // preview pane exists below main window? { RECT rPreview; GetWindowRect (GetDlgItem (g.hMain, IDC_TABS), &rPreview); if (gr.fVert) prTarget->bottom -= cyRECT(rPreview); } } prTarget->right = prTarget->left + cxRECT(rNow); // keep the same width! fEnforceMinimumSize = FALSE; fNotifyChildrenForResize = FALSE; SetWindowPos (g.hMain, NULL, 0, 0, cxRECT(*prTarget), cyRECT(*prTarget), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); fNotifyChildrenForResize = TRUE; fEnforceMinimumSize = TRUE; } // Create a tab control if necessary, or remove it if it should be gone. // if (fPreviewNew && !GetDlgItem (g.hMain, IDC_TABS)) { Main_CreateTabControl(); } if (!fPreviewNew && GetDlgItem (g.hMain, IDC_TABS)) { Main_DeleteTabControl(); } // If there's a tab control, we'll need a splitter; if not, not. // if (GetDlgItem (g.hMain, IDC_SPLITTER_SERVER)) { DeleteSplitter (g.hMain, IDC_SPLITTER_SERVER); } Main_RearrangeChildren (fPreviewNew, fVertNew); if (fPreviewNew) { CreateSplitter (g.hMain, IDC_SERVERS, IDC_TABS, IDC_SPLITTER_SERVER, (fVertNew) ? &gr.diVert.cSplitter : &gr.diHorz.cSplitter, awdSplitServer, TRUE); } if (GetDlgItem (g.hMain, IDC_TABS)) { ShowWindow (GetDlgItem (g.hMain, IDC_TABS), SW_SHOW); } LPVIEWINFO lpvi = (fPreviewNew && !fVertNew) ? &gr.diHorz.viewSvr : &gr.diVert.viewSvr; FL_RestoreView (GetDlgItem (g.hMain, IDC_SERVERS), lpvi); CheckMenuRadioItem (GetMenu (g.hMain), M_DIVIDE_NONE, M_DIVIDE_H, ( (!fPreviewNew) ? M_DIVIDE_NONE : (fVertNew) ? M_DIVIDE_V : M_DIVIDE_H ), MF_BYCOMMAND); gr.fVert = fVertNew; gr.fPreview = fPreviewNew; Main_SetServerViewMenus(); } void Main_OnServerView (int lvsNew) { HWND hServers = GetDlgItem (g.hMain, IDC_SERVERS); if (gr.fPreview && !gr.fVert) FL_StoreView (hServers, &gr.diHorz.viewSvr); else FL_StoreView (hServers, &gr.diVert.viewSvr); if (gr.fPreview && !gr.fVert) gr.diHorz.viewSvr.lvsView = lvsNew; else gr.diVert.viewSvr.lvsView = lvsNew; if (gr.fPreview && !gr.fVert) FL_RestoreView (hServers, &gr.diHorz.viewSvr); else FL_RestoreView (hServers, &gr.diVert.viewSvr); Main_SetServerViewMenus(); FastList_SetTextCallback (GetDlgItem (g.hMain, IDC_SERVERS), GetItemText, ((gr.fPreview && !gr.fVert) ? &gr.diHorz.viewSvr : &gr.diVert.viewSvr)); UpdateDisplay_Servers (FALSE, NULL, 0); } void Main_SetServerViewMenus (void) { LONG lvs; if (gr.fPreview && !gr.fVert) lvs = gr.diHorz.viewSvr.lvsView; else lvs = gr.diVert.viewSvr.lvsView; CheckMenuRadioItem (GetMenu (g.hMain), M_SVR_VIEW_LARGE, M_SVR_VIEW_REPORT, ( (lvs == FLS_VIEW_SMALL) ? M_SVR_VIEW_SMALL : (lvs == FLS_VIEW_LIST) ? M_SVR_VIEW_REPORT : M_SVR_VIEW_LARGE ), MF_BYCOMMAND); ICONVIEW ivSvr = Display_GetServerIconView(); CheckMenuRadioItem (GetMenu (g.hMain), M_SVR_VIEW_ONEICON, M_SVR_VIEW_STATUS, (ivSvr == ivTWOICONS) ? M_SVR_VIEW_TWOICONS : (ivSvr == ivONEICON) ? M_SVR_VIEW_ONEICON : M_SVR_VIEW_STATUS, MF_BYCOMMAND); EnableMenu (GetMenu (g.hMain), M_SVR_VIEW_ONEICON, (lvs == FLS_VIEW_LIST) ? TRUE : FALSE); EnableMenu (GetMenu (g.hMain), M_SVR_VIEW_TWOICONS, (lvs == FLS_VIEW_LIST) ? TRUE : FALSE); EnableMenu (GetMenu (g.hMain), M_SVR_VIEW_STATUS, (lvs == FLS_VIEW_LIST) ? TRUE : FALSE); } void Main_SetActionMenus (void) { CheckMenu (GetMenu (g.hMain), M_ACTIONS, gr.fActions); } void Main_CreateTabControl (void) { HWND hTab = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TABCONTROL, TEXT(""), WS_CHILD | WS_CLIPSIBLINGS | WS_TABSTOP, 0, 0, 128, 128, // arbitrary, but not too small SERVERWINDOW_PREVIEWPANE, (HMENU)IDC_TABS, THIS_HINST, NULL); if (hTab != NULL) { HFONT hf = (HFONT)GetStockObject (DEFAULT_GUI_FONT); SendMessage (hTab, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0)); Server_PrepareTabControl (hTab); LPIDENT lpi = (LPIDENT)FL_GetSelectedData (GetDlgItem (g.hMain, IDC_SERVERS)); Server_SelectServer (SERVERWINDOW_PREVIEWPANE, lpi); } } void Main_DeleteTabControl (void) { if (GetDlgItem (SERVERWINDOW_PREVIEWPANE, IDC_TABS)) { DestroyWindow (GetDlgItem (SERVERWINDOW_PREVIEWPANE, IDC_TABS)); } } void Main_DisplayTab (CHILDTAB iTab) { if (gr.fPreview) { Server_DisplayTab (SERVERWINDOW_PREVIEWPANE, iTab); gr.tabLast = (CHILDTAB)iTab; } } void Main_RearrangeChildren (BOOL fPreviewNew, BOOL fVertNew) { RECT rServers; RECT rPreview; // Start with the Servers window taking up the entire dialog's client area, // leaving a space at the top for the cell combobox. // RECT rCell; GetRectInParent (GetDlgItem (g.hMain, IDC_AFS_ID), &rCell); GetClientRect (g.hMain, &rServers); rServers.top = rCell.bottom +3; // Then, if the preview tab is to be displayed, make the server window // share the space equally with the tab control (vertically or horizontally) // if (fPreviewNew) { rPreview = rServers; if (fVertNew) { rServers.bottom = rServers.top + cyRECT(rServers)/2 - 1; rPreview.top = rServers.bottom + 2; } else { rServers.right = rServers.left + cxRECT(rServers)/2 - 1; rPreview.left = rServers.right + 2; } // Adjust the server/tab windows for the Server splitter's position // if (fVertNew) { LONG cyMod = gr.diVert.cSplitter; if (cyRECT(rServers) > cyMIN_SERVER) cyMod = min( cyMod, cyRECT(rServers)-cyMIN_SERVER ); if (cyRECT(rPreview) > cyMIN_TABS) cyMod = min( cyMod, cyRECT(rPreview)-cyMIN_TABS ); rServers.bottom += cyMod; rPreview.top += cyMod; } else { LONG cxMod = gr.diHorz.cSplitter; if (cxRECT(rServers) > cxMIN_SERVER) cxMod = min( cxMod, cxRECT(rServers)-cxMIN_SERVER ); if (cxRECT(rPreview) > cxMIN_TABS) cxMod = min( cxMod, cxRECT(rPreview)-cxMIN_TABS ); rServers.right += cxMod; rPreview.left += cxMod; } } // Now move the children to their new places! // int nWindows = 1; if (GetDlgItem (g.hMain, IDC_COVERDLG)) ++nWindows; if (GetDlgItem (g.hMain, IDC_TABS)) ++nWindows; HDWP dwp = BeginDeferWindowPos (nWindows); DeferWindowPos (dwp, GetDlgItem (g.hMain, IDC_SERVERS), NULL, rServers.left, rServers.top, cxRECT(rServers), cyRECT(rServers), SWP_NOACTIVATE | SWP_NOZORDER); if (GetDlgItem (g.hMain, IDC_COVERDLG)) { DeferWindowPos (dwp, GetDlgItem (g.hMain, IDC_COVERDLG), NULL, rServers.left, rServers.top, cxRECT(rServers), cyRECT(rServers), SWP_NOACTIVATE | SWP_NOZORDER); } if (GetDlgItem (g.hMain, IDC_TABS)) { DeferWindowPos (dwp, GetDlgItem (g.hMain, IDC_TABS), NULL, rPreview.left, rPreview.top, cxRECT(rPreview), cyRECT(rPreview), SWP_NOACTIVATE | SWP_NOZORDER); } EndDeferWindowPos (dwp); } static LONG_PTR procServers = 0; LRESULT CALLBACK Main_SubclassServersProc (HWND hServers, UINT msg, WPARAM wp, LPARAM lp) { LRESULT rc; if (procServers == 0) rc = DefWindowProc (hServers, msg, wp, lp); else rc = (LRESULT) CallWindowProc ((WNDPROC)procServers, hServers, msg, wp, lp); switch (msg) { case WM_DESTROY: if (procServers != 0) SetWindowLongPtr (hServers, GWLP_WNDPROC, procServers); break; case WM_COMMAND: switch (LOWORD(wp)) { case M_SVR_VIEW_LARGE: case M_SVR_VIEW_SMALL: case M_SVR_VIEW_REPORT: SendMessage (g.hMain, msg, wp, lp); break; case M_VIEW_ONEICON: case M_VIEW_TWOICONS: case M_VIEW_STATUS: SendMessage (g.hMain, msg, wp, lp); break; case M_COLUMNS: ShowColumnsDialog (g.hMain, NULL); break; default: StartContextCommand (g.hMain, NULL, (LPIDENT)FL_GetSelectedData (hServers), LOWORD(wp)); break; } break; } return rc; } void Main_SubclassServers (HWND hDlg) { HWND hServers = GetDlgItem (hDlg, IDC_SERVERS); procServers = GetWindowLongPtr (hServers, GWLP_WNDPROC); SetWindowLongPtr (hServers, GWLP_WNDPROC, (LONG_PTR)Main_SubclassServersProc); } #ifdef DEBUG void ExportCell (void) { if (!g.lpiCell) return; TCHAR szFilter[ cchRESOURCE ]; lstrcpy (szFilter, TEXT("Text File|*.TXT|")); TCHAR chFilter = szFilter[ lstrlen(szFilter)-1 ]; for (LPTSTR pszFilter = szFilter; (*pszFilter) && ((pszFilter = (LPTSTR)lstrchr (pszFilter, chFilter)) != NULL); ++pszFilter) { *pszFilter = TEXT('\0'); } TCHAR szSaveAs[ MAX_PATH ] = TEXT("export"); OPENFILENAME sfn; memset (&sfn, 0x00, sizeof(sfn)); sfn.lStructSize = sizeof(sfn); sfn.hwndOwner = g.hMain; sfn.hInstance = THIS_HINST; sfn.lpstrFilter = szFilter; sfn.nFilterIndex = 1; sfn.lpstrFile = szSaveAs; sfn.nMaxFile = MAX_PATH; sfn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; sfn.lpstrDefExt = TEXT("txt"); if (GetSaveFileName (&sfn)) { LPTSTR psz = CloneString (szSaveAs); StartTask (taskEXPORTCELL, NULL, psz); } } #endif void Main_StartWorking (void) { if (InterlockedIncrement(&nReqWorking) == 1) { AfsAppLib_StartAnimation (GetDlgItem (g.hMain, IDC_ANIMATE)); } } void Main_StopWorking (void) { if (InterlockedDecrement(&nReqWorking) == 0) { AfsAppLib_StopAnimation (GetDlgItem (g.hMain, IDC_ANIMATE)); } } void Main_AnimateIcon (HWND hIcon, int *piFrameLast) { static HICON hiStop; static HICON hiFrame[8]; static BOOL fLoaded = FALSE; if (!fLoaded) { hiStop = TaLocale_LoadIcon (IDI_SPINSTOP); hiFrame[0] = TaLocale_LoadIcon (IDI_SPIN1); hiFrame[1] = TaLocale_LoadIcon (IDI_SPIN2); hiFrame[2] = TaLocale_LoadIcon (IDI_SPIN3); hiFrame[3] = TaLocale_LoadIcon (IDI_SPIN4); hiFrame[4] = TaLocale_LoadIcon (IDI_SPIN5); hiFrame[5] = TaLocale_LoadIcon (IDI_SPIN6); hiFrame[6] = TaLocale_LoadIcon (IDI_SPIN7); hiFrame[7] = TaLocale_LoadIcon (IDI_SPIN8); fLoaded = TRUE; } if (piFrameLast) { *piFrameLast = (*piFrameLast == 7) ? 0 : (1+*piFrameLast); } SendMessage (hIcon, STM_SETICON, (WPARAM)((piFrameLast) ? hiFrame[ *piFrameLast ] : hiStop), 0); } BOOL Main_HandleDialogKeys (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { if (msg == WM_COMMAND) { switch (LOWORD(wp)) { case M_KEY_RETURN: Server_OnKey_Return(); return TRUE; case M_KEY_CTRLTAB: Main_OnKey_CtrlTab (TRUE); return TRUE; case M_KEY_CTRLBACKTAB: Main_OnKey_CtrlTab (FALSE); return TRUE; case M_KEY_TAB: Main_OnKey_Tab (TRUE); return TRUE; case M_KEY_BACKTAB: Main_OnKey_Tab (FALSE); return TRUE; case M_KEY_MENU: Server_OnKey_Menu(); return TRUE; case M_KEY_ESC: Server_OnKey_Esc(); return TRUE; case M_KEY_PROPERTIES: Server_OnKey_Properties(); return TRUE; } } return FALSE; } void Main_OnKey_Tab (BOOL fForward) { // The tab-cycle should go: // ServerList <-> TabsOnQuickViewPane <-> TabChildControls // // If the quick-view pane isn't showing, there's nowhere to tab to. // if (gr.fPreview) { HWND hFocus = GetFocus(); HWND hTabChild = GetTabChild (GetDlgItem (g.hMain, IDC_TABS)); if (fForward) { if (hFocus == GetDlgItem (g.hMain, IDC_SERVERS)) { PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (g.hMain, IDC_TABS), TRUE); } else if (hFocus == GetDlgItem (g.hMain, IDC_TABS)) { PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetNextDlgTabItem (hTabChild, NULL, FALSE), TRUE); } else { if (GetNextDlgTabItem (hTabChild, hFocus, FALSE) == GetNextDlgTabItem (hTabChild, NULL, FALSE)) PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (g.hMain, IDC_SERVERS), TRUE); else PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetNextDlgTabItem (hTabChild, hFocus, FALSE), TRUE); } } else // (!fForward) { if (hFocus == GetDlgItem (g.hMain, IDC_SERVERS)) { PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetLastDlgTabItem (hTabChild), TRUE); } else if (hFocus == GetDlgItem (g.hMain, IDC_TABS)) { PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (g.hMain, IDC_SERVERS), TRUE); } else { if (hFocus == GetNextDlgTabItem (hTabChild, NULL, FALSE)) PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (g.hMain, IDC_TABS), TRUE); else PostMessage (g.hMain, WM_NEXTDLGCTL, (WPARAM)GetNextDlgTabItem (hTabChild, hFocus, TRUE), TRUE); } } } } void Main_OnKey_CtrlTab (BOOL fForward) { if (gr.fPreview) { Server_OnKey_CtrlTab (SERVERWINDOW_PREVIEWPANE, fForward); } }