// **************************************************
// * NAME = SPIN.C *
// * DEV. PLATFORM= Turbo C++,v3.1 for Windows *
// * MEMORY MODEL = SMALL *
// * Demo. program for creating/using spin controls.*
// * Keith E. Bugg, TRISTAR SYSTEMS, Inc *
// **************************************************
#define OEMRESOURCE // MUST define BEFORE <windows.h>
#define DAY_CTRL 100// Ctrl IDs for day editbox ctrl.
#define MONTH_CTRL 200 // ID for month combobox ctrl.
#define YEAR_CTRL 300 // ID for year editbox ctrl.
#include <windows.h>// must have Windows header file
#include <stdio.h> // get basic prototypes
#include <stdlib.h> // for 'itoa()', etc.
/* declare prototypes here */
long FAR PASCAL _export SpinProc(HWND, unsigned,
WORD, LONG);
BOOL FAR PASCAL DateDialog(HWND ,WORD,WORD ,LONG );
//
// GLOBAL VARIABLES HERE
//
HDC hDC; // handle to output Display Context
int day,month,year;
char *months[]= {"January","Febuary","March","April",
"May","June","July","August","September","October",
"November" ,"December"};
int max_days[]= {31,28,31,30,31,30,31,31.30,31,30,31};
char dayval[3],yearval[5];
// **************************************************
// end var. decl., etc. Now do message handler for
// the main window of the spin control demo program
// **************************************************
//
long FAR PASCAL_export SpinProc(HWND hWnd,
unsigned message,WORD wParam, LONG lParam)
{
PAINTSTRUCT ps; // Paint Struct for BeginPaint call
int i; // general purpose variable
HINSTANCE hInstance;
FARPROC lpfnDlgProc;
// --------- end local variables ---------------
//
switch (message) // process messages here
{
case WM_CLOSE: // Exit via system menu
MessageBeep(0); // Warning beep
i= MessageBox(hWnd,
"Are you sure you want to Exit?",
"EXIT",MB_OKCANCEL | MB_ICONEXCLAMATION);
if(i == IDOK) // really wants to exit
{ //queue up a QUIT msg
PostMessage(hWnd,WM_QUIT,0,0);
return 0L;
}
break;
case WM_COMMAND: // check for system message
switch(wParam)
{
case SC_MINIMIZE: // on minimize
ShowWindow(hWnd,SW_SHOWMINIMIZED);
break;
case SC_MAXIMIZE: // on maximize
MessageBeep(0); //stub
ShowWindow(hWnd,SW_SHOWMAXIMIZED);
break;
case SC_RESTORE: // on restore
ShowWindow(hWnd,SW_SHOW);
break;
//
// here is user clicks the sub-menu
// option "Run Demo" from drop-down
case 100: // Run Demo menu option
hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
lpfnDlgProc= MakeProcInstance(DateDialog,hInstance);
DialogBox(hInstance,"DIALOG_1", hWnd,lpfnDlgProc);
break;
default:
break;
}
break;
case WM_QUIT: // QUIT & DESTROY messages
case WM_DESTROY:
return (0L);
default: // message is of no interest
return (DefWindowProc(hWnd, message,
wParam, lParam));
}
return (NULL);
} /* end SpinProc() */
#pragma argsused // TC++ compiler directive
//
// next comes WinMain, which builds demo window
//
// ****************************************************
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE
hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
MSG msg; // message
WNDCLASS wc;
static HWND hWnd;
//
//------------------------------------------------
//
if (!hPrevInstance) // Other instances running?
{
// Fill in window class structure with
// parameters that describe the main window.
//
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc=(long(FAR PASCAL*)())SpinProc;
wc.cbClsExtra = 0; // No per-class extra data.
wc.cbWndExtra = 0; // No per-window extra data.
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, "spin");;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(
RGB(100,255,255)); // cyan background
wc.lpszMenuName = "MAIN_MENU";
wc.lpszClassName = "SPIN";
// Register the window class and return
// success/failure code.
if(!RegisterClass(&wc))
return 0;
// Create main window for application instance.
hWnd = CreateWindow(
"SPIN", // See RegisterClass() call.
"Spin Controls",// Text for title bar.
WS_MAXIMIZE | WS_SYSMENU | WS_MINIMIZEBOX |
WS_MAXIMIZEBOX | WS_THICKFRAME |
WS_OVERLAPPEDWINDOW,// Window's styles..
0, // horizontal position.
0, // vertical position.
600, // Default width.
400, // Default height.
NULL, // no parent.
NULL, // No menu bar (later)
hInstance, // inst. owns window.
NULL // Pointer not needed.
);
//
// If CreateWindow failed, return "failure" */
if (!hWnd)
{
MessageBeep(0);
MessageBox(hWnd,"Could not create window!",
"ERROR",MB_OK);
return 0;
}
// Make window visible; update its client area
nCmdShow= SW_SHOWNORMAL; // Show normal size
ShowWindow(hWnd,nCmdShow ); // Show the window
UpdateWindow(hWnd); // Send WM_PAINT
}
// Acquire and dispatch messages until a
// WM_QUIT message is received.
while (GetMessage(&msg, // message structure
NULL, // window handle rec. msg
NULL, // lowest msg. to examine
NULL)) // highest msg. to examine
{
TranslateMessage(&msg); // Translates msgs.
DispatchMessage(&msg); // Dispatches msgs.
}
return (msg.wParam); // Returns the value
// from PostQuitMessage
} // end WinMain()
BOOL FAR PASCAL DateDialog(HWND hDlg,WORD wMessage,
WORD wParam, LONG lParam)
{
static HWND hDay,hCombo,hYear;
HANDLE hInstance; // app. instance
//
// decl. rectangles for bit maps
//
static RECT day_up,day_down,year_up, year_down;
static HDC hMemDC; // handle to memory DC
static BITMAP bm; // for loading bit maps
static HBITMAP hUp,hDown; // bit map handles
MSG msg; // message struct. for slewing
int k, mon_max; // mon_max is max # days in month
static int bmWidth, bmHeight; // bit map size
POINT pt; // for finding mouse click in rects.
//
switch(wMessage)
{
// initialize dialog box here
case WM_INITDIALOG:
hInstance = GetWindowWord(hDlg,
GWW_HINSTANCE);
//
// create Day edit box as child window
//
hDay = CreateWindow("EDIT", NULL,
ES_LEFT | ES_READONLY | WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP,
40, 55, 50, 25, hDlg, DAY_CTRL, hInstance, NULL);
//
// create Month combobox as child window
//
hCombo = CreateWindow("COMBOBOX",NULL,
WS_CHILD | WS_VSCROLL | WS_TABSTOP
| CBS_DROPDOWN | CBS_HASSTRINGS,
175, 55, 120, 150,hDlg,MONTH_CTRL,
hInstance,NULL);
//
// create Year edit box as child window
//
hYear = CreateWindow("EDIT",NULL,ES_LEFT |
ES_READONLY | WS_CHILD | WS_VISIBLE
| WS_BORDER | WS_TABSTOP,
310,55,70,25,hDlg,YEAR_CTRL,
hInstance,NULL);
ShowWindow(hYear,SW_SHOWNORMAL);
//
// init. combobox with names of months
//
for(k=0; k < 12; k++)
SendMessage(hCombo,CB_ADDSTRING,0,(DWORD)(LPSTR)months[k]);
ShowWindow(hCombo,SW_SHOWNORMAL);
//
// Load the Microsoft-supplied arrows here
//
hUp = LoadBitmap(NULL,OBM_UPARROW);
hDown = LoadBitmap(NULL,OBM_DNARROW);
//
// Get the height & width of the up/down
// arrows supplied by Microsoft. Use
// this to set up rectangles upon which
// the arrows will be "pasted". When
// user clicks mouse inside one of these
// rectangles, we change the day/year
//
GetObject(hUp, sizeof(BITMAP), &bm);
// get size of up/down arrow (same)
bmWidth = bm.bmWidth;
bmHeight = bm.bmHeight;
//
// memory handle to DC; !** IMPORTANT **!
//
hMemDC = CreateCompatibleDC(hDC);
//
// init. the "Day" and "Year" edit boxes
// set to date 15-Jan-1993
//
day= 15; // set day to 15
SetDlgItemText(hDlg,DAY_CTRL,"15");
//
// do month here
//
month= 0; // January
SendMessage(hCombo,CB_SELECTSTRING,0,
(DWORD)(LPSTR)months[month]);
//
//
year= 1993; // set year to 1993
SetDlgItemText(hDlg,YEAR_CTRL,"1993");
//
// define rect. for the "Day" up arrow
// ***********************************
day_up.left=105;
day_up.top= 56;
day_up.right= 105+bmWidth;
day_up.bottom= day_up.top+bmHeight;
//
// now do down arrow for "Day"
//
day_down.left=105;
day_down.top= 74;
day_down.right= 105+bmWidth;
day_down.bottom= day_down.top+bmHeight;
//
// define rect. for the "Year" up arrow
//
year_up.left= 395;
year_up.top= 56;
year_up.right= 395+bmWidth;
year_up.bottom= year_up.top+bmHeight;
//
// do down arrow for "Year"
//
year_down.left= 395;
year_down.top= 74;
year_down.right= 395+bmWidth;
year_down.bottom= year_down.top+bmHeight;
return (TRUE);
//
// do paint message here
//
case WM_PAINT:
//
// get handle to display context
//
hDC= GetDC(hDlg);
//
// now "paste" the up/down arrow bitmap
// into position. Note: the coordinates
// are hard-coded, not as parameters
//
SelectObject(hMemDC,hUp);
BitBlt(hDC,105,56,bmWidth,bmHeight,hMemDC,
0,0,SRCCOPY); // day up
BitBlt(hDC,395,56,bmWidth,bmHeight,hMemDC,
0,0,SRCCOPY); // year up
//
SelectObject(hMemDC,hDown);
BitBlt(hDC,105,74,bmWidth,bmHeight,hMemDC,
0,0,SRCCOPY); // day down
BitBlt(hDC,395,74,bmWidth,bmHeight,hMemDC,
0,0,SRCCOPY); // year down
ReleaseDC(hDlg,hDC); // release DC
break;
//
// end paint message
//
case WM_CLOSE:
//
// *** Release memory back to Windows ***
//
DeleteDC(hMemDC);
DeleteObject(hUp);
DeleteObject(hDown);
EndDialog(hDlg,0); // close dialog box
return (TRUE);
//
// user clicked left button here
//
case WM_LBUTTONDOWN:
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
//
// Was click in day up bit map?
//
if(PtInRect(&day_up,pt))
{
++day; // user wants to increase day
//
// get month, then max days for that
// month.check for leap year, too
//
month = (WORD) SendMessage(hCombo,
CB_GETCURSEL,0,0L);
mon_max= max_days[month];
//
// check for leap year here
//
if(month == 1) // 0=Jan, 1= Feb, etc
{
// need to get year
if((year % 4 == 0 && year % 100 != 0) || year % 400 ==0)
max_days[1]= 29;// lp yr.
}
if(day > mon_max)
day = 1;
itoa(day,dayval,10);
// Update edit box with new day
SetDlgItemText(hDlg,DAY_CTRL,dayval);
}
//
// see if click in day down arrow
//
if(PtInRect(&day_down,pt))
{
--day; // user wants to decrease day
if(day < 1)
day = 1;
itoa(day,dayval,10);
// Update edit box with new day
SetDlgItemText(hDlg,DAY_CTRL,dayval);
}
//
// see if click in year up arrow
//
if(PtInRect(&year_up,pt))
{
++year; // incr. year & check range
if(year > 2200)
year = 2200;
itoa(year,yearval,10);
// Update edit box with new year
SetDlgItemText(hDlg,YEAR_CTRL,yearval);
}
//
// see if click in year down arrow
//
if(PtInRect(&year_down,pt))
{
--year; // decr. year & check range
if(year < 1800)
year = 1800;
itoa(year,yearval,10);
// Update edit box with new year
SetDlgItemText(hDlg,YEAR_CTRL,yearval);
}
break;
case WM_RBUTTONDOWN: // right button slewing
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
//
// Is cursor in year up rectangle?
//
if(PtInRect(&year_up,pt))
{
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
pt = msg.pt;
ScreenToClient(hDlg,&pt);
if(!PtInRect(&year_up,pt))
{ // user moved out of box
break;
}
if(msg.message== WM_RBUTTONUP)
break;
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
++year; // increment year
if(year > 2200) // check range
year = 1993;// default to 1993
itoa(year,yearval,10);
// Update edit box with new year
SetDlgItemText(hDlg, YEAR_CTRL, yearval);
} // end while loop for slewing
} // end if slewed year up
//
// now check for slewing year down
//
if(PtInRect(&year_down,pt))
{
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
pt = msg.pt;
ScreenToClient(hDlg,&pt);
if(!PtInRect(&year_down,pt))
{ // user moved out of box
break;
}
if(msg.message== WN_RBUTTONUP)
break;
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
--year; // decrement year
if(year < 1800) // check range
year = 1800;
itoa(year,yearval,10);
// Update edit box with new year
SetDlgItemText(hDlg, YEAR_CTRL, yearval);
} // end while loop for slewing down
} // end if year down was slewed
break;
} // end switch on messages
return (FALSE);
} // end DateDialog()
//
// end spin.c
//
// End of File