Winapi - rysowanie koloru RGB

0

Przerabiam program pobierający kolor RGB danego piksela i kolorowaniu tła okna, żeby można było samemu wpisać kod RGB. Mam taki kod:

 
#define ID_TEXT1 501
#define ID_TEXT2 502
#define ID_TEXT3 503

// ColorPicker - pobieracz kolorów
#include <string>
#include <sstream>
#include <cstdlib>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
// dane okna
std::string g_strKlasaOkna = "od0dogk_ColorPicker_Window";
HWND g_hwndOkno = NULL;
// uchwyt do kontekstu ekranu
HDC g_hdcEkran = NULL;
// pobrany kolor
int g_r,g_g,g_b;
LPSTR Bufor1 = (LPSTR)malloc(1111);
LPSTR Bufor2 = (LPSTR)malloc(1111);
LPSTR Bufor3 = (LPSTR)malloc(1111);
bool g_rysuj = 0;

COLORREF g_clKolor = RGB(255, 255, 255); // początkowo biały
// ------------------- procedura zdarzeniowa okna ------------------------
LRESULT CALLBACK WindowEventProc(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
	switch (uMsg)
	{
		case WM_RBUTTONDOWN:
			g_r = atoi(Bufor1);
			g_g = atoi(Bufor2);
			g_b = atoi(Bufor3);
			g_clKolor = RGB(g_r,g_g,g_b);
			GlobalFree( Bufor1 );
			GlobalFree( Bufor2 );
			GlobalFree( Bufor3 );
			g_rysuj = 1;
			//
		break;
		case WM_LBUTTONDOWN:
			// łapiemy myszkę
			SetCapture (hWnd);
			// ustawiamy kursor w kształcie celownika
			SetCursor (LoadCursor(NULL, IDC_CROSS));
			return 0;
		case WM_MOUSEMOVE:
			// sprawdzamy, czy myszka jest złapana
			if (GetCapture() == hWnd)
			{
				// odczytujemy współrzędne kursora
				POINT ptKursor;
				ptKursor.x = GET_X_LPARAM(lParam);
				ptKursor.y = GET_Y_LPARAM(lParam);
				// przeliczamy je na koordynaty ekranowe
				ClientToScreen (hWnd, &ptKursor);
				// pobieramy kolor z miejsca kursora
				g_clKolor = GetPixel(g_hdcEkran,
				ptKursor.x, ptKursor.y);
				// wymuszamy odświeżenie okna programu,
				// aby pokazać pobrany kolor
				InvalidateRect (hWnd, NULL, TRUE);
			}
			return 0;
		case WM_LBUTTONUP:
			// uwalniamy mysz
			ReleaseCapture();
			// ustawiamy kursor strzałki
			SetCursor (LoadCursor(NULL, IDC_ARROW));
			return 0;
		case WM_DESTROY:
			// zwalniamy kontekst ekranu
			ReleaseDC (NULL, g_hdcEkran);
			// kończymy program
			PostQuitMessage (0);
			return 0;
	}

	if(uMsg == WM_PAINT || g_rysuj == 1)
	{
		{
			// odrysowanie zawartości okna
		PAINTSTRUCT ps;
		HDC hdcOkno;
		// zaczynamy
		hdcOkno = BeginPaint(hWnd, &ps);
		// pobieramy obszar klienta okna
		RECT rcObszarKlienta;
		GetClientRect (hWnd, &rcObszarKlienta);
		// wypełniamy go pobranym kolorem
		// w tym celu najpierw tworzymy odpowiedni pędzel,
		// a potem wypełniamy prostokąt obszaru klienta
		// potem usuwamy pędzel
		HBRUSH hbrPedzel = CreateSolidBrush(g_clKolor);
		FillRect (hdcOkno, &rcObszarKlienta, hbrPedzel);
		DeleteObject (hbrPedzel);
		// kończymy rysowanie
		EndPaint (hWnd, &ps);
		if(g_rysuj == 1) g_rysuj = 0;
	}
					// pokazanie składowych koloru
	{
		// pobieramy te składowe i konwertujemy na napis
		std::stringstream Strumien;
		Strumien << "RGB: " << (int) GetRValue(g_clKolor)
		<< ", " << (int) GetGValue(g_clKolor)
		<< ", " << (int) GetBValue(g_clKolor);
		// ustawiamy ten napis jako tytuł okna programu
		SetWindowText (hWnd, Strumien.str().c_str());
	}
	return 0;
}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// ------------------------funkcja WinMain() ----------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
	/* rejestrujemy klasę okna */
	WNDCLASSEX KlasaOkna;
	// wypełniamy strukturę WNDCLASSEX
	ZeroMemory (&KlasaOkna, sizeof(WNDCLASSEX));
	KlasaOkna.cbSize = sizeof(WNDCLASSEX);
	KlasaOkna.hInstance = hInstance;
	KlasaOkna.lpfnWndProc = WindowEventProc;
	KlasaOkna.lpszClassName = g_strKlasaOkna.c_str();
	KlasaOkna.hCursor = LoadCursor(NULL, IDC_ARROW);
	KlasaOkna.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	// rejestrujemy klasę okna
	RegisterClassEx (&KlasaOkna);
	/* tworzymy okno */
	// tworzymy okno funkcją CreateWindowEx
	g_hwndOkno = CreateWindowEx(WS_EX_TOOLWINDOW,
		g_strKlasaOkna.c_str(),
		NULL,
		WS_OVERLAPPED | WS_BORDER
		| WS_CAPTION | WS_SYSMENU,
		0, 0,
		140,
		190,
		NULL,
		NULL,
		hInstance,
		NULL);
	// pokazujemy nasze okno i je od razu odświeżamy
	ShowWindow (g_hwndOkno, nCmdShow);
	UpdateWindow (g_hwndOkno);

	//RED
	HWND hText1 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 1, 105, 130, 20,
	g_hwndOkno, ( HMENU ) ID_TEXT1, hInstance, NULL );
	SetWindowText( hText1, "red" );

	DWORD dlugosc1 = GetWindowTextLength( hText1 );
	LPSTR Bufor1 =( LPSTR ) GlobalAlloc( GPTR, dlugosc1 + 1 );
	GetWindowText( hText1, Bufor1, dlugosc1 + 1 );

	//GREEN
	HWND hText2 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 1, 125, 130, 20,
	g_hwndOkno, ( HMENU ) ID_TEXT2, hInstance, NULL );
	SetWindowText( hText2, "green" );

	DWORD dlugosc2 = GetWindowTextLength( hText2 );
	LPSTR Bufor2 =( LPSTR ) GlobalAlloc( GPTR, dlugosc2 + 1 );
	GetWindowText( hText2, Bufor2, dlugosc2 + 1 );

	//BLUE
	HWND hText3 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 1, 145, 130, 20,
	g_hwndOkno, ( HMENU ) ID_TEXT3, hInstance, NULL );
	SetWindowText( hText3, "blue" );

	DWORD dlugosc3 = GetWindowTextLength( hText3 );
	LPSTR Bufor3 =( LPSTR ) GlobalAlloc( GPTR, dlugosc3 + 1 );
	GetWindowText( hText3, Bufor3, dlugosc3 + 1 );
	//
	
	/* pobieramy kontekst urządzenia ekranu */
	g_hdcEkran = GetDC(NULL);
	/* pętla komunikatów */
	MSG msgKomunikat;
	while (GetMessage(&msgKomunikat, NULL, 0, 0))
	{
		TranslateMessage (&msgKomunikat);
		DispatchMessage (&msgKomunikat);
	}
	// zwracamy kod wyjścia
	return static_cast<int>(msgKomunikat.wParam);
}

I nie wiem czemu nie działa, za każdą pomoc bardzo się odwdzięczę.

0

Ogólnie masakra. Kliknięcie prawym na oknie wywala program.
Wywal te wszystkie GlobalAlloc.

0

Dzięki, co do kodu to na razie chcę po prostu, żeby działał, teraz mam problem z tą częścią kodu:

 
        case WM_RBUTTONDOWN:
	//DWORD dlugosc1 = GetWindowTextLength( hText1 );
	GetWindowText( hText1, Bufor1, 4 );
	//DWORD dlugosc2 = GetWindowTextLength( hText2 );
	GetWindowText( hText2, Bufor2, 4 );
	//DWORD dlugosc3 = GetWindowTextLength( hText3 );
	GetWindowText( hText3, Bufor3, 4 );
        g_r = atoi(Bufor1);
        g_g = atoi(Bufor2);
        g_b = atoi(Bufor3);
        g_clKolor = RGB(g_r,g_g,g_b);

Kompiluje się, ale bufory nie mają żadnej wartości.
//edit - literówka

0

Opisz co program ma robić. Co ma się dziać po kliknięciu, co po wpisaniu wartości itp.
Opisz obsługę programu, bo na razie wiemy tylko że „nie działa”. Ale co ma działać i jak?

0

Na początku program po naciśnięciu lewym przyciskiem myszy na okno zmieniał kursor i gdy przeciągnęło się na jakikolwiek piksel na ekranie okno zmieniało kolor na kolor piksela. Chciałem dodać możliwość wpisania gotowego kodu RGB, dodałem 3 text-boxy a po kliknięciu prawym przyciskiem na okno miał stworzyć kolor RGB i wyświetlić.

1

poprawiłem wiele rzeczy, na tyle dużo że nie chce mi się o tym rozpisywać. przejrzyj kod i zobacz co się zmieniło. jakby co - to pytaj.

// ColorPicker - pobieracz kolorów

#include <string>
#include <sstream>
#include <cstdlib>

#define _WIN32_WINNT 0x501
#include <windows.h>
#include <windowsx.h>

#define ID_TEXT1 501
#define ID_TEXT2 502
#define ID_TEXT3 503

// dane okna
const char g_strKlasaOkna[] = "od0dogk_ColorPicker_Window";
HWND g_hText1, g_hText2, g_hText3;

// uchwyt do kontekstu ekranu
HDC g_hdcEkran = NULL;

// pobrany kolor
COLORREF g_clKolor = RGB(255, 255, 255); // początkowo biały

void updateWindowText(HWND hwnd, COLORREF color)
{
	// pobieramy te składowe i konwertujemy na napis
	std::stringstream Strumien;
	Strumien << "RGB: "
		<< (int) GetRValue(color) << ", "
		<< (int) GetGValue(color) << ", "
		<< (int) GetBValue(color);
	
	// ustawiamy ten napis jako tytuł okna programu
	SetWindowText (hwnd, Strumien.str().c_str());
}

// ------------------- procedura zdarzeniowa okna ------------------------
LRESULT CALLBACK WindowEventProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_RBUTTONDOWN:
		{
			int r,g,b;
			char bufor[16];
			GetWindowText(g_hText1, bufor, ARRAYSIZE(bufor));
			r = atoi(bufor);
			GetWindowText(g_hText2, bufor, ARRAYSIZE(bufor));
			g = atoi(bufor);
			GetWindowText(g_hText3, bufor, ARRAYSIZE(bufor));
            b = atoi(bufor);
            g_clKolor = RGB(r,g,b);

			updateWindowText(hWnd, g_clKolor);
			InvalidateRect(hWnd, NULL, TRUE);
		}
        break;
        case WM_LBUTTONDOWN:
            // łapiemy myszkę
            SetCapture (hWnd);
            // ustawiamy kursor w kształcie celownika
            SetCursor (LoadCursor(NULL, IDC_CROSS));
        break;
        case WM_MOUSEMOVE:
            // sprawdzamy, czy myszka jest złapana
            if (GetCapture() == hWnd)
            {
                // odczytujemy współrzędne kursora
                POINT ptKursor;
                ptKursor.x = GET_X_LPARAM(lParam);
                ptKursor.y = GET_Y_LPARAM(lParam);
                // przeliczamy je na koordynaty ekranowe
                ClientToScreen(hWnd, &ptKursor);
                // pobieramy kolor z miejsca kursora
                g_clKolor = GetPixel(g_hdcEkran, ptKursor.x, ptKursor.y);
				updateWindowText(hWnd, g_clKolor);
                // wymuszamy odświeżenie okna programu,
                // aby pokazać pobrany kolor
                InvalidateRect (hWnd, NULL, TRUE);
            }
        break;
        case WM_LBUTTONUP:
            // uwalniamy mysz
            ReleaseCapture();
            // ustawiamy kursor strzałki
            SetCursor(LoadCursor(NULL, IDC_ARROW));
        break;
        case WM_DESTROY:
            // zwalniamy kontekst ekranu
            ReleaseDC (NULL, g_hdcEkran);
            // kończymy program
            PostQuitMessage (0);
		break;
		case WM_PAINT:
		{
            // odrysowanie zawartości okna
			PAINTSTRUCT ps;
			HDC hdcOkno;
			// zaczynamy
			hdcOkno = BeginPaint(hWnd, &ps);
			// pobieramy obszar klienta okna
			RECT rcObszarKlienta;
			GetClientRect (hWnd, &rcObszarKlienta);
			// wypełniamy go pobranym kolorem
			SetDCBrushColor(hdcOkno, g_clKolor);
			FillRect (hdcOkno, &rcObszarKlienta, (HBRUSH)GetStockObject(DC_BRUSH));
			// kończymy rysowanie
			EndPaint (hWnd, &ps);
			break;
		}
		default:
			return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
    return 0;
}

// ------------------------funkcja WinMain() ----------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
	LOGFONT lf;
	ZeroMemory(&lf, sizeof(lf));
	strcpy(lf.lfFaceName, "Tahoma");
	lf.lfHeight = -11;
	HFONT font = CreateFontIndirect(&lf);

    /* rejestrujemy klasę okna */
    WNDCLASS KlasaOkna;
    ZeroMemory (&KlasaOkna, sizeof(WNDCLASS));

    KlasaOkna.hInstance = hInstance;
    KlasaOkna.lpfnWndProc = WindowEventProc;
    KlasaOkna.lpszClassName = g_strKlasaOkna;
	KlasaOkna.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
    KlasaOkna.hCursor = LoadCursor(NULL, IDC_ARROW);
    KlasaOkna.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    RegisterClass(&KlasaOkna);

    /* tworzymy okno */
    HWND hwndOkno = CreateWindowEx(
		WS_EX_TOOLWINDOW, // exstyle
        g_strKlasaOkna,   // class
        NULL,             // name
        WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU, // style
        CW_USEDEFAULT, CW_USEDEFAULT, // x, y
        140, 190,         // w, h
        NULL,             // parent
        NULL,             // menu
        hInstance,        // instance
        NULL              // param
	);
	SetWindowFont(hwndOkno, font, TRUE);

    // pokazujemy nasze okno i je od razu odświeżamy
    ShowWindow(hwndOkno, nCmdShow);
    UpdateWindow(hwndOkno);
 
    //RED
    g_hText1 = CreateWindowEx(
		WS_EX_CLIENTEDGE, "EDIT", "red", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 1, 105, 130, 20,
		hwndOkno, (HMENU)ID_TEXT1, hInstance, NULL);
	SetWindowFont(g_hText1, font, TRUE);
 
    //GREEN
    g_hText2 = CreateWindowEx(
		WS_EX_CLIENTEDGE, "EDIT", "green", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 1, 125, 130, 20,
		hwndOkno, (HMENU)ID_TEXT2, hInstance, NULL);
	SetWindowFont(g_hText2, font, TRUE);
  
    //BLUE
    g_hText3 = CreateWindowEx(
		WS_EX_CLIENTEDGE, "EDIT", "blue", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 1, 145, 130, 20,
		hwndOkno, (HMENU)ID_TEXT3, hInstance, NULL);
	SetWindowFont(g_hText3, font, TRUE);
 
    /* pobieramy kontekst urządzenia ekranu */
    g_hdcEkran = GetDC(NULL);

    /* pętla komunikatów */
    MSG msgKomunikat;
    while (GetMessage(&msgKomunikat, NULL, 0, 0))
		if (!IsDialogMessage(hwndOkno, &msgKomunikat))
		{
	        TranslateMessage(&msgKomunikat);
			DispatchMessage(&msgKomunikat);
		}

    // zwracamy kod wyjścia
    return static_cast<int>(msgKomunikat.wParam);
}
0

Dzięki wielkie, już działa, co do funkcji to sprawdziłem większość w internecie i wiem, gdzie popełniłem błędy, w razie czego będę pytał :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1