steve
2010-12-08 19:45:49 UTC
Hello,
I'm completely new to GDI.
I found this simple gdi animation program in a book.
It compiles just fine, however, it does not animate.
It's just static.
It draws colored rectangles, one inside the other and the colors are
supposed to rotate inward,
creating a "tunnel" effect.
// Animate.c
// Palette animation
// Book:Programming Windows 98/NT Unleashed
// link with: gdi32.lib, user32.lib
#include <windows.h>
void Animate(HWND, HPALETTE);
void DrawCircle(HWND, HPALETTE);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
struct
{
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[12];
} palPalette =
{
0x300,
12,
{
{0xFF, 0x00, 0x00, PC_RESERVED},
{0xC0, 0x40, 0x00, PC_RESERVED},
{0x80, 0x80, 0x00, PC_RESERVED},
{0x40, 0xC0, 0x00, PC_RESERVED},
{0x00, 0xFF, 0x00, PC_RESERVED},
{0x00, 0xC0, 0x40, PC_RESERVED},
{0x00, 0x80, 0x80, PC_RESERVED},
{0x00, 0x40, 0xC0, PC_RESERVED},
{0x00, 0x00, 0xFF, PC_RESERVED},
{0x40, 0x00, 0xC0, PC_RESERVED},
{0x80, 0x00, 0x80, PC_RESERVED},
{0xC0, 0x00, 0x40, PC_RESERVED}
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
d3, int nCmdShow)
{
MSG msg;
HWND hwnd;
WNDCLASS wndClass;
if(hPrevInstance == NULL)
{
memset(&wndClass, 0, sizeof(wndClass));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = "HELLO";
if(!RegisterClass(&wndClass))
{
return FALSE;
}
}
hwnd = CreateWindow("HELLO", "HELLO", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
SetTimer(hwnd, 1, 100, NULL);
while(GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
KillTimer(hwnd, 1);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
static HPALETTE hPalette;
switch(uMsg)
{
case WM_CREATE:
hPalette = CreatePalette((LPLOGPALETTE) &palPalette);
break;
case WM_PAINT:
DrawCircle(hwnd, hPalette);
break;
case WM_TIMER:
Animate(hwnd, hPalette);
break;
case WM_DESTROY:
DeleteObject(hPalette);
hPalette = NULL;
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void DrawCircle(HWND hwnd, HPALETTE hPalette)
{
HDC hDC;
PAINTSTRUCT paintStruct;
RECT rect;
HPALETTE hOldPal;
int i;
hDC = BeginPaint(hwnd, &paintStruct);
if(hDC != NULL)
{
hOldPal = SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
GetClientRect(hwnd, &rect);
DPtoLP(hDC, (LPPOINT) &rect, 2);
for(i = 0; i < 12; i++)
{
HBRUSH hbr;
HBRUSH hbrOld;
hbr = CreateSolidBrush(PALETTEINDEX(i));
hbrOld = (HBRUSH) SelectObject(hDC, hbr);
Rectangle(hDC, MulDiv(i, rect.right, 24), MulDiv(i,
rect.bottom, 24),
rect.right - MulDiv(i, rect.right, 24),
rect.bottom - MulDiv(i, rect.bottom, 24));
SelectObject(hDC, hbrOld);
DeleteObject(hbr);
}
SelectPalette(hDC, hOldPal, FALSE);
EndPaint(hwnd, &paintStruct);
}
}
void Animate(HWND hwnd, HPALETTE hPalette)
{
HDC hDC;
PALETTEENTRY pe[12];
HPALETTE hOldPal;
static int nIndex;
int i;
for(i = 0; i < 12; i++)
{
pe[i] = palPalette.palPalEntry[(i + nIndex) % 12];
}
hDC = GetDC(hwnd);
hOldPal = SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
AnimatePalette(hPalette, 0, 12, pe);
nIndex = (++nIndex) % 12;
SelectPalette(hDC, hOldPal, FALSE);
ReleaseDC(hwnd, hDC);
}
The code is correct. I verified it using two other sources; cd-rom and
online.
From what I can tell, the Timer messages are getting through
correctly.
It just seems that the Animate function isn't animating the color
palette the way it should.
Does someone understand what might be (or not be) happening here ?
Thanks,
Steve
I'm completely new to GDI.
I found this simple gdi animation program in a book.
It compiles just fine, however, it does not animate.
It's just static.
It draws colored rectangles, one inside the other and the colors are
supposed to rotate inward,
creating a "tunnel" effect.
// Animate.c
// Palette animation
// Book:Programming Windows 98/NT Unleashed
// link with: gdi32.lib, user32.lib
#include <windows.h>
void Animate(HWND, HPALETTE);
void DrawCircle(HWND, HPALETTE);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
struct
{
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[12];
} palPalette =
{
0x300,
12,
{
{0xFF, 0x00, 0x00, PC_RESERVED},
{0xC0, 0x40, 0x00, PC_RESERVED},
{0x80, 0x80, 0x00, PC_RESERVED},
{0x40, 0xC0, 0x00, PC_RESERVED},
{0x00, 0xFF, 0x00, PC_RESERVED},
{0x00, 0xC0, 0x40, PC_RESERVED},
{0x00, 0x80, 0x80, PC_RESERVED},
{0x00, 0x40, 0xC0, PC_RESERVED},
{0x00, 0x00, 0xFF, PC_RESERVED},
{0x40, 0x00, 0xC0, PC_RESERVED},
{0x80, 0x00, 0x80, PC_RESERVED},
{0xC0, 0x00, 0x40, PC_RESERVED}
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
d3, int nCmdShow)
{
MSG msg;
HWND hwnd;
WNDCLASS wndClass;
if(hPrevInstance == NULL)
{
memset(&wndClass, 0, sizeof(wndClass));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = "HELLO";
if(!RegisterClass(&wndClass))
{
return FALSE;
}
}
hwnd = CreateWindow("HELLO", "HELLO", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
SetTimer(hwnd, 1, 100, NULL);
while(GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
KillTimer(hwnd, 1);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
static HPALETTE hPalette;
switch(uMsg)
{
case WM_CREATE:
hPalette = CreatePalette((LPLOGPALETTE) &palPalette);
break;
case WM_PAINT:
DrawCircle(hwnd, hPalette);
break;
case WM_TIMER:
Animate(hwnd, hPalette);
break;
case WM_DESTROY:
DeleteObject(hPalette);
hPalette = NULL;
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void DrawCircle(HWND hwnd, HPALETTE hPalette)
{
HDC hDC;
PAINTSTRUCT paintStruct;
RECT rect;
HPALETTE hOldPal;
int i;
hDC = BeginPaint(hwnd, &paintStruct);
if(hDC != NULL)
{
hOldPal = SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
GetClientRect(hwnd, &rect);
DPtoLP(hDC, (LPPOINT) &rect, 2);
for(i = 0; i < 12; i++)
{
HBRUSH hbr;
HBRUSH hbrOld;
hbr = CreateSolidBrush(PALETTEINDEX(i));
hbrOld = (HBRUSH) SelectObject(hDC, hbr);
Rectangle(hDC, MulDiv(i, rect.right, 24), MulDiv(i,
rect.bottom, 24),
rect.right - MulDiv(i, rect.right, 24),
rect.bottom - MulDiv(i, rect.bottom, 24));
SelectObject(hDC, hbrOld);
DeleteObject(hbr);
}
SelectPalette(hDC, hOldPal, FALSE);
EndPaint(hwnd, &paintStruct);
}
}
void Animate(HWND hwnd, HPALETTE hPalette)
{
HDC hDC;
PALETTEENTRY pe[12];
HPALETTE hOldPal;
static int nIndex;
int i;
for(i = 0; i < 12; i++)
{
pe[i] = palPalette.palPalEntry[(i + nIndex) % 12];
}
hDC = GetDC(hwnd);
hOldPal = SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
AnimatePalette(hPalette, 0, 12, pe);
nIndex = (++nIndex) % 12;
SelectPalette(hDC, hOldPal, FALSE);
ReleaseDC(hwnd, hDC);
}
The code is correct. I verified it using two other sources; cd-rom and
online.
From what I can tell, the Timer messages are getting through
correctly.
It just seems that the Animate function isn't animating the color
palette the way it should.
Does someone understand what might be (or not be) happening here ?
Thanks,
Steve