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 >
Wrap
C/C++ Source or Header
|
1997-10-05
|
14KB
|
400 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.
\******************************************************************************/
/*
ddeadd.c
DDEML Execute functions to add selected items
and create new group if specified.
*/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "ddeinst.h"
#include "ddextrn.h"
#include "dialogs.h"
CONVCONTEXT CCFilter = { sizeof (CONVCONTEXT), 0, 0, 0, 0L, 0L };
/********************************************************************
StartAddThread
Function to Start the program item addition thread.
********************************************************************/
BOOL StartAddThread () {
HANDLE hThread;
LONG lThreadId;
hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) AddProgramItems,
"Dummy", CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED, &lThreadId);
if (hThread) {
SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
ResumeThread (hThread);
/* Close the handle since we don't need it anymore */
CloseHandle (hThread);
return (TRUE);
}/*endIf*/
return (FALSE);
}/* end StartAddThread */
/********************************************************************
CreateGroup
Function that creates a group in the Program Manager. If the specified
name already exists the group is activated.
********************************************************************/
BOOL CreateGroup () {
HDDEDATA hData;
LPSTR szText;
LPSTR szCommand;
HCONV hConv;
HSZ szProgMan;
LONG lResult;
// Allocate a block of memory for the group name that the user has selected.
szText = VirtualAlloc (NULL, 64, MEM_COMMIT, PAGE_READWRITE);
// Allocate a block of memory for the command to send to the Program Manager.
szCommand = VirtualAlloc (NULL, 128, MEM_COMMIT, PAGE_READWRITE);
if (szText) {
// We got the memory so we can proceed.
// Initialize the DDE conversation here.
if (DdeInitialize (&lIdInst, (PFNCALLBACK) GroupDDECallback,
(DWORD) APPCMD_CLIENTONLY, 0L)) {
MessageBox (ghwndMain, "DDEML Initialization Failure", "Error", MB_OK);
VirtualFree (szText, 128, MEM_DECOMMIT);
return (FALSE);
}/*endIf*/
// Create a DDEML string handle for the Program Manager.
szProgMan = DdeCreateStringHandle (lIdInst, "PROGMAN", CP_WINANSI);
if (szProgMan) {
// String handle created so continue.
// Establish a conversation with the Program Manager.
hConv = DdeConnect (lIdInst, szProgMan, szProgMan, &CCFilter);
PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
ID_DDEML_CONNECT);
// Retrieve the text of the combo control. This will return back what the
// user has typed in if nothing has been selected.
GetWindowText (hwndCombo, szText, 64);
// Find out if this string is in the list or not. If not create a group
// Otherwise just activate the group.
lResult = (LONG) SendMessage (hwndCombo, CB_FINDSTRING, (WPARAM) -1,
(LPARAM) (LPCSTR) szText);
if (lResult == CB_ERR) {
// Create the group by creating the command line.
// The program manager will activate an existing group if the name matches
// a DDE attempt to create a new group so the create versus show is somewhat
// redundant.
sprintf (szCommand, "[CreateGroup(%s)]", szText);
// Create a DDEML data handle for the command.
hData = DdeCreateDataHandle (lIdInst, szCommand,
strlen (szCommand) + 1, 0, (HSZ) NULL, CF_TEXT, 0L);
// Send the transaction to the server waiting a maximum of 10 seconds.
// The server will release the data handle.
if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF, hConv,
(HSZ) NULL, 0, XTYP_EXECUTE, 10000, &lResult)) {
// If it fails get the error code.
lResult = DdeGetLastError (lIdInst);
MessageBox (NULL, "DdeClientTransaction Failed", "Error",
MB_OK);
}/*endIf*/
PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
ID_DDEML_CREATE);
} else {
// Group already exists so activate it.
sprintf (szCommand, "[ShowGroup(%s,1)]", szText);
// Create a DDEML data handle for the command.
hData = DdeCreateDataHandle (lIdInst, szCommand, strlen (szCommand),
0, (HSZ) NULL, CF_TEXT, 0L);
// Send the transaction to the server waiting a maximum of 10 seconds.
// The server will release the data handle.
if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF, hConv,
(HSZ) NULL, 0, XTYP_EXECUTE, 10000, &lResult)) {
// If it fails get the error code.
lResult = DdeGetLastError (lIdInst);
}/*endIf*/
PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
ID_DDEML_ACTIVATE);
}/*endIf*/
// Release the Program Manager string handle.
DdeFreeStringHandle (lIdInst, szProgMan);
// Disconnect from the server.
DdeDisconnect (hConv);
PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
ID_DDEML_COMPLETE);
} else {
lResult = DdeGetLastError (lIdInst);
}/*endIf*/
// Free the two blocks of memory that were allocated.
VirtualFree (szText, 64, MEM_DECOMMIT);
VirtualFree (szCommand, 64, MEM_DECOMMIT);
EnableWindow (hwndAddButton, TRUE);
// Uninitialize the conversation here so that resources are freed.
DdeUninitialize (lIdInst);
lIdInst = 0L;
return (TRUE);
} else {
MessageBox (NULL, "Memory Allocation failure", "Error", MB_OK);
}/*endIf*/
EnableWindow (hwndAddButton, FALSE);
return (FALSE);
}/* end CreateGroup */
// Local function
void UpdateProgressBar (int, int);
// Flag for progress bar update
BOOL fFirst;
/********************************************************************
AddProgramItems
Function that uses DDEML to add program items to group in Program
Manager.
********************************************************************/
BOOL AddProgramItems (LPSTR szDummy) {
char szPercent[8];
HDDEDATA hData;
HCONV hConv;
HSZ szProgMan;
int lSelCount;
LONG lResult;
LPLONG lpSelection;
LPSTR szProgName;
LPSTR szExePath;
LPSTR szExecuteString;
int iIndex;
int iGroupCount;
fFirst = FALSE;
iGroupCount = 2;
// Retrieve the number of selected items from the file list.
lSelCount = (int) SendMessage (hwndFileList, LB_GETSELCOUNT, 0, 0L);
// Allocate a block of memory to hold the indexes of the list selection.
lpSelection = VirtualAlloc (NULL, lSelCount * sizeof (int), MEM_COMMIT,
PAGE_READWRITE);
if (lpSelection) {
// Establish a new conversation.
if (DdeInitialize (&lIdInst2, (PFNCALLBACK) GroupDDECallback,
(DWORD) APPCMD_CLIENTONLY, 0L)) {
VirtualFree (lpSelection, lSelCount * sizeof (int), MEM_DECOMMIT);
return (FALSE);
}/*endIf*/
// Create a DDEML string handle for the Program Manager.
szProgMan = DdeCreateStringHandle (lIdInst2, "PROGMAN", CP_WINANSI);
// Establish the conversation.
hConv = DdeConnect (lIdInst2, szProgMan, szProgMan, &CCFilter);
PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0,
ID_DDEML_CONNECT);
// Release the string handle that we created.
DdeFreeStringHandle (lIdInst2, szProgMan);
// Allocate a block of memory to hold the path and name of the item.
szProgName = VirtualAlloc (NULL, MAX_PATH * 2, MEM_COMMIT,
PAGE_READWRITE);
szExePath = szProgName + MAX_PATH;
// Allocate some memory to hold the command string.
szExecuteString = VirtualAlloc (NULL, MAX_PATH * 4, MEM_COMMIT,
PAGE_READWRITE);
// Retrieve the array of list selections.
SendMessage (hwndFileList, LB_GETSELITEMS, (WPARAM) lSelCount,
(LPARAM) lpSelection);
// Loop through the array of selections.
for (iIndex = 0; iIndex < lSelCount; iIndex++) {
// Work around for limitation for in ProgMan (no more than 50 items per group)
if (!(iIndex % 50) && (iIndex > 0)) {
LPSTR szText;
LPSTR szText2;
// Allocate a block of memory for the group name
szText = VirtualAlloc (NULL, 64, MEM_COMMIT, PAGE_READWRITE);
szText2 = VirtualAlloc (NULL, 256, MEM_COMMIT, PAGE_READWRITE);
if (szText && szText2) {
GetWindowText (hwndCombo, szText, 64);
sprintf (szText2, "[CreateGroup(%s Part %ld )]", szText,
iGroupCount++);
// Create a DDEML data handle for the command.
hData = DdeCreateDataHandle (lIdInst2, szText2,
strlen (szText2) + 1, 0, (HSZ) NULL, CF_TEXT, 0L);
// Send the transaction to the server waiting a maximum of 10 seconds.
// The server will release the data handle.
if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF, hConv,
(HSZ) NULL, 0, XTYP_EXECUTE, 10000, &lResult)) {
// If it fails get the error code.
lResult = DdeGetLastError (lIdInst);
MessageBox (NULL, "DdeClientTransaction Failed",
"Error", MB_OK);
}/*endIf*/
VirtualFree (szText, 64, MEM_DECOMMIT);
VirtualFree (szText2, 256, MEM_DECOMMIT);
}
}/*endIf*/
// Retrieve the Name of the Program Item to add.
SendMessage (hwndFileList2, LB_GETTEXT, (WPARAM) lpSelection[iIndex],
(LPARAM) szProgName);
// Set the name in the progress dialog
SetDlgItemText (hwndDialog, IDL_ITEMNAME, szProgName);
// Retrieve the absolute path of the item to add.
SendMessage (hwndPathList, LB_GETTEXT, (WPARAM) lpSelection[iIndex],
(LPARAM) szExePath);
// Set the path in the progress dialog
SetDlgItemText (hwndDialog, IDL_EXEPATH, szExePath);
// Set the percentage in the progress dialog
sprintf (szPercent, "%d%%", (iIndex * 100) / lSelCount);
SetDlgItemText (hwndDialog, IDL_PERCENTAGE, szPercent);
UpdateProgressBar (iIndex + 1, lSelCount);
// Create the command string to add the item.
sprintf (szExecuteString, "[AddItem(%s,%s)]", szExePath,
(LPARAM) szProgName);
// Create a DDEML Data handle for the command string.
hData = DdeCreateDataHandle (lIdInst2, szExecuteString,
strlen (szExecuteString) + 1, 0, (HSZ) NULL, CF_TEXT, 0L);
// Send the command over to the program manager.
if (!DdeClientTransaction ((LPBYTE) hData, 0xFFFFFFFF,
hConv, (HSZ) NULL, 0, XTYP_EXECUTE, 1000, &lResult)) {
lResult = DdeGetLastError (lIdInst2);
}/*endIf*/
}/*endFor*/
// Release the memory allocated for path and name retrieval.
VirtualFree (szProgName, MAX_PATH * 2, MEM_DECOMMIT);
// Release the command line memory.
VirtualFree (szExecuteString, MAX_PATH * 4, MEM_DECOMMIT);
// Disoconnect the DDEML Conversation
DdeDisconnect (hConv);
// Release the memory allocate for the list selections.
VirtualFree (lpSelection, lSelCount * sizeof (int), MEM_DECOMMIT);
}/*endIf*/
// Clear the selection in the lists.
SendMessage (hwndFileList, LB_SETSEL, (WPARAM) FALSE, (LPARAM) -1);
SendMessage (hwndFileList2, LB_SETSEL, (WPARAM) FALSE, (LPARAM) -1);
EnableWindow (hwndAddAll, FALSE);
// Uninitialize the local conversation.
DdeUninitialize (lIdInst2);
if (hwndDialog) {
PostMessage (ghwndMain, WM_USER_CLOSE_DIALOG, 0, 0L);
}/*endIf*/
lIdInst2 = 0L;
if (fBatch) {
PostMessage (ghwndMain, WM_COMMAND, (WPARAM)
(WPARAM) MAKELONG (ID_EXITBUTTON, BN_CLICKED),
(LPARAM) hwndExitButton);
}/*endIf*/
return (TRUE);
}/* end AddProgramItems */
HWND hwndBar;
RECT rc;
double iStep;
HBRUSH hBrush;
/********************************************************************
UpdateProgressBar
Function to update the progress bar in the dialog while items are
added to the Program Manager.
********************************************************************/
void UpdateProgressBar (int iIndex, int iCount) {
HDC hdc;
if (!fFirst) {
hwndBar = GetDlgItem (hwndDialog, IDL_PROGRESSBAR);
if (hwndBar) {
GetClientRect (hwndBar, &rc);
fFirst = TRUE;
} else {
return;
}/*endIf*/
iStep = (double) rc.right / (double) iCount;
hBrush = GetStockObject (BLACK_BRUSH);
}/*endIf*/
hdc = GetDC (hwndBar);
rc.right = (int) (iStep * (double) iIndex);
FillRect (hdc, &rc, hBrush);
ReleaseDC (hwndBar, hdc);
PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, iIndex, ID_DDEML_ADD);
}/* end UpdateProgressBar */