A question with fax modem?

I want to write a program to fax text or picture files through modem.
Is there any high level toolbox can do this without consider the modem driver and type.
Can apple script or script addition have the function to use.
Could someone teach me how to do this, and is there any examples.

Who is Participating?
Alex CuryloConnect With a Mentor Commented:
You use the Print Manager to create a port, draw your text/picture into it, and use the regular calls to open the fax modem's driver and send it your picture just as if it was a printer -- your program should neither know or care what kind of device the user has selected a driver for.

The easiest way to accomplish this is to use PowerPlant's LPrintout class; sample code showing how to use it comes with CodeWarrior, and you would just draw your own stuff into the printing port.

If you want to be compatible with OS X as well as the current Mac OS, you should know that Carbon will dramatically change the printing model. Details are at


but if you use PowerPlant like I recommend then LPrintout & friends will be Carbonized pretty transparently I would imagine, most likely by WWDC this year.

As for AppleScript, I imagine you'd have to write a custom OSAX or few but you would still write as if you're printing and rely on the user to pick a driver that makes sense.
TeLiehAuthor Commented:
   thanks for your kind ansering the question.
    I Don't understand "use the regular calls to open the fax modem's driver" How can I get the current modem driver information in the program. And I can't find modem driver in my computer. There is a folder "modem scripts" in the extension folder. How can I use them.
What the general type of modem driver in mac. where can I find the related documents

Best Regards
Alex CuryloCommented:
I was referring to the regular Print Manager calls -- sorry to be unclear about that. You do not actually send a fax as a fax; what you do is select a "printer" driver provided by the fax modem's manufacturer, and you use the Print Manager to give that driver the images of the page you want to send. So the place you would find the fax modem drivers is in the Chooser, the same place as you find printer drivers. The best sample code to start working with are the UPrintingMgr and LPrintout classes that are part of PowerPlant, CodeWarrior's application class library. (If you're not using PowerPlant, you should be. It's definitely the easiest way to write a Mac application.)

This is the only way to send a fax "without considering the modem driver and type", as you asked. If you don't want to rely on the drivers provided by the manufacturer, then you will have to write your own for each modem you want to support. There really is no way at all around that.

Modem scripts are an officially unsupported part of Open Transport and aren't really designed for anything except making ARA and PPP connections. As much detail as Apple has made official is at


The place to start looking for general Mac OS documentation is


but you're not going to find anything there on fax drivers :)

Finally, as for "current modem driver", there really is no such thing. The closest would be the information in the preferences file for the Modem control panel, which is also officially unsupported but there exists sample code to read. I don't think that would be of any particular use in faxing anyhow.
TeLiehAuthor Commented:
Thanks again and your comment is helpful for me.Is it convenient to have your e-Mail address.
The functions in UPrintingMgr such as "openPrinter(), CreatPrinter()...." and printer manager toolbox such as "propen(), PrGeneral()" only work with the current selected printer. Can I set the different current printer driver in my program, How to do it?
I find a printer driver in chooser for fax "faxprint".But it seems doesn't support desktop printer.Is there other famous manufacturer drivers I can use.  
Alex CuryloCommented:
Sure thing -- email alex@dice.net.

Now, as for setting the printer driver, I haven't done it myself, but here is how I GET the name of the currently-selected printer. I suppose a daring person could try to modify it to SET the name, as well. Here's how it works:

1) Get the name of the currently-selected printer driver by calling GetString on resource ID -8192. This string resource resides in the System and tracks, well, the current printer driver. I should warn you that Apple has specifically told me that this is undocumented and not guaranteed to be forever cool.

2) Get a dirID to the current Extensions folder using FindFolder and the following contants: kOnSystemDisk,  kExtensionFolderType, kDontCreateFolder.

3) Using the file name (same as driver name) from step 1 and the dirID from step 2, open the printer driver using FSpOpenResFile.

4) Get resource type 'PAPA', ID -8192, from the newly-opened resource file. The first pascal string in the PAPA resource appears to always contain the currently-selected printer's name.

Here is code posted on c.s.m.p which purports to do that, but which I disclaim all responsibility for if it doesn't work:


Here's an snippet from the extension I wrote a while ago.It used to work
with LW 8.0 and sys 7.1 I took out err checking for brevity.  Use it at your
own risk :-)

void DoChangeCurPrinter()
    StringHandle curDriver;
    Handle curPrinter;
    short resRef;
    curDriver =   GetString(-8192);
  // get the  currently active printer driver - LaserWriter ,
    // Open LaserWriter res file. This call moves memory, so lock the handle
    resRef = OpenResFile(*curDriver);
// get the name of current  printer selection in Chooser
// It' s stored in this resource of the LW
   curPrinter= GetResource('PAPA',-8192);
  // Assuming you got new printer name,zone and addr block
 //from the NBP lookup
   ChangePrinter(curPrinter,newPrinterName, newPrinterZone,    
   CloseResFile( resRef)

void ChangePrinter(Handle curPrinter ,Str32 printerName,
                   Str32 newPrinterZone,AddrBlock* newPrinterAddr)  
  Ptr p;
  Str32 objType="\pLaserWriter";
  /*manually stick new name, type, zone & addr block*/
   p = *curPrinter;
//if there's only 1 zone stick '*' in the zone field
   BlockMove(newPrinterAddrBlock,p,sizeof(long));//ptr to the addr block
   WriteResource( curPrinter );      

HTH, Andy

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.