Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Calling a Print.DLL externally 1

Status
Not open for further replies.

tjcusick

Programmer
Dec 26, 2006
134
US
We have a program and want to have the printing procedure to be a seperate DLL. So i tried the following but when i trace through it, it goes into the DLL procedure to the Begin but immediately goes to the End without touching any of the code.

Code:
[b]type[/b]
  Tkiosklabelprint =procedure (pFamRecord    : TFamRecord;
                                pIndRecord    : TIndRecord;
                                plblInfo      : TLabelInfoObj;
                                LWL:String; [b]var[/b] DoOnce:Boolean); StdCall;

  EDLLLoadError= [b]class[/b](Exception);

  TfrmAddlOptions = [b]class[/b](TForm)
     ...

[b]procedure[/b] TfrmAddlOptions.agbtnPrintClick(Sender: TObject);
[b]var[/b]
  i:integer;   
  myFamTbl: TCBTable;
  LWL: String;
[b]begin[/b]          
  SetupUSERTable(myFamTbl, [teal]'USER\CSFAMILY.UDB'[/teal]);
  [b]for[/b] i:= [purple]1[/purple] [b]to[/b] IndListCount -[purple]1[/purple] [b]do[/b]
    [b]if[/b] IndList[i].Checked [b]then[/b] [b]begin[/b]    
      [b]if[/b] IndList[i].Childlbl=[teal]'True'[/teal] [b]then[/b]
        [b]if[/b] lblInfoitems.WithPicture=[teal]'True'[/teal] [b]then[/b]
          LWL:=ApplDir+[teal]'scChildPic.LWL'[/teal]      [navy][i]//Label to choose is scChildPic.LWL
[/i][/navy]        [b]else[/b]
          LWL:=ApplDir+[teal]'scChildwoPic.LWL'[/teal]    [navy][i]//Label to choose is scChildwoPic.LWL
[/i][/navy]      [b]else[/b]
        LWL:=ApplDir+[teal]'scNursery.LWL'[/teal];        [navy][i]//Label to choose is scNursery.LWL
[/i][/navy]
      getFamInfo(myFamTbl, IndList[i].FamId);
      xFamRecord.NameDir:=xFDir;
      xFamRecord.NameSal:=xFSal;
      xFamRecord.NameMail:=xFMail;
      CallSCPrintDLL(i, LWL); [navy][i]// showmessage('Print Label')
[/i][/navy]    [b]end[/b];
[b]end[/b];

[b]procedure[/b] TfrmAddlOptions.CallSCPrintDLL(i:Integer; LWL:String);
[b]var[/b]
  LibHandle: THandle;
  kiosklabelprint: Tkiosklabelprint;
[b]begin[/b]
  LibHandle := LoadLibrary([teal]'SCPrint.DLL'[/teal]);
  [b]try[/b]
    [b]if[/b] LibHandle=[purple]0[/purple] [b]then[/b]
      [b]raise[/b] EDLLLoadError.Create([teal]'Unable to Load DLL.'[/teal]);
    @kiosklabelprint := GetProcAddress(LibHandle, [teal]'kiosklabelprint'[/teal]);
    [b]if[/b] [b]not[/b] (@kiosklabelprint = [b]nil[/b]) [b]then[/b]
      kiosklabelprint(xFamRecord, IndList[i], lblInfoitems, LWL, DoOnce)
    [b]else[/b]
      RaiseLastWin32Error;
  [b]finally[/b]
    FreeLibrary(LibHandle);
  [b]end[/b];
[b]end[/b];

This is the other way we tried to do it but we get a host of error messages. including a 'Catastrophic Error' that crashes the system.

Code:
[b]procedure[/b] kiosklabelprint(pFamRecord    : TFamRecord;
                          pIndRecord    : TIndRecord;
                          plblInfo      : TLabelInfoObj;
                          LWL:String; DoOnce:Boolean); external [teal]'SCPrint.DLL'[/teal];

[b]procedure[/b] TfrmAddlOptions.agbtnPrintClick(Sender: TObject);
[b]var[/b]
  i:integer;   
  myFamTbl: TCBTable;
  LWL: String;
[b]begin[/b]          
  SetupUSERTable(myFamTbl, [teal]'USER\CSFAMILY.UDB'[/teal]);
  [b]for[/b] i:= [purple]1[/purple] [b]to[/b] IndListCount -[purple]1[/purple] [b]do[/b]
    [b]if[/b] IndList[i].Checked [b]then[/b] [b]begin[/b]    
      [b]if[/b] IndList[i].Childlbl=[teal]'True'[/teal] [b]then[/b]
        [b]if[/b] lblInfoitems.WithPicture=[teal]'True'[/teal] [b]then[/b]
          LWL:=[teal]'scChildPic.LWL'[/teal]      [navy][i]//Label to choose is scChildPic.LWL
[/i][/navy]        [b]else[/b]
          LWL:=[teal]'scChildwoPic.LWL'[/teal]    [navy][i]//Label to choose is scChildwoPic.LWL
[/i][/navy]      [b]else[/b]
        LWL:=[teal]'scNursery.LWL'[/teal];        [navy][i]//Label to choose is scNursery.LWL
[/i][/navy]
      getFamInfo(myFamTbl, IndList[i].FamId);
      xFamRecord.NameDir:=xFDir;
      xFamRecord.NameSal:=xFSal;
      xFamRecord.NameMail:=xFMail;
      kiosklabelprint(xFamRecord, IndList[i], lblInfoitems, LWL, DoOnce) [navy][i]// showmessage('Print Label')
[/i][/navy]    [b]end[/b];
[b]end[/b];
 
I see that you are passing a string between your program and the DLL. delphi's memory manager does not like this (this has changed from D2006). it only supports shortstrings (up to 255 chars) and Pchars. and for this need to include the unit Sharemem (as the first unit) in both app and DLL. and you must distribute borlndmm.dll with your app.

your best option is to download FastMM4 memory manager from sourceforge (built-in from D2006 as standard memory manager) and use it in both app and dll.


Cheers,
Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
thanks that seems to help some no longer getting the catastrophic errors but now getting access violation... also when it shuts down it gives me memory leaks... how do i enable the fulldebug mode, it tells meto do so but not where to put those lines?

Any help...?
 
you need to put the FastMM_FullDebugMode.dll in thae same location as your app.

and edit the FastMM4Options.inc
change line
{.$define FullDebugMode} to {$define FullDebugMode on}
and
{$define LogErrorsToFile} to {$define LogErrorsToFile on}

Aaron
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top