// /// Event handler for the WM_HELP message. // void THelpFileManager::EvHelp(const HELPINFO& hi) { THelpContext context; bool success = false; uint hlpCmd = HELP_CONTEXTPOPUP; if (hi.iContextType == HELPINFO_MENUITEM){ success = GetHelpContextFromMenu(context, hi.iCtrlId); hlpCmd = HELP_CONTEXT; } else if (hi.iContextType == HELPINFO_WINDOW) success = GetHelpContextFromControl(context, hi.iCtrlId, (HWND)hi.hItemHandle); LastHit = hi.MousePos; if (::GetKeyState(VK_F1) < 0 && ::GetKeyState(VK_SHIFT) < 0) { TWindow* wnd = context.GetWindow(); TWindow* child = wnd->ChildWithId(hi.iCtrlId); LastHit = TPoint(wnd->GetWindowAttr().X + child->GetWindowAttr().X, wnd->GetWindowAttr().Y + child->GetWindowAttr().Y); } else if(::GetKeyState(VK_F1) < 0) LastHit = TPoint(-1, -1); if (success) ActivateHelp(context.GetWindow(), context.GetHelpFileContextId(), hlpCmd); }
// /// Insert a decoration window at the left of the client area, possibly to the /// left of another given decoration or the client // void TDecoratedFrame::InsertAtLeft(TWindow& decoration, TWindow* insertLeftOf) { TLayoutMetrics metrics; TWindow* insertRightOf; // Get the layout metrics for "insertLeftOf"(the window the decoration is // going to be inserted to the left of) // GetChildLayoutMetrics(*insertLeftOf, metrics); insertRightOf = metrics.X.RelWin; // If "insertLeftOf" has a border then set its left edge to be the same as // the decoration's right edge; otherwise place its left edge one pixel to // the right of the decoration's right edge // metrics.X.Set(lmLeft, insertLeftOf->GetWindowAttr().Style & WS_BORDER ? lmSameAs : lmRightOf, &decoration, lmRight); SetChildLayoutMetrics(*insertLeftOf, metrics); // Now set the layout metrics for the decoration so it's left edge is the // same as the right edge of "insertRightOf" // bool overlap = (decoration.GetWindowAttr().Style & WS_BORDER); metrics.X.Set(lmLeft, overlap ? lmSameAs : lmRightOf, insertRightOf, insertRightOf ? lmRight : lmLeft); metrics.Width.AsIs(lmWidth); // If the client window & decoration both have or don't have borders then // place the decoration so its "y" and "bottom" are the same as the client // windows; otherwise place its "y" above/below the client window's "y" and // its "bottom" below/above the client window's "bottom" based on who's has // borders & who doesn't // // This way if there are top or bottom decorations they will be tiled // over/under the left/right decorations // if (ToBool(ClientWnd->GetWindowAttr().Style & WS_BORDER) == overlap) { metrics.Y.SameAs(ClientWnd, lmTop); metrics.Height.SameAs(ClientWnd, lmBottom); } else if (overlap) { metrics.Y.Set(lmTop, lmAbove, ClientWnd, lmTop); metrics.Height.Set(lmBottom, lmBelow, ClientWnd, lmBottom); } else { metrics.Y.Set(lmTop, lmBelow, ClientWnd, lmTop); metrics.Height.Set(lmBottom, lmAbove, ClientWnd, lmBottom); } SetChildLayoutMetrics(decoration, metrics); }
// /// Insert a decoration window at the bottom of the client area, possibly below /// another given decoration or the client // void TDecoratedFrame::InsertAtBottom(TWindow& decoration, TWindow* insertBelow) { TLayoutMetrics metrics; TWindow* insertAbove; // Get the layout metrics for "insertBelow"(the window the decoration is // going to be inserted below) // GetChildLayoutMetrics(*insertBelow, metrics); if (insertBelow == ClientWnd) { insertAbove = metrics.Height.RelWin; // If the client window has a border then set the client window's bottom // to be the same as the top edge of the decoration; otherwise set the // client window's bottom edge to be above the decoration's top edge // metrics.Height.Set(lmBottom, ClientWnd->GetWindowAttr().Style & WS_BORDER ? lmSameAs : lmAbove, &decoration, lmTop); } else { insertAbove = metrics.Y.RelWin; // Set the bottom edge of "insertBelow" to be the same as the top edge of // the decoration // metrics.Y.Set(lmBottom, lmSameAs, &decoration, lmTop); } SetChildLayoutMetrics(*insertBelow, metrics); // Now set the layout metrics for the decoration so its bottom edge is the // same as the top edge of "insertAbove" // bool overlap = (decoration.GetWindowAttr().Style & WS_BORDER); metrics.Y.Set(lmBottom, overlap ? lmSameAs : lmAbove, insertAbove, insertAbove ? lmTop : lmBottom); metrics.Height.AsIs(lmHeight); metrics.X.Set(lmLeft, overlap ? lmSameAs : lmRightOf, lmParent, lmLeft); metrics.Width.Set(lmRight, overlap ? lmSameAs : lmLeftOf, lmParent, lmRight); SetChildLayoutMetrics(decoration, metrics); }
// /// Insert a decoration window into position at one of the four edges. // /// After you specify where the decoration should be placed, Insert adds it just /// above, below, left, or right of the client window. This process is especially /// important when there are multiple decorations. Insert looks at the decoration's /// Attr.Style member and checks the WS_VISIBLE flag to tell whether the decoration /// should initially be visible or hidden. /// To position the decoration, Insert uses TLocation enum, which describes Top, /// Left, Bottom, and Right positions where the decoration can be placed. // void TDecoratedFrame::Insert(TWindow& decoration, TLocation location) { // Store away location for remove/re-insetion // SetLocation(decoration, location); // Make sure the decoration has clipsiblings style, since our rearranging // causes corners to overlap sometimes. // ModifyStyle(0, WS_CLIPSIBLINGS);//|WS_CLIPCHILDREN);///???? // Parent to decframe and remove layoutmetrics in case it's a re-insert // decoration.SetParent(this); RemoveChildLayoutMetrics(decoration); // If the window should be visible, proceed with insertion. // NOTE: Should we check the 'wfInsertAtEdge' flag here? It mostly // important when hiding/showing decorations [i.e. In EvCommand // handler]. However, it would be nice to check for it and use // something other than ClientWnd if necessary. // if (decoration.GetWindowAttr().Style & WS_VISIBLE) { switch (location) { case None: break; case Top: InsertAtTop(decoration, ClientWnd); break; case Bottom: InsertAtBottom(decoration, ClientWnd); break; case Left: InsertAtLeft(decoration, ClientWnd); break; case Right: InsertAtRight(decoration, ClientWnd); break; default: //JJH added empty default statement break; } } }
// /// Insert a decoration window at the top of the client area, possibly above /// another given decoration or the client // void TDecoratedFrame::InsertAtTop(TWindow& decoration, TWindow* insertAbove) { TLayoutMetrics metrics; TWindow* insertBelow; // Get the layout metrics for "insertAbove" (the window the decoration is // going to be inserted above) // GetChildLayoutMetrics(*insertAbove, metrics); insertBelow = metrics.Y.RelWin; // If "insertAbove" has a border then set its top edge to be the same as // the decoration's bottom edge; otherwise place its top edge below the // decoration's bottom edge // metrics.Y.Set(lmTop, insertAbove->GetWindowAttr().Style & WS_BORDER ? lmSameAs : lmBelow, &decoration, lmBottom); SetChildLayoutMetrics(*insertAbove, metrics); // Now set the layout metrics for the decoration so its top edge is the same // as or below the bottom edge of "insertBelow" (they overlap if WS_BORDER) // !CQ want to use lmBelow if no border!? // bool overlap = (decoration.GetWindowAttr().Style & WS_BORDER); metrics.Y.Set(lmTop, overlap ? lmSameAs : lmBelow, insertBelow, insertBelow ? lmBottom : lmTop); metrics.Height.AsIs(lmHeight); metrics.X.Set(lmLeft, overlap ? lmSameAs : lmRightOf, lmParent, lmLeft); metrics.Width.Set(lmRight, overlap ? lmSameAs : lmLeftOf, lmParent, lmRight); SetChildLayoutMetrics(decoration, metrics); }
// /// Causes the window to resize and position its children according to the specified /// metrics. You can call Layout to implement changes that occur in the layout /// metrics. // void TLayoutWindow::Layout() { if (ChildMetrics) { TChildMetrics* childMetrics; GetFontHeight(); // Initialize the parent's variables // Variables[2].Value = ClientSize.cx - 1; Variables[3].Value = ClientSize.cy - 1; TRACEX(OwlLayout, 0, _T("Layout() ClientSize: ") << ClientSize); if (hasBorder(this)) { int cxBorder = TUIMetric::CxBorder; int cyBorder = TUIMetric::CyBorder; Variables[0].Value = -cxBorder; Variables[1].Value = -cyBorder; Variables[2].Value += cxBorder; Variables[3].Value += cyBorder; } else { Variables[0].Value = 0; Variables[1].Value = 0; } TRACEX(OwlLayout, 1, _T("Layout() Variables: 0=>") << Variables[0] << _T(", 1=>" << Variables[1]<< ", 2=>" << Variables[2]<< ", 3=>") << Variables[3]); // Rebuild layout plan if necessary // if (PlanIsDirty) { PlanIsDirty = false; for (childMetrics = ChildMetrics; childMetrics; childMetrics = childMetrics->Next) BuildConstraints(*childMetrics); BuildPlan(); } // Use the plan to calculate actual child window position values // ExecutePlan(); // Find out how many windows we're dealing with // int numWindows = 0; for (childMetrics = ChildMetrics; childMetrics; childMetrics = childMetrics->Next) { TWindow* win = childMetrics->Child; if (win->GetHandle()) numWindows++; } #if !defined(OWL_NO_DEFERWINDOWPOS_LAYOUT) // Helper object to use 'DefWindowPos' API // TDeferWinPos dwp(numWindows); #endif // Do actual resizing // for (childMetrics = ChildMetrics; childMetrics; childMetrics = childMetrics->Next) { TWindow* win = childMetrics->Child; TVariable* variables = childMetrics->Variables; TRACEX(OwlLayout, 0, _T("Layout() variables: ") << variables[0] << _T(',') << variables[1] << _T(',') << variables[2] << _T(',') << variables[3]); if (win->GetHandle()) { #if defined(OWL_NO_DEFERWINDOWPOS_LAYOUT) win->SetWindowPos( 0, variables[0].Value, variables[1].Value, variables[2].Value - variables[0].Value + 1, variables[3].Value - variables[1].Value + 1, SWP_NOACTIVATE | SWP_NOZORDER ); #else dwp.DeferWindowPos(*win, 0, variables[0].Value, variables[1].Value, variables[2].Value - variables[0].Value + 1, variables[3].Value - variables[1].Value + 1, SWP_NOACTIVATE | SWP_NOZORDER); #endif } else { win->GetWindowAttr().X = variables[0].Value; win->GetWindowAttr().Y = variables[1].Value; win->GetWindowAttr().W = variables[2].Value - variables[0].Value + 1; win->GetWindowAttr().H = variables[3].Value - variables[1].Value + 1; } } } }
inline void SetLocation(TWindow& w, TDecoratedFrame::TLocation loc) { w.GetWindowAttr().Style = (w.GetWindowAttr().Style & ~locMask) | (uint32(loc) << locShift); }
inline TDecoratedFrame::TLocation GetLocation(TWindow& w) { return TDecoratedFrame::TLocation(uint16((w.GetWindowAttr().Style & locMask) >> locShift)); }