Changing a form from color to grayscale and back to color

How do you change the color of a form to grayscale and back to color. I am trying to use this on the main form when the user makes the smaller form active giving the visual look of the main form inactive.  I've seen this done in applications including windows XP.
alspiveyAsked:
Who is Participating?
 
Slick812Commented:
Hello alspivey, Here is some code I have used to color an Entire Form to show a "Not Enabled" state. It may not be what you want, but it will show that the form is "Different" than normal. There are 2 Forms, Form1 (main) and Form2.


procedure TForm1.FormPaint(Sender: TObject);
var
FmDc: HDC;
begin
if Not Enabled then
  begin
  FmDc := GetWindowDC(Form1.Handle);
  SelectObject(FmDc, GetStockObject(GRAY_BRUSH));
  PatBlt(FmDc, 0, 0, Width,Height,$A000C9);
  ReleaseDC(Form1.Handle, FmDc);
  end;

end;


procedure TForm1.Button1Click(Sender: TObject);
{this button shows the Form2 and disables Form1}
var
  FmDc: HDC;
begin
Form2.Show;
Application.ProcessMessages;
Form1.Enabled := False;
FmDc := GetWindowDC(Form1.Handle);
SelectObject(FmDc, GetStockObject(GRAY_BRUSH));
PatBlt(FmDc, 0, 0, Width,Height,$A000C9);
ReleaseDC(Form1.Handle, FmDc);
end;

This is the close Button on Form 2

procedure TForm2.SpeedButton1Click(Sender: TObject);
begin
Form1.Enabled := True;
Close;
Form1.Invalidate;
end;

you may need to also Repaint any Non-Graphical control.
0
 
tongaliteCommented:
Hi
well I guess you could change the mainform color to
silver(gray) when form2 becomes the active form and
reverse the process when the mainform receives the
focus. Double click the color listbox in Object Inspector
to bring up the colordialogbox... choose your custom color
and its value will be shown in the listbox. Use the value to hardcode the color of your mainform and the color you want it to be when inactive.... Have I over-simplified the situation... sorry if I misunderstood what you want :)

example:

Form1.Color:=TColor($00C9C9C9); //almost silver
Form1.Color:=TColor($00FFC082); //light shade of blue

tongalite
0
 
jswebyCommented:
Put these declarations in your main form's Private section:

    MDIDefProc: Pointer;
    MDIInstance: TFarProc;

    procedure MDIWndProc(var prmMsg: TMessage);
    procedure ShowGradient(prmDC: hDC;prmRed, prmGreen, prmBlue: byte);
    procedure CreateWnd;override;


Implemented like this:

procedure TfrmMain.MDIWndProc(var prmMsg: TMessage);
begin
     // This is where we set the colour for the gradient on the main form
     With prmMsg Do
     Begin
          // Only perform this if the number of colours are above 256.
          If (Msg = WM_ERASEBKGND)
          And (GetDeviceCaps(Canvas.Handle, BITSPIXEL) *
               GetDeviceCaps(Canvas.Handle, PLANES) >= 15) then
          Begin
               ShowGradient(wParam,127,127,127);
               Result := 1;
          End
          Else
          Result := CallWindowProc(MDIDefProc,ClientHandle,Msg,wParam,lParam);
     end;
end;

procedure TfrmMain.CreateWnd;
begin
     // This is part of the gradient processing
     inherited CreateWnd;
     MDIInstance := MakeObjectInstance(MDIWndProc); { create wrapper }
     MDIDefProc := pointer(SetWindowLong(ClientHandle,GWL_WNDPROC,
     longint(MDIInstance)));
end;

procedure TfrmMain.ShowGradient(prmDC:hDC;prmRed,prmGreen,prmBlue:byte);
var
   wrkBrushNew,wrkBrushOld: hBrush;
   wrkColor:TColor;
   wrkSize,wrkY,wrkDelta: integer;
   wrkRect:TRect;
begin
     // Gradient Routine.
     wrkDelta := 255 div (1 + ClientHeight); { number of shades desired }
     If wrkDelta = 0 Then wrkDelta := 1;     { yes, usually 1 }
     wrkSize := ClientHeight div 100;      { size of blended bars }
     If wrkSize = 0 Then wrkSize := 1;
     For wrkY := 0 To 1 + (ClientHeight div wrkSize) Do
     Begin
          wrkColor := RGB(prmRed,prmGreen,prmBlue);
          wrkRect := Rect(0, wrkY*wrkSize, ClientWidth,(wrkY + 1)*wrkSize);
          If FormStyle = fsNormal Then
          Begin
               Canvas.Brush.Color := wrkColor;
               Canvas.FillRect(wrkRect);
          End
          Else If FormStyle = fsMDIForm then
          Begin
               wrkBrushNew := CreateSolidBrush(wrkColor);
               wrkBrushOld := SelectObject(prmDC,wrkBrushNew);
               FillRect(prmDC,wrkRect,wrkBrushNew);
               SelectObject(prmDC,wrkBrushOld);
               DeleteObject(wrkBrushNew);
          End;
          If prmRed >wrkDelta then Dec(prmRed,wrkDelta);
          If prmGreen > wrkDelta then Dec(prmGreen,wrkDelta);
          If prmBlue  > wrkDelta then Dec(prmBlue,wrkDelta);
     end;
end;

J.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
geobulCommented:
Hi,
Why not simply to disable all the the controls on the main form?

in main form:
--------
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure ControlsEnabled(value: boolean);
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.ControlsEnabled(value: boolean);
var
  i: integer;
begin
  with Form1 do
    for i := 0 to ComponentCount - 1 do
      if (Components[i] is TControl) then
        (Components[i] as TControl).Enabled := value;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ControlsEnabled(false);
  Form2.Show;
end;
--------
in form2:
----------
type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

uses unit1;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Form1.ControlsEnabled(true);
end;
----------

Regards, Geo
0
 
alspiveyAuthor Commented:
Sorry guys maybe I was not clear on what i'm trying to do. I am disabling the form and buttons on the main form while the user is on the secondary form. What i'm trying to do is what windows xp does when it turnes a form to black and white, gray scale. This is only a cosmetic look, I know i could turn the form and each button to a gray color. I was just looking for a API or something like that.
0
 
Slick812Commented:
sorry, I was lookin at an early version, the close for form 2 should be


procedure TForm2.SpeedButton1Click(Sender: TObject);
begin
Close;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form1.Enabled := True;
Form1.Invalidate;
Action := caHide
end;
0
 
alspiveyAuthor Commented:
Thanks for the info. This will work for what i'm trying to do, and will not restrict the os like a transparent vcl would do.

0
Question has a verified solution.

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

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.