home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR24
/
PC2_140.ZIP
/
SOURCE.ZIP
/
PC2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-17
|
73KB
|
1,276 lines
/***********************************************************************\
* PC2.c *
* Copyright (C) by Stangl Roman, 1993 *
* This Code may be freely distributed, provided the Copyright isn't *
* removed, under the conditions indicated in the documentation. *
* *
* PC/2 - Program Commander/2 is a configurable program starter for *
* OS/2 2.0 PM. If the user clicks button 1 on the DESKTOP, a user *
* modifyable popup menu is displayed. The user then selects a program *
* to be started, or configuration of PC/2 or dismisses it. *
* PC/2 is an alternative method of starting programs compared to *
* icons and uses no space on DESKTOP, and no folder must be opended *
* to start a program. For frequently used programs, this reduces the *
* time to start an application. *
* *
\***********************************************************************/
static char RCSID[]="@(#) $Header: PC2.c/PC2.h Version 1.40 04,1993 $ (LBL)";
#define _FILE_ "PC/2 - PC2.c V1.40"
#include "PC2.h" /* User include files */
#include "Error.h"
/* PC/2 semaphore to avoid loading PC/2 twice */
#define PC2_SEM "\\SEM32\\PC2_SEM.SEM"
#define DESKTOP_CLASS "#37" /* Class name of the "Desktop" window handle (which
is reserved in the Toolkit */
HEV hevPc2; /* Handle of PC/2 semaphore */
BOOL InstallHelp; /* True if we're installing */
UCHAR *pucFilenameProfile; /* The buffer holding the filename of the profile */
UCHAR *pucFilenameHLP; /* The buffer holding the filename of the HLP file */
UCHAR *pucPathDLL; /* Directory of PC/2 to seek for DLL file */
/* Default the Popup-Menu is displayed after a
WM_BUTTON1CLICK on the Desktop, but users may
prefer WM_BUTTON1DBLCLK to popup the menu */
ULONG ulClickFlag=WM_BUTTON1DBLCLK;
HMODULE hDllPc2; /* Handle of PC/2 DLL */
PFFUNCPTR1 *pPC2DLL_SetHwnd; /* Pointer to DLL-Functions */
PFFUNCPTR2 *pPC2DLL_Hook;
/* *\
* Reserve data referenced generally through all modules. This isn't the best way, hope *
* that C++ comes out soon... *
\* */
HAB hab; /* Handle of PM anchor block */
HMQ hmq; /* Handle of message queue */
HWND hwndFrame; /* Frame handle of window */
HWND hwndClient; /* Client handle of window */
HWND hwndPopupMenu; /* Handel of popup menu window */
/* Input options: mouse button 1 depressed,
Input devices keyboard or mouse button 1,
popup menu allways visible on DESKTOP,
position so that ID_CONFIGDIALOG is under the
pointer */
HWND hwndHelp; /* Help window handle */
SESSIONDATA SessionData; /* Used by Menu Installation dialog and by
Program Installation dialog to store menu or
program data, to be filled from the user or
to be presented to the user. */
MENUDATA *pPopupMenu=NULL; /* Used by all procedures as the starting point
of a linked list of menu entries. */
MENUDATA *pMenuData; /* This pointer points to the current level of
Submenus and Menuitems within the configuration
dialog procedure */
/* Create linked list by starting with this ID */
USHORT MenuDataId=ID_POPUPMENU;
USHORT DialogResult; /* Each dialog procedure returns the result in
this variable to enable the calling routine to
check, if there is valid data or not. */
FILE *Pc2Profile; /* Open the profile, where the user entered menu
data is stored, with this handle */
SWP swpScreen; /* The screen dimensions */
/*--------------------------------------------------------------------------------------*\
* The main procedure. *
* Req: *
* argc, argv, envp *
* Returns: *
* int ........... Exitcode (0, or errorlevel) *
\*--------------------------------------------------------------------------------------*/
int main(int argc, char *argv[], char *envp[])
{
QMSG qmsg; /* Message queue */
ULONG counter; /* Temporary counter */
/* Frame creation control flag */
ULONG flCreate=FCF_TASKLIST | FCF_ACCELTABLE;
/* *\
* Get the full path and filename of the running copy of PC/2 and change the extension *
* .EXE into .cfg to open the configuration file under this name. If the user supplies *
* [-,/Profile filename.ext] then use this filename as the Profile. Also change .EXE *
* into .HLP and PC/2 directory as the current directory to access .DLL. *
\* */
/* Long enough to hold user Profile name */
pucFilenameProfile=malloc(strlen(argv[0])+64);
pucFilenameHLP=malloc(strlen(argv[0])+1);
pucPathDLL=malloc(strlen(argv[0])+1);
strcpy(pucFilenameProfile, argv[0]);
strcpy(pucFilenameHLP, argv[0]);
strcpy(pucPathDLL, argv[0]);
strcpy(strchr(pucFilenameProfile, '.'), ".cfg");
strcpy(strchr(pucFilenameHLP, '.'), ".hlp");
strcpy(strrchr(pucPathDLL, '\\'), ""); /* Backward scan for \ */
InstallHelp=FALSE; /* Assume no installation */
for(counter=1; counter<argc; counter++)
{
strupr(argv[counter]); /* Convert to uppercase */
/* Test for /PROFILE or -PROFILE to get a
profile name */
if((strstr(argv[counter], "/PROFILE")!=NULL) ||
(strstr(argv[counter], "-PROFILE")!=NULL))
strcpy((pucFilenameProfile+strlen(pucFilenameProfile)-7), argv[counter+1]);
/* Test for /INSTALL or -INSTALL to start the help
panels during initialization */
if((strstr(argv[counter], "/INSTALL")!=NULL) ||
(strstr(argv[counter], "-INSTALL")!=NULL))
InstallHelp=TRUE;
/* Test for /DOUBLECLICK or -DOUBLECLICK to display
the Popup-Menu after a double-click instead of
a single click */
if((strstr(argv[counter], "/DOUBLECLICK")!=NULL) ||
(strstr(argv[counter], "-DOUBLECLICK")!=NULL))
ulClickFlag=WM_BUTTON1DBLCLK;
/* Test for /SINGLECLICK or -SINGLECLICK to display
the Popup-Menu after a double-click instead of
a single click */
if((strstr(argv[counter], "/SINGLECLICK")!=NULL) ||
(strstr(argv[counter], "-SINGLECLICK")!=NULL))
ulClickFlag=WM_BUTTON1CLICK;
}
do
{
/* Initialize anchor block and message queue */
if(WinStartUp(&hab, &hmq)==FALSE) break;
if(!WinRegisterClass( /* Register window class */
hab, /* Handle of anchor block */
(PSZ)PC2_CLASSNAME, /* Window class name */
(PFNWP)PC2_MainWindowProc, /* Address of window procedure */
CS_SAVEBITS, /* Class style */
0)) /* Extra window words */
{
GEN_ERR(hab, (HWND)NULL, (HWND)NULL);
break;
}
if((hwndFrame=WinCreateStdWindow( /* Create a standart window */
HWND_DESKTOP, /* DESKTOP is parent */
0, /* Standard window styles */
&flCreate, /* Frame control flags */
(PSZ)PC2_CLASSNAME, /* Client window class name */
"", /* No window text */
0, /* No special class style */
(HMODULE)0, /* Ressource is in .EXE file */
ID_PC2MAINWINDOW, /* Frame window identifier */
&hwndClient) /* Client window handle */
)==NULLHANDLE)
{
GEN_ERR(hab, (HWND)NULL, (HWND)NULL);
break;
}
/* *\
* Check if we are allready loaded before by querying a semaphore that is defined the *
* first time PC/2 runs. *
\* */
if(DosCreateEventSem( /* Create a semaphore */
PC2_SEM, /* Name */
&hevPc2, /* Handle */
(ULONG)0, /* Named semaphores are allways shared */
(BOOL32)FALSE)) /* Initially set */
{ /* If an error occurs, either we can't create
the semaphore or it allready exists. We assume
that it exists, meaning PC/2 allready loaded */
USR_ERR("PC/2 allready loaded - exiting...", hwndFrame, hwndClient);
break;
}
/* *\
* Load the Pc2Hook DLL either from the current directory or a LIBPATH path and *
* obtain the addresses of the entrypoints. There seems to be a little bug?, when the *
* library name contains a .DLL extension - the DLL is loaded sucessfully but not *
* always correct initialized? and calling functions in the DLL tend to fail. Extension *
* .DLL therefore not appended to library name. *
\* */
{
UCHAR ucDrive;
UCHAR ucBuffer[80];
/* Get drive of PC/2's startup directory
1=A, 2=B, 3=C,.... and direcotry itself */
ucDrive=tolower(pucPathDLL[0]);
DosSetDefaultDisk(++ucDrive-'a');
DosSetCurrentDir(pucPathDLL);
if(DosLoadModule( /* Load the DLL of PC/2 */
ucBuffer, /* Save failure there */
sizeof(ucBuffer)-1, /* Length of save area */
"PC2Hook", /* Library name */
&hDllPc2)!=NO_ERROR) /* DLL module handle */
{ /* DLL couldn't be found in the current PC/2
directory or via the LIBPATH path */
USR_ERR("Can't find PC2HOOK.DLL, please check DLL file and LIBPATH - exiting...",
hwndFrame, hwndClient);
break;
}
if(DosQueryProcAddr( /* Now get the address of the functions within the DLL */
hDllPc2, /* DLL module handle */
1, /* Ordinal number of procedure whose address is desired */
"PC2DLL_SetHwnd", /* Procedure name being referenced */
/* Procedure address returned */
(PFN *)(&pPC2DLL_SetHwnd))!=NO_ERROR)
{ /* An error occured */
DosFreeModule(hDllPc2); /* Free DLL reference */
USR_ERR("Can't load from PC2HOOK.DLL - exiting...", hwndFrame, hwndClient);
break;
}
if(DosQueryProcAddr(
hDllPc2,
2,
"PC2DLL_Hook",
(PFN *)(&pPC2DLL_Hook))!=NO_ERROR)
{
DosFreeModule(hDllPc2);
USR_ERR("Can't load from PC2HOOK.DLL - exiting...", hwndFrame, hwndClient);
break;
}
}
/* *\
* Now initilize Help, if it can't be initialized the we get no help but that's no *
* reason to terminate. *
\* */
if(WinStartHelp(hab, pucFilenameHLP, &hwndHelp)==FALSE)
USR_ERR("Can't find PC2.HLP, please check HLP file and HELP - ignoring help requests...",
hwndFrame, hwndClient);
/* Query and save the device resolution */
swpScreen.cx=WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
swpScreen.cy=WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
if(!WinSetWindowPos( /* Set window postion */
hwndFrame, /* Window handle */
HWND_BOTTOM, /* Window position at background */
0, 0, 0, 0, /* Window size */
/* Window control */
SWP_ZORDER | SWP_SHOW | SWP_DEACTIVATE))
GEN_ERR(hab, (HWND)NULL, (HWND)NULL);
WinSetWindowText(hwndFrame, "PC/2 - Program Commander/2");
/* *\
* Now setup the Popup-Menu by loading the data from the profile and install the hook *
* into the system input queue. *
\* */
hwndPopupMenu=WinLoadMenu( /* Load popup menu */
hwndClient, /* Owner window handle */
(HMODULE)0, /* Ressource in .EXE file */
ID_PC2MAINWINDOW); /* Menu identifier in ressource file */
/* Load the data from the profile */
WinPostMsg(hwndClient, WM_SETPOPUPMENU, NULL, NULL);
/* Now install the hook */
WinPostMsg(hwndClient, WM_LOADHOOK, NULL, NULL);
/* *\
* Here we loop dispatching the messages... *
\* */
while(WinGetMsg(hab, &qmsg, 0, 0, 0))
WinDispatchMsg(hab, &qmsg); /* Dispatch messages to window procedure */
WinDestroyWindow(hwndFrame); /* Close window */
} while (FALSE);
if(WinCloseDown(&hwndHelp, &hab, &hmq)==FALSE) return(1);
else return(0);
}
/*--------------------------------------------------------------------------------------*\
* This procedure is the PC/2 window procedure. *
\*--------------------------------------------------------------------------------------*/
MRESULT EXPENTRY PC2_MainWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
switch(msg)
{
case WM_CREATE: /* Create window by WinCreateStdWindow() */
{
USHORT usTimer;
/* First call default window procedure */
WinDefWindowProc(hwnd, msg, mp1, mp2);
if(InstallHelp==TRUE) /* For installation display help panels */
WinPostMsg(hwnd, WM_COMMAND, MPFROMSHORT(ID_HELP), NULL);
/* Start timer for WM_TIMER every 2,5 seconds */
for(usTimer=0; usTimer<=TID_USERMAX; usTimer++)
/* If we found the first timer break */
if(WinStartTimer(hab, hwnd, usTimer, 02500)) break;
if(usTimer>TID_USERMAX) /* Inform user if we can't find a timer */
USR_ERR("Cannot obtain a timer", hwndFrame, hwndClient);
}
break;
/* *\
* Syntax: WM_SETPOPUPMENU, NULL, NULL *
\* */
case WM_SETPOPUPMENU:
/* *\
* Open the profile for reading the linked list containing the popup menu data. If the *
* profile can't be opened, the file is assumed to be empty so the popup menu is empty. *
\* */
if((Pc2Profile=fopen(pucFilenameProfile, "r"))==NULL)
{
pPopupMenu=AllocateMenuData(); /* Allocate an empty MENUDATA structure used as
the first element of linked list */
USR_ERR("Cannot open confguration file - assuming empty file", hwndFrame, hwndClient);
}
else
{
static UCHAR Buffer[256];
pPopupMenu=AllocateMenuData(); /* Allocate an empty MENUDATA structure used as
the first element of linked list */
fgets(Buffer, sizeof(Buffer), Pc2Profile);
if(strcmp(Buffer, "PROFILE START\n")==0)
LoadMenu(pPopupMenu); /* Load the rest by calling a recursive procedure */
fclose(Pc2Profile);
}
pMenuData=pPopupMenu; /* Initialize *MENUDATA for Configuration dialog
procedure to a known value */
break;
case WM_TIMER:
/* *\
* If we run without the WPS, the user may decide to start PMSHELL sometimes. If he *
* does this, the window handle of the Desktop, where we catch the mouse button clicks *
* changes. So we use the timer on a regular basis of about 1 second the query for the *
* window handle to see any changes immediately. *
\* */
/* *\
* Syntax: WM_SETDESKTOPHANDLE, NULL, NULL *
\* */
case WM_SETDESKTOPHANDLE:
/* *\
* Query the window handle of the Desktop window and load it into PC2HOOK.DLL library. *
\* */
{
UCHAR ucClass[33]; /* Save class name here */
HWND hwndDesktop; /* Save "Desktop" window handle, where the user
clicks with mouse button 1 */
HENUM henumWindows; /* Enumerate windows */
BOOL bMatch; /* True if correct "Desktop" window handle was found */
/* Get to bottommost window handle of the "Desktop" */
hwndDesktop=WinQueryWindow(HWND_DESKTOP, QW_BOTTOM);
/* Enumerate all windows at "Desktop" z-order */
henumWindows=WinBeginEnumWindows(hwndDesktop);
bMatch=FALSE;
while(hwndDesktop=WinGetNextWindow(henumWindows))
{
/* Now get the class name of that window handle */
WinQueryClassName(hwndDesktop, sizeof(ucClass)-1, (PCH)ucClass);
/* If we find the required "Desktop" window (it
has a class name of #37, which is reserved in the
Toolkit) set this value into the Hook DLL */
if(!strcmp(ucClass, DESKTOP_CLASS))
{
bMatch=TRUE;
pPC2DLL_SetHwnd(ulClickFlag, hwndDesktop, hwnd);
}
}
WinEndEnumWindows(henumWindows); /* End enumeration */
/* *\
* If bMatch==TRUE then we have found the required "Desktop" window, but this is only *
* available if the WPS is running. If the WPS is not running (PM running alone, then *
* bMatch==FALSE will be set. Thus bMatch will be used to differentiate between PM *
* running with WPS and without WPS - however I don't know if this holds true for all *
* OS/2 2.x releases. *
\* */
if(bMatch==FALSE)
{
/* Without WPS installed we can get the "Desktop"
window handle easily */
hwndDesktop=WinQueryDesktopWindow(hab, NULLHANDLE);
pPC2DLL_SetHwnd(ulClickFlag, hwndDesktop, hwnd);
}
}
break;
/* *\
* Syntax: WM_LOADHOOK, NULL, NULL *
\* */
case WM_LOADHOOK:
/* *\
* Install the hook into the system input queue pointing to the PC2DLL_Hook() procedure *
* in the DLL PC2HOOK.DLL. If we can't do this we exit after an error message box. *
\* */
/* Query and set the window handle of the Desktop */
WinSendMsg(hwnd, WM_SETDESKTOPHANDLE, NULL, NULL);
if(WinSetHook( /* Set a hook */
hab, /* Handle of anchor block */
NULLHANDLE, /* Hook into system message queue */
HK_INPUT, /* Hook of system input queue */
(PFN)pPC2DLL_Hook, /* Pointer to hook procedure */
hDllPc2)==FALSE)
{
USR_ERR("Hooking the system input queue failed - exiting...", hwndFrame, hwndClient);
WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
}
break;
/* *\
* Syntax: WM_POPUPMENU, (x,y), mp2 *
\* */
case WM_POPUPMENU:
/* *\
* The hook found that button 1 was clicked on the Desktop and sent us this message. It *
* is either a WM_BUTTON1CLICK or WM_BUTTON1DBLCLK. First we obtain the focus, to be *
* able to start our programs in the foreground. *
\* */
{
USHORT fsOptions=PU_NONE | PU_KEYBOARD | PU_MOUSEBUTTON1 |
PU_POSITIONONITEM | PU_HCONSTRAIN | PU_VCONSTRAIN;
WinSetFocus(HWND_DESKTOP, hwnd); /* Set focus to our window */
if(!WinPopupMenu( /* Pop up the popup menu */
HWND_DESKTOP, /* Parent window handle */
hwnd, /* Owner window handle that receives all the
notification messages generated by the pop-up
menu */
hwndPopupMenu, /* Popup menu window handle */
SHORT1FROMMP(mp1), /* x-coordinate of mouse pointer for popup menu */
SHORT2FROMMP(mp1), /* y-coordinate of mouse pointer for popup menu */
ID_PC2SETUP, /* Input item identity, if PU_POSITIONONITEM or
PU_SELECTITEM is set */
fsOptions) /* Input options */
) GEN_ERR(hab, (HWND)NULL, (HWND)NULL);
break;
}
case WM_CLOSE:
if(WinMessageBox( /* Ask the user if he really wants to exit */
HWND_DESKTOP, HWND_DESKTOP,
"Are you sure you want to close PC/2?",
"PC/2 - Program Commander/2",
ID_PC2MAINWINDOW,
MB_OKCANCEL | MB_ICONQUESTION | MB_DEFBUTTON2)!=MBID_OK)
return((MRESULT)TRUE); /* Only exit if OK is pressed */
if(WinReleaseHook( /* Release hook */
hab, /* Handle of anchor block */
NULLHANDLE, /* Release from system hook chain */
HK_INPUT, /* Hook of system input queue */
(PFN)pPC2DLL_Hook, /* Pointer to hook procedure */
hDllPc2)==FALSE)
{
USR_ERR("Unhooking the system input queue failed, System ShutDown suggested - exiting...",
hwndFrame, hwndClient);
WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
}
DosFreeModule(hDllPc2); /* Free DLL reference */
WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
break;
case HM_ERROR:
{
GEN_ERR(hab, hwndFrame, hwndClient);
break;
}
case WM_COMMAND:
{
USHORT command;
command=SHORT1FROMMP(mp1); /* Extract the command value */
/* *\
* Filter the IDs of the user defined items of the Popup-Menu. If one is found, call *
* SearchItem() to search for the corresponding MENUDATA structure, copy it to a *
* SESSIONDATA structure and start the session. *
\* */
if((command>=USERITEMFIRST) && (command<=USERITEMLAST))
{
ULONG id=(ULONG)command;
MENUDATA *pMD=NULL;
/* Search in the linked list for this entry */
if((pMD=SearchItem(pPopupMenu, &id))!=NULL)
if(pMD->Item==ENTRYMENUITEM)
{
/* Load SessionData with MENUDATA structure */
LoadMenuData2SessionData(FALSE, pMD, &SessionData);
/* Start the session */
StartSession(&SessionData);
}
}
switch(command)
{
case ID_HELP: /* Display general help panel */
if(hwndHelp!=NULLHANDLE) WinSendMsg(
hwndHelp, /* Help window */
HM_DISPLAY_HELP, /* Display a help panel */
MPFROMSHORT(ID_HELP), /* Panel ID in ressource file */
HM_RESOURCEID); /* MP1 points to the help window identity */
break;
case ID_CONFIGDIALOG: /* Popup menuitem Configure PC/2 selected */
if(!WinDlgBox( /* Start Configure PC/2 dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
CD_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
CDID_CONFIGDIALOG, /* ID of Configure PC/2 dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
break;
case ID_SHUTDOWN: /* ShutDown OS/2 menuitem selected */
if(WinMessageBox( /* Ask the user if he really wants to shut down OS/2 */
HWND_DESKTOP, HWND_DESKTOP,
"Are you really sure you want to ShutDown OS/2?",
"PC/2 - Program Commander/2",
ID_PC2MAINWINDOW,
MB_OKCANCEL | MB_ICONQUESTION | MB_DEFBUTTON2)!=MBID_OK)
return((MRESULT)TRUE); /* Only shut down if OK is pressed */
if(!WinDlgBox( /* Start ShutDown OS/2 dialog box */
HWND_DESKTOP, HWND_DESKTOP, SD_DialogProcedure, 0,
SDID_SHUTDOWNDIALOG, 0))
GEN_ERR(hab, hwndFrame, hwndClient);
break;
case ID_EXIT: /* User selected F3 to shutdown PC/2 */
WinPostMsg(hwnd, WM_CLOSE, 0, 0);
break;
case ID_ABOUTDIALOG: /* User selected About PC/2 dialog */
if(!WinDlgBox( /* Start About PC/2 dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
AD_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
ADID_ABOUTDIALOG, /* ID of Program Installation dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
break;
}
break;
}
default: /* Default window procedure must be called */
return((MRESULT)WinDefWindowProc(hwnd, msg, mp1, mp2));
}
return((MRESULT)FALSE); /* We have handled the message */
}
/*--------------------------------------------------------------------------------------*\
* This dialog procedure handles the PC/2 - Configuration (Setup) dialog. *
* Req: none *
\*--------------------------------------------------------------------------------------*/
MRESULT EXPENTRY CD_DialogProcedure(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
switch(msg)
{
case WM_INITDLG:
{
SWP swp;
WinQueryWindowPos( /* Query position of dialog window */
hwndDlg, /* Handle of dialog window */
&swp); /* Fill with position */
WinSetWindowPos( /* Set dialog window position */
hwndDlg, /* Handle of dialog window */
HWND_TOP, /* Position on top and center of DESKTOP */
(swpScreen.cx-swp.cx)/2,
(swpScreen.cy-swp.cy)/2,
0,
0,
SWP_MOVE);
/* Initialize the listbox */
WinSendMsg(hwndDlg, WM_LOADPOPUPMENU, MPFROMP(pMenuData), NULL);
break;
}
/* *\
* Syntax: WM_LOADPOPUPMENU, *MENUDATA, NULL *
\* */
case WM_LOADPOPUPMENU: /* Load the current level of the Popup-Menu in
the listbox after removing the old items */
{
MENUDATA *pMD;
pMD=PVOIDFROMMP(mp1); /* Get the pointer to the first MENUDATA of the
current level */
WinSendDlgItemMsg( /* Send message to listbox */
hwndDlg, /* Handle of dialog window */
CDLB_MENUPROGRAM, /* Submenu & Program listbox */
LM_DELETEALL, /* Delete all list box items */
(MPARAM)NULL,
(MPARAM)NULL);
if(pMD==NULL) break; /* If linked list is empty break out */
do
{
if(pMD->Item==ENTRYSUBMENU) /* It is a Submenu */
{
UCHAR Buffer[EF_SIZE60+4];
/* Add >> for a Submenu */
sprintf(Buffer, "%s >>", pMD->PgmTitle);
WinSendDlgItemMsg(
hwndDlg,
CDLB_MENUPROGRAM,
LM_INSERTITEM, /* Insert Submenu Title at the end */
MPFROMSHORT(LIT_END),
MPFROMP(Buffer));
}
if(pMD->Item==ENTRYMENUITEM) /* It's a Menuitem */
WinSendDlgItemMsg(
hwndDlg,
CDLB_MENUPROGRAM,
LM_INSERTITEM, /* Insert Menuitem Title at the end */
MPFROMSHORT(LIT_END),
MPFROMP(pMD->PgmTitle));
/* It may also be an empty entry, but then we
ignore it, because it must be filled with
Menuitem or Submenu data first */
if(pMD->Next!=NULL) /* Get through linked list without diving into
Submenus */
pMD=pMD->Next;
else break; /* We're at the end of the linked list */
}while(TRUE);
break;
}
/* *\
* Syntax: WM_SAVEPOPUPMENU, NULL, NULL *
\* */
case WM_SAVEPOPUPMENU: /* Save the Popup-Menu to the configuraion file */
if((Pc2Profile=fopen(pucFilenameProfile, "w"))==NULL)
USR_ERR("Cannot open confguration file - changes won't be saved",
hwndFrame, hwndClient);
else
{
fprintf(Pc2Profile, "PROFILE START\n");
SaveMenu(pPopupMenu); /* Save the menu linked list */
fprintf(Pc2Profile, "PROFILE END\n");
fclose(Pc2Profile);
}
break;
case WM_HELP: /* Help pressed */
WinSendMsg(
hwndHelp, /* Help window */
HM_DISPLAY_HELP, /* Display a help panel */
MPFROMSHORT(ID_CONFIGDIALOG), /* Panel ID in ressource file */
HM_RESOURCEID); /* MP1 points to the help window identity */
break;
case WM_COMMAND: /* Button pressed */
switch(SHORT1FROMMP(mp1))
{
/* *\
* Chain up the linked list until we find the node, where this part-list comes from or *
* the beginning of the complete list. The pointer pMenuData is adjusted. *
\* */
case CDID_LEVELUP: /* Get up one level in the linked list */
{
MENUDATA *pMD; /* Pointer to a MENUDATA structure to find the
Submenu where this part-list starts */
pMD=pMenuData; /* Point to the first element of the linked list
at the current level */
if(pMD->Back==NULL) /* If we're at the beginning of the complete linked
list ignore button */
return((MRESULT)FALSE);
else pMD=pMD->Back; /* Submenu which started current level */
/* Now chain back through the linked list and find
the element, where the pointer to a Submenu
equals the back pointer of the first element
in this Submenu. Then we've found the node */
while(TRUE)
{
if(pMD->Back==NULL) /* If we're now at the beginning break */
break;
if((pMD->Back)->Submenu==pMD)
break;
else pMD=pMD->Back;
}
pMenuData=pMD; /* Load as the top element of the current item */
/* Now redraw items in listbox */
WinSendMsg(hwndDlg, WM_LOADPOPUPMENU, MPFROMP(pMenuData), NULL);
return((MRESULT)FALSE); /* We handled this button */
}
/* *\
* Test the user selection for being a Submenu. If one found chain into this submenu *
* and adjust the pointer pMenuData. *
\* */
case CDID_LEVELDOWN: /* Get down one level in the linked list */
{
MENUDATA *pMD; /* Pointer to a MENUDATA structure to find the
Submenu to chain into */
SHORT sCount;
pMD=pMenuData; /* Point to the first element of the linked list
at the current level */
/* Send message to listbox */
sCount=(SHORT)WinSendDlgItemMsg(
hwndDlg, /* Handle of dialog window */
CDLB_MENUPROGRAM, /* Submenu & Program listbox */
LM_QUERYSELECTION, /* Query first selected list box item */
MPFROMSHORT(LIT_FIRST),
(MPARAM)NULL);
/* If no item selected, ignore this button */
if(sCount==LIT_NONE)
return((MRESULT)FALSE);
for( ;sCount>0; sCount--) /* Walk through the linked list to the selected
item */
pMD=pMD->Next;
if(pMD->Item!=ENTRYSUBMENU) /* It's not a Submenu that's selected, ignore */
return((MRESULT)FALSE);
pMenuData=pMD->Submenu; /* Otherwise chain into this part-list */
/* Now redraw items in listbox */
WinSendMsg(hwndDlg, WM_LOADPOPUPMENU, MPFROMP(pMenuData), NULL);
return((MRESULT)FALSE); /* We handled this button */
}
/* *\
* The user selected to add a (Sub)Menu. Thus dismiss the PC/2 Configuration dialog and *
* load the (Sub)Menu Installation dialog. The new (Sub)Menu is entered in a *
* STARTSESSION structure named StartSession. Save the changes and reload the PC/2 *
* Configuration dialog again. *
\* */
case CDID_ADDMENU: /* Add a Menu to PC/2 Configuration selected */
/* *\
* The user selected to add a Program. Thus dismiss the PC/2 Configuration dialog and *
* load the Program Installation dialog. The new session data is entered in a *
* STARTSESSION structure named StartSession. Save the changes and reload the PC/2 *
* Configuration dialog again. *
\* */
case CDID_ADDPROGRAM: /* Add a Program to PC/2 Configuration selected */
{
UCHAR *pU; /* Temporary character pointer */
MENUDATA *pMD; /* Pointer to a MENUDATA structure to insert a
new MENUDATA stucture after */
MENUDATA *pMDNew; /* Temporary pointer for the new item to be inserted
after pMD */
SHORT sCount;
pMD=pMenuData; /* Point to the first element of the linked list
at the current level */
/* Send message to listbox */
sCount=(SHORT)WinSendDlgItemMsg(
hwndDlg, /* Handle of dialog window */
CDLB_MENUPROGRAM, /* Submenu & Program listbox */
LM_QUERYSELECTION, /* Query first selected list box item */
MPFROMSHORT(LIT_FIRST),
(MPARAM)NULL);
/* If no item selected, and there exists one,
add the new Menuitem after the last available
Menuitem by querying the number from the listbox.
Subtract 0 because we use 0-based instead 1-based. */
if((sCount==LIT_NONE) && (pMenuData->Item!=ENTRYEMPTY))
sCount=(SHORT)WinSendDlgItemMsg(hwndDlg, CDLB_MENUPROGRAM, LM_QUERYITEMCOUNT,
MPFROM2SHORT(NULL, NULL), (MPARAM)NULL)-1;
for( ;sCount>0; sCount--) /* Walk through the linked list to the selected
item */
pMD=pMD->Next;
/* Allocate a new item */
pMDNew=AllocateMenuData();
strcpy(pU=malloc(strlen("Insert here please")+1), "Insert here please");
free(pMDNew->PgmTitle);
pMDNew->PgmTitle=pU;
pMDNew->id=MenuDataId++; /* Increment ID */
/* Load SessionData with empty pMDNew structure */
LoadMenuData2SessionData(TRUE, pMDNew, &SessionData);
WinDismissDlg(hwndDlg, TRUE); /* Clear up Configuration dialog */
if(SHORT1FROMMP(mp1)==CDID_ADDMENU)
{
if(!WinDlgBox( /* Start Addmenu PC/2 dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
MI_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
MIID_MENUDIALOG, /* ID of Addmenu PC/2 dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
}
else
{
if(!WinDlgBox( /* Start Program Installation dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
PI_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
PIID_PROGRAMDIALOG, /* ID of Addprogram PC/2 dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
}
if(DialogResult==DID_OK) /* If manipulation is done successfully, then load
the SESSIONDATA structure back to the MENUDATA
structure and save the changes */
{
LoadSessionData2MenuData(pMDNew, &SessionData);
if(pMD->Item!=ENTRYEMPTY) /* Add new entry, if the current entry isn't empty */
{
if(SHORT1FROMMP(mp1)==CDID_ADDMENU)
{ /* It it is a Submenu, we also must add an empty
first item for it */
MENUDATA *pMDTemp;
pMDTemp=AllocateMenuData();
pMDNew->Submenu=pMDTemp;
pMDTemp->Back=pMDNew;
pMDNew->Item=ENTRYSUBMENU;
}
else pMDNew->Item=ENTRYMENUITEM;
if(pMD->Next!=NULL) (pMD->Next)->Back=pMDNew;
pMDNew->Next=pMD->Next;
pMDNew->Back=pMD;
pMD->Next=pMDNew;
/* Insert item after the existing item */
SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDNew), MPFROMLONG(pMD->id));
}
else /* If it is an empty entry fill it with user data */
{
UCHAR *pU; /* Temporary character pointer */
pMD->id=pMDNew->id;
if(SHORT1FROMMP(mp1)==CDID_ADDMENU)
{ /* It it is a Submenu, we also must add an empty
first item for it */
MENUDATA *pMDTemp;
pMDTemp=AllocateMenuData();
pMD->Submenu=pMDTemp;
pMDTemp->Back=pMD;
pMD->Item=ENTRYSUBMENU;
}
else pMD->Item=ENTRYMENUITEM;
strcpy(pU=malloc(strlen(pMDNew->PgmTitle)+1), pMDNew->PgmTitle);
free(pMD->PgmTitle);
pMD->PgmTitle=pU;
strcpy(pU=malloc(strlen(pMDNew->PgmName)+1), pMDNew->PgmName);
free(pMD->PgmName);
pMD->PgmName=pU;
strcpy(pU=malloc(strlen(pMDNew->PgmDirectory)+1), pMDNew->PgmDirectory);
free(pMD->PgmDirectory);
pMD->PgmDirectory=pU;
strcpy(pU=malloc(strlen(pMDNew->PgmInputs)+1), pMDNew->PgmInputs);
free(pMD->PgmInputs);
pMD->PgmInputs=pU;
pMD->SessionType=pMDNew->SessionType;
pMD->PgmControl=pMDNew->PgmControl;
pMD->FgBg=pMDNew->FgBg;
pMD->InitXPos=pMDNew->InitXPos;
pMD->InitYPos=pMDNew->InitYPos;
pMD->InitXSize=pMDNew->InitXSize;
pMD->InitYSize=pMDNew->InitYSize;
pMD->PriorityClass=pMDNew->PriorityClass;
pMD->PriorityDelta=pMDNew->PriorityDelta;
if(pMD->Back!=NULL) /* This is the first item of a Submenu, then
insert it there */
SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMD), MPFROMLONG((pMD->Back)->id));
else /* This is the complete first item of the linked
list, so insert at the end */
SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMD), MPFROMLONG(MIT_END));
free(pMDNew->PgmTitle); /* Free temporary used structure */
free(pMDNew->PgmName);
free(pMDNew->PgmDirectory);
free(pMDNew->PgmInputs);
free(pMDNew);
}
}
else
{
free(pMDNew->PgmTitle); /* Free temporary MENUDATA structure */
free(pMDNew->PgmName);
free(pMDNew->PgmDirectory);
free(pMDNew->PgmInputs);
free(pMDNew);
}
/* Initialize the listbox */
WinSendMsg(hwndDlg, WM_LOADPOPUPMENU, MPFROMP(pMenuData), NULL);
if(!WinDlgBox( /* Now reload the Configuration dialog */
HWND_DESKTOP,
HWND_DESKTOP,
CD_DialogProcedure,
0,
CDID_CONFIGDIALOG,
0)) GEN_ERR(hab, hwndFrame, hwndClient);
break; /* We never get here because of calling WinDlgBox() */
}
/* *\
* The user selected to change an item. Thus dismiss the PC/2 Configuration dialog and *
* load the Menu or Program Installation dialog. The new session data is entered in a *
* STARTSESSION structure named StartSession. *
* Then reload the PC/2 Configuration dialog again. *
\* */
case CDID_CHANGEENTRY: /* Change a Menu or Program configuration selected */
{
MENUDATA *pMD;
SHORT sCount;
pMD=pMenuData; /* Point to the first element of the linked list
at the current level */
/* Send message to listbox */
sCount=(SHORT)WinSendDlgItemMsg(
hwndDlg, /* Handle of dialog window */
CDLB_MENUPROGRAM, /* Submenu & Program listbox */
LM_QUERYSELECTION, /* Query first selected list box item */
MPFROMSHORT(LIT_FIRST),
(MPARAM)NULL);
if(sCount==LIT_NONE) /* If no item selected ignore this button */
return((MRESULT)FALSE);
for( ;sCount>0; sCount--) /* Walk through the linked list to the selected
item */
pMD=pMD->Next;
/* Now load the MENUDATA to SESSIONDATA structure
where the manipulations will take effect */
LoadMenuData2SessionData(FALSE, pMD, &SessionData);
WinDismissDlg(hwndDlg, TRUE); /* Clear up Configuration dialog */
if(pMD->Submenu==NULL) /* It's a Menuitem so call the Program Installation
dialog box */
{
if(!WinDlgBox( /* Start Program Installation dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
PI_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
PIID_PROGRAMDIALOG, /* ID of Program Installation PC/2 dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
}
else /* It's a Submenu so call the Menu Installation
dialog box */
{
if(!WinDlgBox( /* Start Addmenu PC/2 dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
MI_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
MIID_MENUDIALOG, /* ID of Addmenu PC/2 dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
}
if(DialogResult==DID_OK) /* If manipulation is done successfully, then load
the SESSIONDATA structure back to the MENUDATA
structure and save the changes */
{
LoadSessionData2MenuData(pMD, &SessionData);
/* Now change the menuitem text to the new one */
SetPopupMenu(MM_SETITEMTEXT, MPFROMP(pMD), MPFROMLONG(pMD->id));
/* Initialize the listbox */
WinSendMsg(hwndDlg, WM_LOADPOPUPMENU, MPFROMP(pMenuData), NULL);
}
if(!WinDlgBox( /* Now reload the Configuration dialog */
HWND_DESKTOP,
HWND_DESKTOP,
CD_DialogProcedure,
0,
CDID_CONFIGDIALOG,
0)) GEN_ERR(hab, hwndFrame, hwndClient);
break; /* We never get here because of calling WinDlgBox() */
}
/* *\
* The user selected to remove an item. If thist item is the only one in the linked *
* list or the first item of a submenu set it to empty otherwise free it's ressources *
* and remove the entry. *
\* */
case CDID_REMOVEENTRY: /* Remove a item of the PC/2 Configuration selected */
{
UCHAR *pU;
MENUDATA *pMD;
SHORT sCount;
pMD=pMenuData; /* Point to the first element of the linked list
at the current level */
/* Send message to listbox */
sCount=(SHORT)WinSendDlgItemMsg(
hwndDlg, /* Handle of dialog window */
CDLB_MENUPROGRAM, /* Submenu & Program listbox */
LM_QUERYSELECTION, /* Query first selected list box item */
MPFROMSHORT(LIT_FIRST),
(MPARAM)NULL);
if(sCount==LIT_NONE) /* If no item selected ignore this button */
return((MRESULT)FALSE);
for( ;sCount>0; sCount--) /* Walk through the linked list to the selected
item */
pMD=pMD->Next;
while(TRUE)
{
if((pMD->Back==NULL) && (pMD->Next!=NULL))
{ /* Remove the first item of the complete linked list */
if(pMD->Item==ENTRYSUBMENU)
if((pMD->Submenu)->Item==ENTRYEMPTY)
{ /* If it is an empty Submenu remove it completely */
/* Remove the Submenu and the empty first item
from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
free((pMD->Submenu)->PgmTitle);
free((pMD->Submenu)->PgmName);
free((pMD->Submenu)->PgmDirectory);
free((pMD->Submenu)->PgmInputs);
free(pMD->Submenu);
(pMD->Next)->Back=NULL;
/* Now next element is the first one */
pPopupMenu=pMD->Next;
pMenuData=pMD->Next;
free(pMD->PgmTitle);
free(pMD->PgmName);
free(pMD->PgmDirectory);
free(pMD->PgmInputs);
free(pMD);
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if(pMD->Item==ENTRYMENUITEM)
{ /* If it is an empty Menuitem remove it completly */
(pMD->Next)->Back=NULL;
/* Now next element is the first one */
pPopupMenu=pMD->Next;
pMenuData=pMD->Next;
/* Remove the item from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
free(pMD->PgmTitle);
free(pMD->PgmName);
free(pMD->PgmDirectory);
free(pMD->PgmInputs);
free(pMD);
break; /* Ensure we only test once, because each routine
changes the pointers */
}
}
if((pMD->Back==NULL) && (pMD->Next==NULL))
{ /* If it is the one and only item of the linked list
set it to empty */
if(pMD->Item==ENTRYSUBMENU)
if((pMD->Submenu)->Item==ENTRYEMPTY)
{ /* If it is an empty Submenu remove the empty
item completely */
/* Remove the item from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
free((pMD->Submenu)->PgmTitle);
free((pMD->Submenu)->PgmName);
free((pMD->Submenu)->PgmDirectory);
free((pMD->Submenu)->PgmInputs);
free(pMD->Submenu);
free(pMD->PgmTitle);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmTitle=pU;
free(pMD->PgmName);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmName=pU;
free(pMD->PgmDirectory);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmDirectory=pU;
free(pMD->PgmInputs);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmInputs=pU;
pMD->Item=ENTRYEMPTY;
pMD->Back=NULL;
pMD->Submenu=NULL;
pMD->Next=NULL;
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if(pMD->Item==ENTRYMENUITEM)
{ /* If it is a Menuitem set it to empty */
/* Remove the item from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmTitle=pU;
free(pMD->PgmName);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmName=pU;
free(pMD->PgmDirectory);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmDirectory=pU;
free(pMD->PgmInputs);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmInputs=pU;
pMD->Item=ENTRYEMPTY;
pMD->Back=NULL;
pMD->Submenu=NULL;
pMD->Next=NULL;
break; /* Ensure we only test once, because each routine
changes the pointers */
}
}
if(pMD->Back!=NULL)
{ /* It is any item of more than one item and not
the first one */
if(((pMD->Back)->Submenu==pMD) && (pMD->Submenu==NULL) && (pMD->Next==NULL))
{ /* If it is the first item of a Submenu not followed
by any item, set it to empty */
/* Remove the item from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmTitle=pU;
free(pMD->PgmName);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmName=pU;
free(pMD->PgmDirectory);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmDirectory=pU;
free(pMD->PgmInputs);
strcpy(pU=malloc(strlen("")+1), "");
pMD->Item=ENTRYEMPTY;
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if(pMD->Item==ENTRYSUBMENU)
if((pMD->Submenu)->Item==ENTRYEMPTY)
{ /* If it is an empty Submenu so also remove the
first item in the Submenu */
/* Remove the Submenu and the empty first item
from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
free((pMD->Submenu)->PgmTitle);
free((pMD->Submenu)->PgmName);
free((pMD->Submenu)->PgmDirectory);
free((pMD->Submenu)->PgmInputs);
free(pMD->Submenu);
if(((pMD->Back)->Submenu==pMD) && (pMD->Next==NULL))
{ /* If the previous item is a Submenu, this item is
the first item of it. If none item follows, set
this item to empty */
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmTitle=pU;
free(pMD->PgmName);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmName=pU;
free(pMD->PgmDirectory);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmDirectory=pU;
free(pMD->PgmInputs);
strcpy(pU=malloc(strlen("")+1), "");
pMD->Item=ENTRYEMPTY;
pMD->Submenu=NULL;
pMD->Next=NULL;
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if(((pMD->Back)->Submenu==pMD) && (pMD->Next!=NULL))
{ /* If the previous item is a Submenu, this item ist
the first item of it. If one item follows adjust
the pointer to the current level of items */
pMenuData=pMD->Next;
(pMD->Back)->Submenu=pMD->Next;
if(pMD->Next!=NULL) (pMD->Next)->Back=pMD->Back;
free(pMD->PgmTitle);
free(pMD->PgmName);
free(pMD->PgmDirectory);
free(pMD->PgmInputs);
free(pMD);
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if((pMD->Back)->Submenu!=pMD)
{ /* If this item isn't the first item of a Submenu */
(pMD->Back)->Next=pMD->Next;
if(pMD->Next!=NULL) (pMD->Next)->Back=pMD->Back;
free(pMD->PgmTitle);
free(pMD->PgmName);
free(pMD->PgmDirectory);
free(pMD->PgmInputs);
free(pMD);
break; /* Ensure we only test once, because each routine
changes the pointers */
}
}
if(pMD->Item==ENTRYMENUITEM)
{ /* If it is a Menuitem, just remove it completly */
/* Remove the item from the Popup-Menu */
SetPopupMenu(MM_DELETEITEM, MPFROMP(pMD), MPFROMLONG(pMD->id));
if(((pMD->Back)->Submenu==pMD) && (pMD->Next==NULL))
{ /* If the previous item is a Submenu, this item is
the first item of it. If none item follows, set
this item to empty */
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmTitle=pU;
free(pMD->PgmName);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmName=pU;
free(pMD->PgmDirectory);
strcpy(pU=malloc(strlen("")+1), "");
pMD->PgmDirectory=pU;
free(pMD->PgmInputs);
strcpy(pU=malloc(strlen("")+1), "");
pMD->Item=ENTRYEMPTY;
pMD->Submenu=NULL;
pMD->Next=NULL;
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if(((pMD->Back)->Submenu==pMD) && (pMD->Next!=NULL))
{ /* If the previous item is a Submenu, this item ist
the first item of it. If one item follows adjust
the pointer to the current level of items */
pMenuData=pMD->Next;
(pMD->Back)->Submenu=pMD->Next;
if(pMD->Next!=NULL) (pMD->Next)->Back=pMD->Back;
free(pMD->PgmTitle);
free(pMD->PgmName);
free(pMD->PgmDirectory);
free(pMD->PgmInputs);
free(pMD);
break; /* Ensure we only test once, because each routine
changes the pointers */
}
if((pMD->Back)->Submenu!=pMD)
{ /* If this item isn't the first item of a Submenu */
(pMD->Back)->Next=pMD->Next;
if(pMD->Next!=NULL) (pMD->Next)->Back=pMD->Back;
free(pMD->PgmTitle);
free(pMD->PgmName);
free(pMD->PgmDirectory);
free(pMD->PgmInputs);
free(pMD);
break; /* Ensure we only test once, because each routine
changes the pointers */
}
}
}
break; /* If we come here, we're trying to remove an not
empty Submenu, but we also must exit the
endless loop */
}
/* Initialize the listbox */
WinSendMsg(hwndDlg, WM_LOADPOPUPMENU, MPFROMP(pMenuData), NULL);
return((MRESULT)FALSE); /* We have done everything */
}
/* *\
* The user selected to resort the current level of the menuentries. Load the dialog *
* and let the user resort the linked list of menues pointed to by pMenuData and to *
* resort the menuentries of the Popup-Menu. *
\* */
case CDID_RESORT: /* Load the resort dialog */
{
WinDismissDlg(hwndDlg, TRUE); /* Clear up Configuration dialog */
if(!WinDlgBox( /* Start Resort dialog box */
HWND_DESKTOP, /* DESKTOP is parent */
HWND_DESKTOP, /* DESKTOP is owner */
RD_DialogProcedure, /* Dialog procedure of Program Installation
dialog */
0, /* Ressource is .EXE file */
RDID_RESORTDIALOG, /* ID of Program Installation PC/2 dialog */
0)) /* No initialization data */
GEN_ERR(hab, hwndFrame, hwndClient);
if(!WinDlgBox( /* Now reload the Configuration dialog */
HWND_DESKTOP,
HWND_DESKTOP,
CD_DialogProcedure,
0,
CDID_CONFIGDIALOG,
0)) GEN_ERR(hab, hwndFrame, hwndClient);
}
break;
case DID_OK: /* Enter key pressed */
/* Save the changes */
WinSendMsg(hwndDlg, WM_SAVEPOPUPMENU, NULL, NULL);
DialogResult=DID_OK; /* Dialog terminated with DID_OK */
break;
case DID_CANCEL: /* Escape or Cancel pressed */
DialogResult=DID_CANCEL; /* Dialog terminated with DID_CANCEL */
break;
default:
return(WinDefDlgProc(hwndDlg, msg, mp1, mp2));
}
WinDismissDlg(hwndDlg, TRUE); /* Clear up dialog */
break;
default: /* Default window procedure must be called */
return(WinDefDlgProc(hwndDlg, msg, mp1, mp2));
}
return((MRESULT)FALSE); /* We have handled the message */
}