|
|
/************************************************************/ /* Windows Write, Copyright 1985-1992 Microsoft Corporation */ /************************************************************/ /* register.c - Handles the Win 3.1 registration library.
* * Created by Microsoft Corporation. */
#define LSTRING // for lstrcat etc
#include <windows.h>
#include <shellapi.h>
#include "objreg.h"
#include "mw.h"
#include "winddefs.h"
#include "obj.h"
#include "str.h" /* Needed for string resource id */
#include "menudefs.h"
#include "cmddefs.h"
char szClassName[CBPATHMAX];
HKEY hkeyRoot = NULL;
void NEAR PASCAL MakeMenuString(char *szCtrl, char *szMenuStr, char *szVerb, char *szClass, char *szObject);
/* RegInit() - Prepare the registration database for calls.
*/ void FAR RegInit(HANDLE hInst) { /* this seems to speed up registration operations immensely, but serves
no other purpose */ //RegOpenKey(HKEY_CLASSES_ROOT,NULL,&hkeyRoot);
}
/* RegTerm() - Clean up and terminate the registration library.
*/ void FAR RegTerm(void) { if (hkeyRoot) { RegCloseKey(hkeyRoot); hkeyRoot = NULL; } }
/* RegGetClassId() - Retrieves the string name of a class.
* * Note: Classes are guaranteed to be in ASCII, but should * not be used directly as a rule because they might * be meaningless if running non-English Windows. */ void FAR RegGetClassId(LPSTR lpstrName, LPSTR lpstrClass) { DWORD dwSize = KEYNAMESIZE;
if (RegQueryValue(HKEY_CLASSES_ROOT, lpstrClass, (LPSTR)lpstrName, &dwSize)) lstrcpy(lpstrName, lpstrClass); }
/* RegMakeFilterSpec() - Retrieves class-associated default extensions.
* * This function returns a filter spec, to be used in the "Change Link" * standard dialog box, which contains all the default extensions which * are associated with the given class name. Again, the class names are * guaranteed to be in ASCII. * * Returns: The index nFilterIndex stating which filter item matches the * extension, or 0 if none is found or -1 if error. ** *hFilterSpec is allocated and must be freed by caller. */ int FAR RegMakeFilterSpec(LPSTR lpstrClass, LPSTR lpstrExt, HANDLE *hFilterSpec) { DWORD dwSize; LPSTR lpstrFilterSpec; char szClass[KEYNAMESIZE]; char szName[KEYNAMESIZE]; char szString[KEYNAMESIZE]; unsigned int i; int idWhich = 0; int idFilterIndex = 0;
if (*hFilterSpec == NULL) { if ((*hFilterSpec = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,KEYNAMESIZE+16)) == NULL) return -1; lpstrFilterSpec = MAKELP(*hFilterSpec,0); }
RegOpenKey(HKEY_CLASSES_ROOT,NULL,&hkeyRoot); for (i = 0; !RegEnumKey(HKEY_CLASSES_ROOT, i++, szName, KEYNAMESIZE); ) { if (*szName == '.' /* Default Extension... */
/* ... so, get the class name */ && (dwSize = KEYNAMESIZE) && !RegQueryValue(HKEY_CLASSES_ROOT, szName, szClass, &dwSize)
/* ... and if the class name matches (null class is wildcard) */ && (!lpstrClass || !lstrcmpi(lpstrClass, szClass))
/* ... get the class name string */ && (dwSize = KEYNAMESIZE) && !RegQueryValue(HKEY_CLASSES_ROOT, szClass, szString, &dwSize)) { int offset;
idWhich++;
/* If the extension matches, save the filter index */ if (lpstrExt && !lstrcmpi(lpstrExt, szName)) idFilterIndex = idWhich;
offset = lpstrFilterSpec - MAKELP(*hFilterSpec,0);
if ((GlobalSize(*hFilterSpec) - offset) < (lstrlen(szString) + 16)) { if ((*hFilterSpec = GlobalReAlloc(*hFilterSpec,GlobalSize(*hFilterSpec)+KEYNAMESIZE+16, GMEM_MOVEABLE|GMEM_ZEROINIT)) == NULL) { GlobalFree(*hFilterSpec); *hFilterSpec = NULL; idFilterIndex = -1; break; } lpstrFilterSpec = (LPSTR)MAKELP(*hFilterSpec,0) + offset; }
/* Copy over "<Class Name String> (*<Default Extension>)"
* e.g. "Server Picture (*.PIC)" */ lstrcpy(lpstrFilterSpec, szString); lstrcat(lpstrFilterSpec, " (*"); lstrcat(lpstrFilterSpec, szName); lstrcat(lpstrFilterSpec, ")"); lpstrFilterSpec += lstrlen(lpstrFilterSpec) + 1;
/* Copy over "*<Default Extension>" (e.g. "*.PIC") */ lstrcpy(lpstrFilterSpec, "*"); lstrcat(lpstrFilterSpec, szName); lpstrFilterSpec += lstrlen(lpstrFilterSpec) + 1; } }
/* Add another NULL at the end of the spec (+ 16 accounts for this) */ if (idFilterIndex > -1) *lpstrFilterSpec = 0;
if (hkeyRoot) { RegCloseKey(hkeyRoot); hkeyRoot = NULL; }
return idFilterIndex; }
/* RegCopyClassName() - Returns the ASCII class id from the listbox.
*/ BOOL FAR RegCopyClassName(HWND hwndList, LPSTR lpstrClassName) { BOOL fSuccess = FALSE; DWORD dwSize = 0L; HKEY hkeyTemp; char szClass[KEYNAMESIZE]; char szExec[KEYNAMESIZE]; char szKey[KEYNAMESIZE]; char szName[KEYNAMESIZE]; int i; int iWhich;
iWhich = (int)SendMessage(hwndList, LB_GETCURSEL, 0, 0L); SendMessage(hwndList, LB_GETTEXT, iWhich, (DWORD)(LPSTR)szKey);
RegOpenKey(HKEY_CLASSES_ROOT,NULL,&hkeyRoot); for (i = 0; !fSuccess && !RegEnumKey(HKEY_CLASSES_ROOT, i++, szClass, KEYNAMESIZE); ) if (*szClass != '.') { /* Not default extension... */
/* See if this class really refers to a server */ dwSize = 0; hkeyTemp = NULL; lstrcpy(szExec, szClass); lstrcat(szExec, "\\protocol\\StdFileEditing\\server");
if (!RegOpenKey(HKEY_CLASSES_ROOT, szExec, &hkeyTemp)) { /* ... get the class name string */ dwSize = KEYNAMESIZE; if (!RegQueryValue(HKEY_CLASSES_ROOT, szClass, szName, &dwSize) && !lstrcmp(szName, szKey)) fSuccess = TRUE;
RegCloseKey(hkeyTemp); } }
if (fSuccess) lstrcpy(lpstrClassName, szClass);
if (hkeyRoot) { RegCloseKey(hkeyRoot); hkeyRoot = NULL; }
return fSuccess; }
/* RegGetClassNames() - Fills the list box with possible server names.
*/ BOOL FAR RegGetClassNames(HWND hwndList) { BOOL fSuccess = FALSE; DWORD dwSize = 0L; HKEY hkeyTemp; char szClass[KEYNAMESIZE]; char szExec[KEYNAMESIZE]; char szName[KEYNAMESIZE]; int i;
SendMessage(hwndList, LB_RESETCONTENT, 0, 0L);
RegOpenKey(HKEY_CLASSES_ROOT,NULL,&hkeyRoot); for (i = 0; !RegEnumKey(HKEY_CLASSES_ROOT, i++, szClass, KEYNAMESIZE); ) if (*szClass != '.') { /* Not default extension... */
/* See if this class really refers to a server */ dwSize = 0; hkeyTemp = NULL; lstrcpy(szExec, szClass); lstrcat(szExec, "\\protocol\\StdFileEditing\\server");
if (!RegOpenKey(HKEY_CLASSES_ROOT, szExec, &hkeyTemp)) { /* ... get the class name string */ dwSize = KEYNAMESIZE; if (!RegQueryValue(HKEY_CLASSES_ROOT, szClass, szName, &dwSize)) { SendMessage(hwndList, LB_ADDSTRING, 0, (DWORD)(LPSTR)szName); fSuccess = TRUE; } RegCloseKey(hkeyTemp); } }
if (hkeyRoot) { RegCloseKey(hkeyRoot); hkeyRoot = NULL; } return fSuccess; }
void ObjUpdateMenuVerbs( HMENU hMenu ) { int cObjects; extern struct SEL selCur; extern char szOPropMenuStr[]; extern char szPPropMenuStr[]; extern BOOL vfOutOfMemory; char szBuffer[cchMaxSz]; char szWordOrder2[10], szWordOrder3[10];
if (vfOutOfMemory) { EnableMenuItem(hMenu, EDITMENUPOS, MF_GRAYED|MF_BYPOSITION); return; }
LoadString(hINSTANCE, IDSTRPopupVerbs, szWordOrder2, sizeof(szWordOrder2)); LoadString(hINSTANCE, IDSTRSingleVerb, szWordOrder3, sizeof(szWordOrder3));
DeleteMenu(hMenu, EDITMENUPOS, MF_BYPOSITION);
/** Cases:
0) 0 objects selected 1) 1 object selected a) object supports 0 verbs "Edit <Object Class> Object" b) object supports more than 1 verb "<Object Class> Object" => verbs 2) more than 1 object selected "Objects"
Use the VerbMenu strings to determine the order in which these words should appear in the menu string (for localization). **/
/* how many objects are selected? */ cObjects = ObjSetSelectionType(docCur,selCur.cpFirst, selCur.cpLim);
/* must be only an object, not text in selection */ if (cObjects == 1) { ObjCachePara(docCur,selCur.cpFirst); if (!ObjQueryCpIsObject(docCur,selCur.cpFirst)) cObjects = 0; }
if ((cObjects == -1) // error
|| (cObjects == 0) || (cObjects > 1)) { wsprintf(szBuffer, "%s", (LPSTR)((cObjects > 1) ? szPPropMenuStr : szOPropMenuStr)); InsertMenu(hMenu, EDITMENUPOS, MF_BYPOSITION,imiVerb,szBuffer);
/*
Spec says if > 1 then optionally should enable if all servers are of the same class. I'm opting not to implement. (9.27.91) v-dougk */ EnableMenuItem(hMenu, EDITMENUPOS, MF_GRAYED | MF_BYPOSITION);
#if 0
else // > 1
{ EnableMenuItem(hMenu, EDITMENUPOS, (((OBJ_SELECTIONTYPE == EMBEDDED) || (OBJ_SELECTIONTYPE == LINK)) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); } #endif
return; } else // 1 object selected
{ OBJPICINFO picInfo;
/** CASES:
object supports 0 verbs "Edit <Object Class> Object" object supports more than 1 verb "<Object Class> Object" => verbs **/
RegOpenKey(HKEY_CLASSES_ROOT,NULL,&hkeyRoot);
GetPicInfo(selCur.cpFirst,selCur.cpFirst + cchPICINFOX, docCur, &picInfo);
if ((otOBJ_QUERY_TYPE(&picInfo) == EMBEDDED) || (otOBJ_QUERY_TYPE(&picInfo) == LINK)) { HANDLE hData=NULL; LPSTR lpstrData; OLESTATUS olestat; olestat = OleGetData(lpOBJ_QUERY_OBJECT(&picInfo), otOBJ_QUERY_TYPE(&picInfo) == LINK? vcfLink: vcfOwnerLink, &hData);
if ((olestat == OLE_WARN_DELETE_DATA) || (olestat == OLE_OK)) { HKEY hKeyVerb; DWORD dwSize = KEYNAMESIZE; char szClass[KEYNAMESIZE]; char szVerb[KEYNAMESIZE]; HANDLE hPopupNew=NULL;
lpstrData = MAKELP(hData,0);
/* Both link formats are: "szClass0szDocument0szItem00" */
/* get real language class of object in szClass for menu */ if (RegQueryValue(HKEY_CLASSES_ROOT, lpstrData, szClass, &dwSize)) lstrcpy(szClass, lpstrData); /* if above call failed */
if (olestat == OLE_WARN_DELETE_DATA) GlobalFree(hData);
/* append class key */ for (vcVerbs=0; ;++vcVerbs) { dwSize = KEYNAMESIZE; wsprintf(szBuffer, "%s\\protocol\\StdFileEditing\\verb\\%d", (LPSTR)lpstrData,vcVerbs); if (RegQueryValue(HKEY_CLASSES_ROOT, szBuffer, szVerb, &dwSize)) break;
if (hPopupNew == NULL) hPopupNew = CreatePopupMenu();
InsertMenu(hPopupNew, -1, MF_BYPOSITION, imiVerb+vcVerbs+1, szVerb); }
if (vcVerbs == 0) { LoadString(hINSTANCE, IDSTREdit, szVerb, sizeof(szVerb)); MakeMenuString(szWordOrder3, szBuffer, szVerb, szClass, szOPropMenuStr); InsertMenu(hMenu, EDITMENUPOS, MF_BYPOSITION, imiVerbPlay, szBuffer); } else if (vcVerbs == 1) { MakeMenuString(szWordOrder3, szBuffer, szVerb, szClass, szOPropMenuStr); InsertMenu(hMenu, EDITMENUPOS, MF_BYPOSITION, imiVerbPlay, szBuffer); DestroyMenu(hPopupNew); } else // > 1 verbs
{ MakeMenuString(szWordOrder2, szBuffer, NULL, szClass, szOPropMenuStr); InsertMenu(hMenu, EDITMENUPOS, MF_BYPOSITION | MF_POPUP, hPopupNew, szBuffer); } EnableMenuItem(hMenu, EDITMENUPOS, MF_ENABLED|MF_BYPOSITION); if (hkeyRoot) { RegCloseKey(hkeyRoot); hkeyRoot = NULL; } return; } else ObjError(olestat); } }
/* error if got to here */ wsprintf(szBuffer, "%s", (LPSTR)szOPropMenuStr); InsertMenu(hMenu, EDITMENUPOS, MF_BYPOSITION,NULL,szBuffer); EnableMenuItem(hMenu, EDITMENUPOS, MF_GRAYED|MF_BYPOSITION); if (hkeyRoot) { RegCloseKey(hkeyRoot); hkeyRoot = NULL; } }
void NEAR PASCAL MakeMenuString(char *szCtrl, char *szMenuStr, char *szVerb, char *szClass, char *szObject) { char *pStr; register char c;
while (c = *szCtrl++) { switch(c) { case 'c': // class
case 'C': // class
pStr = szClass; break; case 'v': // class
case 'V': // class
pStr = szVerb; break; case 'o': // object
case 'O': // object
pStr = szObject; break; default: *szMenuStr++ = c; *szMenuStr = '\0'; // just in case
continue; }
if (pStr) // should always be true
{ lstrcpy(szMenuStr,pStr); szMenuStr += lstrlen(pStr); // point to '\0'
} } }
|