├── .gitattributes
├── .gitignore
├── Debug
├── Module1.bas
├── Proyecto1.exe.manifest
├── Proyecto1.vbp
├── Proyecto1.vbw
└── clsTestClass.cls
├── openmsvbvm.sln
└── openmsvbvm
├── ClassFactory.cpp
├── ClassFactory.h
├── DllObjectInterface.cpp
├── DllObjectInterface.h
├── README.md
├── Resource.rc
├── Source.def
├── dllmain.cpp
├── openmsvbvm.vcxproj
├── openmsvbvm.vcxproj.filters
├── resource.h
├── vba_Arrays.cpp
├── vba_CommandLine.cpp
├── vba_CommandLine.h
├── vba_DateManipulation.cpp
├── vba_DllFunctionCall.cpp
├── vba_File.cpp
├── vba_InputBox.cpp
├── vba_InteractionFunctions.cpp
├── vba_Locale.cpp
├── vba_Locale.h
├── vba_MessageBox.cpp
├── vba_Settings.cpp
├── vba_enums.h
├── vba_exception.cpp
├── vba_exception.h
├── vba_exceptions.cpp
├── vba_internal.h
├── vba_internal_coordinates.h
├── vba_internal_includes.h
├── vba_objApp.cpp
├── vba_objApp.h
├── vba_objApp.idl
├── vba_objApp_h.h
├── vba_objManipulation.cpp
├── vba_objManipulation.h
├── vba_objVBGlobal.cpp
├── vba_objVBGlobal.h
├── vba_objVBGlobal.idl
├── vba_objVBGlobal_h.h
├── vba_ole_bridge_macros.h
├── vba_strComparation.cpp
├── vba_strConversion.cpp
├── vba_strManipulation.cpp
├── vba_strManipulation.h
├── vba_structures.h
├── vba_varManipulation.cpp
└── vba_varManipulation.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | # Removed, so we can have a VB6 test project there [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
262 |
263 | openmsvbvm/[Dd]ebug/
264 | openmsvbvm/[Rr]elease/
--------------------------------------------------------------------------------
/Debug/Module1.bas:
--------------------------------------------------------------------------------
1 | Attribute VB_Name = "Module1"
2 | Option Explicit
3 |
4 | Private Declare Function GetVersion Lib "kernel32" () As Long
5 | Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
6 | Private Declare Function MessageBoxW Lib "user32" (ByVal hwnd As Long, ByVal lpText As Long, ByVal lpCaption As Long, ByVal wType As Long) As Long
7 | Private Declare Function MessageBeep Lib "user32" (ByVal wType As Long) As Long
8 |
9 |
10 | Private Declare Sub InitCommonControls Lib "comctl32" ()
11 |
12 | Private Type tTest
13 | sString As String
14 | 'sFixedString As String * 30
15 | lLong As Long
16 | iInteger As Integer
17 | End Type
18 |
19 | Sub Main()
20 | 'Call InitCommonControls
21 |
22 | Call OnErrorGotoTest
23 |
24 | 'Call OnErrorResumeNextTest
25 |
26 | 'Call FPExceptionTest
27 |
28 | 'Call DllStringCallTest
29 |
30 | 'Call MsgboxReturnCodeTest
31 |
32 | 'Call StrCompTest
33 |
34 | 'Dim s As String
35 | 's = Replace$("This is a test", "test", "sample")
36 | 'MsgBox s
37 |
38 | 'Call ObjectCreateTest
39 |
40 | 'Call DateTest
41 |
42 | 'Call InputBoxTest
43 |
44 | 'Call ToStringConversionTest
45 |
46 | 'Call ObjectAppInteractionTest
47 |
48 | 'Call FileManipulationTest
49 |
50 | 'Call StringCopyTest
51 |
52 | 'Call ClassCreationTest
53 |
54 | 'Call ArraysTest
55 |
56 | 'Call VBAInteractionTest
57 |
58 | 'Call llmul
59 |
60 | Debug.Print "ASD"
61 |
62 | MsgBox "END"
63 | End Sub
64 |
65 | Private Sub llmul()
66 | Dim a As Currency
67 | Dim b As Currency
68 | Dim c As Currency
69 | a = -1.3333@
70 | b = 1.2@
71 | c = a * b
72 | 'MsgBox c
73 | End Sub
74 | Private Sub ArraysTest()
75 | 'Dim strArray() As String
76 | 'ReDim strArray(36)
77 | 'strArray(0) = "One"
78 | 'strArray(1) = "Two"
79 | 'strArray(2) = "Three"
80 | 'ReDim Preserve strArray(69)
81 | 'strArray(3) = "Four"
82 | 'MsgBox strArray(3)
83 | 'MsgBox "UBound() = " & UBound(strArray) & " - LBound() = " & LBound(strArray)
84 |
85 |
86 | Dim tUDTArray(30) As tTest
87 | 'ReDim tUDTArray(30)
88 | 'tUDTArray(0).sFixedString = "HAHAHA"
89 | With tUDTArray(0)
90 | .lLong = &HC0C0C0C0
91 | .sString = "string"
92 | End With
93 |
94 | With tUDTArray(0)
95 | MsgBox "tUDTArray(0)" & vbCrLf & _
96 | vbTab & ".sString = '" & .sString & "'" & vbCrLf & _
97 | vbTab & ".lLong = " & Hex(.lLong)
98 | End With
99 | End Sub
100 |
101 | Private Sub VBAInteractionTest()
102 | 'VBA.AppActivate "Debug", 300
103 | 'VBA.Beep
104 | Dim s(4) As Variant
105 | s(0) = "Zero"
106 | s(1) = "One"
107 | s(2) = "Two"
108 | s(3) = "Three"
109 | MsgBox VBA.Choose(2147483600, "Zero", "One", "Two", "Three")
110 | 'MsgBox "Command() = " & Command() & vbCrLf & "Command$() = " & Command$()
111 | 'SaveSetting "ItsMeMario", "Section", "Key", "Setting"
112 | 'MsgBox "GetSetting = " & GetSetting("ItsMeMario", "Section", "Key") ', "ThisIsADefaultValue")
113 | 'DeleteSetting "ItsMeMario", "Section", "Key"
114 | 'MsgBox Environ("TMP") '("TMP")
115 | 'MsgBox IIf(0, Environ("TMP"), Environ("PATH"))
116 | 'MsgBox Partition(10, 0, 100, 5)
117 | 'SendKeys "A", 333
118 | 'MsgBox Switch(False, "should not happen 1", False, "should not happen 2", True, "Yes!!")
119 | End Sub
120 |
121 | Private Sub OnErrorGotoTest()
122 | On Error GoTo fnErrHandler
123 | 'On Error Resume Next
124 | MsgBox "This should happen"
125 | MsgBox 1 / 0
126 | fnNonErrHandler:
127 | MsgBox "This should not be visible"
128 | fnErrHandler:
129 | MsgBox "OnErrorTest() end"
130 | End Sub
131 |
132 | Private Sub OnErrorResumeNextTest()
133 | 'On Error Resume Next
134 | MsgBox "This should happen"
135 | MsgBox 1 / 0
136 | fnNonErrHandler:
137 | MsgBox "This should not be visible"
138 | fnErrHandler:
139 | MsgBox "OnErrorTest() end"
140 | End Sub
141 |
142 | Private Sub MsgboxReturnCodeTest()
143 | Select Case MsgBox("Just a messagebox and the command is " & Command$, vbInformation + vbYesNoCancel, "Just the title")
144 | Case vbYes: MsgBox UCase$("Yes"): Shell "calc"
145 | Case vbNo: MsgBox LCase$("No")
146 | Case vbCancel: MsgBox "Cancel"
147 | End Select
148 | End Sub
149 |
150 | Private Sub StringCaseTest()
151 | MsgBox LCase$("LCASE") & " " & UCase$("ucase")
152 | End Sub
153 |
154 | Private Sub StrCompTest()
155 | Dim l As Long
156 | l = StrComp("lcase", "XXXCASE") ', vbTextCompare)
157 | MsgBox "strcomp = " & l
158 | End Sub
159 |
160 | Private Sub DllStringCallTest()
161 | MessageBox 0, "Testing", "Title", vbOK
162 | End Sub
163 |
164 | Private Sub FPExceptionTest()
165 | 'MsgBox 2147483647 + 1
166 | MsgBox 1 / 0
167 | End Sub
168 |
169 | Private Sub DateTest()
170 | Dim t As Date
171 | t = Now
172 | MsgBox "asd " & t
173 | End Sub
174 |
175 | Private Sub ClassCreationTest()
176 | Dim j As clsTestClass3
177 | Set j = New clsTestClass3
178 | 'j.Pelotudo True
179 | 'MsgBox "delay?"
180 | 'j.Exported2
181 | 'j.SetTrue
182 | 'j.Exported2
183 | 'j.SetFalse
184 | 'j.Exported2
185 |
186 | j.SetString "TESTTTTTTTT!!!!!"
187 | j.MsgboxString True
188 |
189 | Set j = Nothing
190 |
191 | End Sub
192 |
193 | Private Sub StringCopyTest()
194 | Dim s As String
195 | Dim s2 As String
196 | s = "This is S"
197 | s2 = s
198 | MsgBox s2
199 | End Sub
200 |
201 | Private Sub FileManipulationTest()
202 | Dim l As Long
203 | Open "file-wb.txt" For Binary Access Write As #69
204 | 'Put #69, , "string"
205 | 'Put #69, , &HC0C0
206 | Put #69, , &HC0C0C0C0
207 | 'Put #69, , 1.11113
208 | Close #69
209 |
210 | 'Open "file-rb.txt" For Binary Access Read As #69
211 | Open "file-wb.txt" For Binary Access Read As #69
212 | Get #69, , l
213 |
214 | 'MsgBox l & " and should be " & &HC0C0C0C0
215 |
216 | MsgBox "Fsize = " & LOF(69)
217 | Seek 69, 1
218 |
219 | Close #69
220 | Exit Sub
221 |
222 |
223 | Open "file-rwb.txt" For Binary Access Read Write As #69
224 | Close #69
225 |
226 | Open "file-out.txt" For Output As #69
227 | Close #69
228 |
229 | Open "file-in.txt" For Input As #69
230 | Close #69
231 |
232 | Open "file-rand.txt" For Random As #69
233 | Close #69
234 |
235 | Open "file-out-w.txt" For Output Access Write As #69
236 | Close #69
237 |
238 | Open "file-in-r.txt" For Input Access Read As #69
239 | Close #69
240 |
241 | Open "file-rand.txt" For Random As #69
242 | Close #69
243 | End Sub
244 |
245 | Private Sub InputBoxTest()
246 | MsgBox InputBox$("This is the caption of the inputbox", 123456789, "this should be the default value", , , "HelpFile", 6969), vbInformation + vbOKOnly
247 | End Sub
248 |
249 | Private Sub ToStringConversionTest()
250 | MsgBox CStr(True) & " " & CStr(1&) & " " & CStr(1#) & " " & CStr(1.1) & " " & CStr(3.1416949383838)
251 | End Sub
252 |
253 | Private Sub ObjectCreateTest()
254 | 'Call CreateObject("NonExisting")
255 | Call CreateObject("Scripting.FileSystemObject").CreateTextFile("test.txt", True)
256 | MsgBox CreateObject("Scripting.FileSystemObject").GetSpecialFolder(0)
257 | MsgBox CreateObject("Scripting.FileSystemObject").FileExists("test.txt")
258 | End Sub
259 |
260 | Private Sub ObjectAppInteractionTest()
261 | MsgBox "App.Title = " & App.Title & vbCrLf & _
262 | "App.EXEName = " & App.EXEName & vbCrLf & _
263 | "App.Path = " & App.Path
264 | End Sub
265 |
266 |
--------------------------------------------------------------------------------
/Debug/Proyecto1.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | Microsoft Visual Basic
9 |
10 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Debug/Proyecto1.vbp:
--------------------------------------------------------------------------------
1 | Type=Exe
2 | Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation
3 | Module=Module1; Module1.bas
4 | Class=clsTestClass3; clsTestClass.cls
5 | Startup="Sub Main"
6 | HelpFile=""
7 | Title="Proyecto1sddasdasd"
8 | ExeName32="Proyecto1.exe"
9 | Command32=""
10 | Name="Proyecto1"
11 | HelpContextID="0"
12 | CompatibleMode="0"
13 | MajorVer=1
14 | MinorVer=0
15 | RevisionVer=0
16 | AutoIncrementVer=0
17 | ServerSupportFiles=0
18 | VersionCompanyName="Cocus Devices"
19 | CompilationType=0
20 | OptimizationType=0
21 | FavorPentiumPro(tm)=0
22 | CodeViewDebugInfo=-1
23 | NoAliasing=0
24 | BoundsCheck=0
25 | OverflowCheck=0
26 | FlPointCheck=0
27 | FDIVCheck=0
28 | UnroundedFP=0
29 | StartMode=0
30 | Unattended=0
31 | Retained=0
32 | ThreadPerObject=0
33 | MaxNumberOfThreads=1
34 |
35 | [vbAdvance]
36 | IsConsole=0
37 | HasStubFile=0
38 | GenerateMap=0
39 | TSAware=0
40 | XPManifest=1
41 | ResBuildName=.\Proyecto1.dll
42 | ReplaceIcon=0
43 | SendCommandArgs=0
44 | SymbDbgPref=0
45 | RevisionVersion=0
46 |
--------------------------------------------------------------------------------
/Debug/Proyecto1.vbw:
--------------------------------------------------------------------------------
1 | Module1 = 343, 0, 1735, 520,
2 | clsTestClass3 = 52, 52, 786, 418, C
3 |
--------------------------------------------------------------------------------
/Debug/clsTestClass.cls:
--------------------------------------------------------------------------------
1 | VERSION 1.0 CLASS
2 | BEGIN
3 | MultiUse = -1 'True
4 | Persistable = 0 'NotPersistable
5 | DataBindingBehavior = 0 'vbNone
6 | DataSourceBehavior = 0 'vbNone
7 | MTSTransactionMode = 0 'NotAnMTSObject
8 | END
9 | Attribute VB_Name = "clsTestClass3"
10 | Attribute VB_GlobalNameSpace = False
11 | Attribute VB_Creatable = True
12 | Attribute VB_PredeclaredId = False
13 | Attribute VB_Exposed = False
14 | Option Explicit
15 |
16 | Private c_bTesting As Boolean
17 |
18 | Private c_sString As String
19 |
20 | 'Public puto1 As Long
21 | 'Public puto2 As Long
22 |
23 | 'Private c_bTesting2 As Boolean
24 |
25 | 'Private c_bTesting22 As Boolean
26 | 'Private c_bTesting222 As Boolean
27 |
28 | Private Sub Class_Initialize()
29 | MsgBox "Class_Initialize()"
30 | c_bTesting = True
31 | End Sub
32 |
33 | Public Sub SetTrue()
34 | c_bTesting = True
35 | End Sub
36 |
37 | Public Sub SetFalse()
38 | c_bTesting = False
39 | End Sub
40 |
41 | Public Sub SetString(ByVal sString As String)
42 | c_sString = sString
43 | End Sub
44 |
45 | Public Function MsgboxString(ByVal bYesNo As Boolean) As Boolean
46 | MsgBox c_sString & " " & CStr(c_bTesting)
47 | MsgboxString = True
48 | End Function
49 |
50 | Public Function Exported2() As Boolean
51 | MsgBox "Exported2Called!!! " & c_bTesting & " " & Hex(VarPtr(Me))
52 | Exported2 = False
53 | End Function
54 |
55 | Private Sub Class_Terminate()
56 | MsgBox "Class_Terminate()"
57 | End Sub
58 |
--------------------------------------------------------------------------------
/openmsvbvm.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2042
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmsvbvm", "openmsvbvm\openmsvbvm.vcxproj", "{308A6CD3-E957-45F1-814F-05228F69D9EE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Debug|x64.ActiveCfg = Debug|x64
17 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Debug|x64.Build.0 = Debug|x64
18 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Debug|x86.ActiveCfg = Debug|Win32
19 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Debug|x86.Build.0 = Debug|Win32
20 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Release|x64.ActiveCfg = Release|x64
21 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Release|x64.Build.0 = Release|x64
22 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Release|x86.ActiveCfg = Release|Win32
23 | {308A6CD3-E957-45F1-814F-05228F69D9EE}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {9234912D-D44A-4061-9C55-5E049DF09CC5}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/openmsvbvm/ClassFactory.cpp:
--------------------------------------------------------------------------------
1 | #include "ClassFactory.h"
2 |
3 | #include "vba_objApp.h"
4 | #include "vba_objVBGlobal.h"
5 |
6 |
7 |
8 | extern ULONG g_ServerLocks;
9 |
10 | CMasterFactory::CMasterFactory() : m_nRefCount(1)
11 | {
12 | }
13 |
14 | CMasterFactory::~CMasterFactory()
15 | {
16 | }
17 |
18 | HRESULT __stdcall CMasterFactory::QueryInterface(REFIID riid, void ** ppObj)
19 | {
20 | HRESULT rc = S_OK;
21 |
22 | if (riid == IID_IUnknown)
23 | {
24 | *ppObj = (IUnknown*)this;
25 | }
26 | else if (riid == IID_IClassFactory)
27 | {
28 | *ppObj = (IClassFactory*)this;
29 | }
30 | /*else if (riid == IID_IVBGlobal)
31 | {
32 |
33 | }*/
34 | else rc = E_NOINTERFACE;
35 |
36 | if (rc == S_OK)
37 | this->AddRef();
38 |
39 | return rc;
40 | }
41 |
42 | ULONG __stdcall CMasterFactory::AddRef()
43 | {
44 | InterlockedIncrement(&m_nRefCount);
45 |
46 | return this->m_nRefCount;
47 | }
48 |
49 | ULONG __stdcall CMasterFactory::Release()
50 | {
51 | InterlockedDecrement(&m_nRefCount);
52 |
53 | if (this->m_nRefCount == 0)
54 | {
55 | delete this;
56 | return 0;
57 | }
58 | else
59 | {
60 | return this->m_nRefCount;
61 | }
62 | }
63 |
64 | HRESULT __stdcall CMasterFactory::CreateInstance(
65 | IUnknown * pUnknownOuter,
66 | const IID & iid,
67 | void ** ppv)
68 | {
69 | HRESULT rc = E_UNEXPECTED;
70 |
71 | if (pUnknownOuter != NULL)
72 | {
73 | rc = CLASS_E_NOAGGREGATION;
74 | }
75 | else if (iid == IID_IVBGlobal)
76 | {
77 | IUnknown* p;
78 | if ((p = new CVBGlobal()) == NULL)
79 | {
80 | rc = E_OUTOFMEMORY;
81 | }
82 | else {
83 | rc = p->QueryInterface(iid, ppv);
84 | p->Release();
85 | }
86 | }
87 | else if (iid == IID_IApp)
88 | {
89 | IUnknown* p;
90 | if ((p = new CApp()) == NULL)
91 | {
92 | rc = E_OUTOFMEMORY;
93 | }
94 | else {
95 | rc = p->QueryInterface(iid, ppv);
96 | p->Release();
97 | }
98 | }
99 | return rc;
100 | }
101 |
102 | HRESULT __stdcall CMasterFactory::LockServer(BOOL bLock)
103 | {
104 | if (bLock)
105 | {
106 | InterlockedIncrement((LONG*)&(g_ServerLocks));
107 | }
108 | else
109 | {
110 | InterlockedDecrement((LONG*)&(g_ServerLocks));
111 | }
112 |
113 | return S_OK;
114 | }
115 |
--------------------------------------------------------------------------------
/openmsvbvm/ClassFactory.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cocus/openmsvbvm/1ad89d89b91d76f5c5c0937be6e22264cc272e9c/openmsvbvm/ClassFactory.h
--------------------------------------------------------------------------------
/openmsvbvm/DllObjectInterface.cpp:
--------------------------------------------------------------------------------
1 | #include "vba_internal.h"
2 | #include "vba_exception.h"
3 |
4 | #include "DllObjectInterface.h"
5 | #include "ClassFactory.h"
6 |
7 | #include "vba_objVBGlobal.h"
8 | #include "vba_objApp.h"
9 |
10 | ULONG g_ServerLocks = 0;
11 | ULONG g_Components = 0;
12 |
13 | GUID CLSID_VBGlobal = { 0xfcfb3d23, 0xa0fa, 0x1068, { 0xa7, 0x38, 0x08, 0x00, 0x2b, 0x33, 0x71, 0xb5 } };
14 | // 33ad4f78-6699-11cf-b70c-00aa0060d393
15 | GUID CLSID_App = { 0xfcfb3d23, 0xa0fa, 0x1068, { 0xa7, 0x38, 0x08, 0x00, 0x2b, 0x33, 0x71, 0xb5 } }; // TODO: Fix this GUID
16 |
17 |
18 | STDAPI DllCanUnloadNow(void)
19 | {
20 | HRESULT rc = E_UNEXPECTED;
21 |
22 | if ((g_ServerLocks == 0) && (g_Components == 0))
23 | {
24 | rc = S_OK;
25 | }
26 | else
27 | {
28 | rc = S_FALSE;
29 | }
30 | return rc;
31 | };
32 |
33 | CMasterFactory factory;
34 |
35 | STDAPI DllGetClassObject(
36 | const CLSID& clsid,
37 | const IID& iid,
38 | void **ppv
39 | )
40 | {
41 | HRESULT rc = CLASS_E_CLASSNOTAVAILABLE;
42 |
43 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
44 |
45 | if (clsid == CLSID_VBGlobal)
46 | {
47 | DEBUG_WIDE(
48 | "clsid == CLSID_VBGlobal"
49 | );
50 | rc = factory.CreateInstance(nullptr, iid, ppv);
51 | }
52 | else if (clsid == CLSID_App)
53 | {
54 | DEBUG_WIDE(
55 | "clsid == CLSID_App"
56 | );
57 | rc = factory.CreateInstance(nullptr, iid, ppv);
58 | }
59 |
60 | return rc;
61 | };
--------------------------------------------------------------------------------
/openmsvbvm/DllObjectInterface.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void**ppv);
--------------------------------------------------------------------------------
/openmsvbvm/README.md:
--------------------------------------------------------------------------------
1 | # What is this?
2 | This is an open source interpretation of what the MSVBVM60 library does. Such library is used in VB6 applications as a base-library, where most VB functions are implemented.
3 |
4 | # Why?
5 | Well, there's no need to do this, but since VB6 is getting outdated, an open source runtime library might add some years to VB6's lifespan.
6 |
7 | # How we did this?
8 | Since the source code of this library is not available, and reverse engineering the library is a no-go, we've used some tools to get the information we need.
9 | For instance, IDA was used against a dummy VB6 .exe file where the target function was called.
10 | API Monitor from ROHITAB was also used to check some runtime values and function calls from the original MSVBVM60.dll.
11 | Some reverse-engineering sites such as the ones listed in http://sandsprite.com/vb-reversing/
12 |
13 | # How to contribute
14 | In order to contribute, please clone this repo, build it, and after you can run the example VB6 project, you can start adding new functionality.
15 | To do so, try to add a test in the dummy VB6 project and check if that doesn't work against this library. Normally these kind of errors are related to missing exported functions, so, it's easy to check what the original library did (using the methods described before).
16 | After the functionality is implemented, create a pull request.
17 |
18 | # Compiling the sources
19 | You'll need Visual Studio 2017 to compile the library. Just open the solution and build it (either Debug or Release).
20 | An example VB6 project is located inside the Debug folder. In order to compile it, you'll need VB6 installed. Compile the .exe of that project inside the Debug folder, and run it from either opening it directly from Explorer, or from "Run" in Visual Studio (launch configuration will open the VB6 project, and you can add debug the library from there).
21 |
22 | # Status of the library
23 | This library IS NOT A FULL replacement of the original library. So, don't expect to be a drop-in replacement.
24 | Currently, a small subset of the original library are implemented.
25 | Most notable ones:
26 | - Creation of ActiveX objects (CreateObject)
27 | - Access to the VBA object (Shell, Iif, etc.)
28 | - DLL function calls
29 | - MsgBox
30 | - InputBox
31 |
--------------------------------------------------------------------------------
/openmsvbvm/Resource.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cocus/openmsvbvm/1ad89d89b91d76f5c5c0937be6e22264cc272e9c/openmsvbvm/Resource.rc
--------------------------------------------------------------------------------
/openmsvbvm/Source.def:
--------------------------------------------------------------------------------
1 | LIBRARY
2 | EXPORTS
3 |
4 | __vbaChkstk @182
5 |
6 | ThunRTMain @100
7 |
8 | _adj_fdiv_m16i @659
9 | _adj_fdiv_m32 @688
10 | _adj_fdiv_m32i @701
11 | _adj_fdiv_m64 @718
12 |
13 | _adj_fdiv_r @719
14 |
15 | _adj_fdivr_m16i @720
16 | _adj_fdivr_m32 @721
17 | _adj_fdivr_m32i @722
18 | _adj_fdivr_m64 @723
19 |
20 | _adj_fprem @725
21 | _adj_fprem1 @726
22 |
23 | _CIatan @156
24 | _CIcos @157
25 | _CIexp @158
26 | _CIlog @159
27 | _CIsin @160
28 | _CIsqrt @161
29 | _CItan @162
30 |
31 | VarPtr @644
32 |
33 |
34 | __vbaCyMul @198
35 | _allmul @728
36 |
37 | ; vba_InteractionFunctions.cpp
38 | rtcChoose @665
39 | rtcShell @600
40 | rtcAppActivate @597
41 | rtcBeep @534
42 | rtcEnvironBstr @667
43 | rtcEnvironVar @666
44 | rtcImmediateIf @681
45 | rtcPartition @664
46 | rtcSendKeys @599
47 |
48 | ; vba_Settings.cpp
49 | rtcSaveSetting @690
50 | rtcDeleteSetting @691
51 | rtcGetSetting @689
52 |
53 | ; vba_Arrays.cpp
54 | __vbaAryDestruct @167
55 | __vbaGenerateBoundsError @246
56 | __vbaAryConstruct2 @164
57 | __vbaErase @213
58 | __vbaRedim @385
59 | __vbaRedimPreserve @386
60 | __vbaGenerateBoundsError @246
61 | __vbaAryDestruct @167
62 | __vbaAryLock @108
63 | __vbaAryUnlock @172
64 | __vbaLbound @325
65 | __vbaUbound @445
66 |
67 | ; vba_DllFunctionCall.cpp
68 | DllFunctionCall @187
69 |
70 | ; vba_DateManipulation.cpp
71 | rtcGetPresentDate @546
72 | __vbaDateVar @209
73 |
74 | ; vba_exception.cpp
75 | __vbaExitProc @223
76 | __vbaOnError @352
77 | __vbaExceptHandler @218
78 | __vbaFPException @224
79 | __vbaSetSystemError @394
80 |
81 | ; vba_File.cpp
82 | __vbaFileClose @229
83 | __vbaFileOpen @235
84 | __vbaPut3 @357
85 | __vbaGet3 @247
86 | rtcFileLength @570
87 | __vbaFileSeek @236
88 |
89 | ; vba_varManipulation.cpp
90 | __vbaVarCat @452
91 | rtcHexBstrFromVar @572
92 | rtcHexVarFromVar @573
93 | __vbaVarCopy @143
94 | __vbaVarDup @144
95 | __vbaVarMove @145
96 | __vbaFreeVar @131
97 | __vbaFreeVarList @245
98 |
99 | ; vba_objManipulation.cpp
100 | __vbaFreeObj @129
101 | __vbaHresultCheckObj @258
102 | __vbaNew2 @340
103 | __vbaNew @341
104 | __vbaFreeObjList @243
105 | rtcCreateObject2 @716
106 | __vbaObjVar @351
107 | __vbaVarLateMemCallLdRf @113
108 | __vbaVarLateMemCallLd @112
109 | __vbaVarAdd @450
110 | __vbaVarAnd @451
111 | __vbaVarDiv @460
112 | __vbaVarEqv @461
113 | __vbaVarIdiv @466
114 | __vbaVarImp @467
115 | __vbaVarMod @476
116 | __vbaVarMul @477
117 | __vbaVarOr @480
118 | __vbaVarPow @481
119 | __vbaVarSub @488
120 | __vbaVarXor @509
121 | __vbaObjSet @349
122 | __vbaObjSetAddref @350
123 | __vbaCastObj @178
124 | EVENT_SINK_QueryInterface @400
125 | EVENT_SINK_Release @402
126 | EVENT_SINK_AddRef @401
127 |
128 | ; vba_CommandLine.cpp
129 | rtcCommandBstr @669
130 | rtcCommandVar @670
131 |
132 | ; vba_InputBox.cpp
133 | rtcInputBox @596
134 |
135 | ; vba_MessageBox.cpp
136 | rtcMsgBox @595
137 |
138 | ; vba_strComparation.cpp
139 | __vbaStrComp @407
140 |
141 | ; vba_strConversion.cpp
142 | __vbaStrR8 @423
143 | __vbaStrR4 @422
144 | __vbaStrI4 @418
145 | __vbaStrI2 @417
146 | __vbaStrUI1 @428
147 | __vbaStrBool @399
148 | __vbaStrCy @409
149 | __vbaStrDate @415
150 | __vbaStrToAnsi @426
151 |
152 | ; vba_strManipulation.cpp
153 | rtcUpperCaseBstr @527
154 | rtcLowerCaseBstr @517
155 | rtcReplace @712
156 | __vbaStrCat @405
157 | __vbaStrMove @139
158 | __vbaFreeStr @130
159 | __vbaFreeStrList @244
160 | __vbaStrErrVarCopy @111
161 | __vbaStrVarCopy @429
162 | __vbaStrCopy @138
--------------------------------------------------------------------------------
/openmsvbvm/dllmain.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cocus/openmsvbvm/1ad89d89b91d76f5c5c0937be6e22264cc272e9c/openmsvbvm/dllmain.cpp
--------------------------------------------------------------------------------
/openmsvbvm/openmsvbvm.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 15.0
23 | {308A6CD3-E957-45F1-814F-05228F69D9EE}
24 | Win32Proj
25 | openmsvbvm
26 | 10.0.17134.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v141
33 | NotSet
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v141
39 | true
40 | NotSet
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v141
46 | NotSet
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v141
52 | true
53 | NotSet
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | true
75 |
76 |
77 | true
78 |
79 |
80 | false
81 |
82 |
83 | false
84 |
85 |
86 |
87 | NotUsing
88 | Level3
89 | Disabled
90 | true
91 | WIN32;_DEBUG;OPENMSVBVM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
92 | true
93 | true
94 |
95 |
96 | Windows
97 | true
98 | Source.def
99 |
100 |
101 | copy /Y "$(TargetPath)" "$(TargetDir)msvbvm60.dll"
102 | copy /Y "$(OutDir)$(TargetName).pdb" "$(TargetDir)msvbvm60.pdb"
103 |
104 |
105 |
106 |
107 | NotUsing
108 | Level3
109 | Disabled
110 | true
111 | _DEBUG;OPENMSVBVM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
112 | true
113 |
114 |
115 | Windows
116 | true
117 | Source.def
118 |
119 |
120 | copy /Y "$(TargetPath)" "$(TargetDir)msvbvm60.dll"
121 |
122 |
123 |
124 |
125 | NotUsing
126 | Level3
127 | MaxSpeed
128 | true
129 | true
130 | true
131 | WIN32;NDEBUG;OPENMSVBVM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
132 | true
133 | true
134 |
135 |
136 | Windows
137 | true
138 | true
139 | true
140 | Source.def
141 |
142 |
143 | copy /Y "$(TargetPath)" "$(TargetDir)msvbvm60.dll"
144 | copy /Y "$(OutDir)$(TargetName).pdb" "$(TargetDir)msvbvm60.pdb"
145 |
146 |
147 |
148 |
149 | NotUsing
150 | Level3
151 | MaxSpeed
152 | true
153 | true
154 | true
155 | NDEBUG;OPENMSVBVM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
156 | true
157 |
158 |
159 | Windows
160 | true
161 | true
162 | true
163 | Source.def
164 |
165 |
166 | copy /Y "$(TargetPath)" "$(TargetDir)msvbvm60.dll"
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
--------------------------------------------------------------------------------
/openmsvbvm/openmsvbvm.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {4f7e6775-5c4a-4130-82b8-e4e95a34d778}
18 |
19 |
20 | {2c77da8a-c0b4-456f-82d8-06716db6b34f}
21 |
22 |
23 | {bf5360b6-6851-428d-a416-821b161a335d}
24 |
25 |
26 | {d5697d40-1356-459d-897f-004eaf830560}
27 |
28 |
29 | {e909f5bd-4a4f-4805-83e3-2e5cfc475c2d}
30 |
31 |
32 | {0221a90a-5055-47e7-a567-0c1d1fb5027d}
33 |
34 |
35 | {491b344a-3ed1-4e1b-bbf4-4c2c3286a684}
36 |
37 |
38 | {5b7448b3-c642-4744-a705-f21049dc59c1}
39 |
40 |
41 | {7ba692a1-7c00-408f-9b18-5d3e81a3960a}
42 |
43 |
44 | {a97f4288-2f83-479d-b115-0a952d6d1e8b}
45 |
46 |
47 | {d126d7d0-5335-4ca6-b0ef-28c93bf48e42}
48 |
49 |
50 | {aa9f6b1d-443f-4afb-9937-9e81e3e8fa41}
51 |
52 |
53 | {fe6a04b3-275b-4072-9973-ecb71c10ee0d}
54 |
55 |
56 | {c028aac2-9484-42c2-bd76-a65d062db6c7}
57 |
58 |
59 | {795107e9-9fc4-43d8-a11b-2d4b86f1ae6d}
60 |
61 |
62 | {00ee610e-67d2-4e14-a88d-996ab32b8ccb}
63 |
64 |
65 |
66 |
67 | Archivos de origen
68 |
69 |
70 | Archivos de origen\String
71 |
72 |
73 | Archivos de origen\String
74 |
75 |
76 | Archivos de origen\String
77 |
78 |
79 | Archivos de origen\InputBox
80 |
81 |
82 | Archivos de origen\ObjectInterface
83 |
84 |
85 | Archivos de origen\Objects\VBGlobal
86 |
87 |
88 | Archivos de origen\Objects\App
89 |
90 |
91 | Archivos de origen\Objects\VBGlobal
92 |
93 |
94 | Archivos de origen\Objects\App
95 |
96 |
97 | Archivos de origen\Objects
98 |
99 |
100 | Archivos de origen\Objects
101 |
102 |
103 | Archivos de origen\Variant
104 |
105 |
106 | Archivos de origen\File
107 |
108 |
109 | Archivos de origen\MessageBox
110 |
111 |
112 | Archivos de origen\CommandLine
113 |
114 |
115 | Archivos de origen\Exceptions
116 |
117 |
118 | Archivos de origen\DateTime
119 |
120 |
121 | Archivos de origen\Interop
122 |
123 |
124 | Archivos de origen\VBA.Interaction
125 |
126 |
127 | Archivos de origen\VBA.Interaction
128 |
129 |
130 | Archivos de origen\Arrays
131 |
132 |
133 | Archivos de origen\Locale
134 |
135 |
136 |
137 |
138 | Archivos de encabezado
139 |
140 |
141 | Archivos de encabezado
142 |
143 |
144 | Archivos de encabezado
145 |
146 |
147 | Archivos de encabezado
148 |
149 |
150 | Archivos de origen\Objects\App
151 |
152 |
153 | Archivos de origen\Objects\VBGlobal
154 |
155 |
156 | Archivos de origen\Objects
157 |
158 |
159 | Archivos de origen\Objects\VBGlobal
160 |
161 |
162 | Archivos de origen\Objects\App
163 |
164 |
165 | Archivos de origen\Objects
166 |
167 |
168 | Archivos de origen\Variant
169 |
170 |
171 | Archivos de origen\ObjectInterface
172 |
173 |
174 | Archivos de origen\String
175 |
176 |
177 | Archivos de encabezado
178 |
179 |
180 | Archivos de encabezado
181 |
182 |
183 | Archivos de encabezado
184 |
185 |
186 | Archivos de origen\CommandLine
187 |
188 |
189 | Archivos de origen\Exceptions
190 |
191 |
192 |
193 |
194 | Archivos de recursos
195 |
196 |
197 |
198 |
199 | Archivos de origen\Objects\VBGlobal
200 |
201 |
202 | Archivos de origen\Objects\App
203 |
204 |
205 |
206 |
207 | Archivos de origen
208 |
209 |
210 |
211 |
--------------------------------------------------------------------------------
/openmsvbvm/resource.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cocus/openmsvbvm/1ad89d89b91d76f5c5c0937be6e22264cc272e9c/openmsvbvm/resource.h
--------------------------------------------------------------------------------
/openmsvbvm/vba_Arrays.cpp:
--------------------------------------------------------------------------------
1 | #include "vba_internal.h"
2 |
3 | #include "vba_exception.h"
4 |
5 | #include "vba_strManipulation.h"
6 | #include "vba_objManipulation.h"
7 | #include "vba_varManipulation.h"
8 |
9 |
10 |
11 | /**
12 | * @brief Raises the Subscript out of range exception.
13 | */
14 | EXPORT void __stdcall __vbaGenerateBoundsError()
15 | {
16 | vbaRaiseException(VBA_EXCEPTION_SUBSCRIPT_OUT_OF_RANGE);
17 | } /* __vbaGenerateBoundsError */
18 |
19 | /**
20 | * @brief Locks a SafeArray and copies the pointer to another pointer.
21 | * @param ppsaDest Pointer to a SafeArray pointer, where psaSource will be set to.
22 | * @param psaSource Source SafeArray pointer (to be locked).
23 | */
24 | EXPORT void __stdcall __vbaAryLock(
25 | SAFEARRAY ** ppsaDest,
26 | SAFEARRAY * psaSource
27 | )
28 | {
29 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
30 |
31 | DEBUG_WIDE(
32 | "Locking array %.8x",
33 | (unsigned int)psaSource
34 | );
35 |
36 | if (!psaSource || !ppsaDest)
37 | {
38 | vbaRaiseException(VBA_EXCEPTION_SUBSCRIPT_OUT_OF_RANGE);
39 | return;
40 | }
41 |
42 | if (SafeArrayLock(psaSource) != S_OK)
43 | {
44 | vbaRaiseException(VBA_EXCEPTION_ARRAY_FIXED_OR_TEMPORARILY_LOCKED);
45 | return;
46 | }
47 |
48 | *ppsaDest = psaSource;
49 | } /* __vbaAryLock */
50 |
51 | /**
52 | * @brief Unlocks and nulls a pointer to a previously locked SafeArray pointer.
53 | * @param ppsaSafeArray Pointer to a SafeArray pointer.
54 | */
55 | EXPORT void __stdcall __vbaAryUnlock(
56 | SAFEARRAY ** ppsaSafeArray
57 | )
58 | {
59 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
60 |
61 | DEBUG_WIDE(
62 | "Unlocking array %.8x",
63 | (unsigned int)ppsaSafeArray
64 | );
65 |
66 | if (!*ppsaSafeArray)
67 | {
68 | return;
69 | }
70 |
71 | if (SafeArrayUnlock(*ppsaSafeArray) != S_OK)
72 | {
73 | vbaRaiseException(VBA_EXCEPTION_ARRAY_FIXED_OR_TEMPORARILY_LOCKED);
74 | return;
75 | }
76 |
77 | *ppsaSafeArray = 0;
78 | } /* __vbaAryUnlock */
79 |
80 | /**
81 | * @brief Obtains the lower bound of given dimension of a SafeArray.
82 | * @param iDimension Dimension number (base 1).
83 | * @param psaSafeArray Pointer to the SafeArray.
84 | * @return Lower bound of the given dimension, or zero (and a exception) on failure.
85 | */
86 | EXPORT LONG __stdcall __vbaLbound(
87 | signed int iDimension,
88 | SAFEARRAY * psaSafeArray
89 | )
90 | {
91 | if (iDimension < 1)
92 | {
93 | vbaRaiseException(VBA_EXCEPTION_SUBSCRIPT_OUT_OF_RANGE);
94 | return 0;
95 | }
96 | if (!psaSafeArray)
97 | {
98 | vbaRaiseException(VBA_EXCEPTION_INVALID_PROCEDURE_CALL);
99 | return 0;
100 | }
101 | if (iDimension > psaSafeArray->cDims)
102 | {
103 | vbaRaiseException(VBA_EXCEPTION_SUBSCRIPT_OUT_OF_RANGE);
104 | return 0;
105 | }
106 |
107 | return psaSafeArray->rgsabound[psaSafeArray->cDims - iDimension].lLbound;
108 | } /* __vbaLbound */
109 |
110 | /**
111 | * @brief Obtains the upper bound of given dimension of a SafeArray.
112 | * @param iDimension Dimension number (base 1).
113 | * @param psaSafeArray Pointer to the SafeArray.
114 | * @return Upper bound of the given dimension, or zero (and a exception) on failure.
115 | */
116 | EXPORT LONG __stdcall __vbaUbound(
117 | signed int iDimension,
118 | SAFEARRAY * psaSafeArray
119 | )
120 | {
121 | if (iDimension < 1)
122 | {
123 | vbaRaiseException(VBA_EXCEPTION_SUBSCRIPT_OUT_OF_RANGE);
124 | return 0;
125 | }
126 | if (!psaSafeArray)
127 | {
128 | vbaRaiseException(VBA_EXCEPTION_INVALID_PROCEDURE_CALL);
129 | return 0;
130 | }
131 | if (iDimension > psaSafeArray->cDims)
132 | {
133 | vbaRaiseException(VBA_EXCEPTION_SUBSCRIPT_OUT_OF_RANGE);
134 | return 0;
135 | }
136 |
137 | SAFEARRAYBOUND * psabDimensionBounds = &psaSafeArray->rgsabound[psaSafeArray->cDims - iDimension];
138 |
139 | return psabDimensionBounds->lLbound
140 | + psabDimensionBounds->cElements;
141 | } /* __vbaUbound */
142 |
143 | /**
144 | * @brief Creates a SafeArray from a statically defined structure.
145 | * @param psaDest Pointer to the destination SafeArray.
146 | * @param psaSource Pointer to the statically defined SafeArray.
147 | * @param lpVoidArg Pointer to a IRecordInfo, GUID or nothing depending on the
148 | * features in the SafeArray.
149 | */
150 | EXPORT void __stdcall __vbaAryConstruct2(
151 | SAFEARRAY * psaDest,
152 | SAFEARRAY * psaSource,
153 | void * lpVoidArg
154 | )
155 | {
156 | /* Copy the source array psaSource to the destination array psaDest, including the bounds */
157 | memcpy(
158 | psaDest,
159 | psaSource,
160 | sizeof(SAFEARRAY) + (psaSource->cDims > 0u ? (sizeof(SAFEARRAYBOUND) * (psaSource->cDims - 1)) : 0)
161 | );
162 |
163 | /* Is an embedded array in a structure? */
164 | if (!(psaDest->fFeatures & FADF_EMBEDDED))
165 | {
166 | if (SafeArrayAllocData(psaDest) < 0 || !psaDest->pvData)
167 | {
168 | SafeArrayDestroyDescriptor(psaDest);
169 | return;
170 | }
171 | }
172 |
173 | /* Do we have an additional argument? */
174 | if (lpVoidArg)
175 | {
176 | /* If this array contains records, then the additional argument is a pointer to a RecordInfo struct */
177 | if (psaDest->fFeatures & FADF_RECORD)
178 | {
179 | psaDest->rgsabound[0].lLbound = 0;
180 | SafeArraySetRecordInfo(
181 | psaDest,
182 | reinterpret_cast(lpVoidArg)
183 | );
184 | }
185 | /* If this array contains the IID, then the additional argument is a pointer to a GUID struct */
186 | else if (psaDest->fFeatures & FADF_HAVEIID)
187 | {
188 | psaDest->cLocks = 0;
189 | psaDest->pvData = 0;
190 | psaDest->rgsabound[0].cElements = 0;
191 | psaDest->rgsabound[0].lLbound = 0;
192 | SafeArraySetIID(
193 | psaDest,
194 | (const GUID&)lpVoidArg
195 | );
196 | }
197 | else if ((psaSource->fFeatures & FADF_HAVEVARTYPE))
198 | {
199 | // ?
200 | }
201 | }
202 | } /* __vbaAryConstruct2 */
203 |
204 | /**
205 | * @brief Erases a SafeArray and nulls the pointer to that SafeArray.
206 | * @param pData ?
207 | * @param ppSafeArray Pointer to a SafeArray pointer that will be
208 | * destroyed.
209 | */
210 | EXPORT void __stdcall __vbaErase(
211 | int * pData,
212 | SAFEARRAY ** ppSafeArray
213 | )
214 | {
215 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
216 |
217 | DEBUG_WIDE(
218 | "pData %.8x, ppsaSafeArray %.8x",
219 | (unsigned int)pData,
220 | (unsigned int)ppSafeArray
221 | );
222 |
223 | if (!*ppSafeArray)
224 | {
225 | return;
226 | }
227 |
228 | switch (SafeArrayDestroy(*ppSafeArray))
229 | {
230 | case DISP_E_ARRAYISLOCKED:
231 | {
232 | vbaRaiseException(VBA_EXCEPTION_ARRAY_FIXED_OR_TEMPORARILY_LOCKED);
233 | break;
234 | }
235 |
236 | case S_OK:
237 | {
238 | *ppSafeArray = nullptr;
239 | break;
240 | }
241 |
242 | default:
243 | {
244 | vbaRaiseException(VBA_EXCEPTION_INVALID_PROCEDURE_CALL);
245 | break;
246 | }
247 | }
248 | } /* __vbaErase */
249 |
250 | /**
251 | * @brief Destructs a SafeArray and its contents.
252 | * @param pData ?
253 | * @param ppSafeArray Pointer to a SafeArray pointer that will be
254 | * destroyed and nulled.
255 | */
256 | EXPORT void __stdcall __vbaAryDestruct(
257 | int * pData,
258 | SAFEARRAY ** ppSafeArray
259 | )
260 | {
261 | if (!*ppSafeArray)
262 | {
263 | return;
264 | }
265 |
266 | if (((*ppSafeArray)->fFeatures & FADF_EMBEDDED) ||
267 | ((*ppSafeArray)->fFeatures & FADF_AUTO))
268 | {
269 | if ((*ppSafeArray)->fFeatures & FADF_RECORD)
270 | {
271 | SafeArraySetRecordInfo(*ppSafeArray, 0);
272 | }
273 | }
274 | else
275 | {
276 | if ((*ppSafeArray)->pvData)
277 | {
278 | (*ppSafeArray)->fFeatures &= 0xFFEDu;
279 | SafeArrayDestroyData(*ppSafeArray);
280 |
281 | if ((*ppSafeArray)->fFeatures & FADF_RECORD)
282 | {
283 | SafeArraySetRecordInfo(*ppSafeArray, 0);
284 | }
285 | }
286 |
287 | // This might be sufficient, since SafeArrayDestroy also
288 | // does the same as SafeArrayDestroyData.
289 | __vbaErase(pData, ppSafeArray);
290 | }
291 | } /* __vbaAryDestruct */
292 |
293 | /**
294 | * @brief Redims a given dimension of a SafeArray, preserving it's contents.
295 | * @param ppsaSafeArray Pointer to a SafeArray pointer.
296 | * @param uiDimensions Number of dimensions to redim.
297 | * @param ... New value for each dimension.
298 | */
299 | EXPORT void __cdecl __vbaRedimPreserve(
300 | int iUnk1,
301 | int iUnk2,
302 | SAFEARRAY ** ppsaSafeArray,
303 | int iUnk3,
304 | unsigned int uiDimensions,
305 | ...
306 | )
307 | {
308 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
309 |
310 | DEBUG_WIDE(
311 | "ppsaSafeArray %.8x, uiDimensions %.8x",
312 | (unsigned int)ppsaSafeArray,
313 | uiDimensions
314 | );
315 |
316 | va_list args;
317 | va_start(args, uiDimensions);
318 |
319 | if (uiDimensions == 1)
320 | {
321 | /* Redim a one-dimension array by just calling SafeArrayRedim */
322 | int iNewElementCount = va_arg(args, int);
323 |
324 | DEBUG_WIDE(
325 | "iNewElementCount = %d, PreviousElementCount %d",
326 | iNewElementCount,
327 | (*ppsaSafeArray)->rgsabound[0].cElements
328 | );
329 |
330 | SAFEARRAYBOUND sabNewBound;
331 | memcpy(
332 | &sabNewBound,
333 | &(*ppsaSafeArray)->rgsabound[0],
334 | sizeof(sabNewBound)
335 | );
336 | sabNewBound.cElements = iNewElementCount;
337 |
338 | HRESULT hr = SafeArrayRedim(
339 | *ppsaSafeArray,
340 | &sabNewBound
341 | );
342 | }
343 | else
344 | {
345 | // TODO: Multi dimension array redim!
346 | }
347 |
348 | va_end(args);
349 | } /* __vbaRedimPreserve */
350 |
351 | /**
352 | * @brief Redims a given dimension of a SafeArray, nuking it's contents.
353 | * @param uFeatures SafeArray features.
354 | * @param ulElementsSize Size of each element of the array.
355 | * @param ppsaOut Pointer to a SafeArray pointer.
356 | * @param uiDimensions Number of new dimensions to redim.
357 | * @param ... Lower and Upper bound for each dimension (two different arguments per dimension).
358 | */
359 | EXPORT void __cdecl __vbaRedim(
360 | USHORT uFeatures,
361 | ULONG ulElementsSize,
362 | SAFEARRAY ** ppsaOut,
363 | void * lpArgument,
364 | USHORT uiDimensions,
365 | ...
366 | )
367 | {
368 | if (!ppsaOut)
369 | {
370 | // Wtf?
371 | return;
372 | }
373 |
374 | if (*ppsaOut)
375 | {
376 | // We have a previously defined array, so nuke it first
377 | __vbaErase((int*)lpArgument, ppsaOut);
378 | }
379 |
380 | HRESULT hr;
381 |
382 | if (uFeatures & (FADF_RECORD | FADF_HAVEIID | FADF_HAVEVARTYPE))
383 | {
384 | // If the array's feature is RECORD, HAVEIID or HAVEVARTYPE
385 | // then create the descriptor of the SafeArray using SafeArrayAllocDescriptorEx
386 |
387 | VARTYPE vtArrayVarType;
388 |
389 | if (uFeatures & FADF_HAVEIID)
390 | {
391 | vtArrayVarType = VT_DISPATCH; // ?
392 | }
393 | else if (uFeatures & FADF_RECORD)
394 | {
395 | vtArrayVarType = VT_RECORD;
396 | }
397 | else
398 | {
399 | vtArrayVarType = (VARTYPE)lpArgument; // ?
400 | }
401 |
402 | // Allocate the descriptor for this SafeArray with given vartype
403 | hr = SafeArrayAllocDescriptorEx(
404 | vtArrayVarType,
405 | uiDimensions,
406 | ppsaOut
407 | );
408 |
409 | if (hr != S_OK)
410 | {
411 | vbaRaiseException(vbaErrorFromHRESULT(hr));
412 | return;
413 | }
414 |
415 | if (uFeatures & FADF_HAVEIID)
416 | {
417 | // If we have a IID in the lpArgument, then set it via SafeArraySetIID
418 | hr = SafeArraySetIID(
419 | *ppsaOut,
420 | reinterpret_cast(lpArgument)
421 | );
422 |
423 | if (hr != S_OK)
424 | {
425 | SafeArrayDestroyDescriptor(*ppsaOut);
426 |
427 | vbaRaiseException(vbaErrorFromHRESULT(hr));
428 | return;
429 | }
430 | }
431 | else if (uFeatures & FADF_RECORD)
432 | {
433 | // If we have a IRecordInfo* in the lpArgument, then set it via SafeArraySetRecordInfo
434 | hr = SafeArraySetRecordInfo(
435 | *ppsaOut,
436 | reinterpret_cast(lpArgument)
437 | );
438 |
439 | if (hr != S_OK)
440 | {
441 | SafeArrayDestroyDescriptor(*ppsaOut);
442 |
443 | vbaRaiseException(vbaErrorFromHRESULT(hr));
444 | return;
445 | }
446 | }
447 | }
448 | else
449 | {
450 | // Otherwise, create a standard SafeArray
451 | hr = SafeArrayAllocDescriptor(
452 | uiDimensions,
453 | ppsaOut
454 | );
455 |
456 | if (hr != S_OK)
457 | {
458 | vbaRaiseException(vbaErrorFromHRESULT(hr));
459 | return;
460 | }
461 | }
462 |
463 | // Set the members of the SafeArray with given arguments
464 | (*ppsaOut)->fFeatures = uFeatures;
465 | (*ppsaOut)->cbElements = ulElementsSize;
466 |
467 | va_list args;
468 | va_start(args, uiDimensions);
469 |
470 | // Set the bounds of the dimensions
471 | int iCurrDim = 0;
472 | while (uiDimensions--)
473 | {
474 | // We have two elements in the stack per each dimension:
475 | // First one is the Lower-Bound
476 | // Second one is the Element count (i.e. Upper-Bound)
477 | (*ppsaOut)->rgsabound[iCurrDim].cElements = va_arg(args, int) + 1;
478 | (*ppsaOut)->rgsabound[iCurrDim].lLbound = va_arg(args, int);
479 |
480 | // Fix the element count by subtracting the lower bound
481 | (*ppsaOut)->rgsabound[iCurrDim].cElements -= (*ppsaOut)->rgsabound[iCurrDim].lLbound;
482 |
483 | iCurrDim++;
484 | }
485 |
486 | va_end(args);
487 |
488 | // Now alloc the data for all the dimensions and elements
489 | hr = SafeArrayAllocData(*ppsaOut);
490 |
491 | if (hr != S_OK)
492 | {
493 | SafeArrayDestroyDescriptor(*ppsaOut);
494 | *ppsaOut = 0;
495 |
496 | vbaRaiseException(vbaErrorFromHRESULT(hr));
497 | }
498 | } /* __vbaRedim */
--------------------------------------------------------------------------------
/openmsvbvm/vba_CommandLine.cpp:
--------------------------------------------------------------------------------
1 | #include "vba_internal.h"
2 | #include "vba_exception.h"
3 |
4 | // TODO: Make this thread-dependant?
5 | static BSTR m_bstrCommandLine;
6 |
7 | /**
8 | * @brief Returns a BSTR with the app command line.
9 | * @returns A BSTR with the full command line.
10 | */
11 | EXPORT BSTR __stdcall rtcCommandBstr(void)
12 | {
13 | BSTR result;
14 |
15 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
16 |
17 | if (m_bstrCommandLine)
18 | {
19 | result = SysAllocString(m_bstrCommandLine);
20 | }
21 | else
22 | {
23 | result = SysAllocString(L"");
24 | }
25 |
26 | DEBUG_WIDE(
27 | "psz '%ls'",
28 | result
29 | );
30 |
31 | return result;
32 | }
33 |
34 | /**
35 | * @brief Returns a Variant with the app command line.
36 | * @param pvargDest Destination Variant variable.
37 | * @returns A Variant (VT_BSTR) with the full command line.
38 | */
39 | EXPORT VARIANTARG * __stdcall rtcCommandVar(
40 | VARIANTARG *pvargDest
41 | )
42 | {
43 | if (pvargDest)
44 | {
45 | pvargDest->vt = VT_BSTR;
46 | pvargDest->bstrVal = rtcCommandBstr();
47 | }
48 |
49 | return pvargDest;
50 | }
51 |
52 | OLECHAR * __stdcall rtcSetCommandLine(
53 | OLECHAR * psz
54 | )
55 | {
56 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
57 |
58 | DEBUG_WIDE(
59 | "psz '%ls'",
60 | psz
61 | );
62 |
63 | if (m_bstrCommandLine)
64 | {
65 | SysFreeString(m_bstrCommandLine);
66 | }
67 |
68 | m_bstrCommandLine = SysAllocString(psz);
69 |
70 | return m_bstrCommandLine;
71 | }
--------------------------------------------------------------------------------
/openmsvbvm/vba_CommandLine.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "vba_internal.h"
4 |
5 | OLECHAR * __stdcall rtcSetCommandLine(
6 | OLECHAR *psz
7 | );
8 |
9 | EXPORT BSTR __stdcall rtcCommandBstr(void);
--------------------------------------------------------------------------------
/openmsvbvm/vba_DateManipulation.cpp:
--------------------------------------------------------------------------------
1 | #include "vba_internal.h"
2 | #include "vba_exception.h"
3 |
4 | #include "vba_Locale.h"
5 |
6 | #include
7 |
8 |
9 | /**
10 | * @brief Gets the current date time into a VARIANTARG.
11 | * @param pvargResult Pointer to the destination VARIANTARG.
12 | */
13 | EXPORT void __stdcall rtcGetPresentDate(
14 | VARIANTARG * pvargResult
15 | )
16 | {
17 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
18 | UDATE udDate;
19 | HRESULT result;
20 |
21 | GetLocalTime(&udDate.st);
22 | // TODO: Do this in a nicer way!
23 | time_t rawtime;
24 | time(&rawtime);
25 | struct tm t;
26 | localtime_s(&t, &rawtime);
27 | char buff[30];
28 | strftime(buff, sizeof(buff), "%j", &t);
29 | udDate.wDayOfYear = atoi(buff);
30 |
31 | pvargResult->vt = VT_DATE;
32 |
33 | result = VarDateFromUdate(
34 | &udDate,
35 | VAR_VALIDDATE,
36 | &pvargResult->date
37 | );
38 |
39 | DEBUG_WIDE(
40 | "pvargResult %.8x, pvargResult->vt %.8x, pvargResult->date %.16x, VarDateFromUdate = %.8x",
41 | (unsigned int)pvargResult,
42 | pvargResult->vt,
43 | (unsigned long)pvargResult->date,
44 | (unsigned int)result
45 | );
46 |
47 | if (result != S_OK)
48 | {
49 | vbaRaiseException(vbaErrorFromHRESULT(result));
50 | return;
51 | }
52 | } /* rtcGetPresentDate */
53 |
54 | /**
55 | * @brief Converts a VARIANTARG to DATE.
56 | * @param pvargDate Pointer to the source VARIANTARG.
57 | * @return DATE representation of pvargDate, and 0.0 if fails to convert.
58 | */
59 | EXPORT DATE __stdcall __vbaDateVar(
60 | VARIANTARG * pvargDate
61 | )
62 | {
63 | DEBUG_DECLARE_WIDE_BUFFER_IF_NEEDED();
64 | DEBUG_WIDE(
65 | "pvargDate %.8x",
66 | (unsigned int)pvargDate
67 | );
68 |
69 | if (pvargDate->vt = VT_DATE)
70 | {
71 | // Don't convert it since it's already a VT_DATE
72 | return pvargDate->date;
73 | }
74 | else
75 | {
76 | VARIANTARG vargDateTemp;
77 | HRESULT hr;
78 |
79 | // Convert to VT_DATE
80 | hr = VariantChangeType(
81 | &vargDateTemp,
82 | pvargDate,
83 | 0,
84 | VT_DATE
85 | );
86 |
87 | if (hr != S_OK)
88 | {
89 | vbaRaiseException(VBA_EXCEPTION_TYPE_MISMATCH);
90 | return 0.0;
91 | }
92 |
93 | return vargDateTemp.date;
94 | }
95 | } /* __vbaDateVar */
--------------------------------------------------------------------------------
/openmsvbvm/vba_DllFunctionCall.cpp:
--------------------------------------------------------------------------------
1 | #include "vba_internal.h"
2 | #include "vba_exception.h"
3 | #include "vba_structures.h"
4 |
5 | /**
6 | * @brief Loads a DLL and gets the address of a specified procedure.
7 | * @param dllTemplate Pointer to a serDllTemplate structure, with the proper information
8 | * about the DLL and procedure to call.
9 | * @return FARPROC (func pointer) of the specified procedure on success, 0 otherwise.
10 | */
11 | EXPORT FARPROC __stdcall DllFunctionCall(
12 | struct serDllTemplate * dllTemplate
13 | )
14 | {
15 | FARPROC hFuncAddr;
16 | HMODULE hModule;
17 |
18 | if (!dllTemplate)
19 | {
20 | vbaRaiseException(VBA_EXCEPTION_INTERNAL_ERROR);
21 | }
22 |
23 | hModule = LoadLibraryA(
24 | dllTemplate->lpLibraryNameA
25 | );
26 | if (!hModule)
27 | {
28 | RaiseExceptionIfLastErrorIsSet();
29 | }
30 |
31 | hFuncAddr = GetProcAddress(
32 | hModule,
33 | dllTemplate->lpProcAddressA
34 | );
35 | if (!hFuncAddr)
36 | {
37 | RaiseExceptionIfLastErrorIsSet();
38 | }
39 |
40 | return hFuncAddr;
41 | } /* DllFunctionCall */
--------------------------------------------------------------------------------
/openmsvbvm/vba_File.cpp:
--------------------------------------------------------------------------------
1 | #include "vba_internal.h"
2 | #include "vba_exception.h"
3 |
4 | #include
5 | #include
6 | #include