home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rpc / wintyp / client.c next >
Encoding:
C/C++ Source or Header  |  1996-07-23  |  35.1 KB  |  872 lines

  1. /*************************************************************************
  2.                         Copyright Microsoft Corp. 1992-1996
  3.                             Remote Machine WinType sample
  4.  
  5.     FILE        :   CLIENT.C
  6.  
  7.     PURPOSE     :   Client side of the RPC distributed application wintyp
  8.  
  9.     COMMENTS    :   This program shows the client side an application that
  10.                     transfers a Windows datatype (HBITMAP) from the client
  11.                     to the server, using Remote Procedure Calls. When the
  12.                     Bitmap is received on the server end, it modifies the
  13.                     bitmap, and sends it back.
  14.  
  15.                     Since this program uses the implicit binding method, 
  16.                     some of the binding handling must be done at the 
  17.                     client side.
  18.  
  19. *************************************************************************/
  20. #include <windows.h>            // Required for all Windows programs
  21. #include <commdlg.h>            // Support for the common dialogboxes
  22.  
  23. #include "common.h"             // Common headerfile for client and server
  24. #include "client.h"             // Header file for the client
  25. #include "clires.h"             // Definitions for the resource file
  26. #include "wintyp.h"             // Generated by the MIDL compiler
  27.  
  28. TCHAR   szBuffer[200];          // Buffer used for printing messages
  29.  
  30. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  31. //  Procedure   :   WinMain()
  32. //  Desc.       :   Windows main procedure. Calls up the initialization 
  33. //                  of the program , and starts up the message pump
  34. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  35. int WINAPI WinMain  (HINSTANCE  hInstance,
  36.                      HINSTANCE  hPrevInstance,
  37.                      LPSTR      lpszCmdLine,
  38.                      int        nCmdShow)
  39. {
  40.     MSG         uMsg;           // The message struct
  41.     HACCEL      hAccels;        // Handle to the accelerators
  42.     
  43.     // Set the global instance
  44.     g_hInstance = hInstance;
  45.  
  46.     // Perform registration of the class and create the window
  47.     if(!Init())
  48.     {
  49.         return FALSE;
  50.     }
  51.         
  52.     // Display the window
  53.     ShowWindow(g_hWnd, nCmdShow);
  54.     
  55.     // Load the accelerators
  56.     hAccels = LoadAccelerators(hInstance,
  57.         MAKEINTRESOURCE(IDR_ACCELERATOR1));
  58.  
  59.     // Add a message pump to take care of messages
  60.     while (GetMessage(&uMsg, NULL, 0, 0))    // NULL only for WM_QUIT msg.
  61.     {
  62.         if(!TranslateAccelerator(g_hWnd, hAccels, &uMsg))
  63.         {
  64.             TranslateMessage(&uMsg);
  65.             DispatchMessage(&uMsg);
  66.         }
  67.     }
  68.     
  69.     return uMsg.wParam;
  70. }
  71.  
  72.  
  73.  
  74. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  75. // Function :   Init()
  76. // Purpose  :   This function is called once from the start of the program 
  77. //              It will register the window class, create the window, and 
  78. //              perform the binding to the server.
  79. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  80. BOOL Init()
  81. {
  82.     WNDCLASS    sWC;                        // The window class
  83.     
  84.     // Fill in the fields of the window class struct
  85.     sWC.style = 0;                          // Style info
  86.     sWC.lpfnWndProc  = (WNDPROC) ClientProc;// Proc. to handle messsages
  87.     sWC.cbClsExtra   = 0;                   // Extra bytes for class
  88.     sWC.cbWndExtra   = 0;                   // Extra bytes for window
  89.     sWC.hInstance    = g_hInstance;         // Handle to current instance
  90.     sWC.hIcon        = LoadIcon(g_hInstance,// Handle to icon for class
  91.         MAKEINTRESOURCE(IDI_CLIENT_ICON));      
  92.     sWC.hCursor      = LoadCursor(NULL, IDC_ARROW); // Handle to cursor 
  93.     sWC.hbrBackground= GetStockObject(GRAY_BRUSH);  // Brush for backgr.
  94.     sWC.lpszMenuName =
  95.         MAKEINTRESOURCE(IDR_CLIENT_MENU);           // Name of menu to use
  96.     sWC.lpszClassName= g_szClassName;               // Class name
  97.     
  98.     // Register the window class
  99.     if(!RegisterClass(&sWC))
  100.     {
  101.         return FALSE;
  102.     }
  103.  
  104.     // Create the window
  105.     g_hWnd = CreateWindowEx(
  106.         0,                      // Style
  107.         g_szClassName,          // The class name
  108.         g_szWindowCaption,      // Caption showed at top of window
  109.         WS_OVERLAPPEDWINDOW,    // The window style
  110.         CW_USEDEFAULT,          // x-coordinate
  111.         CW_USEDEFAULT,          // y-coordinate
  112.         CW_USEDEFAULT,          // Width of window
  113.         CW_USEDEFAULT,          // Height of window
  114.         NULL,                   // Parent window
  115.         NULL,                   // Menu
  116.         g_hInstance,            // Handle to current instance   
  117.         NULL);                  // lpvParam
  118.     
  119.     // Return false if creation failed
  120.     if(g_hWnd == NULL)
  121.     {
  122.         return FALSE;
  123.     }
  124.  
  125.     // Initialize the binding address
  126.     pszNetworkAddress[0] = 0;
  127.     _tcscpy(pszEndpoint, END_POINT);
  128.     _tcscpy(pszProtocolSequence, PROTOCOL_SEQUENCE);
  129.  
  130.     // Create the binding
  131.     if(Bind(g_hWnd) != RPC_S_OK)
  132.     {
  133.         return FALSE;
  134.     }
  135.  
  136.     return TRUE;                // Initialization OK
  137. }
  138.  
  139.  
  140. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  141. // Procedure    :   ClientWindowProc()
  142. // Desc.        :   This procedure takes care of all the message handling 
  143. //                  from the client main program
  144. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  145. LRESULT CALLBACK    ClientProc(HWND   hWnd,
  146.                                UINT    uMsg,
  147.                                WPARAM  wParam,
  148.                                LPARAM  lParam)
  149. {
  150.     PAINTSTRUCT sPS;                        // The paintstructure
  151.     HDC         hDC = GetDC(g_hWnd);        // Handle to the screen
  152.     HMENU       hMenu = GetMenu(g_hWnd);    // Handle to the menu
  153.     RECT        sRect;
  154.             
  155.     switch(uMsg)
  156.     {
  157.         case WM_COMMAND :
  158.             switch(LOWORD(wParam))
  159.             {
  160.                 case    IDM_MENU_FILE_OPEN  :       // File open was chosen
  161.                     // Get the filename to read
  162.                     if(GetBitmapFileName())
  163.                     {
  164.                         // Read the data from the file. This call will fill
  165.                         // out the global variables g_hBitmap and g_Bitmap
  166.                         if(!ReadBitmapFromFile())
  167.                         {
  168.                             break;
  169.                         }
  170.             
  171.                         // Resize the client area to fit the image
  172.                         GetWindowRect(g_hWnd, &sRect);
  173.                         MoveWindow(g_hWnd,          // Handle to the window
  174.                             sRect.left,             // New X position
  175.                             sRect.top,              // New Y position
  176.                             g_Bitmap.bmWidth +      // New width
  177.                             GetSystemMetrics(SM_CXSIZEFRAME) * 2,
  178.                             g_Bitmap.bmHeight +     // The new height
  179.                             GetSystemMetrics(SM_CYSIZEFRAME) * 2 +
  180.                             GetSystemMetrics(SM_CYMENUSIZE) +   
  181.                             GetSystemMetrics(SM_CYCAPTION),     
  182.                             TRUE);                  // Make a repaint
  183.  
  184.                         // Force an update of the screen
  185.                         GetClientRect(g_hWnd, &sRect);
  186.                         InvalidateRect(g_hWnd, &sRect, TRUE);
  187.                         UpdateWindow(g_hWnd);
  188.  
  189.                         // Enable the rest of the menu options
  190.                         EnableMenuItem(hMenu, IDM_MENU_FILE_CLOSE, 
  191.                             MF_ENABLED);
  192.                         if(GetDeviceCaps(hDC, BITSPIXEL) == 8)
  193.                         {
  194.                             EnableMenuItem(hMenu, IDM_MENU_TOOLS_EDGE, 
  195.                                 MF_ENABLED);
  196.                         }
  197.                         EnableMenuItem(hMenu, IDM_MENU_TOOLS_FLIP, 
  198.                             MF_ENABLED);
  199.                     }   // if(GetBitmapFileName())
  200.                     break;
  201.                 
  202.                 case    IDM_MENU_FILE_CLOSE :   // File close was chosen
  203.                     // If a bitmap has been read in, redraw the client 
  204.                     // area to the background color.
  205.                     if(BITMAP_READ)
  206.                     {
  207.                         // Reset the BITMAP_READ indicator
  208.                         BITMAP_READ = FALSE;
  209.  
  210.                         // Rewrite the screen
  211.                         RedrawClientArea(hDC);
  212.                                 
  213.                         // Disable the menu options
  214.                         EnableMenuItem(hMenu, IDM_MENU_FILE_CLOSE,
  215.                             MF_GRAYED);
  216.                         EnableMenuItem(hMenu, IDM_MENU_TOOLS_EDGE,
  217.                             MF_GRAYED);
  218.                         EnableMenuItem(hMenu, IDM_MENU_TOOLS_FLIP,
  219.                             MF_GRAYED);
  220.  
  221.                         // Delete the bitmap object
  222.                         DeleteObject(g_hBitmap);        
  223.                     }                
  224.                     break;
  225.  
  226.                 case    IDM_MENU_FILE_EXIT  :   // Exit program was chosen
  227.                     PostMessage(g_hWnd, WM_CLOSE, 0, 0);
  228.                     break;
  229.  
  230.                 case    IDM_MENU_TOOLS_EDGE :   // Want to find edges 
  231.                     if (!EDGE_FOUND)
  232.                     {
  233.                         ChangeBitmapRemote(FINDEDGE, &g_hBitmap);
  234.                         RedrawClientArea(hDC);
  235.                         EDGE_FOUND = TRUE;
  236.                     }
  237.                     break;
  238.  
  239.                 case    IDM_MENU_TOOLS_FLIP :   // Want to flip the bitmap
  240.                     ChangeBitmapRemote(FLIPIMAGE, &g_hBitmap);
  241.                     RedrawClientArea(hDC);
  242.                     break;
  243.  
  244.                 case    IDM_MENU_FILE_BINDING:      // Binding dialog box
  245.                     DialogBox(g_hInstance,
  246.                         MAKEINTRESOURCE(IDD_BINDING_DIALOG),
  247.                         hWnd,
  248.                         (DLGPROC) BindingDlgProc);
  249.                     break;
  250.  
  251.                 case    IDM_MENU_ABOUT      :       // About dialog box
  252.                     DialogBox(g_hInstance,
  253.                         MAKEINTRESOURCE(IDD_ABOUT_DIALOG),
  254.                         hWnd,
  255.                         (DLGPROC) AboutDlgProc);
  256.                     break;
  257.             }
  258.             break;
  259.  
  260.         case WM_PAINT :
  261.             BeginPaint(g_hWnd, &sPS);    // Gets a device context
  262.             RedrawClientArea(sPS.hdc);   // Redraws the screen
  263.             EndPaint(g_hWnd, &sPS);      // Releases a device context
  264.             break;
  265.  
  266.         case WM_CLOSE   :               // User requests windows closure
  267.             ShutDown();                 // Shut down the server
  268.             CleanUp();                  // Deallocate some memory
  269.             DestroyWindow(hWnd);        // Generates the WM_DESTROY message
  270.             break;
  271.  
  272.         case WM_DESTROY :
  273.             PostQuitMessage(0);         // Puts a WM_QUIT in the queue
  274.             break;                      // => GetMessage returns NULL
  275.  
  276.         default :
  277.             ReleaseDC(g_hWnd, hDC);
  278.             return DefWindowProc(hWnd, uMsg, wParam, lParam);
  279.     }
  280.     
  281.     ReleaseDC(g_hWnd, hDC);
  282.     return (0L);
  283. }
  284.  
  285.  
  286. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  287. // Procedure    :   void GetBitMapFileName(void)
  288. // Desc.        :   This procedure calls the common dialog box 
  289. //                  GetFileNameOpen to get the filename of a bitmap file
  290. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  291. BOOL GetBitmapFileName(void)
  292. {
  293.     OPENFILENAME    sOfn;       // The OPENFILENAME struct
  294.     
  295.     // Variable used to filter out only the files needed
  296.     LPCTSTR szFilter[] = {TEXT("Windows Bitmaps (*.bmp)"), TEXT("*.bmp"),
  297.                          TEXT("")};
  298.  
  299.     // Fill in the OPENFILENAME Structure
  300.     sOfn.lStructSize         = sizeof(OPENFILENAME);
  301.     sOfn.hwndOwner           = g_hWnd;
  302.     sOfn.hInstance           = g_hInstance;
  303.     sOfn.lpstrFilter         = *szFilter;
  304.     sOfn.lpstrCustomFilter   = NULL;
  305.     sOfn.nMaxCustFilter      = 0;
  306.     sOfn.nFilterIndex        = 0;            
  307.     sOfn.lpstrFile           = g_szFileName; 
  308.     sOfn.nMaxFile            = _MAX_PATH;    
  309.     sOfn.lpstrFileTitle      = NULL;
  310.     sOfn.nMaxFileTitle       = _MAX_FNAME + _MAX_EXT;
  311.     sOfn.lpstrInitialDir     = NULL;         
  312.     sOfn.lpstrTitle          = NULL;
  313.     sOfn.Flags               = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  314.     sOfn.nFileOffset         = 0;
  315.     sOfn.nFileExtension      = 0;
  316.     sOfn.lpstrDefExt         = TEXT("bmp");
  317.     sOfn.lCustData           = 0L;
  318.     sOfn.lpfnHook            = NULL;
  319.     sOfn.lpTemplateName      = NULL;
  320.     
  321.     // This function call will display a Open File dialog box, and read 
  322.     // the name into the the global varaible g_szFileName. It will return
  323.     // TRUE if a filename was chosen, and OK button clicked, else it will 
  324.     // return FALSE
  325.     return GetOpenFileName(&sOfn);
  326. }
  327.  
  328.  
  329. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  330. // Procedure    :   ReadBitmapFromFile()
  331. // Desc.        :   This procedure reads a bitmap from a file and sets the
  332. //                  global variables g_Bitmap and g_hBitmap.
  333. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  334. BOOL ReadBitmapFromFile(void)
  335. {
  336.     UINT    uLoadFlags;
  337.     HDC     hDC = GetDC(g_hWnd);
  338.  
  339.     // Read in the palette from the file. Must do this first, because this
  340.     // procedure checks for valid fileformats
  341.     g_hPalette = LoadPaletteFromFile(g_szFileName);
  342.  
  343.     // If a file has already been read, get rid of that bitmap
  344.     if (BITMAP_READ)
  345.     {
  346.         DeleteObject(g_hBitmap);
  347.         BITMAP_READ = FALSE;
  348.     }
  349.  
  350.     // Load image as a DIB image if its a 256 color image and the screen
  351.     // resolution is in 256 colors
  352.     if(g_BitsPerPixel == 8 && GetDeviceCaps(hDC, BITSPIXEL) == 8)
  353.     {
  354.         uLoadFlags = LR_LOADFROMFILE | LR_CREATEDIBSECTION;
  355.     }
  356.     else
  357.     {
  358.         uLoadFlags = LR_LOADFROMFILE;
  359.     }
  360.  
  361.     // Load the bitmap image in from the global filename found with the
  362.     // GetFileNameOpen common dialogbox
  363.     g_hBitmap = (HBITMAP) LoadImage(
  364.         NULL,                   // Want to load bitmap from file
  365.         g_szFileName,           // Filename where bitmap is stored
  366.         IMAGE_BITMAP,           // Type of image to be loaded
  367.         0, 0,                   // The desired width and height
  368.         uLoadFlags);
  369.     
  370.     // If the reading failed
  371.     if (g_hBitmap == 0)
  372.     {
  373.         return FALSE;
  374.     }
  375.     
  376.     // Obtain the infornation about the bitmap, from the handle returned
  377.     // by the LoadImage function. Must delete this object before quitting
  378.     GetObject(g_hBitmap, sizeof(BITMAP),(LPVOID) &g_Bitmap);
  379.  
  380.     BITMAP_READ = TRUE;         // Let PAINT know what to repaint
  381.     EDGE_FOUND = FALSE;         // Not found the edges in this image yet
  382.  
  383.     return TRUE;
  384. }
  385.  
  386.  
  387. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  388. // Procedure    :   BOOL CALLBACK AboutDlgProc()
  389. // Desc.        :   This procedure is called when the user chooses the
  390. //                  About menu. It displays a Dialogbox defined in the 
  391. //                  client.rc file and returns when the user clicks on the 
  392. //                  OK button
  393. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  394. BOOL CALLBACK AboutDlgProc(HWND hDlg, 
  395.                            UINT uMsg, 
  396.                            WPARAM wParam, 
  397.                            LPARAM lParam)
  398. {
  399.     switch(uMsg)
  400.     {
  401.         case WM_INITDIALOG :            // Return TRUE, windows sets the
  402.             return TRUE;                // focus on the OK button
  403.  
  404.         case WM_COMMAND :
  405.             switch(LOWORD(wParam))
  406.             {
  407.                 case IDOK:              // If the user clicks the OK button
  408.                     EndDialog(hDlg, 0); // Take the dialogbox away
  409.                     return TRUE;
  410.             }
  411.         default:
  412.             return FALSE;           // Windows should handle the message
  413.   }
  414. }
  415.  
  416.  
  417. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  418. // Procedure    :   BOOL CALLBACK BindingDlgProc()
  419. // Desc.        :   This procedure is called when the user chooses Server 
  420. //                  from the File menu. It displays a dialogbox defined in
  421. //                  the client.rc file. Here the user can enter a specific
  422. //                  binding to a remote server by specifying the network - 
  423. //                  protocol and the endpoint to use, and the name of the 
  424. //                  machine that runs the server program.
  425. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  426. BOOL CALLBACK BindingDlgProc(HWND hDlg, 
  427.                              UINT uMsg, 
  428.                              WPARAM wParam, 
  429.                              LPARAM lParam)
  430. {
  431.     switch (uMsg) 
  432.     {
  433.         case WM_INITDIALOG:
  434.             // Fill in the edit boxes with the current values
  435.             SetDlgItemText((HANDLE)hDlg, IDC_PROTSEQ_NAME, 
  436.                 pszProtocolSequence);
  437.             SetDlgItemText((HANDLE)hDlg, IDC_ENDPOINT_NAME, pszEndpoint);
  438.             SetDlgItemText((HANDLE)hDlg, IDC_SERVER_NAME, 
  439.                 pszNetworkAddress);
  440.             return(TRUE);
  441.  
  442.         case WM_COMMAND:   
  443.             switch(LOWORD(wParam)) 
  444.             {
  445.                 case IDCANCEL:     // Cancel button clicked
  446.                     EndDialog(hDlg, FALSE);
  447.                     return(TRUE);
  448.  
  449.                 case IDOK:         // OK button clicked
  450.                     GetDlgItemText(hDlg, IDC_PROTSEQ_NAME, 
  451.                         pszProtocolSequence, 30);
  452.                     GetDlgItemText(hDlg, IDC_SERVER_NAME, 
  453.                         pszNetworkAddress, 30);
  454.                     GetDlgItemText(hDlg, IDC_ENDPOINT_NAME, 
  455.                         pszEndpoint, 30);
  456.  
  457.                     // If we get a binding, all is OK
  458.                     if (Bind(hDlg) == RPC_S_OK) 
  459.                     {
  460.                         EndDialog(hDlg, FALSE);
  461.                         return(TRUE);
  462.                     }
  463.                     // If we couldn't bind, just keep asking for new input
  464.             }   // switch((LOWORD(WPARAM))
  465.     }   // switch(uMsg)
  466.  
  467.     return(FALSE);  // Didn't process a message
  468. }
  469.  
  470.  
  471. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  472. // Procedure    :   RedrawClientArea(HDC)
  473. // Desc.        :   This procedure redraw the client area by either 
  474. //                  displaying the bitmap, or simply drawing a gray 
  475. //                  background.
  476. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  477. void RedrawClientArea(HDC hDC)                // Handle to the screen
  478. {
  479.     HDC     hDCMem;         // A memory device context
  480.     RECT    sRect;          // Rectangle containing the entire client area
  481.  
  482.     // Do a check to see if the bitmap has been read in. If it hasn't, we 
  483.     // leave the screen blank
  484.     if(BITMAP_READ)
  485.     {
  486.         if(g_BitsPerPixel == 8 && g_hPalette != 0)
  487.         {
  488.             // Select and realize the palette to use
  489.             SelectPalette(hDC, g_hPalette, TRUE);
  490.             RealizePalette(hDC);
  491.         }
  492.             
  493.         hDCMem = CreateCompatibleDC(hDC);
  494.         SelectObject (hDCMem, g_hBitmap);
  495.         SetMapMode (hDCMem, GetMapMode(hDC));
  496.  
  497.         // Draw the bitmap using the BitBlt function
  498.         if(BitBlt(
  499.             hDC,                // The destination device context
  500.             0, 0,               // Coordinates of the destination rectangle
  501.             g_Bitmap.bmWidth,   // Width of the dest. and source rectangle
  502.             g_Bitmap.bmHeight,    // Height of the dest. and source rectangle
  503.             hDCMem,
  504.             0, 0,
  505.             SRCCOPY))
  506.         {
  507.             DeleteDC(hDCMem);
  508.         }
  509.     }
  510.     else        // We want to wipe the screen with the background color
  511.     {
  512.         GetClientRect(g_hWnd,  &sRect);
  513.         FillRect(hDC, &sRect, GetStockObject(GRAY_BRUSH));
  514.     }
  515.     return;
  516. }
  517.  
  518.  
  519. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  520. // Funciton     :   LoadPaletteFromFile
  521. // Desc.        :   This procedure loads a palette froma dib-file. It 
  522. //                  checks to see that this is a 256-color image, and
  523. //                  then reads in the palette, and returns a handle
  524. //                  to it
  525. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  526. HPALETTE LoadPaletteFromFile(LPTSTR lpszFileName)
  527. {
  528.     HANDLE              hFile;          // Bitmap filename
  529.     HPALETTE            hPalette;       // Handle to the palette
  530.     HANDLE              hMem,           // A handle to a memory location
  531.                         hCore;          // Handle to memory
  532.     DWORD               dwBitmapType,   // The type of the bitmap
  533.                         dwSize;         // A size of memory to allocate
  534.     int                 nIdx,           // Index in loops
  535.                         nPalEntries;    // # of entries in the palette
  536.     LPSTR               lpCore;         // Pointer to memory bytes
  537.     LPLOGPALETTE        lpMem;          // A mem pointer to the LOGPALETTE
  538.     BITMAPFILEHEADER    sBFH;           // This is always filled in
  539.     BITMAPINFOHEADER    sBIH;           // Used if this is a Windows bitmap
  540.     BITMAPCOREHEADER    sBCH;           // Used if this is a OS/2 bitmap
  541.     DWORD               dwDummy;
  542.  
  543.     // Initialize the palette handle to NULL
  544.     hPalette = NULL;
  545.  
  546.     // Open the file where the bitmap is stored
  547.     hFile = CreateFile(
  548.         lpszFileName, 
  549.         GENERIC_READ, 
  550.         FILE_SHARE_READ,
  551.         NULL,
  552.         OPEN_EXISTING,
  553.         FILE_ATTRIBUTE_NORMAL,
  554.         0);
  555.     if(hFile != 0)
  556.     {
  557.         // Read the BITMAPFILEHEADER from the file
  558.         if (ReadFile(hFile, &sBFH,sizeof(BITMAPFILEHEADER), 
  559.             &dwDummy, NULL))
  560.         {
  561.             // Any valid bitmap file should have filetype = 'BM'
  562.             if(sBFH.bfType == (UINT)0x4D42)
  563.             {
  564.                 // Determine type of bitmap.
  565.                 // The next WORD (4 bytes) in the file (offset 14) will be
  566.                 // either 40 - indicating that this is a Windows Bitmap, 
  567.                 // and therefore will be using a BITMAPINFOHEADER, or it 
  568.                 // will be 14 - indicating that this is a OS/2 1.x bitmap,
  569.                 // and therefore will be using a BITMAPCOREHEADER. 14 and 
  570.                 // 40 are the respective sizes of the HEADERS
  571.                 ReadFile(hFile, &dwBitmapType, sizeof(DWORD), 
  572.                     &dwDummy, NULL);
  573.                 SetFilePointer(hFile,sizeof(BITMAPFILEHEADER),
  574.                     NULL, FILE_BEGIN);
  575.     
  576.                 // Load up INFO header.  If bitmap is a CORE
  577.                 // header, then we need to convert to INFO header.
  578.                 if(dwBitmapType == sizeof(BITMAPCOREHEADER))
  579.                 {
  580.                     // Read in the COREHEADER
  581.                     ReadFile(hFile, &sBCH,sizeof(BITMAPCOREHEADER), 
  582.                         &dwDummy, NULL);
  583.                 
  584.                     // Fill out the missing parts of the INFOHEADER
  585.                     sBIH.biSize          = sizeof(BITMAPINFOHEADER);
  586.                     sBIH.biWidth         = sBCH.bcWidth;
  587.                     sBIH.biHeight        = sBCH.bcHeight;
  588.                     sBIH.biPlanes        = sBCH.bcPlanes;
  589.                     sBIH.biBitCount      = sBCH.bcBitCount;
  590.                     sBIH.biCompression   = BI_RGB;
  591.                     sBIH.biSizeImage     = 0;
  592.                     sBIH.biXPelsPerMeter = 0;
  593.                     sBIH.biYPelsPerMeter = 0;
  594.                     sBIH.biClrUsed       = 0;
  595.                     sBIH.biClrImportant  = 0;
  596.                 }
  597.                 else
  598.                 {
  599.                     // Read in the INFOHEADER
  600.                     ReadFile(hFile, &sBIH,sizeof(BITMAPINFOHEADER), 
  601.                         &dwDummy, NULL);
  602.                 }
  603.  
  604.                 //-------------------------
  605.                 // Palette creation
  606.                 //-------------------------
  607.  
  608.                 // Figure out the number of entries in the palette
  609.                 // i.e. if the number of Bits per pixel (biBitCount) is 8,
  610.                 // the number of palette entries will be 1 << 8 = 256
  611.                 nPalEntries = ((UINT)1 << sBIH.biBitCount);
  612.                 g_BitsPerPixel = sBIH.biBitCount;
  613.        
  614.                 // Determine the size of the memory to allocate 
  615.                 // (The size of all mem needed for the palette)
  616.                 dwSize   = sizeof(LOGPALETTE) + 
  617.                     (nPalEntries * sizeof(PALETTEENTRY));
  618.  
  619.                 // Aloocate space for the palette. this just returns a 
  620.                 // handle to the memory. We must use the function 
  621.                 // GlobalLock to get a pointer to the memory
  622.                 if(hMem = GlobalAlloc(GHND,dwSize))
  623.                 {
  624.                     // Extract a pointer to the memory just allocated, and
  625.                     // cast it as a pointer to a LOGPALETTE struct
  626.                     if(lpMem = (LPLOGPALETTE)GlobalLock(hMem))
  627.                     {
  628.                         // Set LogPalette structure.
  629.                         lpMem->palVersion    = 0x0300;
  630.                         lpMem->palNumEntries = nPalEntries;
  631.  
  632.                         // Read in ColorTable. COREHEADER files uses the 
  633.                         // RGB triplet to store the values of the palette
  634.                         if(dwBitmapType == sizeof(BITMAPCOREHEADER))
  635.                         {
  636.                             // Calculate the size of color map
  637.                             dwSize = (nPalEntries * sizeof(RGBTRIPLE));
  638.  
  639.                             // Allocate memory to store this in
  640.                             if(hCore = GlobalAlloc(GHND,dwSize))
  641.                             {
  642.                                 // Get a pointer to the memory,and LOCK it
  643.                                 if(lpCore = GlobalLock(hCore))
  644.                                 {
  645.                                     // Read the palette data into memory
  646.                                     ReadFile(hFile, lpCore, dwSize, 
  647.                                         &dwDummy, NULL);
  648.     
  649.                                     // Put the palette data into the 
  650.                                     // palette struct
  651.                                     for(nIdx=0; nIdx < nPalEntries; nIdx++)
  652.                                     {
  653.                                         lpMem->palPalEntry[nIdx].peBlue  = 
  654.                                             (((RGBTRIPLE FAR * )lpCore) + nIdx)->rgbtBlue;
  655.                                         lpMem->palPalEntry[nIdx].peGreen = 
  656.                                             (((RGBTRIPLE FAR * )lpCore)+nIdx)->rgbtGreen;
  657.                                         lpMem->palPalEntry[nIdx].peRed   = 
  658.                                             (((RGBTRIPLE FAR * )lpCore)+nIdx)->rgbtRed;
  659.                                         lpMem->palPalEntry[nIdx].peFlags = 0;
  660.                                     }
  661.  
  662.                                     // Unlock the memory used
  663.                                     GlobalUnlock(hCore);
  664.                                 }
  665.  
  666.                                 // Free up the memory used
  667.                                 GlobalFree(hCore);
  668.                             }
  669.                         }
  670.                         else
  671.                         {
  672.                             // The INFOHEADER version of a bitmap file uses
  673.                             // RGB Quads to store the color map
  674.                             dwSize = (nPalEntries * sizeof(RGBQUAD));
  675.  
  676.                             // Allocate memory to store this in
  677.                             if(hCore = GlobalAlloc(GHND,dwSize))
  678.                             {
  679.                                 // Get a pointer to the memory,and LOCK it
  680.                                 if(lpCore = GlobalLock(hCore))
  681.                                 {
  682.                                     // Read the palette data into memory
  683.                                     ReadFile(hFile, lpCore,dwSize, 
  684.                                         &dwDummy, NULL);
  685.  
  686.                                     // Put the palette data into the 
  687.                                     // palette struct
  688.                                     for(nIdx=0; nIdx < nPalEntries; nIdx++)
  689.                                     {
  690.                                         lpMem->palPalEntry[nIdx].peBlue  = 
  691.                                             (((LPRGBQUAD)lpCore)+nIdx)->rgbBlue;
  692.                                         lpMem->palPalEntry[nIdx].peGreen = 
  693.                                             (((LPRGBQUAD)lpCore)+nIdx)->rgbGreen;
  694.                                         lpMem->palPalEntry[nIdx].peRed   = 
  695.                                             (((LPRGBQUAD)lpCore)+nIdx)->rgbRed;
  696.                                         lpMem->palPalEntry[nIdx].peFlags = 0;
  697.                                     }
  698.                                     
  699.                                     // UNLOCK the data just used
  700.                                     GlobalUnlock(hCore);
  701.                                 }
  702.  
  703.                                 // Free up the memory used to store the 
  704.                                 // palette data
  705.                                 GlobalFree(hCore);
  706.                             }
  707.                         }
  708.  
  709.                         // Create a handle to the palette
  710.                         hPalette = CreatePalette(lpMem);
  711.  
  712.                         // Unlock the memory used for storing the data to
  713.                         // the LOGPALETTE
  714.                         GlobalUnlock(hMem);
  715.                     }
  716.  
  717.                     // Free up the memory used by the LOGPALETTE structure
  718.                     GlobalFree(hMem);
  719.                 }
  720.             }
  721.         }
  722.         else        // This is NOT a bitmap file
  723.         {                    
  724.             PRINT(TEXT("This is not a BITMAP file"), 
  725.                 TEXT("Invalid Fileformat"));
  726.             return FALSE;
  727.         }
  728.  
  729.  
  730.         // Close the file we have been reading from
  731.         CloseHandle(hFile);
  732.     }
  733.  
  734.     // Return the handle to the palette to the calling structure
  735.     return(hPalette);
  736. }
  737.  
  738.  
  739.  
  740. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  741. // Procedure    :   RPC_STATUS Bind(HWND)
  742. // Desc.        :   This procedure will make RPC API calls to bind to the 
  743. //                  server application.
  744. //                  The binding calls are made from Init() and whenever
  745. //                  the user changes the server name or endpoint. If the 
  746. //                  bind operation is successful, the global flag fBound 
  747. //                  is set to TRUE. The global flag fBound is used to 
  748. //                  determine whether to call the RPC API function 
  749. //                  RpcBindingFree.
  750. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  751. RPC_STATUS Bind(HWND hWnd)
  752. {
  753.     RPC_STATUS nStatus;
  754.     
  755.     if (g_bBound == TRUE)     // unbind only if bound
  756.     {  
  757.         nStatus = RpcStringFree(&pszStringBinding);
  758.         if (nStatus) 
  759.         {
  760.             _stprintf(szBuffer,TEXT("RpcStringFree failed 0x%x"), nStatus);
  761.             MessageBox(hWnd,
  762.                        szBuffer,
  763.                        TEXT("RPC Sample Application"),
  764.                        MB_ICONSTOP);
  765.             return(nStatus);
  766.         }
  767.  
  768.         nStatus = RpcBindingFree(&global_wintyp_sample_handle);
  769.         if (nStatus) 
  770.         {
  771.             _stprintf(szBuffer,TEXT("RpcBindingFree failed 0x%x"), nStatus);
  772.             MessageBox(hWnd,
  773.                        szBuffer,
  774.                        TEXT("RPC Sample Application"),
  775.                        MB_ICONSTOP);
  776.             return(nStatus);
  777.         }
  778.  
  779.         g_bBound = FALSE;  // unbind successful; reset flag
  780.     }
  781.  
  782.     nStatus = RpcStringBindingCompose(pszUuid,
  783.                                      pszProtocolSequence,
  784.                                      pszNetworkAddress,
  785.                                      pszEndpoint,
  786.                                      pszOptions,
  787.                                      &pszStringBinding);
  788.     if (nStatus) 
  789.     {
  790.         _stprintf(szBuffer, 
  791.             TEXT("RpcStringBindingCompose returned : (0x%x)\nNetwork Address = %s\n"),
  792.             nStatus, pszNetworkAddress);
  793.         MessageBox(hWnd, szBuffer, TEXT("RPC Sample Application"), 
  794.             MB_ICONINFORMATION);
  795.         return(nStatus);
  796.     }
  797.  
  798.     nStatus = RpcBindingFromStringBinding(pszStringBinding,
  799.                             &global_wintyp_sample_handle);
  800.     if (nStatus) 
  801.     {
  802.         _stprintf(szBuffer, 
  803.             TEXT("RpcBindingFromStringBinding returned: (0x%x)\nString = %s\n"),
  804.              nStatus, pszStringBinding);
  805.         MessageBox(hWnd, szBuffer, TEXT("RPC Sample Application"), 
  806.             MB_ICONINFORMATION);
  807.         return(nStatus);
  808.     }
  809.  
  810.     g_bBound = TRUE;  // bind successful; reset flag
  811.  
  812.     return(nStatus);
  813. }
  814.  
  815. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  816. // Procedure    :   CleanUp()
  817. // Desc.        :   This procedure deletes the object, and the memory used
  818. //                  in the program.
  819. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  820. void CleanUp(void)
  821. {
  822.     // Destroy the object used for the bitmap
  823.     DeleteObject(g_hBitmap);
  824.  
  825.     // Delete the space taken up by the binding 
  826.     if (g_bBound)
  827.     {
  828.         status = RpcStringFree(&pszStringBinding);
  829.         if (status) 
  830.         {
  831.             _stprintf(szBuffer,TEXT("RpcStringFree failed 0x%x"), status);
  832.             MessageBox(g_hWnd,
  833.                        szBuffer,
  834.                        TEXT("RPC Sample Application"),
  835.                        MB_ICONSTOP);
  836.             exit(EXECUTION_FAILED);
  837.         }
  838.  
  839.         status = RpcBindingFree(&global_wintyp_sample_handle);
  840.         if (status) 
  841.         {
  842.             _stprintf(szBuffer,TEXT("RpcBindingFree failed 0x%x"), status);
  843.             MessageBox(g_hWnd,
  844.                        szBuffer,
  845.                        TEXT("RPC Sample Application"),
  846.                        MB_ICONSTOP);
  847.             exit(EXECUTION_FAILED);
  848.         }
  849.     }
  850. }
  851.  
  852.  
  853. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  854. // Procedure    :   midl_user_allocate() and midl_user_free()           
  855. // Desc.        :   These procedure are declared in the header file     
  856. //                  generated by the midl compiler. These procedures    
  857. //                  should be used for all memory allocation and        
  858. //                  deallocation.                                       
  859. //                  These procedures are also called by the stub code to
  860. //                  allocate and free memory.                           
  861. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  862. void __RPC_FAR * __RPC_API midl_user_allocate(size_t nLen)
  863. {
  864.     return (malloc(nLen));
  865. }
  866.  
  867. void __RPC_API midl_user_free(void __RPC_FAR * lpvPointer)
  868. {
  869.     if(NULL != lpvPointer)
  870.         free (lpvPointer);
  871. }
  872.