Imported from djndl1/PLLearningGround (
vb_classic/GuiApp/AGENTS.md). Install upstream withnpx skills add djndl1/PLLearningGround --skill GuiApp. Copyright stays with the author.
AGENTS.md - VB6 Codebase Guidelines
This file provides guidelines for agentic coding assistants working in this Visual Basic 6 (VB6) codebase.
Project Overview
This repository contains a legacy Visual Basic 6 application with a multi-component architecture:
Main VB6 Application
- Primary project: GUI application (
GuiApp.vbp) demonstrating various programming concepts including array manipulation, date/time handling, custom error handling, and numeric conversions - Components: GUI forms, utility modules, test classes, and custom error handling classes
LegacyApp.VB6 Subproject
- VB6 ActiveX DLL: Utility library (
LegacyAppVB6.vbp) containing utility classes for arrays, date/time handling, file operations, numerics, and error validation - Numerics Subdirectory: Contains specialized numeric conversion classes (
BigEndianConverter.cls,LittleEndianConverter.cls,NativeConverter.cls,BitReinterpret.cls) - .NET Reference Submodule: LegacyApp/ contains .NET implementations for reference only (not for VB6 development)
Project Structure
GuiApp/
├── GuiApp.vbp # Main VB6 project file
├── GuiApp.vbw # VB6 workspace file
├── MainForm.frm # Main GUI form with test runner
├── Asserter.cls # Test assertion framework
├── IErrorHandler.cls # Error handler interface
├── TextOutputErrorHandler.cls # Error handler implementation
├── ArraysTest.cls # Array utility tests
├── CSliceTest.cls # Array slice tests
├── BigEndianConverterTest.cls # Big endian conversion tests
├── LittleEndianConverterTest.cls # Little endian conversion tests
├── NativeConverterTest.cls # Native conversion tests
├── BitReinterpretTest.cls # Bit reinterpret tests
├── NumericsTest.cls # Numerics utility tests
├── DecimalsTest.cls # Decimal utility tests
├── FileTimeDateTimeTest.cls # Date/time tests
├── build/ # Compiled GUI application
│ ├── GuiApp.exe
│ ├── GuiApp.exe.config
│ └── Activator.dll
└── LegacyApp.VB6/ # ActiveX DLL subproject
├── LegacyAppVB6.vbp # VB6 DLL project
├── Arrays.cls # Array manipulation utilities
├── Ensure.cls # Error validation and assertions
├── TextFileOutput.cls # File I/O operations
├── CSlice.cls # Array slicing utilities
├── Numerics.cls # Numeric operations
├── Decimals.cls # Decimal utilities
├── MinMax.cls # Min/max utilities
├── FileTimeDateTime.cls # File time date/time
├── FileTimeDateTimeFactory.cls # Date/time factory
├── CDateTimeKind.cls # Date/time kind
├── IConsumer.cls # Consumer interface
├── OleDates.bas # OLE date utilities
├── FileTimeDateTimes.bas # File time utilities
├── SystemTime.bas # System time utilities
├── Numerics/ # Numeric conversion classes
│ ├── BigEndianConverter.cls
│ ├── LittleEndianConverter.cls
│ ├── NativeConverter.cls
│ └── BitReinterpret.cls
├── build/ # Compiled DLL outputs
│ └── LegacyAppVB6.dll
└── LegacyApp/ # .NET reference submodule (not for VB6 development)
├── Infrastructure/ # Core .NET utilities
├── Gui/ # .NET GUI utilities
├── Test/ # .NET test projects
└── LegacyApp.sln # .NET solution file
Build Commands
Building the Project
Windows-only build environment required - This is a legacy VB6 project that requires the Visual Basic 6.0 IDE for compilation.
Available build commands (for reference only - do not run automatically):
# Main GUI application
make build_GuiApp
# LegacyApp VB6 DLL
make -C LegacyApp.VB6 build_LegacyAppVB6
# Install DLL to system (requires admin privileges)
make -C LegacyApp.VB6 install
Testing the Project
No automated test framework - Testing must be performed manually through the VB6 IDE or external test applications.
IMPORTANT: Agents should never attempt to build or test this project automatically after editing code.
CRITICAL RULE: Do not build or test this project automatically without explicit instructions from the user.
Code Style Guidelines
File Organization
- File Structure: Separate files for forms (.frm), classes (.cls), and modules (.bas)
- Naming: Files should match their primary class/module name
- Build Output: Compiled to
build/directory
LegacyApp.VB6 Subproject Structure
- VB6 DLL: ActiveX DLL project with utility classes for arrays, date/time, file operations
- .NET Reference Submodule: LegacyApp/ directory contains .NET implementations for reference only (not for VB6 development)
- Numerics Subdirectory: Contains specialized numeric conversion classes (
BigEndianConverter.cls,LittleEndianConverter.cls,NativeConverter.cls,BitReinterpret.cls)
Key Components
- Main Application: GUI application with test runner functionality (MainForm.frm)
- Test Framework: Custom test classes following Asserter pattern (ArraysTest.cls, CSliceTest.cls, etc.)
- Utility Library: LegacyAppVB6.dll containing core functionality
- Error Handling: Custom IErrorHandler interface and implementations
- Numerics Module: Comprehensive numeric operations including Euclidean division, ceiling/floor division, modulo operations, and clamping functions
- Date/Time System: Specialized date/time handling with
FileTimeDateTime,CDateTimeKind, and factory classes - Array Utilities:
Arrayssingleton class for array manipulation andCSlicefor array slicing operations
Formatting
- Indentation: 4 spaces (consistent with existing code)
- Line Length: Aim for 80-100 characters maximum
- Variable Declarations: Use
Option Explicitat the top of every file - Inline Declaration + Assignment: If a variable is used immediately after declaration, combine on one line with
:(e.g.,Dim lenImpl As ILength: Set lenImpl = value) - Declare at Point of Use: Place variable declarations near their first use, not at the procedure start. VB6 has no block scope — all
Dimstatements are hoisted to procedure scope regardless of where they appear. "Point of use" means placing the single declaration at procedure scope just before the first block that uses the variable. Never putDiminsideIf/Else/Select Case/For/Whileblocks — this creates the misleading illusion of block scoping and causes duplicate declaration errors. For variables used across multiple branches, declare once at procedure scope and useSet/=assignment in each branch.
Naming Conventions
- Classes: PascalCase (e.g.,
Asserter,TextFileOutput) - Modules: PascalCase (e.g.,
Arrays,OleDates) - Methods/Functions: PascalCase (e.g.,
GetArrayLength,ResizeArray) - Variables: PascalCase (e.g.,
GuiFileOutput,m_asserter) - Private Fields: Prefix with
m_(e.g.,m_handler) - Constants: ALL_CAPS (e.g.,
AssertionError)
Language Features
- VB6 Compatibility: Target Visual Basic 6.0 runtime
- Data Types: Use appropriate VB6 types (Long, Integer, String, Variant)
- Error Handling: Use
On Errorstatements and custom error handlers
Code Quality Guidelines
Error Handling
' Use custom error handling with Ensure module
Private Sub SomeMethod()
On Error GoTo ErrorHandler
' Code here
Ensure.IsTrue condition, ErrorCodes.TypeMismatch, "SomeMethod", "Error message"
Exit Sub
ErrorHandler:
Err.Raise Err.Number, Err.Source, Err.Description
End Sub
Comments and Documentation
- Use single quote comments for explanations
- Document public methods with purpose, arguments, and return values using the format seen in Arrays.cls
- Use
ReDim Preservefor dynamic array resizing (see Arrays.cls:25-30) - Array Operations: Use the
Arrayssingleton class for array manipulation - Error Checking: Use
Ensure.clsfor validation and precondition checking - Type Safety: Use
VariantTypefunction for type validation - File Operations: Use
TextFileOutputclass for file I/O with Scripting.FileSystemObject - Date/Time: Use specialized date/time classes like
FileTimeDateTimeandCDateTimeKind - Numeric Conversions: Use
BigEndianConverter,LittleEndianConverter, andNativeConverterclasses for byte array conversions - Error Messages: Always provide descriptive message arguments to
Ensure.method calls for better debugging
Test Assertion Messages
- Always include actual output values in assertion failure messages for easier debugging
- The
Asserter.AreEqualmethod automatically includes expected and actual values in the error message - For byte comparison tests, use helper methods that display hex byte arrays (see BitPaddingTest.cls)
Variant Object Reference Safety (IsObject/Set Dispatch)
When assigning from any Variant expression that may hold an object reference (whether from an array element, function return, collection item, or ByRef parameter), you must dispatch between Set and = based on IsObject():
' Use a single-line If to avoid End If:
If IsObject(source) Then Set dest = source _
Else dest = source
Why: VB6's Let assignment (=) between Variants does not call AddRef on the underlying COM object when the source Variant contains an object reference. Without Set, the object can be destroyed prematurely when the source reference goes out of scope, leaving a dangling pointer.
IsObjecton a value-type Variant (vbLong,vbString, etc.) returnsFalse→ uses=(Let), correct for valuesIsObjecton an object-type Variant (vbObject,vbDispatch) returnsTrue→ usesSet, which callsAddRef(seeArrayIterator.cls:45-46)IsObjectonNothingreturnsTrue→ usesSet, which correctly propagatesNothing- This applies to all Variant-to-Variant assignments: array element reads, function return values (
FunctionName = expr), ByRef output parameters (param = expr), Collection items, and intermediary local variables - Prefer
LetSethelper: Instead of writing the inlineIf IsObject...pattern, call theLetSetprocedure fromBuiltin.cls(orBuiltin.LetSetfrom outside the class) for cleaner code. TheLetSetprocedure implements the same IsObject/Set dispatch logic.
Project-Specific Patterns
Test Framework Pattern
' Test classes follow this pattern (see ArraysTest.cls:18-21)
Public Sub Run(ByRef myasserter As Asserter)
Set m_asserter = myasserter
TestMethod1
TestMethod2
End Sub
Private Sub TestMethod1()
m_asserter.IsTrue condition, "TestClass.TestMethod1", "Description"
End Sub
Array Operations Pattern
' Use Arrays singleton class for array manipulation (see Arrays.cls:27-42)
Public Function GetArrayLength(ByRef arr As Variant) As Long
GetArrayLength = UBound(arr) - LBound(arr) + 1
End Function
Public Sub ResizeArray(ByRef arr As Variant, ByVal newSize As Long)
Dim l, u As Long
l = LBound(arr)
u = l + newSize - 1
ReDim Preserve arr(u)
End Sub
Ensure Validation Pattern
' Use Ensure class for parameter validation with descriptive error messages
' Example from Numerics.cls:65
Ensure.NotEqual divisor, 0, ErrorCodes.DivisionByZero, "Numerics.EuclideanDivisionInteger", "divisor cannot be zero"
' Example from BigEndianConverter.cls:134
Ensure.GreaterThanOrEqual Arrays.GetArrayLength(bytes), 2, "bytes", "bytes array must have at least 2 elements"
' Example from Ensure.cls:34-37 (VariantType with optional message)
Public Sub VariantType(ByRef value As Variant, ByVal expectedType As VbVarType, ByVal source As String, Optional ByVal message As String = "")
Dim condition As Boolean
condition = (VarType(value) = expectedType)
If Len(message) > 0 Then
IsTrue condition, ErrorCodes.TypeMismatch, source, message
Else
IsTrue condition, ErrorCodes.TypeMismatch, source
End If
End Sub
Error Handler Pattern
' Custom error handlers implement IErrorHandler interface
Public Sub HandleError(ByVal errorCode As Long, ByVal errorDescription As String)
' Implementation
End Sub
Development Workflow
Adding New Features
- Follow existing naming and coding conventions
- Add appropriate error handling
- Create tests for new functionality
- Update documentation if necessary
- Do not run build or test commands
Debugging
No automatic debugging; leave it to human.
Dependencies
Runtime Dependencies
- Visual Basic 6.0 Runtime
- COM components referenced in GuiApp.vbp
- Windows-specific APIs for date/time functionality
- Microsoft Scripting Runtime (for FileSystemObject in TextFileOutput.cls)
- Microsoft ActiveX Data Objects 6.1 Library (ADO)
- Microsoft WinHTTP Services 5.1
- OPC DA Automation Wrapper 2.02
- Microsoft Message Queue 3.0 Object Library
Development Dependencies
- Visual Basic 6.0 IDE (optional, for GUI development)
- Make utility for command-line builds
- Windows environment for VB6 compilation (cannot build on Android/Linux)
Version Control
Git Guidelines
- Commit messages should describe VB6-specific changes
- Include both .vbp and source files in commits
- Build outputs are excluded via .gitignore
File Types to Track
.vbp- Project file.frm- Form files.cls- Class files.bas- Module files.frx- Form binary resources (if any)
Troubleshooting
Common Issues
- Build failures: Check VB6 installation path in Makefile
- Runtime errors: Verify COM component availability
- Missing references: Update GuiApp.vbp with correct paths
- 32-bit compatibility: VB6 applications are 32-bit only
- Cross-platform limitations: Cannot build VB6 projects on non-Windows platforms
- DLL registration: LegacyAppVB6.dll requires registration with regsvr32 for COM interop
Legacy Considerations
- VB6 is a legacy technology with limited modern tooling
- Some Windows APIs may not be available on newer Windows versions
- Consider compatibility with target deployment environment
Agent Instructions
When working in this codebase, agents should:
- Always verify VB6 compatibility before implementing features
- Follow the existing code style and naming conventions
- Use the custom error handling framework (Ensure.cls) for new functionality
- Implement proper error handling using the Ensure module patterns
- Reference existing patterns from core modules like Arrays.cls and TextFileOutput.cls
- Document breaking changes when updating APIs
- Use exact line references when referring to code (e.g.,
ArraysTest.cls:18-21) - Never attempt automated builds or tests without explicit user instruction
- Always provide descriptive message arguments to
Ensure.method calls for better error reporting - Check for existing patterns in Numerics subdirectory for numeric conversion operations
- Respect the project structure with separate directories for VB6 DLL, .NET reference submodule, and test classes
Code References
When referencing specific functions or pieces of code, include the pattern file_path:line_number to allow the user to easily navigate to the source code location.
This AGENTS.md file will be updated as the project evolves and new conventions are established.