DDEADD.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:

Windows编程

开发平台:

Visual C++

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