Private Sub GE_interrogate_Timer() '************************************************************************************ 'This procedure receives control from the GE_interrogate timer control every '1/100 seconds or the best the processor can do 'The input parameters are: ' None 'Notes on this procedure: ' o When reading this procedure the first question is likely to be: why? ' o The answer is: ' o We have to quite regularly update the latitude and longitude of the ' current GE view by <LookAt> in GE_Update_Chart and the SetCamera ' API calls in GE_Update_Chart and GE_Update_Vessel ' o Neither of these mechanisms appear to have the ability to only update ' latitude and longitude - you must also supply range, bearing and tilt ' o If you just use an arbitrary/default range, bearing and tilt the ' effect is that any changes the user makes to these using the GE ' Navigator control will be overridden at the next <LookAt> or SetCamera, ' which is not a very pleasant user experience ' o We therefor need to know immediately whenever the user changes any of ' the current GE view properties using the GE Navigator control and then ' use these new GE view properties in any subsequent <LookAt> or ' SetCamera ' o This is a sledgehammer approach and a bit embarrassing, however there ' is no obvious neat alternative - some form of event notification from GE ' when the user changes a navigation parameter or the ability to just update ' latitude and longitude in <LookAt> and SetCamera would be very useful ' o A clunky alternate approach would be to require the user to input desired ' changes to current GE view range, bearing and tilt externally to GE, via ' controls under our direct programmatic control, and then just feed these ' to <LookAt> and SetCamera - actually tried this and it is decidedly tacky ' o Having said all this, performance is suprisingly unaffected ' o The procedure is also used to solve another problem: ' o At one point during development of the GE_... procedures they were ' called directly by various procedures within greater C_wiz, including ' some timers ' o It was found that under extreme duress (e.g. when replaying with a Map ' Throttle of 100) occasionally an Automation Error -2147418107 ' (80010005) would occur ' o Microsoft KB article KB176399 explains the causes and suggests some ' workarounds: ' o Just allow a single call to GE at any time ' o "Create the server as a DLL, not an EXE", the "server" being ' googleearth.exe - is this possible? ' o Error wrap all GE calls and ignore the error - is this stable? ' o The best(?) solution is to just allow a single call to GE at a time, ' which is effectively what we have done by: ' o Requiring all procedures in greater C_wiz that want to update the ' GE chart overlay to just set the GE_status_chart_update flag to 1 ' o Requiring all procedures in greater C_wiz that want to update the ' GE vessels to just set the GE_status_vessel_update flag to 1 ' o Controlling all production calls to GE by one procedure (this one) ' so ensuring that all GE calls must be sequential ' o This is all rather messy - is it feasible for googleearth.exe to be ' supplied as a DLL with the standard GE install? '************************************************************************************ 'Set up error handler On Error GoTo BAD_GE 'Get GE's current view info Set GE_interface_view = GE_interface.GetCamera(True) 'Extract new GE range, bearing and tilt new_range! = GE_interface_view.range new_bearing% = GE_interface_view.Azimuth new_tilt% = GE_interface_view.Tilt 'Turn default error handling back on On Error GoTo 0 'If GE range, bearing or tilt has changed... If new_range! <> GE_range Or new_bearing% <> GE_bearing Or new_tilt% <> GE_tilt Then 'Save new GE range, bearing and tilt GE_range = new_range! GE_bearing = new_bearing% GE_tilt = new_tilt% 'Flag GE range, bearing or tilt is changing GE_status_changing = True 'Record time this was observed GE_time_change = GetTickCount 'Otherwise, if GE range, bearing or tilt has been changing... ElseIf GE_status_changing Then 'If a GE latency period has transpired since the last GE range, bearing 'or tilt change ... If Abs(GetTickCount - GE_time_change) > GE_latency Then 'Flag GE range, bearing and tilt are not changing GE_status_changing = False End If End If 'If GE range, bearing or tilt is not changing... If Not GE_status_changing Then 'If GE chart update required... If GE_status_chart_update = 1 Then 'Update GE chart Call GE_Update_Chart End If 'If GE vessel update required... If GE_status_vessel_update = 1 Then 'If GE vessels were last updated more than 1/2 second ago (the idea here 'is to only update the vessel data kml file actually pointed to by the 'vessel link kml file a maximum of twice a second - as the '<refreshInterval> setting in the vessel kml link file is set to cause GE 'to read the vessel data kml file once a second (the minimum possible) 'there is little point doing it more frequently)... If Abs(GetTickCount - GE_vessel_update_time) > 500 Then 'Update GE vessels Call GE_Update_Vessel End If End If End If 'Quit Exit Sub '************************************************************************************ 'This GOSUB handles an error... '************************************************************************************ BAD_GE: 'Turn default error handling back on On Error GoTo 0 'If handle of main GE window no longer points to a window... If IsWindow(GE_main_window_handle) = 0 Then 'Tidy up Call GE_Tidy End If End Sub