Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2001-10

Create an OCX with FreePascal

29 messages · 14 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Cabuzel Thierry

Hi,

Is there a way to create OCX in FreePascal ? If it is possible, did you have some example ?

Thierry Cabuzel

Michael Van Canneyt
to Cabuzel Thierry
Cabuzel Thierry wrote
Hi, Is there a way to create OCX in FreePascal ? If it is possible, did you have some example ?

I don't know what the OCX format is, if it is a simple .dll, then it should be possible. If it is a special format, it will not be possible at this moment.

Michael.

Sebastian Günther
to Michael Van Canneyt: I don't know what the OCX format is, if it is a simple .dll, then it should be possible.…
Michael Van Canneyt wrote
I don't know what the OCX format is, if it is a simple .dll, then it should be possible.

an OCX is a DLL, which follows some special convention (exportet names etc.). Writing an ActiveX Control by hand should be possible with FPC, but it isn't trivial, as you have to implement a lot of COM interfaces. I think Visual C++ or the Platform SDK come with some examples how to write such a thing by hand, they should translate to FPC quite straightforwardly.

- Sebastian

Cabuzel Thierry
Show quoted text 41 lines
-----Original Message----- From: Dirk Mattes Sent: jeudi 11 octobre 2001 15:00 To: Subject: AW: [fpc-pascal]Create an OCX with FreePascal Hi all, > Michael Van Canneyt wrote: > > > > I don't know what the OCX format is, if it is a simple > .dll, then it should > > be possible. > > an OCX is a DLL, which follows some special convention (exportet names > etc.). Writing an ActiveX Control by hand should be possible with FPC, > but it isn't trivial, as you have to implement a lot of COM > interfaces. > I think Visual C++ or the Platform SDK come with some examples how to > write such a thing by hand, they should translate to FPC quite > straightforwardly. to write COM-Objects in FPC is possible and not difficult too much. But an OCX (ActiveX-Control) is a problem, cause has to do with OLE-Automation. Like Michael says, you have to implement many interfaces (i.e. IDispatch for late-binding your methods, IEnumVARIANT and others), that Delphi or VC creates automaticly or Automation gives you in order to you type library. Most of your interfaces have to be comaptible with OLE-Automation. You also have to convert many Header files for constants that OLE uses (like VT_DISPATCH and many others). So, forget about it an use Delphi or VC.

Arg, that's what I doesn't want to hear. But more I read answer from my post, more I feel that's will be the final answer. I think i will go to create a DLL in FP, then write an wrapper OCX in Delphi if I found someone who have Delphi...

Michael Van Canneyt
to Cabuzel Thierry
Cabuzel Thierry wrote 46 lines
> -----Original Message----- > From: Dirk Mattes > Sent: jeudi 11 octobre 2001 15:00 > To: > Subject: AW: [fpc-pascal]Create an OCX with FreePascal > > > Hi all, > > > Michael Van Canneyt wrote: > > > > > > I don't know what the OCX format is, if it is a simple > > .dll, then it should > > > be possible. > > > > an OCX is a DLL, which follows some special convention > (exportet names > > etc.). Writing an ActiveX Control by hand should be > possible with FPC, > > but it isn't trivial, as you have to implement a lot of COM > > interfaces. > > I think Visual C++ or the Platform SDK come with some > examples how to > > write such a thing by hand, they should translate to FPC quite > > straightforwardly. > > to write COM-Objects in FPC is possible and not difficult too much. > > But an OCX (ActiveX-Control) is a problem, cause has to do with > OLE-Automation. Like Michael says, you have to implement many > interfaces > (i.e. IDispatch for late-binding your methods, IEnumVARIANT > and others), > that Delphi or VC creates automaticly or Automation gives you in order > to you type library. Most of your interfaces have to be > comaptible with > OLE-Automation. You also have to convert many Header files > for constants > that OLE uses (like VT_DISPATCH and many others). > > So, forget about it an use Delphi or VC. Arg, that's what I doesn't want to hear. But more I read answer from my post, more I feel that's will be the final answer. I think i will go to create a DLL in FP, then write an wrapper OCX in Delphi if I found someone who have Delphi...

You can register and download Delphi 6 personal edition for free from borlands web site. I don't know whether it contains the ActiveX functionality, it may b e that you need the Professional or Enterprise version for that.

Michael.

Gabor DEAK JAHN
to Cabuzel Thierry: Arg, that's what I doesn't want to hear. But more I read answer from my post, more I feel…

At 10/11/01 03:35 PM, you wrote:

Thierry,

Arg, that's what I doesn't want to hear. But more I read answer from my post, more I feel that's will be the final answer. I think i will go to create a DLL in FP, then write an wrapper OCX in Delphi if I found someone who have Delphi...

It depends on what you could locate in Delphi (or C++) source code. Implementing everything from scratch, using the MSDN documentation would be possible but would require a lot of work. But if you could start with a complete source example, turning that into FPC would be simpler (although it would still require a basic understanding of how COM works).

I often use COM/OLE from FPC (and sometimes, unfortunately, from C which is equivalent to FPC in this respect), the first time you do it you have to write (or collect) some helper routines but later on, it's not that complicated. You certainly have to provide the glue for the various elements yourself but if you had already done it once, the code structure is reusable.

Regards,

   Gabor DEAK JAHN

------------------------------------------------------------------- Gabor DEAK JAHN -- Budapest, Hungary.
WWW: www.tramontana.co.hu
E-mail:

Cabuzel Thierry

Ok, thanks everyone :) Now I have a bunch of choices :)

- Let's it as a DLL
- Wrote a wrapper in C++ around the DLL
- Buy a Delphi 3,4,5 or 6 Pro or C/S and create directly the OCX

If I have too much time in my hands, I will get an eye in the MSDN and wrote an FPC OCX how-to. And after that, if someone else have too much time too, why not implement it into FPC.

Thierry Cabuzel

Michael Van Canneyt
to Cabuzel Thierry
Cabuzel Thierry wrote 9 lines
Ok, thanks everyone :) Now I have a bunch of choices :) - Let's it as a DLL - Wrote a wrapper in C++ around the DLL - Buy a Delphi 3,4,5 or 6 Pro or C/S and create directly the OCX If I have too much time in my hands, I will get an eye in the MSDN and wrote an FPC OCX how-to. And after that, if someone else have too much time too, why not implement it into FPC.

Version 1.1 has support for interfaces. In principle, some of the basic Delphi interfaces (TInterfacedObject and so on) can be made, so this should not be too difficult.

Michael.

Andreas K. Foerster
to Hakimov Rahmatjon
Hakimov Rahmatjon wrote
Men, I beg you all. Anybody, PLEASE, send me in attachment full install package of FPC for Linux Debian. I don't have possibility to download it.

Huh?
FPC is included in Debian!
Although it's not the newest version.

Tschuess Andreas
Fernando Lozano
to Michael Van Canneyt: Version 1.1 has support for interfaces. In principle, some of the basic Delphi interfaces…

Hi there,

Show quoted text 7 lines
> If I have too much time in my hands, I will get an eye in the MSDN and wrote > an FPC OCX how-to. And after that, if someone else have too much time too, > why not implement it into FPC. Version 1.1 has support for interfaces. In principle, some of the basic Delphi interfaces (TInterfacedObject and so on) can be made, so this should not be too difficult.

I'd be very gratefull if someone with spare time could write a tutorial on how to use ODBC and ADO from Free Pascal apps.

[]s, Fernando Lozano

Unknown author
to Fernando Lozano
Fernando Lozano wrote 13 lines
Hi there, > > If I have too much time in my hands, I will get an eye in the MSDN and wrote > > an FPC OCX how-to. And after that, if someone else have too much time too, > > why not implement it into FPC. > > Version 1.1 has support for interfaces. In principle, some of the basic > Delphi interfaces (TInterfacedObject and so on) can be made, so this should > not be too difficult. I'd be very gratefull if someone with spare time could write a tutorial on how to use ODBC and ADO from Free Pascal apps.

I'd be very grateful if someone with spare time could donate the translated ODBC headers. Then I would write this at once, since I could very well use it.

Michael.

Andreas K. Foerster
Hakimov Rahmatjon wrote
What do you want to say? Write me.

I wanted to say, that I can't write to your e-mail address. Is it really correct?

Tschuess Andreas
the reverend
to Unknown author: Is there a library that allows to write an apache module with fpc, like with Delphi ? (or…

given the following:

-------------
program test;
var p: ^word;
begin
  if assigned(p) then writeln('assigned')
  else writeln('unassigned');
end.
-------------

p is unassigned as expected, but:

------------
program test;
procedure temp;
var p: ^word;
begin
  if assigned(p) then writeln('assigned')
  else writeln('unassigned');
end;
begin
  temp;
end.
-------------

why is p assigned? shouldn't p be nil in this case also?

Jonas Maebe
to the reverend
the reverend wrote 17 lines
given the following: ------------- program test; var p: ^word; ------------- p is unassigned as expected, but: ------------ program test; procedure temp; var p: ^word; ------------- why is p assigned? shouldn't p be nil in this case also?

First of all, assigned() just checks if the value of the pointer is different from nil (= 0). If it is, it reports true, otherwise false.

Next, global data is automatically initialized by the linker to 0. Global data is allocated on the stack when you call a routine adn this memory is not zeroed. One reason for this is that it would probably significantly slow down your program, since these variables are allocated every time you call said procedure/function.

As a general rule of the thumb, you should regard any variable which you haven't assigned a value yet hjust like that: uninitialized, which means their value is undefined.

Jonas

the reverend
to Jonas Maebe

ok - i can handle that... but i was using the result of assigned to decide if i should free the memory when i was finished with it, i.e. if pnil then freemem(p); what should i do instead?

ron.

Earlier message 47 lines
-----Original Message----- From: Behalf Of Jonas Maebe Sent: Friday, October 19, 2001 5:19 PM To: Subject: Re: [fpc-pascal]help with pointers? On Fri, 19 Oct 2001, the reverend wrote: > given the following: > > ------------- > program test; > var p: ^word; > ------------- > > p is unassigned as expected, but: > > ------------ > program test; > > procedure temp; > var p: ^word; > ------------- > > why is p assigned? shouldn't p be nil in this case also? First of all, assigned() just checks if the value of the pointer is different from nil (= 0). If it is, it reports true, otherwise false. Next, global data is automatically initialized by the linker to 0. Global data is allocated on the stack when you call a routine adn this memory is not zeroed. One reason for this is that it would probably significantly slow down your program, since these variables are allocated every time you call said procedure/function. As a general rule of the thumb, you should regard any variable which you haven't assigned a value yet hjust like that: uninitialized, which means their value is undefined. Jonas
Ivan Montes
to the reverend
ok - i can handle that... but i was using the result of assigned to decide if i should free the memory when i was finished with it, i.e. if pnil

then

freemem(p); what should i do instead? ron.

Hi,

Let me explain this with an example. In a program you implement a function called InitPointers that initializes your variables. Then you create another function called ClosePointers that frees your variables. If you call first InitPointers and after ClosePointers everything should be fine. But not if you do in the opposite way (first ClosePointers).

So every time you want to free a pointer you have to be sure that the pointer was initialized. If you don't want to assign any memory to the pointer, just declare ptrvar:=NIL. And then you will be sure that Freemem(ptrvar); will not give problems, even if ptrvar is NIL.

bye, Ivan

the reverend
to Ivan Montes

so freemem(nil) will not give an error? ok. thanks. i'll just initialize all my pointers to nil if i am not going to assign memory to them... i'm using an array of records with pointers defined in the record... sometimes i need to put data in those pointers, and sometimes i don't. i want to conserve memory by leaving the unused pointers as nil.

----------------------------------
Hi,

Let me explain this with an example. In a program you implement a function called InitPointers that initializes your variables. Then you create another function called ClosePointers that frees your variables. If you call first InitPointers and after ClosePointers everything should be fine. But not if you do in the opposite way (first ClosePointers).

So every time you want to free a pointer you have to be sure that the pointer was initialized. If you don't want to assign any memory to the pointer, just declare ptrvar:=NIL. And then you will be sure that Freemem(ptrvar); will not give problems, even if ptrvar is NIL.

bye, Ivan

Jonas Maebe
to the reverend
the reverend wrote
so freemem(nil) will not give an error? ok. thanks. i'll just initialize

freemem(nil) will result in a run time error 204. Pascal is a language (just like C, and for the most part C++ as well) where most memory management is manual: you (and only you) are responsible for the proper allocation, management and deallocation of memory for dynamic data structures.

This means you must make sure your program can keep track in one way or another of which pointers are already initialized and when they have to be freed. There is no magic trick to get around this, unless you switch to environment in which all memory management is handled for you by the run time system (such as Java).

Jonas

Matt Emson
to Jonas Maebe
Show quoted text 5 lines
This means you must make sure your program can keep track in one way or another of which pointers are already initialized and when they have to be freed. There is no magic trick to get around this, unless you switch to environment in which all memory management is handled for you by the run time system (such as Java).

The best advice is to always initialize your pointers to nil before using them, and set them back to nil after you have deallocated the memory they point to (the second part is necessary in Delphi, please correct me if I'm wrong.)

Secondly, if you use the try.. finaly construct whereever possible in routines that use local pointer variables, you will save yourself a lot of work:

var
  X: ^word;
begin
  X := nil; //initialize X ... possible this could be an allocation from
new() etc..
  try
     //do something with X
  finally
    if assigned(X) then
       ; //free X
   end;
end;

If you are carefull about the way you lay out your code, the 'assigned' test can be removed.

Better still, don't use pointers ;-) Almost everything you can do with pointers can be done with classes and references (cf. Java - no pointers)

Matt

--- Don't have BeOS? Get it! - http://free.be.com/ Wanna keep BeOS alive? Save BeOS - http://www.BeFAQs.com/save/saveform.html -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
Marco van de Voort
to Matt Emson
Show quoted text 10 lines
>This means you must make sure your program can keep track in one way or >another of which pointers are already initialized and when they have to be >freed. There is no magic trick to get around this, unless you switch to >environment in which all memory management is handled for you by the run >time system (such as Java). The best advice is to always initialize your pointers to nil before using them, and set them back to nil after you have deallocated the memory they point to (the second part is necessary in Delphi, please correct me if I'm wrong.)

There are two distinct reasons to set them back to nil.

- One should set _all_ pointers ack to NIL in windows, because NIL is in protected space in Windows, and will trigger an exception if it is defereferenced.

- Certain automatic functionality in Delphi needs _some_ values to be NILled after use.

On other systems, other values may apply btw. That's why it is good to have freeandnil (though I don't like the name, since it seems to imply zero). If one needs another OS (or windows versions) to set old unused pointers to $FFFFFFFF in order to have the processor detect a violation, only freeandnil must be adjusted.

One can even extend that further, and have two different libraries. E.g. the debugging library FreeAndNill resets the pointer to an easy to detect value like $DEADBEEF

Matt Emson
to Gabor DEAK JAHN: There are two ways, SHGetSpecialFolderLocation and SHGetSpecialFolderPath. With the…

Wasn't me, some other guy. I just told how it usually get's done in Delphi.

Matt

Show quoted text 34 lines
Matt, > You may be able to get away with dropping the IMalloc calls. I really don't > know. You may end up crashing/screwing up Explorer though, as Explorer ('the > shell') has to explicitly release all memory it allocates. There are two ways, SHGetSpecialFolderLocation and SHGetSpecialFolderPath. With the second, you have to use IMalloc because the system allocates the memory and expects you to free it. Therefore, Using SHGetSpecialFolderPath seems to be much simpler (it is a single call, not the complex structures you quoted, returning the path directly instead of a PIDL which you have to convert to a path and deallocate yourself) but the problem is that it is only available starting from version of 4.71 of Shell32.dll (this means 2000, ME or Internet Explorer 4.0 or later installed on previous systems). However, there is a redistributable ShFolder.dll which you are free to include with your program and then you'll be able to use this simpler function on any system and version. Bye, Gábor ------------------------------------------------------------------- Gabor DEAK JAHN -- Budapest, Hungary. E-mail: _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
--- Don't have BeOS? Get it! - http://free.be.com/ Wanna keep BeOS alive? Save BeOS - http://www.BeFAQs.com/save/saveform.html -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
Full_Name
to the reverend: how can i divine the path to the desktop for the current user? i want my program to…

Quoting the reverend :

how can i divine the path to the desktop for the current user? i want my program to deploy a report file to the desktop without asking the user for the path. can someone help me? i know someone has to know how to do this.

This is the method used in Delphi, you might get this to work in FPC, but I doubt it will in anything other that 1.1:

////////////////////////////////////////////////////////////////////////////
const
  CSIDL_DESKTOPDIRECTORY = $0010; //comes from unit 'shlObj'
  shell32 = 'shell32.dll'; //comes from unit 'shlObj'
type
  { TSHItemID -- Item ID } //comes from unit 'shlObj'
  PSHItemID = ^TSHItemID;
  _SHITEMID = record
    cb: Word;                         { Size of the ID (including cb itself) }
    abID: array[0..0] of Byte;        { The item ID (variable length) }
  end;
  TSHItemID = _SHITEMID;
  SHITEMID = _SHITEMID;
  //comes from unit 'shlObj'
  { TItemIDList -- List if item IDs (combined with 0-terminator) }
  PItemIDList = ^TItemIDList;
  _ITEMIDLIST = record
     mkid: TSHItemID;
   end;
  TItemIDList = _ITEMIDLIST;
  ITEMIDLIST = _ITEMIDLIST;
  //comes from unit 'ActiveX'
  IMalloc = interface(IUnknown)
    ['{00000002-0000-0000-C000-000000000046}']
    function Alloc(cb: Longint): Pointer; stdcall;
    function Realloc(pv: Pointer; cb: Longint): Pointer; stdcall;
    procedure Free(pv: Pointer); stdcall;
    function GetSize(pv: Pointer): Longint; stdcall;
    function DidAlloc(pv: Pointer): Integer; stdcall;
    procedure HeapMinimize; stdcall;
  end;
//comes from unit 'shlObj'
function SHGetSpecialFolderLocation(hwndOwner: HWND; nFolder: Integer; var
ppidl: PItemIDList): HResult; stdcall; external shell32
name 'SHGetSpecialFolderLocation';
//comes from unit 'shlObj'
function SHGetPathFromIDList(pidl: PItemIDList; pszPath: PChar): BOOL; stdcall;
external shell32 name 'SHGetPathFromIDListA';
//comes from unit 'shlObj'
function SHGetMalloc(var ppMalloc: IMalloc): HResult; stdcall; external shell32
name 'SHGetMalloc';
//Can't remember where from, somewhere on the 'net. I altered it to
//give the desktop dir.. there are other ID that can be used instead,
//(gets things like 'Program files', 'windows', 'windows\system' etc)
function GetDesktopPath: string;
var
  PIDL: PItemIDList;
  Path: LPSTR;
  AMalloc: IMalloc;
begin
  Path := StrAlloc(MAX_PATH);
  try
    SHGetSpecialFolderLocation(Application.handle,
                               //replace this for other paths..
                               CSIDL_DESKTOPDIRECTORY,
                               PIDL
                               );
    if SHGetPathFromIDList(PIDL, Path) then
      Result := Path;
    SHGetMalloc(AMalloc); //this will cause you a problem...
    AMalloc.Free(PIDL);   //as will this...
  finally
    StrDispose(Path);
  end;
end;
//////////////////////////////////////////////////////////////////////

You may be able to get away with dropping the IMalloc calls. I really don't know. You may end up crashing/screwing up Explorer though, as Explorer ('the shell') has to explicitly release all memory it allocates.

Hope that helps..

Matt

"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." Kristian Wilson, Nintendo, Inc, 1989 -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
Full_Name
to Full_Name

Quoting Full_Name :

This is the method used in Delphi, you might get this to work in FPC, but I doubt it will in anything other that 1.1:

Just tested this under 1.1, and it does compile. The version of 1.1 I have seems to have issues with linking it, and I don't have time to go through them. It came back with a complaint that there was a missing entry point in User32, I believe the routine was 'enumtaskwindow(s?)'. I guess this is fixed by now.

Incidentally, the linker had to be pursuaded into linking. It complained about 'libpwindows.aw' being missing. I guess the error about missing entry points is related to this.

Anyway, I'm guessing that if the app ran, you might get some sort of luck.. who knows. Works perfectly under Delphi, anyway ;-)

Matt

"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." Kristian Wilson, Nintendo, Inc, 1989 -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
Gabor DEAK JAHN
to Full_Name: Quoting the reverend : This is the method used in Delphi, you might get this to work in…

At 11/1/01 10:15 AM, you wrote:

Matt,

You may be able to get away with dropping the IMalloc calls. I really don't know. You may end up crashing/screwing up Explorer though, as Explorer ('the shell') has to explicitly release all memory it allocates.

There are two ways, SHGetSpecialFolderLocation and SHGetSpecialFolderPath. With the second, you have to use IMalloc because the system allocates the memory and expects you to free it. Therefore, Using SHGetSpecialFolderPath seems to be much simpler (it is a single call, not the complex structures you quoted, returning the path directly instead of a PIDL which you have to convert to a path and deallocate yourself) but the problem is that it is only available starting from version of 4.71 of Shell32.dll (this means 2000, ME or Internet Explorer 4.0 or later installed on previous systems).

However, there is a redistributable ShFolder.dll which you are free to include with your program and then you'll be able to use this simpler function on any system and version.

Bye,
Gábor

------------------------------------------------------------------- Gabor DEAK JAHN -- Budapest, Hungary.
E-mail: