home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 7.ddi / MWHC.007 / F6 < prev    next >
Encoding:
Text File  |  1991-10-24  |  14.2 KB  |  406 lines

  1. /*----------------------------------------
  2.    SHOWPOP.C -- DDE Client using DDEPOP
  3.                 (c) Charles Petzold, 1990
  4.   ----------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <dde.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11.  
  12. struct
  13.      {
  14.      char *szAbb ;
  15.      char *szState ;
  16.      long lPop ;
  17.      }
  18.      pop [] = {
  19.               "AL", "Alabama",             0, "AK", "Alaska",              0,
  20.               "AZ", "Arizona",             0, "AR", "Arkansas",            0,
  21.               "CA", "California",          0, "CO", "Colorado",            0,
  22.               "CT", "Connecticut",         0, "DE", "Delaware",            0,
  23.               "DC", "Dist. of Columbia",   0, "FL", "Florida",             0,
  24.               "GA", "Georgia",             0, "HI", "Hawaii",              0,
  25.               "ID", "Idaho",               0, "IL", "Illinois",            0,
  26.               "IN", "Indiana",             0, "IA", "Iowa",                0,
  27.               "KS", "Kansas",              0, "KY", "Kentucky",            0,
  28.               "LA", "Louisiana",           0, "ME", "Maine",               0,
  29.               "MD", "Maryland",            0, "MA", "Massachusetts",       0,
  30.               "MI", "Michigan",            0, "MN", "Minnesota",           0,
  31.               "MS", "Mississippi",         0, "MO", "Missouri",            0,
  32.               "MT", "Montana",             0, "NE", "Nebraska",            0,
  33.               "NV", "Nevada",              0, "NH", "New Hampshire",       0,
  34.               "NJ", "New Jersey",          0, "NM", "New Mexico",          0,
  35.               "NY", "New York",            0, "NC", "North Carolina",      0,
  36.               "ND", "North Dakota",        0, "OH", "Ohio",                0,
  37.               "OK", "Oklahoma",            0, "OR", "Oregon",              0,
  38.               "PA", "Pennsylvania",        0, "RI", "Rhode Island",        0,
  39.               "SC", "South Carolina",      0, "SD", "South Dakota",        0,
  40.               "TN", "Tennessee",           0, "TX", "Texas",               0,
  41.               "UT", "Utah",                0, "VT", "Vermont",             0,
  42.               "VA", "Virginia",            0, "WA", "Washington",          0,
  43.               "WV", "West Virginia",       0, "WI", "Wisconsin",           0,
  44.               "WY", "Wyoming",             0, "US", "United States Total", 0
  45.               } ;
  46.  
  47. #define NUM_STATES       (sizeof (pop) / sizeof (pop [0]))
  48. #define WM_USER_INITIATE (WM_USER + 1)
  49. #define DDE_TIMEOUT      3000
  50.  
  51. long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;
  52.  
  53. char   szAppName [] = "ShowPop" ;
  54.  
  55. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  56.                     LPSTR lpszCmdLine, int nCmdShow)
  57.      {
  58.      HWND     hwnd ;
  59.      MSG      msg ;
  60.      WNDCLASS wndclass ;
  61.  
  62.      if (!hPrevInstance) 
  63.           {
  64.           wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  65.           wndclass.lpfnWndProc   = WndProc ;
  66.           wndclass.cbClsExtra    = 0 ;
  67.           wndclass.cbWndExtra    = 0 ;
  68.           wndclass.hInstance     = hInstance ;
  69.           wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
  70.           wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  71.           wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
  72.           wndclass.lpszMenuName  = NULL ;
  73.           wndclass.lpszClassName = szAppName ;
  74.  
  75.           RegisterClass (&wndclass) ;
  76.           }
  77.  
  78.      hwnd = CreateWindow (szAppName, "DDE Client - US Population",
  79.                           WS_OVERLAPPEDWINDOW,
  80.                           CW_USEDEFAULT, CW_USEDEFAULT,
  81.                           CW_USEDEFAULT, CW_USEDEFAULT,
  82.                           NULL, NULL, hInstance, NULL) ;
  83.  
  84.      ShowWindow (hwnd, nCmdShow) ;
  85.      UpdateWindow (hwnd) ;
  86.  
  87.      SendMessage (hwnd, WM_USER_INITIATE, 0, 0L) ;
  88.  
  89.      while (GetMessage (&msg, NULL, 0, 0))
  90.           {
  91.           TranslateMessage (&msg) ;
  92.           DispatchMessage (&msg) ;
  93.           }
  94.      return msg.wParam ;
  95.      }
  96.  
  97. long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  98.      {
  99.      static BOOL   fDoingInitiate = TRUE ;
  100.      static char   szServerApp [] = "DdePop",
  101.                    szTopic     [] = "US_Population" ;
  102.      static HWND   hwndServer = NULL ;
  103.      static short  cxChar, cyChar ;
  104.      ATOM          aApp, aTop, aItem ;
  105.      char          szBuffer [24], szPopulation [16], szItem [16] ;
  106.      DDEACK        DdeAck ;
  107. #ifdef __HIGHC__
  108.      LPDDEDATA     lpDdeData ;
  109.      LPDDEADVISE   lpDdeAdvise ;
  110. #else
  111.      DDEDATA FAR   *lpDdeData ;
  112.      DDEADVISE FAR *lpDdeAdvise ;
  113. #endif
  114.      DWORD         dwTime ;
  115.      GLOBALHANDLE  hDdeAdvise, hDdeData ;
  116.      HDC           hdc ;
  117.      MSG           msg ;
  118.      PAINTSTRUCT   ps ;
  119.      short         i, x, y ;
  120.      TEXTMETRIC    tm ;
  121.      WORD          wStatus, cfFormat ;
  122.  
  123.      switch (message)
  124.           {
  125.           case WM_CREATE:
  126.                hdc = GetDC (hwnd) ;
  127.                GetTextMetrics (hdc, &tm) ;
  128.                cxChar = tm.tmAveCharWidth ;
  129.                cyChar = tm.tmHeight + tm.tmExternalLeading ;
  130.                ReleaseDC (hwnd, hdc) ;
  131.                return 0 ;
  132.  
  133.           case WM_USER_INITIATE:
  134.  
  135.                      // Broadcast WM_DDE_INITIATE message
  136.  
  137.                aApp = GlobalAddAtom (szServerApp) ;
  138.                aTop = GlobalAddAtom (szTopic) ;
  139.  
  140.                SendMessage (0xFFFF, WM_DDE_INITIATE, hwnd,
  141.                             MAKELONG (aApp, aTop)) ;
  142.  
  143.                      // If no response, try loading DDEPOP first
  144.  
  145.                if (hwndServer == NULL)
  146.                     {
  147.                     WinExec (szServerApp, SW_SHOWMINNOACTIVE) ;
  148.  
  149.                     SendMessage (0xFFFF, WM_DDE_INITIATE, hwnd,
  150.                                  MAKELONG (aApp, aTop)) ;
  151.                     }
  152.  
  153.                     // Delete the atoms
  154.  
  155.                GlobalDeleteAtom (aApp) ;
  156.                GlobalDeleteAtom (aTop) ;
  157.                fDoingInitiate = FALSE ;
  158.  
  159.                     // If still no response, display message box
  160.  
  161.                if (hwndServer == NULL)
  162.                     {
  163.                     MessageBox (hwnd, "Cannot connect with DDEPOP.EXE!",
  164.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  165.  
  166.                     return 0 ;
  167.                     }
  168.  
  169.                     // Post WM_DDE_ADVISE messages
  170.  
  171.                for (i = 0 ; i < NUM_STATES ; i++)
  172.                     {
  173.                     hDdeAdvise = GlobalAlloc (GHND | GMEM_DDESHARE,
  174.                                               sizeof (DDEADVISE)) ;
  175.  
  176. #ifdef __HIGHC__
  177.                     lpDdeAdvise = (LPDDEADVISE) GlobalLock (hDdeAdvise) ;
  178. #else
  179.                     lpDdeAdvise = (DDEADVISE FAR *) GlobalLock (hDdeAdvise) ;
  180. #endif
  181.  
  182.                     lpDdeAdvise->fAckReq   = TRUE ;
  183.                     lpDdeAdvise->fDeferUpd = FALSE ;
  184.                     lpDdeAdvise->cfFormat  = CF_TEXT ;
  185.  
  186.                     GlobalUnlock (hDdeAdvise) ;
  187.  
  188.                     aItem = GlobalAddAtom (pop[i].szAbb) ;
  189.  
  190.                     if (!PostMessage (hwndServer, WM_DDE_ADVISE, hwnd,
  191.                                       MAKELONG (hDdeAdvise, aItem)))
  192.                          {
  193.                          GlobalFree (hDdeAdvise) ;
  194.                          GlobalDeleteAtom (aItem) ;
  195.                          break ;
  196.                          }
  197.  
  198.                     DdeAck.fAck = FALSE ;
  199.  
  200.                     dwTime = GetCurrentTime () ;
  201.  
  202.                     while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
  203.                          {
  204.                          if (PeekMessage (&msg, hwnd, WM_DDE_ACK,
  205.                                           WM_DDE_ACK, PM_REMOVE))
  206.                               {
  207.                               GlobalDeleteAtom (HIWORD (msg.lParam)) ;
  208.  
  209. #ifdef __HIGHC__
  210.                               DdeAck = * (DDEACK *) & msg.lParam;
  211. #else
  212.                               DdeAck = * (DDEACK *) & LOWORD (msg.lParam);
  213. #endif
  214.  
  215.                               if (DdeAck.fAck == FALSE)
  216.                                    GlobalFree (hDdeAdvise) ;
  217.  
  218.                               break ;
  219.                               }
  220.                          }
  221.  
  222.                     if (DdeAck.fAck == FALSE)
  223.                          break ;
  224.  
  225.                     while (PeekMessage (&msg, hwnd, WM_DDE_FIRST,
  226.                                         WM_DDE_LAST, PM_REMOVE))
  227.                          {
  228.                          DispatchMessage (&msg) ;
  229.                          }
  230.                     }
  231.  
  232.                if (i < NUM_STATES)
  233.                     {
  234.                     MessageBox (hwnd, "Failure on WM_DDE_ADVISE!",
  235.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  236.                     }
  237.                return 0 ;
  238.  
  239.           case WM_DDE_ACK:
  240.  
  241.                     // In response to WM_DDE_INITIATE, save server window
  242.  
  243.                if (fDoingInitiate)
  244.                     {
  245.                     hwndServer = wParam ;
  246.                     GlobalDeleteAtom (LOWORD (lParam)) ;
  247.                     GlobalDeleteAtom (HIWORD (lParam)) ;
  248.                     }
  249.                return 0 ;
  250.  
  251.           case WM_DDE_DATA:
  252.  
  253.                     // wParam          -- sending window handle
  254.                     // LOWORD (lParam) -- DDEDATA memory handle
  255.                     // HIWORD (lParam) -- item atom
  256.  
  257.                hDdeData  = LOWORD (lParam) ;
  258. #ifdef __HIGHC__
  259.                lpDdeData = (LPDDEDATA) GlobalLock (hDdeData) ;
  260. #else
  261.                lpDdeData = (DDEDATA FAR *) GlobalLock (hDdeData) ;
  262. #endif
  263.                aItem     = HIWORD (lParam) ;
  264.  
  265.                     // Initialize DdeAck structure
  266.  
  267.                DdeAck.bAppReturnCode = 0 ;
  268.                DdeAck.reserved       = 0 ;
  269.                DdeAck.fBusy          = FALSE ;
  270.                DdeAck.fAck           = FALSE ;
  271.  
  272.                     // Check for matching format and data item
  273.  
  274.                if (lpDdeData->cfFormat == CF_TEXT)
  275.                     {
  276.                     GlobalGetAtomName (aItem, szItem, sizeof (szItem)) ;
  277.  
  278.                     for (i = 0 ; i < NUM_STATES ; i++)
  279.                          if (strcmp (szItem, pop[i].szAbb) == 0)
  280.                               break ;
  281.  
  282.                     if (i < NUM_STATES)
  283.                          {
  284.                          lstrcpy (szPopulation, lpDdeData->Value) ;
  285.                          pop[i].lPop = atol (szPopulation) ;
  286.                          InvalidateRect (hwnd, NULL, FALSE) ;
  287.  
  288.                          DdeAck.fAck = TRUE ;
  289.                          }
  290.                     }
  291.  
  292.                     // Acknowledge if necessary
  293.  
  294.                if (lpDdeData->fAckReq == TRUE)
  295.                     {
  296.                     wStatus = * (WORD *) & DdeAck ;
  297.  
  298.                     if (!PostMessage (wParam, WM_DDE_ACK, hwnd,
  299.                                       MAKELONG (wStatus, aItem)))
  300.                          {
  301.                          GlobalDeleteAtom (aItem) ;
  302.                          GlobalUnlock (hDdeData) ;
  303.                          GlobalFree (hDdeData) ;
  304.                          return 0 ;
  305.                          }
  306.                     }
  307.                else
  308.                     {
  309.                     GlobalDeleteAtom (aItem) ;
  310.                     }
  311.  
  312.                     // Clean up
  313.  
  314.                if (lpDdeData->fRelease == TRUE || DdeAck.fAck == FALSE)
  315.                     {
  316.                     GlobalUnlock (hDdeData) ;
  317.                     //GlobalFree (hDdeData) ;
  318.                     }
  319.                else
  320.                     {
  321.                     GlobalUnlock (hDdeData) ;
  322.                     }
  323.  
  324.                return 0 ;
  325.  
  326.           case WM_PAINT:
  327.                hdc = BeginPaint (hwnd, &ps) ;
  328.  
  329.                for (i = 0 ; i < NUM_STATES ; i++)
  330.                     {
  331.                     if (i < (NUM_STATES + 1) / 2)
  332.                          {
  333.                          x = cxChar ;
  334.                          y = i * cyChar ;
  335.                          }
  336.                     else
  337.                          {
  338.                          x = 44 * cxChar ;
  339.                          y = (i - (NUM_STATES + 1) / 2) * cyChar ;
  340.                          }
  341.  
  342.                     TextOut (hdc, x, y, szBuffer,
  343.                              wsprintf (szBuffer, "%-20s",
  344.                                        (LPSTR) pop[i].szState)) ;
  345.  
  346.                     x += 36 * cxChar ;
  347.  
  348.                     SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
  349.  
  350.                     TextOut (hdc, x, y, szBuffer,
  351.                              wsprintf (szBuffer, "%10ld", pop[i].lPop)) ;
  352.  
  353.                     SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
  354.                     }
  355.  
  356.                EndPaint (hwnd, &ps) ;
  357.                return 0 ;
  358.  
  359.           case WM_DDE_TERMINATE:
  360.  
  361.                     // Respond with another WM_DDE_TERMINATE message
  362.  
  363.                PostMessage (hwndServer, WM_DDE_TERMINATE, hwnd, 0L) ;
  364.                hwndServer = NULL ;
  365.                return 0 ;
  366.  
  367.           case WM_CLOSE:
  368.                if (hwndServer == NULL)
  369.                     break ;
  370.  
  371.                     // Post WM_DDE_UNADVISE message
  372.  
  373.                PostMessage (hwndServer, WM_DDE_UNADVISE, hwnd,
  374.                             MAKELONG (CF_TEXT, NULL)) ;
  375.  
  376.                dwTime = GetCurrentTime () ;
  377.  
  378.                while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
  379.                     {
  380.                     if (PeekMessage (&msg, hwnd, WM_DDE_ACK,
  381.                                      WM_DDE_ACK, PM_REMOVE))
  382.                          break ;
  383.                     }
  384.  
  385.                     // Post WM_DDE_TERMINATE message
  386.  
  387.                PostMessage (hwndServer, WM_DDE_TERMINATE, hwnd, 0L) ;
  388.  
  389.                dwTime = GetCurrentTime () ;
  390.  
  391.                while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
  392.                     {
  393.                     if (PeekMessage (&msg, hwnd, WM_DDE_TERMINATE,
  394.                                      WM_DDE_TERMINATE, PM_REMOVE))
  395.                          break ;
  396.                     }
  397.  
  398.                break ;             // for default processing
  399.  
  400.           case WM_DESTROY:
  401.                PostQuitMessage (0) ;
  402.                return 0 ;
  403.           }
  404.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  405.      }
  406.