home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 1_2002.ISO / Data / Zips / CODE_UPLOAD103621022000.psc / REGISTRY.BAS < prev    next >
Encoding:
BASIC Source File  |  2000-08-10  |  17.0 KB  |  483 lines

  1. Attribute VB_Name = "Registry_Management"
  2. ' Registry management
  3.  
  4. '
  5. '
  6. ' Handling of registry data types is limited.
  7. ' Only the simple string & longint types are supported as yet
  8. '
  9. '
  10. '
  11.  
  12. Option Explicit
  13.  
  14.  
  15.  
  16.  
  17. ' Get the format into ".XXX"
  18. '
  19. Private Function FormatFileExtensionForRegistry$(pExtension$)
  20.  
  21. Dim lExtension$
  22.  
  23.  
  24.   lExtension$ = pExtension$
  25.   If (left$(lExtension$, 1) <> ".") Then lExtension$ = "." & lExtension$
  26.   lExtension$ = LCase$(left$(lExtension$, 4))
  27.   
  28.   FormatFileExtensionForRegistry$ = lExtension$
  29. End Function
  30.  
  31. ' A function in the spirit of GetPrivateProfileString(),
  32. ' but using the Registry.
  33. '
  34. ' Registry usage should comply with the recommendations
  35. ' in the Win '95 Interface Guidelines
  36. '
  37. Public Function GetPrivateRegistryString$(ByVal pKey As Long, pSectionName As String, pEntryName As String, pDefault As String)
  38. Attribute GetPrivateRegistryString.VB_Description = "Simple replacement for GetPrivateProfileString()"
  39.  
  40.   GetPrivateRegistryString = GetRegistryString(pKey, GetRegistryKeyNameForApp$() & "\" & pSectionName, pEntryName, pDefault)
  41. End Function
  42.  
  43.  
  44.  
  45. ' Find the "Server" or "Open" app
  46. '
  47. ' pFindServer is true for the server, false for the Open command
  48. '
  49. ' NB - pExe$ will probably include command line parameters of "%1" substitution parameters
  50. ' particularly for the "Open" item
  51. '
  52. ' Where there is more than one document type registered to this extension,
  53. ' the default type will be returned
  54. '
  55. Function GetRegistryAppByExtension(pExtension$, pExe$, ByVal pFindServer As Boolean) As Long
  56.  
  57. Dim lExtension$
  58.  
  59. Dim lRetVal As Long
  60. Dim lhExtensionKey As Long, lhOpenKey As Long
  61. Dim lProgID$
  62.  
  63.  
  64.   lRetVal = ERROR_SUCCESS
  65.   pExe$ = ""
  66.   
  67.   ' Get the format into ".XXX"
  68.   lExtension$ = FormatFileExtensionForRegistry$(pExtension$)
  69.   
  70.     
  71.   ' Use the extension to find ProgID, then try to find the default property of
  72.   ' either HKEY_CLASSES_ROOT\ProgID\shell\open\command
  73.   ' or HKEY_CLASSES_ROOT\ProgID\protocol\StdFileEditing\server
  74.   lRetVal = RegOpenKey(HKEY_CLASSES_ROOT, lExtension$, KEY_READ, lhExtensionKey)
  75.   If (lRetVal = ERROR_SUCCESS) Then lRetVal = RegQueryValue(lhExtensionKey, "", lProgID$)
  76.   If (lRetVal = ERROR_SUCCESS) Then
  77.     If pFindServer Then
  78.       lRetVal = RegOpenKey(HKEY_CLASSES_ROOT, lProgID$ & "\protocol\StdFileEditing\server", KEY_READ, lhOpenKey)
  79.     Else
  80.       lRetVal = RegOpenKey(HKEY_CLASSES_ROOT, lProgID$ & "\shell\open\command", KEY_READ, lhOpenKey)
  81.     End If
  82.   End If
  83.   If (lRetVal = ERROR_SUCCESS) Then lRetVal = RegQueryValue(lhOpenKey, "", pExe$)
  84.   
  85.   GetRegistryAppByExtension = lRetVal
  86. End Function
  87.  
  88. ' A function in the spirit of GetPrivateProfileString() et al,
  89. ' but using the Registry.
  90. '
  91. ' Registry usage should comply with the recommendations
  92. ' in the Win '95 Interface Guidelines
  93. '
  94. Public Function GetRegistryLong(ByVal pKey As Long, pKeyName As String, pValueName As String, pDefault As Long) As Long
  95.   
  96. Dim llRetVal As Long
  97. Dim lhOurKey As Long
  98. Dim pValue As Variant
  99.  
  100.   
  101.   GetRegistryLong = pDefault
  102.   
  103.   llRetVal = RegOpenKey(pKey, pKeyName, KEY_READ, lhOurKey)
  104.   If (llRetVal = ERROR_SUCCESS) Then llRetVal = RegQueryValue(lhOurKey, pValueName, pValue)
  105.   If (llRetVal = ERROR_SUCCESS) Then
  106.     ' KLUDGE - This is an implicit assumption about the type of data returned
  107.     ' Need to clarify how RegQueryValue works under these circumstances
  108.     GetRegistryLong = pValue
  109.   End If
  110.   
  111. End Function
  112.  
  113. ' Read a string value from the registry
  114. '
  115. ' Registry usage should comply with the recommendations
  116. ' in the Win '95 Interface Guidelines
  117. '
  118. Public Function GetRegistryString$(ByVal pKey As Long, pKeyName As String, pValueName As String, pDefault As String)
  119. Attribute GetRegistryString.VB_Description = "Simple replacement for GetProfileString()"
  120.   
  121. Dim llRetVal As Long
  122. Dim lhOurKey As Long
  123. Dim pValue As Variant
  124.  
  125.   
  126.   GetRegistryString$ = pDefault
  127.   
  128.   llRetVal = RegOpenKey(pKey, pKeyName, KEY_READ, lhOurKey)
  129.   If (llRetVal = ERROR_SUCCESS) Then llRetVal = RegQueryValue(lhOurKey, pValueName, pValue)
  130.   If (llRetVal = ERROR_SUCCESS) Then GetRegistryString$ = pValue
  131.   
  132. End Function
  133.  
  134.  
  135. ' Loads a form's position from the registry
  136. ' Complementary to SaveFormPosition
  137. '
  138. ' To use this, the form must have its Tag property set
  139. '
  140. ' Errors are returned, but most may be ignored
  141. '
  142. ' Positions are stored under:
  143. ' HKEY_CURRENT_USER\Software\App.CompanyName\App.Title\pForm.Tag\X, Y, cX, cY
  144. '
  145. Public Function LoadFormPosition(pForm As Form) As Long
  146. Attribute LoadFormPosition.VB_Description = "Makes a form's position ""sticky"""
  147.  
  148. Dim llRetVal As Long
  149. Dim lKeyName$
  150.  
  151. Dim X As Long, Y As Long, cx As Long, cy As Long
  152.  
  153.  
  154.   llRetVal = ERROR_SUCCESS
  155.   
  156.   ' Tag property must be set
  157.   If (Len(pForm.Tag) = 0) Then llRetVal = ERROR_BADKEY
  158.   
  159.   If (llRetVal = ERROR_SUCCESS) Then
  160.     lKeyName$ = GetRegistryKeyNameForApp$() & "\Form Positions\" & pForm.Tag
  161.     pForm.WindowState = GetRegistryLong(HKEY_CURRENT_USER, lKeyName$, "WindowState", pForm.WindowState)
  162.   End If
  163.   If (llRetVal = ERROR_SUCCESS) Then X = GetRegistryLong(HKEY_CURRENT_USER, lKeyName$, "X", pForm.left)
  164.   If (llRetVal = ERROR_SUCCESS) Then Y = GetRegistryLong(HKEY_CURRENT_USER, lKeyName$, "Y", pForm.top)
  165.   If (llRetVal = ERROR_SUCCESS) Then cx = GetRegistryLong(HKEY_CURRENT_USER, lKeyName$, "cX", pForm.Width)
  166.   If (llRetVal = ERROR_SUCCESS) Then cy = GetRegistryLong(HKEY_CURRENT_USER, lKeyName$, "cY", pForm.Height)
  167.   
  168.   If (llRetVal = ERROR_SUCCESS) Then
  169.     cx = Minimum(Maximum(cx, 32), Screen.Width)
  170.     cy = Minimum(Maximum(cy, 32), Screen.Height)
  171.     X = Minimum(Maximum(X, 0), (Screen.Width - cx))
  172.     Y = Minimum(Maximum(Y, 0), (Screen.Height - cy))
  173.   End If
  174.   
  175.   If (llRetVal = ERROR_SUCCESS) Then
  176.     pForm.Width = cx
  177.     pForm.Height = cy
  178.     pForm.left = X
  179.     pForm.top = Y
  180.   End If
  181.   
  182.   LoadFormPosition = llRetVal
  183. End Function
  184.  
  185. ' A function in the spirit of PutPrivateProfileString(),
  186. ' but using the Registry.
  187. '
  188. ' Returns usual Windows error codes
  189. '   =0 (ERROR_SUCCESS) is OK
  190. '  <>0 is a failure
  191. '
  192. ' Registry usage should comply with the recommendations
  193. ' in the Win '95 Interface Guidelines
  194. '
  195. Public Function PutPrivateRegistryString(ByVal pKey As Long, pSectionName As String, pEntryName As String, pValue As String) As Long
  196. Attribute PutPrivateRegistryString.VB_Description = "Simple replacement for PutPrivateProfileString()"
  197.   
  198.   PutPrivateRegistryString = PutRegistryString(pKey, GetRegistryKeyNameForApp$() & "\" & pSectionName, pEntryName, pValue)
  199. End Function
  200.  
  201.  
  202. ' A function in the spirit of PutPrivateProfileString(),
  203. ' but using the Registry.
  204. '
  205. ' Returns usual Windows error codes
  206. '   =0 (ERROR_SUCCESS) is OK
  207. '  <>0 is a failure
  208. '
  209. ' Registry usage should comply with the recommendations
  210. ' in the Win '95 Interface Guidelines
  211. '
  212. Public Function PutPrivateRegistryLong(ByVal pKey As Long, pSectionName As String, pEntryName As String, pValue As Long) As Long
  213.   
  214.   PutPrivateRegistryLong = PutRegistryLong(pKey, GetRegistryKeyNameForApp$() & "\" & pSectionName, pEntryName, pValue)
  215. End Function
  216.  
  217. ' A function in the spirit of PutPrivateProfileString() et al,
  218. ' but using the Registry.
  219. '
  220. ' Returns usual Windows error codes
  221. '   =0 (ERROR_SUCCESS) is OK
  222. '  <>0 is a failure
  223. '
  224. ' Registry usage should comply with the recommendations
  225. ' in the Win '95 Interface Guidelines
  226. '
  227. Public Function PutRegistryLong(ByVal pKey As Long, pKeyName As String, pValueName As String, pLongValue As Long) As Long
  228.  
  229. Dim llRetVal As Long
  230. Dim lhOurKey As Long
  231.  
  232.  
  233.   ' Construct new keys as necessary
  234.   llRetVal = RegCreateKey(pKey, pKeyName, lhOurKey)
  235.   
  236.     ' Insert our value
  237.   If (llRetVal = ERROR_SUCCESS) Then llRetVal = RegSetValue(lhOurKey, pValueName, REG_DWORD, pLongValue)
  238.   
  239.   ' Close the key. This will cause Windows to flush it, but not immediately
  240.   If (llRetVal = ERROR_SUCCESS) Then llRetVal = RegCloseKey(lhOurKey)
  241.   PutRegistryLong = llRetVal
  242. End Function
  243.  
  244. ' Save an "application path" for an application
  245. '
  246. '   Parameters:
  247. ' pAppName$   Identifier - application's EXE name, "MyApp.EXE"
  248. '
  249. ' pAppEXE$    Full path & filename to the executable
  250. '
  251. ' pAppPath$   Path entries to be added to the PATH when the executable is run
  252. '             A suffix of ";" will be appended if necessary
  253. '
  254. ' If either of the entries is an empty string, that value will not be written to the registry
  255. '
  256. ' If both entries are empty strings, the key will be removed
  257. '
  258. Public Function SaveRegistryAppPath(pAppName$, pAppEXE$, pAppPath$) As Long
  259. Attribute SaveRegistryAppPath.VB_Description = "Register an application path"
  260.  
  261. Dim lRetVal As Long
  262. Dim lKey$
  263.  
  264.  
  265.   lKey$ = "Software\Microsoft\Windows\CurrentVersion\App Paths\" & pAppName$
  266.   
  267.   
  268.   lRetVal = ERROR_SUCCESS
  269.   
  270. '  If (lRetVal = ERROR_SUCCESS) Then
  271.     If (Len(pAppEXE$) > 0) Then
  272.       lRetVal = PutRegistryString(HKEY_LOCAL_MACHINE, lKey$, "", pAppEXE$)
  273.     Else
  274.       lRetVal = RegDeleteValue(HKEY_LOCAL_MACHINE, lKey$, "")
  275.     End If
  276. '  End If
  277.   
  278.   If (lRetVal = ERROR_SUCCESS) Then
  279.     If (Len(pAppPath$) > 0) Then
  280.       lRetVal = PutRegistryString(HKEY_LOCAL_MACHINE, lKey$, "Path", pAppPath$ & IIf((right$(pAppPath$, 1) <> ";"), ";", ""))
  281.     Else
  282.       lRetVal = RegDeleteValue(HKEY_LOCAL_MACHINE, lKey$, "Path")
  283.     End If
  284.   End If
  285.   
  286.   If (lRetVal = ERROR_SUCCESS) Then
  287.     If (Len(pAppEXE$) = 0) And (Len(pAppPath$) = 0) Then
  288.       lRetVal = RegDeleteKey(HKEY_LOCAL_MACHINE, lKey$)
  289.     End If
  290.   End If
  291.   
  292.   SaveRegistryAppPath = lRetVal
  293. End Function
  294.  
  295. ' Save an association for a file extension,
  296. ' i.e. the application used to open files of this type
  297. '
  298. ' If either pOpenCommand$ or pIconPath$ are empty,
  299. ' that section will be ignored
  300. '
  301. Public Function SaveRegistryAssociation(pExtension$, pProgID$, _
  302.   pOpenCommand$, _
  303.   pIconPath$, pIconNumber%) As Long
  304.  
  305. Dim lExtension$
  306. Dim lRetVal As Long
  307. Dim lhKey As Long, lhSubKey As Long
  308.  
  309.   
  310.   lRetVal = ERROR_SUCCESS
  311.  
  312.   lExtension$ = FormatFileExtensionForRegistry$(pExtension$)
  313.   
  314.   ' Check the extension & ProgID for validity
  315.   If Not ((Len(lExtension$) > 0) And (Len(pProgID$) > 0)) Then
  316.     lRetVal = ERROR_BADKEY
  317.   End If
  318.   
  319.   ' Associate the extension with a ProgID
  320.   If (lRetVal = ERROR_SUCCESS) Then
  321.     lRetVal = RegCreateKey(HKEY_CLASSES_ROOT, lExtension$, lhKey)
  322.     If (lRetVal = ERROR_SUCCESS) Then lRetVal = RegSetValue(lhKey, "", REG_SZ, pProgID$)
  323.   End If
  324.   
  325.   ' Save attributes for the ProgID
  326.   If (lRetVal = ERROR_SUCCESS) Then
  327.     lRetVal = RegCreateKey(HKEY_CLASSES_ROOT, pProgID$, lhKey)
  328.     
  329.     ' Open
  330.     If (lRetVal = ERROR_SUCCESS) And (Len(pOpenCommand$) > 0) Then
  331.       lRetVal = RegCreateKey(lhKey, "Shell\Open\Command", lhSubKey)
  332.       If (lRetVal = ERROR_SUCCESS) Then lRetVal = RegSetValue(lhSubKey, "", REG_SZ, pOpenCommand$)
  333.     End If
  334.     
  335.     ' Icon
  336.     If (lRetVal = ERROR_SUCCESS) And (Len(pIconPath$) > 0) Then
  337.       lRetVal = RegCreateKey(lhKey, "DefaultIcon", lhSubKey)
  338.       If (lRetVal = ERROR_SUCCESS) Then lRetVal = RegSetValue(lhSubKey, "", REG_SZ, pIconPath$ & "," & CStr(pIconNumber%))
  339.     End If
  340.   End If
  341.  
  342.   SaveRegistryAssociation = lRetVal
  343. End Function
  344.  
  345.  
  346. ' Store a setting in the Registry,
  347. ' such that the current application will be NOT be re-started
  348. '
  349. Public Function SaveRegistryDontRunAppAfterRestart() As Long
  350. Attribute SaveRegistryDontRunAppAfterRestart.VB_Description = "Cancels SaveRegistryRunAppAfterRestart()"
  351.   
  352.   SaveRegistryDontRunAppAfterRestart = SaveRegistryRunAtStartup(App.Title, "", True, False)
  353. End Function
  354.  
  355.  
  356. ' Store a setting in the Registry,
  357. ' such that the current application will be re-started
  358. '
  359. Public Function SaveRegistryRunAppAfterRestart(pParameters$) As Long
  360. Attribute SaveRegistryRunAppAfterRestart.VB_Description = "Sets current application to restart automatically when Windows is restarted"
  361.   
  362.   SaveRegistryRunAppAfterRestart = SaveRegistryRunAtStartup(App.Title, App.Path & "\" & App.EXEName & ".EXE " & pParameters$, True, False)
  363. End Function
  364.  
  365. ' Save a setting in the Run or RunOnce section of the Registry,
  366. ' such that an executable will be run at next Windows startup
  367. '
  368. ' See Reference [1], pp239-240
  369. '
  370. '
  371. ' pValueName is descriptive, but generally ignored by Windows
  372. ' It must be unique, so may need to have a numeric suffix (or similar) appended to it when needed
  373. '
  374. ' pValue is the path to the executable that will be run
  375. ' when Windows next starts, including a full path and any parameters
  376. '
  377. ' pRunOnce is True for executables that should only be run on the next startup
  378. ' False when they should be run every time Windows starts
  379. '
  380. ' pService will usually be false. It is only true for executables
  381. ' that are run before Windows starts (i.e. system functions such as virus scanners)
  382. '
  383. Public Function SaveRegistryRunAtStartup(pValueName$, pValue$, _
  384.     ByVal pRunOnce As Boolean, pService As Boolean) As Long
  385. Attribute SaveRegistryRunAtStartup.VB_Description = "Sets an application to be run when Windows restarts"
  386.  
  387. Dim lhKey As Long, lKey$
  388.  
  389.  
  390.   lhKey = IIf(pService, HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER)
  391.   lKey$ = "Software\Microsoft\Windows\CurrentVersion\" & IIf(pRunOnce, "RunOnce", "Run")
  392.   
  393.   SaveRegistryRunAtStartup = PutRegistryString(lhKey, lKey$, pValueName$, pValue$)
  394. End Function
  395.  
  396.  
  397.  
  398. ' Store a string value anywhere in the registry
  399. ' The key chain will be built if necessary
  400. '
  401. ' Returns usual Windows error codes
  402. '   =0 (ERROR_SUCCESS) is OK
  403. '  <>0 is a failure
  404. '
  405. ' Registry usage should comply with the recommendations
  406. ' in the Win '95 Interface Guidelines
  407. '
  408. Public Function PutRegistryString(ByVal pKey As Long, pKeyName As String, pValueName As String, pStringValue As String) As Long
  409. Attribute PutRegistryString.VB_Description = "Simple replacement for PutProfileString()"
  410.  
  411. Dim llRetVal As Long
  412. Dim lhOurKey As Long
  413.  
  414.  
  415.   ' Construct new keys as necessary
  416.   llRetVal = RegCreateKey(pKey, pKeyName, lhOurKey)
  417.   
  418.     ' Insert our value
  419.   If (llRetVal = ERROR_SUCCESS) Then llRetVal = RegSetValue(lhOurKey, pValueName, REG_SZ, pStringValue$)
  420.   
  421.   ' Close the key. This will cause Windows to flush it, but not immediately
  422.   If (llRetVal = ERROR_SUCCESS) Then llRetVal = RegCloseKey(lhOurKey)
  423.   PutRegistryString = llRetVal
  424. End Function
  425.  
  426.  
  427.  
  428. ' Returns the suggested key name for this application's setting
  429. '
  430. ' i.e. "Software\Codesmiths\RegistryProgram"
  431. '
  432. Public Function GetRegistryKeyNameForApp$()
  433. Attribute GetRegistryKeyNameForApp.VB_Description = "Returns a suggested Registry sub-key for this application"
  434.  
  435. Dim lSniff$, lFullLen%, lChopLen%
  436.  
  437. Dim lCompanyName$
  438. Dim lAppName$
  439. Dim lAppVersion$
  440. Dim lWork$
  441.  
  442.  
  443.   ' Company name
  444.   lCompanyName$ = App.CompanyName
  445.   
  446.   ' Chop off any trailing "Ltd." (which must have a space before it)
  447.   lFullLen% = Len(lCompanyName$)
  448.   lChopLen% = 0
  449.   If (right$(lCompanyName$, 1) = ".") Then lChopLen% = 1
  450.   lSniff$ = UCase$(Mid$(lCompanyName$, lFullLen% - (lChopLen% + 2), 3))
  451.   If (lSniff$ = " CO") Then
  452.     lChopLen% = lChopLen% + 3
  453.   Else
  454.     lSniff$ = UCase$(Mid$(lCompanyName$, lFullLen% - (lChopLen% + 3), 4))
  455.     If (lSniff$ = " LTD") Or (lSniff$ = " INC") Or (lSniff$ = " PLC") Then
  456.     Sniff$ = " INC") Or (lSnifff$opL lKey$ = "Softwarp.VB_ 1
  457.   lSniff$ = UCase$ UCase$ UCase$ UCase$ UCasy. oe$ Uniff$ = "AlSnifEElse
  458.       lRetimum(Maximum(cx, 32), Screen.Width)
  459.     cy = Minimum(Maximum(cy, 32), Scre 1
  460.   lSin willaMX), ryLong = PutRegistryLongtm(cy.Widt, 32, 32), Scre 1
  461.   lSin wi3))eSLong = pViyLongtm(cyoAs Long
  462. "nyName$, tyegistryxey, pKeyName, lhOurKey)
  463.   
  464.     ' Insert our value
  465.   IEaWf$ X If (riNeSniff$ = " LTD") Or (lSniff$ = " INC") Or (lSniff$ = " PLC") Then
  466.     Sniase$ UCase$ UCName
  467.   
  468.   ' Chop ofee") TheneTe2_im lhKey As LonionNamlhSubKgistv riNeSniff$ = " LTD")me$, pValue$, _
  469.     ByVal pRunOnce As Booleanaid key nWinle,Dll causepm$iE$ m(Maximum(cy, 32), Scre 1
  470.   lSin wiLe As Booleanaid key nWinleeMe should comply stryxeA3), = SaHfrningVar "nBmtAlSnifEElse
  471.       lRetimum(Me Win '95 Interface GuideGui3v "te t " PLC") Then
  472.     Sniase$ UCase$ UCName
  473.   
  474.   ' $, _
  475.     ByVaTYlse
  476.       lRetimum(Me Win '
  477.       lRdideGu, REG_SZ, pIconPath$ e Win '
  478.       lRdideN i.en = eol
  479. '
  480. ' Rpeply "ets arRdideGu, REZlSniff$ = " PLC") ThtCas = " PLC") ThtCas =ly "ets arRdideGu, REZlSniff$ = " PLC") ThtCas = "lsliuld comply9iEZlSnrnifflureidideG)eSLey(CPLC") ThtCas =ly "ets arRdideGu, REZlSniff$ = " PLC") ThtCas = "lsliuld comply9iEZlSnrnifflureidideG)eSLey(CPLC") ThtCas =ly "ets arRdideGu, REZlSniff$ = " PLC") ThtCas = "lsliuld comply9iEZlSnrnifflureidiZlSnrnrnifflureidiZlSClChopLen%ipmy igCPLC") TrlSniff$ = " PLC")lChopLen%ipmy ig e Wy i " INt  
  481.   'en%ioiC")lCA REZlSiTZlSnrnrnifflureid1c0ets arRdideGu, REZlSniff$ = " d key nWi'en%ioiC")sliTrlSniff"as =ly "ets arRdideGu, REZu$ =TD") Or (lSniff$ = " INC")R)sliTrlSniff"as =ly "ets ar 1s,EZu$ =TD"en%ioiC")sliTrlSni = " INGu,$sliTrlSniff"as =ly "ets ar 1conPpLC"conPsisliTrlSnPLC
  482.   pOTryLonureidiZlSnf"as sliTrlSniff"nersnten%ii.n " INGu,nff$en%iiff"  p;nusRg(letVal
  483. E = " P ryLong =C"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c"c