Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
How To Create or Call Crystal Reports inside Foxpro?
Message
De
16/07/2002 02:11:38
Walter Meester
HoogkarspelPays-Bas
 
 
À
15/07/2002 14:53:32
Jane Harper
American Agrisurance
Urbandale, Iowa, États-Unis
Information générale
Forum:
Visual FoxPro
Catégorie:
Gestionnaire de rapports & Rapports
Divers
Thread ID:
00630954
Message ID:
00678969
Vues:
40
Hi Paul,

The keystrokes and the mousewheel is captured by the ActiveX control and never passed throug to VFP. This is a common problem with ActiveX controls. Since the ActiveX CrViewer is used to display a report and users want VFP to react on keystrokes like CTRL + P (for printing) or ESC (for closing the form), etc, this is a real pain.

I've written a DLL to capture the messages from the activeX internally and determine if they should be send to VFP.

All keystrokes besides the arrows (which are used to navigate trhough the report) are send to VFP. The mousewheel message is send to VFP if the cursor is not over the activeX control

O.K. here is the C sourcecode . Compiled in VC++ 6.0
#include <PRO_EXT.H>
#include <mmsystem.h>
#include <winuser.h>

#define MAXHOOKS 100

long oldwindowproc[MAXHOOKS] ;
long newwindowhwnd[MAXHOOKS] ;
long windowshandle[MAXHOOKS] ;
int hookno = 0;

LRESULT CALLBACK HandleWindowMessage(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
/*
void InitHook (ParamBlk *parm) ;
void DestroyHook() ;
*/

void InitHook (ParamBlk *parm)
{
	HWND hSource ;
	HWND hDest ;
	int i = 1;
	int j = 0;
	int f = 0;

	// _BreakPoint(); 

	hSource = (HWND) parm->p[0].val.ev_long ;
	hDest   = (HWND) parm->p[1].val.ev_long ;

	for (i=1; newwindowhwnd[i] != -1  && i <= hookno ; i++) ; 
	
	if (i <= MAXHOOKS){

		for (j=1; windowshandle[j] != (long)hSource && j <= hookno ; j++) ; // Check if already exists
		
		if (windowshandle[j] != (long)hSource) // if not then hook it
		{
			if (i > hookno){
				hookno++ ;
			} ;

			newwindowhwnd[i] = (long)hDest ;
			windowshandle[i] = (long)hSource ;
			oldwindowproc[i] = GetWindowLong(hSource,GWL_WNDPROC);
			SetWindowLong(hSource, GWL_WNDPROC, (LONG)HandleWindowMessage);
		} ;
	} ;
}


LRESULT CALLBACK HandleWindowMessage(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT retvalue = 0 ;
    RECT rect;
    POINT pt;
	int i ;

	for (i=1; windowshandle[i] != (long)hwndDlg && i < hookno ; i++) ;

	if (windowshandle[i] == (long)hwndDlg) {

		switch (uMsg){
		case WM_CHAR:
		case WM_KEYUP:
		case WM_KEYDOWN:
		case WM_SYSKEYUP:
		case WM_SYSKEYDOWN:
		case WM_SYSCHAR:


			if (wParam != VK_UP && wParam != VK_DOWN && wParam != VK_LEFT && wParam != VK_RIGHT){ 
				SendNotifyMessage((HWND)newwindowhwnd[i],uMsg, wParam, lParam) ;
				if (wParam == VK_RETURN && uMsg == WM_KEYDOWN) {
					/* Pass it through VFP */
					SendNotifyMessage((HWND)newwindowhwnd[i],WM_CHAR, wParam, lParam) ;
				};


				break ;
			} 

		case 0x020A: /* Mousewheel, check if the cursor is positioned over the captured window */
		    GetClientRect(hwndDlg,&rect);
		    MapWindowPoints(hwndDlg,NULL,(LPPOINT)&rect,2);
			GetCursorPos(&pt);
			if (!PtInRect(&rect,pt) || (WindowFromPoint(pt) != hwndDlg)) {
				/* Pass it through VFP */
				SendNotifyMessage((HWND)newwindowhwnd[i],uMsg, wParam, lParam) ;
				break ;
			};

		default:
			/* Pass it through the activeX control */
			return (CallWindowProc((WNDPROC)oldwindowproc[i], hwndDlg, uMsg, wParam, lParam)) ;
		}
	} ;
	return (0) ;
}

void DestroyHook()
{
	int i = 1 ;
	for (i=1; i <= hookno; i++){
		SetWindowLong((HWND)windowshandle[i], GWL_WNDPROC, oldwindowproc[i]);
	} ;
}

void ResetHooks(ParamBlk *parm)
{
	int i;
	long j = 0;
	long nHwnd=parm->p[0].val.ev_long ;

	for (i=1; i <= hookno ; i++){
		if (newwindowhwnd[i] == nHwnd){

			SetWindowLong((HWND)windowshandle[i], GWL_WNDPROC, oldwindowproc[i]);
			newwindowhwnd[i] = -1 ;
			windowshandle[i] = -1 ;
			oldwindowproc[i] = -1 ;
			j++ ;
		}
	}
	_RetInt(j,10) ;
}


FoxInfo myFoxInfo[] = {
	{"INITHOOK", (FPFI) InitHook, 2, "II"},
    {"RESETHOOKS",(FPFI) ResetHooks, 1, "I"},
 	{"DESTROYHOOK", (FPFI) DestroyHook, CALLONUNLOAD, ""}
};

extern "C" {
 FoxTable _FoxTable = {
    (FoxTable *)0, sizeof(myFoxInfo) / sizeof(FoxInfo), myFoxInfo
 };
}
O.K. fine, now what ?

Well to connect this code to VFP, we have to pass the WHND of the windows who capture the keystrokes when the activeX control is active. The ActiveX control actually contains a layered number of windows of which only two actually capture the messages. You can check this with a tool like SPY++

In the case for crystal 8.5 the names of the internal windows are: SysTreeView32 for the group tree and ReportView for the actual report.

In the INIT of the form containing the activeX control:
SET LIBRARY TO keybhook.dll ADDITIVE
the following code is activated by a timer (only once). I forgot why...
IF THISFORM.hWndDocument = 0
	THISFORM.gethwnd
ENDIF
The GetHWND method:
DECLARE INTEGER FindWindowEx IN User32.dll INTEGER, INTEGER, STRING, INTEGER
nHwnd=FindWindowEx(THISFORM.HWnd,0,0,0)
nHwnd=FindWindowEx(nHWnd,0,"ReportAlbum"+CHR(0),0)
nHwnd=FindWindowEx(nHWnd,0,"ViewHolder"+CHR(0),0)

THISFORM.hWndCrTreeView=FindWindowEx(nHWnd,0,"SysTreeView32"+CHR(0),0)
THISFORM.hWndDocument=FindWindowEx(nHWnd,0,"ReportView"+CHR(0),0)

inithook(THISFORM.hWndDocument,THISFORM.hwnd)
inithook(THISFORM.hWndCrTreeView,THISFORM.hwnd)
In the qeuryunload:
=RESETHOOKS(THISFORM.HWnd)
One problem remains however:
Since I did not made a mechanism to capture drilldown windows yet, the solution works perfectly for the main window, but for all drilldown tabs the solution does not work yet.

HTH,

I'll send you a compiled keybhook.dll by mail.

Walter,



>Hello Walter,
>
>I am having some of the Crystal Reports problems that you mentioned. Specifically, I am having problems with the keystrokes being captured by the RDC. You mentioned that you wrote a C dll to solve this problem. Would you be willing to give me the dll or at least explain how you did it? Any help would be appreciated.
>
>Thanks,
>Paul Ezerski
>and
>Jane Harper
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform