Microsoft KB Archive/195261

= BUG: Operating System Regional Settings Affect VFP COM Objects =

Article ID: 195261

Article Last Modified on 3/7/2005

-

APPLIES TO


 * Microsoft Visual FoxPro 6.0 Professional Edition

-



This article was previously published under Q195261



SYMPTOMS
When you call a method of a COM object written in Visual FoxPro 6.0, the following error might appear:

OLE error code 0x8002801d: Library not registered.



CAUSE
The Visual FoxPro COM object was built on an operating system that uses a different language ID (LCID) regional setting than the one that the COM object is being instantiated on.



RESOLUTION
Do one of the following to resolve this problem:
 * Generate a type library (TLB) using the LCID ID that the target operating system is using. You must distribute this locale-specific TLB with the COM object.
 * You can run the following sample program to stamp the type library with the language neutral LCID (0x0000). This alters the type library so that it can be used with any regional setting. Save the following code to a program named Tag_TLB_LCID.

Sample Code
** Begin program code ** ********************************************************  *   Program:  Tag_TLB_LCID *  *   Param:    TLB_FileName [,LCID] *  *   Note:  The first param can have any extension (for example, DLL). *  *   This utility tags a Visual FoxPro-created TLB file with the LCID *  specified or with LANG_NEUTRAL by default. This allows *  COM DLLs created with Visual FoxPro 6.0 to be distributed to   *   operating systems that have different Language or Dialect *  (sublanguage) settings. This has only been tested on  *   TLBs created with Visual FoxPro 6.0, and is not guaranteed to   *   work correctly on all TLBs created with Visual FoxPro 6.0. *  *   The TLB file format could not be completely reverse- *  engineered, so you must look for a marker that you believe *  will always point you to the typelib description field. *  the LCID appears nine bytes after that. *  *   The original TLB file is backed up, with _ORIG_LCID *  tacked on to the name (for example, Test_ORIG_LCID.TLB) *  *   If it is successful, the procedure returns ".T.". *  *   For information on what to pass as an LCID for a particular *  region, look at the #DEFINEs in FoxPro.H.   * ***********************************************************

* Localizable strings: #DEFINE D_GETFILE_CAPTION_LOC  "Select a Type Library to modify" #DEFINE D_NO_TLB_LOC "Could not open Type Library, ;  or Type Library ;is empty." #DEFINE D_ERROR_PARSING_TLB_LOC  "Typelib has no description? ;    Error parsing TLB." #DEFINE D_CANNOT_FIND_FILE_LOC  "Cannot find file '%s'." #DEFINE D_BACKUP_FILENAME_POSTFIX  "_ORIG_LCID.TLB"

* Non-localizable definitions #DEFINE LANG_NEUTRAL 0x0000 #DEFINE D_OBJECT_DEF_MARKER  "*\Rffff*#"

*****************************************  *  Code begins *****************************************  LPARAMETERS cDLLName, nLCID LOCAL cLCID, cTLBContents, nTypeLibDesc, nDescLength, nLangIDLocation LOCAL cOldSafety, cTargetFileName, nLastMarker, nOffset

* If no filename passed, prompt for a file. IF PCOUNT < 1 cDLLName = "*.DLL" cDLLName = GETFILE("DLL,TLB", D_GETFILE_CAPTION_LOC) IF EMPTY(cDLLName) * User pressed cancel. RETURN .f.     ENDIF ENDIF

* If no LCID passed, assume LANG_NEUTRAL (0x0000). IF PCOUNT < 2 nLCID = LANG_NEUTRAL ENDIF

* Convert it to a two-byte string, with the low byte first. cLCID = CHR(BITAND(nLCID, 0xFF)) + ; CHR(BITRSHIFT(BITAND(nLCID, 0xFF00),8))

* If not a TLB file, replace the extension with .tlb. IF ! UPPER(RIGHT(ALLTR(cDLLName), 4)) = ".TLB" cDLLName = AddBS(JustPath(cDLLName)) + JustStem(cDllName) + ".TLB" IF NOT FILE(cDLLName) Messagebox(STRTRAN(D_CANNOT_FIND_FILE_LOC, "%s", cDllName)) RETURN .F.     ENDIF ENDIF

* TLBs are never huge, so just use FILETOSTR instead of FOPEN, and so   *  forth. cTLBContents = FILETOSTR(cDllName) IF TYPE("cTLBContents") # "C" OR EMPTY(cTLBContents) Messagebox(D_NO_TLB_LOC) RETURN .F.  ENDIF

* Find TypeLib Description, which is just past the last * occurrence of *\Rffff*#. Actually, if there are more than 15 * COM objects in the DLL, the number (written in ascii) that * comes just past the # can be more than one digit, * so we need to count from the eszet (0xDF) that comes just after. nLastMarker = RAT(D_OBJECT_DEF_MARKER, cTLBContents) nOffset = AT(CHR(0xDF), SUBSTR(cTLBContents, nLastMarker, 20)) nTypeLibDesc = nLastMarker + nOffset + 97

* Assume description will not be more that 255 bytes, so only read one * byte of length field. nDescLength = ASC(SUBSTR(cTLBContents, nTypeLibDesc, 1)) IF nDescLength = 0 Messagebox(D_ERROR_PARSING_TLB_LOC) RETURN .F.  ENDIF

* Now that you have the description length, you know exactly * where the LCID is written. nLangIDLocation = nTypeLibDesc + nDescLength + 10

* Back up original file. cOldSafety = SET("SAFETY") SET SAFETY OFF cTargetFileName = ADDBS(JUSTPATH(cDllName)) + JUSTSTEM(cDLLNAME) +; D_BACKUP_FILENAME_POSTFIX ERASE (cTargetFileName) RENAME (cDLLName) TO (cTargetFileName)

* Now, write your file. STRTOFILE(LEFT(cTLBContents, nLangIDLocation - 1) + cLCID + ;        SUBSTR(cTLBContents, nLangIDLocation + 2), cDLLName)

* Restore environment settings. SET SAFETY &cOldSafety

RETURN .T.  ** End program code ** After you build a Visual FoxPro COM object, you can call the Tag_TLB_LCID program to stamp the type library with the language neutral LCID using the following syntax: DO Tag_TLB_LCID WITH " " This functionality could be implemented using a project hook class. Use the AfterBuild event of the project hook class to make the sample program call.



STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.



Steps to Reproduce Behavior
 BUILD DLL foxsrch FROM HOME(2) + "servers\gopher\foxsrch.pjx". In the Control Panel, click Regional Settings. Choose a different Regional Setting, and click OK.  Run the following code: ox=NewObject("foxsrch.gopher") ox.updatede RESULT: The following error message appears:

OLE error code 0x8002801d: Library not registered.



Keywords: kbbug kbpending KB195261

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.