[win32]récupérer la couleur d'un pixel à l'écran

Soyez le premier à donner votre avis sur cette source.

Vue 12 985 fois - Téléchargée 564 fois

Description

Ce source récupère la couleur du pixel qui se trouve sous la souris.

La couleur est affiché en décimal R, G, B et en hexa.

Le fond de la form prend la même couleur que celle du pixel.

Pour ceux qui voudraient juste utiliser ce programme sans avoir besoin de compiler, il suffit de renommer le fichier du zip .exec en .exe.

Source / Exemple :


#include "windows.h"

HINSTANCE _hThisInstance;              // Handle du module
HWND _hWnd;                            // Handle de la fenêtre
HWND _hTextBox;                        // Handle de la textbox
LPSTR _lpAppName = "GetPixelColor";    // Nom de l'appli

//
// Affiche le message d'erreur associé à la dernière
// erreur Win32.
//
void ShowLastError()
{
  DWORD nLastError;
  LPSTR lpMessageBuffer;

  // Récupération du numéro de l'erreur
  nLastError = GetLastError();

  // Formatage du message
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMessageBuffer, 0, NULL);

  // Affichage du message et fin de l'appli
  MessageBox(NULL, lpMessageBuffer, "ERROR", MB_OK | MB_ICONERROR);

  LocalFree(lpMessageBuffer);
}

//
// Traitement des messages.
//
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
  static HBRUSH hBackBrush;     // Brush de dessin de l'arrière plan de la fenêtre
  static POINT cursor;          // Position de la souris
  static COLORREF nColor;       // Couleur du pixel sous la souris
  static RECT back;             // Rectangle de la zone cliente/fenêtre
  static char lpText[50];       // Affichage de la couleur en hexa et rgb
  static INT32 nHexa;           // La couleur swapée pour afficher un hexa comme on l'attend
  static HDC hScreenDC;         // HDC de l'écran
  
  switch (nMessage)
  {
    case WM_TIMER:
      // On met à jour seulement si on est hors de notre fenêtre
      GetCursorPos(&cursor);
      GetWindowRect(_hWnd, &back);
      
      // Pas besoin de ReleasDC pour ce GetDC : CS_OWNDC dans le style de la classe
      if (! PtInRect(&back, cursor)) SendMessage(_hWnd, WM_ERASEBKGND, (WPARAM)GetDC(_hWnd), 0);
      break;
    case WM_ERASEBKGND:
      // Récupération des coordonnées de la souris
      GetCursorPos(&cursor);
      
      // Récupération de la couleure du pixel sous la souris
      hScreenDC = GetDC(0);
      nColor = GetPixel(hScreenDC, cursor.x, cursor.y);
      nHexa = ReleaseDC(0, hScreenDC);

      // Création du brush de dessin de l'arrière plan de la form
      hBackBrush = CreateSolidBrush(nColor);
      
      // Dessin de la fenêtre
      GetClientRect(_hWnd, &back);
      FillRect((HDC)wParam, &back, hBackBrush);
      DeleteObject(hBackBrush);

      // On remet les octets dans le "bon" sens
      nHexa = ((nColor & 0xFF) << 16) | (nColor & 0xFF00) | ((nColor & 0xFF0000) >> 16);
      
      // Affichage de la couleur en hexa
      // Le dièze, c'est juste qu'en HTML on en met un.
      // %X, ça convertit l'entier en hexa (En majuscule)
      // %6X, ça complète la conversion avec des espaces pour que la chaîne fasse 6 caractères
      // %06X, ça demande des 0 à la place des espaces pour arriver à 6 caractères
      wsprintf(lpText, "#%06X (R = %d, G = %d, B = %d)", nHexa, nColor & 0xFF, (nColor & 0xFF00) >> 8, (nColor & 0xFF0000) >> 16);
      SetWindowText(_hTextBox, lpText);
      RedrawWindow(_hTextBox, NULL, NULL, RDW_INVALIDATE);
      return 1;
    case WM_DESTROY:
      // On signale que le thread va s'arrêter
      PostQuitMessage(0);
      break;
    default:
      // Application du traitement par défaut
      return DefWindowProc(hWnd, nMessage, wParam, lParam);
  }
  return 0;
}

//
// Initialise la fenêtre principale de l'appli.
//
void InitWindow()
{
  WNDCLASSEX wincl;       // Classe de la fenêtre utilisée

  // Création de la classe de fenêtre
  wincl.cbSize = sizeof(WNDCLASSEX);
  wincl.style = CS_OWNDC;
  wincl.lpfnWndProc = WindowProcedure;
  wincl.cbClsExtra = 0;
  wincl.cbWndExtra = 0;
  wincl.hInstance = _hThisInstance;
  wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
  wincl.hbrBackground = NULL;
  wincl.lpszMenuName = 0;
  wincl.lpszClassName = _lpAppName;
  wincl.hIconSm = NULL;

  // Enregistrement de la classe
  if (!RegisterClassEx(&wincl)) ShowLastError();

  // Création de la fenêtre
  _hWnd = CreateWindowEx(0, _lpAppName, _lpAppName, WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 300, 100, HWND_DESKTOP, NULL, _hThisInstance, NULL);
  _hTextBox = CreateWindowEx(0, "EDIT", "color", ES_READONLY | WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 294, 20, _hWnd, NULL, _hThisInstance, NULL);
}

#pragma comment(linker, "/entry:main")
INT32 _cdecl main()
{
  MSG messages;           // Réception des messages envoyés à l'application

  // Récupération du handle du module
  _hThisInstance = GetModuleHandle(NULL);

  InitWindow();
  if (!SetTimer(_hWnd, 1, 100, NULL)) ShowLastError();

  // Boucle de traitement des messages
  while (GetMessage(&messages, NULL, 0, 0))
  {
    // Traduit certains messages
    TranslateMessage(&messages);

    // Distribution des messages aux fenêtres
    DispatchMessage(&messages);
  }
  KillTimer(_hWnd, 1);

  // Code d'erreur en sortie
  return messages.wParam;
}

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

BruNews
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13 -
Il le faut, ça libère au moins une place dans la table des handle.
racpp
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
6 -
ATTENTION:
Le style CS_OWNDC ne doit pas être utilisé avec CreateWindow(). Il doit être plutôt affecté au membre style de la classe WNDCLASS ou WNDCLASSEX. Il s'agit d'un style de classe de fenêtre et non pas un style de fenêtre.

Une variable locale déclarée en static est allouée dans la mémoire globale de l'exécutable, donc accessible à tout moment. Une fonction CALLBACK appelée de manière répétitive doit limiter l'usage de la pile pour gagner un peu en vitesse. Dans ton code, cela ne poserait aucun problème.
racpp
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
6 -
WNDCLASS et WNDCLASSEX sont des structures et non pas des classes comme j'ai dit plus haut sans faire attention.
cs_rt15
Messages postés
3982
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
8 -
Hop, MAJ. Bah encore merci d'avoir vérifier : je vous donne du boulot dites-donc ! Pour la peine, j'ai mis les variables de la callback en static.
Il faut sérieusement 145 lignes pour faire un OS.getpixel(x,y)? Non je ne crois pas.
Commenter la réponse de mogwai93

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.