C++/WinAPI Button + obrazek w tle - IMAGELIST,Button_SetImageList()

Odpowiedz Nowy wątek
2011-10-07 15:44
0

Witam... Mam problem z ustawieniem Imagelist dla buttona (chcialbym zeby przed kliknieciem wyswietlana byla 1 bitmapa, w trakcie trzymania przycisku inna i znowu po puszczeniu przycisku poprzednia). Wczytuje 2 bitmapy do IMAGELIST, robie niby wszystko jak w msdn pisze ale nijak nie widze bitmapy na buttonie...

CreateWindowEx(NULL, "BUTTON", "Polacz!", BS_BITMAP | WS_VISIBLE | WS_CHILD | WS_BORDER, 650, 40, 140, 30, hOkna, (HMENU)3, hThisInstance, NULL);

BUTTON_IMAGELIST bi;
HIMAGELIST lista=ImageList_Create(140,30,ILC_COLOR24,1,0);

HBITMAP obraz=(HBITMAP)LoadImage(0,"D:\\tlobtn.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
ImageList_Add(lista,obraz,NULL);

obraz=(HBITMAP)LoadImage(0,"D:\\tlobtn2.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
ImageList_Add(lista,obraz,NULL);

bi.himl = lista;

//SendMessage(GetDlgItem(hOkna, 3), BCM_SETIMAGELIST, NULL, (LPARAM)&lista);
Button_SetImageList(GetDlgItem(hOkna, 3),lista);

Prosze o jakas wskazowke... pozdro

PS. uzywalem wyszukiwarki, niestety wiekszosc tematow dotyczy ustawienia sztywno jednej bitmapy a mi chodzi zeby byl tez efekt klikniecia przycisku.


non omnis moriar i tyle :-)

Pozostało 580 znaków

2011-10-07 17:23
0

Nie lista tylko bi przesyłasz w SetImageList oraz NIGDY nie używaj liczb określających zasób, tylko stałych zdefionowanych.

Button_SetImageList(GetDlgItem(hOkna, IDC_KOLOROWY_BUTTON), &bi);

@edit:
Aha, tak w ogóle to chyba źle korzystasz (no chyba, że tak chciałeś, a nie na pałę przepisałeś skądś) z tworzenia listy:
http://msdn.microsoft.com/en-us/library/bb761522(VS.85).aspx


Pozdro & poćwicz!
edytowany 1x, ostatnio: stfu, 2011-10-07 17:37

Pozostało 580 znaków

2011-10-07 17:43
0

Niestety nic to nie dalo... moze brakuje mi jakiegos stylu w buttonie?

HWND hbut=CreateWindowEx(NULL, "BUTTON", "Polacz!", BS_BITMAP | WS_VISIBLE | WS_CHILD | WS_BORDER, 650, 40, 140, 30, hOkna, (HMENU)3, hThisInstance, NULL);

Probowalem bez BS_BITMAP ale to samo ;/. Podpiac liste probowalem na 2 sposoby:

SendMessage(hbut, BCM_SETIMAGELIST, NULL, (LPARAM)&bi);
Button_SetImageList(hbut,&bi);

Moze ten kod powinien byc w obsludze jakiegos komunikatu? Bo wstawiam go normalnie po utworzeniu przycisku... Dzieki za zainteresownie ;)

@edit
nie widze bledow w tworzeniu listy, poza przedostatnim parametrem ktory powinien wynosic 2 - poprawione ale ten sam efekt


non omnis moriar i tyle :-)
edytowany 1x, ostatnio: arasso12, 2011-10-07 17:45
Pokaż WM_CREATE z WndProc i kawałek WinMain, gdzie robisz najważniejsze rzeczy z głównym oknem. - stfu 2011-10-07 17:59
I jeszcze jedno. Button_SetImageList zwraca TRUE? ;) - stfu 2011-10-07 18:13

Pozostało 580 znaków

2011-10-07 18:43
0

Super... Myslalem ze Button_SetImageList to juz tylko formalnosc a tu false ;o. W WM_CREATE nie robie nic oprocz wczytania bitmapy na tlo glownego okna, mysle ze to nie moze wplywac na dzialanie Button_SetImageList. Tylko wlasnie, dlaczego nie dziala ;/? (getlasterror zwraca 0)


non omnis moriar i tyle :-)

Pozostało 580 znaków

2011-10-07 19:11
0

Ja już nie pamiętam jak to robiłem w WinAPI, ale chyba obsługiwałem zawsze najechanie myszką, przyciśnięcie buttona, disable buttona i standardową bitmapę. Jak jakieś zdarzenie następowało, to podmieniałem bitmapę. Poczytaj o tym :)
Co do WM_CREATE, to nie Ty nie tworzysz TAM swojego buttona? Jeśli nie, to gdzie w takim razie?


Pozdro & poćwicz!

Pozostało 580 znaków

2011-10-07 19:17
0

Ogolnie to napisalem klase okna - rejestruje klase okna towrze je i odrazu tworze kontrolki - pozniej pokazuje okno. A co do Twojego rozwiazania fakt, byloby ok ale troche "naokoło". Jezeli nic nie wydumam/y to zrobie tak jak piszesz.

edit
Wymiekam... nie mam pojecia czemu to nie dziala, latam po stronach i jeszcze nic nie znalazlem ;/ aktualnie kod wyglada tak:


CreateWindowEx(NULL, "BUTTON", "Polacz!", WS_VISIBLE | WS_CHILD | WS_BORDER, 650, 40, 140, 30, hOkna, (HMENU)3, hThisInstance, NULL);
...
...

BUTTON_IMAGELIST bi;
HIMAGELIST lista=ImageList_Create(140,30, ILC_COLOR24 ,2,0);          

if(lista==NULL)
    MessageBox(0, "ERROR0", "", 0);
obraz=(HBITMAP)LoadImage(0,"D:\\tlobtn.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
obraz2=(HBITMAP)LoadImage(0,"D:\\tlobtn2.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

if(obraz==NULL || obraz2==NULL)
    MessageBox(0, "ERROR1", "", 0);

if(ImageList_Add(lista,obraz,NULL)<0)
    MessageBox(0, "ERROR2", "", 0);

if(ImageList_Add(lista,obraz2,NULL)<0)
    MessageBox(0, "ERROR3", "", 0);

bi.himl = lista;
bi.margin.bottom=1;
bi.margin.left=1;
bi.margin.right=1;
bi.margin.top=1;

bi.uAlign=BUTTON_IMAGELIST_ALIGN_TOP;

if(Button_SetImageList(GetDlgItem(hwnd, 3),&bi)==FALSE)
    MessageBox(0, "ERROR4", "", 0);

Znajduje sie w obsludze WM_CREATE, oczywiscie msg ktory pojawia sie na ekranie to "ERROR4", zaden z poprzednich. Probowalem juz chyba wszystkiego... Myslalem tez nad obsluga komunikatu WM_DRAWITEM, przy czym musialem dodac styl buttona BS_OWNERDRAW a razem z nim przesal dzialac msg BM_SETIMAGE wiec to sie chyba mija z celem. Chyba ze lecialbym z bitblt ale czy to ma sens? Prosze o pomoc bo zwariuje. ;/

EDIT
Dobra, problem rozwiazany za pomoca BS_OWNERDRAW & WM_DRAWITEM.

case WM_DRAWITEM:
            {
                //static std::ofstream out("D:\\else.txt");
                DRAWITEMSTRUCT* dr=(DRAWITEMSTRUCT*)lParam;
                if(wParam==3)
                {
                    //out<<dr->itemState<<std::endl;
                    if( dr->itemState==ODS_FOCUS || dr->itemState==0)
                    {
                        HDC hdcBitmapy=CreateCompatibleDC(dr->hDC);
                        HBITMAP hdcStary=(HBITMAP)SelectObject(hdcBitmapy,obraz2);
                        BitBlt(dr->hDC,0,0,140,30,hdcBitmapy,0,0,SRCCOPY);
                        SelectObject(hdcBitmapy,hdcStary);
                        DeleteDC(hdcBitmapy);
                        ReleaseDC(dr->hwndItem, hdcBitmapy );
                        return TRUE;
                    }
                    else
                    if( dr->itemState==17)
                    {
                        //out<<dr->itemState<<std::endl;
                        HDC hdcBitmapy=CreateCompatibleDC(dr->hDC);
                        HBITMAP hdcStary=(HBITMAP)SelectObject(hdcBitmapy,obraz);
                        BitBlt(dr->hDC,0,0,140,30,hdcBitmapy,0,0,SRCCOPY);
                        SelectObject(hdcBitmapy,hdcStary);
                        DeleteDC(hdcBitmapy);
                        ReleaseDC(dr->hwndItem, hdcBitmapy );
                        return TRUE;
                    }

                    return FALSE;

                }

            };
            break;

Co dziwnego ODS_FOCUS byl jedynym statusem kontrolki jaki dostawalem w DRAWITEMSTRUCT, patrzylem kazy inny ktory zostal opisany na msdn po kolei i nic... az dalem else i wypisywalem do notatnika wartosci dr->itemState - tak doszedlem do rozwiazania problemu ;D. Mimo wszystko dziekuje stfu za zaangazowanie. Pozdro ;)

edit
Problemow ciag dalszy... Ustawiam tlo edita na przezroczyste w ten sposob:


case WM_CTLCOLOREDIT:
{
    SetBkMode((HDC)wParam,TRANSPARENT);
    return (LRESULT)GetStockObject(NULL_BRUSH);
};
break;

Jest ok, napisze cos w edicie, pozniej jak kasuje tekst to normalnie kursor sie cofa a litery zostaja... Tak jakby sie nie odswiezal ;/. Jak temu zaradzic?

Problem z editem rozwiazany (moj poprzednik mial podobny problem ze static, po naprawieniu jego kodu dziala ;)) dla potomnych:


HBRUSH CreateTransparentBrush(HWND hwndParent, HWND hwndStatic)
{

HBRUSH hbr = (HBRUSH)GetProp(hwndStatic, "BRUSH");
if (!hbr)
{
RECT rc;
GetWindowRect(hwndStatic, &rc);
ScreenToClient(hwndParent, (POINT*)&rc); 

HDC hdcBitmapy, hdc;
hdc = GetDC(hwndParent);
hdcBitmapy=CreateCompatibleDC(hdc);

HDC hdctmp=CreateCompatibleDC(GetDC(hwndParent));

HBITMAP bmptmp=CreateCompatibleBitmap(hdc,rc.right-rc.left,rc.bottom-rc.top);

SelectObject(hdctmp,bmptmp);

BitBlt(hdctmp,0,0,rc.right-rc.left,rc.bottom-rc.top,hdc,rc.left,rc.top,SRCCOPY);

DeleteDC(hdcBitmapy);
ReleaseDC(hwndParent, hdcBitmapy );
DeleteDC(hdctmp);
ReleaseDC(hwndParent, hdctmp );

hbr = CreatePatternBrush(bmptmp);

SetProp(hwndStatic, "BRUSH", (HANDLE)hbr);
}
return hbr;
} 
} 

        case WM_CTLCOLOREDIT:
            {
                SetBkMode((HDC)wParam,TRANSPARENT);
                return (LRESULT)CreateTransparentBrush(hwnd, GetDlgItem(hwnd, 301));
            };
            break;

Pozostaje jeszcze 'tylko' problem z listview... pozdro


non omnis moriar i tyle :-)
edytowany 8x, ostatnio: arasso12, 2011-10-09 22:29
Dobra, ale rysuje cokolwiek? Czy żadnej bitmapy nie pokazuje? - stfu 2011-10-08 16:54
Absolutnie nic, zaraz dodam ss programu - arasso12 2011-10-08 18:12
Nie doczytałem, że nie ustawia listy, bo false zwraca. Patrzyłeś tutaj http://msdn.microsoft.com/en-[...]esktop/bb761867(v=vs.85).aspx i sprawdzałeś, czy masz odpowiednie style włączone? Wrzuć gdzieś kod, to sprawdzę u siebie. - stfu 2011-10-08 19:33
A możesz zaznaczyć tekst w tym edicie jak skasujesz kilka znaków? I czy te znaki skasowane też się zaznaczają? - stfu 2011-10-09 22:10

Pozostało 580 znaków

2011-10-09 20:30
0

bi.margin.bottom=1;
bi.margin.left=1;
bi.margin.right=1;
bi.margin.top=1;

Czy sprawdzałeś z innymi wartościami? Chodzi o to, że takie coś tworzy strukturę RECT o zerowej wielkości. Raczej spodziewałbym się czegoś takiego (zgodnie z http://msdn.microsoft.com/en-[...]op/dd162897%28v=vs.85%29.aspx):
bi.margin.left = 1;
bi.margin.right = bi.margin.left + 130;
bi.margin.top = 1;
bi.margin.bottom = bi.margin.top + 30;

130 i 30 to tylko przykład, wartości zależą od tego jak duży jest twój Button.

P.S. jeszcze jedna uwaga z MSDN z powyższego linka:
"Note To use this macro, you must provide a manifest specifying Comclt32.dll version 6.0. For more information on manifests, see Enabling Visual Styles."

Czy masz to spełnione?

edytowany 2x, ostatnio: Tomek2, 2011-10-09 20:36
Dzieki za wskazowke :) moze na przyszlosc mi sie przyda ale nie chce juz do tego wracac - problem rozwiazany. Teraz mecze sie z editem i jego tlem ktore sie nie odswieza (opis wyzej) oraz z kontrolka ListView ( SendMessage(hWndListView,LVM_SETBKCOLOR,0,CLR_NONE); SendMessage(hWndListView,LVM_SETTEXTBKCOLOR,0,CLR_NONE); ) i tlo kontrolki robi sie poprostu szare a nie przezroczyste... ;/ - arasso12 2011-10-09 21:06

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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