Python Experts - I need your expertise
The goal is to bring to Python Virtual Forms Framework by creating a GitHub repository with all the good things that Virtual Forms Framework already provide us in VBA, C#, VB.NET.
But before we can even start, there are some challenges already.
So if you are willing to help to build this great project, boost your social proof by participating in this project, please take a look at this first challenge and if you can, please try to solve it.
Davor
Challenge:
We have a custom COM component (Virtual Forms Control) that fires events and that exposes objects.
(((downloads are at the bottom of the article)))
This code opens this COM component and it connects to the database and shows the form.
But, when I scroll and click through the grid it doesn't catch the events. It should catch the EditChange event that is fired from this COM component.
Here is the CODE1:
class VFEventsClass(object):
def EditChange(self, EditChangeFunction, VirtualFormName, IdDetail, EditState):
print("Edit Change Event")
def EditBeforeSave(self, Cancel, BeforeSaveFunctionName, VirtualFormName, TableName, IdDetail, EditFlag):
print("Before Save Event")
if __name__ == '__main__':
#################################################################
# with this code I'm able to comunicate with the textboxes on the virtual form, but can't catch events
import win32com.client as win32
import pythoncom
import time
vf1 = win32.DispatchWithEvents('VirtualForm2.VirtualForm', VFEventsClass)
vf1.VFFile = r'C:\Users\WinPIS\Desktop\VFPython\VFFilePython.vf'
vf1.DatabaseType = 2
vf1.ConnectionString = r"DRIVER={MySQL ODBC 5.3 Unicode Driver};" \
"Port=3306;" \
"SERVER=virtualforms.a2hosted.com;" \
"DATABASE=virtua51_oms;" \
"USER=virtua51_student;" \
"PASSWORD=Ksq6cXWUXou];" \
"OPTION=3;"
# vf1.OpenVirtualFormDesigner()
vf1.ShowVirtualForm("VF2")
# in the opened VF2 form change the TextBox that is bound to database field customerid
vf1.TextBox("VF2", "[customerid]")[0].Text = "888"
while True:
# Trigger the event handlers if we have anything.
pythoncom.PumpWaitingMessages()
# pythoncom.PumpMessages()
time.sleep(0.1) # Don't use up all our CPU checking constantly
With this code (CODE1) we can communicate with the textbox that is on this COM component with this line of code:
vf1.TextBox("VF2", "[customerid]")[0].Text = "888"
But as I have said, this code (CODE1) doesn’t catch the events.
#######################################
And this code (CODE2) catches the events, but I can’t figure out how to communicate with the textboxes and how to loop PumpEvents so that we can use in practically indefinitely and not only for a number of seconds.
Here is the CODE2:
class VFEventsClass(object):
def EditChange(self, EditChangeFunction, VirtualFormName, IdDetail, EditState):
print("Edit Change Event")
def EditBeforeSave(self, Cancel, BeforeSaveFunctionName, VirtualFormName, TableName, IdDetail, EditFlag):
print("Before Save Event")
if __name__ == '__main__':
#################################################################
# with this code I'm able to get the events from virtual forms,
# but can't comunicate with the textboxes on the virtual form
# and PumpEvents is not in a indefinite loop
# https://pythonhosted.org/comtypes/
from comtypes.client import CreateObject
from comtypes.client import ShowEvents
from comtypes.client import PumpEvents
from comtypes.client import GetEvents
import gc
virtualformcontrol = CreateObject("VirtualForm2.VirtualForm")
virtualformcontrol.VFFile = r'C:\Users\WinPIS\Desktop\VFPython\VFFilePython.vf'
virtualformcontrol.DatabaseType = "2"
virtualformcontrol.ConnectionString = r"DRIVER={MySQL ODBC 5.3 Unicode Driver};" \
"Port=3306;" \
"SERVER=virtualforms.a2hosted.com;" \
"DATABASE=virtua51_oms;" \
"USER=virtua51_student;" \
"PASSWORD=Ksq6cXWUXou];" \
"OPTION=3;"
# OpenVirtualFormDesigner opens the designer
# virtualformcontrol.OpenVirtualFormDesigner()
virtualformcontrol.ShowVirtualForm("VF2")
# this doesn't work
# virtualformcontrol.TextBox("VF2", "[customerid]")[0].Text = "888"
# connection = ShowEvents(virtualformcontrol)
sink = VFEventsClass()
connection = GetEvents(virtualformcontrol, sink)
# how to make that this PumpEvents be used in a loop so that we can use in practically indefinitely
# and not only for a specific number of seconds
PumpEvents(20)
del connection
del virtualformcontrol
gc.collect()
If you want to see it in action, here are 2 videos:
Here are 2 short videos on this control in action in VBA & my first attempts in Python:
Here is the COM component (VFSetupBeta2.0.0.31.exe):
https://www.virtual-forms.com/sharing/Virtual%20Forms%20Framework2.0.0.31.zip
and the VFFilePython.vf:
https://www.virtual-forms.com/sharing/VFFilePython.vf
Do you have any possible ideas for a solution?
Please share it in the comment.
Thanks,
Davor
P.S.
Within the events, we should have the possibility to:
- reference the COM object textboxes like in this code: vf1.TextBox("VF2", "[customerid]")[0].Text = "888"
- some events can return values that are passed in arguments back to the COM component, like EditBeforeSave if we return "Cancel = True" then the COM control will discard saving the record to the database.
[Click here to go to original blog post...]