home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / m / m003_1 / sb_bc.ddi / BC / CH5 / WINAPP-4.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  9.3 KB  |  391 lines

  1. /***              Windows Application 4                ***/
  2. /***                                                   ***/
  3. /***              WINAPP-4 includes                    ***/
  4. /***                       (1) WINAPP-4.CPP            ***/
  5. /***                       (2) WINAPP-4.DEF            ***/
  6.  
  7. #pragma hdrfile "windows.sym"
  8. #include <windows.h>
  9. #pragma hdrstop
  10.  
  11. #include"winapp-2.h"
  12.  
  13. #ifndef min
  14. #define min(a,b)            (((a) < (b)) ? (a) : (b))
  15. #endif
  16.  
  17. #ifndef max
  18. #define max(a,b)            (((a) > (b)) ? (a) : (b))
  19. #endif
  20.  
  21. // Declaration
  22.  
  23. long FAR PASCAL _export AppWndProc (HWND, WORD, WORD, LONG) ;
  24.  
  25.  
  26. class Main
  27. { public:
  28.     static HANDLE hInstance ;
  29.     static HANDLE hPrevInstance ;
  30.     static int    nCmdShow ;
  31.  
  32.     static int MessageLoop(void) ;
  33. } ;
  34.  
  35. HANDLE Main::hInstance = 0 ;
  36. HANDLE Main::hPrevInstance = 0 ;
  37. int    Main::nCmdShow = 0 ;
  38.  
  39. int Main::MessageLoop(void)
  40. { MSG msg ;
  41.  
  42.   while ( GetMessage(&msg, NULL, 0, 0) )
  43.     { TranslateMessage(&msg) ;
  44.       DispatchMessage(&msg) ;
  45.     }
  46.   return msg.wParam ;
  47. }
  48.  
  49.  
  50. ////////// Base Class -> Window
  51. //////////
  52. class Window
  53. { protected:
  54.     HWND hwnd ;
  55.  
  56.   public:
  57.     HWND GetHandle(void)     // get the window handle in the class
  58.     { return hwnd ; }
  59.  
  60.     BOOL Show(int nCmdShow)
  61.     { return ShowWindow(hwnd,nCmdShow) ; }
  62.  
  63.     void Update(void)
  64.     { UpdateWindow(hwnd) ; }
  65.  
  66.     virtual long CreateProc(HWND hwnd,
  67.                 WORD wParam, LONG lParam) = 0 ;
  68.  
  69.     virtual long AppWndProc(WORD message,
  70.                 WORD wParam, LONG lParam) = 0 ;
  71. } ;
  72.  
  73.  
  74. ////////// Derived Class -> MainWindow
  75. //////////
  76. class MainWindow : public Window
  77. { private:
  78.     static char szAppName[8] ;
  79.     struct { short int cxChar, cyChar, cxCaps, nMaxX ; } FontSize ;
  80.  
  81.   public :
  82.     static void Register(void) ;
  83.     MainWindow(void) ;
  84.  
  85.     virtual long CreateProc(HWND hwnd,
  86.                 WORD wParam, LONG lParam) ;
  87.  
  88.     virtual long AppWndProc(WORD message,
  89.                 WORD wParam, LONG lParam) ;
  90. } ;
  91.  
  92. char MainWindow::szAppName[] = "WinApp4" ;
  93.  
  94. void MainWindow::Register(void)
  95. { WNDCLASS wndclass ;
  96.  
  97.   wndclass.style      = CS_HREDRAW | CS_VREDRAW ;
  98.   wndclass.lpfnWndProc      = ::AppWndProc ;
  99.   wndclass.cbClsExtra       = 0 ;
  100.   wndclass.cbWndExtra      = sizeof(MainWindow *) ;
  101.   wndclass.hInstance       = Main::hInstance ;
  102.   wndclass.hIcon      = LoadIcon(NULL,IDI_APPLICATION) ;
  103.   wndclass.hCursor      = LoadCursor(NULL,IDC_ARROW) ;
  104.   wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH) ;
  105.   wndclass.lpszMenuName      = NULL ;
  106.   wndclass.lpszClassName  = szAppName ;
  107.  
  108.   RegisterClass(&wndclass) ;
  109. }
  110.  
  111. MainWindow::MainWindow(void)
  112. {
  113.   hwnd = CreateWindow(szAppName,                // window class name
  114.               "Windows Application 2",  // window caption
  115.               WS_OVERLAPPEDWINDOW |
  116.               WS_VSCROLL |
  117.               WS_HSCROLL ,         // window style
  118.               CW_USEDEFAULT,       // initial x position
  119.               0,                   // initial y position
  120.               CW_USEDEFAULT,       // initial x length
  121.               0,                   // initial y length
  122.               NULL,                // parent window handle
  123.               NULL,                // window menu handle
  124.               Main::hInstance,     // program instance handle
  125.               (LPSTR) this) ;      // parameters , different
  126.                        //   from WINAPP-2
  127.   Show(Main::nCmdShow) ;
  128.   Update() ;
  129. }
  130.  
  131.  
  132. //  special case
  133.  
  134. #pragma argsused
  135. long MainWindow::CreateProc(HWND hwnd,
  136.                 WORD wParam, LONG lParam)
  137. { HDC hdc ;
  138.   TEXTMETRIC tm ;
  139.  
  140.   hdc = GetDC(hwnd) ;
  141.  
  142.   GetTextMetrics(hdc,&tm) ;
  143.   FontSize.cxChar = tm.tmAveCharWidth ;
  144.   FontSize.cyChar = tm.tmHeight + tm.tmExternalLeading ;
  145.   FontSize.cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) *
  146.              FontSize.cxChar / 2 ;
  147.  
  148.   ReleaseDC(hwnd,hdc) ;
  149.  
  150.   FontSize.nMaxX = 20 * FontSize.cxCaps + 45 * FontSize.cxChar ;
  151.  
  152.   return 0L ;
  153. }
  154.  
  155.  
  156. long MainWindow::AppWndProc(WORD message,
  157.                 WORD wParam, LONG lParam)
  158. { HDC hdc ;
  159.   PAINTSTRUCT ps ;
  160.  
  161.   static short int cxClient, cyClient ;
  162.   static short int nVScrollMax, nVScrollPos ;
  163.   static short int nHScrollMax, nHScrollPos ;
  164.  
  165.   short int nVScrollInc, nHScrollInc ;
  166.   short int nBeginLine, nEndLine ;
  167.   short int i,x,y ;
  168.  
  169.   switch (message)
  170.     { case WM_SIZE :
  171.        cxClient = LOWORD(lParam) ;
  172.        cyClient = HIWORD(lParam) ;
  173.  
  174.        nVScrollMax = max(0, NUMLINE+2-cyClient/FontSize.cyChar) ;
  175.        nVScrollPos = min(nVScrollMax,nVScrollPos) ;
  176.        SetScrollRange(hwnd, SB_VERT, 0, nVScrollMax, FALSE) ;
  177.        SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE) ;
  178.  
  179.        nHScrollMax = max( 0,(FontSize.nMaxX-cxClient)/
  180.                 FontSize.cxChar+2) ;
  181.        nHScrollPos = min(nHScrollMax,nHScrollPos) ;
  182.        SetScrollRange(hwnd, SB_HORZ, 0, nHScrollMax, FALSE) ;
  183.        SetScrollPos(hwnd, SB_HORZ, nHScrollPos, TRUE) ;
  184.  
  185.        break ;
  186.  
  187.  
  188.       case WM_VSCROLL :
  189.        switch (wParam)
  190.          { case SB_TOP :
  191.             nVScrollInc = -nVScrollPos ;
  192.             break ;
  193.  
  194.            case SB_BOTTOM :
  195.             nVScrollInc = nVScrollMax-nVScrollPos ;
  196.             break ;
  197.  
  198.            case SB_LINEUP :
  199.             nVScrollInc = -1 ;
  200.             break ;
  201.  
  202.            case SB_LINEDOWN :
  203.             nVScrollInc = 1 ;
  204.             break ;
  205.  
  206.            case SB_PAGEUP :
  207.             nVScrollInc = min(-1,-cyClient/FontSize.cyChar) ;
  208.             break ;
  209.  
  210.            case SB_PAGEDOWN :
  211.             nVScrollInc = max(1,cyClient/FontSize.cyChar) ;
  212.             break ;
  213.  
  214.            case SB_THUMBTRACK :
  215.             nVScrollInc = LOWORD(lParam)-nVScrollPos ;
  216.             break ;
  217.  
  218.            default :
  219.             nVScrollInc = 0 ;
  220.             break ;
  221.          }
  222.  
  223.        nVScrollInc = min(nVScrollInc ,nVScrollMax-nVScrollPos) ;
  224.        nVScrollInc = max(nVScrollInc ,-nVScrollPos) ;
  225.  
  226.        if (nVScrollInc)
  227.           { nVScrollPos += nVScrollInc ;
  228.         ScrollWindow(hwnd, 0, -FontSize.cyChar*nVScrollInc,
  229.                  NULL, NULL) ;
  230.         SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE) ;
  231.         UpdateWindow(hwnd) ;
  232.           }
  233.        break ;
  234.  
  235.  
  236.       case WM_HSCROLL :
  237.        switch (wParam)
  238.          { case SB_TOP :
  239.             nHScrollInc = -nHScrollPos ;
  240.             break ;
  241.  
  242.            case SB_BOTTOM :
  243.             nHScrollInc = nHScrollMax-nHScrollPos ;
  244.             break ;
  245.  
  246.            case SB_LINEUP :
  247.             nHScrollInc = -1 ;
  248.             break ;
  249.  
  250.            case SB_LINEDOWN :
  251.             nHScrollInc = 1 ;
  252.             break ;
  253.  
  254.            case SB_PAGEUP :
  255.             nHScrollInc = min(-1,-cxClient/FontSize.cxChar) ;
  256.             break ;
  257.  
  258.            case SB_PAGEDOWN :
  259.             nHScrollInc = max(1,cxClient/FontSize.cxChar) ;
  260.             break ;
  261.  
  262.            case SB_THUMBTRACK :
  263.             nHScrollInc = LOWORD(lParam)-nHScrollPos ;
  264.             break ;
  265.  
  266.            default :
  267.             nHScrollInc = 0 ;
  268.             break ;
  269.          }
  270.  
  271.        nHScrollInc = min(nHScrollInc ,nHScrollMax-nHScrollPos) ;
  272.        nHScrollInc = max(nHScrollInc ,-nHScrollPos) ;
  273.  
  274.        if (nHScrollInc)
  275.           { nHScrollPos += nHScrollInc ;
  276.         ScrollWindow(hwnd, -FontSize.cxChar*nHScrollInc, 0,
  277.                  NULL, NULL) ;
  278.         SetScrollPos(hwnd, SB_HORZ, nHScrollPos, TRUE) ;
  279.         UpdateWindow(hwnd) ;
  280.           }
  281.        break ;
  282.  
  283.  
  284.       case WM_PAINT :
  285.        hdc = BeginPaint(hwnd, &ps) ;
  286.  
  287.        nBeginLine = max(0, nVScrollPos +
  288.                    ps.rcPaint.top/FontSize.cyChar - 1) ;
  289.        nEndLine = min(NUMLINE, nVScrollPos + ps.rcPaint.bottom /
  290.                          FontSize.cyChar) ;
  291.  
  292.        for (i=nBeginLine ; i<nEndLine ; i++)
  293.          { x = FontSize.cxChar * (1-nHScrollPos) ;
  294.            y = FontSize.cyChar * (1-nVScrollPos+i) ;
  295.  
  296.            TextOut(hdc, x, y,
  297.                WinStruct[i].szStruct,
  298.                lstrlen(WinStruct[i].szStruct)) ;
  299.  
  300.            TextOut(hdc, x+20*FontSize.cxCaps, y,
  301.                WinStruct[i].szDescriptor,
  302.                lstrlen(WinStruct[i].szDescriptor)) ;
  303.          }
  304.  
  305.        EndPaint(hwnd, &ps) ;
  306.        break ;
  307.  
  308.  
  309.       case WM_DESTROY :
  310.        PostQuitMessage(0) ;
  311.        break ;
  312.  
  313.  
  314.       default :
  315.        return DefWindowProc(hwnd, message, wParam, lParam) ;
  316.     }
  317.  
  318.   return 0L ;
  319. }
  320.  
  321.  
  322. #if defined(__SMALL__) || defined(__MEDIUM__)
  323. inline Window *GetPointer( HWND hWnd )
  324. {
  325.     return (Window *) GetWindowWord( hWnd, 0 );
  326. }
  327. inline void SetPointer( HWND hWnd, Window *pWindow )
  328. {
  329.     SetWindowWord( hWnd, 0, (WORD) pWindow );
  330. }
  331.  
  332. // else pointers are far
  333. #elif defined(__LARGE__) || defined(__COMPACT__)
  334. inline Window *GetPointer( HWND hWnd )
  335. {
  336.     return (Window *) GetWindowLong( hWnd, 0 );
  337. }
  338. inline void SetPointer( HWND hWnd, Window *pWindow )
  339. {
  340.     SetWindowLong( hWnd, 0, (LONG) pWindow );
  341. }
  342.  
  343. #else
  344.     #error Choose another memory model!
  345. #endif
  346.  
  347.  
  348. long FAR PASCAL _export AppWndProc (HWND hwnd,   WORD message,
  349.                     WORD wParam, LONG lParam)
  350. { Window *pWindow = GetPointer( hwnd );
  351.  
  352.   if ( pWindow == 0 )
  353.      { if ( message == WM_CREATE )
  354.       { LPCREATESTRUCT lpcs;
  355.  
  356.         lpcs = (LPCREATESTRUCT) lParam;
  357.         pWindow = (Window *) lpcs->lpCreateParams;
  358.  
  359.         SetPointer(hwnd,pWindow);
  360.  
  361.         return pWindow->CreateProc(hwnd, wParam, lParam);
  362.       }
  363.        else return DefWindowProc(hwnd, message, wParam, lParam);
  364.      }
  365.   else return pWindow->AppWndProc(message, wParam, lParam);
  366. }
  367.  
  368.  
  369.  
  370. // Turn off warning: Parameter 'lpszCmdLine' is never used ...
  371. #pragma argsused
  372.  
  373. // Turn off warning: 'mainwindow' is assigned a value that is never ...
  374. #pragma option -w-aus
  375.  
  376.  
  377. int PASCAL WinMain(HANDLE hInstance,
  378.            HANDLE hPrevInstance,
  379.            LPSTR  lpszCmdLine,
  380.            int    nCmdShow)
  381. { Main::hInstance = hInstance ;
  382.   Main::hPrevInstance = hPrevInstance ;
  383.   Main::nCmdShow = nCmdShow ;
  384.  
  385.   if (! Main::hPrevInstance) MainWindow::Register() ;
  386.  
  387.   MainWindow mainwindow ;
  388.  
  389.   return Main::MessageLoop() ;
  390. }
  391.