Allegro WinApi

krstk

Mój pierwszy art na poważnie, jakby co proszę o wyrozumiałość i poprawienie.
Zakładam że ewentualny czytelnik umie choć trochę posługiwać się biblioteką Allegro i WindowsApi.
Więc allegro oferuje proste i szybkie funkcje do obsługi bitmap, prymitywów, spritów, animacji, jednak takie aspekty jak timery czy obsługa klawiatury jest już dosyć toporna i niewygodna.

Ale jest sposób, mianowicie można użyć naraz allegro z WinApi i obsługiwać zdarzenie przy pomocy procedury zdarzeniowej, i używać innych funkcji z WinApi, jak obsługa rejestru naprzykład.
Więc na początek typowy szkielet aplikacji pod windows, ściągnięty z szablonów w dev-C++.

#include <windows.h>
 
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
char szClassName[ ] = "WindowsApp";
 
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
 
{
HWND hwnd; 
hdcokno=GetDC(hwnd); 
MSG messages; 
WNDCLASSEX wincl; 
 
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; 
wincl.style = CS_DBLCLKS; 
wincl.cbSize = sizeof (WNDCLASSEX);
 
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; 
wincl.cbClsExtra = 0; 
wincl.cbWndExtra = 0; 
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
if (!RegisterClassEx (&wincl))
return 0;
 
hwnd = CreateWindowEx ( 0,szClassName,"Windows App",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,500,500,HWND_DESKTOP,NULL,hThisInstance,NULL ); 
ShowWindow (hwnd, nFunsterStil);
 
while (GetMessage (&messages, NULL, 0, 0))
{
 
TranslateMessage(&messages);
DispatchMessage(&messages);
}
 
return messages.wParam;
}
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) 
{
case WM_DESTROY:
PostQuitMessage (0); 
break;
default: 
return DefWindowProc (hwnd, message, wParam, lParam);
}
 
return 0;
}
 

Teraz zmodyfikujmy to nieco tak aby korzystać z allegro w API. Objaśnienia w komentarzach. Nie zapomnijcie dopisać do linkera -lalleg.

#include <allegro.h>
#include <winalleg.h> /*dodajemy allegro.h i ten nagłówek, zamiast windows.h, który z allegro się gryzie*/ 
 
BITMAP *bufor; /*bitmapa, będzie głównym buforem do rysowania, do tego Uchwyt do kontekstu urządzenia i strukturka o wiadomym zastosowaniu*/ 
HDC hdc;
PAINTSTRUCT ps;
 
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
char szClassName[ ] = "WindowsApp";
 
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
 
{
HWND hwnd; 
hdcokno=GetDC(hwnd); 
MSG messages; 
WNDCLASSEX wincl; 
 
/*inicjalizacja allegro*/ 
 
install_allegro( SYSTEM_NONE, &errno, atexit );
set_color_depth( 24 );
 
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; 
wincl.style = CS_DBLCLKS; 
wincl.cbSize = sizeof (WNDCLASSEX);
 
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; 
wincl.cbClsExtra = 0; 
wincl.cbWndExtra = 0; 
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
if (!RegisterClassEx (&wincl))
return 0;
 
hwnd = CreateWindowEx ( 0,szClassName,"Windows App",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,500,500,HWND_DESKTOP,NULL,hThisInstance,NULL );
ShowWindow (hwnd, nFunsterStil);
 
hdc=GetDC(hwnd); /*ładujemy uchwyt*/ 
 
while (GetMessage (&messages, NULL, 0, 0))
{
 
TranslateMessage(&messages);
DispatchMessage(&messages);
}
 
return messages.wParam;
}
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) 
{
 
case WM_CREATE:
bufor = load_bitmap( "bitmapa.bmp", default_palette);/*ładujemy jakiś obrazek*/
break; 
case WM_PAINT: /*Jeśli coś się nam zamaże to odmalowujemy*/
hdc = BeginPaint( hwnd, &ps );
draw_to_hdc( hdc,bufor, 0, 0 );/*funkcja kopiująca bitmapę do hdc, czyli wyświetlająca ją na ekran*/
EndPaint( hwnd, &ps );
break;
case WM_DESTROY: 
destroy_bitmap(bufor); 
PostQuitMessage (0); 
break;
default: 
return DefWindowProc (hwnd, message, wParam, lParam);
}
 
return 0;
}

7 komentarzy

lol miszczu xd bez przesady :D
co do winapi.rox.pl to nic nie wyrzucałem, jak było tak jest, ostatnio pracuję przy tworzeniu nowej strony z kilkoma osobami, dlatego winapi.rox.pl jest już od jakiegoś czasu nieruszane, na nowej stronie będzie całkiem nowy kurs WinAPI, ale start strony na pewno nie wcześniej niż po wakacjach

Po pierwsze nie do końca, gdyż ta struktura jest w allegro też powierzchnią roboczą i ekranem, po drugie w pytaniu chodzi o to czy w tym wypadku obiekty typu BITMAP pochodzą z WinApi czy z allegro, bo w WinApi też jest taka struktura.

Poza tym siemka miszczu, uczyłem się kiedyś z twojego tutoriala na stronie winapi.rox.pl, niezłe jest zwłaszcza to o plikach zasobów.
Swoją drogą, zajrzałem tam znowu dzisiaj, i chyba gdy ostatnio tam byłem to materiału było chyba więcej, wywaliłeś coś?

@crayze: BITMAP to struktura przechowująca obrazek (biblioteka Allegro). A w WinAPI to chyba sam wiesz ;)

To jest struktura w allegro. Aby zachować zgodność w winalleg w przeciwieństwie do windows.h struktury BITMAP nie ma.

a to BITMAP to jest struktura WinAPI? Czy jakiś wewnętrzny typ allegro?

tak się domyślałem, jak będę potrzebował kiedyś allegro, to będzie to pierwsze miejsce do jakiego zajrzę...
pozdrawiam...

wg. mnie używanie bibliotek windowsa w allegro mija się z celem - allegro ma wszystkie najważniejsze rzeczy. Po zatym gra już nie będzie chodziła na linuxach etc. (nie mówie tutaj o emulatorach). Najlepiej wg. mnie przesiąść się na sdl ;]