Scroller: C/C++ Version
Scroller uses the Windows API PeekMessage() function to implement the animation-based message loop. PeekMessage() checks the Windows message queue for any pending messages. If any messages are available, the message loop calls TranslateMessage() and DispatchMessage() as usual to process the message. However, if no messages are waiting, we call our Scroll() function to perform one iteration of the scroll.
/****************************************************************************\
* *
* Scroller.c *
* *
* This program demonstrates circular scrolling within a virtual buffer. *
* *
* Because fg_scroll() requires a "hidden" virtual buffer to save and then *
* restore portions of the area being scrolled, we create a second virtual *
* buffer for this purpose. *
* *
\****************************************************************************/
#include <fgwin.h>
#define vbWidth 320
#define vbHeight 200
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
void Scroll(void);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdParam, int iCmdShow)
{
static char szAppName[] = "FGscroller";
HWND hWnd;
MSG msg;
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
RegisterClassEx(&wndclass);
hWnd = CreateWindow(szAppName, // window class name
"Scrolling Demo", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hWnd,iCmdShow);
UpdateWindow(hWnd);
// The message loop processes entries placed in the message queue.
// When no message is ready, call Scroll() to perform one frame of
// animation.
while (TRUE)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
Scroll();
}
return msg.wParam;
}
/****************************************************************************\
* *
* WindowProc() *
* *
\****************************************************************************/
HDC hDC;
HPALETTE hPal;
int hVB1, hVB2;
UINT cxClient, cyClient;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (iMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
fg_setdc(hDC);
hPal = fg_defpal();
fg_realize(hPal);
fg_vbinit();
hVB1 = fg_vballoc(vbWidth,vbHeight);
hVB2 = fg_vballoc(vbWidth,vbHeight);
fg_vbopen(hVB2);
fg_vbcolors();
fg_vbopen(hVB1);
fg_vbcolors();
fg_sethpage(hVB2);
fg_setcolor(19);
fg_fillpage();
fg_setcolor(25);
fg_rect(132,188,50,150);
fg_setcolor(20);
fg_move(160,67);
fg_draw(175,107);
fg_draw(140,82);
fg_draw(180,82);
fg_draw(145,107);
fg_draw(160,67);
fg_paint(160,77);
fg_paint(150,87);
fg_paint(160,87);
fg_paint(170,87);
fg_paint(155,97);
fg_paint(165,97);
return 0;
case WM_PAINT:
BeginPaint(hWnd,&ps);
fg_vbscale(0,vbWidth-1,0,vbHeight-1,0,cxClient-1,0,cyClient-1);
EndPaint(hWnd,&ps);
return 0;
case WM_SETFOCUS:
fg_realize(hPal);
InvalidateRect(hWnd,NULL,TRUE);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_DESTROY:
fg_vbclose();
fg_vbfree(hVB1);
fg_vbfree(hVB2);
fg_vbfin();
DeleteObject(hPal);
ReleaseDC(hWnd,hDC);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,iMsg,wParam,lParam);
}
/****************************************************************************\
* *
* Scroll() *
* *
* The Scroll() function moves the scrolling region up four pixels in a *
* circular manner. It is called from the message loop in WinMain() when no *
* messages are waiting. *
* *
\****************************************************************************/
void Scroll()
{
fg_scroll(136,184,50,150,-4,0);
fg_vbscale(0,vbWidth-1,0,vbHeight-1,0,cxClient-1,0,cyClient-1);
}
|