home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // ObjectWindows
- // (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
- //
- // Implementation of class TFrameWindow
- //----------------------------------------------------------------------------
- #pragma hdrignore SECTION
- #include <owl/owlpch.h>
- #include <owl/framewin.h>
- #include <owl/applicat.h>
- #include <owl/menu.h>
-
- #if !defined(SECTION) || SECTION == 1
-
- DEFINE_RESPONSE_TABLE1(TFrameWindow, TWindow)
- EV_WM_PAINT,
- EV_WM_ERASEBKGND,
- EV_WM_QUERYDRAGICON,
- EV_WM_INITMENUPOPUP,
- EV_WM_SETFOCUS,
- EV_WM_SIZE,
- EV_WM_PARENTNOTIFY,
- EV_WM_ENTERIDLE,
- END_RESPONSE_TABLE;
-
- //
- // Enable/disable the command sender, in this case the menu item.
- //
- void
- TMenuItemEnabler::Enable(bool enable)
- {
- TCommandEnabler::Enable(enable);
- ::EnableMenuItem(HMenu, Position,
- MF_BYPOSITION | (enable ? MF_ENABLED : MF_GRAYED));
- }
-
- //
- // Set the text for the command sender, in this case the menu item.
- //
- void
- TMenuItemEnabler::SetText(const char far* str)
- {
- ::ModifyMenu(HMenu, Position, MF_BYPOSITION | MF_STRING, Id, str);
- }
-
- //
- // Set the check state of the command sender, in this case the menu item.
- //
- void
- TMenuItemEnabler::SetCheck(int state)
- {
- ::CheckMenuItem(HMenu, Position,
- MF_BYPOSITION | (state == Checked ? MF_CHECKED : MF_UNCHECKED));
- }
-
- //----------------------------------------------------------------------------
-
- //
- // constructor for a TFrameWindow
- //
- TFrameWindow::TFrameWindow(TWindow* parent,
- const char far* title,
- TWindow* clientWnd,
- bool shrinkToClient,
- TModule* module)
- {
- //
- // Initialize virtual base, in case the derived-most used default ctor
- //
- TWindow::Init(parent, title, module);
-
-
- IconResId = 0; // remember that we still need to init
- Init(clientWnd, shrinkToClient);
- }
-
- //
- // constructor for a TFrameWindow. This ctor is generally not used by derived
- // classes, only as generic alias to a framewindow-like HWND
- //
- TFrameWindow::TFrameWindow(HWND hWnd, TModule* module)
- : TWindow(hWnd, module)
- {
- Init(0);
- }
-
- //
- // Protected constructor for use by immediate virtually derived classes.
- // Immediate derivitives must call Init() before constructions are done.
- //
- TFrameWindow::TFrameWindow()
- {
- IconResId = 0; // Zero this member to remember that we still need to init
- }
-
- //
- // Normal initialization of a default constructed TFrameWindow. Is ignored
- // if called more than once.
- //
- void
- TFrameWindow::Init(TWindow* clientWnd, bool shrinkToClient)
- {
- if (!IconResId) {
- Attr.Style = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
- Attr.X = Attr.W = CW_USEDEFAULT;
-
- if (clientWnd)
- Attr.Style |= WS_CLIPCHILDREN;
-
- if (shrinkToClient)
- SetFlag(wfShrinkToClient);
-
- Init(clientWnd);
- }
- }
-
- //
- // Private initializer does a bulk of the common frame window initialization
- //
- void
- TFrameWindow::Init(TWindow* clientWnd)
- {
- HWndRestoreFocus = 0;
- KeyboardHandling = false;
- ClientWnd = clientWnd;
-
- MenuDescr = 0;
- MergeModule = 0;
-
- IconModule = ::Module;
- IconResId = IDI_OWLAPP;
-
- MinimizedPos = TPoint(-1,-1); // Windows convention for never minimized
-
- if (ClientWnd) {
- ClientWnd->SetParent(this);
- ClientWnd->EnableAutoCreate(); // in case client is a dialog
- SetBkgndColor(NoErase); // no need to erase client area
- }
- }
-
- TFrameWindow::~TFrameWindow()
- {
- delete MenuDescr;
- }
-
- static uint32
- GetMenuStateBits(HMENU hmenu, int count)
- {
- uint32 bit = 1;
- uint32 result = 0;
-
- for (int i=0; i<count; i++) {
- uint state = GetMenuState(hmenu, i, MF_BYPOSITION);
- if (state != (uint)-1) {
- if (!(state & (MF_DISABLED | MF_GRAYED))) {
- result |= bit;
- }
- }
- bit <<= 1;
- }
-
- return result;
- }
-
- void
- TFrameWindow::EvInitMenuPopup(HMENU hPopupMenu, uint index, bool sysMenu)
- {
- if (!sysMenu && hPopupMenu) {
- const int count = ::GetMenuItemCount(hPopupMenu);
-
- // Save current state of visible top level menus
- //
- uint32 preState = 0;
- if (hPopupMenu == GetMenu())
- preState = GetMenuStateBits(hPopupMenu, count);
-
- TWindow::EvInitMenuPopup(hPopupMenu, index, sysMenu);
-
- // If the top level menu state changes, redraw the menu bar
- //
- if (hPopupMenu == GetMenu())
- if (GetMenuStateBits(hPopupMenu, count) != preState)
- DrawMenuBar();
- }
- }
-
- static void
- DoIdleAction(TWindow* win, void* idleCount)
- {
- win->IdleAction(*(long*)idleCount);
- }
-
- //
- // TFrameWindow processes idle action occurs once per block of messages
- //
- bool
- TFrameWindow::IdleAction(long idleCount)
- {
- if (idleCount == 0) {
- // do command enabling for the menu bar if this is the active task
- //
- #if defined(BI_PLAT_WIN32)
- if (GetFocus()) {
- #else
- HWND focus = GetFocus();
- if (focus && ::GetWindowTask(focus) == GetCurrentTask()) {
- #endif
- long style = ::GetWindowLong(*this, GWL_STYLE);
- if (!(style & WS_CHILD)) {
- HMENU hMenu = ::GetMenu(*this);
- if (IsMenu(hMenu))
- HandleMessage(WM_INITMENUPOPUP, WPARAM(hMenu));
- }
- }
- // give child windows an opportunity to do any idle processing
- //
- ForEach(DoIdleAction, &idleCount);
- }
- return false; // we don't need any more time for now
- }
-
- //
- // Locate and return the child window that is the target of command and command
- // enable messages.
- //
- HWND
- TFrameWindow::GetCommandTarget()
- {
- // Start with the focus window
- //
- HWND hFocus = ::GetFocus();
-
- // If its a child of ours, then return it.
- //
- if (IsChild(hFocus))
- return hFocus;
-
- // The focus is not our descendent, use our most recently active child
- //
- if (HWndRestoreFocus)
- return HWndRestoreFocus;
-
- // If we have a client, fall back on that
- //
- if (GetClientWindow())
- return *GetClientWindow();
-
- // Don't know who else to send it to, return ourselves
- //
- return *this;
- }
-
- //
- // Handle WM_COMMAND to provide extra processing for commands: send the
- // command down the command chain
- //
- LRESULT
- TFrameWindow::EvCommand(uint id, HWND hWndCtl, uint notifyCode)
- {
- // walk the command chain from the focus child back up to us or until
- // we hit a child that is an owl window. Delegate to owl-child or forward to
- // our base if no child is found.
- //
- if (hWndCtl == 0) {
- HWND hCmdTarget = GetCommandTarget();
-
- // Check owl parentage too in case the hWnds were reparented
- //
- while (hCmdTarget && hCmdTarget != HWindow) {
- TWindow* cmdTarget = GetWindowPtr(hCmdTarget);
-
- if (cmdTarget)
- return cmdTarget->EvCommand(id, hWndCtl, notifyCode);
-
- hCmdTarget = ::GetParent(hCmdTarget);
- }
- }
-
- return TWindow::EvCommand(id, hWndCtl, notifyCode);
- }
-
- //
- // Handle WM_COMMAND_ENABLE to provide command enable distribution and default
- // support for windows without command enable handlers.
- //
- void
- TFrameWindow::EvCommandEnable(TCommandEnabler& commandEnabler)
- {
- // Don't process for windows out of our window tree (esp. other apps)
- //
- RouteCommandEnable(GetCommandTarget(), commandEnabler);
- }
-
- //
- // Preprocess queued messages to handle translation of accelerators on a per
- // window basis, and dialog-like keyboard navigation if enabled.
- //
- bool
- TFrameWindow::PreProcessMsg(MSG& msg)
- {
- if (TWindow::PreProcessMsg(msg))
- return true; // process accelerators
-
- if (KeyboardHandling && msg.message >= WM_KEYFIRST &&
- msg.message <= WM_KEYLAST) {
- HWND parent = ::GetParent(msg.hwnd);
-
- //
- // Retrieve the COMBO handle if we're in the EDIT ctl
- // parented to the combobox
- //
- char szClassName[0x10];
- ::GetClassName(parent, szClassName, sizeof(szClassName));
- if (!strcmpi(szClassName, "COMBOBOX"))
- parent = ::GetParent(parent);
-
- if (parent && ::IsDialogMessage(parent, &msg));
- return true;
- }
-
- return false;
- }
-
- //
- // Overrides TWindow's non-virtual SetMenu to make it virtual. This allows
- // derived frame classes to implement this differently
- // It also calls the application's PreProcessMenu() if it is the main window
- // to let it make any changes just before setting.
- //
- bool
- TFrameWindow::SetMenu(HMENU newMenu)
- {
- if (IsFlagSet(wfMainWindow))
- GetApplication()->PreProcessMenu(newMenu);
-
- return TWindow::SetMenu(newMenu);
- }
-
- //
- // Perform a high-level menu assignment either before or after the HWND for the
- // window has been created.
- //
- // returns true if successful; false otherwise
- //
- bool
- TFrameWindow::AssignMenu(TResId menuResId)
- {
- if (menuResId != Attr.Menu) {
- if (Attr.Menu.IsString())
- delete (char far*)Attr.Menu;
-
- Attr.Menu = menuResId.IsString() ? strnewdup(menuResId) : (char far*)menuResId;
- }
-
- // if the window has been created then load and set the new menu and destroy
- // the old menu
- //
- if (!HWindow)
- return true;
-
- HMENU curMenu = GetMenu();
- HMENU newMenu = GetModule()->LoadMenu(Attr.Menu);
-
- if (!SetMenu(newMenu))
- return false;
-
- if (curMenu)
- ::DestroyMenu(curMenu);
-
- return true;
- }
-
- //
- // Set the Icon for use when this frame is minimized
- //
- bool
- TFrameWindow::SetIcon(TModule* module, TResId resId)
- {
- IconModule = module;
- IconResId = resId;
- return true;
- }
-
- //
- // Return the current client window as a TWindow*
- //
- TWindow*
- TFrameWindow::GetClientWindow()
- {
- return ClientWnd;
- }
-
- //
- // Remove the current client (if any) and set a new one.
- // Assume clientWnd was parented to us.
- //
- TWindow*
- TFrameWindow::SetClientWindow(TWindow* clientWnd)
- {
- TWindow* oldClientWnd = ClientWnd;
- HWND oldHWnd = oldClientWnd ? oldClientWnd->HWindow : (HWND)0;
- RemoveChild(ClientWnd);
-
- if (HWndRestoreFocus == oldHWnd)
- HWndRestoreFocus = 0;
-
- ClientWnd = clientWnd;
-
- if (ClientWnd) {
- ClientWnd->SetParent(this);
- if (!ClientWnd->HWindow)
- ClientWnd->Create();
- ClientWnd->Show(SW_NORMAL);
- SetBkgndColor(NoErase); // no need to erase client area
- ResizeClientWindow();
- }
- else
- SetBkgndColor(NoColor); // will need to erase client area
-
- if (ClientWnd && ClientWnd->HWindow)
- ClientWnd->SetFocus();
- else
- SetFocus();
-
- return oldClientWnd;
- }
-
- //
- // If someone removes our client with a RemoveChild() call, update our client
- // and restore focus ptrs.
- //
- void
- TFrameWindow::RemoveChild(TWindow* child)
- {
- TWindow::RemoveChild(child);
- if (child) {
- if (child == ClientWnd)
- ClientWnd = 0;
- if (child->HWindow == HWndRestoreFocus)
- HWndRestoreFocus = 0;
- }
- }
-
- //
- // Set the document style title for this frame window. Uses SetWindowText to
- // modify the caption directly without modifying the Title data member.
- // Generates a composite title based on Title if it exists, docname, and index
- // if it is > 0.
- // [<Title> - ]<docname>[:<index>]
- //
- bool
- TFrameWindow::SetDocTitle(const char far* docname, int index)
- {
- if (index >= 0) {
- string title;
-
- if (Title && *Title) {
- title = Title;
- title += " - ";
- }
- title += docname;
- if (index > 0) {
- title += ':';
- char num[10];
- itoa(index, num, 10);
- title += num;
- }
-
- SetWindowText(title.c_str());
-
- } // else if index negative, simply acknowledge that title will display
-
- return true;
- }
-
- //
- // Obtain the real windows application icon. The IDI_APPLICATION icon is an
- // ugly black & white box, but when a class is registered with this icon it
- // gets substituted with a better windows icon. Worse case we end up with the
- // ugly box icon.
- //
- static HICON
- getAppIcon()
- {
- static HICON hRealAppIcon = 0;
- if (!hRealAppIcon) {
- WNDCLASS wndClass;
- static char className[] = "IconSnarfer";
- memset(&wndClass, 0, sizeof wndClass);
- wndClass.hInstance = *::Module;
- wndClass.hIcon = ::LoadIcon(0, IDI_APPLICATION);
- wndClass.lpszClassName = className;
- wndClass.lpfnWndProc = ::DefWindowProc;
- ::RegisterClass(&wndClass);
- ::GetClassInfo(*::Module, className, &wndClass);
- hRealAppIcon = wndClass.hIcon;
- ::UnregisterClass(className, *::Module);
- }
- return hRealAppIcon ? hRealAppIcon : ::LoadIcon(0, IDI_APPLICATION);
- }
-
- //
- // Response method for an incoming WM_PAINT message
- //
- // If iconic, and an icon has been defined then draw that.
- // Or, if iconic & there is a client window, then call its paint function.
- //
- // If not iconic, forwards to TWindow for normal paint processing
- //
- void
- TFrameWindow::EvPaint()
- {
- if (IsIconic() && (IconResId || ClientWnd)) {
- TPaintDC dc(HWindow);
-
- if (IconResId) {
- HINSTANCE hInstance = IconModule ? HINSTANCE(*IconModule) : HINSTANCE(0);
- HICON hIcon = ::LoadIcon(hInstance, IconResId);
- ::DrawIcon(dc, 0, 0, hIcon ? hIcon : getAppIcon());
- }
- else
- ClientWnd->Paint(dc, dc.Ps.fErase, *(TRect*)&dc.Ps.rcPaint);
- }
- else
- TWindow::EvPaint();
- }
-
- //
- // Response method for an incoming WM_ERASEBKGND message
- //
- // If this frame window is iconic, and there is a client window, then give it
- // a chance to erase the background since it may want to take over painting.
- //
- // If not iconic, forward to TWindow for normal erase background processing
- //
- bool
- TFrameWindow::EvEraseBkgnd(HDC hDC)
- {
- if (IsIconic()) {
- if (!IconResId && ClientWnd)
- return (bool)ClientWnd->HandleMessage(WM_ERASEBKGND, WPARAM(hDC));
-
- HandleMessage(WM_ICONERASEBKGND, WPARAM(hDC));
- return true;
- }
- else
- return TWindow::EvEraseBkgnd(hDC);
- }
-
- //
- // Response method for an incoming WM_QUERYDRAGICON message
- //
- // If there is an icon set for this frame, then return it so that windows
- // can make a nice cursor out of it when the user drags the icon
- //
- HANDLE
- TFrameWindow::EvQueryDragIcon()
- {
- if (IconResId) {
- HINSTANCE hInstance = IconModule ? HINSTANCE(*IconModule) : HINSTANCE(0);
- HICON hIcon = ::LoadIcon(hInstance, IconResId);
- return hIcon ? hIcon : getAppIcon();
- }
- else
- return TWindow::EvQueryDragIcon();
- }
-
- static inline bool
- IsEnabledVisibleChild(long style)
- {
- return (style & (WS_CHILD | WS_VISIBLE | WS_DISABLED)) == (WS_CHILD | WS_VISIBLE);
- }
-
- static TWindow*
- SearchForChildWithTab(TWindow* win)
- {
- TWindow* firstChild = win->GetFirstChild();
-
- if (firstChild) {
- TWindow* child = firstChild;
-
- do {
- if (child->HWindow) {
- long style = child->GetWindowLong(GWL_STYLE);
-
- if (IsEnabledVisibleChild(style)) {
- if (style & WS_TABSTOP)
- return child;
-
- else {
- TWindow* result = SearchForChildWithTab(child);
- if (result)
- return result;
- }
- }
- }
- child = child->Next();
- } while (child != firstChild);
- }
-
- return 0;
- }
-
- static bool
- EnabledVisibleChild(TWindow* win, void*)
- {
- return win->HWindow ? IsEnabledVisibleChild(win->GetWindowLong(GWL_STYLE)) :
- false;
- }
-
- //
- // if the receiver doesn't have any children then returns 0. otherwise
- // we search for the first child with WS_TABSTOP; if no child has WS_TABSTOP
- // then we return the first enabled visible child
- //
- // does a depth-first search of nested child windows
- //
- // NOTE: we stop at the first child with WS_TABSTOP and do not search its
- // children...
- //
- TWindow*
- TFrameWindow::FirstChildWithTab()
- {
- TWindow* win = SearchForChildWithTab(this);
-
- return win ? win : FirstThat(EnabledVisibleChild);
- }
-
- //
- // Respond to a request to hold on to the handle of a child window that is
- // losing focus, so that we can restore it again later (below).
- //
- // return true if caller can stop searching for a window to hold its handle.
- //
- bool
- TFrameWindow::HoldFocusHWnd(HWND hWndLose, HWND hWndGain)
- {
- if (IsChild(hWndLose)) {
- if (!hWndGain || !IsChild(hWndGain))
- HWndRestoreFocus = hWndLose;
- return true;
- }
- return hWndLose == HWindow;
- }
-
- //
- // Handle WM_SETFOCUS to return focus back to the child that had it most
- // recently, or find the best one to give it to otherwise.
- //
- void
- TFrameWindow::EvSetFocus(HWND hWndLostFocus)
- {
- TWindow::EvSetFocus(hWndLostFocus);
-
- if (HWndRestoreFocus) {
- //
- // Set focus to the saved HWND as long as it is still a valid window handle
- //
- if (::IsWindow(HWndRestoreFocus))
- ::SetFocus(HWndRestoreFocus);
-
- HWndRestoreFocus = 0;
- }
- else {
- TWindow* win = FirstChildWithTab();
-
- if (win && win->HWindow != hWndLostFocus)
- win->SetFocus();
- }
- }
-
- //
- // Close this window if the client is destroyed
- //
- // Clear the wfFullyCreated flag on any child that is destroyed
- // Resize this frame if the client changes size & wfShrinkToClient is set
- //
- void
- TFrameWindow::EvParentNotify(uint event,
- uint childHandleOrX, uint /*childIDOrY*/)
- {
- if (event == WM_DESTROY) {
- if (ClientWnd && ClientWnd->HWindow == HWND(childHandleOrX))
- PostMessage(WM_CLOSE); // using ShutDownWindow() has side effects
-
- TWindow* c = GetWindowPtr(HWND(childHandleOrX));
- if (c)
- c->ClearFlag(wfFullyCreated);
- }
- else if (event == WM_SIZE) {
- if (IsFlagSet(wfShrinkToClient)
- && ClientWnd
- && ClientWnd->HWindow == HWND(childHandleOrX)
- && !IsIconic())
- ResizeClientWindow();
- }
- }
-
- //
- // Watch for WM_ENTERIDLE messages from idling modal dialog boxes so that
- // background processing can continue when they are up.
- //
- void
- TFrameWindow::EvEnterIdle(uint source, HWND hWndDlg)
- {
- if (source == MSGF_DIALOGBOX && IsFlagSet(wfMainWindow))
- IdleAction(0); // could call GetApplication()->IdleAction(0)...
- TWindow::EvEnterIdle(source, hWndDlg);
- }
-
- //
- // Resize & reposition the client window to fit in this frames client area
- // or resize the frame to fit around the client's client area if
- // wfShrinkToClient
- // Return true if a client was actualy resized.
- // Adjust clients styles & make sure they get set.
- //
- bool
- TFrameWindow::ResizeClientWindow(bool redraw)
- {
- if (!ClientWnd)
- return false;
-
- // prevent recursion during resize by ignore calls from EvParentNotify and
- // EvSize when we have already been called
- // do this by disabling notifications while resizing using the
- // wfShrinkToClient flag as a semaphore on the client
- //
- if (ClientWnd->IsFlagSet(wfShrinkToClient))
- return true;
- ClientWnd->SetFlag(wfShrinkToClient);
-
- bool clientResized = false;
- TSize frameSize = GetClientRect().Size();
- TSize childSize = ClientWnd->GetWindowRect().Size();
-
- // first time through, strip client window of thick borders
- // if shrink-to-client, then must measure the client size first
- // if the client has scrolls bars, we must hide them to obtain the correct
- // size
- // Border style is left on & dealt with by hand below
- //
- const uint32 badClientStyles = WS_DLGFRAME | WS_THICKFRAME | // bad borders
- WS_POPUP | WS_OVERLAPPED; // bad parenting
- const uint32 badClientExStyles = WS_EX_DLGMODALFRAME;
- if ((ClientWnd->Attr.Style & badClientStyles) ||
- (ClientWnd->Attr.ExStyle & badClientExStyles)) {
- if (IsFlagSet(wfShrinkToClient)) {
- TSize tstSize = ClientWnd->GetClientRect().Size();
- ClientWnd->ShowScrollBar(SB_BOTH, false);
- childSize = ClientWnd->GetClientRect().Size();
- if (childSize != tstSize) {
- int restore = SB_BOTH;
- if (childSize.cx == tstSize.cx)
- restore = SB_HORZ;
- if (childSize.cy == tstSize.cy)
- restore = SB_VERT;
- ClientWnd->ShowScrollBar(restore, true);
- }
- }
- if (ClientWnd->Attr.Style & badClientStyles) {
- bool reparent = (ClientWnd->Attr.Style & (WS_POPUP|WS_OVERLAPPED)) != 0;
- ClientWnd->Attr.Style &= ~badClientStyles;
- ClientWnd->Attr.Style |= WS_CHILD | WS_BORDER | WS_VISIBLE;
- ClientWnd->SetWindowLong(GWL_STYLE, ClientWnd->Attr.Style);
- if (reparent)
- ::SetParent(*ClientWnd, *this);
- }
- if (ClientWnd->Attr.ExStyle & badClientExStyles) {
- ClientWnd->Attr.ExStyle &= ~badClientExStyles;
- ClientWnd->SetWindowLong(GWL_EXSTYLE, ClientWnd->Attr.ExStyle);
- }
- }
- if (ClientWnd->Attr.Style & WS_BORDER) {
- childSize = ClientWnd->GetClientRect().Size();
- }
- if (childSize != frameSize) {
- if (IsFlagSet(wfShrinkToClient)) {
- TRect outside = GetWindowRect();
- TPoint outsideOrg(0, 0);
- if (Parent)
- Parent->ClientToScreen(outsideOrg); // adjust our rect by our parent's
-
- TSize border = outside.Size() - frameSize;
- MoveWindow(outside.left - outsideOrg.x, outside.top - outsideOrg.y,
- childSize.cx + border.cx, childSize.cy + border.cy, redraw);
- frameSize = childSize; // must move client, will not cause an EvSize
- }
- else {
- clientResized = true; // client will get resized
- }
- }
- // If frame is sizeable, turn off flag so that user can then resize
- // after initial setup
- //
- if (Attr.Style & WS_THICKFRAME)
- ClearFlag(wfShrinkToClient);
-
- // Handle border style by shoving the client's borders under the frame
- //
- if (ClientWnd->Attr.Style & WS_BORDER) {
- int bx = ::GetSystemMetrics(SM_CXBORDER);
- int by = ::GetSystemMetrics(SM_CYBORDER);
- ClientWnd->MoveWindow(-bx, -by, frameSize.cx+bx+bx, frameSize.cy+by+by, redraw);
- }
- else
- ClientWnd->MoveWindow(0, 0, frameSize.cx, frameSize.cy, redraw);
-
- ClientWnd->ClearFlag(wfShrinkToClient);
- return clientResized;
- }
-
- //
- // called following a successful association between an MS-Windows interface
- // element and a TFrameWindow
- //
- void
- TFrameWindow::SetupWindow()
- {
- // create windows in child list (this includes the client window)
- //
- TWindow::SetupWindow();
-
- ResizeClientWindow();
-
- if (MinimizedPos != TPoint(-1,-1)) {
- WINDOWPLACEMENT windata;
- windata.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement(&windata);
- windata.flags = WPF_SETMINPOSITION;
- windata.showCmd = SW_SHOWNA;
- windata.ptMinPosition = MinimizedPos;
- SetWindowPlacement(&windata);
- }
-
- // if SetMenuDescr() was called before window created, update the menu now
- //
- if (IsFlagSet(wfMainWindow) && MenuDescr) {
- HMENU curMenu = GetMenu();
- TMenu newMenu(*MenuDescr, NoAutoDelete);
- if (SetMenu(newMenu)) {
- if (curMenu)
- ::DestroyMenu(curMenu);
- }
- else
- ::DestroyMenu(newMenu);
- }
-
- // if we haven't set HWndRestoreFocus then pick the first child with tabstop
- //
- if (!HWndRestoreFocus) {
- TWindow* win = FirstChildWithTab();
-
- HWndRestoreFocus = win ? win->HWindow : HWindow;
- }
- }
-
- //
- // response method for an incoming WM_SIZE message
- //
- // if not minimizing resizes the client window to be the same size as the
- // client rectangle,
- // if no WM_SIZE sent, forwards WM_SIZE message to client so it can recalc.
- //
- void
- TFrameWindow::EvSize(uint sizeType, TSize& size)
- {
- TWindow::EvSize(sizeType, size);
-
- if (ClientWnd) {
- bool sizeSent = false;
- if (sizeType != SIZE_MINIMIZED) {
- sizeSent = ResizeClientWindow();
- size = ClientWnd->GetClientRect().Size();
- }
- if (!sizeSent)
- ClientWnd->ForwardMessage();
- }
- }
-
- #endif
- #if !defined(SECTION) || SECTION == 2
-
- //
- // Set the menu descriptor for this frame window
- //
- void
- TFrameWindow::SetMenuDescr(const TMenuDescr& menuDescr)
- {
- delete MenuDescr;
- MenuDescr = new TMenuDescr(menuDescr);
-
- if (IsFlagSet(wfMainWindow) && HWindow) {
- HMENU curMenu = GetMenu();
- TMenu newMenu(*MenuDescr, NoAutoDelete);
- if (SetMenu(newMenu))
- ::DestroyMenu(curMenu);
- else
- ::DestroyMenu(newMenu);
- }
- }
-
- //
- // Merge another menu, given its menu descriptor, into our own using our menu
- // descriptor.
- // optionally use an existing HMENU to merge into & set
- //
- bool
- TFrameWindow::MergeMenu(const TMenuDescr& childMenuDescr)
- {
- if (!MenuDescr || !HWindow)
- return false;
-
- MergeModule = childMenuDescr.GetModule();
- TMenu curMenu(*this, NoAutoDelete);
- TMenu newMenu(NoAutoDelete);
-
- MenuDescr->Merge(childMenuDescr, newMenu);
-
- if (IsFlagSet(wfMainWindow))
- GetApplication()->PreProcessMenu(newMenu);
-
- if (SetMenu(newMenu)) {
- ::DestroyMenu(curMenu);
- return true;
-
- }
- else {
- ::DestroyMenu(newMenu);
- return false;
- }
-
- }
-
- //
- // Restore our menu to the one described by our menu descriptor
- //
- bool
- TFrameWindow::RestoreMenu()
- {
- if (!MenuDescr)
- return false;
-
- HMENU curMenu = GetMenu();
- TMenu newMenu(*MenuDescr, NoAutoDelete);
- if (SetMenu(newMenu)) {
- MergeModule = 0;
- ::DestroyMenu(curMenu);
- }
- else
- ::DestroyMenu(newMenu);
- return true;
- }
-
- #endif
- #if !defined(SECTION) || SECTION == 3
-
- IMPLEMENT_STREAMABLE1(TFrameWindow, TWindow);
-
- //
- // reads data of the uninitialized TFrameWindow from the passed ipstream
- //
- void*
- TFrameWindow::Streamer::Read(ipstream& is, uint32 /*version*/) const
- {
- TFrameWindow* o = GetObject();
- ReadVirtualBase((TWindow*)o, is);
- if (o->IsFlagSet(wfMainWindow))
- return o;
-
- is >> o->ClientWnd;
- is >> o->KeyboardHandling;
- o->HWndRestoreFocus = 0;
-
- bool hasMenuDescr = is.readByte();
- if (hasMenuDescr) {
- o->MenuDescr = new TMenuDescr;
- is >> *o->MenuDescr;
- }
- else
- o->MenuDescr = 0;
-
- is >> o->IconModule;
- is >> o->IconResId;
- is >> o->MergeModule;
- is >> o->MinimizedPos;
-
- return o;
- }
-
- //
- // writes data of the TFrameWindow to the passed opstream
- //
- void
- TFrameWindow::Streamer::Write(opstream& os) const
- {
- TFrameWindow* o = GetObject();
- WriteVirtualBase((TWindow*)o, os);
- if (o->IsFlagSet(wfMainWindow))
- return;
-
- os << o->ClientWnd;
- os << o->KeyboardHandling;
-
- os.writeByte(uint8(o->MenuDescr ? 1 : 0));
- if (o->MenuDescr)
- os << *o->MenuDescr;
-
- os << o->IconModule;
- os << o->IconResId;
- os << o->MergeModule;
- WINDOWPLACEMENT windata;
- windata.length = sizeof(WINDOWPLACEMENT);
- o->GetWindowPlacement(&windata);
- os << TPoint(windata.ptMinPosition);
- }
-
- #endif // SECTION
-