📄 figure.cpp
字号:
m_pHW->ChildSet(NULL);
//Make sure the hatch window is invisible and owned by Cosmo
ShowWindow(m_pHW->Window(), SW_HIDE);
SetParent(m_pHW->Window(), m_pDoc->m_hWnd);
GetClientRect(m_pDoc->m_hWnd, &rc);
InflateRect(&rc, -8, -8);
SetWindowPos(m_pPL->Window(), NULL, rc.left, rc.top
, rc.right-rc.left, rc.bottom-rc.top
, SWP_NOZORDER | SWP_NOACTIVATE);
if (NULL!=m_pIOleIPSite)
m_pIOleIPSite->OnInPlaceDeactivate();
m_pFR->m_pIOleIPFrame=NULL;
ReleaseInterface(m_pIOleIPFrame);
ReleaseInterface(m_pIOleIPUIWindow);
ReleaseInterface(m_pIOleIPSite);
return;
}
/*
* CFigure::UIActivate
*
* Purpose:
* Goes through all the steps of activating the user interface of
* the Figure as an in-place object.
*
* Parameters:
* None
*
* Return Value:
* HRESULT NOERROR or error code.
*/
HRESULT CFigure::UIActivate(void)
{
//1. Call IOleInPlaceSite::UIActivate
if (NULL!=m_pIOleIPSite)
m_pIOleIPSite->OnUIActivate();
//2. Critical for accelerators to work initially.
SetFocus(m_pHW->Window());
//3. Set the active object
#ifdef WIN32ANSI
OLECHAR szTemp[40];
MultiByteToWideChar(CP_ACP, 0, PSZ(IDS_INPLACETITLE)
, -1, szTemp, 40);
#endif
if (NULL!=m_pIOleIPFrame)
{
m_pIOleIPFrame->SetActiveObject(m_pImpIOleIPActiveObject
#ifdef WIN32ANSI
, szTemp);
#else
, PSZ(IDS_INPLACETITLE));
#endif
}
if (NULL!=m_pIOleIPUIWindow)
{
m_pIOleIPUIWindow->SetActiveObject(m_pImpIOleIPActiveObject
#ifdef WIN32ANSI
, szTemp);
#else
, PSZ(IDS_INPLACETITLE));
#endif
}
//4. Create frame tools
InPlaceToolsCreate();
//5. Create the shared menu.
InPlaceMenuCreate();
return NOERROR;
}
/*
* CFigure::UIDeactivate
*
* Purpose:
* Reverses all the user interface activation steps from
* UIActivate.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CFigure::UIDeactivate(void)
{
//1. Remove the in-place tools
InPlaceToolsDestroy();
//2. Remove the shared menu.
InPlaceMenuDestroy();
//3. Set active obejcts to NULL
if (NULL!=m_pIOleIPFrame)
m_pIOleIPFrame->SetActiveObject(NULL, NULL);
if (NULL!=m_pIOleIPUIWindow)
m_pIOleIPUIWindow->SetActiveObject(NULL, NULL);
//3. Call IOleInPlaceSite::OnUIDeactivate
if (NULL!=m_pIOleIPSite)
m_pIOleIPSite->OnUIDeactivate(FALSE);
return;
}
/*
* CFigure::InPlaceMenuCreate
*
* Purpose:
* Creates and sets a menu for an in-place embedded object.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if everything is well, FALSE on error.
*/
BOOL CFigure::InPlaceMenuCreate(void)
{
HMENU hMenu, hMenuT;
UINT uTemp=MF_BYPOSITION | MF_POPUP;
UINT i;
OLEMENUGROUPWIDTHS mgw;
for (i=0; i<6; i++)
mgw.width[i]=0;
//We already have popup menu handles in m_pFR->m_phMenu[]
//Create the new shared menu and let container do its thing
hMenu=CreateMenu();
m_pIOleIPFrame->InsertMenus(hMenu, &mgw);
/*
* Add our menus remembering that the container has added its
* already.
*/
InsertMenu(hMenu, (UINT)mgw.width[0]
, uTemp, (UINT)m_pFR->m_phMenu[1], PSZ(IDS_MENUEDIT));
/*
* Add the Open item to the edit menu.
* NOTE: If you are a multiple-use server, this sort of code
* will also modify the menu on the server window as well as
* this shared menu in which case you need a separate popup menu
* altogether.
*/
AppendMenu(m_pFR->m_phMenu[1], MF_SEPARATOR, 0, NULL);
AppendMenu(m_pFR->m_phMenu[1], MF_STRING, IDM_EDITOPEN
, PSZ(IDS_MENUOPEN));
InsertMenu(hMenu, (UINT)mgw.width[0]+1+(UINT)mgw.width[2]
, uTemp, (UINT)m_pFR->m_phMenu[2], PSZ(IDS_MENUCOLOR));
InsertMenu(hMenu, (UINT)mgw.width[0]+1+(UINT)mgw.width[2]+1
, uTemp, (UINT)m_pFR->m_phMenu[3], PSZ(IDS_MENULINE));
//Window menu position changes between MDI and SDI
#ifdef MDI
hMenuT=m_pFR->m_phMenu[5];
#else
hMenuT=m_pFR->m_phMenu[4];
#endif
InsertMenu(hMenu, (UINT)mgw.width[0]+1+(UINT)mgw.width[2]+2
+ (UINT)mgw.width[4], uTemp, (UINT)hMenuT
, PSZ(IDS_MENUHELP));
//Tell OLE how many items in each group are ours.
mgw.width[1]=1;
mgw.width[3]=2;
mgw.width[5]=1;
m_hMenuShared=hMenu;
m_hOLEMenu=OleCreateMenuDescriptor(m_hMenuShared, &mgw);
m_pIOleIPFrame->SetMenu(m_hMenuShared, m_hOLEMenu
, m_pFR->Window());
return TRUE;
}
/*
* CFigure::InPlaceMenuDestroy
*
* Purpose:
* Performs opposite actions from InPlaceMenuCreate
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if all is well, FALSE otherwise.
*/
BOOL CFigure::InPlaceMenuDestroy(void)
{
int cItems, i, j;
HMENU hMenuT;
//If we don't have a shared menu, nothing to do.
if (NULL==m_hMenuShared)
return TRUE;
//Stop the container frame from using this menu.
m_pIOleIPFrame->SetMenu(NULL, NULL, NULL);
//Clean up what we got from OleCreateMenuDescriptor.
OleDestroyMenuDescriptor(m_hOLEMenu);
m_hOLEMenu=NULL;
cItems=GetMenuItemCount(m_hMenuShared);
/*
* Walk backwards down the menu. For each popup, see if it
* matches any other popup we know about, and if so, remove
* it from the shared menu.
*/
for (i=cItems; i >=0; i--)
{
hMenuT=GetSubMenu(m_hMenuShared, i);
for (j=0; j <= CMENUS; j++)
{
/*
* If the submenu matches any we have, remove, don't
* delete. Since we're walking backwards this only
* affects the positions of those menus after us so the
* GetSubMenu call above is not affected.
*/
if (hMenuT==m_pFR->m_phMenu[j])
RemoveMenu(m_hMenuShared, i, MF_BYPOSITION);
}
}
/*
* Remove the Open item and separator from the Edit menu.
* NOTE: If you are a multiple-user server, this affects the
* menu on the server window as well as the shared menu in which
* case you need to use a separate popup menu altogether.
*/
RemoveMenu(m_pFR->m_phMenu[1], MPOS_OPEN, MF_BYPOSITION);
RemoveMenu(m_pFR->m_phMenu[1], MPOS_SEP, MF_BYPOSITION);
if (NULL!=m_pIOleIPFrame)
m_pIOleIPFrame->RemoveMenus(m_hMenuShared);
DestroyMenu(m_hMenuShared);
m_hMenuShared=NULL;
return TRUE;
}
/*
* CFigure::InPlaceToolsCreate
*
* Purpose:
* Creates a toolbar for in-place activation and negotiates the
* border space for the toolbar.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if we could allocate the space and create
* the tools. FALSE if we fail, meaning that we
* just do in-place with menus only, since we can
* do without the tools. We could fail and attempt
* to reverse what we might have done already, but
* since we don't really *need* the toolbar, we
* keep going.
*/
BOOL CFigure::InPlaceToolsCreate(void)
{
BORDERWIDTHS bw;
HWND hWnd;
UINT uState=GIZMO_NORMAL;
UINT utCmd =GIZMOTYPE_BUTTONCOMMAND;
UINT utEx =GIZMOTYPE_BUTTONATTRIBUTEEX;
UINT i;
HBITMAP hBmp;
RECT rc;
UINT dxB, dyB;
//We don't need anything on the document, so send zeros.
SetRectEmpty((LPRECT)&bw);
if (NULL!=m_pIOleIPUIWindow)
m_pIOleIPUIWindow->SetBorderSpace(&bw);
if (NULL==m_pIOleIPFrame)
return FALSE;
/*
* 1. Make sure we can reserve space for what we need. If this
* fails then we just do without because the menu has
* everything we really need. A more willing server could
* put tools in popup windows as well.
*/
if (!InPlaceToolsRenegotiate())
{
//If the container doesn't allow us any, don't ask for any.
m_pIOleIPFrame->SetBorderSpace(&bw);
return FALSE;
}
/*
* 2. Create the toolbar window using the container window as
* the parent. In order to get messages from it, we use
* it's AssociateSet ability directly after creation and
* before we add any tools to the bar.
*/
m_pIOleIPFrame->GetWindow(&hWnd);
//If we already have a toolbar, just show it again.
if (NULL!=m_pTB)
{
ShowWindow(m_pTB->Window(), SW_SHOW);
return TRUE;
}
m_pTB=new CToolBar(m_pFR->m_hInst);
if (NULL==m_pTB)
{
SetRectEmpty((LPRECT)&bw);
m_pIOleIPFrame->SetBorderSpace(&bw);
return FALSE;
}
m_pTB->Init(hWnd, ID_GIZMOBAR, m_cyBar);
g_pInPlaceTB=m_pTB;
//Insure the tools are initially invisible
ShowWindow(m_pTB->Window(), SW_HIDE);
//Tell the toolbar who to send messages to.
m_pTB->HwndAssociateSet(m_pFR->m_hWnd);
/*
* Add tools to the bar, setting CFrame::fInit to avoid
* command processing
*/
m_pFR->m_fInit=TRUE;
hBmp=m_pFR->m_hBmp;
dxB=m_pFR->m_dxB;
dyB=m_pFR->m_dyB;
//Edit Undo, Cut, Copy, Paste
m_pTB->Add(utCmd, 1, IDM_EDITUNDO, dxB, dyB, NULL, hBmp, 1, uState);
m_pTB->Add(utCmd, 2, IDM_EDITCUT, dxB, dyB, NULL, NULL, 0, uState);
m_pTB->Add(utCmd, 3, IDM_EDITCOPY, dxB, dyB, NULL, NULL, 1, uState);
m_pTB->Add(utCmd, 4, IDM_EDITPASTE, dxB, dyB, NULL, NULL, 2, uState);
//Separator
m_pTB->Add(GIZMOTYPE_SEPARATOR, 5, 0, 6, dyB, NULL, NULL, 0, uState);
//Color Background and Color Line
m_pTB->Add(utCmd, 6, IDM_COLORBACKGROUND, dxB, dyB, NULL, hBmp, 3
, GIZMO_NORMAL | PRESERVE_BLACK);
m_pTB->Add(utCmd, 7, IDM_COLORLINE, dxB, dyB, NULL, hBmp, 4, uState);
//Separator
m_pTB->Add(GIZMOTYPE_SEPARATOR, 8, 0, 6, dyB, NULL, NULL, 0, uState);
//Line styles.
m_pTB->Add(utEx, 19, IDM_LINESOLID, dxB, dyB, NULL, hBmp, 5, uState);
m_pTB->Add(utEx, 10, IDM_LINEDASH, dxB, dyB, NULL, hBmp, 6, uState);
m_pTB->Add(utEx, 11, IDM_LINEDOT, dxB, dyB, NULL, hBmp, 7, uState);
m_pTB->Add(utEx, 12, IDM_LINEDASHDOT, dxB, dyB, NULL, hBmp, 8
, uState);
m_pTB->Add(utEx, 13, IDM_LINEDASHDOTDOT, dxB, dyB, NULL, hBmp, 9
, uState);
//Check the current line style.
i=m_pPL->LineStyleGet()+IDM_LINEMIN;
m_pTB->Check(i, TRUE);
m_pFR->m_fInit=FALSE;
/*
* Before making the toolbar visible, resize it to the
* container's GetBorder rectangle. By default the toolbar
* sizes itself to the client area of the parent, but we can't
* assume that's the same as GetBorder returns, so we do the
* extra work here.
*/
m_pIOleIPFrame->GetBorder(&rc);
SetWindowPos(m_pTB->Window(), NULL, rc.left, rc.top
, rc.right-rc.left, rc.top+m_cyBar, SWP_NOZORDER);
//3. Make the tools visible.
ShowWindow(m_pTB->Window(), SW_SHOW);
return TRUE;
}
/*
* CFigure::InPlaceToolsDestroy
*
* Purpose:
* Reverses the process of InPlaceToolsCreate
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CFigure::InPlaceToolsDestroy(void)
{
//Nothing to do if we never created anything.
if (NULL==m_pTB)
return TRUE;
/*
* No reason to call SetBorderSpace with an empty rectangle
* since you call IOleInPlaceSite::OnUIDeactivate. The
* container will restore its own tools appropriately.
*/
//Destroy the toolbar.
if (NULL!=m_pTB)
{
delete m_pTB;
m_pTB=NULL;
g_pInPlaceTB=NULL;
}
return TRUE;
}
/*
* CFigure::InPlaceToolsRenegotiate
*
* Purpose:
* Calls IOleInPlaceFrame::RequestBorderSpace and SetBorderSpace
* to reserve space for our toolbar.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if all is well, FALSE otherwise.
*/
BOOL CFigure::InPlaceToolsRenegotiate(void)
{
HRESULT hr;
BORDERWIDTHS bw;
SetRect((LPRECT)&bw, 0, m_pFR->m_cyBar, 0, 0);
hr=m_pIOleIPFrame->RequestBorderSpace(&bw);
if (NOERROR!=hr)
return FALSE;
//Safety net: RequestBorderSpace may modify values in bw
SetRect((LPRECT)&bw, 0, m_pFR->m_cyBar, 0, 0);
m_pIOleIPFrame->SetBorderSpace(&bw);
return TRUE;
}
/*
* CFigure::OpenIntoWindow
*
* Purpose:
* If we're current open in-place, send ourselves the OPEN verb to
* show into a full window.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CFigure::OpenIntoWindow(void)
{
if (NULL!=m_pIOleIPSite)
{
//Make sure we don't try to do this.
m_fUndoDeactivates=FALSE;
/*
* We can get away with passing a lot of NULLs since we know
* how we implemented DoVerb.
*/
m_pImpIOleObject->DoVerb(OLEIVERB_OPEN, NULL
, m_pIOleClientSite, -1, NULL, NULL);
//This makes sure we save ourselves when closing.
m_fForceSave=TRUE;
//Repaint the container immediately
SendAdvise(OBJECTCODE_DATACHANGED);
}
return;
}
/*
* Undo
*
* Purpose:
* If we have not done anything else in this object then call
* IOleInPlaceSite::DeactivateAndUndo and return TRUE, otherwise
* just return FALSE. Note that the m_fUndoDeactivates is set
* to FALSE in CFigure::SendAdvise for OBJECTCODE_DATACHANGED.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if we deactivated, FALSE otherwise.
*/
BOOL CFigure::Undo(void)
{
if (!m_fUndoDeactivates)
return FALSE;
m_fUndoDeactivates=FALSE;
m_pIOleIPSite->DeactivateAndUndo();
return TRUE;
}
//End CHAPTER23MOD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -