home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c081_7 / 2.ddi / WEXAMPLE.ZIP / DLLDEMO.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-13  |  9.4 KB  |  298 lines

  1. // Borland C++ - (C) Copyright 1991 by Borland International
  2.  
  3. //  Windows DLL example - C++ Version
  4. //
  5. //  You must build BITMAP.DLL before building DLLDEMO. There is
  6. //  a project file called BITMAP.PRJ for building the DLL.
  7.  
  8.  
  9. #include <windows.h>
  10.  
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #define _EXPORT huge
  15. #include "bitmap.h"
  16.  
  17. long FAR PASCAL _export WndProc( HWND hWnd, WORD iMessage,
  18.                                  WORD wParam, LONG lParam );
  19.  
  20. class Main
  21. {
  22.     public:
  23.     static HANDLE hInstance;
  24.     static HANDLE hPrevInstance;
  25.     static int nCmdShow;
  26.     static int MessageLoop( void );
  27. };
  28. HANDLE Main::hInstance = 0;
  29. HANDLE Main::hPrevInstance = 0;
  30. int Main::nCmdShow = 0;
  31.  
  32. int Main::MessageLoop( void )
  33. {
  34.     MSG msg;
  35.  
  36.     while( GetMessage( (LPMSG) &msg, NULL, 0, 0 ) )
  37.     {
  38.         TranslateMessage( &msg );
  39.         DispatchMessage( &msg );
  40.     }
  41.     return msg.wParam;
  42. }
  43.  
  44.  
  45. // Base class
  46. class Window
  47. {
  48.     protected:
  49.         HWND hWnd;
  50.     public:
  51.         // Provide (read) access to the window's handle in case it is needed
  52.         // elsewhere.
  53.         HWND GetHandle( void ) { return hWnd; }
  54.  
  55.         BOOL Show( int nCmdShow ) { return ShowWindow( hWnd, nCmdShow ); }
  56.         void Update( void ) { UpdateWindow( hWnd ); }
  57.         // Pure virtual function makes Window an abstract class.
  58.         virtual long WndProc( WORD iMessage, WORD wParam, LONG lParam ) = 0;
  59. };
  60.  
  61. class MainWindow : public Window
  62. {
  63.     private:
  64.         static char szClassName[14];
  65.         Bitmap FAR *lpBitmap1;
  66.         Bitmap FAR *lpBitmap2;
  67.         // Helper function used by Paint function; it is used as a
  68.         // callback function by LineDDA.
  69.         static void FAR PASCAL LineFunc( int X, int Y, LPSTR lpData );
  70.     public:
  71.         // Register the class only AFTER WinMain assigns appropriate
  72.         // values to static members of Main and only if no previous
  73.         // instances of the program exist (a previous instance would
  74.         // have already performed the registration).
  75.         static void Register( void )
  76.         {
  77.             WNDCLASS wndclass;   // Structure used to register Windows class.
  78.  
  79.             wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  80.             wndclass.lpfnWndProc   = ::WndProc;
  81.             wndclass.cbClsExtra    = 0;
  82.             // Reserve extra bytes for each instance of the window;
  83.             // we will use these bytes to store a pointer to the C++
  84.             // (MainWindow) object corresponding to the window.
  85.             // the size of a 'this' pointer depends on the memory model.
  86.             wndclass.cbWndExtra    = sizeof( MainWindow * );
  87.             wndclass.hInstance     = Main::hInstance;
  88.             wndclass.hIcon         = LoadIcon( Main::hInstance, "whello" );
  89.             wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW );
  90.             wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
  91.             wndclass.lpszMenuName  = NULL;
  92.             wndclass.lpszClassName = szClassName;
  93.  
  94.             if ( ! RegisterClass( &wndclass ) )
  95.                 exit( FALSE );
  96.         }
  97.  
  98.         // Do not create unless previously registered.
  99.         MainWindow( void )
  100.         {
  101.             lpBitmap1 = new Bitmap( Main::hInstance, "dlldemo1" );
  102.             lpBitmap2 = new Bitmap( Main::hInstance, "dlldemo2" );
  103.             // Pass 'this' pointer in lpParam of CreateWindow().
  104.             hWnd = CreateWindow( szClassName,
  105.                 szClassName,
  106.                 WS_OVERLAPPEDWINDOW,
  107.                 CW_USEDEFAULT,
  108.                 0,
  109.                 CW_USEDEFAULT,
  110.                 0,
  111.                 NULL,
  112.                 NULL,
  113.                 Main::hInstance,
  114.                 (LPSTR) this );
  115.             if ( ! hWnd )
  116.                 exit( FALSE );
  117.  
  118.             Show( Main::nCmdShow );
  119.             Update();
  120.         }
  121.         ~MainWindow( void )
  122.         {
  123.             delete lpBitmap1;
  124.             delete lpBitmap2;
  125.         }
  126.         long WndProc( WORD iMessage, WORD wParam, LONG lParam );
  127.  
  128.         // Print a message in the client rectangle.
  129.         void Paint( void );
  130.         // Struct used by Paint to pass information to callback function
  131.         // used by LineDDA
  132.         struct LINEFUNCDATA
  133.         {
  134.             HDC hDC;
  135.             Bitmap FAR *lpBM1;
  136.             Bitmap FAR *lpBM2;
  137.             POINT size1;
  138.             POINT size2;
  139.             LINEFUNCDATA( HDC h, Bitmap FAR *lpBitmap1, Bitmap FAR *lpBitmap2 )
  140.             {
  141.                 hDC = h;
  142.                 lpBM1 = lpBitmap1;
  143.                 lpBM2 = lpBitmap2;
  144.                 size1 =lpBitmap1->GetSize( hDC );
  145.                 size2 =lpBitmap2->GetSize( hDC );
  146.             };
  147.         };
  148. };
  149. char MainWindow::szClassName[] = "Hello, World!";
  150.  
  151. void MainWindow::Paint( void )
  152. {
  153.     PAINTSTRUCT ps;
  154.     RECT rect;
  155.     FARPROC lpLineFunc;
  156.  
  157.     lpLineFunc = MakeProcInstance( (FARPROC) MainWindow::LineFunc, Main::hInstance );
  158.     GetClientRect( hWnd, (LPRECT) &rect );
  159.  
  160.     BeginPaint( hWnd, &ps );
  161.     LINEFUNCDATA LineFuncData( ps.hdc, lpBitmap1, lpBitmap2 );
  162.     LineDDA( 0, 0, rect.right - (lpBitmap1->GetSize( ps.hdc )).x,
  163.              0, lpLineFunc, (LPSTR) &LineFuncData );
  164.     EndPaint( hWnd, &ps );
  165.     FreeProcInstance( lpLineFunc );
  166. }
  167.  
  168. void FAR PASCAL MainWindow::LineFunc( int X, int Y, LPSTR lpData )
  169. {
  170.     LINEFUNCDATA FAR * lpLineFuncData = (LINEFUNCDATA FAR *) lpData;
  171.     HDC hDC = lpLineFuncData->hDC;
  172.     Bitmap FAR *lpBitmap1 = lpLineFuncData->lpBM1;
  173.     Bitmap FAR *lpBitmap2 = lpLineFuncData->lpBM2;
  174.     static int i = 0;
  175.  
  176.     if ( !( i % 4 ) ) {
  177.         lpBitmap1->Display( hDC, X, Y );
  178.         // Draw second bitmap below first.
  179.         lpBitmap2->Display( hDC, X / 4, ( Y + (lpLineFuncData->size1).y ) );
  180.     }
  181.     i++;
  182. }
  183.  
  184. long MainWindow::WndProc( WORD iMessage, WORD wParam, LONG lParam )
  185. {
  186.     switch (iMessage)
  187.     {
  188.     case WM_CREATE:
  189.         break;
  190.         case WM_PAINT:
  191.             Paint();
  192.             break;
  193.         case WM_DESTROY:
  194.             PostQuitMessage( 0 );
  195.             break;
  196.         default:
  197.             return DefWindowProc( hWnd, iMessage, wParam, lParam );
  198.     }
  199. }
  200.  
  201. // If data pointers are near pointers
  202. #if defined(__SMALL__) || defined(__MEDIUM__)
  203. inline Window *GetPointer( HWND hWnd )
  204. {
  205.     return (Window *) GetWindowWord( hWnd, 0 );
  206. }
  207. inline void SetPointer( HWND hWnd, Window *pWindow )
  208. {
  209.     SetWindowWord( hWnd, 0, (WORD) pWindow );
  210. }
  211.  
  212. // else pointers are far
  213. #elif defined(__LARGE__) || defined(__COMPACT__)
  214. inline Window *GetPointer( HWND hWnd )
  215. {
  216.     return (Window *) GetWindowLong( hWnd, 0 );
  217. }
  218. inline void SetPointer( HWND hWnd, Window *pWindow )
  219. {
  220.     SetWindowLong( hWnd, 0, (LONG) pWindow );
  221. }
  222.  
  223. #else
  224.     #error Choose another memory model!
  225. #endif
  226.  
  227.  
  228. long FAR PASCAL _export WndProc( HWND hWnd, WORD iMessage, WORD wParam,
  229.                                  LONG lParam )
  230. {
  231.     // Pointer to the (C++ object that is the) window.
  232.     Window *pWindow = GetPointer( hWnd );
  233.  
  234.     // The pointer pWindow will have an invalid value if the WM_CREATE
  235.     // message has not yet been processed (we respond to the WM_CREATE
  236.     // message by setting the extra bytes to be a pointer to the
  237.     // (C++) object corresponding to the Window identified
  238.     // by hWnd).  The messages that
  239.     // precede WM_CREATE must be processed without using pWindow so we
  240.     // pass them to DefWindowProc.
  241.     // How do we know in general if the pointer pWindow is invalid?
  242.     // Simple: Windows allocates the window extra bytes using LocalAlloc
  243.     // which zero initializes memory; thus, pWindow will have a value of
  244.     // zero before we set the window extra bytes to the 'this' pointer.
  245.     // Caveat emptor: the fact that LocalAlloc will zero initialize the
  246.     // window extra bytes is not documented; therefore, it could change
  247.     // in the future.
  248.  
  249.     if ( pWindow == 0 )
  250.     {
  251.         if ( iMessage == WM_CREATE )
  252.         {
  253.             LPCREATESTRUCT lpcs;
  254.  
  255.             lpcs = (LPCREATESTRUCT) lParam;
  256.             pWindow = (Window *) lpcs->lpCreateParams;
  257.  
  258.             // Store a pointer to this object in the window's extra bytes;
  259.             // this will enable to access this object (and its member
  260.             // functions) in WndProc where we are
  261.             // given only a handle to identify the window.
  262.             SetPointer( hWnd, pWindow );
  263.             // Now let the object perform whatever
  264.             // initialization it needs for WM_CREATE in its own
  265.             // WndProc.
  266.             return pWindow->WndProc( iMessage, wParam, lParam );
  267.         }
  268.         else
  269.             return DefWindowProc( hWnd, iMessage, wParam, lParam );
  270.     }
  271.     else
  272.         return pWindow->WndProc( iMessage, wParam, lParam );
  273. }
  274.  
  275. // Turn off warning: Parameter 'lpszCmdLine' is never used in function WinMain(unsigned int,unsigned int,char far*,int)
  276. #pragma argsused
  277.  
  278. int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine,
  279.                     int nCmdShow )
  280. {
  281.     Main::hInstance = hInstance;
  282.     Main::hPrevInstance = hPrevInstance;
  283.     Main::nCmdShow = nCmdShow;
  284.  
  285.     // A Windows class should be registered with Windows before any windows
  286.     // of that type are created.
  287.     // Register here all Windows classes that will be used in the program.
  288.     // Windows classes should not be registered if an instance of
  289.     // the program is already running.
  290.     if ( ! Main::hPrevInstance ) {
  291.         MainWindow::Register();
  292.     }
  293.  
  294.     MainWindow MainWnd;
  295.  
  296.     return Main::MessageLoop();
  297. }
  298.