The floating toolbox is a variation on the toolbar and toolbox covered in week 10 of cs372. The main difference is that this toolbox must have its own frame so it can be moved around the screen. This frame will contain the toolbox and in turn be contained in the SDIDecFrame of the main window. This means that commands placed in the toolbox must be relayed to the SDIDecFrame through the toolbox's frame. The toolbox frame, TFFrame, is a descendent of TFloatingFrame, must also have its own close event handler to make sure it is closed properly. When it is closed the SDIDecFrame must know that it is closed, so it can create a new toolbox on demand.
This toolbox will be created by a member function of the SDIDecFrame. The code for this function is much the same as that seen in week 10, but in addition to creating the toolbox, we have to create the frame and modify items in the SDIDecFrame menu. We will also add a boolean data member, toolBoxUp, to SDIDecFrame. This variable will indicate whether the toolbox is visible. If it is then the user will not be able to create a new toolbox. The code creating the toolbox is not called from the SDIDecFrame constructor, so the frame containing the window must call Create to show itself. |
The code that initializes the box is:
void SDIDecFrame::showToolBox()
{
TToolBox* cb = new TToolBox(0,4,4);
cb->Insert(*new TButtonGadget(CM_FILENEW, CM_FILENEW));
cb->Insert(*new TButtonGadget(CM_FILEOPEN, CM_FILEOPEN));
cb->Insert(*new TButtonGadget(CM_FILESAVE, CM_FILESAVE));
cb->Insert(*new TSeparatorGadget(6));
cb->Insert(*new TButtonGadget(CM_EDITCUT, CM_EDITCUT));
cb->Insert(*new TButtonGadget(CM_EDITCOPY, CM_EDITCOPY));
cb->Insert(*new TButtonGadget(CM_EDITPASTE, CM_EDITPASTE));
cb->Insert(*new TSeparatorGadget(6));
cb->Insert(*new TButtonGadget(CM_EDITUNDO, CM_EDITUNDO));
cb->Insert(*new TSeparatorGadget(6));
cb->Insert(*new TButtonGadget(CM_EDITFIND, CM_EDITFIND));
cb->Insert(*new TButtonGadget(CM_EDITFINDNEXT, CM_EDITFINDNEXT));
cb->Insert(*new TSeparatorGadget(6));
cb->Insert(*new TButtonGadget(CM_AN_ITEM, CM_AN_ITEM));
cb->Insert(*new TButtonGadget(CM_EXIT, CM_EXIT));
// Add fly-over help hints.
cb->SetHintMode(TGadgetWindow::EnterHints);
TFFrame *toolFrame = new TFFrame(this,"Toolbox",cb,
TRUE,TFloatingFrame::DefaultCaptionHeight,TRUE);
toolFrame->Create(); // must create since this will not be called from a constructor
toolBoxUp = true;
TMenu menu(HWindow);
HMENU hMenu = menu.GetSubMenu(4);
TMenuItemEnabler(hMenu,CM_TOOL_BAR_ON,HWindow,0).SetCheck(1);
}
The floating frame must have some messages implemented. First, any of the command notifications that are not standard windows command notifications, must be implemented in the usual way. These event handlers will simply pass the command on to the SDIDecFrame, or leave the handler as generated by the ClassExpert. Here is an example of such a handler.
void TFFrame::cmAnItem ()
{
// INSERT>> Your code here.
Parent->PostMessage(CM_AN_ITEM);
}
If you do not create handlers for user defined command notifications, the corresponding buttons will not appear in the toolbox.
In addition to the commands, I want this window to handle the WM_CLOSE command in a special way. Its parent, the SDIDecFrame, must know when this window is visible and when it is not. The WM_CLOSE handler sends the message WM_TOOLS_GONE back to the SDIDecFrame. This has to be done before the call to the TFloatingFrame::EvClose function is called or the parent will no longer be available which leads to runtime errors. Here is the code for EvClose.
void TFFrame::EvClose ()
{
Parent->SendMessage(WM_TOOLS_GONE);
TFloatingFrame::EvClose();
// INSERT>> Your code here.
}
In addition to creating the toolbox in the SDIDecFrame, you must create functions that will create the toolbox in response to the menu command, a disabler for the command when the toolbox is visible and the message handler for WM_TOOLS_GONE, EvTools . These are all fairly standard functions and are given below without comment. Notice the toolbar is initialized in SetupWindow because it accesses the menu for the window which is not constructed until after the constructor is called.
LRESULT SDIDecFrame::EvTools (WPARAM,LPARAM)
{
toolBoxUp = false;
TMenu menu(HWindow);
HMENU hMenu = menu.GetSubMenu(4);
TMenuItemEnabler(hMenu,CM_TOOL_BAR_ON,HWindow,0).SetCheck(0);
return 1;
}
void SDIDecFrame::cmToolBoxOn ()
{
// INSERT>> Your code here.
if (toolBoxUp)
toolFrame->SendMessage(WM_CLOSE);
else
showToolBox();
}
void SDIDecFrame::SetupWindow ()
{
TDecoratedFrame::SetupWindow();
// INSERT>> Your code here.
showToolBox();
}
To get the complete code for this program click here.