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 >
Wrap
C/C++ Source or Header
|
1997-10-05
|
5KB
|
209 lines
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
/*****************************************************************************\
* PROGHELP.C
*
* Main module to implement a simple DDEML service DLL that makes interaction
* with progman simple.
\*****************************************************************************/
#include <windows.h>
#include <ddeml.h>
#include <string.h>
typedef struct {
HCONV hConv;
DWORD idInst;
} THREADINFO;
DWORD TlsIndex;
/*
* This is the default DDEML callback function for ProgHelp
*/
HDDEDATA CALLBACK ProgHelpDdeCallback(
UINT wType,
UINT wFmt,
HCONV hConv,
HSZ hsz1,
HSZ hsz2,
HDDEDATA hData,
DWORD dwData1,
DWORD dwData2)
{
return(0);
}
/*
* This is the DLL init routine called by the system at attach/detatch time.
*
* We allocate a Tls for each thread that calls this DLL so that their state
* can be tracked independently.
*/
BOOLEAN APIENTRY DllMain(
IN PVOID hmod,
ULONG Reason,
IN PCONTEXT pctx OPTIONAL)
{
THREADINFO *pti;
UNREFERENCED_PARAMETER(hmod);
UNREFERENCED_PARAMETER(pctx);
switch (Reason) {
case DLL_PROCESS_ATTACH:
TlsIndex = TlsAlloc();
case DLL_THREAD_ATTACH:
pti = (THREADINFO *)LocalAlloc(LPTR, sizeof(THREADINFO));
if (!pti) {
return(FALSE);
}
TlsSetValue(TlsIndex, pti);
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
pti = TlsGetValue(TlsIndex);
LocalFree(pti);
if (Reason == DLL_PROCESS_DETACH) {
TlsFree(TlsIndex);
}
break;
}
return TRUE;
}
/*
* An application must call this API first to establish a conversation
* with progman. DDEML initialization is done automatically if needed.
*/
BOOL ConnectToProgmanA()
{
THREADINFO *pti;
HSZ hszProgman;
pti = TlsGetValue(TlsIndex);
if (!pti->idInst) {
if (DdeInitializeA(&(pti->idInst), ProgHelpDdeCallback,
APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS,
0L) != DMLERR_NO_ERROR) {
return(FALSE);
}
}
if (pti->hConv == 0) {
hszProgman = DdeCreateStringHandleA(pti->idInst, "Progman", 0);
pti->hConv = DdeConnect(pti->idInst, hszProgman, hszProgman, NULL);
}
return(pti->hConv != 0);
}
BOOL ConnectToProgmanW()
{
THREADINFO *pti;
HSZ hszProgman;
pti = TlsGetValue(TlsIndex);
if (!pti->idInst) {
if (DdeInitializeW(&(pti->idInst), ProgHelpDdeCallback,
APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS,
0L) != DMLERR_NO_ERROR) {
return(FALSE);
}
}
if (pti->hConv == 0) {
hszProgman = DdeCreateStringHandleA(pti->idInst, "Progman", 0);
pti->hConv = DdeConnect(pti->idInst, hszProgman, hszProgman, NULL);
}
return(pti->hConv != 0);
}
/*
* This API should be called when operations with progman are complete.
* We shutdown DDEML here as well so we don't have to deal with it
* at DLL detatch time.
*/
BOOL DisconnectFromProgman()
{
THREADINFO *pti;
pti = TlsGetValue(TlsIndex);
if (!pti->idInst) {
return(TRUE);
}
if (pti->hConv) {
DdeDisconnect(pti->hConv);
pti->hConv = 0;
}
DdeUninitialize(pti->idInst);
pti->idInst = 0;
return(TRUE);
}
/*
* This API sends an ASCII execute string to progman. It immediately returns
* and the results of the execute are not known. Calling applications should
* be aware that these transactions are done asynchronously. This allows
* this API to work under modal-loop conditions. DisconnectFromProgman()
* will not succeed until all transactions are complete.
*/
BOOL ProgmanExecuteStringA(
LPSTR pszExec)
{
THREADINFO *pti;
DWORD dwResult;
pti = TlsGetValue(TlsIndex);
if (!pti->idInst || !pti->hConv) {
return(FALSE);
}
if (!DdeClientTransaction((PBYTE)pszExec, strlen(pszExec) + 1,
pti->hConv, 0, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &dwResult)) {
return(FALSE);
}
return(TRUE);
}
BOOL ProgmanExecuteStringW(
LPWSTR pszExec)
{
THREADINFO *pti;
DWORD dwResult;
pti = TlsGetValue(TlsIndex);
if (!pti->idInst || !pti->hConv) {
return(FALSE);
}
if (!DdeClientTransaction((PBYTE)pszExec,
(wcslen(pszExec) + 1) * sizeof(WCHAR),
pti->hConv, 0, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &dwResult)) {
return(FALSE);
}
return(TRUE);
}