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 / ddeadd.c next >
C/C++ Source or Header  |  1997-10-05  |  14KB  |  400 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.  
  14.    ddeadd.c
  15.    DDEML Execute functions to add selected items
  16.    and create new group if specified.
  17.  
  18. */
  19.  
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #include "ddeinst.h"
  25. #include "ddextrn.h" 
  26. #include "dialogs.h"
  27.  
  28. CONVCONTEXT   CCFilter = { sizeof (CONVCONTEXT), 0, 0, 0, 0L, 0L };
  29.  
  30.  
  31. /********************************************************************
  32.  
  33.    StartAddThread
  34.  
  35.    Function to Start the program item addition thread.
  36.  
  37. ********************************************************************/
  38.  
  39. BOOL StartAddThread () {
  40.    HANDLE hThread;
  41.    LONG   lThreadId;
  42.  
  43.    hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) AddProgramItems,
  44.          "Dummy", CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED, &lThreadId);
  45.    if (hThread) {
  46.       SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
  47.       ResumeThread (hThread);
  48.  
  49. /* Close the handle since we don't need it anymore */
  50.  
  51.       CloseHandle (hThread);
  52.       return (TRUE);
  53.    }/*endIf*/
  54.    return (FALSE);
  55. }/* end StartAddThread */
  56.  
  57. /********************************************************************
  58.  
  59.    CreateGroup
  60.  
  61.    Function that creates a group in the Program Manager. If the specified
  62.    name already exists the group is activated.
  63.  
  64. ********************************************************************/
  65.  
  66. BOOL CreateGroup () {
  67.    HDDEDATA   hData;
  68.    LPSTR      szText;
  69.    LPSTR      szCommand;
  70.    HCONV      hConv;
  71.    HSZ        szProgMan;
  72.    LONG       lResult;
  73.  
  74. // Allocate a block of memory for the group name that the user has selected.
  75.    szText = VirtualAlloc (NULL, 64, MEM_COMMIT, PAGE_READWRITE);
  76.  
  77. // Allocate a block of memory for the command to send to the Program Manager.
  78.    szCommand = VirtualAlloc (NULL, 128, MEM_COMMIT, PAGE_READWRITE);
  79.    if (szText) {
  80.    // We got the memory so we can proceed.
  81.  
  82.    // Initialize the DDE conversation here.
  83.  
  84.       if (DdeInitialize (&lIdInst, (PFNCALLBACK) GroupDDECallback,
  85.             (DWORD) APPCMD_CLIENTONLY, 0L)) {
  86.          MessageBox (ghwndMain, "DDEML Initialization Failure", "Error", MB_OK);
  87.          VirtualFree (szText, 128, MEM_DECOMMIT);
  88.          return (FALSE);
  89.       }/*endIf*/
  90.  
  91.    // Create a DDEML string handle for the Program Manager.
  92.       szProgMan = DdeCreateStringHandle (lIdInst, "PROGMAN", CP_WINANSI);
  93.       if (szProgMan) {
  94.  
  95.       // String handle created so continue.
  96.  
  97. // Establish a conversation with the Program Manager.
  98.          hConv = DdeConnect (lIdInst, szProgMan, szProgMan, &CCFilter);
  99.  
  100.          PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
  101.                ID_DDEML_CONNECT);
  102.  
  103. // Retrieve the text of the combo control. This will return back what the
  104. // user has typed in if nothing has been selected.
  105.          GetWindowText (hwndCombo, szText, 64);
  106.  
  107. // Find out if this string is in the list or not. If not create a group
  108. // Otherwise just activate the group.
  109.          lResult = (LONG) SendMessage (hwndCombo, CB_FINDSTRING, (WPARAM) -1,
  110.                (LPARAM) (LPCSTR) szText);
  111.          if (lResult == CB_ERR) {
  112.  
  113. // Create the group by creating the command line.
  114. // The program manager will activate an existing group if the name matches
  115. // a DDE attempt to create a new group so the create versus show is somewhat
  116. // redundant.
  117.             sprintf (szCommand, "[CreateGroup(%s)]", szText);
  118.  
  119. // Create a DDEML data handle for the command.
  120.             hData = DdeCreateDataHandle (lIdInst, szCommand,
  121.                   strlen (szCommand) + 1, 0, (HSZ) NULL, CF_TEXT, 0L);
  122.  
  123. // Send the transaction to the server waiting a maximum of 10 seconds.
  124. // The server will release the data handle.
  125.             if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF, hConv,
  126.                   (HSZ) NULL, 0, XTYP_EXECUTE, 10000, &lResult)) {
  127.  
  128. // If it fails get the error code.
  129.                lResult = DdeGetLastError (lIdInst);
  130.                MessageBox (NULL, "DdeClientTransaction Failed", "Error",
  131.                   MB_OK);
  132.             }/*endIf*/
  133.  
  134.             PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
  135.                   ID_DDEML_CREATE);
  136.  
  137.          } else {
  138.  
  139. // Group already exists so activate it.
  140.             sprintf (szCommand, "[ShowGroup(%s,1)]", szText);
  141.  
  142. // Create a DDEML data handle for the command.
  143.             hData = DdeCreateDataHandle (lIdInst, szCommand, strlen (szCommand),
  144.                   0, (HSZ) NULL, CF_TEXT, 0L);
  145.  
  146. // Send the transaction to the server waiting a maximum of 10 seconds.
  147. // The server will release the data handle.
  148.             if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF, hConv,
  149.                   (HSZ) NULL, 0, XTYP_EXECUTE, 10000, &lResult)) {
  150.  
  151. // If it fails get the error code.
  152.                lResult = DdeGetLastError (lIdInst);
  153.             }/*endIf*/
  154.  
  155.             PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
  156.                   ID_DDEML_ACTIVATE);
  157.  
  158.          }/*endIf*/
  159.  
  160. // Release the Program Manager string handle.
  161.          DdeFreeStringHandle (lIdInst, szProgMan);
  162.  
  163. // Disconnect from the server.
  164.          DdeDisconnect (hConv);
  165.          PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
  166.                   ID_DDEML_COMPLETE);
  167.       } else {
  168.          lResult = DdeGetLastError (lIdInst);
  169.       }/*endIf*/
  170.  
  171. // Free the two blocks of memory that were allocated.
  172.       VirtualFree (szText, 64, MEM_DECOMMIT);
  173.       VirtualFree (szCommand, 64, MEM_DECOMMIT);
  174.       EnableWindow (hwndAddButton, TRUE);
  175.  
  176.    // Uninitialize the conversation here so that resources are freed.
  177.  
  178.       DdeUninitialize (lIdInst);
  179.       lIdInst = 0L;
  180.       return (TRUE);
  181.    } else {
  182.       MessageBox (NULL, "Memory Allocation failure", "Error", MB_OK);
  183.    }/*endIf*/
  184.    EnableWindow (hwndAddButton, FALSE);
  185.    return (FALSE);
  186. }/* end CreateGroup */
  187.  
  188.  
  189. // Local function
  190. void UpdateProgressBar (int, int);
  191.  
  192. // Flag for progress bar update
  193. BOOL   fFirst;
  194.  
  195. /********************************************************************
  196.  
  197.    AddProgramItems
  198.  
  199.    Function that uses DDEML to add program items to group in Program
  200.    Manager.
  201.  
  202. ********************************************************************/
  203.  
  204. BOOL AddProgramItems (LPSTR szDummy) {
  205.    char      szPercent[8];
  206.    HDDEDATA  hData;
  207.    HCONV     hConv;
  208.    HSZ       szProgMan;
  209.    int       lSelCount;
  210.    LONG      lResult;
  211.    LPLONG    lpSelection;
  212.    LPSTR     szProgName;
  213.    LPSTR     szExePath;
  214.    LPSTR     szExecuteString;
  215.    int       iIndex;
  216.    int       iGroupCount;
  217.  
  218.    fFirst = FALSE;
  219.    iGroupCount = 2;
  220. // Retrieve the number of selected items from the file list.
  221.    lSelCount = (int) SendMessage (hwndFileList, LB_GETSELCOUNT, 0, 0L);
  222.  
  223. // Allocate a block of memory to hold the indexes of the list selection.
  224.    lpSelection = VirtualAlloc (NULL, lSelCount * sizeof (int), MEM_COMMIT,
  225.          PAGE_READWRITE);
  226.    if (lpSelection) {
  227.  
  228. // Establish a new conversation.
  229.       if (DdeInitialize (&lIdInst2, (PFNCALLBACK) GroupDDECallback,
  230.             (DWORD) APPCMD_CLIENTONLY, 0L)) {
  231.          VirtualFree (lpSelection, lSelCount * sizeof (int), MEM_DECOMMIT);
  232.          return (FALSE);
  233.       }/*endIf*/
  234.  
  235. // Create a DDEML string handle for the Program Manager.
  236.       szProgMan = DdeCreateStringHandle (lIdInst2, "PROGMAN", CP_WINANSI);
  237.  
  238. // Establish the conversation.
  239.       hConv = DdeConnect (lIdInst2, szProgMan, szProgMan, &CCFilter);
  240.  
  241.       PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
  242.            ID_DDEML_CONNECT);
  243.  
  244.  
  245. // Release the string handle that we created.
  246.       DdeFreeStringHandle (lIdInst2, szProgMan);
  247.  
  248.  
  249. // Allocate a block of memory to hold the path and name of the item.
  250.       szProgName = VirtualAlloc (NULL, MAX_PATH * 2, MEM_COMMIT,
  251.             PAGE_READWRITE);
  252.       szExePath = szProgName + MAX_PATH;
  253.  
  254. // Allocate some memory to hold the command string.
  255.       szExecuteString = VirtualAlloc (NULL, MAX_PATH * 4, MEM_COMMIT,
  256.             PAGE_READWRITE);
  257.  
  258. // Retrieve the array of list selections.
  259.       SendMessage (hwndFileList, LB_GETSELITEMS, (WPARAM) lSelCount,
  260.             (LPARAM) lpSelection);
  261.  
  262. // Loop through the array of selections.
  263.       for (iIndex = 0; iIndex < lSelCount; iIndex++) {
  264.  
  265. // Work around for limitation for in ProgMan (no more than 50 items per group)
  266.          if (!(iIndex % 50) && (iIndex > 0)) {
  267.             LPSTR      szText;
  268.             LPSTR      szText2;
  269.  
  270.          // Allocate a block of memory for the group name 
  271.             szText = VirtualAlloc (NULL, 64, MEM_COMMIT, PAGE_READWRITE);
  272.             szText2 = VirtualAlloc (NULL, 256, MEM_COMMIT, PAGE_READWRITE);
  273.             if (szText && szText2) {
  274.                GetWindowText (hwndCombo, szText, 64);
  275.                sprintf (szText2, "[CreateGroup(%s Part %ld )]", szText,
  276.                      iGroupCount++);
  277.  
  278.          // Create a DDEML data handle for the command.
  279.                hData = DdeCreateDataHandle (lIdInst2, szText2,
  280.                   strlen (szText2) + 1, 0, (HSZ) NULL, CF_TEXT, 0L);
  281.  
  282.          // Send the transaction to the server waiting a maximum of 10 seconds.
  283.          // The server will release the data handle.
  284.                if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF, hConv,
  285.                      (HSZ) NULL, 0, XTYP_EXECUTE, 10000, &lResult)) {
  286.          // If it fails get the error code.
  287.                   lResult = DdeGetLastError (lIdInst);
  288.                   MessageBox (NULL, "DdeClientTransaction Failed",
  289.                         "Error", MB_OK);
  290.                }/*endIf*/
  291.                VirtualFree (szText, 64, MEM_DECOMMIT);
  292.                VirtualFree (szText2, 256, MEM_DECOMMIT);
  293.             }
  294.          }/*endIf*/
  295.  
  296. // Retrieve the Name of the Program Item to add.
  297.          SendMessage (hwndFileList2, LB_GETTEXT, (WPARAM) lpSelection[iIndex],
  298.                (LPARAM) szProgName);
  299.  
  300. // Set the name in the progress dialog
  301.          SetDlgItemText (hwndDialog, IDL_ITEMNAME, szProgName);
  302.  
  303. // Retrieve the absolute path of the item to add.
  304.          SendMessage (hwndPathList, LB_GETTEXT, (WPARAM) lpSelection[iIndex],
  305.                (LPARAM) szExePath);
  306.  
  307. // Set the path in the progress dialog
  308.          SetDlgItemText (hwndDialog, IDL_EXEPATH, szExePath);
  309.  
  310. // Set the percentage in the progress dialog
  311.          sprintf (szPercent, "%d%%", (iIndex * 100) / lSelCount);
  312.          SetDlgItemText (hwndDialog, IDL_PERCENTAGE, szPercent);
  313.          UpdateProgressBar (iIndex + 1, lSelCount);
  314.  
  315. // Create the command string to add the item.
  316.          sprintf (szExecuteString, "[AddItem(%s,%s)]", szExePath,
  317.                (LPARAM) szProgName);
  318.  
  319. // Create a DDEML Data handle for the command string.
  320.          hData = DdeCreateDataHandle (lIdInst2, szExecuteString,
  321.                strlen (szExecuteString) + 1, 0, (HSZ) NULL, CF_TEXT, 0L);
  322.  
  323. // Send the command over to the program manager.
  324.          if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF,
  325.                hConv, (HSZ) NULL, 0, XTYP_EXECUTE, 1000, &lResult)) {
  326.             lResult = DdeGetLastError (lIdInst2);
  327.          }/*endIf*/
  328.       }/*endFor*/
  329.  
  330. // Release the memory allocated for path and name retrieval.
  331.       VirtualFree (szProgName, MAX_PATH * 2, MEM_DECOMMIT);
  332.  
  333. // Release the command line memory.
  334.       VirtualFree (szExecuteString, MAX_PATH * 4, MEM_DECOMMIT);
  335.  
  336. // Disoconnect the DDEML Conversation
  337.       DdeDisconnect (hConv);
  338.  
  339. // Release the memory allocate for the list selections.
  340.       VirtualFree (lpSelection, lSelCount * sizeof (int), MEM_DECOMMIT);
  341.    }/*endIf*/
  342.  
  343. // Clear the selection in the lists.
  344.  
  345.    SendMessage (hwndFileList, LB_SETSEL, (WPARAM) FALSE, (LPARAM) -1);
  346.    SendMessage (hwndFileList2, LB_SETSEL, (WPARAM) FALSE, (LPARAM) -1);
  347.    EnableWindow (hwndAddAll, FALSE);
  348.  
  349. // Uninitialize the local conversation.
  350.    DdeUninitialize (lIdInst2);
  351.    
  352.    if (hwndDialog) {
  353.       PostMessage (ghwndMain, WM_USER_CLOSE_DIALOG, 0, 0L);
  354.    }/*endIf*/
  355.    lIdInst2 = 0L;
  356.    if (fBatch) {
  357.       PostMessage (ghwndMain, WM_COMMAND, (WPARAM)
  358.             (WPARAM) MAKELONG (ID_EXITBUTTON, BN_CLICKED),
  359.             (LPARAM) hwndExitButton);
  360.    }/*endIf*/
  361.    return (TRUE);
  362. }/* end AddProgramItems */
  363.  
  364.  
  365. HWND   hwndBar;
  366. RECT   rc;
  367. double iStep;
  368. HBRUSH hBrush;
  369.  
  370. /********************************************************************
  371.  
  372.    UpdateProgressBar
  373.  
  374.    Function to update the progress bar in the dialog while items are
  375.    added to the Program Manager.
  376.  
  377. ********************************************************************/
  378.  
  379. void UpdateProgressBar (int iIndex, int iCount) {
  380.    HDC  hdc;
  381.  
  382.    if (!fFirst) {
  383.       hwndBar = GetDlgItem (hwndDialog, IDL_PROGRESSBAR);
  384.       if (hwndBar) {
  385.          GetClientRect (hwndBar, &rc);
  386.          fFirst = TRUE;
  387.       } else {
  388.          return;
  389.       }/*endIf*/
  390.       iStep = (double) rc.right / (double) iCount;
  391.       hBrush = GetStockObject (BLACK_BRUSH);
  392.    }/*endIf*/
  393.    hdc = GetDC (hwndBar);
  394.    rc.right = (int) (iStep * (double) iIndex);
  395.    FillRect (hdc, &rc, hBrush);
  396.    ReleaseDC (hwndBar, hdc);
  397.  
  398.    PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, iIndex, ID_DDEML_ADD);
  399. }/* end UpdateProgressBar */
  400.