|
|
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:
1.1.1.2 ! root 14: #include "afxoleui.h" // user interface parts
1.1 root 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.