Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Winapi - błąd programu do rysowania koloru RGB

Ostatnio zmodyfikowano 2014-02-12 10:23
Autor Wiadomość
verijon
Temat założony przez niniejszego użytkownika
Winapi - błąd programu do rysowania koloru RGB
» 2014-02-11 23:27:36
Mam problem, uczę się winapi, zaczynam rozdział o grafice i jest program pobierający kolor piksela w formacie RGB i wyświetlający jako kolor tła okna. Postanowiłem przerobić, żeby można było samemu wpisać wartość każdego z koloru (od 0 do 255), wszystko się skompilowało, ale po naciśnięciu prawego przycisku, gdzie miały zajść obliczenia wywala błąd visual c++ "Debug Assertion Failed", może dam kod, bo długo się nad tym męczę i nie wiem gdzie popełniłem błąd. (nie wiem jak wywołać case WM_PAINT, zmienna g_rysuj miała mieć zostać użyta do tego)
C/C++
#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, Bufor2, Bufor3;
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_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
                // 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;
        }
    case WM_DESTROY:
        // zwalniamy kontekst ekranu
        ReleaseDC( NULL, g_hdcEkran );
        // kończymy program
        PostQuitMessage( 0 );
        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 );
}

Na pewno dałoby się lepiej napisać, ale na razie chcę, żeby chociaż działał. Bardzo odwdzięczę się za każdą pomoc.
P-104484
Monika90
» 2014-02-12 00:05:03
Zmienne globalne Bufor1,2,3 są równe NULL, ponieważ nigdy niczego do nich nie przypisujesz.
P-104485
verijon
Temat założony przez niniejszego użytkownika
» 2014-02-12 10:23:18
Ok wielkie dzięki, już nie wywala błędów :) Ale nie działa rysowanie koloru, może pokażę kod:
C/C++
#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;
        //
        {
            // 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;
        }
        //
        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_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
                // 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;
        }
    case WM_DESTROY:
        // zwalniamy kontekst ekranu
        ReleaseDC( NULL, g_hdcEkran );
        // kończymy program
        PostQuitMessage( 0 );
        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 );
}
Chwilowo przekopiowałem z WM_PAINT do WM_RBUTTONDOWN, ale to nie powinno mieć znaczenia.
//Edit
P-104496
« 1 »
  Strona 1 z 1