declare integer GetForegroundWindow in Win32API(2) The simplest. If you want the event to occur when a specific form is run by the user, let the form
ShowWindow = 2 && as top level formAs far as I can see, the form activate() fires
#define GWL_HINSTANCE (-6) #define EVENT_MIN 0x00000001 #define EVENT_MAX 0x7FFFFFFF #define EVENT_SYSTEM_SOUND 0x0001 #define EVENT_SYSTEM_ALERT 0x0002 #define EVENT_SYSTEM_FOREGROUND 0x0003 #define EVENT_SYSTEM_MENUSTART 0x0004 #define EVENT_SYSTEM_MENUEND 0x0005 #define EVENT_SYSTEM_MENUPOPUPSTART 0x0006 #define EVENT_SYSTEM_MENUPOPUPEND 0x0007 #define EVENT_SYSTEM_CAPTURESTART 0x0008 #define EVENT_SYSTEM_CAPTUREEND 0x0009 #define EVENT_SYSTEM_MOVESIZESTART 0x000A #define EVENT_SYSTEM_MOVESIZEEND 0x000B #define EVENT_SYSTEM_CONTEXTHELPSTART 0x000C #define EVENT_SYSTEM_CONTEXTHELPEND 0x000D #define EVENT_SYSTEM_DRAGDROPSTART 0x000E #define EVENT_SYSTEM_DRAGDROPEND 0x000F #define EVENT_SYSTEM_DIALOGSTART 0x0010 #define EVENT_SYSTEM_DIALOGEND 0x0011 #define EVENT_SYSTEM_SCROLLINGSTART 0x0012 #define EVENT_SYSTEM_SCROLLINGEND 0x0013 #define EVENT_SYSTEM_SWITCHSTART 0x0014 #define EVENT_SYSTEM_SWITCHEND 0x0015 #define EVENT_SYSTEM_MINIMIZESTART 0x0016 #define EVENT_SYSTEM_MINIMIZEEND 0x0017 #define WINEVENT_OUTOFCONTEXT 0x0000 && Events are ASYNC #define WINEVENT_SKIPOWNTHREAD 0x0001 && Don't call back for events on installer's thread #define WINEVENT_SKIPOWNPROCESS 0x0002 && Don't call back for events on installer's process #define WINEVENT_INCONTEXT 0x0004 && Events function do_it() set library to \projectnet\vfp\release\vfp.fll additive && adjust path declare long SetWinEventHook in win32api ; integer eventMin, ; integer eventMax, ; long hmodWinEventProc, ; long lpfnWinEventProc, ; long idProcess, ; long idThread, ; long dwflags ; declare integer UnhookWinEvent in win32api ; long hWinEventHook declare long GetWindowLong in win32api long hwnd, long nIndex declare long FindWindow in win32api string @lpClassName, string @WindowName declare long GetCurrentThreadId in win32api declare long GetWindowThreadProcessId in win32api ; integer hWnd, long @pid if( type('_screen.hwnd') == T_UNDEFINED ) && I'm still on vfp6 _screen.AddProperty('hwnd', FindWindow(null, _screen.Caption)) endif public HookFunction, hHook HookFunction = CallBack_Set( 'HookCalled', 'iiiiiii') local hMod, ProcessId hMod = GetWindowLong(FindWindow(null, _screen.Caption), GWL_HINSTANCE) ProcessId = 1 ThreadId = GetWindowThreadProcessId(_screen.hwnd, @ProcessId) hHook = SetWinEventHook( EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, hMod, HookFunction, ProcessId, GetCurrentThreadId(), WINEVENT_INCONTEXT) && this needs to be done at some point in time && in this order && before vfp exits or library unloaded, or it crashes on quit suspend ?UnhookWinEvent(hHook) ?CallBack_Release(HookFunction) endfunc *--------------------------------------------------------------------------- function HookCalled(hWinEventHook, iEvent, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) && any error in this function, like referencing a variable that does not exist, will crash vfp *?hHook, _screen.hwnd *?hWinEventHook, iEvent, hwnd, idObject, idChild, dwEventThread, dwmsEventTime && The tests below are not really necessary since && (1) event min and max are set to EVENT_SYSTEM_FOREGROUND && (2) we only track this process && do case case iEvent == EVENT_SYSTEM_FOREGROUND do case case hwnd == _screen.hwnd acti screen ? 'vfp on foreground' endcase endcase return 0 endfunc *---------------------------------------------------------------------------