MMCstDlg.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:57k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49(0)351-8037944               =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/index.html               =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 20.10.98 - 16:34:15 $                                        =}
  24. {========================================================================}
  25. unit MMCstDlg;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.   Windows,
  31. {$ELSE}
  32.   WinProcs,
  33.   WinTypes,
  34. {$ENDIF}
  35.   Messages,
  36.   SysUtils,
  37.   Classes,
  38.   Graphics,
  39.   Controls,
  40.   Forms,
  41.   Dialogs,
  42.   CommDlg,
  43.   ExtCtrls,
  44.   MMObj,
  45.   MMWave,
  46.   MMWavOut,
  47.   MMPCMSup,
  48.   MMWaveIO,
  49.   MMRiff,
  50.   MMMulDiv,
  51.   MMUtils,
  52.   MMString,
  53.   MMACMDlg,
  54.   MMADCvt,
  55.   MMDIB;
  56. type
  57.   {$IFNDEF WIN32}
  58.   POpenFilenameA = ^TOpenFilenameA;
  59.   TOpenFilenameA = record
  60.     lStructSize: Longint;
  61.     hWndOwner: HWnd;
  62.     hInstance: THandle;
  63.     lpstrFilter: PChar;
  64.     lpstrCustomFilter: PChar;
  65.     nMaxCustFilter: Longint;
  66.     nFilterIndex: Longint;
  67.     lpstrFile: PChar;
  68.     nMaxFile: Longint;
  69.     lpstrFileTitle: PChar;
  70.     nMaxFileTitle: Longint;
  71.     lpstrInitialDir: PChar;
  72.     lpstrTitle: PChar;
  73.     Flags: Longint;
  74.     nFileOffset: Word;
  75.     nFileExtension: Word;
  76.     lpstrDefExt: PChar;
  77.     lCustData: Longint;
  78.     lpfnHook: function (Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Word;
  79.     lpTemplateName: PChar;
  80.   end;
  81.   {$ENDIF}
  82.   TSelChangeEvent= procedure(Sender : TObject; Filename: String) of Object;
  83.   TFileOKEvent   = procedure(Sender : TObject; Filename: String; var IsOk: Boolean) of Object;
  84.   TCommandEvent  = procedure(Sender : TObject; Wnd,Parent,cmd: Integer) of Object;
  85.   {-- TMMCustomOpenDialog -----------------------------------------------------}
  86.   TMMCustomOpenDialog = class(TMMCommonDialog)
  87.   private
  88.     FHwnd         : Hwnd;            { Window handle for hook }
  89.     FTemplateName : String;          { Dialog template name }
  90.     FHistoryList  : TStrings;
  91.     FOptions      : TOpenOptions;
  92.     FFilter       : String;
  93.     FFilterIndex  : Integer;
  94.     FInitialDir   : String;
  95.     FTitle        : String;
  96.     FDefaultExt   : String;
  97.     FFileName     : TFileName;
  98.     FFiles        : TStrings;
  99.     FTempFiles    : TStringList;
  100.     {$IFNDEF DELPHI4}
  101.     FSizing       : Boolean;
  102.     {$ENDIF}
  103.     { Custom event handlers }
  104.     FOnCreate     : TNotifyEvent;
  105.     FOnDestroy    : TNotifyEvent;
  106.     FOnFileOK     : TFileOkEvent;
  107.     FOnSelChange  : TSelChangeEvent;
  108.     FOnCommand    : TCommandEvent;
  109.     procedure SetHistoryList(Value: TStrings);
  110.     procedure SetInitialDir(const Value: string);
  111.   protected
  112.     function  DoExecute(Func: Pointer): Bool;
  113.     procedure DoCreate; dynamic;
  114.     procedure DoDestroy; dynamic;
  115.     procedure DoFileOK(FName: String; var IsOk: Boolean);dynamic;
  116.     procedure DoSelChanged(FName: String);dynamic;
  117.     procedure DoCommand(Wnd,Parent: Hwnd; cmd: Integer); dynamic;
  118.     property OnCreate: TNotifyEvent read FOnCreate write FOnCreate;
  119.     property OnDestroy: TNotifyEvent read FOnDestroy write FOnDestroy;
  120.     property OnFileOK: TFileOKEvent read FOnFileOK write FOnFileOK;
  121.     property OnSelChange: TSelChangeEvent read FOnSelChange write FOnSelChange;
  122.     property OnCommand: TCommandEvent read FOnCommand write FOnCommand;
  123.     property DefaultExt: string read FDefaultExt write FDefaultExt;
  124.     property FileName: TFileName read FFileName write FFileName;
  125.     property Filter: String read FFilter write FFilter;
  126.     property FilterIndex: Integer read FFilterIndex write FFilterIndex default 1;
  127.     property HistoryList: TStrings read FHistoryList write SetHistoryList;
  128.     property InitialDir: string read FInitialDir write SetInitialDir;
  129.     property Options: TOpenOptions read FOptions write FOptions default [];
  130.     property Title: string read FTitle write FTitle;
  131.     property TemplateName: string read FTemplateName write FTemplateName;
  132.     {$IFNDEF DELPHI4}
  133.     property EnableSizing: Boolean read FSizing write FSizing default False;
  134.     {$ENDIF}
  135.   public
  136.     constructor Create(AOwner: TComponent); override;
  137.     destructor Destroy; override;
  138.     function  Execute: Boolean; override;
  139.     property  Files: TStrings read FFiles;
  140.     property  Wnd: HWnd read FHWnd write FHWnd;
  141.   end;
  142.   {-- TMMWaveOpenDialog -------------------------------------------------------}
  143.   TMMWaveOpenDialog = class(TMMCustomOpenDialog)
  144.   private
  145.     FWaveFile    : TMMWaveFile;
  146.     FADPCMConvert: TMMADPCMConverter;
  147.     FWaveOut     : TMMWaveOut;
  148.     FDeviceID    : integer;
  149.     FTimer       : TTimer;
  150.     FData        : Pointer;
  151.     FForeColor   : TColor;
  152.     FColor       : TColor;
  153.     FLocatorColor: TColor;
  154.     FPreview     : Boolean;
  155.     FAutoPlay    : Boolean;
  156.     FUpdating    : Boolean;
  157.     FOldPos      : Longint;
  158.     FScopeWnd    : HWND;
  159.     FScopeDefProc: TFarProc;
  160.     FScopeOldProc: Longint;
  161.     FDIBWnd      : HWND;
  162.     FDIBDefProc  : TFarProc;
  163.     FDIBOldProc  : Longint;
  164.     procedure WaveOutStart(Sender: TObject);
  165.     procedure WaveOutStop(Sender: TObject);
  166.     procedure TimerExpired(Sender: TObject);
  167.     procedure UpdateWave;
  168.     procedure UpdatePlayParams;
  169.     procedure DrawLocator(var OldPos: Longint; NewPos: Longint);
  170.     procedure CreatePCMData(DC: HDC; aRect: TRect);
  171.     procedure DrawPCMData(DC: HDC; aRect: TRect);
  172.     procedure DrawDISP(DC: HDC; aRect: TRect);
  173.     procedure ScopeWndHookProc(var Message: TMessage);
  174.     procedure DIBWndHookProc(var Message: TMessage);
  175.   protected
  176.     procedure DoCreate;override;
  177.     procedure DoDestroy;override;
  178.     procedure DoFileOK(FName: String; var IsOk: Boolean);override;
  179.     procedure DoSelChanged(FName: String);override;
  180.     procedure DoCommand(Wnd,Parent: Hwnd; cmd: Integer);override;
  181.   public
  182.     constructor Create(AOwner: TComponent); override;
  183.     destructor  Destroy; override;
  184.   published
  185.     property OnFileOK: TFileOKEvent read FOnFileOK write FOnFileOK;
  186.     property FileName;
  187.     property Filter;
  188.     property FilterIndex;
  189.     property InitialDir;
  190.     property Title;
  191.     {$IFNDEF DELPHI4}
  192.     property EnableSizing;
  193.     {$ENDIF}
  194.     property Options;
  195.     property Color: TColor read FColor write FColor default clBlack;
  196.     property ForeColor: TColor read FForeColor write FForeColor default clLime;
  197.     property LocatorColor: TColor read FLocatorColor write FLocatorColor default clRed;
  198.     property Preview: Boolean read FPreview write FPreview default False;
  199.     property AutoPlay: Boolean read FAutoPlay write FAutoPlay default False;
  200.     property DeviceID: integer read FDeviceID write FDeviceID default -1;
  201.   end;
  202.   {-- TMMWaveSaveDialog -------------------------------------------------------}
  203.   TMMWaveSaveDialog = class(TMMWaveOpenDialog)
  204.   public
  205.     constructor Create(AOwner: TComponent); override;
  206.     function Execute: Boolean; override;
  207.   end;
  208.   {-- TMMPictureOpenDialog ----------------------------------------------------}
  209.   TMMPictureOpenDialog = class(TMMCustomOpenDialog)
  210.   private
  211.     FBitmap      : TBitmap;
  212.     FPicture     : TPicture;
  213.     FPreview     : Boolean;
  214.     FColor       : TColor;
  215.     FHookWnd     : HWND;
  216.     FDefProc     : TFarProc;
  217.     FOldProc     : Longint;
  218.     FLastFile    : string;
  219.     procedure UpdatePicture;
  220.     procedure DrawPicture(DC: HDC; aRect: TRect);
  221.     procedure WndHookProc(var Message: TMessage);
  222.   protected
  223.     procedure DoCreate;override;
  224.     procedure DoDestroy;override;
  225.     procedure DoFileOK(FName: String; var IsOk: Boolean);override;
  226.     procedure DoSelChanged(FName: String);override;
  227.     procedure DoCommand(Wnd,Parent: Hwnd; cmd: Integer);override;
  228.   public
  229.     constructor Create(AOwner: TComponent); override;
  230.     destructor  Destroy; override;
  231.   published
  232.     property OnFileOK: TFileOKEvent read FOnFileOK write FOnFileOK;
  233.     property DefaultExt;
  234.     property FileName;
  235.     property Filter;
  236.     property FilterIndex default 1;
  237.     property InitialDir;
  238.     property Title;
  239.     property Options;
  240.     property Color: TColor read FColor write FColor default clWindow;
  241.     property Preview: Boolean read FPreview write FPreview default False;
  242.   end;
  243.   {-- TMMPictureSaveDialog ----------------------------------------------------}
  244.   TMMPictureSaveDialog = class(TMMPictureOpenDialog)
  245.   public
  246.     constructor Create(AOwner: TComponent); override;
  247.     function Execute: Boolean; override;
  248.   end;
  249. implementation
  250. {$IFDEF WIN32}
  251.    {$R MMCSTDLG.D32}
  252. {$ELSE}
  253.    {$R MMCSTDLG.D16}
  254. {$ENDIF}
  255. type
  256.    TDisplayRec = packed record
  257.       LeftMin : SmallInt;
  258.       LeftMax : SmallInt;
  259.       RightMin: SmallInt;
  260.       RightMax: SmallInt;
  261.    end;
  262.    PDisplayData = ^TDisplayData;
  263.    TDisplayData = array[0..0] of TDisplayRec;
  264. const
  265.      lst1 = $0460; { FileListBox ID  }
  266.      lst2 = $0461; { DirListBox ID   }
  267.      cmb2 = $0471; { DriveListBox ID }
  268.      BT_PLAY    = 1000;
  269.      CB_PREVIEW = 1001;
  270.      CB_AUTOPLAY= 1002;
  271.      LT_FORMAT  = 1003;
  272.      ST_SCOPE   = 1004;
  273.      ST_DIB     = 1005;
  274.      ST_PICTURE = 1000;   { Preview window for Picture Dialog }
  275.      Obj: TMMCustomOpenDialog = nil;
  276. const
  277.   HookCtl3D: Boolean = False;
  278.   DialogTitle: PChar = nil;
  279. var
  280.   CD_LBSelCh: Word;
  281.   CD_ShareVi: Word;
  282.   CD_FileOK : Word;
  283. procedure InitDialogs;
  284. begin
  285.    CD_LBSelCh := RegisterWindowMessage(LBSelChString);
  286.    CD_ShareVi := RegisterWindowMessage(ShareViString);
  287.    CD_FileOK  := RegisterWindowMessage(FileOKString);
  288. end;
  289. {-- Center the given window on the screen -------------------------------------}
  290. procedure CenterWindow(Wnd: HWnd);
  291. var
  292.   Rect: TRect;
  293. begin
  294.    GetWindowRect(Wnd, Rect);
  295.    SetWindowPos(Wnd, 0,
  296.          (GetSystemMetrics(SM_CXSCREEN) - Rect.Right + Rect.Left) div 2,
  297.          (GetSystemMetrics(SM_CYSCREEN) - Rect.Bottom + Rect.Top) div 3,
  298.          0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER);
  299. end;
  300. {$IFNDEF WIN32}
  301. function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
  302. type
  303.   TDialogFunc = function(var DialogData): Bool;
  304. var
  305.   ActiveWindow: HWnd;
  306.   WindowList: Pointer;
  307. begin
  308.   ActiveWindow := GetActiveWindow;
  309.   WindowList := DisableTaskWindows(0);
  310.   try
  311.     Result := TDialogFunc(DialogFunc)(DialogData);
  312.   finally
  313.     EnableTaskWindows(WindowList);
  314.     SetActiveWindow(ActiveWindow);
  315.   end;
  316. end;
  317. {$ENDIF}
  318. {------------------------------------------------------------------------------}
  319. function ExtractFileName_A(P: PChar; var S: String): PChar;
  320. var
  321.    Separator: Char;
  322. begin
  323.    Separator := #0;
  324.    Result := P;
  325.    while (Result[0] <> #0) and (Result[0] <> Separator) do Inc(Result);
  326.    SetString(S, P, Result - P);
  327.    if Result[0] = Separator then Inc(Result);
  328. end;
  329. {------------------------------------------------------------------------------}
  330. function ExtractFileName_B(P: PChar; var S: string): PChar;
  331. var
  332.    Separator: Char;
  333. begin
  334.    Separator := '"';
  335.    Result := P;
  336.    while (Result[0] <> #0) and (Result[0] <> Separator) do Inc(Result);
  337.    SetString(S, P, Result - P);
  338.    while (Result[0] = Separator) or (Result[0] = ' ') do inc(Result);
  339. end;
  340. {------------------------------------------------------------------------------}
  341. procedure ExtractFileNames(P: PChar; FileList: TStringList);
  342. var
  343.    DirName, FileName: string;
  344. begin
  345.    FileList.Clear;
  346.    P := ExtractFileName_A(P, DirName);
  347.    P := ExtractFileName_A(P, FileName);
  348.    if FileName = '' then
  349.       FileList.Add(DirName)
  350.    else
  351.      repeat
  352.        if (FileName[1] <> '') and ((Length(FileName) <= 3) or
  353.           (FileName[2] <> ':') or (FileName[3] <> '')) then
  354.            FileName := CheckPath(DirName,True) + FileName;
  355.        FileList.Add(FileName);
  356.        P := ExtractFileName_A(P, FileName);
  357.      until FileName = '';
  358. end;
  359. {------------------------------------------------------------------------------}
  360. function FindLastFileName(FName: string): string;
  361. var
  362.    DirName, FileName: string;
  363.    Buf,P: PChar;
  364. begin
  365.    Result := '';
  366.    if (FName <> '') then
  367.    begin
  368.       Buf := StrAlloc(8192);
  369.       try
  370.          P := Buf;
  371.          StrPCopy(P, FName);
  372.          P := ExtractFileName_B(P, DirName);
  373.          if DirName[Length(DirName)] = '' then SetLength(DirName, Length(DirName)-1);
  374.          P := ExtractFileName_B(P, FileName);
  375.          if FileName = '' then
  376.             Result := DirName
  377.          else
  378.          repeat
  379.             if (FileName[1] <> '') and ((Length(FileName) <= 3) or
  380.                (FileName[2] <> ':') or (FileName[3] <> '')) then
  381.                FileName := CheckPath(DirName,True) + FileName;
  382.             Result := FileName;
  383.             P := ExtractFileName_B(P, FileName);
  384.          until FileName = '';
  385.       finally
  386.          StrDispose(Buf);
  387.       end;
  388.    end;
  389. end;
  390. {------------------------------------------------------------------------------}
  391. { Explorer hook. Centers the dialog on the screen in response to
  392.   the WM_INITDIALOG message also distributes events}
  393. {$IFDEF WIN32}
  394. function ExplorerHook(Wnd: HWnd; Msg: UINT; WParam: WPARAM; LParam: LPARAM): UINT;stdcall;
  395. {$ELSE}
  396. function ExplorerHook(Wnd: HWnd; Msg, WParam: Word; LParam: Longint): Word; export;
  397. {$ENDIF}
  398. const
  399.    BufSize = 8192;
  400. var
  401.    Parent: HWnd;
  402.    ofn : ^TOpenFileName;
  403.    Len: Integer;
  404.    FName: String;
  405.    aResult: Boolean;
  406.    Buf: PChar;
  407.    i: integer;
  408. begin
  409.    Result := 0;
  410.    try
  411.       Parent := GetParent(Wnd);
  412.       case Msg of
  413.         WM_INITDIALOG:
  414.         begin
  415.            if HookCtl3D then
  416.            begin
  417.               Subclass3DDlg(Wnd, CTL3D_ALL);
  418.               SetAutoSubClass(True);
  419.            end;
  420.            {$IFDEF WIN32}
  421.            if not NewStyleControls then
  422.            {$ENDIF}
  423.            CenterWindow(Wnd);
  424.            ofn := Pointer(LParam);    {remember object pointer }
  425.            obj := Pointer(ofn^.lCustData);
  426.            obj.FHWnd := Wnd;
  427.            obj.DoCreate;
  428.            Result := 1;
  429.         end;
  430.         WM_Destroy:
  431.         begin
  432.            {clean up }
  433.            if assigned(obj) then
  434.            begin
  435.               obj.DoDestroy;
  436.               obj.FHWND := 0;
  437.               obj := nil;
  438.            end;
  439.            if HookCtl3D then SetAutoSubClass(False);
  440.         end;
  441.         WM_CTLCOLOR:
  442.            if HookCtl3D and (@Ctl3DCtlColorEx <> nil) then
  443.             Result := Ctl3DCtlColorEx(Wnd, Msg, WParam, LParam);
  444.         {$IFDEF WIN32}
  445.         { route notifications }
  446.         WM_NOTIFY:
  447.         begin
  448.            { Center after INIT if requested }
  449.            if (POFNotify(LParam)^.hdr.code = CDN_INITDONE) then
  450.               CenterWindow(GetWindowLong(Wnd, GWL_HWNDPARENT));
  451.            if assigned(obj) then
  452.            begin
  453.               { Dispatch each event }
  454.               if (POFNotify(LParam)^.hdr.code = CDN_FILEOK) then
  455.               begin
  456.                  aResult := True;
  457.                  if (ofAllowMultiSelect in obj.FOptions) then
  458.                  begin
  459.                     ExtractFileNames(POFNotify(LParam).lpOFN.lpstrFile, obj.FTempFiles);
  460.                     for i := 0 to obj.FTempFiles.Count-1 do
  461.                     begin
  462.                        obj.DoFileOK(obj.FTempFiles[i],aResult);
  463.                        if not aResult then break;
  464.                     end
  465.                  end
  466.                  else
  467.                  begin
  468.                     SetString(FName, POFNotify(LParam).lpOFN.lpstrFile,
  469.                               StrLen(POFNotify(LParam).lpOFN.lpstrFile));
  470.                               obj.DoFileOK(FName,aResult);
  471.                  end;
  472.                  Result := ord(not aResult);
  473.                  SetWindowLong(Wnd, DWL_MSGRESULT, ord(not aResult));
  474.               end;
  475.               if (POFNotify(LParam)^.hdr.code = CDN_SELCHANGE) then
  476.               begin
  477.                  Buf := StrAlloc(BufSize);
  478.                  try
  479.                     Len := SendMessage(GetParent(Wnd),CDM_GETFILEPATH,BufSize,LongInt(Buf));
  480.                     SetString(FName,Buf,Len-1);
  481.                     obj.DoSelChanged(FName);
  482.                  finally
  483.                     StrDispose(Buf);
  484.                  end;
  485.               end;
  486.            end;
  487.         end;
  488.         {$ENDIF}
  489.         { dispatch WM_COMMAND }
  490.         WM_COMMAND:
  491.            if assigned(obj) then obj.DoCommand(Wnd,Parent,LOWORD(WParam));
  492.         {$IFNDEF WIN32}
  493.         WM_NCACTIVATE,
  494.         WM_NCPAINT,
  495.         WM_SETTEXT:
  496.            if HookCtl3D and (@Ctl3DDlgFramePaint <> nil) then
  497.            begin
  498.               { The following fixes a Ctrl3D bug under Windows NT }
  499.               if (GetWinFlags and $4000 <> 0) and (Msg = WM_SETTEXT) and
  500.                  (DialogTitle <> nil) then
  501.                  LParam := Longint(DialogTitle);
  502.               SetWindowLong(Wnd, DWL_MSGRESULT, Ctl3DDlgFramePaint(Wnd, Msg,
  503.                             WParam, LParam));
  504.               Result := 1;
  505.            end;
  506.         {$ENDIF}
  507.         else
  508.         {$IFDEF WIN32}
  509.         if not NewStyleControls then
  510.         {$ENDIF}
  511.         begin
  512.            if (Msg = CD_FILEOK) then
  513.            begin
  514.               if assigned(obj) then
  515.               begin
  516.                  aResult := True;
  517.                  if (ofAllowMultiSelect in obj.FOptions) then
  518.                  begin
  519.                     ExtractFileNames(POpenFileNameA(LParam)^.lpstrFile, obj.FTempFiles);
  520.                     for i := 0 to obj.FTempFiles.Count-1 do
  521.                     begin
  522.                        obj.DoFileOK(obj.FTempFiles[i],aResult);
  523.                        if not aResult then break;
  524.                     end;
  525.                  end
  526.                  else
  527.                  begin
  528.                     FName := StrPas(POpenFileNameA(LParam)^.lpstrFile);
  529.                     obj.DoFileOK(FName,aResult);
  530.                  end;
  531.                  Result := ord(not aResult);
  532.                  SetWindowLong(Wnd, DWL_MSGRESULT, ord(not aResult));
  533.               end;
  534.            end;
  535.            if (Msg = CD_LBSelCh) then
  536.            begin
  537.               if (wParam = lst1) and assigned(obj) then
  538.               begin
  539.                  Buf := StrAlloc(BufSize);
  540.                  try
  541.                     Len := SendDlgItemMessage(Wnd,lst1, LB_GETTEXT, LoWord(lParam), Longint(Buf));
  542.                     if (Len <> LB_Err) then
  543.                     begin
  544.                        FName := ExpandUNCFileName(StrPas(Buf));
  545.                        obj.DoSelChanged(FName);
  546.                     end;
  547.                  finally
  548.                     StrDispose(Buf);
  549.                  end;
  550.               end;
  551.            end;
  552.         end;
  553.       end;
  554.    except
  555.       Application.HandleException(nil);
  556.    end;
  557. end;
  558. {== TMMCustomOpenDialog =======================================================}
  559. constructor TMMCustomOpenDialog.Create(AOwner: TComponent);
  560. begin
  561.    inherited Create(AOwner);
  562.    FHistoryList := TStringList.Create;
  563.    FFiles       := TStringList.Create;
  564.    FTempFiles   := TStringList.Create;
  565.    FFilterIndex := 1;
  566.    {$IFNDEF DELPHI4}
  567.    FSizing      := False;
  568.    {$ENDIF}
  569.    ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  570.    if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
  571. end;
  572. {-- TMMCustomOpenDialog -------------------------------------------------------}
  573. destructor TMMCustomOpenDialog.Destroy;
  574. begin
  575.    FFiles.Free;
  576.    FTempFiles.Free;
  577.    FHistoryList.Free;
  578.    inherited Destroy;
  579. end;
  580. {-- TMMCustomOpenDialog -------------------------------------------------------}
  581. function TMMCustomOpenDialog.DoExecute(Func: Pointer): Bool;
  582. const
  583.     {$IFNDEF DELPHI4}
  584.     OFN_ENABLESIZING    = $00800000;
  585.     {$ENDIF}
  586.     {$IFNDEF DELPHI6}
  587.     OFN_DONTADDTORECENT = $02000000;
  588.     OFN_FORCESHOWHIDDEN = $10000000;
  589.     {$ENDIF}
  590.     {$IFDEF WIN32}
  591.     {$IFDEF DELPHI6}
  592.     MultiSelectBufferSize = High(Word) - 16;
  593.     {$ELSE}
  594.     MultiSelectBufferSize = 8192;
  595.     {$ENDIF}
  596.     OpenOptions: array [TOpenOption] of DWORD = (
  597.     OFN_READONLY, OFN_OVERWRITEPROMPT, OFN_HIDEREADONLY,
  598.     OFN_NOCHANGEDIR, OFN_SHOWHELP, OFN_NOVALIDATE, OFN_ALLOWMULTISELECT,
  599.     OFN_EXTENSIONDIFFERENT, OFN_PATHMUSTEXIST, OFN_FILEMUSTEXIST,
  600.     OFN_CREATEPROMPT, OFN_SHAREAWARE, OFN_NOREADONLYRETURN,
  601.     OFN_NOTESTFILECREATE, OFN_NONETWORKBUTTON, OFN_NOLONGNAMES,
  602.     OFN_EXPLORER, OFN_NODEREFERENCELINKS
  603.     {$IFDEF DELPHI4}
  604.     ,OFN_ENABLEINCLUDENOTIFY,
  605.     OFN_ENABLESIZING
  606.     {$ENDIF}
  607.     {$IFDEF DELPHI6}
  608.     ,OFN_DONTADDTORECENT,
  609.     OFN_FORCESHOWHIDDEN
  610.     {$ENDIF}
  611.     );
  612.     {$ELSE}
  613.     MultiSelectBufferSize = 1000;
  614.     OpenOptions: array [TOpenOption] of Longint = (
  615.     OFN_READONLY, OFN_OVERWRITEPROMPT, OFN_HIDEREADONLY,
  616.     OFN_NOCHANGEDIR, OFN_SHOWHELP, OFN_NOVALIDATE, OFN_ALLOWMULTISELECT,
  617.     OFN_EXTENSIONDIFFERENT, OFN_PATHMUSTEXIST, OFN_FILEMUSTEXIST,
  618.     OFN_CREATEPROMPT, OFN_SHAREAWARE, OFN_NOREADONLYRETURN,
  619.     OFN_NOTEXTFILECREATE);
  620.     {$ENDIF}
  621. var
  622.   OpenFilename: TOpenFilename;
  623.   Option: TOpenOption;
  624.   CDefaultExt: array[0..3] of Char;
  625.   CInitialDir: array[0..79] of Char;
  626.   CTitle: array[0..79] of Char;
  627.   CFilter: array[0..1023] of Char;
  628.   CTemplate: array[0..257] of Char;
  629.   S: string;
  630.   function StrFilterCopy(P: PChar; const S: string): PChar;
  631.   begin
  632.     Result := nil;
  633.     if S <> '' then
  634.     begin
  635.       {$IFDEF WIN32}
  636.       { Because StrPCopy truncates 256 characters }
  637.       Result := StrCopy(P,PChar(S));
  638.       {$ELSE}
  639.       Result := StrPCopy(P, S);
  640.       {$ENDIF}
  641.       while P^ <> #0 do
  642.       begin
  643.         if P^ = '|' then P^ := #0;
  644.         Inc(P);
  645.       end;
  646.       Inc(P);
  647.       P^ := #0;
  648.     end;
  649.   end;
  650. begin
  651.    FFiles.Clear;
  652.    FillChar(OpenFileName, SizeOf(OpenFileName), 0);
  653.    with OpenFilename do
  654.    try
  655.      lStructSize := SizeOf(TOpenFilename);
  656.      hInstance := {$IFDEF DELPHI3}SysInit.HInstance{$ELSE}System.HInstance{$ENDIF};
  657.      lpstrFilter := StrFilterCopy(CFilter, FFilter);
  658.      nFilterIndex := FFilterIndex;
  659.      if ofAllowMultiSelect in FOptions then
  660.         nMaxFile := MultiSelectBufferSize
  661.      else
  662.         {$IFDEF WIN32}
  663.         nMaxFile := MAX_PATH;
  664.         {$ELSE}
  665.         nMaxFile := sizeof(TFileName);
  666.         {$ENDIF}
  667.      GetMem(lpstrFile, nMaxFile + 2);
  668.      FillChar(lpstrFile^, nMaxFile + 2, 0);
  669.      StrPCopy(lpstrFile, FFileName);
  670.      lpstrInitialDir := StrPLCopy(CInitialDir, FInitialDir,
  671.                                   SizeOf(CInitialDir) - 1);
  672.      lpstrTitle := StrPLCopy(CTitle, FTitle, SizeOf(CTitle) - 1);
  673.      if Length(FTitle) > 0 then DialogTitle := lpstrTitle;
  674.      { Always enable hook }
  675.      Flags := OFN_ENABLEHOOK;
  676.      for Option := Low(Option) to High(Option) do
  677.      if Option in FOptions then
  678.         Flags := Flags or OpenOptions[Option];
  679.      {$IFDEF WIN32}
  680.      if NewStyleControls then
  681.      begin
  682.         Flags := Flags or OFN_EXPLORER;
  683.         {$IFNDEF DELPHI4}
  684.         if FSizing then Flags := Flags or OFN_ENABLESIZING;
  685.         {$ENDIF}
  686.      end
  687.      else
  688.         Flags := Flags and not OFN_EXPLORER;
  689.      {$ENDIF}
  690.      lpstrDefExt := StrPCopy(CDefaultExt, FDefaultExt);
  691.      { add custom callback }
  692.      lpfnHook := ExplorerHook;
  693. {$IFDEF WIN32}
  694.      if NewStyleControls then
  695.         HookCtl3D := False
  696.      else
  697. {$ENDIF}
  698.         HookCtl3D := Ctl3D;
  699.      { add custom resource  }
  700.      if FTemplateName <> '' then
  701.      begin
  702.         lpTemplateName:= StrPLCopy(CTemplate, FTemplateName, SizeOf(CTemplate)-1);
  703.         Flags := Flags or OFN_ENABLETEMPLATE;
  704. {$IFDEF WIN32}
  705.         if not NewStyleControls then
  706.            StrLCat(lpTemplateName,'OLD',SizeOf(CTemplate)-1);
  707. {$ENDIF}
  708.      end;
  709.      {$IFDEF WIN32}
  710.      {$IFDEF TRIAL}
  711.      {$DEFINE _HACK2}
  712.      {$I MMHACK.INC}
  713.      {$ENDIF}
  714.      {$ENDIF}
  715.      { allow callback to find object }
  716.      lCustData:=LongInt(Self);
  717.      hWndOwner := Application.Handle;
  718.      Result := TaskModalDialog(Func, OpenFileName);
  719.      DialogTitle := nil;
  720.      if Result then
  721.      begin
  722.         if ofAllowMultiSelect in FOptions then
  723.         begin
  724.            ExtractFileNames(lpstrFile,TStringList(FFiles));
  725.            FFileName := FFiles[0];
  726.         end
  727.         else
  728.         begin
  729.            ExtractFileName_A(lpstrFile, S);
  730.            FFileName := S;
  731.            FFiles.Add(FFileName);
  732.         end;
  733.         if (Flags and OFN_EXTENSIONDIFFERENT) <> 0 then
  734.             Include(FOptions, ofExtensionDifferent)
  735.         else
  736.             Exclude(FOptions, ofExtensionDifferent);
  737.         if (Flags and OFN_READONLY) <> 0 then
  738.             Include(FOptions, ofReadOnly)
  739.         else
  740.             Exclude(FOptions, ofReadOnly);
  741.         FFilterIndex := nFilterIndex;
  742.      end;
  743.    finally
  744.      if lpstrFile <> nil then FreeMem(lpstrFile, nMaxFile + 2);
  745.    end;
  746. end;
  747. {-- TMMCustomOpenDialog -------------------------------------------------------}
  748. procedure TMMCustomOpenDialog.SetHistoryList(Value: TStrings);
  749. begin
  750.    {$IFDEF WIN32}
  751.    {$IFDEF TRIAL}
  752.    {$DEFINE _HACK1}
  753.    {$I MMHACK.INC}
  754.    {$ENDIF}
  755.    {$ENDIF}
  756.    FHistoryList.Assign(Value);
  757. end;
  758. {-- TMMCustomOpenDialog -------------------------------------------------------}
  759. procedure TMMCustomOpenDialog.SetInitialDir(const Value: string);
  760. var
  761.   L: Integer;
  762. begin
  763.    L := Length(Value);
  764.    if (L > 1) and (Value[L] = '') and (Value[L - 1] <> ':') then Dec(L);
  765.    FInitialDir := Copy(Value, 1, L);
  766.    {$IFDEF WIN32}
  767.    {$IFDEF TRIAL}
  768.    {$DEFINE _HACK3}
  769.    {$I MMHACK.INC}
  770.    {$ENDIF}
  771.    {$ENDIF}
  772. end;
  773. {-- TMMCustomOpenDialog -------------------------------------------------------}
  774. function TMMCustomOpenDialog.Execute: Boolean;
  775. begin
  776.    Result := DoExecute(@GetOpenFileName);
  777. end;
  778. {-- TMMCustomOpenDialog -------------------------------------------------------}
  779. procedure TMMCustomOpenDialog.DoCreate;
  780. begin
  781.    if assigned(FOnCreate) then
  782.       FOnCreate(Self);
  783. end;
  784. {-- TMMCustomOpenDialog -------------------------------------------------------}
  785. procedure TMMCustomOpenDialog.DoDestroy;
  786. begin
  787.    if assigned(FOnDestroy) then
  788.       FOnDestroy(Self);
  789. end;
  790. {-- TMMCustomOpenDialog -------------------------------------------------------}
  791. procedure TMMCustomOpenDialog.DoFileOK(FName: String; var IsOk: Boolean);
  792. begin
  793.    if assigned(FOnFileOK) then
  794.       FOnFileOK(Self,FName,IsOK);
  795. end;
  796. {-- TMMCustomOpenDialog -------------------------------------------------------}
  797. procedure TMMCustomOpenDialog.DoSelChanged(FName: String);
  798. begin
  799.    if assigned(FOnSelChange) then
  800.       FOnSelChange(Self,FName);
  801. end;
  802. {-- TMMCustomOpenDialog -------------------------------------------------------}
  803. procedure TMMCustomOpenDialog.DoCommand(Wnd,Parent: Hwnd; cmd: Integer);
  804. begin
  805.    if assigned(FOnCommand) then
  806.       FOnCommand(Self,Wnd,Parent,cmd);
  807. end;
  808. {== TMMWaveOpenDialog =========================================================}
  809. constructor TMMWaveOpenDialog.Create(AOwner: TComponent);
  810. begin
  811.    inherited Create(AOwner);
  812.    Options := Options + [ofHideReadOnly];
  813.    {$IFDEF WIN32}
  814.    Options := Options + [ofNoNetworkButton];
  815.    {$ENDIF}
  816.    FPreview := False;
  817.    FAutoPlay:=False;
  818.    FDeviceID:= -1;
  819.    FUpdating := False;
  820.    FColor := clBlack;
  821.    FForeColor := clLime;
  822.    FLocatorColor := clRed;
  823.    FData := nil;
  824.    Title := LoadResStr(IDS_WAVEOPEN);
  825.    DefaultExt:= 'wav';
  826.    Filter := LoadResStr(IDS_WAVEFILTER);
  827.    FScopeWnd := 0;
  828.    FDIBWnd := 0;
  829.    {$IFNDEF WIN32}
  830.    if _WINNT_ then
  831.       TemplateName := 'CustomWaveOpenDlgNT'
  832.    else
  833.    {$ENDIF}
  834.       TemplateName := 'CustomWaveOpenDlg';
  835. end;
  836. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  837. destructor TMMWaveOpenDialog.Destroy;
  838. begin
  839.    DoDestroy;
  840.    inherited Destroy;
  841. end;
  842. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  843. procedure TMMWaveOpenDialog.DoCreate;
  844. var
  845.    aRect: TRect;
  846.    aBuf: array[0..20] of Char;
  847. begin
  848.    if (FScopeWnd = 0) then
  849.    begin
  850.       FScopeWnd := GetDlgItem(Wnd,ST_SCOPE);
  851.       FScopeDefProc := Pointer(GetWindowLong(FScopeWnd,GWL_WNDPROC));
  852.       FScopeOldProc := SetWindowLong(FScopeWnd,GWL_WNDPROC,
  853.                        Longint(MakeObjectInstance(ScopeWndHookProc)));
  854.    end;
  855.    if (FDIBWnd = 0) then
  856.    begin
  857.       FDIBWnd := GetDlgItem(Wnd,ST_DIB);
  858.       FDIBDefProc := Pointer(GetWindowLong(FDIBWnd,GWL_WNDPROC));
  859.       FDIBOldProc := SetWindowLong(FDIBWnd,GWL_WNDPROC,
  860.                      Longint(MakeObjectInstance(DIBWndHookProc)));
  861.    end;
  862.    if (FData = nil) then
  863.    begin
  864.       { alloc the data buffer for the scope data }
  865.       {$IFDEF WIN32}
  866.       Windows.GetClientRect(FScopeWnd, aRect);
  867.       {$ELSE}
  868.       WinProcs.GetClientRect(FScopeWnd, aRect);
  869.       {$ENDIF}
  870.       FData := GlobalAllocPtr(GPTR, (aRect.Right-aRect.Left)*sizeOf(TDisplayRec));
  871.       { now create some components }
  872.       FWaveFile := TMMWaveFile.Create(Self);
  873.       FWaveFile.Wave.TimeFormat := tfByte;
  874.       FWaveFile.Wave.IOBufferSize := 4*32768;
  875.       FADPCMConvert := TMMADPCMConverter.Create(Self);
  876.       FADPCMConvert.Input := FWaveFile;
  877.       FWaveOut := TMMWaveOut.Create(Self);
  878.       FWaveOut.Input := FADPCMConvert;
  879.       FWaveOut.OnStart := WaveOutStart;
  880.       FWaveOut.OnStop := WaveOutStop;
  881.       FWaveOut.BufferSize := 32768;
  882.       FWaveOut.NumBuffers := 10;
  883.       FWaveOut.TimeFormat := tfByte;
  884.       if FWaveOut.NumDevs > 0 then
  885.          FWaveOut.DeviceID := FDeviceId
  886.       else EnableWindow(GetDlgItem(Wnd,CB_AutoPlay), False);
  887.       FTimer := TTimer.Create(Self);
  888.       FTimer.Enabled := False;
  889.       FTimer.Interval := 50;
  890.       FTimer.OnTimer := TimerExpired;
  891.    end;
  892.    EnableWindow(GetDlgItem(Wnd,BT_Play), False);
  893.    EnableWindow(GetDlgItem(Wnd,CB_PREVIEW), False);
  894.    SetDlgItemText(Wnd,CB_PREVIEW,StrPCopy(aBuf,LoadResStr(IDS_PREVIEW)));
  895.    SendDlgItemMessage(Wnd,CB_PREVIEW, BM_SETCHECK, Ord(FPReview), 0);
  896.    SendDlgItemMessage(Wnd,CB_AUTOPLAY, BM_SETCHECK, Ord(FAutoPlay), 0);
  897.    {$IFDEF WIN32}
  898.    if not NewStyleControls then
  899.    {$ENDIF}
  900.    begin
  901.       { TODO: hier Texte im Dialog lokalisieren !!!
  902.        oder gleich englische Resource verwenden }
  903.    end;
  904.    inherited DoCreate;
  905. end;
  906. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  907. procedure TMMWaveOpenDialog.DoDestroy;
  908. begin
  909.    if (FData <> nil) then
  910.    begin
  911.       { free the data buffer }
  912.       GlobalFreePtr(FData);
  913.       FData := nil;
  914.    end;
  915.    if (FWaveOut <> nil) then
  916.    begin
  917.       FWaveOut.Close;
  918.       FWaveOut.Free;
  919.       FWaveOut := nil;
  920.    end;
  921.    if (FADPCMConvert <> nil) then
  922.    begin
  923.       FADPCMConvert.Close;
  924.       FADPCMConvert.Free;
  925.       FADPCMConvert := nil;
  926.    end;
  927.    if (FWaveFile <> nil) then
  928.    begin
  929.       FWaveFile.Wave.FreeWave;
  930.       FWaveFile.Free;
  931.       FWaveFile := nil;
  932.    end;
  933.    if (FTimer <> nil) then
  934.    begin
  935.       FTimer.Free;
  936.       FTimer := nil;
  937.    end;
  938.    if (FScopeWnd <> 0) then
  939.    begin
  940.       FreeObjectInstance(Pointer(SetWindowLong(FScopeWnd,GWL_WNDPROC,FScopeOldProc)));
  941.       FScopeWnd := 0;
  942.    end;
  943.    if (FDIBWnd <> 0) then
  944.    begin
  945.       FreeObjectInstance(Pointer(SetWindowLong(FDIBWnd,GWL_WNDPROC,FDIBOldProc)));
  946.       FDIBWnd := 0;
  947.    end;
  948.    inherited DoDestroy;
  949. end;
  950. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  951. procedure TMMWaveOpenDialog.DoFileOK(FName: String; var IsOk: Boolean);
  952. begin
  953.    if not (Self is TMMWaveSaveDialog) then
  954.    begin
  955.       IsOK := wioIsWaveFile(FName, RIFF_FILE);
  956.       if not IsOK then
  957.          MessageDlg(LoadResStr(IDS_WAVEINVALID), mtError, [mbOK], 0)
  958.       else
  959.          inherited DoFileOK(FName, IsOK);
  960.    end
  961.    else inherited DoFileOK(FName, IsOK);
  962. end;
  963. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  964. procedure TMMWaveOpenDialog.DoSelChanged(FName: String);
  965. var
  966.    LastName: String;
  967. begin
  968.    if assigned(FWaveFile) then
  969.    begin
  970.       LastName := FindLastFileName(FName);
  971.       if (LastName <> FWaveFile.Wave.FileName) then
  972.       begin
  973.          FWaveOut.Close;
  974.          if wioIsWaveFile(LastName, RIFF_FILE) then
  975.          begin
  976.             FWaveFile.Wave.FileName := LastName;
  977.             FADPCMConvert.Enabled := FADPCMConvert.CanConvert;
  978.          end
  979.          else
  980.             FWaveFile.Wave.FreeWave;
  981.          FUpdating := True;
  982.          { make sure the item is first selected, then update }
  983.          KillTimer(FScopeWnd,99);
  984.          SetTimer(FScopeWnd,99,50,nil);
  985.       end;
  986.    end;
  987.    inherited DoSelChanged(FName);
  988. end;
  989. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  990. procedure TMMWaveOpenDialog.DoCommand(Wnd,Parent: Hwnd; cmd: Integer);
  991. begin
  992.    if (Wnd = FHWnd) then
  993.    begin
  994.       if (cmd = BT_Play) and (FWaveOut.NumDevs > 0) then
  995.       begin
  996.          if not (wosPlay in FWaveOut.State) then
  997.          begin
  998.             if not FWaveFile.Wave.Empty and
  999.                FWaveOut.QueryDevice(FWaveOut.DeviceID,FWaveOut.PWaveFormat) then
  1000.             try
  1001.                FWaveOut.Start;
  1002.             except
  1003.                { don't raise a exception here }
  1004.             end;
  1005.          end
  1006.          else FWaveOut.Close;
  1007.       end
  1008.       else if (cmd = CB_PREVIEW) then
  1009.       begin
  1010.          FPreview := SendDlgItemMessage(Wnd, CB_PREVIEW, BM_GetCheck, 0, 0)<> 0;
  1011.          if FPreview then FWaveOut.Close;
  1012.          UpdateWave;
  1013.       end
  1014.       else if (cmd = CB_AUTOPLAY) then
  1015.       begin
  1016.          FAutoPlay := SendDlgItemMessage(Wnd, CB_AUTOPLAY, BM_GetCheck, 0, 0)<> 0;
  1017.          if FAutoPlay then
  1018.          begin
  1019.             if not (wosPlay in FWaveOut.State) and
  1020.                not FWaveFile.Wave.Empty and
  1021.                FWaveOut.QueryDevice(FWaveOut.DeviceID,FWaveOut.PWaveFormat) then
  1022.             try
  1023.                FWaveOut.Start;
  1024.             except
  1025.                { don't raise a exception here }
  1026.             end;
  1027.          end
  1028.          else FWaveOut.Close;
  1029.       end;
  1030.    end;
  1031.    inherited DoCommand(Wnd,Parent,cmd);
  1032. end;
  1033. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1034. procedure TMMWaveOpenDialog.WaveOutStart(Sender: TObject);
  1035. begin
  1036.    FOldPos := -1;
  1037.    FTimer.Enabled := True;
  1038.    SetDlgItemText(Wnd,BT_PLAY,'Stop');
  1039. end;
  1040. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1041. procedure TMMWaveOpenDialog.WaveOutStop(Sender: TObject);
  1042. begin
  1043.    FTimer.Enabled := False;
  1044.    DrawLocator(FOldPos,-1);
  1045.    SetDlgItemText(Wnd,BT_PLAY,'Play');
  1046. end;
  1047. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1048. procedure TMMWaveOpenDialog.DrawLocator(var OldPos: Longint; NewPos: Longint);
  1049. Var
  1050.    OldPen: HPen;
  1051.    OldMode: integer;
  1052.    DC: HDC;
  1053.    aRect: TRect;
  1054.    X: integer;
  1055. begin
  1056.    if not FPreview or (FWaveFile.Wave.FormatTag <> 1) then exit;
  1057.    {$IFDEF WIN32}
  1058.    Windows.GetClientRect(FScopeWnd, aRect);
  1059.    {$ELSE}
  1060.    WinProcs.GetClientRect(FScopeWnd, aRect);
  1061.    {$ENDIF}
  1062.    InflateRect(aRect, -2, -2);
  1063.    DC := GetDC(FScopeWnd);
  1064.    try
  1065.       OldPen := SelectObject(DC,CreatePen(PS_SOLID,1,ColorToRGB(FLocatorColor)));
  1066.       try
  1067.           OldMode := SetROP2(DC, R2_XORPEN);
  1068.           try
  1069.               if (OldPos <> -1) then
  1070.               begin
  1071.                  { clear old locator }
  1072.                  X := MulDiv32(aRect.Right-aRect.Left,OldPos,FWaveFile.Wave.DataSize);
  1073.                  MoveToEx(DC,aRect.Left+X,aRect.Top, nil);
  1074.                  LineTo(DC,aRect.Left+X,aRect.Bottom-1);
  1075.               end;
  1076.               { draw new locator }
  1077.               if (NewPos <> -1) then
  1078.               begin
  1079.                  X := MulDiv32(aRect.Right-aRect.Left,NewPos,FWaveFile.Wave.DataSize);
  1080.                  MoveToEx(DC,aRect.Left+X,aRect.Top, nil);
  1081.                  LineTo(DC,aRect.Left+X,aRect.Bottom-1);
  1082.               end;
  1083.               OldPos := NewPos;
  1084.           finally
  1085.             SetROP2(DC, OldMode);
  1086.           end;
  1087.       finally
  1088.           DeleteObject(SelectObject(DC,OldPen));
  1089.       end;
  1090.    finally
  1091.       ReleaseDC(FScopeWnd,DC);
  1092.    end;
  1093. end;
  1094. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1095. procedure TMMWaveOpenDialog.TimerExpired(Sender: TObject);
  1096. begin
  1097.    if (wosPlay in FWaveOut.State) then
  1098.       DrawLocator(FOldPos,FWaveOut.Position);
  1099. end;
  1100. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1101. procedure TMMWaveOpenDialog.DrawDISP(DC: HDC; aRect: TRect);
  1102. var
  1103.    ParentDC: HDC;
  1104.    aBitmap: TBitmap;
  1105.    R: TRect;
  1106.    lpDisp: PDISP;
  1107.    hBM: HBITMAP;
  1108.    Clr: Longint;
  1109. begin
  1110.    with FWaveFile.Wave, aRect do
  1111.    begin
  1112.       aBitmap := TBitmap.Create;
  1113.       with aBitmap, aBitmap.Canvas do
  1114.       try
  1115.          aBitmap.Width := aRect.Right-aRect.Left;
  1116.          aBitmap.Height := aRect.Bottom-aRect.Top;
  1117.          R := Rect(0,0,aBitmap.Width,aBitmap.Height);
  1118.          { find the right background color }
  1119.          ParentDC := GetDC(Wnd);
  1120.          clr := GetPixel(ParentDC,0,0);
  1121.          ReleaseDC(Wnd, ParentDC);
  1122.          { clear background }
  1123.          Brush.Color := clr;{ clBtnFace; }
  1124.          FillRect(R);
  1125.          if (FileName <> '') then
  1126.          begin
  1127.             lpDisp := PWaveIOInfo^.lpDisp^.pHead;
  1128.             while (lpDisp <> nil) do
  1129.             begin
  1130.                if (lpDisp^.cfid = CF_DIB) then break;
  1131.                lpDisp := lpDisp^.pNext;
  1132.             end;
  1133.             if (lpDisp <> nil) then
  1134.             begin
  1135.                InflateRect(R, -2, -2);
  1136.                { Frame3D(Canvas,R,clBtnShadow,clBtnHighLight,1);
  1137.                  Frame3D(Canvas,R,clWindowFrame,cl3DLight,1); }
  1138.                DIB_Display(PDIB(lpDisp^.lpChunk),Canvas.Handle, R);
  1139.             end
  1140.             else
  1141.             begin
  1142.                InflateRect(R, -2, -2);
  1143.                hBM := LoadBitmap(HInstance, 'BMP_WAVE');
  1144.                DrawTransparentBitmap(Canvas.Handle, hBM,
  1145.                                      R.Left,R.Top,
  1146.                                      GetTransparentColor(hBM));
  1147.                DeleteObject(hBM);
  1148.             end;
  1149.          end;
  1150.          BitBlt(DC,aRect.Left,aRect.Top,aRect.Right-aRect.Left,
  1151.                 aRect.Bottom-aRect.Top,
  1152.                 aBitmap.Canvas.Handle, 0,0,SRCCOPY);
  1153.       finally
  1154.          aBitmap.Free;
  1155.       end;
  1156.    end;
  1157. end;
  1158. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1159. procedure TMMWaveOpenDialog.CreatePCMData(DC: HDC; aRect: TRect);
  1160. var
  1161.    i,aWidth,aHeight,Y1: integer;
  1162.    aResult,Bytes: Longint;
  1163.    ReadBuffer: PChar;
  1164.    Data: PDisplayData;
  1165.    Canvas: TCanvas;
  1166. begin
  1167.    InflateRect(aRect, -2, -2);
  1168.    aWidth := aRect.Right-aRect.Left;
  1169.    aHeight := aRect.Bottom-aRect.Top;
  1170.    FillChar(FData^, aWidth*sizeOf(TDisplayRec),0);
  1171.    if not FWaveFile.Wave.Empty and FPreview then
  1172.    with FWaveFile.Wave do
  1173.    begin
  1174.       Canvas := TCanvas.Create;
  1175.       with Canvas, aRect do
  1176.       try
  1177.          Handle := DC;
  1178.          Brush.Color := FColor;
  1179.          FillRect(aRect);
  1180.          Bytes := Max(DataSize div aWidth and not 3,4);
  1181.          ReadBuffer := GlobalAllocPtr(GHND, Bytes);
  1182.          try
  1183.             OpenFile;
  1184.             Position := 0;
  1185.             Data:= FData;
  1186.             Screen.Cursor := crHourGlass;
  1187.             Pen.Color := FForeColor;
  1188.             MoveTo(Left,Top+(aHeight div 2));
  1189.             i := 0;
  1190.             while (i < aWidth) do
  1191.             begin
  1192.                aResult := ReadDataBytes(ReadBuffer, Bytes);
  1193.                if aResult <= 0 then break;
  1194.                pcmFindMinMax(PWaveFormat,ReadBuffer, aResult,
  1195.                              Data^[i].LeftMin,
  1196.                              Data^[i].LeftMax,
  1197.                              Data^[i].RightMin,
  1198.                              Data^[i].RightMax);
  1199.                if (BitLength = 8) then
  1200.                begin
  1201.                   Data^[i].LeftMin := (Word(Data^[i].LeftMin) shl 8) xor $8000;
  1202.                   Data^[i].LeftMax := (Word(Data^[i].LeftMax) shl 8) xor $8000;
  1203.                   Data^[i].RightMin:= (Word(Data^[i].RightMin) shl 8) xor $8000;
  1204.                   Data^[i].RightMax:= (Word(Data^[i].RightMax) shl 8) xor $8000;
  1205.                end;
  1206.                Brush.Color := FColor;
  1207.                FillRect(Rect(Left+i,Top,Left+i+1,Bottom));
  1208.                Y1 := MulDiv32(Min(Data^[i].LeftMin,Data^[i].RightMin)+ Long($7FFF),aHeight,$FFFF);
  1209.                LineTo(Left+i, Bottom-Y1-1);
  1210.                Y1 := MulDiv32(Max(Data^[i].LeftMax,Data^[i].RightMax)+ Long($7FFF),aHeight,$FFFF);
  1211.                LineTo(Left+i, Bottom-Y1-1);
  1212.                Brush.Color := FLocatorColor;
  1213.                if (i < aWidth-1) and (DataSize > 1024*2048) then
  1214.                   FillRect(Rect(Left+i+1,Top,Left+i+2,Bottom));
  1215.                {$IFDEF WIN32}
  1216.                GDIFlush;
  1217.                {$ENDIF}
  1218.                inc(i);
  1219.             end;
  1220.             if (i < aWidth-1) then
  1221.             begin
  1222.                if (i > 0) then dec(i);
  1223.                MoveTo(Left+i, Top+(aHeight div 2));
  1224.                LineTo(Right, Top+(aHeight div 2));
  1225.             end;
  1226.          finally
  1227.             CloseFile;
  1228.             GlobalFreePtr(ReadBuffer);
  1229.             Screen.Cursor := crDefault;
  1230.          end;
  1231.       finally
  1232.          Canvas.Handle := 0;
  1233.          Canvas.Free;
  1234.       end;
  1235.    end;
  1236. end;
  1237. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1238. procedure TMMWaveOpenDialog.DrawPCMData(DC: HDC; aRect: TRect);
  1239. var
  1240.    i,Y1,aHeight: integer;
  1241.    R: TRect;
  1242.    Data: PDisplayData;
  1243.    aBitmap: TBitmap;
  1244. begin
  1245.    with FWaveFile.Wave do
  1246.    begin
  1247.       aBitmap := TBitmap.Create;
  1248.       with aBitmap.Canvas, R do
  1249.       try
  1250.          aBitmap.Width := aRect.Right-aRect.Left;
  1251.          aBitmap.Height := aRect.Bottom-aRect.Top;
  1252.          R := Rect(0,0,aBitmap.Width,aBitmap.Height);
  1253.          { clear background }
  1254.          Brush.Color := FColor;
  1255.          FillRect(R);
  1256.          Frame3D(aBitmap.Canvas,R,clBtnShadow,clBtnHighLight,1);
  1257.          Frame3D(aBitmap.Canvas,R,clWindowFrame,cl3DLight,1);
  1258.          FOldPos := -1;
  1259.          if (FileName = '') or not FPreview or
  1260.             (FormatTag <> 1) or (DataSize <= 0) then
  1261.          begin
  1262.             { only draw a horizontal line }
  1263.             Pen.Color := clGray;
  1264.             MoveTo(Left+5, Top+(Bottom-Top) div 2);
  1265.             LineTo((Right-Left)-5,Top+(Bottom-Top) div 2);
  1266.          end
  1267.          else if not FUpdating then
  1268.          begin
  1269.             Data := FData;
  1270.             Pen.Color := FForeColor;
  1271.             aHeight := Bottom-Top;
  1272.             Y1 := MulDiv32(Min(Data^[0].LeftMin,Data^[0].RightMin) + Long($7FFF),aHeight,$FFFF);
  1273.             MoveTo(Left, Top+aHeight-Y1-1);
  1274.             Y1 := MulDiv32(Max(Data^[0].LeftMax,Data^[0].RightMax) + Long($7FFF),aHeight,$FFFF);
  1275.             LineTo(Left, Top+aHeight-Y1-1);
  1276.             i := 0;
  1277.             while i < Right-Left do
  1278.             begin
  1279.                Y1 := MulDiv32(Min(Data^[i].LeftMin,Data^[i].RightMin) + Long($7FFF),aHeight,$FFFF);
  1280.                LineTo(Left+i, Bottom-Y1-1);
  1281.                Y1 := MulDiv32(Max(Data^[i].LeftMax,Data^[i].RightMax) + Long($7FFF),aHeight,$FFFF);
  1282.                LineTo(Left+i, Bottom-Y1-1);
  1283.                inc(i);
  1284.             end;
  1285.             LineTo(Left+i, Bottom-Y1-1);
  1286.          end;
  1287.          BitBlt(DC,aRect.Left,aRect.Top,aRect.Right-aRect.Left,
  1288.                 aRect.Bottom-aRect.Top,
  1289.                 aBitmap.Canvas.Handle,0,0,SRCCOPY);
  1290.       finally
  1291.          aBitmap.Free;
  1292.       end;
  1293.    end;
  1294. end;
  1295. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1296. procedure TMMWaveOpenDialog.UpdatePlayParams;
  1297. begin
  1298.    if not FWaveFile.Wave.Empty and (FWaveOut.PWaveFormat <> nil) then
  1299.    begin
  1300.       { adjust the buffersize for best results }
  1301.       case Word(FWaveOut.PWaveFormat^.nSamplesPerSec) of
  1302.            00000..15000: FWaveOut.BufferSize := 512;
  1303.            15001..24000: FWaveOut.BufferSize := 1024;
  1304.            24001..32000: FWaveOut.BufferSize := 2048;
  1305.            32001..48000: FWaveOut.BufferSize := 3072;
  1306.       end;
  1307.       case FWaveOut.PWaveFormat^.wBitsPerSample of
  1308.               1: FWaveOut.BufferSize := FWaveOut.BufferSize div 16;
  1309.            2..4: FWaveOut.BufferSize := FWaveOut.BufferSize div 8;
  1310.            5..7: FWaveOut.BufferSize := FWaveOut.BufferSize div 4;
  1311.           9..16: FWaveOut.BufferSize := FWaveOut.BufferSize * 2;
  1312.       end;
  1313.    end;
  1314. end;
  1315. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1316. procedure TMMWaveOpenDialog.UpdateWave;
  1317. Label CheckDevice;
  1318. var
  1319.    aBuf: array[0..256] of Char;
  1320.    Format,FormatName,Size: String;
  1321.    aRect: TRect;
  1322.    DC: HDC;
  1323. begin
  1324.    {$IFDEF WIN32}
  1325.    Windows.GetClientRect(FDIBWnd, aRect);
  1326.    {$ELSE}
  1327.    WinProcs.GetClientRect(FDIBWnd, aRect);
  1328.    {$ENDIF}
  1329.    DC := GetDC(FDIBWnd);
  1330.    try
  1331.       DrawDISP(DC, aRect);
  1332.    finally
  1333.       ReleaseDC(FDIBWnd,DC);
  1334.    end;
  1335.    EnableWindow(GetDlgItem(Wnd,CB_PREVIEW), False);
  1336.    with FWaveFile.Wave do
  1337.    if (FileName = '') then
  1338.    begin
  1339.       Format := LoadResStr(IDS_WAVEUNKNOWN);
  1340.       SetDlgItemText(Wnd,LT_FORMAT,StrPCopy(aBuf, Format));
  1341.       EnableWindow(GetDlgItem(Wnd,BT_Play), False);
  1342.       {$IFDEF WIN32}
  1343.       Windows.GetClientRect(FScopeWnd, aRect);
  1344.       {$ELSE}
  1345.       WinProcs.GetClientRect(FScopeWnd, aRect);
  1346.       {$ENDIF}
  1347.       InvalidateRect(FScopeWnd, @aRect, False);
  1348.    end
  1349.    else
  1350.    begin
  1351.       acmGetFormatDescription(PWaveFormat,FormatName,Format);
  1352.       Size := '; ' + IntToStr(FileSize div 1024) + ' KB';
  1353.       SetDlgItemText(Wnd,LT_FORMAT,StrPCopy(aBuf, FormatName+'; '+Format+Size));
  1354.       {$IFDEF WIN32}
  1355.       Windows.GetClientRect(FScopeWnd, aRect);
  1356.       {$ELSE}
  1357.       WinProcs.GetClientRect(FScopeWnd, aRect);
  1358.       {$ENDIF}
  1359.       if (FormatTag = 1) and (DataSize > 0) then
  1360.       begin
  1361.          EnableWindow(GetDlgItem(Wnd,CB_PREVIEW), True);
  1362.          if FPreview then
  1363.          begin
  1364.             DC := GetDC(FScopeWnd);
  1365.             try
  1366.                CreatePCMData(DC,aRect);
  1367.             finally
  1368.                ReleaseDC(FScopeWnd, DC);
  1369.             end;
  1370.             goto CheckDevice;
  1371.          end;
  1372.       end;
  1373.       InvalidateRect(FScopeWnd, @aRect, False);
  1374. CheckDevice:
  1375.       if (FWaveOut.NumDevs > 0) and not FWaveFile.Wave.Empty and
  1376.           FWaveOut.QueryDevice(FWaveOut.DeviceID,FWaveOut.PWaveFormat) and
  1377.           not (wosPlay in FWaveOut.State) then
  1378.       begin
  1379.          UpdatePlayParams;
  1380.          EnableWindow(GetDlgItem(Wnd,BT_Play), True);
  1381.          if FAutoPlay then
  1382.          try
  1383.             FWaveOut.Start;
  1384.          except
  1385.             { don't raise a exception here }
  1386.          end;
  1387.       end
  1388.       else EnableWindow(GetDlgItem(Wnd,BT_Play), False);
  1389.    end;
  1390. end;
  1391. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1392. procedure TMMWaveOpenDialog.ScopeWndHookProc(var Message: TMessage);
  1393. var
  1394.    DC: HDC;
  1395.    Paint: TPaintStruct;
  1396.    aRect: TRect;
  1397. begin
  1398.    with Message do
  1399.    begin
  1400.       if (Msg = WM_Paint) then
  1401.       begin
  1402.          DC := BeginPaint(FScopeWnd,Paint);
  1403.          {$IFDEF WIN32}
  1404.          Windows.GetClientRect(FScopeWnd,aRect);
  1405.          {$ELSE}
  1406.          WinProcs.GetClientRect(FScopeWnd,aRect);
  1407.          {$ENDIF}
  1408.          DrawPCMData(DC,aRect);
  1409.          EndPaint(FScopeWnd, Paint);
  1410.       end
  1411.       else if (Msg = WM_TIMER) then
  1412.       begin
  1413.          KillTimer(FScopeWnd,wParam);
  1414.          FUpdating := False;
  1415.          UpdateWave;
  1416.       end
  1417.       else Result := CallWindowProc(FScopeDefProc,FScopeWnd,Msg,wParam,lParam);
  1418.    end;
  1419. end;
  1420. {-- TMMWaveOpenDialog ---------------------------------------------------------}
  1421. procedure TMMWaveOpenDialog.DIBWndHookProc(var Message: TMessage);
  1422. var
  1423.    DC: HDC;
  1424.    Paint: TPaintStruct;
  1425.    aRect: TRect;
  1426. begin
  1427.    with Message do
  1428.    begin
  1429.       if (Msg = WM_Paint) then
  1430.       begin
  1431.          DC := BeginPaint(FDIBWnd,Paint);
  1432.          {$IFDEF WIN32}
  1433.          Windows.GetClientRect(FDIBWnd,aRect);
  1434.          {$ELSE}
  1435.          WinProcs.GetClientRect(FDIBWnd,aRect);
  1436.          {$ENDIF}
  1437.          DrawDISP(DC,aRect);
  1438.          EndPaint(FDIBWnd, Paint);
  1439.       end
  1440.       else Result := CallWindowProc(FDIBDefProc,FDIBWnd,Msg,wParam,lParam);
  1441.    end;
  1442. end;
  1443. {== TMMWaveSaveDialog =========================================================}
  1444. constructor TMMWaveSaveDialog.Create(aOwner: TComponent);
  1445. begin
  1446.    inherited Create(aOwner);
  1447.    Title := LoadResStr(IDS_WAVESAVE);
  1448. end;
  1449. {-- TMMWaveSaveDialog ---------------------------------------------------------}
  1450. function TMMWaveSaveDialog.Execute: Boolean;
  1451. begin
  1452.    Result := DoExecute(@GetSaveFileName);
  1453. end;
  1454. {== TMMPictureOpenDialog ======================================================}
  1455. constructor TMMPictureOpenDialog.Create(AOwner: TComponent);
  1456. begin
  1457.    inherited Create(AOwner);
  1458.    Options := Options + [ofHideReadOnly];
  1459.    {$IFDEF WIN32}
  1460.    Options := Options + [ofNoNetworkButton];
  1461.    {$ENDIF}
  1462.    FBitmap := TBitmap.Create;
  1463.    FPicture := TPicture.Create;
  1464.    FPreview := False;
  1465.    FColor := clWindow;
  1466.    FLastFile := '';
  1467.    Title := LoadResStr(IDS_PICTUREOPEN);
  1468.    DefaultExt := GraphicExtension(TGraphic);
  1469.    Filter := GraphicFilter(TGraphic);
  1470.    FilterIndex := 1;
  1471.    FHookWnd := 0;
  1472.    {$IFNDEF WIN32}
  1473.    if _WINNT_ then
  1474.       TemplateName := 'CustomPictureOpenDlgNT'
  1475.    else
  1476.    {$ENDIF}
  1477.       TemplateName := 'CustomPictureOpenDlg';
  1478. end;
  1479. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1480. destructor TMMPictureOpenDialog.Destroy;
  1481. begin
  1482.    FBitmap.Free;
  1483.    FPicture.Free;
  1484.    inherited Destroy;
  1485. end;
  1486. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1487. procedure TMMPictureOpenDialog.DoCreate;
  1488. var
  1489.    aBuf: array[0..20] of Char;
  1490. begin
  1491.    if (FHookWnd = 0) then
  1492.    begin
  1493.       FHookWnd := GetDlgItem(Wnd,ST_PICTURE);
  1494.       FDefProc := Pointer(GetWindowLong(FHookWnd,GWL_WNDPROC));
  1495.       FOldProc := SetWindowLong(FHookWnd,GWL_WNDPROC,
  1496.                   Longint(MakeObjectInstance(WndHookProc)));
  1497.    end;
  1498.    SetDlgItemText(Wnd,CB_PREVIEW,StrPCopy(aBuf,LoadResStr(IDS_PREVIEW)));
  1499.    SendDlgItemMessage(Wnd,CB_PREVIEW, BM_SETCHECK, Ord(FPReview), 0);
  1500.    {$IFDEF WIN32}
  1501.    if not NewStyleControls then
  1502.    {$ENDIF}
  1503.    begin
  1504.       { TODO: hier Texte im Dialog lokalisieren !!!
  1505.        oder gleich englische Resource verwenden }
  1506.    end;
  1507.    inherited DoCreate;
  1508. end;
  1509. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1510. procedure TMMPictureOpenDialog.DoDestroy;
  1511. begin
  1512.    if (FHookWnd <> 0) then
  1513.    begin
  1514.       FreeObjectInstance(Pointer(SetWindowLong(FHookWnd,GWL_WNDPROC,FOldProc)));
  1515.       FHookWnd := 0;
  1516.    end;
  1517.    inherited DoDestroy;
  1518. end;
  1519. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1520. procedure TMMPictureOpenDialog.DoFileOK(FName: String; var IsOk: Boolean);
  1521. begin
  1522.    { TODO: hier Format pr黤en ? }
  1523.    inherited DoFileOK(FName, IsOK);
  1524. end;
  1525. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1526. procedure TMMPictureOpenDialog.DoSelChanged(FName: String);
  1527. var
  1528.    LastName: string;
  1529. begin
  1530.    if assigned(FPicture) then
  1531.    begin
  1532.       if (FName <> '') then
  1533.       begin
  1534.          LastName := FindLastFileName(FName);
  1535.          if (LastName <> FLastFile) and FileExists(LastName) then
  1536.          begin
  1537.             try
  1538.                FPicture.LoadFromFile(LastName);
  1539.                FLastFile := LastName;
  1540.             except
  1541.                FPicture.Bitmap.Handle := 0;
  1542.                FPicture.Icon.Handle := 0;
  1543.                FPicture.Metafile.Handle := 0;
  1544.                FLastFile := '';
  1545.             end;
  1546.             UpdatePicture;
  1547.          end;
  1548.       end
  1549.       else if (FLastFile <> '') then
  1550.       begin
  1551.          FPicture.Bitmap.Handle := 0;
  1552.          FPicture.Icon.Handle := 0;
  1553.          FPicture.Metafile.Handle := 0;
  1554.          FLastFile := '';
  1555.          UpdatePicture;
  1556.       end;
  1557.    end;
  1558.    inherited DoSelChanged(FName);
  1559. end;
  1560. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1561. procedure TMMPictureOpenDialog.DoCommand(Wnd,Parent: Hwnd; cmd: Integer);
  1562. begin
  1563.    if (Wnd = FHWnd) then
  1564.    begin
  1565.       if (cmd = CB_PREVIEW) then
  1566.       begin
  1567.          FPreview := SendDlgItemMessage(Wnd, CB_PREVIEW, BM_GetCheck, 0, 0)<> 0;
  1568.          UpdatePicture;
  1569.       end;
  1570.    end;
  1571.    inherited DoCommand(Wnd,Parent,cmd);
  1572. end;
  1573. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1574. procedure TMMPictureOpenDialog.DrawPicture(DC: HDC; aRect: TRect);
  1575. const
  1576.    Space = 5;
  1577. var
  1578.    aCanvas: TCanvas;
  1579.    oldPal: HPalette;
  1580.    Factor: Float;
  1581.    iWidth,iHeight: integer;
  1582. begin
  1583.    with FPicture, aRect do
  1584.    begin
  1585.       aCanvas := TCanvas.Create;
  1586.       with aCanvas do
  1587.       try
  1588.          Handle := DC;
  1589.          { clear background }
  1590.          Brush.Color := clWindow;
  1591.          FillRect(aRect);
  1592.          Frame3D(aCanvas,aRect,clBtnShadow,clBtnHighLight,1);
  1593.          Frame3D(aCanvas,aRect,clWindowFrame,cl3DLight,1);
  1594.          if (Graphic <> nil) and not Graphic.Empty and FPreview then
  1595.          begin
  1596.             iWidth := FPicture.Width;
  1597.             iHeight := FPicture.Height;
  1598.             if (Graphic is TIcon) or (Graphic is TMetaFile) then
  1599.             begin
  1600.                if (iWidth < (Right-Left)-2*Space) and
  1601.                   (iHeight < (Bottom-Top)-2*Space) then
  1602.                begin
  1603.                   aRect := Bounds(((Right-Left) - iWidth) div 2,
  1604.                                   ((Bottom-Top) - iHeight) div 2,
  1605.                                     iWidth, iHeight);
  1606.                end;
  1607.                aCanvas.StretchDraw(aRect,Graphic);
  1608.             end
  1609.             else if (Graphic is TBitmap) then
  1610.             begin
  1611.                OldPal := SelectPalette(Handle,Bitmap.Palette,False);
  1612.                RealizePalette(Handle);
  1613.                if (iWidth < (Right-Left)-2*Space) and
  1614.                   (iHeight < (Bottom-Top)-2*Space) then
  1615.                begin
  1616.                   aRect := Bounds(((Right-Left) - iWidth) div 2,
  1617.                                   ((Bottom-Top) - iHeight) div 2,
  1618.                                     iWidth, iHeight);
  1619.                end
  1620.                else if (iWidth > iHeight) then
  1621.                begin
  1622.                   Factor := ((Right-Left)-2*Space)/iWidth;
  1623.                   iHeight := Trunc(iHeight * Factor);
  1624.                   aRect.Top := Top+((Bottom-Top)-iHeight) div 2;
  1625.                   aRect.Bottom := Top + iHeight;
  1626.                   aRect.Left := Left+Space;
  1627.                   aRect.Right := Right-Space;
  1628.                end
  1629.                else
  1630.                begin
  1631.                   Factor := ((Bottom-Top)-2*Space)/iHeight;
  1632.                   iWidth := Trunc(iWidth * Factor);
  1633.                   aRect.Left := Left+((Right-Left)-iWidth) div 2;
  1634.                   aRect.Right := Left + iWidth;
  1635.                   aRect.Top := aRect.Top + Space;
  1636.                   aRect.Bottom := Bottom - Space;
  1637.                end;
  1638.                aCanvas.StretchDraw(aRect,Graphic);
  1639.                SelectPalette(Handle, OldPal, False);
  1640.                RealizePalette(Handle);
  1641.             end;
  1642.          end;
  1643.       finally
  1644.          aCanvas.Handle := 0;
  1645.          aCanvas.Free;
  1646.       end;
  1647.    end;
  1648. end;
  1649. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1650. Procedure TMMPictureOpenDialog.UpdatePicture;
  1651. var
  1652.    aRect: TRect;
  1653. begin
  1654.    {$IFDEF WIN32}
  1655.    Windows.GetClientRect(FHookWnd, aRect);
  1656.    {$ELSE}
  1657.    WinProcs.GetClientRect(FHookWnd, aRect);
  1658.    {$ENDIF}
  1659.    InvalidateRect(FHookWnd, @aRect, False);
  1660. end;
  1661. {-- TMMPictureOpenDialog ------------------------------------------------------}
  1662. procedure TMMPictureOpenDialog.WndHookProc(var Message: TMessage);
  1663. var
  1664.    DC: HDC;
  1665.    Paint: TPaintStruct;
  1666.    aRect: TRect;
  1667. begin
  1668.    with Message do
  1669.    begin
  1670.       if (Msg = WM_Paint) then
  1671.       begin
  1672.          DC := BeginPaint(FHookWnd,Paint);
  1673.          {$IFDEF WIN32}
  1674.          Windows.GetClientRect(FHookWnd,aRect);
  1675.          {$ELSE}
  1676.          WinProcs.GetClientRect(FHookWnd,aRect);
  1677.          {$ENDIF}
  1678.          DrawPicture(DC,aRect);
  1679.          EndPaint(FHookWnd, Paint);
  1680.       end
  1681.       else Result := CallWindowProc(FDefProc,FHookWnd,Msg,wParam,lParam);
  1682.    end;
  1683. end;
  1684. {== TMMPictureSaveDialog ======================================================}
  1685. constructor TMMPictureSaveDialog.Create(aOwner: TComponent);
  1686. begin
  1687.    inherited Create(aOwner);
  1688.    Title := LoadResStr(IDS_PICTURESAVE);
  1689. end;
  1690. {-- TMMPictureSaveDialog ------------------------------------------------------}
  1691. function TMMPictureSaveDialog.Execute: Boolean;
  1692. begin
  1693.    Result := DoExecute(@GetSaveFileName);
  1694. end;
  1695. initialization
  1696.    {$IFDEF WIN32}
  1697.    if not NewStyleControls then
  1698.    {$ENDIF}
  1699.    InitDialogs;
  1700. end.