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

[C++, WinApi] Klasa okna własnej kontrolki ciągle zarejestrowana

Ostatnio zmodyfikowano 2012-08-19 00:09
Autor Wiadomość
lorkan
Temat założony przez niniejszego użytkownika
[C++, WinApi] Klasa okna własnej kontrolki ciągle zarejestrowana
» 2012-08-18 17:41:38
Witam serdecznie.

Edit.Poprawione

Próbuję od podstaw utworzyć własną kontrolkę sugerując się znalezionym u was artykułem "Własne Kontrolki 2" znalezionym w dziale Kursy.

Mój problem polega na tym że aby po wprowadzeniu jakiejś zmiany w WM_PAINT kontrolki ujrzeć efekty muszę zmienić klasę okna jaką nadaje mojej kontrolce.

Nie do końca rozumiem czemu się tak dzieje. Ciągła zmiana nazwy to nie rozwiązanie proszę o sugestie.


main.cpp

#include <windows.h>
#include "AngleControl.h"
LRESULT CALLBACK WndProc( HWND , UINT , WPARAM , LPARAM  );

HINSTANCE HINST;
LPSTR NazwaKontrolki = "Test2";

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    LPSTR NazwaKlasy = "Test";
    HINST = hInstance;
   
    WNDCLASSEX wc;

    wc.cbSize = sizeof( WNDCLASSEX );
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 );
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NazwaKlasy;
    wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );

if( !RegisterClassEx( & wc ) )
{
    MessageBox( NULL, "Błąd rejestracji okna głównego.", "Error", MB_ICONEXCLAMATION | MB_OK );
    return 1;
}   
    HWND hwnd;
    hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, NazwaKlasy, "Testowe", WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, hInstance, NULL );

if( hwnd == NULL )
{
    MessageBox( NULL, "Nie utworzono okna.", "Error", MB_ICONEXCLAMATION );
    return 1;
}   

    ShowWindow( hwnd, nCmdShow );
    UpdateWindow( hwnd );
   
    MSG Komunikat;
while( GetMessage( & Komunikat, NULL, 0, 0 ) )
{
    TranslateMessage( & Komunikat );
    DispatchMessage( & Komunikat );
}

return Komunikat.wParam;   
   
    return 0;
}


LRESULT CALLBACK WndProc( HWND g_hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CREATE:
         if( !RejestrujPrzycisk( HINST ) )
         {
         MessageBox( g_hwnd, "Nie udało się zarejestrować klasy przycisku.", "Yh...", MB_ICONSTOP );
         DestroyWindow( g_hwnd );
         }       
         HWND hControl;
         hControl = CreateWindowEx( 0, NazwaKontrolki, NULL,WS_CHILD | WS_VISIBLE, 0, 0, 50, 50, g_hwnd, NULL, HINST, NULL );
         if (hControl == NULL)
            DestroyWindow( g_hwnd );                

        break;
                   
    case WM_CLOSE:
        DestroyWindow( g_hwnd );
        break;
      
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;
      
        default:
        return DefWindowProc( g_hwnd, msg, wParam, lParam );
    }
  
    return 0;
}

AngleControl.h

int max=50;
BOOL RejestrujPrzycisk( HINSTANCE  );
LRESULT CALLBACK ControlProc( HWND , UINT , WPARAM , LPARAM  );

BOOL RejestrujPrzycisk( HINSTANCE hInst )
{
    WNDCLASS wc;
    wc.style = 0; // stylowy kibel? ;-)
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NazwaKontrolki;
    wc.hInstance = hInst;
    wc.lpfnWndProc = ControlProc;
    wc.cbWndExtra = 0;
    wc.cbClsExtra = 0;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground =( HBRUSH ) GetStockObject( NULL_BRUSH );
  
    if( !RegisterClass( & wc ) ) return FALSE;
     
    return TRUE;
}

LRESULT CALLBACK ControlProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CREATE:
         SetWindowPos( hwnd, NULL, 0, 0, max, max, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
         HRGN hRgn;
         hRgn = CreateEllipticRgn( 0, 0, max - 1, max - 1 );
         SetWindowRgn( hwnd, hRgn, FALSE );      
         break;

    case WM_PAINT:

         PAINTSTRUCT ps;
         HDC hdcOkno;
         hdcOkno = GetDC(hwnd);
         HBRUSH PedzelZiel, Pudelko;
         HPEN OlowekCzerw, Piornik;
         PedzelZiel = CreateSolidBrush( 0x00FFFF );
         OlowekCzerw = CreatePen( PS_DOT, 1, 0x0000FF );
         Pudelko =( HBRUSH ) SelectObject( hdcOkno, PedzelZiel );
         Piornik =( HPEN ) SelectObject( hdcOkno, OlowekCzerw );
         Ellipse( hdcOkno, 0, 0, 50, 50 );
         SelectObject( hdcOkno, Pudelko );
         SelectObject( hdcOkno, Piornik );
         DeleteObject( OlowekCzerw );
         DeleteObject( PedzelZiel );
         EndPaint( hwnd, & ps );
         ReleaseDC( hwnd, hdcOkno );
         break;
                   
    case WM_CLOSE:
         DestroyWindow( hwnd );
         break;
      
    case WM_DESTROY:
         PostQuitMessage( 0 );
         break;
      
    default:
         return DefWindowProc( hwnd, msg, wParam, lParam );
    }
  
    return 0;
}

P-62864
pekfos
» 2012-08-18 17:43:39
Popraw nazwę tematu.
P-62865
DejaVu
» 2012-08-18 17:45:30
» Kurs STC » Kolorowanie składniKolorowanie składni języka C++ lekcja

Co do problemu.... jeżeli smarujesz cokolwiek w WM_PAINT to musisz liczyć się z tym, że trzeba będzie przerysowywać obraz nieustannie. Wynika to z architektury Windowsa i tego nie przeskoczysz. Jeżeli chcesz rysować sobie kolejne elementy na ekranie to musiałbyś stworzyć bufor, smarować wszystko na buforze, a w WM_PAINT wyświetlać zawsze bufor na ekran.
P-62866
lorkan
Temat założony przez niniejszego użytkownika
» 2012-08-18 17:49:57
Tak rozumiem jednak kłopocze mnie dlaczego efekty następują dopiero po nadaniu okienku kontrolki innej nazwy klasy. Przecież po zniszczeniu okna klasa którą tworzę powinna zniknąć.

Mianowicie musze zmienic zmienną "NazwaKontrolki".
P-62867
DejaVu
» 2012-08-18 17:58:25
Niestety nie rozumiem za bardzo o co Ci chodzi (ale pewnie dlatego, że nie jestem aż tak biegły w tych sprawach ;p).
P-62871
lorkan
Temat założony przez niniejszego użytkownika
» 2012-08-18 18:14:39
Ja też nie jestem specialistą raczej błądzę o macku.

Spróbuje jeszcze raz wyjaśnić o co chodzi.

Tworze sobię okno o klasie "Test" którą rejestruję i nazwie "Testowe".
Umieszczam na nim inne okienko ("kontrolke") o klasie "Test2" którą również rejestruję.

W procedurze obsługi kontrolki obsługuję komunikat WM_PAINT w celu narysowania jej według uznania.

Tyle faktów wynika z kodu i jest to praktycznie identyczne z zawartością kursy "Własne kontrolki cz.2" z tą różnicą że nie tworzę własnego przycisku na podstawie bitmapy.

Kompiluje uruchamiam i w oknie rysuję się elipsa (de fakto w kształcie koła) o danym kolorze. Wszystko pieknie.

Teraz zmieniam kolor na inny kompiluje uruchamiam i co widze kolor sie nie zmienił.

Aby nowy kolor się pokazał zmieniam nazwę klasy kontrolki i dopiero wtedy widać efekt po kompilacji i uruchomieniu.

Doszedłem do wniosku że jak zarejestruję klasę raz to drugi raz nie mogę tylko nie rozumiem czemu.
P-62877
DejaVu
» 2012-08-18 18:25:18
Może po prostu nie zamykasz prawidłowo aplikacji i proces pozostaje w pamięci... albo jakieś takie cuda? Albo np. spróbuj Rebuild po wprowadzeniu zmian?
P-62882
lorkan
Temat założony przez niniejszego użytkownika
» 2012-08-18 18:49:12
Niestety nic z tych rzeczy. Używam Dev C++ jeśli to coś pomoże po przebudowaniu projektu nadal nic ;/ kruczek musi tkwić gdzieś przy rejestracji klasy okna.

Na zasadzie że gdy po zmianie próbuję zarejestrować ponownie tą sama klasę ona się nie przyjmuje. Co ciekawe RegisterClass wykonuje się poprawnie.
P-62891
« 1 » 2
  Strona 1 z 2 Następna strona