// // Called when the dockpanel receivees a WM_NOTIFY from one of its child-windows // i.e. either the TabView, or one of the DOCKWND's // LRESULT DockPanel_OnNotify(DOCKPANEL *dpp, WPARAM wParam, NMHDR *hdr) { // notification message from the TabView if(hdr->hwndFrom == dpp->hwndTabView) { TCITEM tci = { TCIF_PARAM }; DOCKWND *dwp; // get the active selection int iItem = TabCtrl_GetCurSel(dpp->hwndTabView); // every tab-item's lParam is a dockwindow-ID TabCtrl_GetItem(dpp->hwndTabView, iItem, &tci); switch(hdr->code) { case TCN_SELCHANGE: // show the appropriate DOCKWND DockWnd_Show(dpp->hwndMain, (UINT)tci.lParam, TRUE); break; case TCN_CLOSE: // hide the DOCKWND DockWnd_Show(dpp->hwndMain, (UINT)tci.lParam, FALSE); // delete the tab TabCtrl_DeleteItem(dpp->hwndTabView, iItem); break; case TCN_MOUSELEAVE: // the mouse has moved outside of the tab, // whilst being clicked - so we need to drag // the tab off into its own floating dock-window dwp = DOCKWNDFromId(dpp->hwndMain, (UINT)tci.lParam); if(dpp->WndListHead->flink == dwp && dpp->WndListTail->blink == dwp) { // if this is the last tab, then do a normal undock SendMessage(dpp->hwndTabView, WM_CANCELMODE, 0, 0); dpp->fUndockNextMsg = TRUE; DragOff(dpp); } else { // otherwise detach the tab and float it in a new DOCKPANEL UndockAndRemoveTab(dpp, (UINT)tci.lParam); } break; } return 0; } else { // forward it straight on return SendMessage(dpp->hwndMain, WM_NOTIFY, wParam, (LPARAM)hdr); } }
void UndockAndRemoveTab(DOCKPANEL *dpp, UINT uWndId) { DOCKPANEL *dppNew; DOCKWND *dwp; POINT pt; SendMessage(dpp->hwndTabView, WM_CANCELMODE, 0, 0); dwp = DOCKWNDFromId(dpp->hwndMain, uWndId); // create a new DOCKPANEL for the floating DOCKWND dppNew = NewDockPanel(dpp->pDockServer); // make a few tweaks dppNew->dwStyle = dpp->dwStyle; dppNew->DockSize = dpp->DockSize; dppNew->FloatSize = dpp->FloatSize; dppNew->fDocked = FALSE; dppNew->uCurrentTabId = uWndId; // dwpNew->uPanelId = nextid; //dwpNew->hwndContents = dwp->hwndContents; dppNew->hwndTabView = 0; dppNew->hwndPanel = 0; // delete the old one if this was the last tab // that we dragged off //if(dpp->WndListHead->flink == dpp->WndListTail) //{ // RemoveObj(dpp); //} // start a mouse-drag at curr GetCursorPos(&pt); dppNew->xpos = pt.x - 20; dppNew->ypos = pt.y - 20; // hide the tab that we are about to undock.... but KEEP the hwndContent!!! DockWnd_HideInternal2(dwp, TRUE);//, FALSE, TRUE); SetDockPanel(dppNew, dwp); // show the tab in the new dockpanel DockWnd_Show(dppNew->hwndMain, uWndId, TRUE); dppNew->fUndockNextMsg = TRUE; dppNew->fDragging = TRUE; //DelKey(dsp, dpp->uPanelId, uWndId); DockPanel_SetKeyboardHook(dppNew); //SendMessage(dwpNew->hwndPanel, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(dwpNew->xpos, dwpNew->ypos)); SendMessage(dppNew->hwndPanel, WM_SYSCOMMAND, SC_MOVE+HTCAPTION, MAKELPARAM(dppNew->xpos, dppNew->ypos)); }
// // Show/Hide a collection of dockwindows based on the group-id // BOOL WINAPI DockWnd_ShowGroup(HWND hwndMain, UINT uGroupId, BOOL fShow) { DOCKSERVER *dsp = GetDockServer(hwndMain); DOCKPANEL *dpp; DOCKWND *dwp; for(dpp = dsp->PanelListHead; dpp; dpp = dpp->flink) { for(dwp = dpp->WndListHead; dwp; dwp = dwp->flink) { if(dwp->uGroupId == uGroupId) { DockWnd_Show(hwndMain, dwp->uWndId, fShow); } } } return TRUE; }
// // Update the specified server-window // BOOL WINAPI DockWnd_Update(HWND hwndMain) { DOCKSERVER *dsp; DOCKPANEL *dpp; if((dsp = GetDockServer(hwndMain)) == 0) return FALSE; // for(i = 0; i < dsp->nNumDockPanels; i++) for(dpp = dsp->PanelListHead; dpp; dpp = dpp->flink) { //if(dsp->PanelList[i]hwndPanel) // DockWnd_Show(hwndMain, dsp->PanelList[i].uId, TRUE); if(dpp->fVisible)// && dpp->fDocked == FALSE && dsp->fDeferShowWindow == FALSE) { // show the 'last' current tab, this will force the window visible DockWnd_Show(hwndMain, dpp->uCurrentTabId, TRUE); } } return TRUE; }
void InitDockingBars(HWND hwnd) { HDWP hdwp = 0; DockWnd_Initialize(hwnd, REGLOC); // load DOCKWNDs from the registry DockWnd_LoadSettings(hwnd, g_fRestoreWinPos); //hdwp = DockWnd_BeginDefer(hwnd, 10); DockWnd_DeferShowPopups(hwnd); // if(DockWnd_Undefined(hwnd, DWID_TOOLBAR))//, TEXT("Toolbar"))) { DWORD dwStyle = DWS_FORCEDOCK |DWS_DRAWGRIPPER |DWS_DOCKED_TOP |DWS_THEMED_BACKGROUND |DWS_NOSETFOCUS |DWS_FIXED_VERT |DWS_FIXED_HORZ ; DockWnd_Register(hwnd, DWID_TOOLBAR, TEXT("Toolbar")); //DockWnd_SetStyle(hwnd, DWID_TOOLBAR, DWS_DOCKED|DWS_FORCEDOCK|DWS_FIXED_SIZE, DWS_DOCKED|DWS_FORCEDOCK|DWS_FIXED_SIZE); DockWnd_SetStyle(hwnd, DWID_TOOLBAR, dwStyle, dwStyle); DockWnd_Dock(hwnd, DWID_TOOLBAR); DockWnd_Show(hwnd, DWID_TOOLBAR, TRUE); CenterRelative(DockWnd_GetWindow(hwnd, DWID_TOOLBAR), hwnd, hdwp); } // if(0&&DockWnd_Undefined(hwnd, DWID_SEARCHBAR))//, TEXT("SearchBar"))) { DWORD dwStyle = DWS_DRAWGRIPPER | DWS_FIXED_VERT | DWS_DOCKED_BOTTOM; DockWnd_Register(hwnd, DWID_SEARCHBAR, TEXT("SearchBar")); DockWnd_SetStyle(hwnd, DWID_SEARCHBAR, dwStyle, dwStyle); //DockWnd_Dock(hwnd, DWID_SEARCHBAR); DockWnd_Show(hwnd, DWID_SEARCHBAR, TRUE); //CenterWindow(DockWnd_GetWindow(hwnd, DWID_SEARCHBAR)); } if(DockWnd_Undefined(hwnd, DWID_TYPEVIEW))//, TEXT("TypeView"))) { DWORD dwStyle = DWS_SPLITTER | DWS_TABSTRIP | DWS_DOCKED_BOTTOM //| //DWS_DOCKED_TITLEBAR ;// | DWS_DRAWGRIPPER; DockWnd_Register(hwnd, DWID_TYPEVIEW, TEXT("TypeView")); DockWnd_SetGroupId(hwnd, DWID_TYPEVIEW, DWID_TYPEVIEW); DockWnd_SetStyle(hwnd, DWID_TYPEVIEW, dwStyle, dwStyle); DockWnd_Dock(hwnd, DWID_TYPEVIEW); //DockWnd_Show(hwnd, DWID_TYPEVIEW, TRUE); CenterRelative(DockWnd_GetWindow(hwnd, DWID_TYPEVIEW), hwnd, hdwp); } if(DockWnd_Undefined(hwnd, DWID_ALLTYPES))//, TEXT("TypeView"))) { DWORD dwStyle = DWS_SPLITTER|DWS_TABSTRIP| DWS_DOCKED_BOTTOM;// | DWS_DRAWGRIPPER; DockWnd_RegisterEx(hwnd, DWID_ALLTYPES, DWID_TYPEVIEW, TEXT("All Types")); DockWnd_SetGroupId(hwnd, DWID_ALLTYPES, DWID_TYPEVIEW); DockWnd_SetStyle(hwnd, DWID_ALLTYPES, dwStyle, dwStyle); DockWnd_Dock(hwnd, DWID_ALLTYPES); //DockWnd_Show(hwnd, DWID_ALLTYPES, TRUE); CenterRelative(DockWnd_GetWindow(hwnd, DWID_ALLTYPES), hwnd, hdwp); } if(DockWnd_Undefined(hwnd, DWID_HIGHLIGHT)) { DWORD dwStyle = DWS_SPLITTER|DWS_TABSTRIP| DWS_DOCKED_RIGHT;// | DWS_DRAWGRIPPER; DockWnd_Register(hwnd, DWID_HIGHLIGHT, TEXT("Bookmarks")); DockWnd_SetStyle(hwnd, DWID_HIGHLIGHT, dwStyle, dwStyle); DockWnd_Dock(hwnd, DWID_HIGHLIGHT); //DockWnd_Show(hwnd, DWID_HIGHLIGHT, TRUE); CenterRelative(DockWnd_GetWindow(hwnd, DWID_HIGHLIGHT), hwnd, hdwp); } if(DockWnd_Undefined(hwnd, DWID_STRINGS)) { DWORD dwStyle = DWS_SPLITTER| DWS_DOCKED_RIGHT;// | DWS_DRAWGRIPPER; DockWnd_Register(hwnd, DWID_STRINGS, TEXT("Strings")); DockWnd_SetStyle(hwnd, DWID_STRINGS, dwStyle, dwStyle); //DockWnd_Dock(hwnd, DWID_HIGHLIGHT); //DockWnd_Show(hwnd, DWID_STRINGS, TRUE); CenterRelative(DockWnd_GetWindow(hwnd, DWID_STRINGS), hwnd, hdwp); } // DockWnd_ShowGui(hwnd); DockWnd_Update(hwnd); //DockWnd_EndDefer(hwnd); }
// // Called when the dockpanel has stopped being dragged around // need to decide whether to dock/undock/leave it as it is // LRESULT DockPanel_ExitSizeMove(DOCKPANEL *dpp) { extern HWND hwndTransPanel; DestroyWindow(hwndTransPanel); hwndTransPanel = 0; DockPanel_RemoveKeyboardHook(dpp); dpp->fUndockNextMsg = FALSE; if(dpp->fDragging) { DOCKSERVER *dsp = dpp->pDockServer; DOCKPANEL *dppUnder; RECT rectDrag; POINT pt; UINT area; HWND hwnd; DestroyWindow(hwndTransPanel); hwndTransPanel = 0; dpp->fDragging = FALSE; GetCursorPos(&pt); area = GetDockTarget(dpp->pDockServer, dpp, pt, &rectDrag, &dppUnder); // did we want to dock onto anything? if(area != 0)//dpp->fDragStatus || g_dppTargetDockPanel) { ShowWindow(dpp->hwndPanel, SW_HIDE); RemoveWindowTrans(dpp->hwndPanel); // docking onto an existing DOCKPANEL (i.e. not the main window, // but becoming a tab in another panel) if(area == TAB) { // move all DOCKWNDs in the current panel to the DOCKPANEL // that we are dragging on to DOCKWND *dwp, *next = 0; for(dwp = dpp->WndListHead->flink; dwp != dpp->WndListTail; dwp = next)//dwp->flink) { next = dwp->flink; SetDockPanel(dppUnder, dwp); DockWnd_Show(dpp->hwndMain, dwp->uWndId, TRUE); } UpdateDockTabView(dppUnder); // oof! RemoveObj(dpp); hwnd = dpp->hwndPanel; dpp->hwndPanel = 0; DestroyWindow(hwnd);//dpp->hwndPanel); } // otherwise dock with the main window else { // if docking on the inside, // move to end of dock-panel list if(dppUnder == (DOCKPANEL *)1) // NASTY HACK!! WHY!??? { RemoveObj(dpp); InsertBefore(dpp, dsp->PanelListTail); } // if docking else if(dppUnder) { if( area == TOP && (dppUnder->dwStyle & BOTTOM) || area == BOTTOM && (dppUnder->dwStyle & TOP) || area == LEFT && (dppUnder->dwStyle & RIGHT) || area == RIGHT && (dppUnder->dwStyle & LEFT)) { // inside of target panel RemoveObj(dpp); InsertBefore(dpp, dppUnder->flink); if(area == TOP) area = BOTTOM; else if(area == BOTTOM) area = TOP; else if(area == LEFT) area = RIGHT; else if(area == RIGHT) area = LEFT; } else if( area == TOP && (dppUnder->dwStyle & TOP) || area == BOTTOM && (dppUnder->dwStyle & BOTTOM) || area == LEFT && (dppUnder->dwStyle & LEFT) || area == RIGHT && (dppUnder->dwStyle & RIGHT)) { // outside of target panel RemoveObj(dpp); InsertBefore(dpp, dppUnder); } } // if docking against the outside edge else { RemoveObj(dpp); InsertBefore(dpp, dsp->PanelListHead->flink); } dpp->dwStyle = (dpp->dwStyle & ~DWS_DOCKED_MASK) | area; DockWindow(dpp); } ShowWindow(dpp->hwndPanel, SW_SHOW); } dpp->fDragging = FALSE; dpp->fDragStatus = 0; } // if the dock-panel is still floating, determine if it's edges // intersect the main window, and turn on the 'sticky' flag if(dpp->fDocked == FALSE) { RECT r1, r2, r3; GetWindowRect(dpp->hwndMain, &r2); GetWindowRect(dpp->hwndPanel, &r3); dpp->fSticky = IntersectRect(&r1, &r2, &r3); } return 0; }