[WinAPI]Button z grafiką i tekstem, co nie tak?

0

Od paru dni siedzę i kombinuję jak tu stworzyć Button z grafiką i tekstem. Przekopałem MSDN i stworzyłem takie coś:


#include "stdafx.h"
#include "asd.h"
#include "Commctrl.h"

LPSTR NazwaKlasy = "Klasa Okienka";
MSG Komunikat;
HWND guzik;
HBITMAP obraz,maska;
HIMAGELIST lista;
BUTTON_IMAGELIST bi;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
obraz = (HBITMAP)LoadImage(NULL, "c:\\plik.bmp", IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);
maska = (HBITMAP)LoadImage(NULL, "c:\\maska.bmp", IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE);

//WYPEŁNIANIE STRUKTURY
 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_BACKGROUND);
 wc.lpszMenuName = NULL;
 wc.lpszClassName = NazwaKlasy;
 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

//REJESTROWANIE KLASY OKNA
 if(!RegisterClassEx(&wc))
 {
  MessageBox(NULL, "Rejestracja okna nie powiodla sie.", "Error", MB_ICONEXCLAMATION | MB_OK);
   return 1;
 }

//TWORZENIE OKNA
 HWND hwnd;

 hwnd = CreateWindowEx(0, NazwaKlasy, "Okienko", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInstance, NULL);

 if(hwnd==NULL)
 {
  MessageBox(NULL, "Okno sie nie pojawilo.", "Error", MB_ICONEXCLAMATION);
  return 1;
 }

guzik = CreateWindowEx(0, "BUTTON", "Guzik", WS_CHILD | WS_VISIBLE, 150, 150, 150, 30, hwnd, NULL, hInstance, NULL);
 
lista=ImageList_Create(32,32,ILC_MASK | ILC_COLOR24,1,0);
if(!lista)
{
MessageBox(hwnd,"Blad z tworzeniem listy.","asd",MB_ICONINFORMATION);
}

 ImageList_Add(lista,obraz,maska);
 
 bi.himl = lista;
         bi.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;
         bi.margin.top = 3;
         bi.margin.bottom = 3;
         bi.margin.left = 3;
         bi.margin.right = 3;
                
                Button_SetImageList(guzik,lista);
               


DeleteObject(obraz);
 DeleteObject(maska);
 ShowWindow(hwnd, nCmdShow); //Pokaż okienko...
 UpdateWindow(hwnd);

//Pętla komunikatów
 while(GetMessage(&Komunikat, NULL, 0, 0))
 {
  TranslateMessage(&Komunikat);
  DispatchMessage(&Komunikat);
 }
 return Komunikat.wParam;
}

//OBSŁUGA ZDARZEŃ
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
 switch(msg)
 {
  case WM_CLOSE:
   DestroyWindow(hwnd);
  break;
 
  case WM_DESTROY:
   PostQuitMessage(0);
  break;
  default:
   return DefWindowProc(hwnd, msg, wParam, lParam);
  }
 return 0;
} 

Używam MS Visual Studio 2005.
Podpowie mi ktoś gdzie jest błąd? Bo kod kompiluje mi się bez błędów, a na guziku grafiki jak nie było tak nie ma :/

Próbowałem też po prostu wysyłać do przycisku komunikat BM_SETIMAGE, ale nie udało mi się uzyskać jednocześnie i tekstu i grafiki. W komentarzu na MSDN piszą nawet, że na Windows XP to niemożliwe.
Jest jakiś prostszy sposób niż tworzenie własnej kontrolki? :-/

0

z masd'a

Note To use this API, you must provide a manifest specifying Comclt32.dll version 6.0. For more information on manifests, see Enabling Visual Styles.

0

Ano widziałem to, ale zielonego pojęcia nie mam jak w visualu taki manifest dodać i co właściwie ma w nim być. Czytałem to na MSDN, mógłby ktoś jakoś mi to opowiedzieć? I co ma na celu dodanie tego manifestu?

0

Jak dodac manifest z pragma jest na tym portalu (w c sharpie).

Jesli nie pojdzie to BM_SETIMAGE, to mi dziala teraz.

Nie wiem czemu (ustawienie listy) teraz nie dziala (z dodaniem manifestu, wszytskie funkcje zwracaja true, dodalem style BS_ do buttona) ale siedze na 2003 bez skorek z minimum grafiki i wiem, ze tu nie dziala bardzo duzo elementow graficznych (sam kiedys siedzialem i nie wiedzialem czemu mi nie dziala IDropTargetHelper a po przeniesieniu na kolorowe XP wszytsko bylo OK.).

0

Ja też mam "niekolorowy" system, ale XP. Przełączyłem sobie na "kolorowy", ale bez zmian. Hmm, chyba się poddam i zrobię gui w jakimś środowisku RAD, bo zaczyna mnie to już irytować pomału.

0

Dexterek, poszukaj programu rc.exe (lub ściągnij gorc.exe ze strony gordona).
Stwórz pliczek xpstyle.rc ewentualnie poprawiając literkę dysku:1 24 c:\\windows\\WindowsShell.ManifestI skompiluj go poleceniem

rc xpstyle.rc
lub
gorc /r xpstyle.rc

Powstanie plik xpstyle.res którego sobie skopiuj do folderu LIB w swoim kompilatorze, a tego .rc usuń.
Teraz by aktywować style-xp w programach po prostu zlinkuj xpstyle.res w opcjach projektu, lub pisząc w kodzie

#pragma comment(lib, "xpstyle.res")

Mogą powstać problemy (duplicate resource id) gdy kompilator sam tworzy manifest dla crt (od visual studio 2005), wtedy ten sposób odpada. http://blogs.msdn.com/oldnewthing/archive/2007/05/31/2995284.aspx

0

Przepraszam, że odkopuję stary temat, ale:
Tworzę plik w notatniku, w treści wpisuję:
c:\windows\WindowsShell.Manifest

Zapisuję jako style.rc i kompiluję za pomocą rc.exe do style.res. Kopiuję do katalogu lib i robię

#pragma comment(lib, "style.res")

Wszystko ładnie, a jak próbuję kompilować to:

1>D:\VS\VC\lib\style.res : fatal error LNK1107: invalid or corrupt file: cannot read at 0x20

No i domyślam się, że gdzieś robię błąd, ale gdzie?

0

Kurcze, niezarejestrowani nie mogą edytować:/

OK, błąd był taki, że musi być tak jak sapero podał dokładnie czyli:

1 24 c:\windows\WindowsShell.Manifest

No i ok, kompiluje się z tym wszystko, ale grafiki wciąż nie ma...

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