DDE / OLE

DDE / OLE

GroupFile and additems to Group
Ole Automation on Delphi16
OLE Server
DDE- passing text
How to add a group to the program manager
Getting DDE to talk to Program Manger under Win95


GroupFile and additems to Group

Question


How to create groups in program manager?

Answer


A:

Here is the code for creating a group file and add an item file to the

group. To use the procedure, specify the DDE clientconv App as ProgMan.



******************************************************

procedure TMainForm.CreateWinGroup(Sender: TObject);

var

  Name: string;

  Name1: string;

  Macro: string;

  Macro1: string;

  Cmd, Cmd1: array[0..255] of Char;

begin

 {destDir is the dos directory to hold the YourFile.Ext'}

    Name := 'GroupName';

    Name1 := destDir + 'YourFile.Ext, FileName_in_Group  ';

    Macro := Format('[CreateGroup(%s)]', [Name]) + #13#10;

    Macro1 :=Format('[Additem(%s)]',[Name1]) +#13#10;

    StrPCopy (Cmd, Macro);

    StrPCopy (cmd1, Macro1);

    DDEClient.OpenLink;

    if not DDEClient.ExecuteMacro(Cmd, False) then

      MessageDlg('Unable to create group '+Name,mtInformation, [mbOK], 0)

    else

      begin

      DDEClient.ExecuteMacro(Cmd1, False);

      end;

    DDEClient.CloseLink;



end;


Ole Automation on Delphi16

Question


Can Delphi16 do Ole Automation?

Answer


A:

Delphi 16 can do OLE Automation, and just about anything else. But

there are no nifty pre-built components nor objects to make the job as

easy as it is to do most other things in Delphi. Delphi32 should have a

all of the OLE features managed in someway (at least I hope so).



So if you are going to do any OLE server types of actions then you have

to use all of the mean and nasty Windows SDK routines for it. However

there may be a component that will manage the stuff for you. If so it is

not from Borland.


OLE Server

Question


I want to make an OLE-server with Delphi. In OLE you pass 'Interfaces'

around, which are basically structures with function pointers. I need

to be able to generate these structures and to call functions defined

by those structures. The problem is that the functions use the 'c'

calling convention, which Delphi supports (sort of) with the 'cdecl'

keyword. I say 'sort of' because the following wont compile:



  ...

  interface

    function OLEfunction(x, y, z: integer): integer; cdecl; export;

  implementation

    function OLEfunction(x, y, z: integer): integer;

    begin

    end;



    procedure buildOLEstructure;

    var

      F: function (x, y, z: integer): integer; { need 'cdecl' here }

    begin

      F := OLEfunction; { Type mismatch here... }

    end;



This will not compile, because of a type mismatch caused by the 'cdecl'

on the function (which I really need) and the missing 'cdecl' on the

definition of the variable 'F'. In this example I could live with a

simple pointer-definition for F, because I don't need to call the

function myself, but OLE sometimes gives me a pointer to a 'cdecl'

function, which I need to call myself. As I see it, there is no way

that this is possible. Am I right in this assumption?

Answer


A:

The following code compiled OK. It's not so clean but it may help you:



  unit Unit1;



  interface

	 function OLEfunction(x, y, z: integer): integer; cdecl; export;

  implementation





	 function OLEfunction(x, y, z: integer): integer;

	 begin

	 end;



	 procedure buildOLEstructure;

	 var

		F: pointer;

	 begin

		F := @OLEfunction; { Compiles OK ... }

	 end;





   end.



A:

Use the approach that follows. You have to declare one calling function for

each combination of parameters that you are going to pass. Then you call the

calling function passing as a pointer the function you want to call.



library Pcdecl;



function olefunction(a1 : pchar; a2 : longint; x : integer )  : integer;

		cdecl; export;

begin

	end;



function callolefunction(func : pointer; a1 : pchar; a2 : longint; x :

integer)  : integer;

	assembler;

asm

	push	x	            { push parameters in reverse order }

	push	word ptr a2 + 2     { if a 32 bit value push it in two steps, starting

with the high part }

	push	word ptr a2

	push	word ptr a1 + 2

	push	word ptr a1

	call	func

	add	sp, 10		     { restore stack by adding back the bytes pushed. Note that

func is not pushed }

	end;



procedure buildolefunction;

var

	f	: pointer;

	reslt	: integer;

begin

	f := @olefunction;

	{ --- }

	reslt := callolefunction(f, 'hello world', 1000000, 25);

	{ --- }

	end;



begin

	{ --- }

end.





This compiled perfectly well in my computer. It should do the job.

Warning. Methods should be treated slightly different than functions.


DDE- passing text

Question


I just want to pass a text value from a ddeclient to a ddeserver using

pokedata.

I have , however, found it strangely difficult. I've put all relevant

values as watches to see what was happening and found that the ddeItem

property was a nil string!! It should be something like ddeServerItem1.

The following is some example code. See if you can spot any deliberate

mistakes.





procedure TForm2.Button2Click(Sender: TObject);

Var

  DDeCli : TDdeClientConv;

  SPtr : array[0..200] of char;

begin

 {DdeClientItem1.DdeItem := 'DdeServerItem1'; what it should be?}

  DdeCli := DdeClientItem1.DdeConv;

  if DdeCli  <> nil then

    DdeCli.PokeData(DdeClientItem1.DdeItem, StrPCopy(SPtr, Edit1.Text));

end;



As you can see when button2 is hit it should poke the data from an

editbox upto the ddeServer. It doesn't work. {even when i included the

bracketed code}

What am i missing. I bet it's pretty obvious.



Answer


A:

     This works for me when poking to Excel:



        DDEClientConv1.SetLink('Excel','Sheet1');

        try

          DDEClientConv1.OpenLink;

          DDEClientItem1.DDEItem:= 'R1C1';

          DDEClientConv1.PokeData(DDEClientItem1.DDEItem,

                    StrPCopy(P, SomeString)));

        finally

          DDEClientConv1.CloseLink;

        end;



     As you see the DDEItem property is determined by the server. If your

     server is a Delphi application, the DDEItem is the name of the

     DDEServerItem. I wouldn't trust debugging DDE programs too much, if I

     were you. There is a lot of synchronization involved, that goes either

     right or wrong when debugging.


How to add a group to the program manager

Question


I am writing an installation utility , but i don't know how to add a group

and icon to the program manager.

Answer


A:

interface

procedure CreateGroup;



implementation



procedure TSetupForm.CreateGroup;

{ Uses the TProgMan component to install Program Manager group }

var

  ItemList: TStringList;

  GroupName: String;

  ItemName: String;

  i: word;

begin

  { Get the GroupName string from the INI file }

  GroupName := IniFile.ReadString('General', 'PMGroup', '');

  { If there is one, then install group }

  if GroupName <> '' then begin

    ItemList := TStringList.Create;

    try

      { read items to be installed }

      IniFile.ReadSectionValues('PMGroup', ItemList);

      with TProgMan.Create(Self) do

      try

        CreateGroup(GroupName);

        for i := 0 to ItemList.Count - 1 do begin

          { get file name }

          ItemName := Copy(ItemList.Strings[i], 1, Pos('=',

                           ItemList.Strings[i]) - 1);

          { append file name to path and add the item }

          AddItem(GetTarget(ItemList.Values[ItemName][1]) + ItemName, ItemName);

        end;

      finally

        Free;

      end;

    finally

      ItemList.Free;

    end;

  end;

end;


Getting DDE to talk to Program Manger under Win95

Question


Is there a special trick to getting DDE to establish a link with

program Manger using DDE, when uisng Win95 (V1.0 of delphi)?

Answer


A:

I've been using the following unit to manage program groups using dde to

progman. It's an adaption of Steve Texeira's(sp) code in Dephi Developers Guide.



have had success in 3.1 and '95.



unit Pm;



interface



uses

  SysUtils, Classes, DdeMan;



type

  EProgManError = class(Exception);



  TProgMan = class(TComponent)

  private

    FDdeClientConv: TDdeClientConv;

    procedure InitDDEConversation;

    function ExecMacroString(Macro: String): Boolean;

  public

    constructor Create(AOwner: TComponent); override;

    destructor Destroy; override;

    Procedure CreateGroup(GroupName: String; ShowGroup:Boolean);

    procedure DeleteGroup(GroupName: String);

    procedure DeleteItem(ItemName: String);

    procedure AddItem(CmdLine, ItemName: String);

  end;



implementation



uses Utils;



const

  { Program Manager DDE macro strings }

  SDDECreateGroup   = '[CreateGroup(%s)]';

  SDDEShowGroup     = '[ShowGroup(%s, 1)]';

  SDDEDeleteGroup   = '[DeleteGroup(%s)]';

  SDDEDeleteItem    = '[DeleteItem(%s)]';

  SDDEAddItem       = '[AddItem(%s, "%s", %s)]';



constructor TProgMan.Create(AOwner: TComponent);

begin

  inherited Create(AOwner);

  InitDDEConversation;

end;



destructor TProgMan.Destroy;

begin

  if Assigned(FDDEClientConv) then

    FDdeClientConv.CloseLink;

  inherited Destroy;

end;



function TProgMan.ExecMacroString(Macro: String): Boolean;

Begin

  StringAsPchar(Macro);

  Result := FDdeClientConv.ExecuteMacro(@Macro[1], False);

End;



Procedure TProgMan.InitDDEConversation;

begin

  FDdeClientConv := TDdeClientConv.Create(Self);

  If NOT FDdeClientConv.SetLink('PROGMAN', 'PROGMAN') then

    raise EProgManError.Create('Failed to establish DDE Link');

end;



Procedure TProgMan.CreateGroup(GroupName: String; ShowGroup:Boolean);

Begin

  { Delete the group if it exists }

  ExecMacroString(Format(SDDEDeleteGroup, [GroupName]));



  If NOT ExecMacroString(Format(SDDECreateGroup, [GroupName])) then

    raise EProgManError.Create('Could not create group ' + GroupName);

  If ShowGroup then

    If not ExecMacroString(Format(SDDEShowGroup, [GroupName])) then

      raise EProgManError.Create('Could not show group ' + GroupName);

End;



Procedure TProgMan.DeleteGroup(GroupName: String);

Begin

  if NOT ExecMacroString(Format(SDDEDeleteGroup, [GroupName])) then

    raise EProgManError.Create('Could not delete group ' + GroupName);

End;



Procedure TProgMan.DeleteItem(ItemName: String);

Begin

  if NOT ExecMacroString(Format(SDDEDeleteGroup, [ItemName])) then

    raise EProgManError.Create('Could not delete item ' + ItemName);

End;



Procedure TProgMan.AddItem(CmdLine, ItemName: String);

Var

  P: PChar;

  PSize: Word;

Begin

  PSize := StrLen(SDDEAddItem) + (Length(CmdLine) *2) + Length(ItemName) + 1;

  GetMem(P, PSize);

  try

    StrFmt(P, SDDEAddItem, [CmdLine, ItemName, CmdLine]);

    if NOT FDdeClientConv.ExecuteMacro(P, False) then

      raise EProgManError.Create('Could not add item ' + ItemName);

  finally

    FreeMem(P, PSize);

  end;

End;



end.


Close    To Top
  • Prev Article-Programming:
  • Next Article-Programming:
  • Now: Tutorial for Web and Software Design > Programming > delphi > Programming Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction