home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol11n19.zip / CDOWL.PAS < prev    next >
Pascal/Delphi Source File  |  1992-06-30  |  31KB  |  991 lines

  1. Unit CDOwl;
  2. {****************************************************}
  3. {                                                    }
  4. {   Turbo Pascal for Windows                         }
  5. {   Common Dialog / Object Windows Library interface }
  6. {   Copyright (c) 1992 by Pat Ritchey                }
  7. {                                                    }
  8. {****************************************************}
  9.  
  10. interface
  11.  
  12. {$R CDOWL.RES}
  13.  
  14. uses WinTypes,WinProcs,
  15.  
  16. {$IFDEF VER10}         { TPW 1.0 }
  17.   {$IFDEF BWCC}
  18.     WObjectB,
  19.   {$ELSE}
  20.     Wobjects,
  21.   {$ENDIF}
  22.   Xtra31,
  23.  
  24. {$ELSE}                { TPW 1.5 and later }
  25.   Wobjects,Win31,
  26. {$ENDIF}
  27.   WinDOS,Strings,Dlgs,COMMDLG;
  28.  
  29. { This include file pulls in any identifiers used in the creation of CDOWL.RES }
  30. {$I CDOWL.INC}
  31.  
  32. type
  33.    PCDDlg = ^TCDDlg;
  34.    TCDDlg = object(TDialog)
  35.      UsingBWCCDlg : boolean;
  36.      DialogCancelled : boolean;
  37.      CDTransferBuffer : pointer;
  38.      Constructor Init(AParent  : PWindowsObject;
  39.                       AResID   : Pchar;
  40.                       AUseBWCC : boolean;
  41.                   var TemplateName : Pchar);
  42.      Procedure   SetupWindow; virtual;
  43.      Function    Create : boolean; virtual;
  44.      Function    Execute : integer; virtual;
  45.      Function    CommonDialogExec : boolean; virtual;
  46.      Function    CommonDialogCreate : word; virtual;
  47.      Procedure   OK(var Msg : TMessage);     virtual id_First+id_OK;
  48.      Procedure   Cancel(var Msg : TMessage); virtual id_first+id_Cancel;
  49.      Procedure   SetCDTransferBuffer(p : pointer);
  50.      end;
  51.  
  52.    PChooseFontDlg = ^TChooseFontDlg;
  53.    TChooseFontDlg = object(TCDDlg)
  54.      CF : TChooseFont;
  55.      ColorPtr : ^Longint;
  56.      GrayBrush : hBrush;
  57.  
  58.      Constructor Init(AParent : PWindowsObject;
  59.                       AFlags   : longint;
  60.                       ALogFont : PLogFont;
  61.                   var AColor : longint);
  62.  
  63.      Constructor InitCustom(AParent : PWindowsObject;
  64.                       AFlags   : longint;
  65.                       ALogFont : PLogFont;
  66.                   var AColor : longint;
  67.                       AResName : Pchar;
  68.                       AUseBWCC : boolean);
  69.  
  70.      Destructor  Done; virtual;
  71.      Function    CommonDialogExec : boolean; virtual;
  72.      Procedure   WMCtlColor(var Msg : TMEssage); virtual wm_first+wm_CtlColor;
  73.      Procedure   SetMinMaxPtSize(AMin,AMax : integer);
  74.      Procedure   SetPrinterDC(DC : hDC);
  75.      end;
  76.  
  77.  { The CustColorArray type is defined to satisfy the requirements of
  78.    the lpCustColors field of the TChooseColor structure.  }
  79.  
  80.  CustColorArray = array[0..15] of longint;
  81.  
  82.  
  83.  PChooseColorDlg = ^TChooseColorDlg;
  84.  TChooseColorDlg = object(TCDDlg)
  85.      CC : TChooseColor;
  86.      ColorPtr : ^Longint;
  87.      GrayBrush : hBrush;
  88.  
  89.      Constructor Init(AParent     : PWindowsObject;
  90.                       AFlags      : longint;
  91.                   var ACustColors : CustColorArray;
  92.                   var AColor      : longint);
  93.  
  94.  
  95.      Constructor InitCustom(AParent     : PWindowsObject;
  96.                       AFlags      : longint;
  97.                   var ACustColors : CustColorArray;
  98.                   var AColor      : longint;
  99.                       AResName    : Pchar;
  100.                       AUseBWCC    : boolean);
  101.  
  102.      Destructor Done; virtual;
  103.      Procedure  WMCtlColor(var Msg : TMessage); virtual wm_first+wm_CtlColor;
  104.      Function   CommonDialogExec : boolean; virtual;
  105.      end;
  106.  
  107.  { The IOtypes enumeration is used by TFileDlg to determine which COMMDLG
  108.    API function should be called }
  109.  
  110.  IOTypes = (Open,Save);
  111.  
  112.  PCDListBox = ^TCDListBox;
  113.  TCDListBox = object(TListBox)
  114.     Procedure WMEraseBkgnd(var Msg : TMessage); virtual wm_first+wm_EraseBkgnd;
  115.     end;
  116.  
  117.  PFileDlg = ^TFileDlg;
  118.  TFileDlg = object(TCDDlg)
  119.      OFN : TOpenFileName;
  120.      IOType : IOTypes;
  121.      FileName : Pchar;
  122.      NameLength : integer;
  123.  
  124.      Constructor Init(AParent : PWindowsObject;
  125.                       AFlags   : Longint;
  126.                       AIOType  : IOTypes;
  127.                       AFileName : Pchar;
  128.                       ANameLength : integer);
  129.  
  130.      Constructor InitCustom(AParent : PWindowsObject;
  131.                       AFlags   : Longint;
  132.                       AIOType  : IOTypes;
  133.                       AFileName : Pchar;
  134.                       ANameLength : integer;
  135.                       AResName   : Pchar;
  136.                       AUseBWCC   : boolean);
  137.  
  138.      Destructor Done; virtual;
  139.      Procedure SetupWindow; virtual;
  140.      Procedure WMSysColorChange(var Msg : TMessage);
  141.          virtual wm_first+wm_syscolorchange;
  142.      Function CommonDialogExec : boolean; virtual;
  143.      Function GetFileFilter : Pchar; virtual;
  144.      Function GetDialogTitle : Pchar; virtual;
  145.      Function GetDefaultExtension : Pchar; virtual;
  146.      end;
  147.  
  148. { the IDC_xxxxx variables contain the values of the Windows messages
  149.   registered by COMMDLG.  They aren't used directly by CDOWL, but are
  150.   initialized for the convenience of the program which uses CDOWL. }
  151.  
  152. var
  153.   IDC_FindReplace,
  154.   IDC_HelpMessage : word;
  155.  
  156. type
  157.  PFindReplaceDlg = ^TFindReplaceDlg;
  158.  TFindReplaceDlg = object(TCDDlg)
  159.    FR : TFindReplace;
  160.    FindNextBits : array[0..2] of hBitmap;
  161.    Constructor Init(AParent   : PWindowsObject;
  162.                     AFlags    : Longint;
  163.                     AFindText : Pchar;
  164.                     AReplaceText : Pchar);
  165.  
  166.    Constructor InitCustom(AParent   : PWindowsObject;
  167.                     AFlags    : Longint;
  168.                     AFindText : Pchar;
  169.                     AReplaceText : Pchar;
  170.                     AResName     : Pchar;
  171.                     AUseBWCC   : boolean);
  172.  
  173.  
  174.    Destructor  Done; virtual;
  175.    Procedure   SetupWindow; virtual;
  176.    Function    CommonDialogCreate : word; virtual;
  177.    Function    FindOptionSet(Mask : longint) : boolean;
  178.    Function    FindWhat : Pchar;
  179.    Function    ReplaceWith : Pchar;
  180.    end;
  181.  
  182.  PPrintInitDlg = ^TPrintInitDlg;
  183.  TPrintInitDlg = object(TCDDlg)
  184.     PD : TPrintDlg;
  185.     SetupBits : array[0..2] of hBitmap;
  186.     DevNamesPtr : ^Pointer;
  187.     DevModePtr  : ^Pointer;
  188.     PrintDCptr : ^hDC;
  189.  
  190.     Constructor Init(AParent   : PWindowsObject;
  191.                      AFlags    : Longint;
  192.                 var  APrintDC  : hDC;
  193.                 var  ADevNames : PDevNames;
  194.                 var  ADevMode  : PDevMode);
  195.  
  196.     Constructor InitCustom(AParent   : PWindowsObject;
  197.                      AFlags    : Longint;
  198.                 var  APrintDC  : hDC;
  199.                 var  ADevNames : PDevNames;
  200.                 var  ADevMode  : PDevMode;
  201.                      AResInit  : Pchar;
  202.                      AResSetup : Pchar;
  203.                      AUseBWCC  : boolean);
  204.  
  205.     Destructor Done; virtual;
  206.     Procedure SetupWindow; virtual;
  207.     Function CommonDialogExec : boolean; virtual;
  208.     Procedure SetMinMaxPage(MinPage,MaxPage : integer);
  209.     end;
  210.  
  211. implementation
  212.  
  213. const
  214.    rgbLightGray = $C0C0C0;
  215.  
  216.    BBM_SETBITS = (BM_SETSTYLE+10); { Defined in BWCC.PAS.  If CDOWL used
  217.                                      BWCC the DLL would be implicitly loaded
  218.                                      so the constant is "defined" here.}
  219.  
  220.    idFontDisplay = 1092;  { These constants are defined in DLGS.PAS  }
  221.    idFilesList   = 1120;  { The identifier names used here are a bit }
  222.    idDirList     = 1121;  { more descriptive than the identifiers in }
  223.                           { DLGS.PAS. }
  224.  
  225. var
  226.    CallBWCCGetPattern  : Function : hBrush;
  227.    BWCCAvailable : boolean;
  228.    BaseBitmapID : word;
  229.    HelpBits : array[0..2] of hBitmap;
  230.    WindowBrush : hBrush;
  231.  
  232. type
  233.    PCDSubStrata = ^TCDSubStrata;
  234.    TCDSubStrata = object(TWindow)
  235.      procedure SetupWindow; virtual;
  236.      procedure wmPaint(var Msg: TMessage); virtual wm_First + wm_Paint;
  237.      procedure wmEraseBkgnd(var Msg: TMessage); virtual wm_First + wm_EraseBkgnd;
  238.    end;
  239.  
  240.  
  241. Function FlagSet(Flags : longint; Mask : longint) : boolean;
  242. begin
  243.   FlagSet := (Flags and Mask) <> 0;
  244. end;
  245.  
  246. Constructor TCDDlg.Init(AParent : PWindowsObject;
  247.                         AResID  : Pchar;
  248.                         AUseBWCC : boolean;
  249.                     var TemplateName : Pchar);
  250. begin
  251.    { Common initialization for all of the common dialog objects.}
  252.    TDialog.Init(AParent,nil);
  253.    DialogCancelled := False;
  254.    TemplateName := AResID;
  255.    UsingBWCCDlg := AUseBWCC and BWCCAvailable;
  256.    CDTransferBuffer := nil;
  257. end;
  258.  
  259. Procedure   TCDDlg.SetupWindow;
  260. begin
  261.    TDialog.SetupWindow;
  262.    if UsingBWCCDlg then
  263.       { Change the bitmap used to paint the Help button }
  264.       { By default BWCC expects a Help button to have an id of 998.
  265.         COMMDLG expects a help button to have an id of "pshHelp" ($040E)
  266.         We have to respect COMMDLG's wishes if the help button is to function
  267.         correctly }
  268.       SendMessage(GetDlgItem(hWindow,pshHelp),BBM_SETBITS,0,Longint(@HelpBits));
  269. end;
  270.  
  271. Function    TCDDlg.Create : boolean;
  272. {- This method is equivalent to TDialog.Create except that it calls the
  273.    CommonDialogCreate method rather than CreateWindow.}
  274. var
  275.   HParent: HWnd;
  276.   CDError : integer;
  277. begin
  278.   if Status = 0 then
  279.   begin
  280.     DisableAutoCreate;
  281.     EnableKBHandler;
  282.     IsModal := False;
  283.     HWindow := CommonDialogCreate;
  284.     if HWindow = 0 then
  285.        begin
  286.        Status := -CommDlgExtendedError;
  287.        if Status = 0 then
  288.           Status := em_InvalidWindow
  289.        end;
  290.   end;
  291.   Create := Status = 0;
  292. end;
  293.  
  294. Function    TCDDlg.Execute : integer;
  295. { Basically, this is the code from TDialog.Execute with the call to
  296.   DialogBoxParam changed to a call to the CommonDialogExec method }
  297. var
  298.   CDError : longint;
  299.   OldKbHandler: PWindowsObject;
  300. begin
  301.   if Status = 0 then
  302.   begin
  303.     DisableAutoCreate;
  304.     EnableKBHandler;
  305.     IsModal := True;
  306.     OldKbHandler := Application^.KBHandlerWnd;
  307.     if CommonDialogExec then
  308.        execute := id_ok
  309.     else
  310.        begin
  311.        CDError := CommDlgExtendedError;
  312.        if CDError = 0 then
  313.           execute := id_Cancel
  314.        else
  315.           begin
  316.           Status := -CdError;
  317.           execute := Status;
  318.           end;
  319.        end;
  320.     Application^.KBHandlerWnd := OldKbHandler;
  321.     HWindow := 0;
  322.   end
  323.   else Execute := Status;
  324. end;
  325.  
  326. Function    TCDDlg.CommonDialogExec : boolean;
  327. { only descendants of TCDDlg know how to Exec a common dialog.  For
  328.   this abstract class, we return the equivalent of the cancel button
  329.   being pressed}
  330. begin
  331.   CommonDialogExec := false;
  332. end;
  333.  
  334. Function    TCDDlg.CommonDialogCreate : hWnd;
  335. { only descendants of TCDDlg know how to Create a common dialog.  For
  336.   this abstract class, we return the equivalent of a failure to create
  337.   the modeless dialog.}
  338. begin
  339.   CommonDialogCreate := 0;
  340. end;
  341.  
  342. Procedure   TCDDlg.SetCDTransferBuffer(p : pointer);
  343. { This method records the address of a buffer used to pass the applicable
  344.   record structure back to the calling application (after the common dialog
  345.   has been closed).  The address passed should be the address of a variable
  346.   of the correct type (ie: a TChooseFontDlg object should pass the address
  347.   of a TChooseFont record.}
  348. begin
  349.   CDTransferBuffer := p;
  350. end;
  351.  
  352. Procedure   TCDDlg.OK(var Msg : TMessage);
  353. { COMMDLG requires that the hook function (ie: this method) does NOT call
  354.   EndDlg() for it's modal dialogs.  Setting Msg.Result to 0 will allow
  355.   COMMDLG to terminate the dialog.  A value of 1 will cause COMMDLG to
  356.   ignore the OK button press. }
  357. begin
  358.   if CanClose then
  359.      begin
  360.      TransferData(tf_getData);
  361.      Msg.Result := 0;
  362.      end
  363.   else
  364.      Msg.Result := 1;
  365.  
  366. end;
  367.  
  368. Procedure   TCDDlg.Cancel(var Msg : TMessage);
  369. { Set DialogCancelled boolean so that the Done destructor can act
  370.   appropriately }
  371. begin
  372.  DialogCancelled := true;
  373.  Msg.Result := 0
  374. end;
  375.  
  376. { TCDSubStrata methods.  This object is used to 'cut a hole' in the
  377.   BWCC facade, to allow areas that are painted by the CommDlg dialog
  378.   function to show through.  The ChooseFont dialog's sample font display
  379.   is drawn by the CommDlg dialog function, and would be painted over
  380.   by a normal BWCC dialog. }
  381.  
  382. procedure TCDSubStrata.SetupWindow;
  383. begin
  384.   TWindow.SetupWindow;
  385.   ShowWindow(HWindow, sw_Show);
  386. end;
  387.  
  388. procedure TCDSubStrata.wmPaint(var Msg: TMessage);
  389. var PS: TPaintStruct;
  390. begin
  391.   Msg.Result := 1;          { Tell Windows we've handled this message }
  392.   BeginPaint(HWindow, PS);  { then fake a paint sequence.  This will  }
  393.   EndPaint(HWindow, PS);    { provide the illusion of transparency.   }
  394. end;
  395.  
  396. procedure TCDSubStrata.wmEraseBkgnd(var Msg: TMessage);
  397. begin
  398.   Msg.Result := 1;   { Prevent Windows from performing default erasures }
  399. end;
  400.  
  401.  
  402. { TChooseFontDlg Methods }
  403.  
  404. Constructor TChooseFontDlg.InitCustom(
  405.           AParent : PWindowsObject;
  406.           AFlags   : longint;
  407.           ALogFont : PLogFont;
  408.       var AColor : longint;
  409.           AResName : Pchar;
  410.           AUseBWCC : boolean);
  411. var
  412.   Dummy: PWindowsObject;
  413. begin
  414.    FillChar(CF,Sizeof(CF),0);
  415.    TCDDlg.Init(AParent,AResName,AUseBWCC,CF.lpTemplateName);
  416.    ColorPtr := @AColor;
  417.    GrayBrush := CreateSolidBrush(rgbLightGray);
  418.    With CF do begin
  419.      lStructSize := SizeOf(CF);
  420.      if AParent <> nil then
  421.         hwndOwner := AParent^.hWindow;
  422.      rgbColors := AColor;
  423.      lpLogFont := ALogFont;
  424.      Flags     := AFlags or CF_INITTOLOGFONTSTRUCT or CF_ENABLEHOOK;
  425.      if lpTemplateName <> nil then Flags := Flags or CF_ENABLETEMPLATE;
  426.      @lpfnHook := Instance;
  427.      hInstance := System.hInstance;
  428.      end;
  429.   if UsingBWCCDlg then
  430.      Dummy := new(PCDSubStrata, InitResource(@Self, idFontDisplay));
  431. end;
  432.  
  433. Constructor TChooseFontDlg.Init(
  434.           AParent : PWindowsObject;
  435.           AFlags   : longint;
  436.           ALogFont : PLogFont;
  437.       var AColor : longint);
  438.  
  439. var
  440.   DefResName : Pchar;
  441. begin
  442.   If not BWCCAvailable then
  443.      DefResName := nil
  444.   else
  445.     If FlagSet(AFlags,CF_EFFECTS) then
  446.        DefResName := 'CF_BWCC'
  447.     else
  448.        DefResName := 'CFM_BWCC';
  449.   TChooseFontDlg.InitCustom(AParent,AFlags,ALogFont,AColor,DefResName,BWCCAvailable);
  450. end;
  451.  
  452. Destructor TChooseFontDlg.Done;
  453. begin
  454.   If not DialogCancelled then
  455.      begin
  456.      If CDTransferBuffer <> nil then
  457.         Move(CF,CDTransferBuffer^,Sizeof(CF));
  458.      ColorPtr^ := CF.rgbColors;
  459.      end;
  460.   DeleteObject(GrayBrush);
  461.   TCDDlg.Done;
  462. end;
  463.  
  464.  
  465. Function TChooseFontDlg.CommonDialogExec : boolean;
  466. { Make the COMMDLG API call.  "lpfnHook" is set to the value of the
  467.   exported instance stub created earlier by OWL.  It is the instance stub that
  468.   receives messages destined for this dialog and dispatches them to the
  469.   appropriate methods.}
  470. begin
  471.   CommonDialogExec := ChooseFont(CF);
  472. end;
  473.  
  474. Procedure TChooseFontDlg.WMCTLCOLOR(var Msg : TMessage);
  475. { Due to the manner in which COMMDLG draws the sample font display,
  476.   creating a "true" BorDlg class dialog would cause the sample display
  477.   written by COMMDLG to interfere with BWCC's painting of the static
  478.   control.  To solve this painting conflict between BWCC and COMMDLG, we
  479.   don't use the BWCC BorDlg dialog class - we emulate the BWCC look in a
  480.   simple dialog.  COMMDLG is told to paint the background with BWCC's
  481.   "chiseled steel" brush giving a good approximation of the BWCC dialog
  482.   appearance}
  483. begin
  484.   if UsingBWCCDlg then
  485.      With Msg do begin
  486.      SetBkColor(hdc(Msg.wParam),rgbLightGray);
  487.      if (lParamHi = CtlColor_DLG) and (lPAramLo = hWindow) then
  488.         Result := CallBWCCGetPattern
  489.      else
  490.         Result := GrayBrush;
  491.      end
  492.   else
  493.      DefWndProc(Msg);
  494. end;
  495.  
  496. Procedure TChooseFontDlg.SetPrinterDC(DC : hDC);
  497. { This method may be called after the app has called the constructor and 
  498.   prior to calling the Execute method.  Setting a printer DC automatically
  499.   adjusts the TChooseFont record fields so that COMMDLG displays the
  500.   applicable printer fonts. }
  501. begin
  502.    CF.HDC := DC;
  503.    if DC <> 0 then
  504.       CF.Flags := CF.Flags or CF_PRINTERFONTS;
  505. end;
  506.  
  507. Procedure TChooseFontDlg.SetMinMaxPtSize(AMin,AMax : integer);
  508. { This method may be called after the app has called the constructor and prior to
  509.   calling the Execute method.  The minimum and maximum point sizes are set in the
  510.   TChooseFont record and the Flags word is modified to inform COMMDLG that
  511.   it should respect the mimimum and maximum point sizes.}
  512. begin
  513.   With CF do begin
  514.     nSizeMin := AMin;
  515.     nSizeMax := AMax;
  516.     Flags := Flags or CF_LIMITSIZE;
  517.     end;
  518. end;
  519.  
  520. { TChooseColorDlg Methods }
  521.  
  522. Constructor TChooseColorDlg.InitCustom;
  523. begin
  524.    FillChar(CC,Sizeof(CC),0);
  525.    TCDDlg.Init(AParent,AResName,AUseBWCC,CC.lpTemplateName);
  526.    ColorPtr := @AColor;
  527.    GrayBrush := CreateSolidBrush(rgbLightGray);
  528.    With CC do begin
  529.      lStructSize := SizeOf(CC);
  530.      if AParent <> nil then
  531.         hwndOwner := AParent^.hWindow;
  532.      rgbResult    := AColor;
  533.      lpCustColors := @ACustColors;
  534.      @lpfnHook := Instance;
  535.      Flags     := AFlags or CC_RGBINIT or CC_ENABLEHOOK;
  536.      if lpTemplateName <> nil then
  537.         Flags := Flags or CC_ENABLETEMPLATE;
  538.      hInstance := System.hInstance;
  539.      end;
  540. end;
  541.  
  542. Constructor TChooseColorDlg.Init;
  543. var
  544.  DefResID : Pchar;
  545. begin
  546.    if BWCCAvailable then DefResID := 'CC_BWCC' else DefResID := nil;
  547.    TChooseColorDlg.InitCustom(AParent,AFlags,ACustColors,AColor,DefResID,BWCCAvailable);
  548. end;
  549.  
  550. Destructor TChooseColorDlg.Done;
  551. { Clean up by deleting the resources created in the constructor.  Set the AColor
  552.   parameter passed to the constructor to the selected color. }
  553. begin
  554.   if not DialogCancelled then
  555.      begin
  556.      ColorPtr^ := CC.rgbResult;
  557.      If CDTransferBuffer <> nil then
  558.         Move(CC,CDTransferBuffer^,Sizeof(CC));
  559.      end;
  560.   DeleteObject(GrayBrush);
  561.   TCDDlg.Done;
  562. end;
  563.  
  564. Procedure TChooseColorDlg.WMCTLCOLOR;
  565.  
  566. begin
  567.   if UsingBWCCDlg then
  568.      With Msg do begin
  569.      SetBkColor(hdc(Msg.wParam),rgbLightGray);
  570.      if (lParamHi = CtlColor_DLG) and (lPAramLo = hWindow) then
  571.         Result := CallBWCCGetPattern
  572.      else
  573.         Msg.Result := GrayBrush;
  574.      end
  575.   else
  576.      DefWndProc(Msg);
  577. end;
  578.  
  579. Function TChooseColorDlg.CommonDialogExec : boolean;
  580. begin
  581.   CommonDialogExec := ChooseColor(CC);
  582. end;
  583.  
  584. { TCDListBox methods }
  585.  
  586. Procedure TCDListBox.WMEraseBkgnd;
  587. var
  588.   R : TRect;
  589. begin
  590.   With Msg do begin
  591.    GetClientRect(hWindow,R);            { get the area of the list box }
  592.    FillRect(hDC(wParam),R,WindowBrush); { erase it with a consistent color }
  593.    Msg.Result := 1;                     { tell the Windows we handled the erasure }
  594.    end;
  595. end;
  596.  
  597. { TFileDlg methods }
  598.  
  599.  
  600. Constructor TFileDlg.InitCustom;
  601. var
  602.   TempName : array[0..fsFileName] of char;
  603.   TempExt  : array[0..fsExtension] of char;
  604.   Dummy : PWindowsObject;
  605. begin
  606.   FillChar(OFN,Sizeof(OFN),0);
  607.   TCDDlg.Init(AParent,AResName,AUseBWCC,OFN.lpTemplateName);
  608.   if UsingBWCCDlg then
  609.      begin
  610.      { create some TCDListBox objects so that we can subclass
  611.        the listboxes and perform consistent background painting }
  612.      WindowBrush := CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  613.      Dummy := New(PCDListBox,InitResource(@Self,idFilesList));
  614.      Dummy := New(PCDListBox,InitResource(@Self,idDirList));
  615.      end;
  616.   IOType := AIOType;
  617.   NameLength := ANameLength;
  618.   FileName   := AFileName;
  619.   With OFN do begin
  620.      lStructSize := SizeOf(OFN);
  621.      if AParent <> nil then
  622.         hwndOwner := AParent^.hWindow;
  623.      Flags     := AFlags or OFN_ENABLEHOOK;
  624.      if lpTemplateName <> nil then
  625.         Flags := Flags or OFN_ENABLETEMPLATE;
  626.      hInstance := System.hInstance;
  627.      @lpfnHook := Instance;
  628.      lpstrFilter := GetFileFilter;
  629.      lpstrTitle  := GetDialogTitle;
  630.      lpstrDefExt := GetDefaultExtension;
  631.      nFilterIndex    := 1;
  632.      GetMem(lpstrFile,Succ(fsPathName));
  633.      nMaxFile        := Succ(fsPathName);
  634.      lpstrFileTitle  := nil;
  635.      nMaxFileTitle   := 0 ;
  636.      GetMem(lpstrInitialDir,Succ(fsDirectory));
  637.      FileExpand(lpstrFile,AFileName);
  638.      FileSplit(lpstrFile,lpstrInitialDir,TempName,TempExt);
  639.      StrCat(StrCopy(lpstrFile,TempName),TempExt);
  640.      end;
  641. end;
  642.  
  643. Constructor TFileDlg.Init;
  644. var
  645.   DefResID : Pchar;
  646. begin
  647.   If not BWCCAvailable then
  648.      DefResID := nil
  649.   else
  650.      if FlagSet(AFlags,OFN_ALLOWMULTISELECT) then
  651.         DefResID := 'OFM_BWCC'
  652.      else
  653.         DefResID := 'OF_BWCC';
  654.   TFileDlg.InitCustom(AParent,AFlags,AIOType,AFileName,ANameLength,DefResID,BWCCAvailable);
  655. end;
  656.  
  657. Destructor TFileDlg.Done;
  658. { Clean up by copying the selected file name to the file name parameter passed in
  659.   to the constructor, free the memory allocated in the constructor and delete the
  660.   brush created in the constructor. }
  661. begin
  662.  If not DialogCancelled then
  663.     begin
  664.     StrLCopy(FileName,OFN.lpstrFile,NameLength);
  665.     If CDTransferBuffer <> nil then
  666.        Move(OFN,CDTransferBuffer^,Sizeof(OFN));
  667.     end;
  668.  FreeMem(OFN.lpstrFile,Succ(fsPathName));
  669.  FreeMem(OFN.lpstrInitialDir,Succ(fsDirectory));
  670.  if UsingBWCCDlg then
  671.     DeleteObject(WindowBrush);
  672.  TCDDlg.Done;
  673. end;
  674.  
  675. Procedure TFileDlg.SetupWindow;
  676. { A SetupWindow method exists for TFileDlg so that the BorShade group
  677.   surrounding the "Read Only" check box can be hidden when the
  678.   caller requests that the check box is hidden (via the OFN_HIDEREADONLY
  679.   flag.}
  680. begin
  681.   TCDDlg.SetupWindow;
  682.   if UsingBWCCDlg then
  683.     if FlagSet(OFN.Flags,OFN_HIDEREADONLY) then
  684.       ShowWindow(GetItemHandle(OF_ReadOnly_Shade),sw_hide);
  685. end;
  686.  
  687. Function TFileDlg.CommonDialogExec : boolean;
  688. { Call the appropriate COMMDLG API entry point }
  689. begin
  690.   if IOType = Open then
  691.      CommonDialogExec := GetOpenFileName(OFN)
  692.   else
  693.      CommonDialogExec := GetSaveFileName(OFN);
  694. end;
  695.  
  696. Procedure TFileDlg.WMSysColorChange(var Msg : TMessage);
  697. { This method keeps the background of TCDListBoxes in sync with any
  698.   changes made to the System Colors. }
  699. begin
  700.   DefWndProc(Msg);           { Let COMMDLG make it's changes }
  701.   DeleteObject(WindowBrush); { and then update the brush used by TCDListBox }
  702.   WindowBrush := CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  703. end;
  704.  
  705. Function TFileDlg.GetFileFilter : Pchar;
  706. { Called by the Init constructor to initialize the lpstrFilter field
  707.   of the TOpenFileName structure.  By default there is no filter.  To
  708.   specify a filter a descendant of TFileDlg should be created and this
  709.   method should be overridden. }
  710. begin
  711.    GetFileFilter := nil;
  712. end;
  713.  
  714. Function TFileDlg.GetDialogTitle : Pchar;
  715. { Called by the Init constructor to initialize the lpstrTitle field
  716.   of the TOpenFileName structure.  By default the title is "Save File As" or
  717.   "Open File" depending on the value of the IOtype field.
  718.   To specify a different title a descendant of TFileDlg should be created
  719.   and this method should be overridden. }
  720. begin
  721.  if IOType = Save then
  722.     GetDialogTitle := 'Save File As'
  723.  else
  724.     GetDialogTitle := 'Open File';
  725. end;
  726.  
  727. Function TFileDlg.GetDefaultExtension : Pchar;
  728. { Called by the Init constructor to initialize the lpstrDefExt field
  729.   of the TOpenFileName structure.  By default there is no default extension.
  730.   To specify a default extension a descendant of TFileDlg should be created
  731.   and this method should be overridden. }
  732. begin
  733.   GetDefaultExtension := nil;
  734. end;
  735.  
  736. {TReplaceDlg Methods }
  737.  
  738. Constructor TFindReplaceDlg.InitCustom;
  739. var
  740.   BWCCRes : Pchar;
  741.   BaseID : integer;
  742. begin
  743.    FillChar(FR,Sizeof(FR),0);
  744.    TCDDlg.Init(AParent,AResName,AUseBWCC,FR.lpTemplateName);
  745.    With FR do begin
  746.      lStructSize := SizeOf(FR);
  747.      if AParent <> nil then
  748.         hwndOwner := AParent^.hWindow;
  749.      Flags     := AFlags or FR_ENABLEHOOK or FR_DOWN;
  750.      if lpTemplateName <> nil then
  751.         Flags := Flags or FR_ENABLETEMPLATE;
  752.      hInstance := System.hInstance;
  753.      @lpfnHook := Instance;
  754.      wFindWhatLen := 81;
  755.      GetMem(lpstrFindWhat,wFindWhatLen);
  756.      if AFindText <> nil then
  757.         StrLCopy(lpstrFindWhat,AFindText,wFindWhatLen)
  758.      else
  759.         lpstrFindWhat[0] := #0;
  760.  
  761.      If FlagSet(AFlags,FR_Replace) then
  762.         begin
  763.         wReplaceWithLen := 81;
  764.         GetMem(lpstrReplaceWith,wReplaceWithLen);
  765.         if AReplaceText <> nil then
  766.            StrLCopy(lpstrReplaceWith,AReplaceText,wReplaceWithLen)
  767.         else
  768.            lpstrReplaceWith[0] := #0;
  769.         end;
  770.      end;
  771.   if UsingBWCCDlg then
  772.      begin
  773.      BaseID := BaseBitmapID+102;
  774.      FindNextBits[0] := LoadBitmap(hInstance,Pchar(BaseId));
  775.      FindNextBits[1] := LoadBitmap(hInstance,Pchar(BaseID+2000));
  776.      FindNextBits[2] := LoadBitmap(hInstance,Pchar(BaseID+4000));
  777.      end;
  778.  
  779. end;
  780.  
  781. Constructor TFindReplaceDlg.Init;
  782. var
  783.   DefResId : Pchar;
  784. begin
  785.   If not BWCCAvailable then
  786.      DefResID := nil
  787.   else
  788.      if FlagSet(AFlags,FR_REPLACE) then
  789.         DefResID := 'FRR_BWCC' else DefResID := 'FRF_BWCC';
  790.   TFindReplaceDlg.InitCustom(AParent,AFlags,AFindText,AReplaceText,DefResID,BWCCAvailable);
  791. end;
  792.  
  793. Destructor TFindReplaceDlg.Done;
  794. var
  795.   i : integer;
  796. begin
  797.  With FR do begin
  798.   FreeMem(lpstrFindWhat,wFindWhatLen);
  799.   if lpstrReplaceWith <> nil then
  800.      FreeMem(lpstrReplaceWith,wReplaceWithLen);
  801.   end;
  802.   TCDDlg.Done;
  803.   if UsingBWCCDlg then
  804.      for i := 0 to 2 do DeleteObject(FindNextBits[i]);
  805. end;
  806.  
  807. Procedure TFindReplaceDlg.SetupWindow;
  808. begin
  809.   TCDDlg.SetupWindow;
  810.   if UsingBWCCDlg then
  811.     SendMessage(GetDlgItem(hWindow,1),BBM_SETBITS,0,Longint(@FindNextBits));
  812. end;
  813.  
  814. Function TFindReplaceDlg.CommonDialogCreate;
  815. { a Find/Replace dialog *must* be created as a modeless dialog. }
  816. begin
  817.   if FlagSet(FR.Flags,FR_REPLACE) then
  818.      CommonDialogCreate := ReplaceText(FR)
  819.   else
  820.      CommonDialogCreate := FindText(FR);
  821. end;
  822.  
  823. Function TFindReplaceDlg.FindOptionSet(Mask : longint) : boolean;
  824. { This method is used by the app which created the dialog to determine what
  825.   flags are set when a notification message is received by the app. }
  826. begin
  827.   FindOptionSet := (FR.Flags and Mask) <> 0;
  828. end;
  829.  
  830. Function TFindReplaceDlg.FindWhat : Pchar;
  831. { This method is used by the app which created the dialog to retrieve the current
  832.   text to find when a notification message is received by the app. }
  833. begin
  834.   FindWhat := FR.lpstrFindWhat;
  835. end;
  836.  
  837. Function TFindReplaceDlg.ReplaceWith : Pchar;
  838. { This method is used by the app which created the dialog to retrieve the current
  839.   text to replace when a notification message is received by the app. }
  840. begin
  841.   ReplaceWith := FR.lpstrReplaceWith;
  842. end;
  843.  
  844. { TPrintInitDlg Methods }
  845.  
  846. Constructor TPrintInitDlg.InitCustom;
  847. { TPrintInitDlg encapsulates COMMDLG's PrintDlg() function.  This object differs from the
  848.   others in that the Printer initialization dialog has the option of calling a Printer
  849.   setup dialog.  TPrintInitDlg allows for a customized template for the setup dialog but
  850.   does NOT create an object that encapsulates the setup dialog. } 
  851. var
  852.   BaseID : word;
  853. begin
  854.    FillChar(PD,Sizeof(PD),0);
  855.    TCDDlg.Init(AParent,AResInit,AUseBWCC,PD.lpPrintTemplateName);
  856.    With PD do begin
  857.      lStructSize := SizeOf(PD);
  858.      if AParent <> nil then
  859.         hwndOwner := AParent^.hWindow;
  860.      Flags     := AFlags or PD_EnablePrintHook or PD_ReturnDC;
  861.      if lpPrintTemplateName <> nil then
  862.         Flags := Flags or PD_ENABLEPRINTTEMPLATE;
  863.      hInstance := System.hInstance;
  864.      @lpfnPrintHook := Instance;
  865.      lpSetupTemplateName := AResSetup;
  866.      if lpSetupTemplateName <> nil then
  867.         Flags := Flags or PD_EnableSetupTemplate;
  868.      DevModePtr := @ADevMode;
  869.      DevNamesPtr := @ADevNames;
  870.      PrintDCPtr  := @APrintDC;
  871.      if ADevMode <> nil then
  872.         hDevMode := Seg(ADevMode^);
  873.      if ADevNames <> nil then
  874.         hDevNames := Seg(ADevNames^);
  875.      end;
  876.   if UsingBWCCDlg then
  877.      begin
  878.      BaseID := BaseBitmapID+101;
  879.      SetupBits[0] := LoadBitmap(hInstance,Pchar(BaseId));
  880.      SetupBits[1] := LoadBitmap(hInstance,Pchar(BaseID+2000));
  881.      SetupBits[2] := LoadBitmap(hInstance,Pchar(BaseID+4000));
  882.      end;
  883. end;
  884.  
  885. Constructor TPrintInitDlg.Init;
  886. var
  887.   DefResInit,DefResSetup : pchar;
  888. begin
  889.   If not BWCCAvailable then
  890.      begin DefResInit := nil; DefResSetup := nil; end
  891.   else
  892.      begin DefResInit := 'PD_BWCC'; DefResSetup := 'PS_BWCC'; end;
  893.   TPrintInitDlg.InitCustom(AParent,AFlags,APrintDC,ADevNames,ADevMode,
  894.                            DefResInit,DefResSetup,BWCCAvailable);
  895. end;
  896.  
  897. Destructor TPrintInitDlg.Done;
  898. var
  899.   i : integer;
  900. begin
  901.   if UsingBWCCDlg then
  902.      for i := 0 to 2 do DeleteObject(SetupBits[i]);
  903.   DevNamesPtr^ := GlobalLock(PD.hDevNames);
  904.   DevModePtr^ := GlobalLock(PD.hDevMode);
  905.   if not DialogCancelled then
  906.      with PD do begin
  907.      PrintDCPtr^ := hDC;
  908.      If CDTransferBuffer <> nil then
  909.         Move(PD,CDTransferBuffer^,Sizeof(PD));
  910.      end;
  911.   TCDDlg.Done;
  912. end;
  913.  
  914. Procedure TPrintInitDlg.SetupWindow;
  915. begin
  916.  TCDDlg.SetupWindow;
  917.  if UsingBWCCDlg then
  918.     SendMessage(GetDlgItem(hWindow,1024),BBM_SETBITS,0,Longint(@SetupBits));
  919. end;
  920.  
  921. Function TPrintInitDlg.CommonDialogExec : boolean;
  922. begin
  923.   CommonDialogExec := PrintDlg(PD);
  924. end;
  925.  
  926. Procedure TPrintInitDlg.SetMinMaxPage;
  927. { This method may be called after the app has called the constructor and prior to
  928.   calling the Execute method.  The minimum and maximum page numbers are set in the
  929.   TPrintDlg record.  By default nMinPage and nMaxPage are initialized to zero. }
  930. begin
  931.   PD.nMinPage := MinPage;
  932.   PD.nMaxPage := MaxPage;
  933.   PD.nFromPage := MinPage;
  934.   PD.nToPage   := MaxPage;
  935. end;
  936.  
  937. var
  938.   OldExitProc : pointer;
  939.  
  940. Procedure Cleanup; far;
  941. var
  942.   i : integer;
  943. begin
  944.   ExitProc := OldExitProc;
  945.   if BWCCAvailable then
  946.      for i := 0 to 2 do DeleteObject(HelpBits[i]);
  947. end;
  948.  
  949.  
  950. Procedure DetectBWCCPresence;
  951. var
  952.   DC : hDC;
  953.   BaseID : word;
  954.   hBWCC : word;
  955. begin
  956.   {$IFDEF VER10}
  957.      {$IFDEF BWCC}
  958.         BWCCAvailable := true;
  959.      {$ELSE}
  960.         BWCCAvailable := false;
  961.      {$ENDIF}
  962.   {$ELSE}
  963.      BWCCAvailable := BWCCClassNames;
  964.   {$ENDIF}
  965.   hBWCC := GetModuleHandle('BWCC');
  966.   BWCCAvailable := BWCCAvailable and (hBWCC <> 0);
  967.   if BWCCAvailable then
  968.      begin
  969.      @CallBWCCGetPattern := GetProcAddress(hBWCC,'BWCCGETPATTERN');
  970.      DC := GetDC(0);
  971.      { Determine if an EGA or VGA adapter is being used and load the
  972.        appropriate bitmaps for the BWCC "Help" button }
  973.      if (GetDeviceCaps(DC,VERTRES) < 480) or
  974.         (Word(getDeviceCaps(DC,NUMCOLORS)) < 16)  then
  975.         BaseBitmapID := 2000 else BaseBitmapID := 1000;
  976.      ReleaseDC(0,DC);
  977.      BaseID := BaseBitmapID+998;
  978.      HelpBits[0] := LoadBitmap(hBWCC,Pchar(BaseId));
  979.      HelpBits[1] := LoadBitmap(hBWCC,Pchar(BaseID+2000));
  980.      HelpBits[2] := LoadBitmap(hBWCC,Pchar(BaseID+4000));
  981.      end;
  982. end;
  983.  
  984. begin
  985.   DetectBWCCPresence;
  986.   OldExitProc := ExitProc;
  987.   ExitProc := @Cleanup;
  988.   IDC_HelpMessage := RegisterWindowMessage(HelpMsgString);
  989.   IDC_FindReplace := RegisterWindowMessage(FindMsgString);
  990. end.
  991.