What is so easy to do in HTML gets quite involved in C. Once you learn to look past the standard GUI overhead it becomes more obvious. This example shows the effect of the mouse cursor moving across a label by changing foreground and background colors.
Mouse-over (rollover) effect in a Windows GUI program
// show mouse-over (rollover) action on a label
// BCX created code modified for Pelles C and Dev C++
// (invalid conversions of lpfnOldProc solved by proper casting)
#include <windows.h> // in turn includes winuser.h
#define ID_Form1 0
#define ID_Label1 1
static HINSTANCE BCX_hInstance;
static int BCX_ScaleX;
static int BCX_ScaleY;
static char BCX_ClassName[2048];
static HWND Form1;
static HWND Label1;
static int Focus;
#define Show(Window) RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW);
HWND BCX_Form(char*,int=0,int=0,int=250,int=150,int=0,int=0);
HWND BCX_Label(char*,HWND,int=0,int=0,int=0,int=0,int=0,int=0,int=0);
LRESULT Set_Color (int,int,int,int);
void FormLoad (void);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK LabelProc (HWND, UINT, WPARAM, LPARAM);
// standard main for windows GUI programs
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int CmdShow)
{
WNDCLASS Wc;
MSG Msg;
// *****************************
strcpy(BCX_ClassName,"MouseOverLabel1");
// ***************************************
// Programmer has selected to use pixels
// adjust scaling accordingly
// ***************************************
BCX_ScaleX = 1;
BCX_ScaleY = 1;
BCX_hInstance = hInst;
// ******************************************************
Wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
Wc.lpfnWndProc = WndProc;
Wc.cbClsExtra = 0;
Wc.cbWndExtra = 0;
Wc.hInstance = hInst;
Wc.hIcon = LoadIcon(NULL,IDI_WINLOGO);
Wc.hCursor = LoadCursor(NULL,IDC_ARROW);
Wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
Wc.lpszMenuName = NULL;
Wc.lpszClassName = BCX_ClassName;
RegisterClass(&Wc);
FormLoad();
while(GetMessage(&Msg,NULL,0,0))
{
HWND hActiveWindow = GetActiveWindow();
if (!IsWindow(hActiveWindow) || !IsDialogMessage(hActiveWindow,&Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}
// create the windows form
HWND BCX_Form(char *Caption, int X, int Y, int W, int H, int Style, int Exstyle)
{
HWND A;
// assign default style
if (!Style)
{
Style= WS_MINIMIZEBOX |
WS_SIZEBOX |
WS_CAPTION |
WS_MAXIMIZEBOX |
WS_POPUP |
WS_SYSMENU;
}
A = CreateWindowEx(Exstyle,BCX_ClassName,Caption,
Style,
X*BCX_ScaleX,
Y*BCX_ScaleY,
(4+W)*BCX_ScaleX,
(12+H)*BCX_ScaleY,
NULL,(HMENU)NULL,BCX_hInstance,NULL);
SendMessage(A,(UINT)WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),
(LPARAM)MAKELPARAM(FALSE,0));
return A;
}
// create a label
HWND BCX_Label
(char* Text,HWND hWnd,int id,int X,int Y,int W,int H,int Style,int Exstyle)
{
HWND A;
// assign default style
if (!Style)
{
Style=WS_CHILD | SS_NOTIFY | SS_LEFT | WS_VISIBLE;
}
A = CreateWindowEx(Exstyle,"static",Text,Style,X*BCX_ScaleX, Y*BCX_ScaleY,
W*BCX_ScaleX, H*BCX_ScaleY,hWnd,(HMENU)id,BCX_hInstance,NULL);
SendMessage(A,(UINT)WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),
(LPARAM)MAKELPARAM(FALSE,0));
if (W==0)
{
HDC hdc=GetDC(A);
SIZE size;
GetTextExtentPoint32(hdc,Text,strlen(Text),&size);
ReleaseDC(A,hdc);
MoveWindow(A,X*BCX_ScaleX,Y*BCX_ScaleY,size.cx,size.cy,TRUE);
}
return A;
}
LRESULT Set_Color (int TxtColr,int BkColr,int wParam,int lParam)
{
static HBRUSH ReUsableBrush;
SetTextColor((HDC)wParam,TxtColr);
if (BkColr==-1)
{
BkColr=GetClassLong(GetParent((HWND)lParam),GCL_HBRBACKGROUND);
if (BkColr>31)
{
SetBkMode((HDC)wParam,TRANSPARENT);
return BkColr;
}
else
BkColr=GetSysColor(BkColr-1);
}
DeleteObject(ReUsableBrush);
ReUsableBrush=CreateSolidBrush(BkColr);
SetBkColor((HDC)wParam,BkColr);
return (LRESULT)ReUsableBrush;
}
// details like corner coordinates, width, height ...
void FormLoad (void)
{
Form1=BCX_Form("Mouse-over Label ...",80,88,320,102);
Label1=BCX_Label("Move the mouse over me!",Form1,ID_Label1,32,24,250,28);
// setup callback functions
SetProp(Label1,"oldproc",(HANDLE)GetWindowLong(Label1,GWL_WNDPROC));
SetWindowLong(Label1,GWL_WNDPROC,(DWORD)LabelProc);
Show(Form1);
}
// standard windows message handler
LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
while(1)
{
if (Msg==WM_MOUSEMOVE)
{
if (Focus)
{
Focus=FALSE;
InvalidateRect(Label1,0,TRUE);
}
break;
}
if (Msg==WM_CTLCOLORSTATIC)
{
static int cFG;
memset(&cFG,0,sizeof(cFG));
static int cBG;
memset(&cBG,0,sizeof(cBG));
if ((HANDLE)lParam==Label1)
{
if (Focus)
{
cFG=RGB(0,0,0); // black text
cBG=RGB(255,255,0); // label bg = yellow
}
else
{
cFG=RGB(255,255,255); // white text
cBG=RGB(0,0,255); // label bg = blue
}
if ((HWND)lParam==Label1 && Msg==WM_CTLCOLORSTATIC)
return Set_Color(cFG,cBG,wParam,lParam);
}
break;
}
if (Msg==WM_CLOSE)
{
DestroyWindow(Form1);
return 0;
}
break;
}
// clean up and exit program
if (Msg==WM_DESTROY)
{
UnregisterClass(BCX_ClassName,BCX_hInstance);
PostQuitMessage(0);
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}
// the label events
LRESULT CALLBACK LabelProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static FARPROC lpfnOldProc;
memset(&lpfnOldProc,0,sizeof(lpfnOldProc));
static LRESULT lResult;
memset(&lResult,0,sizeof(lResult));
lpfnOldProc=(FARPROC)GetProp(hWnd,"oldproc"); // cast to FARPROC
while(1)
{
if (Msg==WM_MOUSEMOVE)
{
if (!Focus)
{
Focus=TRUE;
InvalidateRect(Label1,0,TRUE);
}
break;
}
// clean up
if (Msg==WM_DESTROY)
{
SetWindowLong(hWnd,GWL_WNDPROC,(DWORD)GetProp(hWnd,"oldproc"));
RemoveProp(hWnd,"oldproc");
// cast to WNDPROC
return CallWindowProc((WNDPROC)lpfnOldProc,hWnd,Msg,wParam,lParam);
}
break;
}
// cast to WNDPROC
return CallWindowProc((WNDPROC)lpfnOldProc,hWnd,Msg,wParam,lParam);
}
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.