home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d56 / RMCTL.ZIP / rmMDIBackground.pas < prev    next >
Pascal/Delphi Source File  |  2001-06-22  |  9KB  |  318 lines

  1. {================================================================================
  2. Copyright (C) 1997-2001 Mills Enterprise
  3.  
  4. Unit     : rmMDIBackground
  5. Purpose  : To allow an image to be placed with in the workspace area of an
  6.            MDI Form.  Background colors are also available.
  7. Date     : 04-24-2000
  8. Author   : Ryan J. Mills
  9. Version  : 1.80
  10. ================================================================================}
  11.  
  12. unit rmMDIBackground;
  13.  
  14. interface
  15.  
  16. {$I CompilerDefines.INC}
  17.  
  18. uses
  19.    Windows, Messages, Classes, Forms, graphics;
  20.  
  21. type
  22.    TrmBMPDisplayStyle = (dsTiled, dsStretched, dsCentered, dsNone) ;
  23.  
  24.    TrmMDIBackground = class(TComponent)
  25.    private
  26.       OldWndProc: TFarProc;
  27.       NewWndProc: Pointer;
  28.  
  29.       OldMDIWndProc: TFarProc;
  30.       NewMDIWndProc: Pointer;
  31.  
  32.       fBitmap: TBitmap;
  33.       fstyle: TrmBMPDisplayStyle;
  34.       fColor: TColor;
  35.  
  36.       fBuffer: TBitmap;
  37.       fLastRect: TRect;
  38.  
  39.       procedure SetBitmap(const Value: tBitmap) ;
  40.       procedure SetDStyle(const Value: TrmBMPDisplayStyle) ;
  41.       procedure SetMDIColor(const Value: TColor) ;
  42.  
  43.     { Private declarations }
  44.    protected
  45.     { Protected declarations }
  46.       procedure HookWndProc(var AMsg: TMessage) ;
  47.       procedure HookWnd;
  48.       procedure UnHookWnd;
  49.  
  50.       procedure HookMDIWndProc(var AMsg: TMessage) ;
  51.       procedure HookMDIWin;
  52.       procedure UnhookMDIWin;
  53.  
  54.       procedure PaintImage;
  55.    public
  56.     { Public declarations }
  57.       constructor create(AOwner: TComponent) ; override;
  58.       destructor destroy; override;
  59.    published
  60.     { Published declarations }
  61.       property Bitmap: tBitmap read fBitmap write SetBitmap;
  62.       property DisplayStyle: TrmBMPDisplayStyle read fstyle write SetDStyle default dsNone;
  63.       property Color: TColor read fColor write SetMDIColor default clappWorkspace;
  64.    end;
  65.  
  66. implementation
  67.  
  68. uses rmGlobalComponentHook;
  69.  
  70. { TrmMDIBackground }
  71.  
  72. constructor TrmMDIBackground.create(AOwner: TComponent) ;
  73. begin
  74.    inherited;
  75.  
  76.    NewWndProc := nil;
  77.    OldWndProc := nil;
  78.  
  79.    OldMDIWndProc := nil;
  80.    NewMDIWndProc := nil;
  81.  
  82.    fBitmap := tBitmap.create;
  83.    fbuffer := tbitmap.create;
  84.  
  85.    fColor := clAppWorkSpace;
  86.    fstyle := dsNone;
  87.  
  88.    fLastRect := rect(0, 0, 0, 0) ;
  89.  
  90.    HookWnd;
  91. end;
  92.  
  93. destructor TrmMDIBackground.destroy;
  94. begin
  95.    UnHookWnd;
  96.  
  97.    fBitmap.free;
  98.    fbuffer.free;
  99.  
  100.    inherited;
  101. end;
  102.  
  103. procedure TrmMDIBackground.HookMDIWin;
  104. begin
  105.    if csdesigning in componentstate then exit;
  106.    if not assigned(NewMDIWndProc) then
  107.    begin
  108.       OldMDIWndProc := TFarProc(GetWindowLong(TForm(Owner) .ClientHandle, GWL_WNDPROC) ) ;
  109.       {$ifdef BD6}
  110.       NewMDIWndProc := Classes.MakeObjectInstance(HookMDIWndProc) ;
  111.       {$else}
  112.       NewMDIWndProc := MakeObjectInstance(HookMDIWndProc) ;
  113.       {$endif}
  114.       SetWindowLong(TForm(Owner) .ClientHandle, GWL_WNDPROC, LongInt(NewMDIWndProc) ) ;
  115.    end;
  116. end;
  117.  
  118. procedure TrmMDIBackground.HookMDIWndProc(var AMsg: TMessage) ;
  119. begin
  120.    with AMsg do
  121.    begin
  122.       Result := CallWindowProc(OldMDIWndProc, TForm(Owner) .ClientHandle, Msg, wParam, lParam) ;
  123.       if (msg = WM_NCPaint) or (msg = wm_Paint) then
  124.          PaintImage;
  125.    end;
  126. end;
  127.  
  128. procedure TrmMDIBackground.HookWnd;
  129. begin
  130.    if csdesigning in componentstate then exit;
  131.    if TForm(Owner) .formstyle <> fsMDIForm then exit;
  132.    if not assigned(NewWndProc) then
  133.    begin
  134.       OldWndProc := TFarProc(GetWindowLong(TForm(Owner) .handle, GWL_WNDPROC) ) ;
  135.       {$ifdef BD6}
  136.       NewWndProc := Classes.MakeObjectInstance(HookWndProc) ;
  137.       {$else}
  138.       NewWndProc := MakeObjectInstance(HookWndProc) ;
  139.       {$endif}
  140.       SetWindowLong(TForm(Owner) .handle, GWL_WNDPROC, LongInt(NewWndProc) ) ;
  141.       PushOldProc(TForm(Owner) , OldWndProc) ;
  142.       HookMDIWin;
  143.    end;
  144. end;
  145.  
  146. procedure TrmMDIBackground.HookWndProc(var AMsg: TMessage) ;
  147. begin
  148.    case AMsg.msg of
  149.       WM_DESTROY:
  150.          begin
  151.             AMsg.Result := CallWindowProc(OldWndProc, Tform(Owner) .handle, AMsg.Msg, AMsg.wParam, AMsg.lParam) ;
  152.             UnHookWnd;
  153.             exit;
  154.          end;
  155.       wm_EraseBKGND:
  156.          begin
  157.             aMsg.Result := 1;
  158.             exit;
  159.          end;
  160.    end;
  161.  
  162.    AMsg.Result := CallWindowProc(OldWndProc, Tform(Owner) .handle, AMsg.Msg, AMsg.wParam, AMsg.lParam) ;
  163.  
  164.    case aMsg.Msg of
  165.       WM_PAINT, // WM_ERASEBKGND,
  166.          WM_NCPaint: PaintImage;
  167.    end;
  168. end;
  169.  
  170. procedure TrmMDIBackground.PaintImage;
  171. var
  172.    DC: HDC;
  173.    Brush: HBrush;
  174.    cx, cy: integer;
  175.    wRect: TRect;
  176.    x, y: integer;
  177. begin
  178.    if csdesigning in componentstate then exit;
  179.    if TForm(Owner) .FormStyle <> fsMDIForm then exit;
  180.  
  181.    GetWindowRect(TForm(Owner) .ClientHandle, wRect) ;
  182.  
  183.    DC := GetDC(TForm(Owner) .clienthandle) ;
  184.    try
  185.       case fstyle of
  186.          dsTiled, dsStretched, dsCentered:
  187.             begin
  188.                case fStyle of
  189.                   dsTiled:
  190.                      begin
  191.                         cx := (wRect.right - wRect.left) ;
  192.                         cy := (wRect.bottom - wRect.top) ;
  193.  
  194.                         y := 0;
  195.                         while y < cy do
  196.                         begin
  197.                            x := 0;
  198.                            while x < cx do
  199.                            begin
  200.                               bitBlt(DC, x, y, fBitmap.width, fBitmap.height,
  201.                                  fBitmap.canvas.Handle, 0, 0, srccopy) ;
  202.  
  203.                               inc(x, fBitmap.width) ;
  204.                            end;
  205.                            inc(y, fBitmap.Height) ;
  206.                         end;
  207.                      end;
  208.  
  209.                   dsStretched:
  210.                      begin
  211.                         cx := (wRect.right - wRect.left) ;
  212.                         cy := (wRect.bottom - wRect.top) ;
  213.  
  214.                         StretchBlt(DC, 0, 0, cx, cy, fBitmap.Canvas.Handle, 0, 0, fBitmap.width, fBitmap.height, srccopy) ;
  215.                      end;
  216.  
  217.                   dsCentered:
  218.                      begin
  219.                         fBuffer.width := wRect.right - wRect.left;
  220.                         fBuffer.height := wRect.bottom - wRect.top;
  221.  
  222.                         Brush := CreateSolidBrush(ColorToRGB(fcolor) ) ;
  223.                         try
  224.                            FillRect(fBuffer.canvas.handle, rect(0, 0, fBuffer.width, fBuffer.height) , brush) ;
  225.                         finally
  226.                            DeleteObject(Brush) ;
  227.                         end;
  228.  
  229.                         cx := (fBuffer.width div 2) - (fBitmap.width div 2) ;
  230.                         cy := (fBuffer.height div 2) - (fbitmap.height div 2) ;
  231.  
  232.                         bitBlt(fBuffer.Canvas.handle, cx, cy, fBitmap.width, fBitmap.height,
  233.                            fBitmap.Canvas.Handle, 0, 0, srccopy) ;
  234.  
  235.                         bitBlt(DC, 0, 0, fBuffer.width, fBuffer.height,
  236.                            fBuffer.Canvas.Handle, 0, 0, srccopy) ;
  237.                      end;
  238.                end;
  239.             end;
  240.          dsNone:
  241.             begin
  242.                Brush := CreateSolidBrush(ColorToRGB(fcolor) ) ;
  243.                try
  244.                   FillRect(DC, TForm(Owner) .ClientRect, brush) ;
  245.                finally
  246.                   DeleteObject(Brush) ;
  247.                end;
  248.             end;
  249.       end;
  250.  
  251.       fLastRect := wRect;
  252.  
  253.    finally
  254.       ReleaseDC(TForm(Owner) .clienthandle, DC) ;
  255.    end;
  256. end;
  257.  
  258. procedure TrmMDIBackground.SetBitmap(const Value: tBitmap) ;
  259. begin
  260.    fBitmap.assign(Value) ;
  261. end;
  262.  
  263. procedure TrmMDIBackground.SetDStyle(const Value: TrmBMPDisplayStyle) ;
  264. begin
  265.    if fstyle <> Value then
  266.    begin
  267.       fstyle := Value;
  268.       PaintImage;
  269.    end;
  270. end;
  271.  
  272. procedure TrmMDIBackground.SetMDIColor(const Value: TColor) ;
  273. begin
  274.    if fColor <> Value then
  275.    begin
  276.       fColor := Value;
  277.       PaintImage;
  278.    end;
  279. end;
  280.  
  281. procedure TrmMDIBackground.UnhookMDIWin;
  282. begin
  283.    if csdesigning in componentstate then exit;
  284.    if assigned(NewMDIWndProc) then
  285.    begin
  286.       SetWindowLong(TForm(Owner) .ClientHandle, GWL_WNDPROC, LongInt(OldMDIWndProc) ) ;
  287.       if assigned(NewMDIWndProc) then
  288.       {$ifdef BD6}
  289.          Classes.FreeObjectInstance(NewMDIWndProc) ;
  290.       {$else}
  291.          FreeObjectInstance(NewMDIWndProc) ;
  292.       {$endif}
  293.       NewMDIWndProc := nil;
  294.       OldMDIWndProc := nil;
  295.    end;
  296. end;
  297.  
  298. procedure TrmMDIBackground.UnHookWnd;
  299. begin
  300.    if csdesigning in componentstate then exit;
  301.    if assigned(NewWndProc) then
  302.    begin
  303.       SetWindowLong(TForm(Owner) .handle, GWL_WNDPROC, LongInt(PopOldProc(TForm(Owner) ) ) ) ;
  304.       if assigned(NewWndProc) then
  305.       {$ifdef BD6}
  306.          Classes.FreeObjectInstance(NewWndProc) ;
  307.       {$else}
  308.          FreeObjectInstance(NewWndProc) ;
  309.       {$endif}
  310.       NewWndProc := nil;
  311.       OldWndProc := nil;
  312.    end;
  313.    UnHookMDIWin;
  314. end;
  315.  
  316. end.
  317.  
  318.