home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windoware
/
WINDOWARE_1_6.iso
/
source
/
3dbutn
/
odbutton.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-06
|
19KB
|
473 lines
/****************************************************************************
PROGRAM: Odbutton.c
PURPOSE: Based on Generic template for Windows applications,
but the dialog box has been modified to demonstrate an
owner-draw button that mimics the appearance of a
Windows 3.0 gray 3-dimensional style push button by using
two bitmaps and text centered in the face of the bitmaps.
FUNCTIONS:
HandleFocusState() ------ handles drawing dashed rectangle around text in
owner-draw button
HandleSelectionState() -- handles drawing button with one bitmap for "up"
and another bitmap when button is pressed.
About() ----------------- processes messages for "About" dialog box and
handles the owner-draw messages for the od button
DrawBitmap() ------------ draw the 2 bitmaps for the owner-draw button
InitApplication() ------- initializes window data and registers window
InitInstance() ---------- saves instance handle and creates main window
MainWndProc() ----------- processes messages
WinMain() --------------- calls initialization function, processes message loop
COMMENTS:
Bitmaps are display resolution specific, so to have buttons of
comparible size to non-owner-draw buttons, a pair of button "up" and
"down" bitmaps is required for each supported display resolution.
StretchBlt can have the effect of making the button's borders too thick.
Windows can have several copies of an application running at the
same time. The variable hInst keeps track of which instance this
application is so that processing will be to the correct window.
Copyright (c) 1991 Microsoft Corporation. All rights reserved.
****************************************************************************/
#include "windows.h" /* required for all Windows applications */
#include "odbutton.h" /* specific to this program */
HANDLE hInst; // current instance
POINT pt; // button bitmap's dimensions
DWORD dwRectDim; // used for text rectangle dimensions
LPDRAWITEMSTRUCT lpdis; // Long Pointer to owner-draw struct
HBITMAP hButtonBitmap, // for button's regular state bm
hButtonDown; // for button's pushed state bm
RECT rectHi, // rectangle around up button's "Hi!"
rectHiDown; // rectangle around down button's "Hi!"
int nSpaceWidth, // space between text and dashed focus
nSpaceHeight, // rectangle
nOldBkMode; // original text background mode
HDC hDC; // handle to device context of various wins
BITMAP bm; // 1 of 2 bitmaps for owner-draw button
DWORD dwSize; // size of bitmap
/*****************************************************************************
FUNCTION: HandleFocusState
PURPOSE: If button has focus, draw dashed rectangle around text in button
*****************************************************************************/
void HandleFocusState(LPDRAWITEMSTRUCT lpdis)
{
// if focus state, draw a dashed rect around text
if (lpdis->itemState & ODS_FOCUS)
{
// if selected, shift focus rect right and down 2 pixels around text
if (lpdis->itemState & ODS_SELECTED)
DrawFocusRect(lpdis->hDC, (LPRECT)&rectHiDown);
// else text centered, so focus rect will be too
else
DrawFocusRect(lpdis->hDC, (LPRECT)&rectHi);
}
return;
}
/*****************************************************************************
FUNCTION: HandleSelectedState
PURPOSE: Draw button bitmaps and text:
if button selected, draw "down"/pressed button bitmap
with text shifted right and down 2 pixels
else draw "up"/unpressed button bitmap
with text centered in button
*****************************************************************************/
void HandleSelectedState(LPDRAWITEMSTRUCT lpdis)
{
// handle button pressed down select state -- button down bitmap
// text is right & down 2 pixels
if (lpdis->itemState & ODS_SELECTED)
{
DrawBitmap(lpdis->hDC,lpdis->rcItem.left,
lpdis->rcItem.top, hButtonDown,SRCCOPY);
// put text 2 pixels right and down of center of bitmap
nOldBkMode = SetBkMode(lpdis->hDC,TRANSPARENT);
TextOut(lpdis->hDC, 2 + ((pt.x - LOWORD(dwRectDim)) >> 1),
2 + ((pt.y - HIWORD(dwRectDim)) >> 1), "Hi!", lstrlen("Hi!"));
SetBkMode(lpdis->hDC,nOldBkMode);
}
// not selected -- button up; text is in normal position
else
{
DrawBitmap(lpdis->hDC,lpdis->rcItem.left,
lpdis->rcItem.top, hButtonBitmap,SRCCOPY);
// center text in bitmap
nOldBkMode = SetBkMode(lpdis->hDC,TRANSPARENT);
TextOut(lpdis->hDC, (pt.x - LOWORD(dwRectDim) ) >> 1,
(pt.y - HIWORD(dwRectDim)) >> 1, "Hi!", lstrlen("Hi!"));
SetBkMode(lpdis->hDC,nOldBkMode);
}
return;
}
/****************************************************************************
FUNCTION: About(HWND, unsigned, WORD, LONG)
PURPOSE: Processes messages for "About" dialog box
MESSAGES:
WM_DRAWITEM - draw owner-draw button control
WM_INITDIALOG - initialize dialog box
WM_COMMAND - Input received
COMMENTS:
Demonstrates drawing owner-draw button in response to various
states (default ODA_DRAWENTIRE, ODS_SELECT, or ODS_FOCUS).
No initialization is needed for this particular dialog box, but TRUE
must be returned to Windows to indicate the message was handled.
Wait for user to click on "Ok" button, then close the dialog box.
****************************************************************************/
BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg; /* window handle of the dialog box */
unsigned message; /* type of message */
WORD wParam; /* message-specific information */
LONG lParam;
{
switch (message)
{
/* Get dimensions text rectangle and set dimensions of focus rect */
case WM_INITDIALOG:
// load bitmap
hButtonBitmap = LoadBitmap(hInst,"BUTTONBITMAP"); // regular state
hButtonDown = LoadBitmap(hInst,"BUTTONDOWN"); // pushed state
GetObject(hButtonBitmap, sizeof (BITMAP), (LPSTR) &bm);
pt.x = bm.bmWidth;
pt.y = bm.bmHeight;
// define size of dashed rectangles around text in both bitmaps
hDC = GetDC(hDlg);
dwRectDim = GetTextExtent(hDC, "Hi!", lstrlen("Hi!"));
ReleaseDC(hDlg, hDC);
nSpaceWidth = GetSystemMetrics(SM_CXBORDER) << 1;
nSpaceHeight = GetSystemMetrics(SM_CYBORDER) << 1;
rectHi.top = -nSpaceHeight + ((pt.y - HIWORD(dwRectDim)) >> 1);
rectHi.bottom = (nSpaceHeight << 1) + rectHi.top + HIWORD(dwRectDim);
rectHi.left = -nSpaceWidth + ((pt.x - LOWORD(dwRectDim)) >> 1);
rectHi.right = (nSpaceWidth << 1) + rectHi.left + LOWORD(dwRectDim);
rectHiDown.top = 2 + rectHi.top;
rectHiDown.bottom = 2 + rectHi.bottom;
rectHiDown.left = 2 + rectHi.left;
rectHiDown.right = 2 + rectHi.right;
return TRUE;
/* draw owner-draw button in all its states: normal, selected, focus */
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT)lParam; // for convenience
switch (lpdis->itemAction)
{
// handle normal drawing of button, but check if its
// selected or focus
case ODA_DRAWENTIRE:
// this handles both button down and button up
HandleSelectedState(lpdis);
// this handles focus rectangle around "Hi!"
HandleFocusState(lpdis);
return TRUE;
// handle drawing selection if needed
// selected is button down, not selected is button up
// focus will occur when button is pressed.
case ODA_SELECT:
HandleSelectedState(lpdis);
HandleFocusState(lpdis);
return TRUE;
// handle focus drawing if needed
case ODA_FOCUS:
HandleFocusState(lpdis);
return TRUE;
} //itemAction
break;
case WM_COMMAND: /* message: received a command */
if (wParam == IDD_OWNBUT) // owner-draw button selected
{
if (HIWORD(lParam) == BN_CLICKED)
{
MessageBeep(0);
MessageBeep(0);
MessageBeep(0);
}
}
else
if ((wParam == IDOK) || (wParam == IDCANCEL))
{
EndDialog(hDlg, TRUE); /* Exits the dialog box */
return TRUE;
}
break;
case WM_DESTROY:
DeleteObject(hButtonBitmap);
DeleteObject(hButtonDown);
break;
}
return FALSE; /* Didn't process a message */
}
/****************************************************************************
FUNCTION: DrawBitmap
PURPOSE: Draw default or pushed button bitmap
****************************************************************************/
void DrawBitmap(hDC, xStart, yStart, hBitmap, rop)
HDC hDC;
short xStart, yStart;
HBITMAP hBitmap;
DWORD rop;
{
HDC hMemDC;
hMemDC = CreateCompatibleDC(hDC);
SelectObject(hMemDC, hBitmap);
BitBlt(hDC, xStart, yStart, pt.x, pt.y, hMemDC, 0, 0, rop);
DeleteDC(hMemDC);
}
/****************************************************************************
FUNCTION: InitApplication(HANDLE)
PURPOSE: Initializes window data and registers window class
COMMENTS:
This function is called at initialization time only if no other
instances of the application are running. This function performs
initialization tasks that can be done once for any number of running
instances.
In this case, we initialize a window class by filling out a data
structure of type WNDCLASS and calling the Windows RegisterClass()
function. Since all instances of this application use the same window
class, we only need to do this when the first instance is initialized.
****************************************************************************/
BOOL InitApplication(hInstance)
HANDLE hInstance; /* current instance */
{
WNDCLASS wc;
/* Fill in window class structure with parameters that describe the */
/* main window. */
wc.style = NULL; /* Class style(s). */
wc.lpfnWndProc = MainWndProc; /* Function to retrieve messages for */
/* windows of this class. */
wc.cbClsExtra = 0; /* No per-class extra data. */
wc.cbWndExtra = 0; /* No per-window extra data. */
wc.hInstance = hInstance; /* Application that owns the class. */
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "odbuttonMenu"; /* Name of menu resource in .RC file. */
wc.lpszClassName = "odbuttonWClass"; /* Name used in call to CreateWindow. */
/* Register the window class and return success/failure code. */
return RegisterClass(&wc);
}
/****************************************************************************
FUNCTION: InitInstance(HANDLE, int)
PURPOSE: Saves instance handle and creates main window
COMMENTS:
This function is called at initialization time for every instance of
this application. This function performs initialization tasks that
cannot be shared by multiple instances.
In this case, we save the instance handle in a static variable and
create and display the main program window.
****************************************************************************/
BOOL InitInstance(hInstance, nCmdShow)
HANDLE hInstance; /* Current instance identifier. */
int nCmdShow; /* Param for first ShowWindow() call. */
{
HWND hWnd; /* Main window handle. */
/* Save the instance handle in static variable, which will be used in */
/* many subsequence calls from this application to Windows. */
hInst = hInstance;
/* Create a main window for this application instance. */
hWnd = CreateWindow(
"odbuttonWClass", /* See RegisterClass() call. */
"OD Button Sample Application", /* Text for window title bar. */
WS_OVERLAPPEDWINDOW, /* Window style. */
CW_USEDEFAULT, /* Default horizontal position. */
CW_USEDEFAULT, /* Default vertical position. */
CW_USEDEFAULT, /* Default width. */
CW_USEDEFAULT, /* Default height. */
NULL, /* Overlapped windows have no parent. */
NULL, /* Use the window class menu. */
hInstance, /* This instance owns this window. */
NULL /* Pointer not needed. */
);
/* If window could not be created, return "failure" */
if (!hWnd)
return FALSE;
/* Make the window visible; update its client area; and return "success" */
ShowWindow(hWnd, nCmdShow); /* Show the window */
UpdateWindow(hWnd); /* Sends WM_PAINT message */
return TRUE; /* Returns the value from PostQuitMessage */
}
/****************************************************************************
FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
PURPOSE: Processes messages
MESSAGES:
WM_COMMAND - application menu (About dialog box)
WM_DESTROY - destroy window
COMMENTS:
To process the IDM_ABOUT message, call MakeProcInstance() to get the
current instance address of the About() function. Then call DialogBox
which will create the box according to the information in the
odbutton.rc file and turn control over to the About() function. When
About returns, free the intance address.
****************************************************************************/
long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd; /* window handle */
unsigned message; /* type of message */
WORD wParam; /* additional information */
LONG lParam; /* additional information */
{
FARPROC lpProcAbout; /* pointer to the "About" function */
switch (message)
{
case WM_COMMAND: /* message: command from application menu */
switch (wParam)
{
case IDM_ABOUT:
lpProcAbout = MakeProcInstance(About, hInst);
DialogBox(hInst, /* current instance */
"AboutBox", /* resource to use */
hWnd, /* parent handle */
lpProcAbout); /* About() instance address */
FreeProcInstance(lpProcAbout);
break;
}
break;
case WM_DESTROY: /* message: window being destroyed */
PostQuitMessage(0);
break;
default: /* Passes it on if unproccessed */
return DefWindowProc(hWnd, message, wParam, lParam);
}
return NULL;
}
/****************************************************************************
FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
PURPOSE: calls initialization function, processes message loop
COMMENTS:
Windows recognizes this function by name as the initial entry point
for the program. This function calls the application initialization
routine, if no other instance of the program is running, and always
calls the instance initialization routine. It then executes a message
retrieval and dispatch loop that is the top-level control structure
for the remainder of execution. The loop is terminated when a WM_QUIT
message is received, at which time this function exits the application
instance by returning the value passed by PostQuitMessage().
If this function must abort before entering the message loop, it
returns the conventional value NULL.
****************************************************************************/
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance; /* current instance */
HANDLE hPrevInstance; /* previous instance */
LPSTR lpCmdLine; /* command line */
int nCmdShow; /* show-window type (open/icon) */
{
MSG msg; /* message */
if (!hPrevInstance) /* Other instances of app running? */
if (!InitApplication(hInstance)) /* Initialize shared things */
return FALSE; /* Exits if unable to initialize */
/* Perform initializations that apply to a specific instance */
if (!InitInstance(hInstance, nCmdShow))
return FALSE;
/* Acquire and dispatch messages until a WM_QUIT message is received. */
while (GetMessage(&msg, /* message structure */
NULL, /* handle of window receiving the message */
NULL, /* lowest message to examine */
NULL)) /* highest message to examine */
{
TranslateMessage(&msg); /* Translates virtual key codes */
DispatchMessage(&msg); /* Dispatches message to window */
}
return msg.wParam; /* Returns the value from PostQuitMessage */
}