Link to home
Start Free TrialLog in
Avatar of tongalite
tongalite

asked on

Eyedropper color selector

Hi all,

Can anybody explain the logistics of
implementing an eyedropper color selector
like the function in M$ Frontpage?

At the moment I have a ColorDialog to set
the color of  a control and the desired
color is selected manually... How, for
instance, can I detect the color beneath
the cursor at any point on the screen
(or background color of user desktop scheme
and click to set that color for the control
I want to change the color of.

Info please for me to work on :)

(If you think I;ve been a bit stingy on the
points award, I'm rounding off my points total,
The real points will come for code examples ;))

TIA.
tonga
Avatar of kretzschmar
kretzschmar
Flag of Germany image

already coded,
but source not on hand yet,
i can post it in about ~7 hours,
if not solved until

meikl ;-)

Avatar of tongalite
tongalite

ASKER

Meikl,
Was für eine überaschung! Sehr schnell Anwort!

Thank a lot... I'll look forward to that
and award you more points.

Cheers!
t.
well,
but even not with a solution.

its quiet simple,
i used a timer,
where in the timer event,
the color of the desktop-pixel
under the mouse is retrieved,
and then displayed
as delphi colorstring
in an editbox, so that it
could be simple copied
into a colorproperty or
into the sourcecode

additional i had there
appended the colorpicker
from mike-lischke,
where it is easy to
select another
nuance of the retrieved color

if you want, i can send you this little app,
which i've coded, to get some seen colors,
without to try and error with a colordialog
(my customer wanted special colors (corporate identity))

its a small simple app,
just leave your email here,
and i send it to you this evening

meikl ;-)
OK Meikl...

Thanks a lot...

tongalite@supalife.com

t.
ooops,

don't find what i have provided,
was two years ago

the only thing i found was this prototype

unit color_pipette_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Edit1: TEdit;
    Panel1: TPanel;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Timer1Timer(Sender: TObject);
var
  HDC : THandle;
  P : TPoint;
  C : TColor;
begin
  GetCursorPos(P);
  HDC := GetDC(0);
  C := GetPixel(HDC,P.x,P.y);
  ReleaseDC(HDC,0);
  edit1.Text := ColorToString(C);
  Panel1.Color := c;
end;

end.

i can send you the exe for this,
but its so simple, so i guess
you can implement it byself

hope this help

meikl ;-)
Meikl,
That does a good job of selecting a color.
I modified it a little.
3 further questions.

How to....
(a)halt select color process onmousedown
to pass panel the selected color? i.e. click
to stop select/panel is then colored?

(b) Is it possible to have a cursor
active outside of form region which will
only select colors and not activate desktop
icons etc?

(c)To use a pipette/eyedropper cursor.. does this require a custom cursor loaded from resource?

Thanks
t.
Jumping in with my 2 cents worth... (actually 1 cent.. some of the code is meikl's)

How to....
(a)halt select color process onmousedown
to pass panel the selected color? i.e. click
to stop select/panel is then colored?

Check this out:
=================


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    procedure ColorthePanel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ColorthePanel;
var
 HDC : THandle;
 P : TPoint;
 C : TColor;
begin
 GetCursorPos(P);
 HDC := GetDC(0);
 C := GetPixel(HDC,P.x,P.y);
 ReleaseDC(HDC,0);
 Panel1.Color := c;
end;



procedure TForm1.Button1Click(Sender: TObject);
var msg:Tagmsg;
begin
  SetCapture(self.handle);
   While true do
    if  PeekMessage(msg,0,WM_LBUTTONDOWN,WM_LBUTTONDOWN,PM_NOREMOVE) then
    begin
      ColorthePanel; ///look familiar? <G>
      TranslateMessage(msg);
      DispatchMessage(msg);
      ReleaseCapture;
      Break;
   end;
end;

end.
================================================
(b) Is it possible to have a cursor
active outside of form region which will
only select colors and not activate desktop
icons etc?


 Yes, but it wouldn't be the actual desktop. What you'd want to do it to create an invisible window that occupies the entire screen. Take a look at the CreateWindowEx API for guidance.

 



(c)To use a pipette/eyedropper cursor.. does this require a custom cursor loaded from resource?


Yes. (short and sweet)



Good luck and happy coding!!

listening
nothing to append to drdelphi's comment ;-)
Hi guys...
Thanks for the response.

Dr Delphi,
I tried your suggestion which is pretty much what Meikl gave me. Your other comments to my added questions are appreciated.
/ / / / / / / / / / / / /
Nick,
The demo you sent me used a custom trackbar
comp which I substituted with the delphi tbar
to get it running.Stripping away all but the
function I need, results in virtually the same
as Meikl's solution :)
/ / / / / / / / / / / / /

So, if I can get a bit more mileage out of this question....:-)

Doc,
Regarding your comments to my question (b) above...

Am I right in thinking this is a possibility:
OnBtnClick, take a screenshot of entire screen
and display it.
Move mouse pointer to any area of displayed
screenshot to select desired color.
Mouse L.Click to pass selected color to panel on
form and at same time release screenshot.
Click OK button to stop color selection function
and panel keeps assigned color

Would that work? (I hope you can make sense of that)
/ / / / / / / / / / / / / /

Later.
t.

There's no reason to go through all that. The code I gave you under Form1.Button1Click is already doing what you're looking for.The buttonlick starts the "selection" and will only stop on a LeftClick, at which time it calls the code that Meikl gave you for getting the color that the mouse is over. Is there something here that I'm not getting?


It bears mentioning however that what you suggested is possible.
DrDelphi

Just bear with me...
It's this bit I'm pondering over...

> and will only stop on a LeftClick, at
> which time it calls the code that Meikl
> gave you for getting the color that the
> mouse is over.

OK, supposing the mousepointer is over an
icon on the Taskbar and I want that color...
If I click to pass that color to the panel,
would that not activate the icon and fire up
its associated app! That's why I thought about
the screenshot... to simulate everything on
the desktop. If I'm talking BS here please put
me right... this is very new territory to me.

Here for clarity, is the exact (but simplified)
scenario:

//...........................
I have two forms, Mainform & Form2
Mainform has 2 buttons: Color & Show.

// Code for Color is a simple ColorDialog1 call

procedure TMainform.colorClick(Sender: TObject);
begin
colordialog1.Execute;
Form2.Color:=ColorDialog1.color;
end;
//.............................
procedure TMainform.ShowClick(Sender: TObject);
begin
Hide;
Form2.visible:=True;
end;
//............................

So, instead of using the standard colordialog
I want to implement the eyedropper option to get
the exact color of the desktop. (BTW when form2
is visible, I have a dblClick event set up to
restore Mainform and hide self/form2).

Simple as that...
I now have to work the code you supplied above
into my unit, if it will do what I want, as
you say it will.

Hope that makes things clearer.

Looks like I'll have to award points to you both....
Sorry Nick.... I'll get you next time :-)

t.

If I click to pass that color to the panel,
would that not activate the icon and fire up
its associated app!

-Nope.... The SetCapture call is passing the mouseclicks to your form. It is not released until AFTER the LBUTTON down, so at worst you'd get the effect of a LMouseUp, which to the best of my knowledge does nothing to to a shortcut.

Add this to my original example and you'll see what I mean.


procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  showmessage('MouseDown')
end;



Good luck!!
 
Hi again
dd.....
I just ran your color pickercode again.
I dropped a button and a panel on the form
and set up the button event, pasted your code
into my unit and hit the F9 key. Guess what? I
clicked the button, aimed the cursor at the IE
icon on my taskbar and gave a left mouse click...
The panel went a lovely shade of light blue.... and
IE6 fired up!!! I repeated the same on all the one
click icons on my Taskbar... each click passed the
color to the panel and fired up the associated app
like I was afraid it would..... Do we have something missing here? or am I implementing things wrong?.

BTW, if I double the points... how do I split them between you and M? I don't want to post a zero point 'question'
Thanks
T.
ASKER CERTIFIED SOLUTION
Avatar of DrDelphi
DrDelphi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
BTW,
 
Re:Points... I really don't know how you'd go about it, but I suspect that you could probably ask the moderators to split them up for you.


Happy coding!!

clever ;-)
by clever i meant your last code above,
and not your last comment, drdelphi
(saw it after post)
meikl ;-)
Doc,
That is brilliant! :-)
I managed to get it to compile after a few botched runs and it's working great... Now I need to modify it to suit my purposes. It's like what I had in mind with the screen shot method but you used a transparent form...neat!
Thanks to all for the great help.

I'll try to split the points between you (drdelphi) and meikl.

Meikl... Do you know the point splitting procedure?
I'll top up the points with another 100
t.
Glad to hear it's working for you....


Good luck!!