|
|
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: #include "afxole.h" ! 12: #pragma hdrstop ! 13: ! 14: #include "afxoleUI.h" // user interface parts ! 15: ! 16: #include "shellapi.h" ! 17: ! 18: #ifdef AFX_OLE_SEG ! 19: #pragma code_seg(AFX_OLE_SEG) ! 20: #endif ! 21: ! 22: #ifdef _DEBUG ! 23: #undef THIS_FILE ! 24: static char BASED_CODE THIS_FILE[] = __FILE__; ! 25: #endif ! 26: ! 27: ///////////////////////////////////////////////////////////////////////////// ! 28: // User interface for COleClientItem ! 29: ! 30: int COleClientItem::cWaitForRelease = 0; ! 31: BOOL COleClientItem::InWaitForRelease() ! 32: { ! 33: return cWaitForRelease != 0; ! 34: } ! 35: ! 36: void COleClientItem::WaitForServer() ! 37: { ! 38: // enforce synchronous action from the server ! 39: if (afxTraceFlags & 0x10) ! 40: TRACE("WAITING for server\n"); ! 41: ! 42: ASSERT(m_lpObject != NULL); ! 43: ASSERT(cWaitForRelease == 0); ! 44: #ifdef _DEBUG ! 45: m_lastStatus = OLE_WAIT_FOR_RELEASE; ! 46: #endif ! 47: cWaitForRelease++; ! 48: ! 49: // OnRelease may NULL out our m_lpObject ! 50: while (m_lpObject != NULL && ::OleQueryReleaseStatus(m_lpObject) != OLE_OK) ! 51: { ! 52: TRY ! 53: { ! 54: AfxGetApp()->PumpMessage(); ! 55: } ! 56: CATCH(CException,e) ! 57: { ! 58: TRACE("DANGER: caught exception in WaitForServer - continuing\n"); ! 59: } ! 60: END_CATCH ! 61: } ! 62: cWaitForRelease--; ! 63: ! 64: if (afxTraceFlags & 0x10) ! 65: TRACE("DONE WAITING for server\n"); ! 66: } ! 67: ! 68: BOOL COleClientItem::ReportError(OLESTATUS status) ! 69: // return TRUE if error or warning reported ! 70: { ! 71: UINT idString = 0; ! 72: ! 73: switch (status) ! 74: { ! 75: default: ! 76: return FALSE; // nothing sensible to report ! 77: ! 78: case OLE_ERROR_STATIC: ! 79: idString = AFX_ERROR_STATIC_OBJECT; ! 80: break; ! 81: ! 82: case OLE_ERROR_REQUEST_PICT: ! 83: case OLE_ERROR_ADVISE_RENAME: ! 84: case OLE_ERROR_SHOW: ! 85: case OLE_ERROR_OPEN: ! 86: case OLE_ERROR_NETWORK: ! 87: case OLE_ERROR_ADVISE_PICT: ! 88: case OLE_ERROR_COMM: ! 89: case OLE_ERROR_LAUNCH: ! 90: // invalid link ! 91: idString = AFX_ERROR_FAILED_TO_CONNECT; ! 92: break; ! 93: ! 94: case OLE_ERROR_DOVERB: ! 95: idString = AFX_ERROR_BAD_VERB; ! 96: break; ! 97: ! 98: case OLE_BUSY: ! 99: idString = AFX_ERROR_SERVER_BUSY; ! 100: break; ! 101: ! 102: case OLE_ERROR_MEMORY: ! 103: idString = AFX_ERROR_MEMORY; ! 104: break; ! 105: } ! 106: ! 107: CString s; ! 108: s.LoadString(idString); ! 109: ! 110: // bring up a message box in the topmost window ! 111: CWinApp* pApp = AfxGetApp(); ! 112: ASSERT(pApp != NULL && pApp->m_pMainWnd != NULL); ! 113: pApp->m_pMainWnd->MessageBox(s, pApp->m_pszAppName, ! 114: MB_OK | MB_ICONEXCLAMATION); ! 115: ! 116: return TRUE; ! 117: } ! 118: ! 119: ! 120: ///////////////////////////////////////////////////////////////////////////// ! 121: // OLE Object Verb Menu helpers ! 122: ! 123: // Parameters: ! 124: // pClient = client object to operate on (NULL => none) ! 125: // pMenu = menu to modify ! 126: // iMenuItem = index into menu where menu item or popup is to be placed ! 127: // (note will delete the old one) ! 128: // nIDVerbMin = first menu command id for sending to pClient ! 129: // ! 130: // Supported cases: ! 131: // NULL client "&Object" disabled ! 132: // 0 verbs "<Object Class> &Object" ! 133: // 1 verb (no name) "<Object Class> &Object" ! 134: // 1 verb == edit "<Object Class> &Object" ! 135: // 1 verb != edit "<verb> <Object Class> &Object" ! 136: // more than 1 verb "<Object Class> &Object" => verbs ! 137: ! 138: void AfxOleSetEditMenu(COleClientItem* pClient, CMenu* pMenu, ! 139: UINT iMenuItem, UINT nIDVerbMin) ! 140: { ! 141: ASSERT(pMenu != NULL); ! 142: ! 143: static CString NEAR strObjectVerb; // "&Object" ! 144: static CString NEAR strEditVerb; // "Edit" ! 145: static BOOL bInited = FALSE; ! 146: if (!bInited) ! 147: { ! 148: VERIFY(strObjectVerb.LoadString(AFX_IDS_OBJECT_MENUITEM)); ! 149: VERIFY(strEditVerb.LoadString(AFX_IDS_EDIT_VERB)); ! 150: } ! 151: ! 152: pMenu->DeleteMenu(iMenuItem, MF_BYPOSITION); // get rid of old UI ! 153: ! 154: HANDLE hLinkData = NULL; ! 155: UINT mfObjectVerb = MF_GRAYED|MF_DISABLED; ! 156: ! 157: if (pClient != NULL) ! 158: { ! 159: // get type from object ! 160: hLinkData = pClient->GetLinkFormatData(); ! 161: mfObjectVerb = MF_ENABLED; ! 162: } ! 163: ! 164: LPCSTR lpszData; ! 165: // use the link data to determine what class we are talking about ! 166: ! 167: if (hLinkData == NULL || ! 168: (lpszData = (LPCSTR)::GlobalLock(hLinkData)) == NULL) ! 169: { ! 170: // not a valid link, just use the simple '&Object' format disabled ! 171: pMenu->InsertMenu(iMenuItem, MF_BYPOSITION, nIDVerbMin, strObjectVerb); ! 172: pMenu->EnableMenuItem(iMenuItem, mfObjectVerb | MF_BYPOSITION | ! 173: MF_GRAYED|MF_DISABLED); ! 174: return; ! 175: } ! 176: ! 177: LONG lSize; ! 178: char szClass[OLE_MAXNAMESIZE]; ! 179: char szBuffer[OLE_MAXNAMESIZE+40]; ! 180: ! 181: // get real language class of object in szClass for menu ! 182: lSize = OLE_MAXNAMESIZE; ! 183: if (::RegQueryValue(HKEY_CLASSES_ROOT, lpszData, szClass, ! 184: &lSize) != ERROR_SUCCESS) ! 185: { ! 186: // no localized class name, use unlocalized name ! 187: lstrcpy(szClass, lpszData); ! 188: } ! 189: ::GlobalUnlock(hLinkData); ! 190: ! 191: // determine list of available verbs ! 192: char szFirstVerb[OLE_MAXNAMESIZE]; ! 193: HMENU hPopup = NULL; ! 194: int cVerbs = 0; ! 195: ! 196: while (1) ! 197: { ! 198: wsprintf(szBuffer, "%s\\protocol\\StdFileEditing\\verb\\%d", ! 199: (LPCSTR)lpszData, cVerbs); ! 200: ! 201: /* get verb name */ ! 202: char szVerb[OLE_MAXNAMESIZE]; ! 203: lSize = OLE_MAXNAMESIZE; ! 204: if (::RegQueryValue(HKEY_CLASSES_ROOT, szBuffer, szVerb, &lSize) != 0) ! 205: { ! 206: // finished counting verbs ! 207: break; ! 208: } ! 209: cVerbs++; ! 210: ! 211: if (_stricmp(szVerb, strEditVerb) == 0) ! 212: strcpy(szVerb, strEditVerb); // use 'Edit' not 'EDIT' ! 213: ! 214: if (cVerbs == 1) ! 215: { ! 216: // save first verb (special case if this is it) ! 217: strcpy(szFirstVerb, szVerb); ! 218: } ! 219: else ! 220: { ! 221: // overflow into popup ! 222: if (cVerbs == 2) ! 223: { ! 224: // start the popup ! 225: ASSERT(hPopup == NULL); ! 226: hPopup = CreatePopupMenu(); ! 227: ! 228: // now add the first verb ! 229: InsertMenu(hPopup, -1, MF_BYPOSITION, nIDVerbMin + 0, ! 230: szFirstVerb); ! 231: } ! 232: ! 233: ASSERT(hPopup != NULL); ! 234: InsertMenu(hPopup, -1, MF_BYPOSITION, nIDVerbMin + cVerbs - 1, ! 235: szVerb); ! 236: } ! 237: } ! 238: ! 239: if (cVerbs >= 2) ! 240: { ! 241: // install the popup ! 242: wsprintf(szBuffer, "%s %s", (LPCSTR)szClass, (LPCSTR)strObjectVerb); ! 243: pMenu->InsertMenu(iMenuItem, MF_BYPOSITION|MF_POPUP, (UINT)hPopup, szBuffer); ! 244: } ! 245: else if (cVerbs == 0 || _stricmp(szFirstVerb, strEditVerb) == 0) ! 246: { ! 247: // no verbs or redundant 'edit' verb ! 248: wsprintf(szBuffer, "%s %s", (LPCSTR)szClass, (LPCSTR)strObjectVerb); ! 249: pMenu->InsertMenu(iMenuItem, MF_BYPOSITION, nIDVerbMin, szBuffer); ! 250: } ! 251: else ! 252: { ! 253: // use that verb in menu item ! 254: ASSERT(cVerbs == 1); ! 255: wsprintf(szBuffer, "%s %s %s", (LPCSTR)szFirstVerb, (LPCSTR)szClass, ! 256: (LPCSTR)strObjectVerb); ! 257: pMenu->InsertMenu(iMenuItem, MF_BYPOSITION, nIDVerbMin, szBuffer); ! 258: } ! 259: ! 260: // enable what we added ! 261: pMenu->EnableMenuItem(iMenuItem, MF_ENABLED|MF_BYPOSITION); ! 262: } ! 263: ! 264: ///////////////////////////////////////////////////////////////////////////// ! 265: // InsertObject dialog ! 266: ! 267: class CInsertNewObjectDlg : public CModalDialog ! 268: { ! 269: public: ! 270: CString& m_rClassName; ! 271: ! 272: CInsertNewObjectDlg(CString& rReturn) ! 273: : CModalDialog(AFX_IDD_INSERTNEWOBJECT), ! 274: m_rClassName(rReturn) ! 275: { } ! 276: ! 277: BOOL OnInitDialog(); ! 278: void OnOK(); ! 279: DECLARE_MESSAGE_MAP() ! 280: }; ! 281: ! 282: BEGIN_MESSAGE_MAP(CInsertNewObjectDlg, CModalDialog) ! 283: ON_LBN_DBLCLK(AFX_IDC_LISTBOX, OnOK) ! 284: END_MESSAGE_MAP() ! 285: ! 286: BOOL CInsertNewObjectDlg::OnInitDialog() ! 287: { ! 288: int cClasses = 0; ! 289: CListBox* pList = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX); ! 290: ! 291: pList->ResetContent(); ! 292: ! 293: char szClass[OLE_MAXNAMESIZE]; ! 294: int i = 0; ! 295: while (::RegEnumKey(HKEY_CLASSES_ROOT, i++, szClass, OLE_MAXNAMESIZE) == 0) ! 296: { ! 297: if (*szClass == '.') ! 298: continue; // skip extensions ! 299: ! 300: // See if this class really refers to a server ! 301: LONG lSize; ! 302: HKEY hkey = NULL; ! 303: char szExec[OLE_MAXNAMESIZE+40]; ! 304: lstrcpy(szExec, szClass); ! 305: lstrcat(szExec, "\\protocol\\StdFileEditing\\server"); ! 306: ! 307: if (::RegOpenKey(HKEY_CLASSES_ROOT, szExec, &hkey) == 0) ! 308: { ! 309: // since it has a server - add it to the list ! 310: char szName[OLE_MAXNAMESIZE]; ! 311: lSize = OLE_MAXNAMESIZE; ! 312: if (::RegQueryValue(HKEY_CLASSES_ROOT, szClass, ! 313: szName, &lSize) == 0) ! 314: { ! 315: // we have a class name ! 316: pList->AddString(szName); ! 317: cClasses++; ! 318: } ! 319: ::RegCloseKey(hkey); ! 320: } ! 321: } ! 322: ! 323: if (cClasses == 0) ! 324: { ! 325: // whoops - nothing to choose from ! 326: EndDialog(IDCANCEL); ! 327: } ! 328: pList->SetCurSel(0); ! 329: return TRUE; ! 330: } ! 331: ! 332: void CInsertNewObjectDlg::OnOK() ! 333: { ! 334: CListBox* pList = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX); ! 335: ! 336: char szKey[OLE_MAXNAMESIZE]; ! 337: pList->GetText(pList->GetCurSel(), szKey); ! 338: ! 339: char szClass[OLE_MAXNAMESIZE]; ! 340: int i = 0; ! 341: while (::RegEnumKey(HKEY_CLASSES_ROOT, i++, szClass, OLE_MAXNAMESIZE) == 0) ! 342: { ! 343: if (*szClass == '.') ! 344: continue; // skip extensions ! 345: ! 346: // See if this class really refers to a server ! 347: LONG lSize; ! 348: HKEY hkey = NULL; ! 349: char szExec[OLE_MAXNAMESIZE+40]; ! 350: lstrcpy(szExec, szClass); ! 351: lstrcat(szExec, "\\protocol\\StdFileEditing\\server"); ! 352: ! 353: if (::RegOpenKey(HKEY_CLASSES_ROOT, szExec, &hkey) == 0) ! 354: { ! 355: // we found a match - see if appropriate name ! 356: char szName[OLE_MAXNAMESIZE]; ! 357: lSize = OLE_MAXNAMESIZE; ! 358: if (::RegQueryValue(HKEY_CLASSES_ROOT, szClass, ! 359: szName, &lSize) == 0) ! 360: { ! 361: // it is a named class - see if it matches key ! 362: if (strcmp(szKey, szName) == 0) ! 363: { ! 364: // this is it ! 365: m_rClassName = szClass; ! 366: CModalDialog::OnOK(); // terminate dialog ! 367: return; ! 368: } ! 369: } ! 370: ::RegCloseKey(hkey); ! 371: } ! 372: } ! 373: ! 374: // didn't find it ! 375: EndDialog(IDCANCEL); ! 376: } ! 377: ! 378: ! 379: BOOL AfxOleInsertDialog(CString& name) ! 380: { ! 381: CInsertNewObjectDlg dlg(name); ! 382: ! 383: return (dlg.DoModal() == IDOK); ! 384: } ! 385: ! 386: /////////////////////////////////////////////////////////////////////////////
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.