home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_04 / bugg / spin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-08  |  13.8 KB  |  503 lines

  1. //    *** LISTING 1
  2. //  **************************************************
  3. //  * NAME = SPIN.C                                  *
  4. //  * DEV. PLATFORM=  Turbo C++,v3.1 for Windows     *
  5. //    * MEMORY MODEL =  SMALL                          *
  6. //    * Demo. program for creating/using spin controls.*
  7. //  * Keith E. Bugg, TRISTAR SYSTEMS, Inc            *
  8. //  **************************************************
  9. #define OEMRESOURCE    // MUST define BEFORE <windows.h>
  10. #define DAY_CTRL 100// Ctrl IDs for day editbox ctrl.
  11. #define MONTH_CTRL 200    // ID for month combobox ctrl.
  12. #define YEAR_CTRL 300    // ID for year editbox ctrl.
  13. #include <windows.h>// must have Windows header file
  14. #include <stdio.h>    // get basic prototypes
  15. #include <stdlib.h>    // for 'itoa()', etc.
  16.  
  17.         /* declare prototypes here  */
  18. long FAR PASCAL _export SpinProc(HWND, unsigned,
  19.     WORD, LONG);
  20. BOOL FAR PASCAL DateDialog(HWND ,WORD,WORD ,LONG );
  21. //
  22. //      GLOBAL VARIABLES HERE
  23. //
  24. HDC hDC;        // handle to output Display Context
  25. int day,month,year;
  26. char *months[]= {"January","Febuary","March","April",
  27.     "May","June","July","August","September","October",
  28.     "November" ,"December"};
  29. int max_days[]= {31,28,31,30,31,30,31,31.30,31,30,31};
  30. char dayval[3],yearval[5];
  31. //  **************************************************
  32. //    end var. decl., etc.  Now do message handler for
  33. //    the main window of the spin control demo program
  34. //  **************************************************
  35. //
  36. long FAR PASCAL _export SpinProc(HWND hWnd,
  37.     unsigned message,WORD wParam, LONG lParam)
  38. {
  39.     PAINTSTRUCT ps; // Paint Struct for BeginPaint call
  40.     int i;                    // general purpose variable
  41.     HINSTANCE hInstance;
  42.     FARPROC lpfnDlgProc; 
  43.     // --------- end local variables ---------------
  44.     //
  45.     switch (message)    // process messages here
  46.     {
  47.  
  48.         case WM_CLOSE:     //  Exit via system menu
  49.             MessageBeep(0);        // Warning beep
  50.             i= MessageBox(hWnd,
  51.             "Are you sure you want to Exit?",
  52.             "EXIT",MB_OKCANCEL | MB_ICONEXCLAMATION);
  53.             if(i == IDOK)      // really wants to exit 
  54.             {                  // queue up a QUIT msg
  55.                 PostMessage(hWnd,WM_QUIT,0,0); 
  56.                 return 0L;
  57.             }
  58.                break;
  59.     
  60.         case WM_COMMAND:     // check for system message
  61.             switch(wParam)
  62.             {
  63.                 case SC_MINIMIZE:   //  on minimize
  64.                     ShowWindow(hWnd,SW_SHOWMINIMIZED);
  65.                     break;
  66.             
  67.                 case SC_MAXIMIZE:   //  on maximize
  68.                     MessageBeep(0); //stub
  69.                     ShowWindow(hWnd,SW_SHOWMAXIMIZED);
  70.                     break;
  71.  
  72.                 case SC_RESTORE:    //  on restore
  73.                     ShowWindow(hWnd,SW_SHOW);
  74.                     break;
  75.                 //
  76.                 //    here is user clicks the sub-menu
  77.                 //    option "Run Demo" from drop-down
  78.                 case 100:    //  Run Demo menu option
  79.                     hInstance = GetWindowWord(hWnd,
  80.                         GWW_HINSTANCE);
  81.                     lpfnDlgProc= MakeProcInstance(
  82.                         DateDialog,hInstance);
  83.                     DialogBox(hInstance,"DIALOG_1",
  84.                         hWnd,lpfnDlgProc);
  85.                     break;
  86.  
  87.                 default:
  88.                     break;
  89.             }
  90.             break;
  91.         
  92.         case WM_QUIT:       // QUIT & DESTROY messages
  93.         case WM_DESTROY: 
  94.             return (0L);
  95.  
  96.         default:          // message is of no interest
  97.             return (DefWindowProc(hWnd, message,
  98.                 wParam, lParam));
  99.     }
  100.     return (NULL);
  101. }       /* end SpinProc()    */
  102.  
  103. #pragma argsused        // TC++ compiler directive
  104. //
  105. //    next comes WinMain, which builds demo window
  106. //
  107. //****************************************************
  108. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE
  109.     hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
  110. {
  111.     MSG msg;            // message
  112.     WNDCLASS  wc;
  113.     static HWND hWnd;
  114.     //
  115.     // ----------------------------------------------
  116.     //
  117.     
  118.     if (!hPrevInstance) // Other instances running?
  119.     {
  120.         // Fill in window class structure with
  121.         // parameters that describe the main window.
  122.         //
  123.         wc.style = CS_HREDRAW | CS_VREDRAW;  
  124.         wc.lpfnWndProc=(long(FAR PASCAL*)())SpinProc;
  125.         wc.cbClsExtra = 0; // No per-class extra data.
  126.         wc.cbWndExtra = 0; // No per-window extra data.
  127.         wc.hInstance = hInstance;
  128.         wc.hIcon = LoadIcon(hInstance, "spin");;
  129.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  130.         wc.hbrBackground = CreateSolidBrush(
  131.             RGB(100,255,255)); // cyan background
  132.         wc.lpszMenuName = "MAIN_MENU";
  133.         wc.lpszClassName = "SPIN";
  134.  
  135.         // Register the window class and return
  136.         // success/failure code. 
  137.  
  138.         if(!RegisterClass(&wc))
  139.             return 0;
  140.  
  141.         // Create main window for application instance.
  142.  
  143.         hWnd = CreateWindow(
  144.             "SPIN",       // See RegisterClass() call.
  145.             "Spin Controls",// Text for title bar.
  146.             WS_MAXIMIZE | WS_SYSMENU | WS_MINIMIZEBOX |
  147.             WS_MAXIMIZEBOX | WS_THICKFRAME |
  148.             WS_OVERLAPPEDWINDOW,// Window's styles..
  149.             0,                     // horizontal position.
  150.             0,                    // vertical position.
  151.             600,                  // Default width.
  152.             400,                 // Default height.
  153.             NULL,               // no parent.
  154.             NULL,               // No menu bar (later)
  155.             hInstance,          // inst. owns window.
  156.             NULL                // Pointer not needed.
  157.             );               
  158.         //
  159.         // If CreateWindow failed, return "failure" */
  160.         if (!hWnd)
  161.         {        
  162.             MessageBeep(0);
  163.             MessageBox(hWnd,"Could not create window!",
  164.                 "ERROR",MB_OK);
  165.             return 0;
  166.         }
  167.  
  168.         // Make window visible; update its client area
  169.  
  170.         nCmdShow= SW_SHOWNORMAL;    // Show normal size
  171.         ShowWindow(hWnd,nCmdShow ); // Show the window
  172.         UpdateWindow(hWnd);         // Send WM_PAINT 
  173.         
  174.     }
  175.     //     Acquire and dispatch messages until a
  176.     //    WM_QUIT message is received.
  177.  
  178.     while (GetMessage(&msg, // message structure
  179.         NULL,               // window handle rec. msg
  180.         NULL,               // lowest msg. to examine
  181.         NULL))              // highest msg. to examine
  182.     {
  183.         TranslateMessage(&msg); // Translates msgs.
  184.         DispatchMessage(&msg);  // Dispatches msgs. 
  185.     }
  186.     return (msg.wParam);    // Returns the value
  187.                             // from PostQuitMessage
  188. }               // end WinMain()
  189.  
  190. BOOL FAR PASCAL DateDialog(HWND hDlg,WORD wMessage,
  191.     WORD wParam, LONG lParam)
  192. {
  193.     static HWND hDay,hCombo,hYear;
  194.     HANDLE hInstance;    // app. instance
  195.     //
  196.     //    decl. rectangles for bit maps
  197.     //
  198.     static RECT day_up,day_down,year_up, year_down;
  199.     static HDC hMemDC;    // handle to memory DC        
  200.     static BITMAP bm;    // for loading bit maps
  201.     static HBITMAP    hUp,hDown;    // bit map handles
  202.     MSG msg;        // message struct. for slewing
  203.     int k, mon_max;    // mon_max is max # days in month    
  204.     static int bmWidth, bmHeight; // bit map size
  205.     POINT pt;    // for finding mouse click in rects.
  206.     //
  207.     switch(wMessage)
  208.     {
  209.         // initialize dialog box here
  210.         case WM_INITDIALOG:        
  211.             hInstance = GetWindowWord(hDlg,
  212.                 GWW_HINSTANCE);
  213.             //
  214.             //    create Day edit box as child window
  215.             //
  216.             hDay = CreateWindow("EDIT",NULL,ES_LEFT |
  217.                    ES_READONLY | WS_CHILD | WS_BORDER
  218.                    | WS_VISIBLE | WS_TABSTOP,40,55,50,
  219.                    25,hDlg,DAY_CTRL,hInstance,NULL);
  220.             //
  221.             //    create Month combobox as child window
  222.             //
  223.             hCombo = CreateWindow("COMBOBOX",NULL,
  224.                      WS_CHILD | WS_VSCROLL | WS_TABSTOP
  225.                      | CBS_DROPDOWN | CBS_HASSTRINGS,
  226.                      175, 55, 120, 150,hDlg,MONTH_CTRL,
  227.                      hInstance,NULL);
  228.             //
  229.             //    create Year edit box as child window
  230.             //
  231.             hYear = CreateWindow("EDIT",NULL,ES_LEFT |
  232.                     ES_READONLY | WS_CHILD | WS_VISIBLE
  233.                     | WS_BORDER | WS_TABSTOP,
  234.                     310,55,70,25,hDlg,YEAR_CTRL,
  235.                     hInstance,NULL);
  236.             ShowWindow(hYear,SW_SHOWNORMAL);
  237.             //
  238.             // init. combobox with names of months
  239.             //
  240.             for(k=0; k < 12; k++)    
  241.                 SendMessage(hCombo,CB_ADDSTRING,0,
  242.                     (DWORD)(LPSTR)months[k]);
  243.                 
  244.             ShowWindow(hCombo,SW_SHOWNORMAL);
  245.             //
  246.             // Load the Microsoft-supplied arrows here
  247.             //
  248.             hUp = LoadBitmap(NULL,OBM_UPARROW);
  249.             hDown = LoadBitmap(NULL,OBM_DNARROW); 
  250.             //
  251.             //    Get the height & width of the up/down
  252.             //  arrows supplied by Microsoft.  Use
  253.             //  this to set up rectangles upon which
  254.             //    the arrows will be "pasted".  When
  255.             //  user clicks mouse inside one of these
  256.             //  rectangles, we change the day/year
  257.             //  
  258.             GetObject(hUp, sizeof(BITMAP), &bm);
  259.             // get size of up/down arrow (same)
  260.             bmWidth = bm.bmWidth;    
  261.                bmHeight= bm.bmHeight;
  262.             //
  263.             // memory handle to DC; !** IMPORTANT **!
  264.             //
  265.             hMemDC = CreateCompatibleDC(hDC);    
  266.             //
  267.             //    init. the "Day" and "Year" edit boxes
  268.             //  set to date 15-Jan-1993
  269.             //
  270.             day= 15;        // set day to 15
  271.             SetDlgItemText(hDlg,DAY_CTRL,"15");
  272.             //
  273.             //    do month here
  274.             //
  275.             month= 0;        // January
  276.             SendMessage(hCombo,CB_SELECTSTRING,0,
  277.                 (DWORD)(LPSTR)months[month]);
  278.             //
  279.             //
  280.             year= 1993;        // set year to 1993
  281.             SetDlgItemText(hDlg,YEAR_CTRL,"1993");  
  282.             //
  283.             //    define rect. for the "Day" up arrow
  284.             //  ***********************************
  285.             day_up.left=105;
  286.             day_up.top= 56;
  287.             day_up.right= 105+bmWidth;
  288.             day_up.bottom= day_up.top+bmHeight; 
  289.             //
  290.             // now do down arrow for "Day"
  291.             //
  292.             day_down.left=105;
  293.             day_down.top= 74;
  294.             day_down.right= 105+bmWidth;
  295.             day_down.bottom= day_down.top+bmHeight;
  296.             //
  297.             //    define rect. for the "Year" up arrow
  298.             //
  299.             year_up.left= 395;
  300.             year_up.top= 56;
  301.             year_up.right= 395+bmWidth;
  302.             year_up.bottom= year_up.top+bmHeight; 
  303.             //
  304.             // do down arrow for "Year"
  305.             //
  306.             year_down.left= 395;
  307.             year_down.top= 74;
  308.             year_down.right= 395+bmWidth;
  309.             year_down.bottom= year_down.top+bmHeight;
  310.             
  311.             return (TRUE);
  312.             //
  313.             //    do paint message here
  314.             //
  315.         case WM_PAINT:
  316.             //
  317.             // get handle to display context
  318.             //
  319.             hDC= GetDC(hDlg);
  320.             //
  321.             // now "paste" the up/down arrow bitmap
  322.             // into position.  Note:  the coordinates
  323.             // are hard-coded, not as parameters
  324.             //
  325.             SelectObject(hMemDC,hUp);
  326.             BitBlt(hDC,105,56,bmWidth,bmHeight,hMemDC,
  327.                 0,0,SRCCOPY);  // day up
  328.             BitBlt(hDC,395,56,bmWidth,bmHeight,hMemDC,
  329.                 0,0,SRCCOPY);  // year up
  330.             //
  331.             SelectObject(hMemDC,hDown);
  332.             BitBlt(hDC,105,74,bmWidth,bmHeight,hMemDC,
  333.                 0,0,SRCCOPY);  // day down
  334.             BitBlt(hDC,395,74,bmWidth,bmHeight,hMemDC,
  335.                 0,0,SRCCOPY);  // year down
  336.  
  337.                ReleaseDC(hDlg,hDC);    // release DC
  338.             break;
  339.             //
  340.             // end paint message
  341.             //
  342.         case WM_CLOSE:
  343.             //
  344.             // *** Release memory back to Windows ***
  345.             //
  346.             DeleteDC(hMemDC);    
  347.             DeleteObject(hUp); 
  348.             DeleteObject(hDown);
  349.             EndDialog(hDlg,0);    // close dialog box
  350.             return (TRUE);
  351.             //
  352.             //    user clicked left button here
  353.             //
  354.         case WM_LBUTTONDOWN:
  355.             pt.x = LOWORD(lParam);
  356.             pt.y = HIWORD(lParam);
  357.             //
  358.             //    Was click in day up bit map?
  359.             //
  360.             if(PtInRect(&day_up,pt))
  361.             {
  362.                 ++day;    // user wants to increase day
  363.                 //
  364.                 //    get month, then max days for that
  365.                 //    month.check for leap year, too
  366.                 //
  367.                 month = (WORD) SendMessage(hCombo,
  368.                          CB_GETCURSEL,0,0L);
  369.                 mon_max= max_days[month];
  370.                 //
  371.                 //    check for leap year here
  372.                 //
  373.                 if(month == 1)    // 0=Jan, 1= Feb, etc
  374.                 {
  375.                     // need to get year
  376.                     if((year % 4 == 0 && year % 100
  377.                         != 0) || year % 400 ==0)
  378.                             max_days[1]= 29;// lp yr.
  379.                 }
  380.                 if(day > mon_max)  
  381.                     day = 1;            
  382.                 itoa(day,dayval,10);
  383.                 //    Update edit box with new day
  384.                 SetDlgItemText(hDlg,DAY_CTRL,dayval);
  385.             }
  386.             //
  387.             //    see if click in day down arrow
  388.             //
  389.             if(PtInRect(&day_down,pt))
  390.             {
  391.                 --day;    // user wants to decrease day
  392.                 if(day < 1)
  393.                     day = 1;
  394.                 itoa(day,dayval,10);
  395.                 //    Update edit box with new day
  396.                 SetDlgItemText(hDlg,DAY_CTRL,dayval);
  397.             }
  398.             //
  399.             //    see if click in year up arrow
  400.             //
  401.             if(PtInRect(&year_up,pt))
  402.             {
  403.                 ++year;    // incr. year & check range
  404.                 if(year > 2200)  
  405.                     year = 2200;    
  406.                 itoa(year,yearval,10);
  407.                 //    Update edit box with new year
  408.                 SetDlgItemText(hDlg,YEAR_CTRL,yearval);
  409.             }
  410.             //
  411.             //    see if click in year down arrow
  412.             //
  413.             if(PtInRect(&year_down,pt))
  414.             {
  415.                 --year;    // decr. year & check range
  416.                 if(year < 1800)
  417.                     year = 1800;    
  418.                 itoa(year,yearval,10);
  419.                 //    Update edit box with new year
  420.                 SetDlgItemText(hDlg,YEAR_CTRL,yearval);
  421.             }
  422.             break;
  423.         
  424.     case WM_RBUTTONDOWN:   // right button slewing
  425.             pt.x = LOWORD(lParam);
  426.             pt.y = HIWORD(lParam);
  427.             //
  428.             //    Is cursor in year up rectangle?
  429.             //
  430.             if(PtInRect(&year_up,pt))
  431.             {
  432.                 while(1)  
  433.                 {
  434.                     if(PeekMessage(&msg,NULL,0,0,
  435.                         PM_REMOVE))
  436.                     {
  437.                         pt = msg.pt;
  438.                         ScreenToClient(hDlg,&pt);
  439.                         if(!PtInRect(&year_up,pt))
  440.                         {    // user moved out of box
  441.                             break;
  442.                         }
  443.                         if(msg.message== WM_RBUTTONUP)
  444.                             break;
  445.                            else
  446.                         {
  447.                             TranslateMessage(&msg);
  448.                             DispatchMessage(&msg);
  449.                         }
  450.                     }
  451.                     ++year;    // increment year
  452.                     if(year > 2200) // check range  
  453.                         year = 1993;// default to 1993
  454.                     itoa(year,yearval,10);
  455.                     //    Update edit box with new year
  456.                     SetDlgItemText(hDlg,YEAR_CTRL,
  457.                         yearval);
  458.  
  459.                 }    // end while loop for slewing
  460.             
  461.             }    // end if slewed year up
  462.             //
  463.             //    now check for slewing year down
  464.             //
  465.             if(PtInRect(&year_down,pt))
  466.             {
  467.                 while(1)
  468.                 {
  469.                     if(PeekMessage(&msg,NULL,0,0,
  470.                         PM_REMOVE))
  471.                     {
  472.                         pt = msg.pt;
  473.                            ScreenToClient(hDlg,&pt);
  474.                         if(!PtInRect(&year_down,pt))
  475.                         {      // user moved out of box
  476.                             break;
  477.                         }
  478.                         if(msg.message== WM_RBUTTONUP)
  479.                             break;
  480.                            else
  481.                         {
  482.                             TranslateMessage(&msg);
  483.                             DispatchMessage(&msg);
  484.                         }
  485.                     }
  486.                     --year;        // decrement year                     
  487.                     if(year < 1800)    // check range
  488.                         year = 1800;        
  489.                     itoa(year,yearval,10);
  490.                     //    Update edit box with new year
  491.                     SetDlgItemText(hDlg,YEAR_CTRL,
  492.                         yearval);
  493.                 }    // end while loop for slewing down
  494.             }    // end if year down was slewed
  495.  
  496.             break;
  497.     }            // end switch on messages
  498.     return (FALSE);
  499. }                // end DateDialog()
  500. //
  501. //  end spin.c
  502. //
  503.