I come from a C++/asm background and have written a number of programs with the Win32 API (ie. I'm quite familiar with Windows programming, just having issues with VBA's/Access's 'quirks') and have been trying to help a friend 'fix' (ie. re-write from practically scratch) their access database. Its mostly done but I've come across a number of very strange bugs. I've spent 10-12 hours over the last 2-3 days scouring forums and everything google could find and have come up with absolutely nothing of use. I just thought I'd throw these out there in case anyone had any insight.
I tried to design a form that could be used both as a standard form, and as a pop-up window using DoCmd.OpenForm and acWindowNormal/acDialog. The acWindowNormalmethod seems to work but the 'acDialog' is all sorts of quirky. Initially the form when opened with 'acDialog' would show up in strange locations around the screen, often on a completely different monitor or under the windows task bar. Even when moved to a proper location the form would return to its bizarre initial position upon re-opening. Even when closed with DoCmd.CloseForm with acSaveYes the position was not saved and upon next opening it would be back hiding under a taskbar or on another monitor.
The next idea was to use the Win32 API (as suggested on some forums) to reposition the dialog on load. Being familiar ground I thought this was a wonderful idea. Alas to no avail. The code did work, and the window was moved to the proper location but now the Access program itself caused a weird problem. Simply adding the following Win32 API function definitions to a code module:
Code:
Private Declare PtrSafe Function apiGetClientRect Lib "user32" Alias "GetClientRect" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare PtrSafe Function apiGetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare PtrSafe Function apiSetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare PtrSafe Function apiShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
caused access to hang. What would happen is after a code change (ie. as I was debugging) and after switching from design to form view both the access window and the vba editor would hang with the access status bar stuck on 'calculating...'. This wouldn't happen every time though, only once every 3-5 attempts. The time hanging would vary from 2-20min. It would also cause Internet Explorer to run slowly, and the task manager showed one of the 4 processors working at max. If I were to hazard an uneducated guess it seemed very similar to a mutex bug in the Win32 API I came across years ago... But the MS devs would surely be aware of a bug in their own software right?? I can't be the only one who's tried to run Win32 functions from within VBA? So in the end even though the functions technically worked (when access would stop hanging and run the forms did open in the proper locations), I couldn't work with it as the constant hanging made editing difficult, also I worry that the same issues might affect the DB after deployment.
My next attempt was to abandon the idea of having forms in both as a normal report and a dialog, and just use them as dialogs exclusively. Now I had tested them extensively as normal forms, and they worked fine. But code that ran completely without issue previously would crash if either the 'Pop Up' or 'Modal' properties were set to true. I had code set to run on form unload (checks if changes are made, asks if the user wants to save, pretty standard stuff). When 'Pop Up' and 'Modal' are set to false it runs fine. If either 'Pop Up' or 'Modal' are set to true, the code will crash when switching from form to design view. Now it doesn't crash when closing the window outright. And of course I can go from closed to design view fine. But for some reason, despite the exact same code being run in the same way, switching from form view to design view causes errors, while closing the form does not. And of course this only occurs when 'Pop Up' or 'Modal' are set to true. Even when opening the form with a DoCmd.OpenForm with acDialog, but 'Pop Up' and 'Modal' set to false, it will STILL run fine. It seems to only occur when opened from the editor.
While playing around I also found a few other things that have left me baffled. The 'Auto Center' property has no effect when the form is opened from DoCmd.OpenForm. No matter what size I set my form in the properties menu or design editor, when opened as a pop-up it will not be the proper size. The 'Auto Resize' property never works, constantly making the dialog far too big and leaving bands on the bottom. The 'Border Style' property has no effect that I can tell.
On top of all this I've had a particularly aggravating issue with errors and OnUnload events. It seems that if an error occurs when the form is running, access or vba likes to simply lose all its global variables (occasionally warning me that the project will be reset, but not always). Which means the OnUnload event (which uses these globals) of course would error out. This would leave me unable to close or unload a form, seemingly permanently stuck in form view, requiring me to comment out code just to get back to design view to re-enable the code to try another fix. It got particularly annoying when this occurred with a form in dialog mode, as there was no way to close it short of using the task manager to kill the process.
No one who was worked with C++ is unfamiliar with odd errors and hard to track bugs. But nothing I've seen has prepared me for the absolutely mindboggling screwyness of access/vba. I actually started to miss template metaprogramming errors at one point.
The big problem here is that no one on the various forums I've seen seems to have any clue. Over 90% of the solutions suggested have just flat out not worked. Apparently somewhere between VB 6 and VB.net, VBA got lost. I taught myself the D3D9 and D3D11 APIs almost entirely from scouring the MSDN reference's, so I'm not unfamiliar with the format, but the VB references are in many cases incorrect, and the rest of the time have so little to as to be completely useless.
At this point I'm at a loss at where to go next...