// File...: BB2TDE01.C (c) SOFTWARE SYSTEMS 1997
// Version: 1.00 
// Date...: 31.Aug.1997

#include <windows.h>

#define BUTTON1	100
#define BUTTON2	200
                         
HANDLE ghInstance;					             // Global Instance
RECT   rect;                                     // Left side of client area
short  cxChar, cyChar,   				         // Font size (char height & width)
       LineCount, MaxLineCount;                  // Lines in the left side of client area
BOOL   ScrollFlag;                               // Flag: Scroll left side yes/no
                         
// Function Prototyps
                        
void            MessageInfo (HWND, char *, int);                        
long FAR PASCAL WndFunction (HWND, WORD, WORD, LONG);

//****************************************************************************************

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{  
   static char szAppName[]= "BB2TD-CONTROLS",
               szTitleBar[]= "BB2TD Controls Example 01";
   HWND        hWnd;	
   WNDCLASS    wndclass;
   MSG         msg;
      
   // Register Class

   ghInstance= hInstance;      
   if (! hPrevInstance) {
      wndclass.style        = CS_HREDRAW | CS_VREDRAW;
      wndclass.lpfnWndProc  = WndFunction;
      wndclass.cbClsExtra   = 0;
      wndclass.cbWndExtra   = 0;
      wndclass.hInstance    = hInstance;
      wndclass.hIcon        = LoadIcon (NULL, IDI_APPLICATION);
      wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW);
      wndclass.hbrBackground= GetStockObject (WHITE_BRUSH);
      wndclass.lpszMenuName = NULL;
      wndclass.lpszClassName= szAppName;
      
      RegisterClass (&wndclass);
   }
   
   // Create window with 640 * 480 dots at position x= y= 0 and show window
   
   hWnd= CreateWindow (szAppName,
                       szTitleBar,
                       WS_OVERLAPPEDWINDOW,
                       0,                   // x position for this window
                       0,                   // y position for this window
                       640,                 // window width is 640 dots
                       480,                 // window height is 480 dots
                       NULL,               
                       NULL,              
                       hInstance,          
                       NULL); 

   ShowWindow   (hWnd, nCmdShow);
   UpdateWindow (hWnd);

   // Dispatch Message or exit program
   
   while (GetMessage (&msg, NULL, 0, 0)) {
      TranslateMessage (&msg);
      DispatchMessage  (&msg);
   }
   return (msg.wParam);
}

//******************************************************

void MessageInfo (HWND hWnd, char *szMessage, int Count)
{
   HDC hDC;
   
   // ... scroll left side of client area if necessary
                         
   if (ScrollFlag == TRUE)
      ScrollWindow (hWnd, 0, -cyChar, &rect, &rect);

   if (LineCount == MaxLineCount) ScrollFlag= TRUE;

   // ... write message to left side of client area
                           
   hDC= GetDC (hWnd);
   SelectObject (hDC, GetStockObject (SYSTEM_FIXED_FONT));
   TextOut (hDC, cxChar, rect.top + (cyChar * LineCount), szMessage, Count);
   ReleaseDC (hWnd, hDC);
   ValidateRect (hWnd, NULL);
   
   if (LineCount != MaxLineCount) LineCount++;
}

//**************************************************************************

long FAR PASCAL WndFunction (HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
{     
   static HWND hButton1, hButton2;
   int         OemScanCode;
   HDC         hDC;
   TEXTMETRIC  tm;
            
   switch (wMsg) {
      
      // Create and show two PushButton Controls
      
      case WM_CREATE: hButton1= CreateWindow ("BUTTON", "Button1",
                                              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                              395, 100, 160, 60, hWnd, BUTTON1,
                                              ghInstance, NULL);
                      ShowWindow (hButton1, SW_SHOW);
                                                
                      // ... second PushButton Control
                                                
                      hButton2= CreateWindow ("BUTTON", "Button2",
                                              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                              395, 275, 160, 60, hWnd, BUTTON2,
                                              ghInstance, NULL);
                      ShowWindow (hButton2, SW_SHOW);
                      
                      // ... we need the font size (char height & width)
                      
                      hDC= GetDC (hWnd);
                      SelectObject (hDC, GetStockObject (SYSTEM_FIXED_FONT));
                      GetTextMetrics (hDC, &tm);
                      cxChar= tm.tmAveCharWidth;
                      cyChar= tm.tmHeight;
                      ReleaseDC (hWnd, hDC);
                      rect.top= cyChar / 2;
                      break;

      // ... we need the current size of the client area
      
      case WM_SIZE: rect.right = rect.left + (35 * cxChar);
                    rect.bottom= HIWORD (lParam);
                    UpdateWindow (hWnd);
                    LineCount= 0;
                    MaxLineCount= ((rect.bottom - rect.top) / cyChar) - 1;
                    ScrollFlag= FALSE;
                    return (0);
                          			     
      // ... set focus allways to main window
      
      case WM_COMMAND: MessageBeep (0);
                       SetFocus (hWnd);
                       break;
      
      // ... check here for KEY DOWN, use OEM Scan Code
      
      case WM_KEYDOWN: OemScanCode= HIWORD (lParam) & 0x00ff;
                       switch (OemScanCode) {
                          case 0x24: SendMessage (hButton1, BM_SETSTATE, 1, 0l);
                          		     MessageInfo (hWnd, "WM_KEYDOWN Button1, SC= 0x24...", 31);
                                     break;
                          case 0x25: SendMessage (hButton1, BM_SETSTATE, 1, 0l);
                          		     MessageInfo (hWnd, "WM_KEYDOWN Button1, SC= 0x25...", 31);
                                     break;
                          case 0x06: SendMessage (hButton2, BM_SETSTATE, 1, 0l);
                                     MessageInfo (hWnd, "WM_KEYDOWN Button2, SC= 0x06...", 31);
                                     break;          
                          case 0x07: SendMessage (hButton2, BM_SETSTATE, 1, 0l);
                                     MessageInfo (hWnd, "WM_KEYDOWN Button2, SC= 0x07...", 31);
                                     break;
                       }
                       MessageBeep (0);
                       break;
      
      // ... check here for KEY UP, use OEM Scan Code
                        
      case WM_KEYUP: OemScanCode= HIWORD (lParam) & 0x00ff;
                     switch (OemScanCode) {
                        case 0x24: SendMessage (hButton1, BM_SETSTATE, 0, 0l);
                                   MessageInfo (hWnd, "WM_KEYUP   Button1, SC= 0x24...", 31);
                                   break;
                        case 0x25: SendMessage (hButton1, BM_SETSTATE, 0, 0l);
                                   MessageInfo (hWnd, "WM_KEYUP   Button1, SC= 0x25...", 31);
                                   break;
                        case 0x06: SendMessage (hButton2, BM_SETSTATE, 0, 0l);
                                   MessageInfo (hWnd, "WM_KEYUP   Button2, SC= 0x06...", 31);
                                   break;          
                        case 0x07: SendMessage (hButton2, BM_SETSTATE, 0, 0l);
                                   MessageInfo (hWnd, "WM_KEYUP   Button2, SC= 0x07...", 31);
                                   break;
                     }
                     MessageBeep (0);
                     break; 

      // ... destroy window
      
      case WM_DESTROY: PostQuitMessage (0);
                       return (0);
   }
   return (DefWindowProc (hWnd, wMsg, wParam, lParam));
}
