|
|
1.1 ! root 1: // This is a part of the Microsoft Foundation Classes C++ library. ! 2: // Copyright (C) 1992 Microsoft Corporation ! 3: // All rights reserved. ! 4: // ! 5: // This source code is only intended as a supplement to the ! 6: // Microsoft Foundation Classes Reference and Microsoft ! 7: // QuickHelp documentation provided with the library. ! 8: // See these sources for detailed information regarding the ! 9: // Microsoft Foundation Classes product. ! 10: ! 11: // MAINWND.CXX : main window ! 12: ! 13: #include "oclient.h" ! 14: #include "mainwnd.h" ! 15: #include "itemwnd.h" ! 16: ! 17: static LPSTR CreateNewUniqueName(LPSTR lpstr); ! 18: ! 19: ///////////////////////////////////////////////////////////////////////////// ! 20: ! 21: ! 22: #pragma warning(disable:4355) ! 23: // C4355 is "'this' used in base initializer list" warning ! 24: ! 25: CMainWnd::CMainWnd() ! 26: : m_document(this) ! 27: { ! 28: VERIFY(m_title.LoadString(IDS_APPNAME)); ! 29: VERIFY(LoadAccelTable(MAKEINTRESOURCE(ID_APPLICATION))); ! 30: Create(NULL, m_title, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, ! 31: rectDefault, NULL, MAKEINTRESOURCE(ID_APPLICATION)); ! 32: ASSERT(m_hWnd != NULL); ! 33: m_pSelection = NULL; ! 34: m_fDirty = FALSE; ! 35: } ! 36: ! 37: #pragma warning(default:4355) ! 38: ! 39: // Iterator over content ! 40: COleClientItem* CMainDocument::GetNextItem(POSITION& rPosition, ! 41: BOOL* pIsSelected) ! 42: { ! 43: CItemWnd* pItemWnd = (CItemWnd*) rPosition; ! 44: if (pItemWnd == NULL) ! 45: pItemWnd = (CItemWnd*)m_pView->GetTopWindow(); ! 46: else ! 47: pItemWnd = (CItemWnd*)pItemWnd->GetNextWindow(); ! 48: ! 49: *pIsSelected = (m_pView->GetSelection() == pItemWnd); ! 50: rPosition = (POSITION)pItemWnd; ! 51: return (pItemWnd == NULL) ? NULL : pItemWnd->GetEmbedded(); ! 52: } ! 53: ! 54: ! 55: ///////////////////////////////////////////////////////////////////////////// ! 56: ! 57: void CMainWnd::OnAbout() ! 58: { ! 59: CModalDialog about(MAKEINTRESOURCE(IDDT_ABOUT), this); ! 60: about.DoModal(); ! 61: } ! 62: ! 63: void CMainWnd::Hourglass(BOOL bOn) ! 64: { ! 65: static int count = 0; ! 66: static HCURSOR hcurWait = AfxGetApp()->LoadStandardCursor(IDC_WAIT); ! 67: static HCURSOR hcurLast; ! 68: ! 69: ASSERT(hcurWait != NULL); ! 70: if (bOn) ! 71: { ! 72: if (count++ == 0) ! 73: hcurLast = ::SetCursor(hcurWait); ! 74: } ! 75: else ! 76: { ! 77: if (--count == 0) ! 78: ::SetCursor(hcurLast); ! 79: } ! 80: } ! 81: ! 82: void CMainWnd::OnClose() ! 83: { ! 84: if (COleClientItem::InWaitForRelease()) ! 85: { ! 86: ErrorMessage(E_BUSY); ! 87: return; ! 88: } ! 89: ! 90: if (!SaveAsNeeded()) ! 91: return; // don't quit ! 92: ! 93: DeregisterDoc(); ! 94: DestroyWindow(); ! 95: } ! 96: ! 97: BOOL CMainWnd::OnQueryEndSession() ! 98: { ! 99: if (COleClientItem::InWaitForRelease()) ! 100: return FALSE; ! 101: return CFrameWnd::OnQueryEndSession(); ! 102: } ! 103: ! 104: void CMainWnd::OnDestroy() ! 105: { ! 106: GetDocument()->Revoke(); // revoke just in case ! 107: CFrameWnd::OnDestroy(); // will close down the app ! 108: } ! 109: ! 110: ///////////////////////////////////////////////////////////////////////////// ! 111: // Error reporting ! 112: ! 113: void CMainWnd::ErrorMessage(UINT id) ! 114: { ! 115: // if in exit mode no message box ! 116: if (!GetDocument()->IsOpen()) ! 117: return; ! 118: ! 119: CString str; ! 120: str.LoadString(id); ! 121: MessageBox(str, AfxGetAppName(), MB_OK | MB_ICONEXCLAMATION); ! 122: } ! 123: ! 124: ///////////////////////////////////////////////////////////////////////////// ! 125: ! 126: void CMainWnd::OnExit() ! 127: { ! 128: // close window - NOTE: Do _not_ call 'OnClose' message map function ! 129: SendMessage(WM_CLOSE); ! 130: } ! 131: ! 132: ///////////////////////////////////////////////////////////////////////////// ! 133: ! 134: ! 135: BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) ! 136: // windows messages ! 137: ON_WM_INITMENUPOPUP() ! 138: ON_WM_CLOSE() ! 139: ON_WM_DESTROY() ! 140: ON_WM_QUERYENDSESSION() ! 141: ON_WM_ACTIVATE() ! 142: ! 143: // file menu commands ! 144: ON_COMMAND(IDM_NEW, OnFileNew) ! 145: ON_COMMAND(IDM_OPEN, OnFileOpen) ! 146: ON_COMMAND(IDM_SAVE, OnFileSave) ! 147: ON_COMMAND(IDM_SAVEAS, OnFileSaveAs) ! 148: ON_COMMAND(IDM_EXIT, OnExit) ! 149: ON_COMMAND(IDM_ABOUT, OnAbout) ! 150: // edit menu commands ! 151: ON_COMMAND(IDM_CUT, OnCut) ! 152: ON_COMMAND(IDM_COPY, OnCopy) ! 153: ON_COMMAND(IDM_PASTE, OnPaste) ! 154: ON_COMMAND(IDM_PASTELINK, OnPasteLink) ! 155: ON_COMMAND(IDM_CLEAR, OnClear) ! 156: ON_COMMAND(IDM_CLEARALL, OnClearAll) ! 157: ON_COMMAND(IDM_INSERT_OBJECT, OnInsertObject) ! 158: ON_COMMAND(IDM_LINKS, OnEditLinks) ! 159: END_MESSAGE_MAP() ! 160: ! 161: ! 162: ///////////////////////////////////////////////////////////////////////////// ! 163: // Most Edit Commands ! 164: ! 165: void CMainWnd::OnInitMenuPopup(CMenu* pMenu, UINT iMenu, BOOL bSysMenu) ! 166: { ! 167: if (bSysMenu || iMenu != IMENU_EDIT) ! 168: return; // system and file menu don't do any dynamic updating ! 169: ! 170: ASSERT(pMenu != NULL); ! 171: // only enable/diable items on the Edit menu ! 172: CItemWnd* pSelection = GetSelection(); ! 173: ! 174: //BLOCK: Simple editing ! 175: { ! 176: UINT mfCanEdit = MF_GRAYED|MF_DISABLED; ! 177: ! 178: if (pSelection != NULL) ! 179: mfCanEdit = MF_ENABLED; // have some content ! 180: ! 181: // Now enable appropriate menu items ! 182: pMenu->EnableMenuItem(IDM_CUT, mfCanEdit); ! 183: pMenu->EnableMenuItem(IDM_COPY, mfCanEdit); ! 184: pMenu->EnableMenuItem(IDM_CLEAR, mfCanEdit); ! 185: pMenu->EnableMenuItem(IDM_CLEARALL, mfCanEdit); ! 186: } ! 187: ! 188: //BLOCK: paste variants ! 189: { ! 190: pMenu->EnableMenuItem(IDM_PASTE, COleClientItem::CanPaste() ? ! 191: MF_ENABLED : (MF_GRAYED|MF_DISABLED)); ! 192: pMenu->EnableMenuItem(IDM_PASTELINK, COleClientItem::CanPasteLink() ? ! 193: MF_ENABLED : (MF_GRAYED|MF_DISABLED)); ! 194: } ! 195: ! 196: //BLOCK: special case if any linked objects ! 197: { ! 198: UINT mfLinks = MF_GRAYED|MF_DISABLED; ! 199: ! 200: CItemWnd* pItemWnd; ! 201: for (pItemWnd = (CItemWnd*)GetTopWindow(); pItemWnd != NULL; ! 202: pItemWnd = (CItemWnd*)pItemWnd->GetNextWindow()) ! 203: { ! 204: if (pItemWnd->GetEmbedded()->GetType() == OT_LINK) ! 205: { ! 206: mfLinks = MF_ENABLED; ! 207: break; ! 208: } ! 209: } ! 210: pMenu->EnableMenuItem(IDM_LINKS, mfLinks); ! 211: } ! 212: ! 213: //BLOCK: Object menu specific ! 214: { ! 215: static int iItemObjectVerb = -1; // position on the Edit menu ! 216: ! 217: if (iItemObjectVerb == -1) ! 218: { ! 219: // one-time init - find the position of the "Object ?" menuitem ! 220: int nItems = pMenu->GetMenuItemCount(); ! 221: for (int iItem = 0; iItem < nItems; iItem++) ! 222: { ! 223: if (pMenu->GetMenuItemID(iItem) == IDM_OBJECT_VERB_MIN) ! 224: { ! 225: iItemObjectVerb = iItem; ! 226: break; ! 227: } ! 228: } ! 229: ASSERT(iItemObjectVerb != -1); ! 230: // MUST BE IN THE MENU TEMPLATE ON INIT ! ! 231: } ! 232: ! 233: AfxOleSetEditMenu(pSelection == NULL ? NULL : pSelection->GetEmbedded(), ! 234: pMenu, iItemObjectVerb, IDM_OBJECT_VERB_MIN); ! 235: } ! 236: } ! 237: ! 238: BOOL CMainWnd::OnCommand(UINT wParam, LONG lParam) ! 239: { ! 240: // if we are waiting for release - ignore all commands ! 241: if (COleClientItem::InWaitForRelease()) ! 242: { ! 243: ErrorMessage(E_BUSY); ! 244: return TRUE; // handled ! 245: } ! 246: ! 247: if (LOWORD(lParam) == 0 && wParam >= IDM_OBJECT_VERB_MIN && ! 248: wParam <= IDM_OBJECT_VERB_MAX) ! 249: { ! 250: // activate the current selection with the appropriate verb ! 251: CItemWnd* pItemWnd = GetSelection(); ! 252: ASSERT(pItemWnd != NULL); ! 253: pItemWnd->DoVerb(wParam - IDM_OBJECT_VERB_MIN); ! 254: return TRUE; // handled ! 255: } ! 256: return CFrameWnd::OnCommand(wParam, lParam); ! 257: } ! 258: ! 259: ///////////////////////////////////////////////////////////////////////////// ! 260: // Selection support ! 261: ! 262: void CMainWnd::SetSelection(CItemWnd* pNewSelection) ! 263: { ! 264: if (pNewSelection != GetTopWindow() && pNewSelection != NULL) ! 265: pNewSelection->BringWindowToTop(); ! 266: ! 267: if (m_pSelection != pNewSelection) ! 268: { ! 269: // de-select old ! 270: if (m_pSelection != NULL) ! 271: m_pSelection->Select(FALSE); ! 272: // select the new ! 273: if (pNewSelection != NULL) ! 274: { ! 275: pNewSelection->Select(TRUE); ! 276: } ! 277: m_pSelection = pNewSelection; ! 278: } ! 279: } ! 280: ! 281: void CMainWnd::OnActivate(UINT nState, CWnd*, BOOL) ! 282: { ! 283: if (m_pSelection) ! 284: m_pSelection->Select(nState != 0); ! 285: } ! 286: ! 287: ///////////////////////////////////////////////////////////////////////////// ! 288: ! 289: void CMainWnd::OnCut() ! 290: { ! 291: if (!DoCopySelection()) ! 292: { ! 293: ErrorMessage(E_CLIPBOARD_CUT_FAILED); ! 294: return; ! 295: } ! 296: // cut it out ! 297: OnClear(); ! 298: Dirty(); ! 299: } ! 300: ! 301: ! 302: void CMainWnd::OnCopy() ! 303: { ! 304: if (!DoCopySelection()) ! 305: ErrorMessage(E_CLIPBOARD_COPY_FAILED); ! 306: } ! 307: ! 308: BOOL CMainWnd::DoCopySelection() ! 309: { ! 310: CItemWnd* pSel = GetSelection(); ! 311: ASSERT(pSel != NULL); ! 312: ! 313: if (!OpenClipboard()) ! 314: return FALSE; ! 315: ! 316: /* Empty the clipboard */ ! 317: EmptyClipboard(); ! 318: ! 319: TRY ! 320: pSel->GetEmbedded()->CopyToClipboard(); ! 321: CATCH (CException, e) ! 322: return FALSE; ! 323: END_CATCH ! 324: ! 325: CloseClipboard(); ! 326: return TRUE; ! 327: } ! 328: ! 329: ! 330: void CMainWnd::OnClear() ! 331: { ! 332: ASSERT(GetSelection() != NULL); ! 333: CItemWnd* pSel = GetSelection(); ! 334: ! 335: if (pSel) ! 336: pSel->DestroyWindow(); ! 337: ! 338: Dirty(); ! 339: } ! 340: ! 341: void CMainWnd::ClearAll() ! 342: { ! 343: CWnd* pKid; ! 344: while ((pKid = GetTopWindow()) != NULL) ! 345: { ! 346: VERIFY(pKid->DestroyWindow()); ! 347: } ! 348: } ! 349: ! 350: void CMainWnd::OnClearAll() ! 351: { ! 352: ClearAll(); /* Wipes out all items */ ! 353: Dirty(); ! 354: } ! 355: ! 356: void CMainWnd::OnPaste() ! 357: { ! 358: if (!DoPaste(FALSE)) ! 359: ErrorMessage(E_GET_FROM_CLIPBOARD_FAILED); ! 360: Dirty(); ! 361: } ! 362: ! 363: void CMainWnd::OnPasteLink() ! 364: { ! 365: if (!DoPaste(TRUE)) ! 366: ErrorMessage(E_GET_FROM_CLIPBOARD_FAILED); ! 367: } ! 368: ! 369: BOOL CMainWnd::DoPaste(BOOL fLink) ! 370: { ! 371: if (!OpenClipboard()) ! 372: return NULL; /* Couldn't open the clipboard */ ! 373: ! 374: Hourglass(TRUE); ! 375: ! 376: /* Don't replace the current object unless we're successful */ ! 377: CItemWnd* pItemWnd = new CItemWnd(this); ! 378: CEmbeddedItem* pItem = pItemWnd->GetEmbedded(); ! 379: char szName[OLE_MAXNAMESIZE]; ! 380: CreateNewUniqueName(szName); ! 381: ! 382: TRY ! 383: { ! 384: if (fLink) ! 385: { ! 386: if (!pItem->CreateLinkFromClipboard(szName)) ! 387: AfxThrowMemoryException(); // any exception will do ! 388: } ! 389: else ! 390: { ! 391: // paste embedded ! 392: if (pItem->CreateFromClipboard(szName)) ! 393: { ! 394: TRACE("embedded an embedded OLE object\n"); ! 395: } ! 396: else if (pItem->CreateStaticFromClipboard(szName)) ! 397: { ! 398: TRACE("embedded a static picture object\n"); ! 399: } ! 400: else ! 401: { ! 402: AfxThrowMemoryException(); // any exception will do ! 403: } ! 404: } ! 405: } ! 406: CATCH (CException, e) ! 407: { ! 408: // general cleanup ! 409: TRACE("failed to embed/link an OLE object\n"); ! 410: delete pItemWnd; ! 411: pItemWnd = NULL; ! 412: } ! 413: END_CATCH ! 414: ! 415: CloseClipboard(); ! 416: Hourglass(FALSE); ! 417: ! 418: if (pItemWnd == NULL) ! 419: return FALSE; ! 420: ! 421: // create as a live health ItemWnd ! 422: if (!pItemWnd->CreateItemWindow(TRUE)) ! 423: { ! 424: delete pItemWnd; ! 425: return FALSE; ! 426: } ! 427: ! 428: // Success ! ! 429: // (from this point on the PostNcCreate hook will clean up memory) ! 430: return TRUE; ! 431: } ! 432: ! 433: ! 434: ///////////////////////////////////////////////////////////////////////////// ! 435: // Insert new object ! 436: ! 437: void CMainWnd::OnInsertObject() ! 438: { ! 439: CString className; ! 440: ! 441: if (!AfxOleInsertDialog(className)) ! 442: return; ! 443: ! 444: TRACE("Trying to Insert OLE object (class '%s')\n", (const char*)className); ! 445: CItemWnd* pItemWnd = new CItemWnd(this); ! 446: CEmbeddedItem* pItem = pItemWnd->GetEmbedded(); ! 447: ! 448: char szTmp[OLE_MAXNAMESIZE]; ! 449: TRY ! 450: { ! 451: if (!pItem->CreateNewObject(className, CreateNewUniqueName(szTmp))) ! 452: AfxThrowMemoryException(); // any exception will do ! 453: } ! 454: CATCH (CException, e) ! 455: { ! 456: ErrorMessage(E_FAILED_TO_CREATE); ! 457: // clean up item ! 458: delete pItemWnd; ! 459: return; ! 460: } ! 461: END_CATCH ! 462: ! 463: // Create invisible (will become visible later when updated) ! 464: if (!pItemWnd->CreateItemWindow(FALSE)) ! 465: delete pItemWnd; ! 466: ! 467: // Success! ! 468: // (from this point on the PostNcCreate hook will clean up memory) ! 469: ! 470: Dirty(); ! 471: } ! 472: ! 473: ///////////////////////////////////////////////////////////////////////////// ! 474: ! 475: void FixObjectBounds(CRect& rect) ! 476: { ! 477: /* If we have an empty rectangle, start at default size */ ! 478: if (rect.IsRectNull()) ! 479: { ! 480: rect.SetRect(0, 0, CXDEFAULT, CYDEFAULT); ! 481: } ! 482: else ! 483: { ! 484: // First map from HIMETRIC back to screen coordinates ! 485: { ! 486: CClientDC screenDC(NULL); ! 487: ! 488: short oldMode = screenDC.SetMapMode(MM_HIMETRIC); ! 489: screenDC.LPtoDP(&rect); ! 490: screenDC.SetMapMode(oldMode); ! 491: } ! 492: ! 493: /* Preserve the Aspect Ratio of the picture */ ! 494: DWORD xDiff = (DWORD) (rect.right - rect.left + 1); ! 495: DWORD yDiff = (DWORD) (rect.bottom - rect.top + 1); ! 496: ! 497: /* Don't use *= here because of integer arithmetic. */ ! 498: if (xDiff > CXDEFAULT || yDiff > CYDEFAULT) ! 499: { ! 500: if ((xDiff * CYDEFAULT) > (yDiff * CXDEFAULT)) ! 501: { ! 502: yDiff = ((yDiff * CXDEFAULT) / xDiff); ! 503: xDiff = CXDEFAULT; ! 504: } ! 505: else ! 506: { ! 507: xDiff = ((xDiff * CYDEFAULT) / yDiff); ! 508: yDiff = CYDEFAULT; ! 509: } ! 510: } ! 511: rect.SetRect(0, 0, (int)xDiff - 1, (int)yDiff - 1); ! 512: } ! 513: } ! 514: ! 515: ///////////////////////////////////////////////////////////////////////////// ! 516: // Name generator helper ! 517: ! 518: LPSTR CreateNewUniqueName(LPSTR lpstr) ! 519: { ! 520: static int CurrentNumber = 0; ! 521: wsprintf(lpstr, "%s%04d", (LPSTR)OBJ_NAME_PREFIX, CurrentNumber++); ! 522: return(lpstr); ! 523: } ! 524: ! 525: ///////////////////////////////////////////////////////////////////////////// ! 526: ! 527: void CMainWnd::OnEditLinks() ! 528: { ! 529: CItemWnd* pSelection = GetSelection(); ! 530: ! 531: AfxOleLinksDialog(GetDocument()); ! 532: } ! 533: ! 534: ///////////////////////////////////////////////////////////////////////////// ! 535: // Diagnostics ! 536: ! 537: #ifdef _DEBUG ! 538: void CMainWnd::AssertValid() const ! 539: { ! 540: ASSERT(GetDocument()->IsOpen()); ! 541: } ! 542: #endif ! 543: ! 544: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.