mozprobe feature (approved by blythe/don); mozprobe.dll implementation, plus C/C++ test programs

This commit is contained in:
law%netscape.com 1998-08-01 19:12:04 +00:00
parent b0082a9741
commit e170f6477c
5 changed files with 1148 additions and 0 deletions

View File

@ -0,0 +1,746 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* mozprobe.cpp :
*
* This is the WinFE implementation of mozprobe.dll. This DLL provides
* dynamic "client" and "server" support for the layout probe API to be
* accessed from third-party applications.
*
* The "server" piece is the function mozProbeServerProc. It
* is dynamically linked to by mozilla.exe (see hiddenfr.cpp) and called
* when Mozilla's hidden frame received certain WM_COPYDATA requests.
*
* The "client" piece is implemented in two layers. You can use objects
* of the C++ class MozillaLayoutProbe. Or, you can use the less elegant
* C APIs that are declared identically to the real layout probe APIs in
* layprobe.h. The latter are intended to be linked to dynamically using
* LoadLibrary and GetProcAddr.
*
* This file entirely encapsulates the interface/protocol between these
* two components. See the implementation below for details.
*/
#include <string.h>
#include <stdio.h>
#include <windows.h>
#include "mozprobe.h"
/*
* Format for input/output area passed via lpData field in COPYDATASTRUCT.
*/
struct PROBEAPISTRUCT {
long lProbeID; // Probe ID. Returned on NSCP_Probe_Create.
unsigned long ulSharedMemSize; // Length of shared memory result buffer.
void* data; // Unused (at the moment).
};
/* copyResultToSharedMem
*
* This utility is used to copy LONG result values obtained from various LO_QA_*
* APIs into the shared memory buffer allocated by the client component. We use
* the convention that the mapping file name is "MozillaLayoutProbe" followed
* by the probeID.
*/
static const char * const mappingNameTemplate = "MozillaLayoutProbe%ld";
static BOOL copyResultToSharedMem( long lResult, long probeID ) {
BOOL rc = FALSE;
// Access shared memory (aka memory-mapped file).
char mappingName[ _MAX_PATH ];
sprintf( mappingName, mappingNameTemplate, probeID );
HANDLE hSharedMem = OpenFileMapping( FILE_MAP_WRITE, FALSE, mappingName );
if ( hSharedMem ) {
// Map the file.
long *pResult = (long*)MapViewOfFile( hSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
if ( pResult ) {
// Copy the result to the shared memory.
rc = TRUE;
*pResult = lResult;
UnmapViewOfFile( pResult );
}
CloseHandle( hSharedMem );
}
return rc;
}
/* mozProbeServerProc
*
* This is the exported function which is called from
* CHiddenFrame::OnProcessIPCHook to process layout probe
* IPC requests.
*
* This function's implementation defines the protocol between the client component
* and the server component (that is, the layout and semantics of the information
* passed on the WM_COPYDATA messages).
*/
long mozProbeServerProc( WPARAM wparam, LPARAM lparam, PROBEAPITABLE *api ) {
LONG rc = 0;
BOOL bResult;
LONG lResult;
char *pText;
struct MWContext_* pContext;
COPYDATASTRUCT *pcds = (COPYDATASTRUCT*)lparam;
PROBEAPISTRUCT *p = (PROBEAPISTRUCT*)( pcds ? pcds->lpData : 0 );
if ( pcds && p ) {
switch ( pcds->dwData ) {
case NSCP_Probe_Create:
// Get the MWContext corresponding to the ordinal passed in.
pContext = api->Ordinal2Context( p->lProbeID );
// If the context is valid, use it to create a probe.
if ( pContext ) {
// Create the probe, returning its ID as result.
rc = api->LO_QA_CreateProbe( pContext );
}
break;
case NSCP_Probe_Destroy:
// Destroy the probe.
api->LO_QA_DestroyProbe( p->lProbeID );
// Presume it succeeded.
rc = 1;
break;
case NSCP_Probe_GotoFirstElement:
// Position probe at first element.
// Return FALSE if it fails, TRUE if successful.
rc = api->LO_QA_GotoFirstElement( p->lProbeID );
break;
case NSCP_Probe_GotoNextElement:
// Position probe at next element.
// Return FALSE if it fails, TRUE if successful.
rc = api->LO_QA_GotoNextElement( p->lProbeID );
break;
case NSCP_Probe_GotoChildElement:
// Position probe at first element in child (if possible).
// Returns FALSE if it fails, TRUE if successful.
rc = api->LO_QA_GotoChildElement( p->lProbeID );
break;
case NSCP_Probe_GotoParentElement:
// Position probe at parent of current element (if possible).
// Returns FALSE if it fails, TRUE if successful.
rc = api->LO_QA_GotoParentElement( p->lProbeID );
break;
case NSCP_Probe_GetElementType:
// Get type of element at current probe position.
// Returns FALSE if it fails.
rc = 0;
api->LO_QA_GetElementType( p->lProbeID, (int*)&rc );
break;
case NSCP_Probe_GetElementXPosition:
// Get the horizontal offset of the current element.
// Returns FALSE if it fails, TRUE if it succeeds.
// The result value is returned through shared memory.
rc = api->LO_QA_GetElementXPosition( p->lProbeID, &lResult );
if ( rc ) {
rc = copyResultToSharedMem( lResult, p->lProbeID );
}
break;
case NSCP_Probe_GetElementYPosition:
// Get the vertical offset of the current element.
// Returns FALSE if it fails, TRUE if it succeeds.
// The result value is returned through shared memory.
rc = api->LO_QA_GetElementYPosition( p->lProbeID, &lResult );
if ( rc ) {
rc = copyResultToSharedMem( lResult, p->lProbeID );
}
break;
case NSCP_Probe_GetElementWidth:
// Get the width of the current element.
// Returns FALSE if it fails, TRUE if it succeeds.
// The result value is returned through shared memory.
rc = api->LO_QA_GetElementWidth( p->lProbeID, &lResult );
if ( rc ) {
rc = copyResultToSharedMem( lResult, p->lProbeID );
}
break;
case NSCP_Probe_GetElementHeight:
// Get the height of the current element.
// Returns FALSE if it fails, TRUE if it succeeds.
// The result value is returned through shared memory.
rc = api->LO_QA_GetElementHeight( p->lProbeID, &lResult );
if ( rc ) {
rc = copyResultToSharedMem( lResult, p->lProbeID );
}
break;
case NSCP_Probe_ElementHasURL:
// Query whether the current element has a URL associated with it.
// Returns -1 if it fails, a TRUE or FALSE result if it succeeds.
bResult = api->LO_QA_HasURL( p->lProbeID, (BOOL*)( &rc ) );
if ( !bResult ) {
rc = -1;
}
break;
case NSCP_Probe_ElementHasText:
// Query whether the current element has text associated with it.
// Returns -1 if it fails, a TRUE or FALSE result if it succeeds.
bResult = api->LO_QA_HasText( p->lProbeID, (BOOL*)( &rc ) );
if ( !bResult ) {
rc = -1;
}
break;
case NSCP_Probe_ElementHasColor:
// Query whether the current element has a color attribute.
// Returns -1 if it fails, a TRUE or FALSE result if it succeeds.
bResult = api->LO_QA_HasColor( p->lProbeID, (BOOL*)( &rc ) );
if ( !bResult ) {
rc = -1;
}
break;
case NSCP_Probe_ElementHasChild:
// Query whether the current element has child elements (is a table/cell/layer).
// Returns -1 if it fails, a TRUE or FALSE result if it succeeds.
bResult = api->LO_QA_HasChild( p->lProbeID, (BOOL*)( &rc ) );
if ( !bResult ) {
rc = -1;
}
break;
case NSCP_Probe_ElementHasParent:
// Query whether the current element has a parent element.
// Returns -1 if it fails, a TRUE or FALSE result if it succeeds.
bResult = api->LO_QA_HasParent( p->lProbeID, (BOOL*)( &rc ) );
if ( !bResult ) {
rc = -1;
}
break;
case NSCP_Probe_GetElementText:
// Get the element's text.
// Returns FALSE if it fails, TRUE if it succeeds.
// The text string is returned in shared memory.
if ( p->ulSharedMemSize ) {
// Access shared memory buffer.
char mappingName[ _MAX_PATH ];
sprintf( mappingName, mappingNameTemplate, p->lProbeID );
HANDLE hSharedMem = OpenFileMapping( FILE_MAP_WRITE, FALSE, mappingName );
if ( hSharedMem ) {
char *pResult = (char*)MapViewOfFile( hSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
if ( pResult ) {
// Read text into shared memory buffer.
rc = api->LO_QA_GetText( p->lProbeID, pResult, p->ulSharedMemSize );
// Unmap the file.
UnmapViewOfFile( pResult );
}
// Close the mapping file.
CloseHandle( hSharedMem );
}
}
break;
case NSCP_Probe_GetElementTextLength:
// Get the length of the element's text.
// Returns FALSE if it fails, TRUE if it succeeds.
// The result is returned in shared memory.
rc = api->LO_QA_GetTextLength( p->lProbeID, &lResult );
if ( rc ) {
rc = copyResultToSharedMem( lResult, p->lProbeID );
}
break;
case NSCP_Probe_GetElementColor:
// Get the element's color.
// Returns FALSE if it fails, TRUE if it succeeds.
// The color value is returned in shared memory.
rc = api->LO_QA_GetColor( p->lProbeID, &lResult, (PROBECOLORTYPE)(unsigned long)( p->data ) );
if ( rc ) {
rc = copyResultToSharedMem( lResult, p->lProbeID );
}
break;
default:
// Unexpected API, return error.
rc = 0;
break;
}
}
return rc;
}
static HWND mozHWND = 0;
/* MozillaLayoutProbe::MakeProbe
*
* Use "new" to create a probe from the context.
*/
MozillaLayoutProbe* MozillaLayoutProbe::MakeProbe( long context ) {
return new MozillaLayoutProbe( context );
}
/* MozillaLayoutProbe::MozillaLayoutProbe
*
* The first time called, we locate the Mozilla hidden frame.
*
* We create the probe by invoking the "create" layout probe
* IPC request.
*/
MozillaLayoutProbe::MozillaLayoutProbe( long context )
: m_lProbeID( 0 ),
m_bOK( FALSE ),
m_hSharedMem( 0 ),
m_ulSharedMemSize( 0 ) {
// If not yet hooked to mozilla, do so now.
if ( !mozHWND ) {
mozHWND = FindWindow( "aHiddenFrameClass", NULL );
}
// Create the probe and store the resulting ID.
if ( mozHWND ) {
m_lProbeID = context;
m_lProbeID = sendRequest( NSCP_Probe_Create );
m_bOK = !!m_lProbeID; // Bad if ID==0.
}
}
/* MozillaLayoutProbe::~MozillaLayoutProbe
*
* Destroy the probe and clean up the mapping file.
*/
MozillaLayoutProbe::~MozillaLayoutProbe() {
// Clean up state info inside Mozilla (destroy the probe).
if ( m_lProbeID ) {
sendRequest( NSCP_Probe_Destroy );
}
// Clean up shared memory.
if ( m_hSharedMem ) {
if ( m_pSharedMem ) {
UnmapViewOfFile( m_pSharedMem );
}
CloseHandle( m_hSharedMem );
}
}
/* MozillaLayoutProbe::position, MozillaLayoutProbe::Goto<X>Element
*
* All 4 positioning function simply send the request and record
* whether it worked.
*/
BOOL MozillaLayoutProbe::position( PROBE_IPC_REQUEST req ) const {
setOK( FALSE );
if ( m_lProbeID ) {
sendRequest( req );
}
return m_bOK;
}
BOOL MozillaLayoutProbe::GotoFirstElement() {
return position( NSCP_Probe_GotoFirstElement );
}
BOOL MozillaLayoutProbe::GotoNextElement() {
return position( NSCP_Probe_GotoNextElement );
}
BOOL MozillaLayoutProbe::GotoChildElement() {
return position( NSCP_Probe_GotoChildElement );
}
BOOL MozillaLayoutProbe::GotoParentElement() {
return position( NSCP_Probe_GotoParentElement );
}
/* MozillaLayoutProbe::GetElementType
*
*/
int MozillaLayoutProbe::GetElementType() const {
int result = 0;
setOK( FALSE );
if ( m_lProbeID ) {
result = sendRequest( NSCP_Probe_GetElementType );
setOK( !!result ); // 0 -> something went wrong.
}
return result;
}
/* MozillaLayoutProbe::getLongAttribute
*
* To obtain element attributes, we need shared memory into which mozilla can place
* the result. The process is the same for all 5 member functions, differing only
* in the PROBE_IPC_REQUEST value passed.
*/
long MozillaLayoutProbe::getLongAttribute( PROBE_IPC_REQUEST req, void* data ) const {
long result = 0;
setOK( FALSE );
if ( m_lProbeID ) {
// Get room for result.
setOK( allocSharedMem( sizeof( long ) ) );
if ( m_bOK ) {
sendRequest( req, sizeof( long ), data );
// Extract result, if available.
if ( m_bOK ) {
result = *( (long*)m_pSharedMem );
}
}
}
return result;
}
long MozillaLayoutProbe::GetElementXPosition() const {
return getLongAttribute( NSCP_Probe_GetElementXPosition );
}
long MozillaLayoutProbe::GetElementYPosition() const {
return getLongAttribute( NSCP_Probe_GetElementYPosition );
}
long MozillaLayoutProbe::GetElementWidth() const {
return getLongAttribute( NSCP_Probe_GetElementWidth );
}
long MozillaLayoutProbe::GetElementHeight() const {
return getLongAttribute( NSCP_Probe_GetElementHeight );
}
long MozillaLayoutProbe::GetElementColor( PROBECOLORTYPE attr ) const {
return getLongAttribute( NSCP_Probe_GetElementColor, (void*)attr );
}
long MozillaLayoutProbe::GetElementTextLength() const {
return getLongAttribute( NSCP_Probe_GetElementTextLength );
}
/* MozillaLayoutProbe::GetElementText
*
* To obtain element string attributes, we need shared memory into which mozilla can place
* the result. We allocate a comparable chunk of shared memory, issue the request, and
* then copy the result into the caller's buffer. We return the length of the result
* string.
*/
long MozillaLayoutProbe::GetElementText( char *pText, long maxLen ) const {
long result = 0;
setOK( FALSE );
if ( m_lProbeID && maxLen ) {
// Allocate shared memory (mapping file).
setOK( allocSharedMem( maxLen + 1 ) );
if ( m_bOK ) {
sendRequest( NSCP_Probe_GetElementText, maxLen );
// Extract result, if available.
if ( m_bOK ) {
sprintf( pText, "%.*s", (int)maxLen, (char*)m_pSharedMem );
// Ensure our result is properly terminated.
*( (char*)m_pSharedMem + maxLen ) = 0;
result = strlen( (char*)m_pSharedMem );
}
}
}
return result;
}
/* MozillaLayoutProbe::getBOOLAttribute, MozillaLayoutProbe::ElementHas<Attribute>
*
* BOOL element attributes are obtained by issueing the request and mapping the
* result code.
*/
BOOL MozillaLayoutProbe::getBOOLAttribute( PROBE_IPC_REQUEST req ) const {
BOOL result = FALSE;
setOK( FALSE );
if ( m_lProbeID ) {
// Don't use sendMessage as that converts the -1 to FALSE.
PROBEAPISTRUCT pas = { m_lProbeID, 0, 0 };
COPYDATASTRUCT cds = { req, sizeof pas, &pas };
result = SendMessage( mozHWND, WM_COPYDATA, NULL, (LPARAM)&cds );
if ( result == -1 ) {
// Request failed.
setOK( FALSE );
result = FALSE;
} else {
// Request succeeded.
setOK( TRUE );
}
}
return result;
}
BOOL MozillaLayoutProbe::ElementHasURL() const {
return getBOOLAttribute( NSCP_Probe_ElementHasURL );
}
BOOL MozillaLayoutProbe::ElementHasText() const {
return getBOOLAttribute( NSCP_Probe_ElementHasText );
}
BOOL MozillaLayoutProbe::ElementHasColor() const {
return getBOOLAttribute( NSCP_Probe_ElementHasColor );
}
BOOL MozillaLayoutProbe::ElementHasChild() const {
return getBOOLAttribute( NSCP_Probe_ElementHasChild );
}
BOOL MozillaLayoutProbe::ElementHasParent() const {
return getBOOLAttribute( NSCP_Probe_ElementHasParent );
}
/* MozillaLayoutProbe::IsOK
*
* IsOK is simply the member m_bOK.
*/
BOOL MozillaLayoutProbe::IsOK() const {
return m_bOK;
}
/* MozillaLayoutProbe::allocSharedMem
*
* Ensure m_pSharedMem points to sufficiently sized memory block
* (backed by mapping file, as it happens).
*/
BOOL MozillaLayoutProbe::allocSharedMem( unsigned long ulSize ) const {
MozillaLayoutProbe *self = (MozillaLayoutProbe*)this;
BOOL result = FALSE;
// Check whether current allocation is big enough for this request.
if ( m_ulSharedMemSize >= ulSize ) {
// Just use existing allocation.
result = TRUE;
} else {
// See if existing allocation must be disposed of.
if ( m_hSharedMem ) {
// Need to free prior allocation.
UnmapViewOfFile( m_pSharedMem );
self->m_pSharedMem = 0;
CloseHandle( m_hSharedMem );
self->m_hSharedMem = 0;
self->m_ulSharedMemSize = 0;
}
// Allocate minimum of 256 bytes.
self->m_ulSharedMemSize = max( 256, ulSize );
// Use canned name.
char mappingName[ _MAX_PATH ];
sprintf( mappingName, "MozillaLayoutProbe%ld", m_lProbeID );
// Create memory-mapped file.
self->m_hSharedMem = CreateFileMapping( (void*)0xFFFFFFFF, // Use dwMaximumSize[High/Low]
NULL, // No security attribute.
PAGE_READWRITE, // Read/write.
0, // dwMaximumHigh.
m_ulSharedMemSize, // dwMaximumLow.
mappingName ); // Name.
if ( m_hSharedMem ) {
// Memory mapped file created, now "map" it.
self->m_pSharedMem = MapViewOfFile( m_hSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
// Handle error.
if ( m_pSharedMem ) {
result = TRUE;
} else {
CloseHandle( m_hSharedMem );
self->m_hSharedMem = 0;
self->m_ulSharedMemSize = 0;
}
}
}
return result;
}
/* MozillaLayoutProbe::sendRequest
*
* Build PROBEAPISTRUCT and COPYDATASTRUCT and issue WM_COPYDATA message.
* We convert a -1 return code to an error.
*/
long MozillaLayoutProbe::sendRequest( PROBE_IPC_REQUEST req,
unsigned long ulSize,
void* pUser ) const {
long result = 0;
PROBEAPISTRUCT pas = { m_lProbeID, ulSize, pUser };
COPYDATASTRUCT cds = { req, sizeof pas, &pas };
result = SendMessage( mozHWND, WM_COPYDATA, 0, (LPARAM)&cds );
if ( result == -1 ) {
result = 0;
}
setOK( result );
return result;
}
/* MozillaLayoutProbe::setOK
*
* Have to cast away const so this can be set from const members.
*/
void MozillaLayoutProbe::setOK( BOOL b ) const {
MozillaLayoutProbe *self = (MozillaLayoutProbe*)this;
self->m_bOK = b;
return;
}
/* LO_QA_*
*
* These functions are exported so they can be dynamically loaded from client
* applications. They all have the same name as the "real" layout probe APIs
* declared in layprobe.h. Further, they provide exactly the same interface
* (with the one exception noted in mozprobe.h).
*
* Create/Destroy new/delete a MozillaLayoutProbe object. This object's
* address is converted to the "probeID" returned by Create (and provided
* on all subsequent APIs).
*/
extern "C" long LO_QA_CreateProbe( struct MWContext_ *context ) {
// Allocate a MozillaLayoutProbe.
MozillaLayoutProbe *p = MozillaLayoutProbe::MakeProbe( (long)context );
if ( p->IsOK() ) {
// It worked. Return it's address as the "id".
return (long)p;
} else {
// It failed. Delete the object and return 0.
delete p;
return 0;
}
}
extern "C" void LO_QA_DestroyProbe( long probeID ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
// Delete the object.
delete p;
}
extern "C" BOOL LO_QA_GotoFirstElement( long probeID ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
p->GotoFirstElement();
return p->IsOK();
}
extern "C" BOOL LO_QA_GotoNextElement( long probeID ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
p->GotoNextElement();
return p->IsOK();
}
extern "C" BOOL LO_QA_GotoChildElement( long probeID ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
p->GotoChildElement();
return p->IsOK();
}
extern "C" BOOL LO_QA_GotoParentElement( long probeID ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
p->GotoParentElement();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetElementType( long probeID, int *type ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*type = p->GetElementType();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetElementXPosition( long probeID, long *x ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*x = p->GetElementXPosition();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetElementYPosition( long probeID, long *y ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*y = p->GetElementYPosition();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetElementWidth( long probeID, long *width ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*width = p->GetElementWidth();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetElementHeight( long probeID, long *height ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*height = p->GetElementHeight();
return p->IsOK();
}
extern "C" BOOL LO_QA_HasURL( long probeID, BOOL *hasURL ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*hasURL = p->ElementHasURL();
return p->IsOK();
}
extern "C" BOOL LO_QA_HasText( long probeID, BOOL *hasText ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*hasText = p->ElementHasText();
return p->IsOK();
}
extern "C" BOOL LO_QA_HasColor( long probeID, BOOL *hasColor ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*hasColor = p->ElementHasColor();
return p->IsOK();
}
extern "C" BOOL LO_QA_HasChild( long probeID, BOOL *hasChild ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*hasChild = p->ElementHasChild();
return p->IsOK();
}
extern "C" BOOL LO_QA_HasParent( long probeID, BOOL *hasParent ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*hasParent = p->ElementHasParent();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetText( long probeID, char *text, long len ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
p->GetElementText( text, len );
return p->IsOK();
}
extern "C" BOOL LO_QA_GetTextLength( long probeID, long *len ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*len = p->GetElementTextLength();
return p->IsOK();
}
extern "C" BOOL LO_QA_GetColor( long probeID, long *color, PROBECOLORTYPE attr ) {
MozillaLayoutProbe *p = (MozillaLayoutProbe*)probeID;
*color = p->GetElementColor( attr );
return p->IsOK();
}

View File

@ -0,0 +1,22 @@
EXPORTS
mozProbeServerProc
LO_QA_CreateProbe
LO_QA_DestroyProbe
LO_QA_GotoFirstElement
LO_QA_GotoNextElement
LO_QA_GotoChildElement
LO_QA_GotoParentElement
LO_QA_GetElementType
LO_QA_GetElementXPosition
LO_QA_GetElementYPosition
LO_QA_GetElementWidth
LO_QA_GetElementHeight
LO_QA_GetText
LO_QA_GetTextLength
LO_QA_GetColor
LO_QA_HasText
LO_QA_HasURL
LO_QA_HasColor
LO_QA_HasChild
LO_QA_HasParent
?MakeProbe@MozillaLayoutProbe@@SAPAU1@J@Z

View File

@ -0,0 +1,85 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
# mozprobe.mak
#
# This file makes mozprobe.dll and two test programs:
# probe1.exe (C++) and probe2.exe (C). There are 4
# pseudo-targets: dll (builds just the .dll), tests
# (builds just the test programs), all (builds
# both the .dll and the tests), and clean (erases .obj/.exe/.dll files.
#
# "all" is the default target.
DEPTH = ..\..\..
!if "$(MOZ_DEBUG)"!=""
C_OPTS_DBG = /Zi
EXE_OPTS_DBG = /DEBUG
!if "$(MOZ_BITS)"=="32"
OBJDIR = $(MOZ_OUT)\x86Dbg
!else
OBJDIR = $(MOZ_OUT)\16x86Dbg
!endif
!else
C_OPTS_DBG = /O1
!if "$(MOZ_BITS)"=="32"
OBJDIR = $(MOZ_OUT)\x86Rel
!else
OBJDIR = $(MOZ_OUT)\16x86Rel
!endif
!endif
DLL = $(OBJDIR)\mozprobe.dll
PROBE1 = $(OBJDIR)\probe1.exe
PROBE2 = $(OBJDIR)\probe2.exe
C_OPTS = /nologo /c /I.. /Fo$@ $(C_OPTS_DBG)
CPP_OPTS = $(C_OPTS)
EXE_OPTS = $(EXE_OPTS_DBG) /OUT:$@
DLL_OPTS = $(EXE_OPTS) /DLL
all : dll tests
dll : $(DLL)
tests : $(PROBE1) $(PROBE2)
clean :
-@erase $(DLL) $(PROBE1) $(PROBE2) 1>nul 2>&1
-@erase $(OBJDIR)\mozprobe.* $(OBJDIR)\probe1.* $(OBJDIR)\probe2.obj 1>nul 2>&1
$(DLL) : $(OBJDIR)\mozprobe.obj mozprobe.def
link $(DLL_OPTS) /IMPLIB:$(OBJDIR)\mozprobe.lib /DEF:mozprobe.def $(OBJDIR)\mozprobe.obj user32.lib
$(OBJDIR)\mozprobe.obj : mozprobe.cpp ..\mozprobe.h mozprobe.mak
cl $(CPP_OPTS) mozprobe.cpp
$(PROBE1) : $(OBJDIR)\probe1.obj $(OBJDIR)\mozprobe.lib
link $(EXE_OPTS) $**
$(PROBE2) : $(OBJDIR)\probe2.obj $(OBJDIR)\mozprobe.lib
link $(EXE_OPTS) $**
$(OBJDIR)\mozprobe.lib : $(DLL)
$(OBJDIR)\probe1.obj : probe1.cpp ..\mozprobe.h
cl $(CPP_OPTS) probe1.cpp
$(OBJDIR)\probe2.obj : probe2.c ..\mozprobe.h
cl $(C_OPTS) probe2.c

View File

@ -0,0 +1,132 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* probe1.cpp :
*
* This is a C++ test/sample for how to use the Mozilla layout probe
* "hooks" from a C++ program.
*/
#include <iostream.h>
#include <windows.h>
#include "mozprobe.h"
static const char * const typeAsText( int type ) {
const char * p;
switch ( type ) {
case Probe_Text: p = "text"; break;
case Probe_HRule: p = "horizontal rule"; break;
case Probe_Image: p = "image"; break;
case Probe_Bullet: p = "bullet"; break;
case Probe_Form: p = "form element"; break;
case Probe_Table: p = "table"; break;
case Probe_Cell: p = "cell"; break;
case Probe_Embed: p = "embed"; break;
case Probe_Java: p = "java"; break;
case Probe_Object: p = "object"; break;
default: p = "unknown"; break;
}
return p;
}
static const char * const indent( int depth ) {
static char buffer[ 256 ];
memset( buffer, '\t', depth + 2 );
buffer[ depth + 2 ] = 0;
return buffer;
}
void main() {
cout << "Mozilla layout probe C++ test starting..." << endl;
// Loop over "contexts" till done.
for ( long context = 1; ; context++ ) {
// Create a probe for this context.
cout << "\tCreating probe for context " << context << "..." << endl;
MozillaLayoutProbe *probe = MozillaLayoutProbe::MakeProbe( context );
// Check if it worked.
if ( probe->IsOK() ) {
cout << "\t...created OK; now enumerating elements..." << endl;
// Now enumerate all elements.
cout << "\t\tGoing to first element..." << endl;
probe->GotoFirstElement();
int depth = 0;
while ( probe->IsOK() ) {
cout << indent(depth) << "...OK, here's the element info:" << endl;
cout << indent(depth) << "\ttype = " << probe->GetElementType()
<< " (" << typeAsText( probe->GetElementType() ) << ")" << endl;
cout << indent(depth) << "\tx = " << probe->GetElementXPosition() << endl;
cout << indent(depth) << "\ty = " << probe->GetElementYPosition() << endl;
cout << indent(depth) << "\twidth = " << probe->GetElementWidth() << endl;
cout << indent(depth) << "\theight = " << probe->GetElementHeight() << endl;
cout << indent(depth) << "\tfg color = " << hex << probe->GetElementColor(Probe_Foreground) << endl;
cout << indent(depth) << "\tbg color = " << hex << probe->GetElementColor(Probe_Background) << endl;
cout << indent(depth) << "\tborder color = " << hex << probe->GetElementColor(Probe_Border) << endl;
cout << indent(depth) << "\ttext len = " << dec << probe->GetElementTextLength() << endl;
cout << indent(depth) << "\tHasText = " << probe->ElementHasText() << endl;
cout << indent(depth) << "\tHasURL = " << probe->ElementHasURL() << endl;
cout << indent(depth) << "\tHasColor = " << probe->ElementHasColor() << endl;
cout << indent(depth) << "\tHasChild = " << probe->ElementHasChild() << endl;
cout << indent(depth) << "\tHasParent = " << probe->ElementHasParent() << endl;
// Allocate space for text.
long len = probe->GetElementTextLength() + 1;
char *pText = new char[ len ];
// Ensure it's properly terminated.
if ( pText ) {
*pText = 0;
cout << indent(depth) << "\ttext = " << ( probe->GetElementText( pText, len ), pText ) << endl;
// Free the text buffer.
delete pText;
}
// Recurse into sub-elements if there are any...
if ( probe->GotoChildElement() ) {
cout << indent(depth) << "Recursing into child elements..." << endl;
depth++;
} else {
// Go on to next element.
cout << indent(depth) << "Going to the next element..." << endl;
probe->GotoNextElement();
while ( !probe->IsOK() ) {
if ( depth-- ) {
// Go up to parent and advance to next element.
cout << indent(depth) << "...end of child elements." << endl;
probe->GotoParentElement();
probe->GotoNextElement();
} else {
break;
}
}
}
}
cout << "\t...end of element list (or error); GetLastError=0x" << GetLastError() << endl;
} else {
cout << "\t...create failed; GetLastError=0x" << hex << GetLastError() << dec << endl;
// Terminate the test.
break;
}
// Delete probe.
delete probe;
}
cout << "...test completed." << endl;
}

163
cmd/winfe/mozprobe/probe2.c Normal file
View File

@ -0,0 +1,163 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* probe2.c
*
* This is a C test/sample for how to use the Mozilla layout probe
* "hooks" from a C++ program.
*/
#include <stdio.h>
#include <windows.h>
#include "mozprobe.h"
/* Clever macro to get DLL entry points. */
#define ENTRY_POINT(fn,type) \
entryPoints.fn = (type)GetProcAddress( probeDLL, #fn ); \
if ( !entryPoints.fn ) { \
printf( "\t...error loading entry point %s, GetLastError=0x%lX\n", #fn, GetLastError() ); \
goto abortTest; \
}
static const char * const typeAsText( int type ) {
const char * p;
switch ( type ) {
case Probe_Text: p = "text"; break;
case Probe_HRule: p = "horizontal rule"; break;
case Probe_Image: p = "image"; break;
case Probe_Bullet: p = "bullet"; break;
case Probe_Form: p = "form element"; break;
case Probe_Table: p = "table"; break;
case Probe_Cell: p = "cell"; break;
case Probe_Embed: p = "embed"; break;
case Probe_Java: p = "java"; break;
case Probe_Object: p = "object"; break;
default: p = "unknown"; break;
}
return p;
}
void main() {
long context;
BOOL bOK;
long probe;
HINSTANCE probeDLL;
PROBEAPITABLE entryPoints = { 0 };
printf( "MozillaLayoutProbe C test starting...\n" );
printf( "\tLoading %s.dll...\n", mozProbeDLLName );
probeDLL = LoadLibrary( mozProbeDLLName );
if ( probeDLL ) {
printf( "\t...loaded OK.\n" );
printf( "\tGetting entry points in DLL...\n" );
ENTRY_POINT( LO_QA_CreateProbe, LONG(*)(struct MWContext_*) );
ENTRY_POINT( LO_QA_DestroyProbe, void(*)(long) );
ENTRY_POINT( LO_QA_GotoFirstElement, BOOL(*)(long) );
ENTRY_POINT( LO_QA_GotoNextElement, BOOL(*)(long) );
ENTRY_POINT( LO_QA_GotoChildElement, BOOL(*)(long) );
ENTRY_POINT( LO_QA_GotoParentElement, BOOL(*)(long) );
ENTRY_POINT( LO_QA_GetElementType, BOOL(*)(long,int*) );
ENTRY_POINT( LO_QA_GetElementXPosition, BOOL(*)(long,long*) );
ENTRY_POINT( LO_QA_GetElementYPosition, BOOL(*)(long,long*) );
ENTRY_POINT( LO_QA_GetElementWidth, BOOL(*)(long,long*) );
ENTRY_POINT( LO_QA_GetElementHeight, BOOL(*)(long,long*) );
ENTRY_POINT( LO_QA_HasText, BOOL(*)(long,BOOL*) );
ENTRY_POINT( LO_QA_HasURL, BOOL(*)(long,BOOL*) );
ENTRY_POINT( LO_QA_HasColor, BOOL(*)(long,BOOL*) );
ENTRY_POINT( LO_QA_HasChild, BOOL(*)(long,BOOL*) );
ENTRY_POINT( LO_QA_HasParent, BOOL(*)(long,BOOL*) );
ENTRY_POINT( LO_QA_GetTextLength, BOOL(*)(long,long*) );
ENTRY_POINT( LO_QA_GetText, BOOL(*)(long,char*,long) );
ENTRY_POINT( LO_QA_GetColor, BOOL(*)(long,long*,PROBECOLORTYPE) );
printf( "\t...all entry points loaded OK.\n" );
/* Loop over "contexts" till done. */
for ( context = 1; ; context++ ) {
/* Create a probe for this context. */
printf( "\tCreating probe for context %ld...\n", context );
probe = entryPoints.LO_QA_CreateProbe( (struct MWContext_*)context );
/* Check if it worked. */
if ( probe ) {
printf( "\t...created OK; now enumerating elements...\n" );
/* Now enumerate all elements. */
printf( "\t\tGoing to first element...\n" );
bOK = entryPoints.LO_QA_GotoFirstElement( probe );
while ( bOK ) {
int type;
long lAttr;
BOOL bAttr;
char *pText;
long textLen;
printf( "\t\t...OK, here's the element info:\n" );
printf( "\t\t\ttype = %d (%s)\n", ( entryPoints.LO_QA_GetElementType( probe, &type ), type ), typeAsText(type) );
printf( "\t\t\tx = %ld\n", ( entryPoints.LO_QA_GetElementXPosition( probe, &lAttr ), lAttr ) );
printf( "\t\t\ty = %ld\n", ( entryPoints.LO_QA_GetElementYPosition( probe, &lAttr ), lAttr ) );
printf( "\t\t\twidth = %ld\n", ( entryPoints.LO_QA_GetElementWidth( probe, &lAttr ), lAttr ) );
printf( "\t\t\theight = %ld\n", ( entryPoints.LO_QA_GetElementHeight( probe, &lAttr ), lAttr ) );
printf( "\t\t\tfg color = %lX\n", ( entryPoints.LO_QA_GetColor( probe, &lAttr, Probe_Foreground ), lAttr ) );
printf( "\t\t\tbg color = %lX\n", ( entryPoints.LO_QA_GetColor( probe, &lAttr, Probe_Background ), lAttr ) );
printf( "\t\t\tborder color = %lX\n", ( entryPoints.LO_QA_GetColor( probe, &lAttr, Probe_Border ), lAttr ) );
printf( "\t\t\ttext len = %ld\n", ( entryPoints.LO_QA_GetTextLength( probe, &lAttr ), lAttr ) );
printf( "\t\t\tHasText = %d\n", ( entryPoints.LO_QA_HasText( probe, &bAttr ), (int)bAttr ) );
printf( "\t\t\tHasURL = %d\n", ( entryPoints.LO_QA_HasURL( probe, &bAttr ), (int)bAttr ) );
printf( "\t\t\tHasColor = %d\n", ( entryPoints.LO_QA_HasColor( probe, &bAttr ), (int)bAttr ) );
printf( "\t\t\tHasChild = %d\n", ( entryPoints.LO_QA_HasChild( probe, &bAttr ), (int)bAttr ) );
printf( "\t\t\tHasParent = %d\n", ( entryPoints.LO_QA_HasParent( probe, &bAttr ), (int)bAttr ) );
/* Allocate space for text. */
entryPoints.LO_QA_GetTextLength( probe, &textLen );
textLen++;
pText = malloc( textLen );
if ( pText ) {
/* Ensure it's properly terminated. */
*pText = 0;
/* Get text. */
entryPoints.LO_QA_GetText( probe, pText, textLen );
printf( "\t\t\ttext = %s\n", pText );
/* Free the text buffer. */
free( pText );
}
/* Go on to next element. */
printf( "\t\tGoing to the next element...\n" );
bOK = entryPoints.LO_QA_GotoNextElement( probe );
}
printf( "\t...end of element list (or error); GetLastError=0x%lX\n", GetLastError() );
} else {
printf( "\t...create failed; GetLastError=0x%lX\n", GetLastError() );
/* Terminate the test. */
break;
}
// Destroy the probe.
entryPoints.LO_QA_DestroyProbe( probe );
}
} else {
printf( "\t...load failed; GetLastError=0x%lX\n", GetLastError() );
}
abortTest:
printf( "...test completed.\n" );
}