[ Wajda.W @ 22.05.2009. 20:29 ] @
E ovako, namestio sam neku klasu (klasa polje) koja ima metodu da se iscrta:


Code:


void place::draw(HDC hdc)
{
    HBITMAP hbmMine = NULL;
    HDC hdcMine = CreateCompatibleDC(hdc);
    HWND hwnd;
    hwnd = GetActiveWindow();

    hbmMine = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_MINE_0));
            if(hbmMine == NULL)
                MessageBox(hwnd, "Could not load resource!", "Error", MB_OK | MB_ICONEXCLAMATION);
       

    SelectObject(hdcMine, hbmMine);

    BitBlt(hdc, x, y, 16, 16, hdcMine, 0, 0, SRCCOPY);  // x, y su  clanice klase i predstavljaju poziciju polja u okviru prozora
    DeleteDC(hdcMine);

}




Kada pozovem metodu u WM_PAINT-u u nekoj petlji npr:

Code:


place p[10][10];
.
.
.
case WM_PAINT:
        {

            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            for(int i=0;i<20;i++)
            for(int j=0;j<20;j++)
            p[i][j].draw(hdc,mine_clear);

            EndPaint(hwnd, &ps);
        }
        break;



i kad krenem da resize-ujem prozor salje se WM_PAINT poruka koja ponovo iscrtava resajzovani prozor, to mi je jasno, ali pri vecim matricama mi
izbaci onaj messagebox iz metode - Could not load resource!...
Kontam da kad mi to izbaci da messagebox salje jos WM_PAINT poruka i da otprilike ostanem zaglavljen u beskonacnoj petlji.
Ali zasto mi to izbacuje samo pri velikim matricama npr ovoj 20x20 ili 10x10, na matrici 2x2, 3x3 mi to ne izbacuje??? Zasto?
Da li nesto nisam dobro uradio u samoj metodi za crtanje ili je preopterecenje resorsa?
Da li neko moze da mi objasni zasto se to desava i sta ne valja, sta trebam da ispravim?
Hvala unapred
Vajda
[ milanche @ 23.05.2009. 05:51 ] @
Citat:
Kontam da kad mi to izbaci da messagebox salje jos WM_PAINT poruka i da otprilike ostanem zaglavljen u beskonacnoj petlji.
Ali zasto mi to izbacuje samo pri velikim matricama npr ovoj 20x20 ili 10x10, na matrici 2x2, 3x3 mi to ne izbacuje??? Zasto?


Za pocetak - pokusaj da stvari uradis na optimalniji nacin.

Prvo sto je ocito - bitmapu ne moras da load-ujes bas svaki put. Dovoljno je load-ovati je samo prvi put, kad hbmMine ima
vrednost NULL. Da sve ima smisla, premesti hbmMine u persistentije promenljive (umesto sto ti je lokalna promenljiva funkcije,
stavi je da bude, recimo privatna clanica klase (private, ili protected)) i u konstruktoru je inicijalizuj na NULL.

Znaci:
Code:

class place
{
...
...
...
private:
     HBITMAP m_hbmMine;
};


Code:

place::place(...)
    : m_hbmMine(NULL)
{
...
}


Code:

void place::draw(HDC hdc)
{
    if(NULL == m_hbmMine)
        m_hbmMine = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_MINE_0));

    if(NULL == m_hbmMine == NULL)
    {
        MessageBox(hwnd, "Could not load resource!", "Error", MB_OK | MB_ICONEXCLAMATION);
        return;
    }

    HDC hdcMine = CreateCompatibleDC(hdc);
    HWND hwnd;
    hwnd = GetActiveWindow();
       
    SelectObject(hdcMine, hbmMine);

    BitBlt(hdc, x, y, 16, 16, hdcMine, 0, 0, SRCCOPY);  // x, y su  clanice klase i predstavljaju poziciju polja u okviru prozora
    DeleteDC(hdcMine);
}


Ovako na prvi pogled rekao bih da to moze da bude jedan od jacih razloga zasto ti se javljaju problemi pri vecim bitmapama
a recimo ne pri manjim. Naravno, moze da bude i drugih razloga koji nisu ocigledni na osnovu prilozenog koda.
[ Wajda.W @ 23.05.2009. 16:23 ] @
ok, pokusacu tako nesto, hvala!
[ Wajda.W @ 23.05.2009. 17:30 ] @
Nasao sam gresku, nije problem sto loadujem u metodi, problem je sto nisam brisao objekat, pa je doslo do 'zasicenja'.
falilo mi je dole na kraju metode draw ovo:

DeleteObject(hbmMine);

znaci:

Code:

void place::draw(HDC hdc)
{
    HBITMAP hbmMine = NULL;
    HDC hdcMine = CreateCompatibleDC(hdc);
    HWND hwnd;
    hwnd = GetActiveWindow();

    hbmMine = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_MINE_0));
            if(hbmMine == NULL)
                MessageBox(hwnd, "Could not load resource!", "Error", MB_OK | MB_ICONEXCLAMATION);
       

    SelectObject(hdcMine, hbmMine);

    BitBlt(hdc, x, y, 16, 16, hdcMine, 0, 0, SRCCOPY);  // x, y su  clanice klase i predstavljaju poziciju polja u okviru prozora
    DeleteDC(hdcMine);
    DeleteObject(hbmMine);
}



[Ovu poruku je menjao Wajda.W dana 23.05.2009. u 18:41 GMT+1]
[ DjoleReject @ 27.05.2009. 12:48 ] @
Citat:
Wajda.W: Nasao sam gresku, nije problem sto loadujem u metodi, problem je sto nisam brisao objekat, pa je doslo do 'zasicenja'.

Pa jeste, ali ne mozes se s C++om ponasati kao sa C#om (da postoji garbage collesctor) :)
Nije samo stvar u tome da odradis delete nakon pravljenja nekog objekta, nego bi bilo dobro i da racionalnije pristupis svojim resursima. Na primer, ideja da za svaki poziv draw funkcije, ispocetka loadujes i brises velike objekte, se nikako ne moze nazvati dobro organizovanim kodom. Radice to ok ovako kad ti treba jedna slika, ali ako odlucis da sve to bude deo veceg projekta, upadas u probleme.
Eto, cisto mojih pet centi...
[ Wajda.W @ 27.05.2009. 19:37 ] @
@DjoleReject: Da, znam da nije tehnicki najbolje resenje, ali mislim da bi struktura sa loadovanim HBITMAP-om bila mnogo velika, trebalo bi to odraditi kao jedno loadovanje negde na pocetku, ali nisam smislio dorbo resenje za to, za trenutne potrebe radice i ovako. :)
pozdrav