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 / ddeprog / proghelp.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  5KB  |  209 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. * PROGHELP.C
  14. *
  15. * Main module to implement a simple DDEML service DLL that makes interaction
  16. * with progman simple.
  17. \*****************************************************************************/
  18.  
  19. #include <windows.h>
  20. #include <ddeml.h>
  21. #include <string.h>
  22.  
  23. typedef struct {
  24.     HCONV hConv;
  25.     DWORD idInst;
  26. } THREADINFO;
  27.  
  28. DWORD TlsIndex;
  29.  
  30. /*
  31.  * This is the default DDEML callback function for ProgHelp
  32.  */
  33. HDDEDATA CALLBACK ProgHelpDdeCallback(
  34. UINT wType,
  35. UINT wFmt,
  36. HCONV hConv,
  37. HSZ hsz1,
  38. HSZ hsz2,
  39. HDDEDATA hData,
  40. DWORD dwData1,
  41. DWORD dwData2)
  42. {
  43.     return(0);
  44. }
  45.  
  46.  
  47. /*
  48.  * This is the DLL init routine called by the system at attach/detatch time.
  49.  *
  50.  * We allocate a Tls for each thread that calls this DLL so that their state
  51.  * can be tracked independently.
  52.  */
  53. BOOLEAN APIENTRY DllMain(
  54. IN PVOID hmod,
  55. ULONG Reason,
  56. IN PCONTEXT pctx OPTIONAL)
  57. {
  58.     THREADINFO *pti;
  59.     UNREFERENCED_PARAMETER(hmod);
  60.     UNREFERENCED_PARAMETER(pctx);
  61.  
  62.     switch (Reason) {
  63.     case DLL_PROCESS_ATTACH:
  64.         TlsIndex = TlsAlloc();
  65.  
  66.     case DLL_THREAD_ATTACH:
  67.         pti = (THREADINFO *)LocalAlloc(LPTR, sizeof(THREADINFO));
  68.         if (!pti) {
  69.             return(FALSE);
  70.         }
  71.         TlsSetValue(TlsIndex, pti);
  72.         break;
  73.  
  74.     case DLL_THREAD_DETACH:
  75.     case DLL_PROCESS_DETACH:
  76.         pti = TlsGetValue(TlsIndex);
  77.         LocalFree(pti);
  78.         if (Reason == DLL_PROCESS_DETACH) {
  79.             TlsFree(TlsIndex);
  80.         }
  81.         break;
  82.     }
  83.     return TRUE;
  84. }
  85.  
  86. /*
  87.  * An application must call this API first to establish a conversation
  88.  * with progman.  DDEML initialization is done automatically if needed.
  89.  */
  90. BOOL ConnectToProgmanA()
  91. {
  92.     THREADINFO *pti;
  93.     HSZ hszProgman;
  94.  
  95.     pti = TlsGetValue(TlsIndex);
  96.  
  97.     if (!pti->idInst) {
  98.         if (DdeInitializeA(&(pti->idInst), ProgHelpDdeCallback,
  99.                 APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS,
  100.                 0L) != DMLERR_NO_ERROR) {
  101.             return(FALSE);
  102.         }
  103.     }
  104.  
  105.     if (pti->hConv == 0) {
  106.         hszProgman = DdeCreateStringHandleA(pti->idInst, "Progman", 0);
  107.         pti->hConv = DdeConnect(pti->idInst, hszProgman, hszProgman, NULL);
  108.     }
  109.     return(pti->hConv != 0);
  110. }
  111.  
  112.  
  113.  
  114. BOOL ConnectToProgmanW()
  115. {
  116.     THREADINFO *pti;
  117.     HSZ hszProgman;
  118.  
  119.     pti = TlsGetValue(TlsIndex);
  120.  
  121.     if (!pti->idInst) {
  122.         if (DdeInitializeW(&(pti->idInst), ProgHelpDdeCallback,
  123.                 APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS,
  124.                 0L) != DMLERR_NO_ERROR) {
  125.             return(FALSE);
  126.         }
  127.     }
  128.  
  129.     if (pti->hConv == 0) {
  130.         hszProgman = DdeCreateStringHandleA(pti->idInst, "Progman", 0);
  131.         pti->hConv = DdeConnect(pti->idInst, hszProgman, hszProgman, NULL);
  132.     }
  133.     return(pti->hConv != 0);
  134. }
  135.  
  136.  
  137.  
  138. /*
  139.  * This API should be called when operations with progman are complete.
  140.  * We shutdown DDEML here as well so we don't have to deal with it
  141.  * at DLL detatch time.
  142.  */
  143. BOOL DisconnectFromProgman()
  144. {
  145.     THREADINFO *pti;
  146.  
  147.     pti = TlsGetValue(TlsIndex);
  148.  
  149.     if (!pti->idInst) {
  150.         return(TRUE);
  151.     }
  152.  
  153.     if (pti->hConv) {
  154.         DdeDisconnect(pti->hConv);
  155.         pti->hConv = 0;
  156.     }
  157.  
  158.     DdeUninitialize(pti->idInst);
  159.     pti->idInst = 0;
  160.     return(TRUE);
  161. }
  162.  
  163.  
  164. /*
  165.  * This API sends an ASCII execute string to progman.  It immediately returns
  166.  * and the results of the execute are not known.  Calling applications should
  167.  * be aware that these transactions are done asynchronously.  This allows
  168.  * this API to work under modal-loop conditions.  DisconnectFromProgman()
  169.  * will not succeed until all transactions are complete.
  170.  */
  171. BOOL ProgmanExecuteStringA(
  172. LPSTR pszExec)
  173. {
  174.     THREADINFO *pti;
  175.     DWORD dwResult;
  176.  
  177.     pti = TlsGetValue(TlsIndex);
  178.  
  179.     if (!pti->idInst || !pti->hConv) {
  180.         return(FALSE);
  181.     }
  182.     if (!DdeClientTransaction((PBYTE)pszExec, strlen(pszExec) + 1,
  183.             pti->hConv, 0, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &dwResult)) {
  184.         return(FALSE);
  185.     }
  186.     return(TRUE);
  187. }
  188.  
  189.  
  190.  
  191. BOOL ProgmanExecuteStringW(
  192. LPWSTR pszExec)
  193. {
  194.     THREADINFO *pti;
  195.     DWORD dwResult;
  196.  
  197.     pti = TlsGetValue(TlsIndex);
  198.  
  199.     if (!pti->idInst || !pti->hConv) {
  200.         return(FALSE);
  201.     }
  202.     if (!DdeClientTransaction((PBYTE)pszExec,
  203.             (wcslen(pszExec) + 1)  * sizeof(WCHAR),
  204.             pti->hConv, 0, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &dwResult)) {
  205.         return(FALSE);
  206.     }
  207.     return(TRUE);
  208. }
  209.