It is currently March 28th, 2024, 11:46 am

CursorColor

Skins that control functions in Windows or Rainmeter
Post Reply
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

CursorColor

Post by jsmorley »

Demonstrates a new ColorCursor 3rd-party plugin.

Retrieves the color of the pixel under the cursor when you fire the measure with !CommandMeasure. I would expect this to generally be on a mouse click action.

Must be called with:
[!CommandMeasure MeasureName "GetColor"]

Only option is "Format", which can be RGB/Red/Green/Blue.

The plugin is included in the .rmskin, as are the plugin 32bit and 64bit .dll files, for use in your .rmskin..
CursorColor_1.0.rmskin
(285.47 KiB) Downloaded 496 times
Or just the plugin 32bit and 64bit .dll files, for use in your .rmskin.
CursorColorPlugin.zip
(127.87 KiB) Downloaded 263 times

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Metadata]
Name=ColorCursor
Author=JSMorley
Information=Demonstrates the ColorCursor plugin.|Retrieves the color of the pixel under the cursor.||Must be called with:|[!CommandMeasure MeasureName "GetColor"]||Only option is "Format", which can be RGB/Red/Green/Blue.
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Version=May 28, 2016

[CursorColor]
Measure=Plugin
Plugin=CursorColor
Format=RGB
Substitute="":"0,0,0"

[CursorRed]
Measure=Plugin
Plugin=CursorColor
Format=Red
Substitute="":"0"

[CursorGreen]
Measure=Plugin
Plugin=CursorColor
Format=Green
Substitute="":"0"

[CursorBlue]
Measure=Plugin
Plugin=CursorColor
Format=Blue
Substitute="":"0"

[MeterBack]
Meter=Image
W=390
H=290
SolidColor=170,170,170,255

[MeterPallet]
Meter=Image
W=370
H=200
X=10
Y=10
ImageName=#@#Images\Pallet.png
LeftMouseUpAction=[!CommandMeasure CursorColor "GetColor"][!CommandMeasure CursorRed "GetColor"][!CommandMeasure CursorGreen "GetColor"][!CommandMeasure CursorBlue "GetColor"][!UpdateMeter *][!Redraw][!SetClip "[CursorColor]"]

[MeterRedGreenBlue]
Meter=String
X=10
Y=5R
FontSize=20
AntiAlias=1
Text=Red: [CursorRed] Green: [CursorGreen] Blue: [CursorBlue]
InlineSetting=Color | [CursorRed],0,0
InlinePattern=Red: (.*) Green: .* Blue: .*
InlineSetting2=Color | 0,[CursorGreen],0
InlinePattern2=Red: .* Green: (.*) Blue: .*
InlineSetting3=Color | 0,0,[CursorBlue]
InlinePattern3=Red: .* Green: .* Blue: (.*)
InlinePattern=.*
DynamicVariables=1

[MeterSelectedColor]
Meter=String
X=10
Y=5R
FontSize=20
FontColor=[CursorColor]
AntiAlias=1
Text=Selected Color: [CursorColor]
DynamicVariables=1
CursorColor.jpg

Code: Select all

#include <string>
#include <stdio.h>
#include <Windows.h>
#include "../../API/RainmeterAPI.h"

enum Instance
{
	RGB,
	RED,
	GREEN,
	BLUE
};

struct Measure
{
	std::wstring returnedString;
	Instance type;
	void* rm;
	Measure() : type(RGB), rm() {}
};

PLUGIN_EXPORT void Initialize(void** data, void* rm)
{
	Measure* measure = new Measure;
	*data = measure;
	measure->rm = rm;
}

PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
	Measure* measure = (Measure*)data;

	LPCWSTR colorFormat = RmReadString(rm, L"FORMAT", L"RGB");
	if (_wcsicmp(colorFormat, L"RGB") == 0)
	{
		measure->type = RGB;
	}
	if (_wcsicmp(colorFormat, L"RED") == 0)
	{
		measure->type = RED;
	}
	if (_wcsicmp(colorFormat, L"GREEN") == 0)
	{
		measure->type = GREEN;
	}
	if (_wcsicmp(colorFormat, L"BLUE") == 0)
	{
		measure->type = BLUE;
	}

}

//PLUGIN_EXPORT double Update(void* data)
//{
//        Measure* measure = (Measure*)data;
//        return 0.0;
//}

PLUGIN_EXPORT LPCWSTR GetString(void* data)
{
	Measure* measure = (Measure*)data;
	return measure->returnedString.c_str();
}

PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args)
{
	Measure* measure = (Measure*)data;

	if (_wcsicmp(args, L"GetColor") == 0) {
		WCHAR buffer[32];

		// Get the device context for the screen
		HDC hDC = GetDC(NULL);
		if (hDC == NULL) {
			RmLogF(measure->rm, LOG_WARNING, L"CursorColor: Error getting screen device handle");
			return;
		}

		// Get the current cursor position
		POINT p;
		BOOL b = GetCursorPos(&p);
		if (!b) {
			RmLogF(measure->rm, LOG_WARNING, L"CursorColor: Error getting current cursor position");
			return;
		}

		// Retrieve the color at that position
		COLORREF color = GetPixel(hDC, p.x, p.y);
		if (color == CLR_INVALID) {
			RmLogF(measure->rm, LOG_WARNING, L"CursorColor: Error getting pixel color");
			return;
		}

		// Release the device context again
		ReleaseDC(GetDesktopWindow(), hDC);

		switch (measure->type)
		{
		case RGB:
			_snwprintf_s(buffer, _TRUNCATE, L"%i,%i,%i", GetRValue(color), GetGValue(color), GetBValue(color));
			break;
		case RED:
			_snwprintf_s(buffer, _TRUNCATE, L"%i", GetRValue(color));
			break;
		case GREEN:
			_snwprintf_s(buffer, _TRUNCATE, L"%i", GetGValue(color));
			break;
		case BLUE:
			_snwprintf_s(buffer, _TRUNCATE, L"%i", GetBValue(color));
			break;
		}

		measure->returnedString = buffer;
	}
}

PLUGIN_EXPORT void Finalize(void* data)
{
	Measure* measure = (Measure*)data;
	delete measure;
}
User avatar
Active Colors
Moderator
Posts: 1251
Joined: February 16th, 2012, 3:32 am
Location: Berlin, Germany
Contact:

Re: CursorColor

Post by Active Colors »

I was waiting for this plugin two years. Now I have to stop procrastinating and make a color picker based on your plugin merged with another handy tool developed by dgrace and reimagined by you https://forum.rainmeter.net/viewtopic.php?p=117322#p117322
User avatar
raiguard
Posts: 660
Joined: June 25th, 2015, 7:02 pm
Location: The Sky, USA
Contact:

Re: CursorColor

Post by raiguard »

Sorry to gravedig!

Would it be possible to amend this plugin so that rather than just getting the color and creating a preview of the desktop at the cursor position, you could instead get the color / create a magnified preview around certain pixel coordinates in an image? So it would have all of the same capabilities, but for an image. Additionally, it would be nice if you could change the filepath of the resulting preview image when using ZoomCreate:

Code: Select all

[MeasureCursorColor]
Measure=Plugin
Plugin=CursorColor
Format=RGB
; Image you want to scan
ImageName=C:\Windows\Temp\colorpickerplus-capture.bmp
; X position to get the color for
CursorX=420
; Y position to get the color for
CursorY=69
RealTime=1
ZoomCreate=1
ZoomToWidth=100
ZoomToHeight=100
ZoomFactor=5
ZoomFileName=C:\Windows\Temp\colorpickerplus-zoompreview.bmp
DynamicVariables=1
The reason I ask for this is because for my color picker skin's eyedropper, I set it up so that the magnified preview rides along next to the cursor:
2019-04-11 15_14_42.png
As you can see, since it's just capturing the desktop, that includes the preview window itself. While the preview window is supposed to sit outside the range of CursorColor's preview, moving the mouse too quickly will cause Rainmeter to fall behind, which leads to recursive previews flashing on your screen.

Thanks for your time!

EDIT: I've attached an rmskin of the color picker so you can see why I want these features.

EDIT 2: Oopsie, it appears I forgot to include the HotKey plugin in the rmskin. Oh well!
Attachments
ColorPickerPlus_dev.2.rmskin
(802.03 KiB) Downloaded 105 times
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: CursorColor

Post by jsmorley »

I don't fully understand your solution, but in any case, I just don't see a big issue with the fact that if you move your mouse really fast, for an instant or two you can get a recursive zoom window. Almost before it can react to that, the preview is moved away with your example skin.

I also don't see any real need to change or set where the preview bitmap is saved. That is just used internally by the plugin, and isn't something the skin should care about.
User avatar
raiguard
Posts: 660
Joined: June 25th, 2015, 7:02 pm
Location: The Sky, USA
Contact:

Re: CursorColor

Post by raiguard »

That's alright, it was mostly just an OCD thing. And the only real reason why I would want to move the file is to keep my repository working tree clean. Thanks anyway!
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: CursorColor

Post by jsmorley »

Personally, I saw no functional benefit at all to having the zoom/preview follow the cursor. I just found it distracting and in the way. I far prefer that it be in a static position in the skin. That is why I did mine the way I did. Now, I grant you that you can get infinite recursion if you hold the eyedropper over that zoom/preview window in my skin, but.. don't... It doesn't hurt anything, as it will only recurse so far and stop, but it's not a useful place to select from.
User avatar
raiguard
Posts: 660
Joined: June 25th, 2015, 7:02 pm
Location: The Sky, USA
Contact:

Re: CursorColor

Post by raiguard »

I'm the opposite. I use Greenshot a lot (like, a LOT) and its preview rides along with the cursor. I much prefer to be able to see the magnification right where I am already looking, rather than having to glance back and forth between the preview and the eyedropper.

To each their own, I guess.
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: CursorColor

Post by jsmorley »

raiguard wrote: April 11th, 2019, 9:56 pm I'm the opposite. I use Greenshot a lot (like, a LOT) and its preview rides along with the cursor. I much prefer to be able to see the magnification right where I am already looking, rather than having to glance back and forth between the preview and the eyedropper.

To each their own, I guess.
Yup...
Post Reply