The Window Proc function is an application-defined function that processes messages sent to a window.
The Get Window Long API function retrieves the address of the window procedure, or a handle representing the address of the window procedure. The Set Window Long function creates the subclass by changing the window procedure associated with a particular window, causing the system to call the new window procedure instead of the previous one.
This is how it works in VB:
OldWindowProc = Set Window Long (hWnd, GWL_WNDPROC, Address Of NewWindowProc)
There is no direct way how to provide this function with the address of a VFP procedure (VFP6, imho). Creating a DLL and passing hWnd to its function solves this problem, though new Window Proc will be contained within this DLL. Still it gives a chance to intercept messages being sent to the VFP form.
The next problem is how to pass the intercepted messages back to the VFP.
The VFP application creates a DDE Server with a topic linked to a VFP function intended to process messages. The DLL code connects to this server then sending intercepted messages through the DdeClientTransaction function with XTYP_POKE parameter (similar to the DDEPoke function).
The mentioned VFP function receives three main parameters for every message: Msg, wParam, and lParam.
The following Windows Messages are typically sent to the Window Proc function of a VFP form (the list is not complete):
When yo set up the structure WNDCLASSEX (which requires in the structure the 'Address Of' pointer to the Window Proc function), do you think there is a way of using a custom object with a property_assign (eg WindowProc_Assign) which would fire everytime the 'property' is changed? (I hope that you can understand this as it's a complicated thought process!). If this could work, the assign method could handle the same logic as a true Window Proc function in VB.
This code needs it's own page, but I couln't figure out a topic title, so I figured I would let someone else do that part.
*!* API calls to know how many times a program is running:
*!* This looks like we might be able to see if someone else is in the application on a server.
*!* If ur application is running from central server then it is possible
*!* to count no. of instanses dynamacally using API Calls.
*!* this method is used in my application.
*!* You can change Your Application Caption insted of "Int-E-View 2000" in following Code.
*!* You are free to use this code in your application.
#Define AppName "WinPars"
Set Step on
lox = CreateObject( "AppInstances" )
Define Class AppInstances As Custom
Procedure VerifyInstance(lMessageOnly As Boolean) As Integer
Local hWinActive, hWindow, lcWinText, hWinCount, lnWinIndex
hWinActive = GetActiveWindow()
hWindow = -1
hWinCount = 0
nCounter = 0
#Define GW_HWNDFIRST 0
#Define GW_HWNDLAST 1
#Define GW_HWNDNEXT 2
Do While hWindow <> GetWindow (hWinActive, GW_HWNDLAST)
If hWindow = -1
hWindow = GetWindow(hWinActive, GW_HWNDFIRST)
hWindow = GetWindow(hWindow, GW_HWNDNEXT)
If IsWindow(hWindow) <> 0 And IsWindowVisible(hWindow) <> 0;
And GetWindowTextLength(hWindow) > 0
lcWinText = .GetWinText(hWindow)
If hWindow <> hWinActive And Not "Program Manager" $ lcWinText
hWinCount = hWinCount + 1
Dimen arrWin[hWinCount, 2]
arrWin[hWinCount, 1] = hWindow
arrWin[hWinCount, 2] = lcWinText
If hWinCount > 0
nCounter = 0
For lnWinIndex=1 To hWinCount
aa = Upper(arrWin[lnWinIndex, 2])
If Left(aa,15) = AppName
nCounter = nCounter + 1
If lMessageOnly And nCounter >= 1
If nCounter = 1
Messagebox(Transform(nCounter,"999 ")+" Instance of Your Application is already opened. ",0,_Screen.Caption)
Messagebox(Transform(nCounter,"999 ")+" Instance of Your Application are already opened ",0,_Screen.Caption)
Function CloseApp (hWindow)
#Define WM_QUIT 18
#Define WM_SYSCOMMAND 274
#Define SC_CLOSE 61536 && 0xF060
#Define PROCESS_TERMINATE 1
Local hWinProcId, hWinThreadId, hProcess
Declare SHORT PostMessage In user32;
INTEGER HWnd, Integer Msg, Integer wParam, Integer Lparam
= PostMessage(hWindow, WM_SYSCOMMAND, SC_CLOSE, 0)
If IsWindow(hWindow) = 0
This.GetThreadProcessId (hWindow, @hWinProcId, @hWinThreadId)
hProcess = OpenProcess(PROCESS_TERMINATE, 0, hWinProcId)
If hProcess <> 0
Local lnBufsize, lcBuffer
lnBufsize = 1024
lcBuffer = Repli(Chr(0), lnBufsize)
lnBufsize = GetWindowText(hWindow, @lcBuffer, lnBufsize)
Return Iif(lnBufsize=0, "", Left(lcBuffer,lnBufsize))
Procedure GetThreadProcessId(hWindow, hProcId, hThreadId)
Store 0 To hProcId, hThreadId
hThreadId = GetWindowThreadProcessId(hWindow, @hProcId)
Declare Integer GetActiveWindow In user32
Declare Integer GetWindow In user32 Integer HWnd, Integer wFlag
Declare Integer IsWindow In user32 Integer HWnd
Declare Integer IsWindowVisible In user32 Integer HWnd
Declare Integer GetWindowTextLength In user32 Integer HWnd
Declare Integer CloseHandle In kernel32 Integer hObject
Declare Integer GetWindowText In user32;
INTEGER HWnd, String @lpString, Integer cch
Declare Integer GetWindowThreadProcessId In user32;
INTEGER HWnd, Integer @lpdwProcId
Declare Integer OpenProcess In kernel32;
INTEGER dwDesiredAccess, Integer bInheritHandle,;
Declare Integer TerminateProcess In kernel32;
INTEGER hProcess, Integer uExitCode