PDA

View Full Version : shifting focus to excel



djdjoko
01-04-2006, 03:52 AM
Hi,
I have programmed an application in VBA that is rather complex and uses realtime datafeeds. Therefore the application is constantly receiving information and is quite extensively using the CPU. Anyways I have two problems with the focus of Excel.
1. when I click on Outlook, I cannot write an email or use this program anymore since the Excel application that is running in the background is constantly getting focus. Whereas other applications (I assume that are not part of MS Office) do not have this problem. Any idea how to solve this?

2.I would like to write code while the application is running, but again I cannot type anything into the visual basic editor since the focus does not let me. Is there a way around this problem as well?

Thanks again for all your help

DjDjoko

Killian
01-04-2006, 06:17 AM
Hi and welcome to VBAX :hi:

There are a number of considerations here and much will depend on the structure of the datafeed code. However, some comments:

Using DoEvents in the datafeed loop will allow Excel to yield to other processes during it's loop (which is how I'm guessing the datafeed is controlled).

Instead of using a loop to run the datafeeds (which is what's eating all the processor capacity), you could construct a timer (using WinAPI function calls) and use set intervals to update the feeds - freeing up the CPU resource between calls.

Provided you can live without that instance of excel while the code is running, you can use Application.Visible = False to avoid focus flipping (don't forget to set it back to True when you're done)

You can use WinAPI calls to lower the thread priority so other apps get more processor share. e.g.Const THREAD_BASE_PRIORITY_IDLE = -15
Const THREAD_BASE_PRIORITY_LOWRT = 15
Const THREAD_BASE_PRIORITY_MIN = -2
Const THREAD_BASE_PRIORITY_MAX = 2
Const THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN
Const THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX
Const THREAD_PRIORITY_BELOW_NORMAL = (THREAD_PRIORITY_LOWEST + 1)
Const THREAD_PRIORITY_ABOVE_NORMAL = (THREAD_PRIORITY_HIGHEST - 1)
Const THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE
Const THREAD_PRIORITY_NORMAL = 0
Const THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT
Const HIGH_PRIORITY_CLASS = &H80
Const IDLE_PRIORITY_CLASS = &H40
Const NORMAL_PRIORITY_CLASS = &H20
Const REALTIME_PRIORITY_CLASS = &H100
Private Declare Function SetThreadPriority Lib "kernel32" _
(ByVal hThread As Long, ByVal nPriority As Long) As Long
Private Declare Function SetPriorityClass Lib "kernel32" _
(ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long
Private Declare Function GetThreadPriority Lib "kernel32" _
(ByVal hThread As Long) As Long
Private Declare Function GetPriorityClass Lib "kernel32" _
(ByVal hProcess As Long) As Long
Private Declare Function GetCurrentThread Lib "kernel32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

Sub test()

Dim s, e
Dim hThread As Long, hProcess As Long
'retrieve the current thread and process
hThread = GetCurrentThread
hProcess = GetCurrentProcess
'set the new thread priority to "lowest"
SetThreadPriority hThread, THREAD_PRIORITY_LOWEST
'set the new priority class to "idle"
SetPriorityClass hProcess, IDLE_PRIORITY_CLASS

s = Now
Do 'hog the processer for 10 seconds
e = Now
Loop Until DateDiff("s", s, e) > 10

End Sub

Regarding the use of the VBE - I'm not sure there's a way around that.

The harsh reality is, if this feed is going to run constantly, then it really needs to be compiled as a standalone exe with its processer use managed (by design or thread priority control). Running it in VBA is inevitably going to tie up the host app.