home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / ipc / ddeml / ddeinst / ddeprocs.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  19KB  |  541 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /*
  13.    ddeprocs.c
  14. */
  15.  
  16. #include <windows.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include "ddeinst.h"
  20. #include "ddextrn.h"
  21. #include "dialogs.h"
  22.  
  23. // function prototype for List synchronization
  24. void   SynchronizeLists (HWND);
  25. void   SynchronizeListSelection (HWND);
  26.  
  27. // function prototype for child window creation 
  28. void   CreateChildren (HWND);
  29.  
  30. // internal thread counter
  31. int    iThreadCount = 0;
  32.  
  33. /********************************************************************
  34.  
  35.    MainWndProc.
  36.    
  37.    Function that processes the messages sent to the main window.
  38.  
  39. ********************************************************************/
  40.  
  41. LRESULT APIENTRY MainWndProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
  42.       LPARAM lParam) {
  43.    BOOL        fFlag;
  44.  
  45.    switch (uiMsg) {
  46.       case WM_CREATE: {
  47.  
  48. // Create all of the child windows that are desired.
  49.          CreateChildren (hwnd);
  50.          break;
  51.       }/*endCase*/
  52.       case WM_DESTROY: {
  53.          PostQuitMessage (0);
  54.          return (0L);
  55.       }/*endCase*/
  56.       case WM_USER_CLOSE_DIALOG: {
  57.          if (hwndDialog) {
  58.             DestroyWindow (hwndDialog);
  59.             hwndDialog = (HWND) NULL;
  60.             return (TRUE);
  61.          }/*endIf*/
  62.          break;
  63.       }/*endCase*/
  64.       case WM_SIZE: {
  65.       /* Need to resize the StatusBar */
  66.          if (hwndStatus) {
  67.             long lHeight;
  68.             int  iWidth;
  69.             int  iHeight;
  70.  
  71.             iWidth = LOWORD (lParam);
  72.             iHeight = HIWORD (lParam);
  73.             lHeight = GetWindowLong (hwndStatus, GWL_USERDATA);
  74.             MoveWindow (hwndStatus, -1, iHeight - (int) lHeight,
  75.                   iWidth + 2, lHeight + 2, TRUE);
  76.          }/*endIf*/
  77.          break;
  78.       }/*endCase*/
  79.       case WM_USER_GET_APPS: {
  80.          StartTraverseThread (szUserPath);
  81.          return (1L);
  82.       }/*endCase*/
  83.       case WM_USER_GET_GROUPS: {
  84.          StartGroupRetrievalThread ();
  85.          return (1L);
  86.       }/*endCase*/
  87.       case WM_USER_THREAD_DONE: {
  88.          iThreadCount++;
  89.          if (!fBatch) {
  90.             break;
  91.          }/*endIf*/
  92.          if (iThreadCount == 2) {
  93.             PostMessage (ghwndMain, WM_COMMAND,
  94.                   (WPARAM) MAKELONG (ID_ADDALLBUTTON, BN_CLICKED),
  95.                   (LPARAM) hwndAddAll);
  96.             PostMessage (ghwndMain, WM_COMMAND,
  97.                   (WPARAM) MAKELONG (ID_ADDGROUP, BN_CLICKED),
  98.                   (LPARAM) hwndAddGroupButton);
  99.             PostMessage (ghwndMain, WM_COMMAND,
  100.                   (WPARAM) MAKELONG (ID_ADDBUTTON, BN_CLICKED), 
  101.                   (LPARAM) hwndAddButton);
  102.             iThreadCount = 0;
  103.          }/*endIf*/
  104.          break;
  105.       }/*endCase*/
  106.       case WM_COMMAND: {
  107.          switch (HIWORD (wParam)) {
  108.             case LBN_SELCHANGE: {
  109.                SynchronizeListSelection ((HWND) lParam);
  110.                if ((HWND) lParam == hwndCombo) {
  111.                   EnableWindow (hwndAddGroupButton, TRUE);
  112.                }/*endIf*/
  113.                break;
  114.             }/*endCase*/
  115.             case CBN_EDITCHANGE: {
  116.                fFlag = (BOOL) GetWindowTextLength (hwndCombo);
  117.                EnableWindow (hwndAddGroupButton, fFlag);
  118.                break;
  119.             }/*endCase*/
  120.             case BN_CLICKED: {
  121.                switch (LOWORD (wParam)) {
  122.                   case ID_ADDALLBUTTON: {
  123.  
  124.                // Select all elements in the two lists.
  125.                // Under Win 3.x LPARAM of LB_SETSEL is MAKELPARAM (-1, 0)
  126.                // Under Win32 it is -1
  127.                
  128.                      SendMessage (hwndFileList, LB_SETSEL, (WPARAM) TRUE,
  129.                            (LPARAM) -1);
  130.  
  131.                // Under Win 3.x LPARAM of LB_SETSEL is MAKELPARAM (-1, 0)
  132.                // Under Win32 it is -1
  133.                
  134.                      SendMessage (hwndFileList2, LB_SETSEL, (WPARAM) TRUE,
  135.                            (LPARAM) -1);
  136.                      break;
  137.                   }/*endCase*/
  138.                   case ID_EXITBUTTON: {
  139.                      PostQuitMessage (0);
  140.                      break;
  141.                   }/*endCase*/
  142.                   case ID_ADDBUTTON: {
  143.                   // Create the Progress Dialog
  144.                      hwndDialog = CreateDialog (ghModule,
  145.                            "ProgressDialog", hwnd, ProgressDlgWndProc);
  146.  
  147.                   // Start a thread to add the items 
  148.                      StartAddThread ();
  149.                      break;
  150.                   }/*endCase*/
  151.                   case ID_ADDGROUP: {
  152.  
  153.                   // Add the user defined group.
  154.                      CreateGroup ();
  155.                      break;
  156.                   }/*endCase*/
  157.                }/*endSwitch*/
  158.                break;
  159.             }/*endCase*/
  160.          }/*endSwitch*/
  161.  
  162.      // Process menu events now.
  163.  
  164.          switch (LOWORD (wParam)) {
  165.             case DI_EXIT: {
  166.                PostQuitMessage (0);
  167.                return (1L);
  168.             }/*endCase*/
  169.             case DI_ABOUT: {
  170.                DialogBox (ghModule, "AboutBox", hwnd,
  171.                      (DLGPROC) AboutBoxWndProc);
  172.                break;
  173.             }/*endCase*/
  174.          }/*endSwitch*/
  175.          break;
  176.       }/*endCase*/
  177.    }/*endSwitch*/
  178.    return (DefWindowProc (hwnd, uiMsg, wParam, lParam));
  179. }/* end MainWndProc */
  180.  
  181. /********************************************************************
  182.  
  183.    StatusBarWndProc.
  184.    
  185.    Function that manages the Status bar at the bottom of the main 
  186.    window.
  187.  
  188. ********************************************************************/
  189.  
  190. LRESULT APIENTRY StatusBarWndProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
  191.       LPARAM lParam) {
  192.    HDC             hdc;
  193.    long            lHeight;
  194.    RECT            rc;
  195.    PAINTSTRUCT     ps;
  196.    TEXTMETRIC      tm;
  197.    POINT           pts[6];
  198.  
  199.    switch (uiMsg) {
  200.       case WM_CTLCOLORSTATIC: {
  201.          SetBkMode ((HDC) wParam, TRANSPARENT);
  202.          return ((LRESULT) GetStockObject (WHITE_BRUSH));
  203.       }/*endCase*/
  204.       case WM_CREATE: {
  205.          hdc = GetDC (hwnd); // Get the DC for text metrics
  206.  
  207.          GetClientRect (GetParent (hwnd), &rc);
  208.          GetTextMetrics (hdc, &tm);
  209.  
  210.       // Calculate the height of the window
  211.          lHeight = tm.tmHeight + 10 * GetSystemMetrics (SM_CYBORDER) + 2;
  212.  
  213.       // Save away the calculated height
  214.          SetWindowLong (hwnd, GWL_USERDATA, lHeight);
  215.  
  216.       //* resize the window
  217.          SetWindowPos (hwnd, NULL, -1, rc.bottom - lHeight,
  218.             rc.right + 2, lHeight + 2, SWP_NOZORDER | SWP_NOMOVE);
  219.  
  220.          ReleaseDC (hwnd, hdc);
  221.          break;
  222.       }/*endCase*/
  223.       case WM_USER_UPDATE_STATUS: {
  224.          switch (lParam) {
  225.             case ID_DDEML_CONNECT: {
  226.                SetWindowText (hwndStatusText, "DDEML Connection");
  227.                break;
  228.             }/*endCase*/
  229.             case ID_DDEML_RETRIEVING: {
  230.                SetWindowText (hwndStatusText, "DDEML Retrieving");
  231.                break;
  232.             }/*endCase*/
  233.             case ID_DDEML_DISCONNECT: {
  234.                SetWindowText (hwndStatusText, "DDEML Disconnect");
  235.                break;
  236.             }/*endCase*/
  237.             case ID_DDEML_COMPLETE: {
  238.                SetWindowText (hwndStatusText, "DDEML Complete");
  239.                break;
  240.             }/*endCase*/
  241.             case ID_DDEML_ACTIVATE: {
  242.                SetWindowText (hwndStatusText, "DDEML Activate Group");
  243.                break;
  244.             }/*endCase*/
  245.             case ID_DDEML_CREATE: {
  246.                SetWindowText (hwndStatusText, "DDEML Create Group");
  247.                break;
  248.             }/*endCase*/
  249.             case ID_DDEML_ADD: {
  250.                TCHAR   szText[32];
  251.  
  252.                sprintf (szText, "DDEML Add Item %ld", wParam);
  253.                SetWindowText (hwndStatusText, szText);
  254.                break;
  255.             }/*endCase*/
  256.          }/*endSwitch*/
  257.          break;
  258.       }/*endCase*/
  259.       case WM_PAINT: {
  260.          HBRUSH   hBrush;
  261.          HBRUSH   hBrushTemp;
  262.          HPEN     hPen;
  263.          HPEN     hPenTemp;
  264.  
  265.          hdc = BeginPaint (hwnd, &ps);
  266.          GetClientRect (hwnd, &rc);
  267.  
  268.          lHeight = GetWindowLong (hwnd, GWL_USERDATA);
  269.          pts[0].x = 3;
  270.          pts[0].y = pts[5].y = lHeight - 4;
  271.          pts[1].x = 6;
  272.          pts[1].y = pts[2].y = lHeight - 6;
  273.          pts[2].x = pts[3].x = (rc.right / 2) - 4;
  274.          pts[3].y = 6;
  275.          pts[4].y = 3;
  276.          pts[4].x = pts[5].x = rc.right / 2;
  277.          hBrush = GetStockObject (WHITE_BRUSH);
  278.          hPen = GetStockObject (WHITE_PEN);
  279.          hBrushTemp = SelectObject (hdc, hBrush);
  280.          hPenTemp = SelectObject (hdc, hPen);
  281.          SetPolyFillMode (hdc, WINDING);
  282.          Polygon (hdc, pts, 6);
  283.          hBrush = CreateSolidBrush (GetSysColor (COLOR_BTNSHADOW));
  284.          pts[2].x = 6;
  285.          hPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNSHADOW));
  286.          pts[2].y = 6;
  287.          pts[5].x = pts[5].y = 3;
  288.          SelectObject (hdc, hBrush);
  289.          SelectObject (hdc, hPen);
  290.          Polygon (hdc, pts, 6);
  291.          rc.left = rc.top = 7;
  292.          rc.right = (rc.right / 2) - 4;
  293.          rc.bottom = lHeight - 7;
  294.          SelectObject (hdc, hBrushTemp);
  295.          SelectObject (hdc, hPenTemp);
  296.          DeleteObject (hBrush);
  297.          DeleteObject (hPen);
  298.          hBrush = GetStockObject (WHITE_BRUSH);
  299.          FillRect (hdc, &rc, hBrush);
  300.          DeleteObject (hBrush);
  301.          EndPaint (hwnd, &ps);
  302.          return (0L);
  303.       }/*endCase*/
  304.    }/*endSwitch*/
  305.    return (DefWindowProc (hwnd, uiMsg, wParam, lParam));
  306. }/* end StatusBarWndProc */
  307.  
  308. /********************************************************************
  309.  
  310.    ListBoxWndProc.
  311.    
  312.    Function that manages the list boxes that are on the screen. Subclassed
  313.    to provide additional functionality.
  314.  
  315. ********************************************************************/
  316.  
  317. LRESULT APIENTRY ListBoxWndProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
  318.       LRESULT lParam) {
  319.  
  320.    switch (uiMsg) {
  321.       case WM_KEYUP: {
  322.          SynchronizeLists (hwnd);
  323.          break;
  324.       }/*endCase*/
  325.       case WM_VSCROLL: {
  326.          SynchronizeLists (hwnd);
  327.          break;
  328.       }/*endCase*/
  329.       break;
  330.    }/*endSwitch*/
  331.    return (CallWindowProc (DefListBoxWndProc, hwnd, uiMsg, wParam, lParam));
  332. }/* end ListBoxWndProc */
  333.  
  334. /********************************************************************
  335.  
  336.    SynchronizeLists.
  337.    
  338.    Function that makes sure that the two lists are synchronized and 
  339.    always have the same selection.
  340.  
  341. ********************************************************************/
  342.  
  343. void SynchronizeLists (HWND hwnd) {
  344.    HWND   hwndOther;
  345.    long   lSourceTop;
  346.    long   lTargetTop;
  347.  
  348. // If this is from the combo list then return.
  349.    if (hwnd == hwndCombo) {
  350.       return;
  351.    }/*endIf*/
  352.  
  353. // Figure out which list caused the event and update the other.
  354.    if (hwnd == hwndFileList) {
  355.       hwndOther = hwndFileList2;
  356.    } else {
  357.       hwndOther = hwndFileList;
  358.    }/*endIf*/
  359.  
  360. // Get the top index of the source list.
  361.    lSourceTop = SendMessage (hwnd, LB_GETTOPINDEX, 0, 0L);
  362.  
  363. // Get the top index of the target list.
  364.    lTargetTop = SendMessage (hwndOther, LB_GETTOPINDEX, 0, 0L);
  365.  
  366. // If the top indexes are different set the top of the target to the
  367. // same value as the source.
  368.    if (lSourceTop != lTargetTop) {
  369.       SendMessage (hwndOther, LB_SETTOPINDEX, lSourceTop, 0L);
  370.    }/*endIf*/
  371. }/* end SynchronizeLists */
  372.  
  373. /********************************************************************
  374.  
  375.    SynchronizeListSelection.
  376.    
  377.    Function that actually manages the list selection.
  378.  
  379. ********************************************************************/
  380.  
  381. void SynchronizeListSelection (HWND hwnd) {
  382.    HWND   hwndOther;
  383.    long   lNumSel;
  384.    int   * lpSelection;
  385.    long   lIndex;
  386.  
  387. // If this is from the combo list then return.
  388.  
  389.    if (hwnd == hwndCombo) {
  390.       return;
  391.    }/*endIf*/
  392.  
  393. // Figure out which list caused the event and update the other.
  394.  
  395.    if (hwnd == hwndFileList) {
  396.       hwndOther = hwndFileList2;
  397.    } else {
  398.       hwndOther = hwndFileList;
  399.    }/*endIf*/
  400.  
  401. // Find out how many items are selected in the source list.
  402.  
  403.    lNumSel = SendMessage (hwnd, LB_GETSELCOUNT, 0, 0L);
  404.    if (lNumSel != LB_ERR && lNumSel != 0) {
  405.  
  406.    // Allocate a block of memory to hold the selection indexes.
  407.       lpSelection = (int *) GlobalAlloc (GMEM_FIXED | GMEM_ZEROINIT,
  408.          lNumSel * sizeof (int));
  409.       if (lpSelection) {
  410.  
  411.    // Clear the selection in the list before reselecting.
  412.    // Under Win 3.x LPARAM of LB_SETSEL is MAKELPARAM (-1, 0)
  413.    // Under Win32 it is -1
  414.                
  415.          SendMessage (hwndOther, LB_SETSEL, (WPARAM) FALSE, (LPARAM) -1);
  416.  
  417.    // Retrieve the selection indexes.
  418.  
  419.          SendMessage (hwnd, LB_GETSELITEMS, lNumSel, (LPARAM) lpSelection);
  420.  
  421.    // Loop the indexes selecting the same values in the target list.
  422.  
  423.          for (lIndex = 0; lIndex < lNumSel; lIndex++) {
  424.             SendMessage (hwndOther, LB_SETSEL, (WPARAM) TRUE,
  425.                MAKELPARAM (lpSelection[lIndex], 0));
  426.          }/*endFor*/
  427.  
  428.    // Release the memory that was allocated.
  429.  
  430.          GlobalFree (lpSelection);
  431.       }/*endIf*/
  432.    }/*endIf*/
  433. }/* end SynchronizeListSelection */
  434.  
  435. /********************************************************************
  436.  
  437.    CreateChildren.
  438.    
  439.    Function that creates all of the child windows for the app.
  440.  
  441. ********************************************************************/
  442.  
  443. void CreateChildren (HWND hwnd) {
  444.    int              iListHeight;
  445.    long             lHeight;
  446.    RECT             rc;
  447.  
  448. // Create the status bar at the bottom of the window.
  449.    hwndStatus = CreateWindow ("StatusBar", NULL,
  450.          WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
  451.          0, 0, 0, 0, hwnd, (HMENU) ID_STATUSBAR, ghModule, NULL);
  452.  
  453. // Retrieve the height of the status bar.
  454.    lHeight = GetWindowLong (hwndStatus, GWL_USERDATA);
  455.  
  456. // Retrieve the size of the client area of the status bar.
  457.    GetClientRect (hwndStatus, &rc);
  458.  
  459.    hwndStatusText = CreateWindow ("Static", "Status Bar",
  460.          WS_VISIBLE | WS_CHILD | SS_LEFT,
  461.          7, 7, rc.right / 2 - 10, lHeight - 14, hwndStatus, (HMENU) 0, ghModule,
  462.          NULL);
  463.  
  464. // Retrieve the size of the client area of the parent window
  465.    GetClientRect (hwnd, &rc);
  466.  
  467. // Calculate the size of a list box.
  468.    iListHeight = rc.bottom - lHeight * 2;
  469.  
  470. // Decrease the size of lHeight to compensate for size of status bar.
  471.    lHeight -= 8;
  472.  
  473. // Create a Static window in the upper left corner.
  474.    CreateWindow ("Static", "Available exe's",
  475.          WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | SS_LEFT,
  476.          0, 0, 200, lHeight - 2, hwnd, (HMENU) 0, ghModule, NULL);
  477.  
  478. // Create the first list to hold the file name.
  479.    hwndFileList = CreateWindow ("ListBox", NULL, WS_CLIPSIBLINGS | LBS_NOTIFY |
  480.          WS_BORDER | WS_VISIBLE | WS_CHILD | LBS_EXTENDEDSEL | LBS_HASSTRINGS,
  481.          0, lHeight, 150, iListHeight, hwnd, (HMENU) ID_FILELIST, ghModule,
  482.          NULL);
  483.  
  484. // Subclass the list box window proc so we can do the synchronization
  485.    DefListBoxWndProc = (WNDPROC) GetWindowLong (hwndFileList, GWL_WNDPROC);
  486.    SetWindowLong (hwndFileList, GWL_WNDPROC, (LONG) ListBoxWndProc);
  487.  
  488. // Create the second list box that holds the name that will be used in the
  489. // Program Manager.
  490.    hwndFileList2 = CreateWindow ("ListBox", NULL,
  491.          WS_BORDER | WS_VISIBLE | WS_CHILD | WS_VSCROLL | LBS_EXTENDEDSEL |
  492.          LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_CLIPSIBLINGS, 150,
  493.          lHeight, 150, iListHeight, hwnd, (HMENU) ID_FILELIST2, ghModule,
  494.          NULL);
  495.  
  496. // Subclass the list.
  497.    SetWindowLong (hwndFileList2, GWL_WNDPROC, (LONG) ListBoxWndProc);
  498.  
  499. // Create a third list box that is not visible that contains the absolute
  500. // path to the executable.
  501.    hwndPathList = CreateWindow ("ListBox", NULL,
  502.          WS_BORDER | WS_CHILD | WS_VSCROLL | LBS_EXTENDEDSEL |
  503.          LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_CLIPSIBLINGS, 150, lHeight,
  504.          150, iListHeight, hwnd, (HMENU) ID_PATHLIST, ghModule, NULL);
  505.  
  506. // Create a button that is used to add a group.
  507.    hwndAddGroupButton = CreateWindow ("Button", "Add Group",
  508.          WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
  509.          rc.right - 110, iListHeight - (int) (lHeight * 4),
  510.          100, lHeight, hwnd, (HMENU) ID_ADDGROUP, ghModule, NULL);
  511.  
  512. // Create the button that is used to add the selected items.
  513.    hwndAddButton = CreateWindow ("Button", "Add Items",
  514.          WS_DISABLED | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
  515.          rc.right - 110, iListHeight - (int) (lHeight * 3),
  516.          100, lHeight, hwnd, (HMENU) ID_ADDBUTTON, ghModule, NULL);
  517.  
  518. // Create the button that is used to select all of the items in the list.
  519.    hwndAddAll = CreateWindow ("Button", "Select All",
  520.          WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
  521.          rc.right - 110, iListHeight - (int) (lHeight * 2),
  522.          100, lHeight, hwnd, (HMENU) ID_ADDALLBUTTON, ghModule, NULL);
  523.  
  524. // Create a button that can be used to exit the application.
  525.    hwndExitButton = CreateWindow ("Button", "Exit",
  526.          WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
  527.          rc.right - 110, iListHeight - (int) lHeight, 100, lHeight, hwnd,
  528.          (HMENU) ID_EXITBUTTON, ghModule, NULL);
  529.  
  530. // Create a drop down combo box for the group names from the Program Manager.
  531.    hwndCombo = CreateWindow ("ComboBox", NULL,
  532.          WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | CBS_DROPDOWN | WS_VSCROLL |
  533.          CBS_AUTOHSCROLL | CBS_HASSTRINGS, rc.right - 200, lHeight,
  534.          190, lHeight * 5, hwnd, (HMENU) ID_COMBOBOX, ghModule, NULL);
  535.  
  536. // Create a Static window to label the combo box.
  537.    CreateWindow ("Static", "Available Groups",
  538.          WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | SS_LEFT,
  539.          rc.right - 200, 0, 190, lHeight - 2, hwnd, (HMENU) 0, ghModule, NULL);
  540. }/* end CreateChildren */
  541.