DDE VCL replacements

116 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Henrik Nedergaard

ungelesen,
29.12.2001, 12:27:5129.12.01
an
Hi

Jezzes I can't believe how bad those Borland DDE's VCL's are. I wonder why
they included them when they didn't make a proper implementations, jezzes
they sucks.

Does anyone know some proper 3.party DDE components? I got a link some month
ago but I've lost it again.

regards
Henrik


Peter Below (TeamB)

ungelesen,
03.01.2002, 11:19:0603.01.02
an
In article <3c2dfde5_2@dnews>, Henrik Nedergaard wrote:
> Jezzes I can't believe how bad those Borland DDE's VCL's are. I wonder why
> they included them when they didn't make a proper implementations, jezzes
> they sucks.

They worked fairly well on Delphi 1 but the move to Win32 seems to have thrown
a few spanners into the works. Not only for Delphi, by the way. DDEs basic
concept is not very compatible with a multithreading OS, so MS has been trying
hard to bury it, touting OLE automation as replacement. It refuses to die,
however <G>.

> Does anyone know some proper 3.party DDE components? I got a link some month
> ago but I've lost it again.

DJANGO DDE components
http://dspace.dial.pipex.com/town/estate/ns21/icfmdc.htm

These received good reviews some years back. And you can always use the DDEML
API directly, of course.

Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Henrik Nedergaard

ungelesen,
04.01.2002, 15:20:5604.01.02
an
> They worked fairly well on Delphi 1 but the move to Win32 seems to have
thrown
> a few spanners into the works. Not only for Delphi, by the way. DDEs basic
> concept is not very compatible with a multithreading OS, so MS has been
trying
> hard to bury it, touting OLE automation as replacement. It refuses to die,
> however <G>.
yeah s* happens, when microsoft yields jump, chances are that lots of people
will actually do that and some will even ask how high <S>

> > Does anyone know some proper 3.party DDE components? I got a link some
month
> > ago but I've lost it again.
>
> DJANGO DDE components
> http://dspace.dial.pipex.com/town/estate/ns21/icfmdc.htm

Thanks, I've seen it, but it a high price to pay for my max. 32 items.


> These received good reviews some years back. And you can always use the
DDEML
> API directly, of course.
>

Have you seen anyone making any examples on how to do that, I mean I don't
realy need to make anything sophisticated I just need to setup communication
with those damn 32 dde items.


regards
Henrik


Erwin Dokter

ungelesen,
04.01.2002, 19:28:5904.01.02
an
Peter Below (TeamB) wrote:
>
> > Jezzes I can't believe how bad those Borland DDE's VCL's are.
>
> They worked fairly well on Delphi 1...

PHOOEY! :)

Read my post above? (Time to brush up...) Somehow, D1 DDE components are
not even able to function properly as Shell DDE, which was the first
ever emplementation of DDE (Program Manager). I am having great
diffifculty providing a 'Groups' DDE item for setup programs.

-- Erwin Dokter
mailto:edo...@home.nl
http://members.home.nl/edokter

Peter Below (TeamB)

ungelesen,
05.01.2002, 10:21:5805.01.02
an
In article <3C3648...@home.nl>, Erwin Dokter wrote:
> Read my post above? (Time to brush up...) Somehow, D1 DDE components are
> not even able to function properly as Shell DDE, which was the first
> ever emplementation of DDE (Program Manager). I am having great
> diffifculty providing a 'Groups' DDE item for setup programs.

The Progman DDE interface was completely centered around macro commands
you send to the server, if memory serves. So you do not access a Groups
item, you execute a macro [GROUPS] and get back the list of groups. Has
been ages since i played with that stuff, though, i may misremember it...

Peter Below (TeamB)

ungelesen,
05.01.2002, 10:21:5405.01.02
an
In article <3c360f75_1@dnews>, Henrik Nedergaard wrote:
> Have you seen anyone making any examples on how to do that,
>

I did some when i was still using Borland Pascal 7 for Win 3.1
development and later ported the class to Delphi 1. I think i even did
a D2 port of that, but never actually used it. I'll append it, perhaps
it can be of some use for you. Unfortunately i have absolutely no
examples on its use around anymore. You will need to provide a
significantly more complex callback than the default, for example, for
anything moderately demanding. The default is enough for connecting to
a server to send it macro commands, and that was all i ever used this
class for.

{+------------------------------------------------------------
| Unit DDEObjec
|
| Version: 2.0 Created: 12/18/96, 12:58:02
| Last Modified: 12/18/96, 12:58:02
| Author : P. Below
| Project: Common utilities
| Description:
| Simple DDEML interface for Delphi 2.0
+------------------------------------------------------------}
Unit DDEObjec;

Interface

Uses Windows, DDEML, SysUtils, ErrClass;

Type
EDDEMLException = Class( Exception );

TDDEMLClass = Class( TErrClass )
private
f_Inst: LongInt; (* ddeml instance *)
f_Conv: HConv; (* conversation handle *)
f_Server: HSz; (* server name string handle *)
f_Topic : HSz; (* topic name string handle *)
f_Timeout: LongInt; (* timeout for transactions *)
f_LastResult: LongInt; (* last transaction result *)
f_LastError : LongInt; (* last dde error status *)
f_CallbackInst: TFNCallback; (* callback for this instance *)
f_codepage : Integer; (* default code page to use *)

protected
public
Constructor Create( aCallback: TFNCallback; flags : LongInt );
Destructor Destroy; override;

Function MakeHSz( aStr: PChar ): HSz;
Procedure FreeHSz( Var aHSz: HSz );
Function CompareHSz( HSz1, HSz2: HSz ): Integer;
Function QueryHSz( aHSz: HSz; Var aStrObj: String ): Boolean;

Function Connect( aServer, aTopic: PChar): Boolean;
Procedure Disconnect;
Function ClientTransaction( pServerData: Pointer; dataSize:
LongInt;
Item: HSz; Format, DataType: UINT ): HDDEData;
Function Request( Item: PChar; Format:UINT ): HDDEData;
Function Execute( command: PChar ): Boolean;
Function GetData( hData: hDDEData; buf: Pointer;
bufSize, offset: LongInt ): LongInt;
Function GetDataAsStrObj( hData: hDDEData; Var aStrObj: String ):
Boolean;
Procedure FreeDatahandle( hData: hDDEData );
Function CreateDataHandle( source: Pointer; len, offset: LongInt;
item: HSz; Format, Command: UINT):
hDDEData;
Function AddData( data: hDDEData;source: Pointer;
len, offset: LongInt ): hDDEData;
Function AccessData( data: hDDEData; DataSize: PDWORD ): Pointer;
Procedure UnaccessData( data: hDDEData );

Function IsConnected: Boolean;
Function IsValid: Boolean;

Procedure DDE_Error;
Procedure SetDDE_Error( err: Longint );

property Timeout: LongInt read f_timeout write f_timeout;
property LastDdeError: LongInt read f_lasterror;
property LastDdeResult: LongInt read f_lastresult;
property Server: HSz read f_server;
property Topic: HSz read f_topic;
property Codepage: Integer read f_codepage write f_codepage;

End;

Implementation

Const
{$IFDEF GERMAN}
errAdvAckTimeout = 'Timeout bei Bestätigung einer Benachrichtigung
(dmlErr_AdvAckTimeout)';
errBusy = 'DDEML ist beschäftigt (dmlErr_Busy)';
errDataAckTimeout = 'Timeout bei Bestätigung einer Datenübertragung
(dmlErr_DataAckTimeout)';
errDLL_Not_Initialized = 'DDEML wurde nicht initialisiert
(dmlErr_DLL_Not_Initialized)';
errDLL_Usage = 'Die Anwendung ist nicht für die versuchte Aktion bei
DDEML angemeldet worden (dmlErr_DLL_Usage)';
errExecAckTimeout = 'Timeout bei Bestätigung einer Makroausführung
(dmlErr_ExecAckTimeout)';
errInvalidParameter = 'Ein ungültiger Parameter wurde an DDEML
übergeben (dmlErr_InvalidParameter)';
errLow_Memory = 'DDEML interner Speicherüberlauf
(dmlErr_Low_Memory)';
errMemory_Error = 'DDEML kann keinen freien Speicher mehr finden
(dmlErr_Memory_Error)';
errNotProcessed = 'Empfänger der DDE-Nachricht hat diese nicht
bearbeitet (dmlErr_NotProcessed)';
errNo_Conv_Established = 'Die DDE-Verbindung konnte nicht aufgebaut
werden (dmlErr_No_Conv_Established)';
errPokeAckTimeout = 'Timeout bei Bestätigung einer Datenübermittlung
(dmlErr_PokeAckTimeout)';
errPostMsg_Failed =
'DDEML konnte ein PostMessage nicht ausführen, die
Meldungswarteschlange des Empfängers ist voll (dmlErr_PostMsg_Failed)';
errReentrancy = 'Es wurde versucht, synchrone Übertragungen oder
Callbacks zu schachteln (dmlErr_Reentrancy)';
errServer_Died = 'Die Serveranwendung ist nicht mehr aktiv
(dmlErr_Server_Died)';
errSys_Error = 'DDEML interner Fehler, System API-Funktion
fehlgeschlagen (dmlErr_Sys_Error)';
errUnadvAckTimeout = 'Timeout bei Beenden eines Links
(dmlErr_UnadvAckTimeout)';
errUnfound_Queue_ID = 'DDEML wurde mit einer ungültigen
Transaktions-ID aufgerufen (dmlErr_Unfound_Queue_ID)';
{$ELSE}
errAdvAckTimeout = 'Timeout while waiting for acknowledgement of
advise message (dmlErr_AdvAckTimeout)';
errBusy = 'DDEML is busy (dmlErr_Busy)';
errDataAckTimeout = 'Timeout while waiting for acknowledgement of
data transfer (dmlErr_DataAckTimeout)';
errDLL_Not_Initialized = 'DDEML has not been initialized
(dmlErr_DLL_Not_Initialized)';
errDLL_Usage = 'This application was not registered with DDEML for
the requested action (dmlErr_DLL_Usage)';
errExecAckTimeout = 'Timeout while waiting for acknowledgement of
macro execution (dmlErr_ExecAckTimeout)';
errInvalidParameter = 'An invalid parameter has been passed to DDEML
(dmlErr_InvalidParameter)';
errLow_Memory = 'DDEML internal memory overflow (dmlErr_Low_Memory)';
errMemory_Error = 'DDEML is unable to find some working memory to use
(dmlErr_Memory_Error)';
errNotProcessed = 'Recipient of a DDEML message has not processed the
message (dmlErr_NotProcessed)';
errNo_Conv_Established = 'Unable to establish a DDE conversation
(dmlErr_No_Conv_Established)';
errPokeAckTimeout = 'Timeout while waiting for acknowledgement of
data transfer (dmlErr_PokeAckTimeout)';
errPostMsg_Failed =
'DDEML was unable to execute a PostMessage command, the receivers
queue is full (dmlErr_PostMsg_Failed)';
errReentrancy = 'Illegal try to nest synchroneous data transfer or
callback (dmlErr_Reentrancy)';
errServer_Died = 'The server application is no longer activ
(dmlErr_Server_Died)';
errSys_Error = 'DDEML internal error, a system API function failed
(dmlErr_Sys_Error)';
errUnadvAckTimeout = 'Timeout while closing a link
(dmlErr_UnadvAckTimeout)';
errUnfound_Queue_ID = 'DDEML was called with an invalid transactions
ID (dmlErr_Unfound_Queue_ID)';
{$ENDIF}
Type
TErrRec = Record
errcode: Word;
errstr : String
End;
TErrMsg = Array [ dmlerr_First .. dmlerr_Last ] of TErrRec;
Const
DDEErrs : TErrMsg = (
(errcode: dmlErr_AdvAckTimeout; errstr: errAdvAckTimeout),
(errcode: dmlErr_Busy; errstr: errBusy),
(errcode: dmlErr_DataAckTimeout; errstr: errDataAckTimeout),
(errcode: dmlErr_DLL_Not_Initialized; errstr:
errDLL_Not_Initialized),
(errcode: dmlErr_DLL_Usage; errstr: errDLL_Usage),
(errcode: dmlErr_ExecAckTimeout; errstr: errExecAckTimeout),
(errcode: dmlErr_InvalidParameter; errstr: errInvalidParameter),
(errcode: dmlErr_Low_Memory; errstr: errLow_Memory),
(errcode: dmlErr_Memory_Error; errstr: errMemory_Error),
(errcode: dmlErr_NotProcessed; errstr: errNotProcessed),
(errcode: dmlErr_No_Conv_Established; errstr:
errNo_Conv_Established),
(errcode: dmlErr_PokeAckTimeout; errstr: errPokeAckTimeout),
(errcode: dmlErr_PostMsg_Failed; errstr: errPostMsg_Failed),
(errcode: dmlErr_Reentrancy; errstr: errReentrancy),
(errcode: dmlErr_Server_Died; errstr: errServer_Died),
(errcode: dmlErr_Sys_Error; errstr: errSys_Error),
(errcode: dmlErr_UnadvAckTimeout; errstr: errUnadvAckTimeout),
(errcode: dmlErr_Unfound_Queue_ID; errstr: errUnfound_Queue_ID));

function DefDdeCallback(CallType, Fmt: UINT; Conv: HConv; hsz1, hsz2:
HSZ;
Data: HDDEData; Data1, Data2: DWORD): HDDEData stdcall;
begin
DefDdeCallback := 0;
End;


{+------------------------------------------------------------------
| Methods of TDDEMLClass
+------------------------------------------------------------------}

Constructor TDDEMLClass.Create( aCallback: TFNCallback; flags : LongInt
);
Begin
inherited Create;
f_Timeout:= 10000;
ErrAction := ea_Log_and_Ignore;
f_codepage := CP_WINANSI;
If @aCallback = Nil Then
f_CallbackInst := DefDdeCallback
Else
f_CallbackInst := aCallback;
SetDDE_Error( DDEInitialize( f_Inst, f_CallbackInst,
flags, 0 ));
End; { TDDEMLClass.Create }

Destructor TDDEMLClass.Destroy;
Begin
If f_Inst <> 0 Then Begin
If f_Conv <> 0 Then
Disconnect;
DDEUninitialize( f_Inst );
If f_Server <> 0 Then
FreeHSz( f_Server );
If f_Topic <> 0 Then
FreeHSz( f_Topic );
End;
inherited Destroy;
End; { TDDEMLClass.Destroy }

Function TDDEMLClass.MakeHSz( aStr: PChar ): HSz;
Begin
If IsValid Then Begin
Result := DdeCreateStringHandle( f_Inst, aStr, f_codepage );
If Result = 0 Then
DDE_Error;
End
Else Begin
Result := 0;
SetDDE_Error( dmlErr_DLL_Not_Initialized );
End;
End; { TDDEMLClass.MakeHSz }

Procedure TDDEMLClass.FreeHSz( Var aHSz: HSz );
Begin
If aHSz <> 0 Then
If IsValid Then Begin
DdeFreeStringHandle( f_Inst, aHSz );
aHSz := 0;
End { If }
Else
SetDDE_Error( dmlErr_DLL_Not_Initialized );
End; { TDDEMLClass.FreeHSz }

Function TDDEMLClass.CompareHSz( HSz1, HSz2: HSz ): Integer;
Begin
CompareHSz := DdeCmpStringHandles( HSz1, HSz2 );
End; { TDDEMLClass.CompareHSz }

Function TDDEMLClass.QueryHSz( aHSz: HSz; Var aStrObj: String ):
Boolean;
Var
len: LongInt;
Begin
Result := false;
If IsValid Then Begin
len := DdeQueryString( f_Inst, aHSz, nil, 0, f_codepage );
If len = 0 Then
DDE_Error
Else Begin
SetLength( aStrObj, len );
DdeQueryString( f_Inst, aHSz, @aStrObj[1], len+1, f_codepage );
SetLength(aStrObj, StrLen(@aStrObj[1]));
Result := True;
End; { Else }
End { If }
Else
SetDDE_Error( dmlErr_DLL_Not_Initialized );
End; { TDDEMLClass.QueryHSz }

Function TDDEMLClass.Connect( aServer, aTopic: PChar): Boolean;
Begin
Connect := False;
If IsValid Then Begin
If IsConnected Then
Disconnect;
If not Failed Then Begin
If Assigned( aServer ) Then
f_Server := MakeHSz( aServer )
Else
f_Server := 0;
If Failed Then Exit;
If Assigned( aTopic ) Then
f_Topic := MakeHSz( aTopic )
Else
f_Topic := 0;
If Failed Then Exit;
f_Conv := DdeConnect( f_Inst, f_Server, f_Topic, Nil );
If f_Conv = 0 Then
DDE_Error
Else
Connect := True;
End; { If }
End { If }
Else
SetDDE_Error( dmlErr_DLL_Not_Initialized );
End; { TDDEMLClass.Connect }

Procedure TDDEMLClass.Disconnect;
Begin
If IsConnected Then Begin
DdeDisconnect( f_conv );
f_Conv := 0;
FreeHSz( f_Topic );
FreeHSz( f_Server );
End;
End; { TDDEMLClass.Disconnect }

Function TDDEMLClass.ClientTransaction( pServerData: Pointer; dataSize:
LongInt;
Item: HSz; Format, DataType: UINT ): HDDEData;
Var
temp: hDDEData;
Begin
temp := 0;
If IsConnected Then Begin
temp := DdeClientTransaction( pServerData, dataSize,
f_Conv, Item, Format, Datatype, f_timeout,
@f_lastresult );
If temp = 0 Then
DDE_Error;
End { If }
Else
SetDDE_Error( dmlErr_No_Conv_Established );
ClientTransaction := temp;
End; { TDDEMLClass.ClientTransaction }

Function TDDEMLClass.Request( Item: PChar; Format: UINT ): HDDEData;
Var
hszItem: HSz;
Begin
hszItem:= MakeHSz( Item );
If not Failed Then Begin
Request := ClientTransaction( Nil, 0, hszItem, Format,
XTYP_REQUEST );
FreeHSz( hszItem );
End { If }
Else
Request := 0;
End; { TDDEMLClass.Request }

Function TDDEMLClass.Execute( command: PChar ): Boolean;
Var
data: hDDEData;
Begin
Execute := False;
If Assigned( command ) Then Begin
data := CreateDatahandle( command, StrLen( command )+1,
0, 0, CF_TEXT, 0 );
If data <> 0 Then
Execute := ClientTransaction( Pointer( data ), cbr_Block,
0, 0, XTYP_EXECUTE ) <> 0;
End; { If }
End; { TDDEMLClass.Execute }

Function TDDEMLClass.GetData( hData: hDDEData; buf: Pointer;
bufSize, offset: LongInt ): LongInt;
Begin
GetData := DdeGetData( hData, buf, bufSize, offset );
DDE_Error;
End; { TDDEMLClass.GetData }

Function TDDEMLClass.GetDataAsStrObj( hData: hDDEData;
Var aStrObj: String ): Boolean;
Var
len: LongInt;
Begin
GetDataAsStrObj := False;
If hData <> 0 Then Begin
len := DdeGetData( hData, Nil, 0, 0 );
If len > 0 Then Begin
SetLength( aStrObj,len );
len := DdeGetData( hData, @aStrObj[1], len, 0 );
SetLength( aStrObj, StrLen(@aStrObj[1]));
GetDataAsStrObj := True;
End { If }
Else
OutOfMemoryError;
End
Else
SetDDE_Error( dmlErr_InvalidParameter );
End; { TDDEMLClass.GetDataAsStrObj }

Procedure TDDEMLClass.FreeDatahandle( hData: hDDEData );
Begin
DdeFreeDataHandle( hData );
DDE_Error;
End; { TDDEMLClass.FreeDatahandle }

Function TDDEMLClass.CreateDataHandle( source: Pointer; len, offset:
LongInt;
item: HSz; Format, Command: UINT): hDDEData;
Var
temp: hDDEData;
Begin
temp := 0;
If IsValid Then Begin
temp := DdeCreateDataHandle( f_Inst, source, len, offset,
item, format, command );
If temp = 0 Then
DDE_Error;
End { If }
Else
SetDDE_Error( dmlErr_DLL_Not_Initialized );
CreateDataHandle := temp;
End; { TDDEMLClass.CreateDataHandle }

Function TDDEMLClass.AddData( data: hDDEData;source: Pointer;
len, offset: LongInt ): hDDEData;
Var
temp: hDDEData;
Begin
temp := 0;
If data <> 0 Then Begin
temp := DdeAddData( data, source, len, offset );
If temp = 0 Then
DDE_Error;
End; { If }
AddData := temp;
End; { TDDEMLClass.AddData }

Function TDDEMLClass.AccessData( data: hDDEData; DataSize: PDWORD ):
Pointer;
Var
temp: Pointer;
Begin
temp := Nil;
If data <> 0 Then Begin
temp := DdeAccessData( data, DataSize );
If temp = Nil Then
DDE_Error;
End; { If }
AccessData := temp;
End; { TDDEMLClass.AccessData }

Procedure TDDEMLClass.UnaccessData( data: hDDEData );
Begin
If data <> 0 Then
DdeUnaccessData( data );
End; { TDDEMLClass.UnaccessData }


Function TDDEMLClass.IsConnected: Boolean;
Begin
IsConnected := f_Conv <> 0;
End; { TDDEMLClass.IsConnected }

Function TDDEMLClass.IsValid: Boolean;
Begin
IsValid := f_Inst <> 0;
End; { TDDEMLClass.IsValid }

Procedure TDDEMLClass.DDE_Error;
Begin
SetDDE_Error( DDEGetLastError( f_Inst ));
End; { TDDEMLClass.DDE }

Procedure TDDEMLClass.SetDDE_Error( err: LongInt );
Begin
f_lastError := err;
If ( err <= dmlErr_Last) and ( err >= dmlErr_First )Then
Error( EDDEMLException.Create( DDEErrs[ err ].errstr ))
Else
Failed := False;
End; { TDDEMLClass.SetDDE_Error }

End.

{+------------------------------------------------------------
| Unit ErrClass
|
| Version: 1.0 Last modified: 09/02/95, 15:50:33
| Author : P. Below
| Project: Utility classes for Delphi
| Description:
| This Unit declares a class that can serve as a base class
| for all non-visual object that need a consistent way of error
| handling. The class has an OnError property that can be
| assigned an error notification method. That method will see
| all exceptions passed to the Error method before they are
| raised and can decide to not raise them ( by returning false ).
| In addition the Unit also has a variable for a _global_
| error handler. This handler, when assigned, will see all
| exceptions passed to the Error method of _all_ instances
| of classes derived from TErrClass. The global handler gets
| first choice; if it returns false the objects local handler
| will not be called and the exception will not be raised.
| A exception not raised is automatically destroyed by Error
| so your handlers should _never_ destroy the passed exception
| object. They may raise it, however.
|
| Note that this object is only designed to organize the handling
| of exceptions you decide to raise in your code! It will not
| trap exceptions raised by VCL or runtime functions!
+------------------------------------------------------------}
Unit ErrClass;

Interface

Uses SysUtils;

Type
TErrNotification = Function( Sender: TObject;
err: Exception ): Boolean of Object;
TErrAction = ( ea_pass_on, ea_log_and_ignore, ea_report );
TErrClass = Class
private
FErr: Boolean;
FErrAction: TErrAction;
FOnError: TErrNotification;

public
Procedure Error( err: Exception ); virtual;
property OnError: TErrNotification read FOnError write FOnError;
property Failed: Boolean read FErr write FErr;
property ErrAction: TErrAction read FErrAction write FErrAction;
End;

Const
GlobalOnError: TErrNotification = Nil;


Implementation

Uses Dialogs;

Const
{$IFDEF GERMAN}
ErrText = 'Eine Ausnahme vom Typ %s ist aufgetreten:'+#13+#10+'%s';
{$ELSE}
ErrText = 'An exception of type %s was trapped:'+#13+#10+'%s';
{$ENDIF}

{************************************************************
* Error
*
* Parameters:
* err: an exception object
* Description:
* This method defines the default error handling of all classes
* derived from TErrClass. The method is virtual and can be overriden
* by a derived class.
* The default behaviour is governed by the ErrAction property as
follows:
* The default state is ea_Pass_On. In this case,
* if a global error handler is assigned it is called; if it returns
* false the exception is not raised but the object is destroyed.
*
* If no global handler is assigned or if it returns true, the local
* OnError handler of the object is examined next. If it is
assigned,
* it is called and the return value determines whether the
exception
* is raised or just destroyed.
*
* If no handler is found the exception is raised unconditional.
* If ErrAction is ea_Log_and_Ignore, the exception will destroyed but
* the FErr flag is set, so the program can test the Failed property
* to detect an error.
* If ErrAction is ea_Report, the exception is reported to the user
and
* the destroyed without beeing raised in the first place! Any
installed
* handlers are not called, if ErrAction is <> ea_Pass_On!
*
* Whatever the status of handlers: after the method has run its
course
* the exception object will be gone to bit heaven and FErr will be
True!
*
*Created: 09/02/95 15:11:42 by P. Below
************************************************************}
Procedure TErrClass.Error( err: Exception );
Var
destroy: Boolean;
Begin
FErr := True;
If not Assigned( err ) Then Exit;
Case ErrAction Of
ea_Pass_On: Begin
destroy := False;
If Assigned( GlobalOnError ) Then
destroy := not GlobalOnError( Self, err );
If not destroy Then
If Assigned( FOnError ) Then
destroy := not FOnError( Self, err );
If destroy Then
err.free
else
raise err;
End;
ea_Log_and_Ignore:
err.Free;
ea_Report: Begin
If err.HelpContext <> 0 Then
MessageDlg( Format( ErrText, [ err.Classname, err.Message ]
),
mtError, [ mbOK, mbHelp ], err.HelpContext )
Else
MessageDlg( Format( ErrText, [ err.Classname, err.Message ]
),
mtError, [ mbOK ], 0 );
err.Free;
End;
End; { Case }
End;

End.

Roger Abbott

ungelesen,
05.01.2002, 16:56:1305.01.02
an
"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote in message news:<VA.0000806...@antispam.compuserve.com>...

> In article <3C3648...@home.nl>, Erwin Dokter wrote:
> > Read my post above? (Time to brush up...) Somehow, D1 DDE components are
> > not even able to function properly as Shell DDE, which was the first
> > ever emplementation of DDE (Program Manager). I am having great
> > diffifculty providing a 'Groups' DDE item for setup programs.
>
> The Progman DDE interface was completely centered around macro commands
> you send to the server, if memory serves. So you do not access a Groups
> item, you execute a macro [GROUPS] and get back the list of groups. Has
> been ages since i played with that stuff, though, i may misremember it...

You do misremember. Groups (case insensitive) is an item you request
with format CF_TEXT. You get the contents of any group by requesting
it with the group name as item name and CF_TEXT. There is no possible
return value from executing commands except for success/failure.

Roger Abbott,
http://www.rhaminisys.com
DDE and IPC components and FAQ
Other Freeware and Shareware

Erwin Dokter

ungelesen,
05.01.2002, 17:06:5105.01.02
an
Peter Below (TeamB) wrote:
>
> The Progman DDE interface was completely centered around macro commands
> you send to the server, if memory serves. So you do not access a Groups
> item, you execute a macro [GROUPS] and get back the list of groups. Has
> been ages since i played with that stuff, though, i may misremember it...

You do...

Macro's are used to create, delete and show program groups and icons. To
*get* information, you have to request data from DDE items with the
group's name, the 'Groups' item being the list of groups.

Peter Dunne

ungelesen,
09.01.2002, 16:14:3909.01.02
an
is it possible to have an exe file work as an activeX server also?
I ask because I want to implement some code which will prevent a second
instance of an application but also will pass any command line parameters to
the running instance, I would like to do this without dde and cannot see how
to pass the parameters otherwise, any suggestions on where to go with this
would be appreciated


Thanks in advance
Peter

http://www.gda.bizhosting.com


Peter Below (TeamB) <10011...@compuXXserve.com> wrote in message ...


>In article <3c360f75_1@dnews>, Henrik Nedergaard wrote:
>> Have you seen anyone making any examples on how to do that,

<snipped>

peter dunne.vcf

Robby Tanner

ungelesen,
09.01.2002, 18:07:3309.01.02
an
The short answer is yes.

However, there are numerous ways to do this. Check any sample code for
single instance verification and there should be some tips in there. If
not, what you want is some IPC (inter-process communication). There are
numerous ways of doing this without resorting to ActiveX; named pipes,
mutexes, shared memory files, sockets, the list goes on.

I think there is even a windows messages (WM_SENDDATA or something) that
will allow you to send and trap IPC.

I'm a little vague, because a lot of this I haven't done myself, but you're
certainly not stuck with those buggy DDE components that encapsulate a
poorly designed protocol.

Rob

"Peter Dunne" <refuge...@hotmail.com> wrote in message
news:3c3cb2c8_1@dnews...

Peter Below (TeamB)

ungelesen,
10.01.2002, 14:12:2410.01.02
an
In article <3c3cb2c8_1@dnews>, Peter Dunne wrote:
> is it possible to have an exe file work as an activeX server also?
> I ask because I want to implement some code which will prevent a second
> instance of an application but also will pass any command line parameters to
> the running instance, I would like to do this without dde and cannot see how
> to pass the parameters otherwise, any suggestions on where to go with this
> would be appreciated

Making an app a OLE automation server would be gross overkill for this
problem. Use WM_COPYDATA messages.

Open the projects DPR file (Project|View source) and add this line immediately
after the Begin of the main block:

If Alreadyrunning Then Exit;

Then scroll up and add this function after the Uses clause:

Function AlreadyRunning: Boolean;
Var
wnd: HWND;
S: String;
copydata: TCopyDataStruct;
Begin
wnd:= FindWindow('TMyAppsMainformclass', Nil );
Result := wnd <> 0;
If Result and (ParamCount > 0) Then Begin
S:= ParamStr(1);
With copydata Do Begin
dwData := 0;
cbData := Length(S)+1; {Need to transfer terminating #0 as well}
lpData := @S[1];
End;
SendMessage( wnd, WM_COPYDATA, 0, LPARAM( @copydata ));
End;
End;

Note that you need to make sure the main form class for your application has a
reasonably unique name, so FindWindow finds the correct window.

The second change needed is made to the main form class itself. It needs a
handler for the WM_COPYDATA message.

private
{ Private declarations }
procedure WMCopyData(Var msg: TWMCopyData); message WM_COPYDATA;

Procedure TMyAppsMainformclass.WMCopyData(Var msg: TWMCopyData);
Var
param : String;
Begin
param := PChar(msg.CopyDataStruct^.lpData);
...process param
End;

Peter Dunne

ungelesen,
12.01.2002, 14:34:0612.01.02
an
Thanks Peter
Much appreciated
I would like to put credits to yourself & TeamB in my source, do you have a
url I can use
Basically I believe it is only fair to credit the people who supply snippets
to me
--
Regards
Peter I. Dunne

http://www.gda.bizhosting.com (A developers site by developers for
developers)
No attachments in replies unless requested please

Peter Below (TeamB) <10011...@compuXXserve.com> wrote in message ...

Peter Below (TeamB)

ungelesen,
13.01.2002, 08:45:1013.01.02
an
In article <3c408fb4$1_2@dnews>, Peter Dunne wrote:
> I would like to put credits to yourself & TeamB in my source, do you have a
> url I can use

http://www.teamb.com may do.



Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!

Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


Allen antworten
Dem Autor antworten
Weiterleiten
0 neue Nachrichten