Fix VBA CopyMemory Crashes When Enumerating Child Windows in Excel
Question details
The application closes unexpectedly when using the CopyMemory API function in VBA to enumerate child windows.

- Product
- Excel / WPS Spreadsheet
- Device & OS
- not provided
- Scenario
- Using VBA macros with Windows API functions like CopyMemory and EnumChildWindows to enumerate and process child windows.
- Observed behavior
- The application crashes immediately upon executing the CopyMemory statement, specifically when attempting to copy callback data using LenB on a user-defined type (UDT) containing a dynamic array.
Save all open workbooks and create a backup of your VBA project before modifying API calls, as incorrect memory handling will cause immediate application crashes without warning.
Implement Safe Callback Design for EnumChildWindows
Prevent memory corruption by eliminating unsafe CopyMemory operations on dynamic arrays and utilizing module-level variables for callback data.
The primary cause of the crash is using CopyMemory with LenB on a user-defined type (UDT) that contains a dynamic array. In VBA, dynamic arrays inside UDTs are stored as pointers. Copying them directly via API overwrites memory improperly, corrupting the VBA process and terminating the host application.
Locate the statement `CopyMemory data, ByVal lParam, LenB(data)` in your VBA callback function and remove it entirely to stop unsafe memory copying.
Declare a module-level Collection or a dynamic array at the top of your standard module. Use this to store the window handles instead of passing them unsafely through the lParam pointer.
Before invoking the `EnumChildWindows` function, verify that the parent window handle is valid (not zero) using standard conditional checks to avoid enumerating a non-existent window.
When extracting class names or window text inside the callback, pre-allocate fixed-length string buffers (e.g., `Dim buffer As String * 255`) before passing them to APIs like GetWindowText.

Develop and Run VBA Macros Safely in WPS Office
WPS Office provides comprehensive support for VBA macros, including advanced Windows API integrations. You can seamlessly write, edit, and execute your updated EnumChildWindows code directly within the WPS Spreadsheet environment.
- 1. Enable Developer Tools: Open WPS Spreadsheet, go to the Options menu, and ensure the Developer tab is enabled in your ribbon.
- 2. Open the VBA Editor: Click on the Developer tab and select 'Visual Basic' to launch the integrated development environment (IDE).
- 3. Insert a Standard Module: Right-click on your project in the VBA Project Explorer, choose 'Insert', and select 'Module' to place your API declarations safely.
- 4. Execute the Macro: Run your updated EnumChildWindows procedure safely using the built-in macro runner or by stepping through the code with F8.

Frequently Asked Questions
Why does LenB cause crashes with dynamic arrays in VBA?
LenB evaluates the size of the pointer (usually 4 or 8 bytes) rather than the allocated memory of the array's actual contents. Using CopyMemory with this inaccurate size results in overwriting memory bounds, which immediately corrupts the host application process.
How do I safely retrieve window text in an EnumChildWindows callback?
You must use pre-allocated fixed-length string buffers. Declare a string like `Dim sBuffer As String * 256` or use `String(255, vbNullChar)` before passing it to the GetWindowText API, rather than letting VBA dynamically size it during the callback.
Can I pass a VBA Collection object directly to an API callback pointer?
No, passing VBA objects directly via Windows API pointers (like lParam) is highly unsafe and often leads to crashes. The recommended approach is to declare a module-level Collection to store data retrieved during the callback execution without passing it through memory pointers.




