home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 6.ddi / WEXAMPLE.ZIP / DLLDEMO.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  9.3 KB  |  299 lines

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