>declare integer GetForegroundWindow in Win32API >>
>ShowWindow = 2 && as top level form >>As 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 >*--------------------------------------------------------------------------- >