home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
03
/
megaphon
/
megaphon.c
< prev
next >
Wrap
Text File
|
1991-01-17
|
35KB
|
1,177 lines
/*****************************************************************************
PROGRAM: Megaphone
AUTHOR : Mike Klein
VERSION: 1.0
FILE : megaphon.exe
CREATED: 10-25-90
REQUIREMENTS: Windows 3.x and a Novell NetWare 2.1x or compatible network
PURPOSE : Messaging and simple information system for Novell NetWare.
Allows quick replies to messages from coworkers and
miscellaneous login information about them.
*****************************************************************************/
#define NOCOMM
#include <windows.h>
#include <direct.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <nwbindry.h>
#include <nwconn.h>
#include <nwdir.h>
#include <nwmsg.h>
#include <nwwrkenv.h>
#include "megaphon.h"
HANDLE hInstMegaphone; /* Original instance of Megaphone */
/* These are handles to commonly accessed controls in different dialogs */
HWND hWndCurrent; /* handle to currently active window on screen */
HWND hDlgMegaphone; /* handle to Megaphone dialog window */
HWND hWndUserListBox;
HWND hWndServerComboBox;
HWND hWndMessageEditBox;
HWND hWndSendButton;
/* Set up some additional global variables to commonly used NetWare stuff */
WORD DefaultConnectionID;
BYTE ServerName[48];
WORD UserConnectionNum;
BYTE UserName[48];
BYTE UserLoginTime[7];
WORD SelUserConnectionNum;
BYTE SelUserNetworkAddr[4];
BYTE SelUserNodeAddr[6];
BYTE SelUserName[48];
BYTE SelUserFullName[48];
BYTE SelUserLoginTime[7];
BOOL AcceptMessages = TRUE;
BOOL IconizeMessages = FALSE;
BOOL AllUsers = FALSE;
BYTE Text[100];
/*****************************************************************************
FUNCTION: WinMain
PURPOSE : Calls initialization function, processes message loop
*****************************************************************************/
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
MSG msg;
if(!hPrevInstance) /* Other instances of app running? */
{
hInstMegaphone = hInstance; /* Remember original instance */
/* Fill in window class structure with parameters that describe the */
/* main window. */
wc.style = CS_DBLCLKS; /* Process double click msgs */
wc.lpfnWndProc = MainWndProc; /* Function to retrieve msgs for */
/* windows of this class. */
wc.cbClsExtra = 0; /* No per-class extra data. */
wc.cbWndExtra = DLGWINDOWEXTRA; /* Set becuase we used the CLASS */
/* statement in dialog box */
wc.hInstance = hInstance; /* Application that owns the class.*/
wc.hIcon = LoadIcon(hInstance, "Megaphone");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "Megaphone";
wc.lpszClassName = "Megaphone";
if(!RegisterClass(&wc))
return(FALSE);
/* Fill in window class structure with parameters that describe the */
/* message window. */
wc.style = NULL; /* Process double click msgs */
wc.lpfnWndProc = MessageHandler;
wc.cbClsExtra = 0; /* No per-class extra data. */
wc.cbWndExtra = DLGWINDOWEXTRA; /* Set becuase we used the CLASS */
/* statement in dialog box */
wc.hInstance = hInstance; /* Application that owns the class.*/
wc.hIcon = LoadIcon(hInstance, "Message");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "Message";
if(!RegisterClass(&wc))
return(FALSE);
/* Fill in window class structure with parameters that describe the */
/* userinfo window. */
wc.style = NULL; /* Process double click msgs */
wc.lpfnWndProc = UserInfo;
wc.cbClsExtra = 0; /* No per-class extra data. */
wc.cbWndExtra = DLGWINDOWEXTRA; /* Set becuase we used the CLASS */
/* statement in dialog box */
wc.hInstance = hInstance; /* Application that owns the class.*/
wc.hIcon = LoadIcon(hInstance, "User");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "User";
if(!RegisterClass(&wc))
return(FALSE);
/* Create the main dialog window Megaphone, get window handles to */
/* several of the controls, send the message edit box a message to */
/* limit itself to MAX_MESSAGE_LEN characters, and set the system */
/* font (mono-spaced) for server combo box and user list box. */
hDlgMegaphone = CreateDialog(hInstance, "Megaphone", NULL, 0L);
hWndUserListBox = GetDlgItem(hDlgMegaphone, IDC_USERLISTBOX);
hWndServerComboBox = GetDlgItem(hDlgMegaphone, IDC_SERVERCOMBOBOX);
hWndMessageEditBox = GetDlgItem(hDlgMegaphone, IDC_MESSAGEEDITBOX);
hWndSendButton = GetDlgItem(hDlgMegaphone, IDC_SENDBUTTON);
SendMessage(hWndMessageEditBox, EM_LIMITTEXT, MAX_MESSAGE_LEN - 1, 0L);
SendMessage(hWndUserListBox, WM_SETFONT,
GetStockObject(SYSTEM_FIXED_FONT), FALSE);
SendMessage(hWndServerComboBox, WM_SETFONT,
GetStockObject(SYSTEM_FIXED_FONT), FALSE);
/* Finally, show the Megaphone dialog box */
ShowWindow(hDlgMegaphone, nCmdShow);
UpdateWindow(hDlgMegaphone);
/* Initialize the network stuff, and fill in list boxes */
InitNetStuff();
}
else
{
/* If there was another instance of Megaphone running, then switch to */
/* it by finding any window of class = "Megaphone". Then, if it's an */
/* icon, open the window, otherwise just make it active. */
hDlgMegaphone = FindWindow("Megaphone", NULL);
if(IsIconic(hDlgMegaphone))
ShowWindow(hDlgMegaphone, SW_SHOWNORMAL);
SetActiveWindow(hDlgMegaphone);
return(FALSE);
}
/* Acquire and dispatch messages until a WM_QUIT message is received. */
/* The window handle hWndCurrent points to the currently active window, */
/* and is used to identify and process keystrokes going to any modeless */
/* dialog box. */
while(GetMessage(&msg, NULL, NULL, NULL))
if(hWndCurrent == NULL || !IsDialogMessage(hWndCurrent, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/*****************************************************************************
FUNCTION: MainWndProc
PURPOSE : Processes messages for Megaphone dialog box
*****************************************************************************/
long FAR PASCAL MainWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
{
FARPROC lpProc; /* Far procedure ptr to be used for About box */
HWND hWndTemp;
HWND hDlgMessage;
BYTE *ptr;
int Index = 100;
BYTE MessageCaption[100];
BYTE MessageDate[9];
BYTE MessageTime[9];
switch(wMsg)
{
case WM_COMMAND :
switch(wParam)
{
/* When wParam == 1, return was pressed in either the list box, */
/* combo box, check boxes, or edit control. */
case 1 :
/* Find out the current control (window) and process ENTER */
/* key accordingly. */
switch(GetDlgCtrlID(GetFocus()))
{
case IDC_USERLISTBOX :
ShowUserInformation();
break;
case IDC_SERVERCOMBOBOX :
SendMessage(hWndServerComboBox, WM_KILLFOCUS, NULL, 0L);
SendMessage(hWndServerComboBox, WM_SETFOCUS, NULL, 0L);
break;
case IDC_MESSAGEEDITBOX :
if(IsWindowEnabled(hWndSendButton))
{
SendMessage(hWndSendButton, WM_LBUTTONDOWN, 0, 0L);
SendMessage(hWndSendButton, WM_LBUTTONUP, 0, 0L);
SendMessage(hDlgMegaphone, WM_NEXTDLGCTL,
hWndMessageEditBox, TRUE);
}
else
{
MessageBeep(0);
MessageBox(hDlgMegaphone, "You need a message and a user(s)",
"ERROR", MB_ICONEXCLAMATION | MB_OK);
}
break;
default :
break;
}
break;
case IDC_USERLISTBOX :
if(HIWORD(lParam) == LBN_DBLCLK)
{
/* Restore the list box item's selection state. If it */
/* isn't flagged, then flag it, and vice versa. */
Index = (int) SendMessage(hWndUserListBox, LB_GETCURSEL, 0, 0L);
if(SendMessage(hWndUserListBox, LB_GETSEL, Index, 0L))
SendMessage(hWndUserListBox, LB_SETSEL, FALSE, Index);
else
SendMessage(hWndUserListBox, LB_SETSEL, TRUE, Index);
ShowUserInformation();
}
else
EnableOrDisableSendButton();
break;
case IDC_SERVERCOMBOBOX :
if(HIWORD(lParam) == CBN_SELCHANGE)
{
if((Index = (int) SendMessage(hWndServerComboBox, CB_GETCURSEL,
0, 0L)) == CB_ERR)
break;
SendMessage(hWndServerComboBox, CB_GETLBTEXT, Index,
(LONG) (LPSTR) ServerName);
if(!GetConnectionID(ServerName, &DefaultConnectionID))
{
SetPreferredConnectionID(DefaultConnectionID);
InitNetStuff();
}
}
break;
case IDC_MESSAGEEDITBOX :
EnableOrDisableSendButton();
break;
case IDC_SENDBUTTON :
if(HIWORD(lParam) == BN_CLICKED)
SendNetWareMessageToUsers();
break;
case IDM_EXIT :
case IDC_EXITBUTTON :
SendMessage(hDlgMegaphone, WM_CLOSE, 0, 0L);
break;
case IDM_ABOUT :
lpProc = MakeProcInstance(About, hInstMegaphone);
DialogBox(hInstMegaphone, "About", hWnd, lpProc);
FreeProcInstance(lpProc);
break;
case IDM_REFRESH :
InitNetStuff();
break;
case IDC_SETTINGSBUTTON :
lpProc = MakeProcInstance(Settings, hInstMegaphone);
DialogBox(hInstMegaphone, "Settings", hWnd, lpProc);
FreeProcInstance(lpProc);
break;
default :
break;
}
break;
case WM_TIMER :
/* This is the Windows timer for retrieving messages that goes off */
/* every five seconds. */
GetBroadcastMessage(Text);
if(*Text)
{
/* Create the message reply dialog box and limit the edit box */
/* to NetWare's limit of 56 or so characters. */
hDlgMessage = CreateDialog(hInstMegaphone, "Message",
hDlgMegaphone, 0L);
SendDlgItemMessage(hDlgMessage, IDC_REPLYEDITBOX, EM_LIMITTEXT,
MAX_MESSAGE_LEN - 1, 0L);
/* Parse the incoming string of 'username[station#]message' */
if((ptr = strchr(Text, '[')) == NULL)
{
/* If the incoming message isn't formatted by NetWare's */
/* SEND command, SESSION program, or Megaphone, then we */
/* can't use the REPLY button, so disable it. */
SelUserName[0] = '\0';
SelUserConnectionNum = 0;
EnableWindow(GetDlgItem(hDlgMessage, IDC_REPLYBUTTON), FALSE);
}
else
{
/* Pull up the user name and connection#, and message, which */
/* is right after the ']'. */
strncpy(SelUserName, Text, ptr - Text);
SelUserName[ptr - Text] = '\0';
SelUserConnectionNum = atoi(ptr + 1);
if((ptr = strchr(Text, ']')) != NULL)
lstrcpy((LPSTR) Text, (LPSTR) (ptr + 1));
/* Check again to see if we pulled up a valid Conn#. If we */
/* didn't, then disable the REPLY button. */
if(SelUserConnectionNum < 1 || SelUserConnectionNum > 255)
EnableWindow(GetDlgItem(hDlgMessage, IDC_REPLYBUTTON), FALSE);
}
/* Put the retrieved message in the dialog's edit box */
SetDlgItemText(hDlgMessage, IDC_REPLYEDITBOX, Text);
/* Record the date and time that the message came in at and */
/* make it reflected in the message caption. */
_strdate(MessageDate);
_strtime(MessageTime);
wsprintf(MessageCaption, "%s %s %s", (LPSTR) SelUserName,
(LPSTR) MessageDate, (LPSTR) MessageTime);
SetWindowText(hDlgMessage, MessageCaption);
/* Finally, show (or minimize) the completed message dialog box */
if(IconizeMessages)
ShowWindow(hDlgMessage, SW_SHOWMINNOACTIVE);
else
ShowWindow(hDlgMessage, SW_SHOWNORMAL);
MessageBeep(0);
}
return(0L);
case WM_CLOSE :
/* Check before closing the main window if there are any */
/* outstanding messages that haven't been closed. */
if(hWndTemp = FindWindow((LPSTR) "Message", NULL))
{
if(MessageBox(hDlgMegaphone,
"Quit without disposing of/reading messages?",
"Messages Outstanding", MB_YESNO | MB_APPLMODAL |
MB_ICONEXCLAMATION | MB_DEFBUTTON2) == IDYES)
{
DestroyWindow(hDlgMegaphone);
}
else
{
ShowWindow(hWndTemp, SW_SHOWNORMAL);
SetActiveWindow(hWndTemp);
}
}
else
DestroyWindow(hDlgMegaphone);
return(0L);
case WM_SETFOCUS :
if(IsWindowEnabled(hWndMessageEditBox))
SendMessage(hDlgMegaphone, WM_NEXTDLGCTL, hWndMessageEditBox, TRUE);
else
SendMessage(hDlgMegaphone, WM_NEXTDLGCTL,
GetDlgItem(hDlgMegaphone, IDC_EXITBUTTON), TRUE);
return(0L);
case WM_ACTIVATE :
hWndCurrent = (wParam == NULL) ? NULL : hWnd;
break;
case WM_DESTROY :
PostQuitMessage(0);
return(0L);
default :
break;
}
return(DefDlgProc(hWnd, wMsg, wParam, lParam));
}
/*****************************************************************************
FUNCTION: SendNetWareMessageToUsers
PURPOSE : Do I really need to explain this one?
*****************************************************************************/
VOID PASCAL SendNetWareMessageToUsers(VOID)
{
BYTE Message[MAX_MESSAGE_LEN];
WORD ConnectionsToSend[MAX_CONNECTIONS];
BYTE ResultList[MAX_CONNECTIONS];
int NumUsers;
int i, j;
/* Get text inside message edit box and format message so it includes */
/* the username, connection#, and message. The first two fields are */
/* needed for replying back since there's nothing in NetWare's messaging */
/* facility to tell you who sent the message. */
GetDlgItemText(hDlgMegaphone, IDC_MESSAGEEDITBOX, (LPSTR) Text, MAX_MESSAGE_LEN);
wsprintf(Message, "%s[%d]%s", (LPSTR) UserName, UserConnectionNum,
(LPSTR) Text);
/* Get total number of users in list box and check to see if they've */
/* been selected or not. If they have, get their Connection# and put it */
/* in the ConnectionsToSend array. */
NumUsers = (int) SendMessage(hWndUserListBox, LB_GETCOUNT, 0, 0L);
for(i = j = 0; i < NumUsers; i++)
if(SendMessage(hWndUserListBox, LB_GETSEL, i, 0L))
{
SendMessage(hWndUserListBox, LB_GETTEXT, i, (LONG) (LPSTR) Text);
ConnectionsToSend[j++] = atoi(&Text[18]);
}
/* Send the message to users in the array. */
SendBroadcastMessage(Message, ConnectionsToSend, ResultList, j);
/* Scan through the ResultList array checking for messages that had */
/* problems. Selecting OK will continue to check the status of the other */
/* messages, where selecting CANCEL from the message box will abort the */
/* send status checking altogether. */
for(i = 0; i < j; i++)
switch(ResultList[i])
{
case 0xfc :
wsprintf(Text, "Message to Connection %d", ConnectionsToSend[i]);
if(MessageBox(hDlgMegaphone,
"Message not sent - User already has message pending",
Text, MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
{
i = j;
}
break;
case 0xfd :
wsprintf(Text, "Message to Connection %d", ConnectionsToSend[i]);
if(MessageBox(hDlgMegaphone,
"Message not sent - Invalid connection number",
Text, MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
{
i = j;
}
break;
case 0xff :
wsprintf(Text, "Message to Connection %d", ConnectionsToSend[i]);
if(MessageBox(hDlgMegaphone,
"Message not sent - User has blocking turned on",
Text, MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
{
i = j;
}
break;
default :
break;
}
}
/*****************************************************************************
FUNCTION: EnableOrDisableSendButton
PURPOSE : Based on a message being in the edit box and at least one
selected user, the send button is enabled or disabled
*****************************************************************************/
VOID PASCAL EnableOrDisableSendButton(VOID)
{
/* Check to see if at least one user is selected and at least a one */
/* character message in the edit box. If there is, then enable the SEND */
/* button and thicken it to make it the default response when ENTER is */
/* pressed. */
if(SendMessage(hWndUserListBox, LB_GETSELCOUNT, 0, 0L) &&
SendMessage(hWndMessageEditBox, EM_LINELENGTH, -1, 0L))
{
EnableWindow(hWndSendButton, TRUE);
}
else
{
EnableWindow(hWndSendButton, FALSE);
}
}
/*****************************************************************************
FUNCTION: InitNetStuff
PURPOSE : Initialize network connections and fill in combo and list boxes
*****************************************************************************/
BOOL PASCAL InitNetStuff(VOID)
{
HCURSOR hOldCursor;
WORD NumberOfConnections;
WORD NumberOfServers;
int Index;
BYTE DirHandle;
BYTE TempServerName[48];
WORD ObjectType;
WORD ConnID;
WORD ConnectionList[MAX_CONNECTIONS];
BYTE SearchObjectName[48] = "*";
BYTE ObjectName[48];
long ObjectID;
BYTE ObjectHasProperties;
BYTE ObjectFlag;
BYTE ObjectSecurity;
/* Check to see if a connection has been made to any server */
if(UserConnectionNum = GetConnectionNumber())
if(!GetConnectionInformation(UserConnectionNum, UserName, &ObjectType,
&ObjectID, UserLoginTime))
if(*UserName)
{
/* If we have a preferred connection ID, then were supposed to */
/* use it for all of our requests. If we don't, then check to */
/* see if we're sitting on a local drive (bit 0 or 1 not set). */
/* If we are, then set the default connection ID to that of the */
/* primary server. If we're sitting on a network drive, then */
/* requests go to the associated server. */
if(GetPreferredConnectionID())
DefaultConnectionID = GetPreferredConnectionID();
else
{
if(!(GetDriveInformation((BYTE) (_getdrive() - 1), &ConnID,
&DirHandle) & 3))
{
DefaultConnectionID = GetPrimaryConnectionID();
}
SetPreferredConnectionID(DefaultConnectionID);
}
/* Set NetWare's message mode so that Megaphone can poll for */
/* messages instead of automatically having them sent to the */
/* station. */
EnableBroadcasts();
SetBroadcastMode(3);
/* Set up a Windows timer so that every 5 seconds, the server is */
/* polled for waiting messages. */
SetTimer(hDlgMegaphone, IDT_MESSAGETIMER, 5000, NULL);
EnableWindow(GetDlgItem(hDlgMegaphone, IDC_SETTINGSBUTTON), TRUE);
}
if(!UserConnectionNum)
{
EnableWindow(GetDlgItem(hDlgMegaphone, IDC_SETTINGSBUTTON), FALSE);
MessageBox(hDlgMegaphone, "Must be logged into a NetWare server",
"ERROR - NO USERS", MB_ICONSTOP | MB_OK);
return(FALSE);
}
/* Now that we've established a network connection, let's fill in the */
/* drop-down combo box with file servers and the list box with users of */
/* whatever the node's preferred server is. */
/* Turn off re-drawing of the list box so it doesn't flicker, reset the */
/* contents of both boxes, capture and intercept all mouse activity, and */
/* turn the cursor into an hourglass. */
SendMessage(hWndUserListBox, WM_SETREDRAW, FALSE, 0L);
SendMessage(hWndUserListBox, LB_RESETCONTENT, 0, 0L);
SendMessage(hWndServerComboBox, CB_RESETCONTENT, 0, 0L);
SetCapture(hDlgMegaphone);
hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
/* Scan through the possible ConnectionID#'s (1-8) and see what file */
/* servers are attached, if any are, and put them in the combo box. */
for(ConnID = 1; ConnID < 9; ++ConnID)
{
GetFileServerName(ConnID, TempServerName);
if(*TempServerName)
SendMessage(hWndServerComboBox, CB_ADDSTRING, NULL,
(LONG) (LPSTR) TempServerName);
}
/* Get default server */
GetFileServerName(DefaultConnectionID, ServerName);
/* Search the NetWare bindery for active user connections, putting */
/* them into the list box */
ObjectID = -1;
while(!ScanBinderyObject(SearchObjectName, OT_USER, &ObjectID, ObjectName,
&ObjectType, &ObjectHasProperties, &ObjectFlag, &ObjectSecurity))
{
GetObjectConnectionNumbers(ObjectName, OT_USER, &NumberOfConnections,
ConnectionList, MAX_CONNECTIONS);
/* If there are multiple connections for a single user then we */
/* have to make sure and get all of them. */
if(!NumberOfConnections)
{
if(AllUsers)
{
wsprintf(Text, "[%s]", (LPSTR) ObjectName);
SendMessage(hWndUserListBox, LB_ADDSTRING, NULL, (LONG) (LPSTR) Text);
}
}
else
for(Index = 0; Index < (int) NumberOfConnections; ++Index)
{
if(UserConnectionNum == ConnectionList[Index])
wsprintf(Text, "%-16.16s *%3d", (LPSTR) ObjectName, ConnectionList[Index]);
else
wsprintf(Text, "%-17.17s %3d", (LPSTR) ObjectName, ConnectionList[Index]);
SendMessage(hWndUserListBox, LB_ADDSTRING, NULL, (LONG) (LPSTR) Text);
}
}
/* Turn re-drawing for the list box back on and make the first item in */
/* the server combo box and user list box the default. */
InvalidateRect(hWndUserListBox, NULL, TRUE);
SendMessage(hWndUserListBox, LB_SETSEL, 0, 0L);
SendMessage(hWndUserListBox, WM_SETREDRAW, TRUE, 0L);
/* Select the default server in the server combo box */
SendMessage(hWndServerComboBox, CB_SELECTSTRING, -1, (LONG) (LPSTR) ServerName);
/* Add the # of servers and users to the caption on the server and list */
/* boxes. */
NumberOfConnections = (int) SendMessage(hWndUserListBox, LB_GETCOUNT, 0, 0L);
wsprintf(Text, "%d &Users on %s", NumberOfConnections, (LPSTR) ServerName);
SetDlgItemText(hDlgMegaphone, IDC_USERLISTBOXTITLE, (LPSTR) Text);
NumberOfServers = (int) SendMessage(hWndServerComboBox, CB_GETCOUNT, 0, 0L);
wsprintf(Text, "%d Ser&vers", NumberOfServers);
SetDlgItemText(hDlgMegaphone, IDC_SERVERCOMBOBOXTITLE, (LPSTR) Text);
/* Restore mouse activity, set the cursor back to normal, and initially */
/* disable the Send button. */
ReleaseCapture();
SetCursor(hOldCursor);
EnableOrDisableSendButton();
return(TRUE);
}
/*****************************************************************************
FUNCTION: About
PURPOSE : Processes messages for About box
*****************************************************************************/
BOOL FAR PASCAL About(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
{
switch(wMsg)
{
case WM_INITDIALOG :
return(TRUE);
case WM_COMMAND :
if(wParam == IDOK || wParam == IDCANCEL)
{
EndDialog(hWnd, TRUE);
return(TRUE);
}
break;
default :
break;
}
return(FALSE);
}
/*****************************************************************************
FUNCTION: Settings
PURPOSE : Processes messages for Settings window
*****************************************************************************/
BOOL FAR PASCAL Settings(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
{
switch(wMsg)
{
case WM_INITDIALOG :
CheckDlgButton(hWnd, IDC_ACCEPTMESSAGES, AcceptMessages);
CheckDlgButton(hWnd, IDC_ICONIZEMESSAGES, IconizeMessages);
if(AllUsers)
CheckRadioButton(hWnd, IDC_ALLUSERSINBINDERY,
IDC_ALLUSERSINBINDERY, IDC_ALLUSERSINBINDERY);
else
CheckRadioButton(hWnd, IDC_ONLYATTACHEDUSERS,
IDC_ONLYATTACHEDUSERS, IDC_ONLYATTACHEDUSERS);
break;
case WM_COMMAND :
switch(wParam)
{
case IDC_ACCEPTMESSAGES :
if(IsDlgButtonChecked(hWnd, IDC_ACCEPTMESSAGES))
{
EnableBroadcasts();
SetTimer(hDlgMegaphone, IDT_MESSAGETIMER, 5000, NULL);
AcceptMessages = TRUE;
}
else
{
DisableBroadcasts();
KillTimer(hDlgMegaphone, IDT_MESSAGETIMER);
AcceptMessages = FALSE;
}
break;
case IDC_ICONIZEMESSAGES :
if(IsDlgButtonChecked(hWnd, IDC_ICONIZEMESSAGES))
IconizeMessages = TRUE;
else
IconizeMessages = FALSE;
break;
case IDC_ONLYATTACHEDUSERS :
AllUsers = FALSE;
InitNetStuff();
break;
case IDC_ALLUSERSINBINDERY :
AllUsers = TRUE;
InitNetStuff();
break;
case IDOK :
case IDCANCEL :
EndDialog(hWnd, TRUE);
return(TRUE);
default :
break;
}
}
return(FALSE);
}
/*****************************************************************************
FUNCTION: MessageHandler
PURPOSE : Processes messages for user message dialog box/window
*****************************************************************************/
long FAR PASCAL MessageHandler(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
{
BYTE Message[MAX_MESSAGE_LEN];
WORD ConnectionsToSend[1];
BYTE ResultList[1];
switch(wMsg)
{
case WM_COMMAND :
switch(wParam)
{
case 1 :
/* A '1' is generated when ENTER is pressed while in a */
/* control in a dialog box and there's no default button */
/* defined. This is to trap the ENTER key when in the reply */
/* edit box. We'll simulate the pressing of the REPLY button */
if(IsWindowEnabled(GetDlgItem(hWnd, IDC_REPLYBUTTON)))
{
SendMessage(GetDlgItem(hWnd, IDC_REPLYBUTTON),
WM_LBUTTONDOWN, 0, 0L);
SendMessage(GetDlgItem(hWnd, IDC_REPLYBUTTON),
WM_LBUTTONUP, 0, 0L);
}
else
{
MessageBeep(0);
MessageBox(hWnd, "You cannot reply to this message",
"ERROR", MB_ICONEXCLAMATION | MB_OK);
}
break;
case IDC_SAVEBUTTON :
/* "Save" the message by iconizing it */
CloseWindow(hWnd);
break;
case IDC_REPLYBUTTON :
/* Get text from edit box located in message dialog box */
GetDlgItemText(hWnd, IDC_REPLYEDITBOX, (LPSTR) Text,
MAX_MESSAGE_LEN);
/* Set up my connection# to send to, format the message, and */
/* send it to the user. */
ConnectionsToSend[0] = SelUserConnectionNum;
wsprintf(Message, "%s[%d]%s", (LPSTR) SelUserName,
SelUserConnectionNum, (LPSTR) Text);
SendBroadcastMessage(Message, ConnectionsToSend, ResultList, 1);
/* Possible results of sending a message */
switch(ResultList[0])
{
case 0xfc :
wsprintf(Text, "Message to Connection %d",
ConnectionsToSend[0]);
MessageBox(hDlgMegaphone,
"Message not sent - User already has message pending",
Text, MB_OK | MB_ICONEXCLAMATION);
break;
case 0xfd :
wsprintf(Text, "Message to Connection %d",
ConnectionsToSend[0]);
MessageBox(hDlgMegaphone,
"Message not sent - Invalid connection number",
Text, MB_OK | MB_ICONEXCLAMATION);
break;
case 0xff :
wsprintf(Text, "Message to Connection %d",
ConnectionsToSend[0]);
MessageBox(hDlgMegaphone,
"Message not sent - User has blocking turned on",
Text, MB_OK | MB_ICONEXCLAMATION);
break;
default :
break;
}
/* Get rid of the message reply dialog box/window */
DestroyWindow(hWnd);
return(0L);
case IDCANCEL :
DestroyWindow(hWnd);
return(0L);
default :
break;
}
break;
case WM_CLOSE :
DestroyWindow(hWnd);
return(0L);
case WM_SETFOCUS :
/* Set the focus to the edit control. */
SendMessage(hWnd, WM_NEXTDLGCTL, GetDlgItem(hWnd, IDC_REPLYEDITBOX),
TRUE);
return(0L);
case WM_ACTIVATE :
hWndCurrent = (wParam == NULL) ? NULL : hWnd;
break;
default :
break;
}
return(DefDlgProc(hWnd, wMsg, wParam, lParam));
}
/*****************************************************************************
FUNCTION: ShowUserInformation
PURPOSE : Shows user information on current or double-clicked entry
*****************************************************************************/
VOID PASCAL ShowUserInformation(VOID)
{
int Index;
BYTE *ptr;
HWND hDlgUserInfo;
WORD ObjectType;
long ObjectID;
WORD SocketNum;
BYTE PropertyValue[128];
BYTE MoreSegments;
BYTE PropertyFlags;
/* Get an index to the user name underneath the cursor, */
/* and then get the user's connection number so we can */
/* retrieve NetWare information on him/her. */
Index = (int) SendMessage(hWndUserListBox, LB_GETCURSEL, 0, 0L);
SendMessage(hWndUserListBox, LB_GETTEXT, Index, (LONG) (LPSTR) Text);
/* If entry in list box doesn't have a connection #, then we need to get */
/* the login name by parsing the list box string, we can't use a call to */
/* GetConnectionInformation(). */
memset(SelUserLoginTime, '\0', 7);
memset(SelUserNetworkAddr, '\0', 4);
memset(SelUserNodeAddr, '\0', 6);
SelUserFullName[0] = '\0';
SelUserConnectionNum = 0;
if(Text[0] == '[')
{
ptr = strchr(Text, ']');
strncpy(SelUserName, Text + 1, ptr - Text - 1);
SelUserName[ptr - Text - 1] = '\0';
}
else
{
ptr = strchr(Text, ' ');
strncpy(SelUserName, Text, ptr - Text);
SelUserConnectionNum = atoi(&Text[18]);
SelUserName[ptr - Text] = '\0';
/* We can get connection info only for users that are logged in to a */
/* server. So, get the user name and login time, network and node */
/* address, and full name for specified connection#. */
GetConnectionInformation(SelUserConnectionNum, SelUserName, &ObjectType,
&ObjectID, SelUserLoginTime);
GetInternetAddress(SelUserConnectionNum, SelUserNetworkAddr,
SelUserNodeAddr, &SocketNum);
}
if(!ReadPropertyValue(SelUserName, OT_USER, "IDENTIFICATION", 1,
PropertyValue, &MoreSegments, &PropertyFlags))
{
wsprintf(SelUserFullName, "%s", (LPSTR) PropertyValue);
}
/* Create userinfo dialog box and change caption to the */
/* user's login name. */
hDlgUserInfo = CreateDialog(hInstMegaphone, "UserInfo", hDlgMegaphone, 0L);
SetWindowText(hDlgUserInfo, SelUserName);
/* Initialize the user info dialog box by changing */
/* the values of different static text fields to */
/* reflect acquired user information */
wsprintf(Text, ": %s", (LPSTR) SelUserName);
SetDlgItemText(hDlgUserInfo, IDC_USERNAME, (LPSTR) Text);
wsprintf(Text, ": %d", SelUserConnectionNum);
SetDlgItemText(hDlgUserInfo, IDC_STATION, (LPSTR) Text);
wsprintf(Text, ": %s", (LPSTR) SelUserFullName);
SetDlgItemText(hDlgUserInfo, IDC_FULLNAME, (LPSTR) Text);
wsprintf(Text, ": %02d/%02d/%02d %02d:%02d:%02d",
SelUserLoginTime[1], SelUserLoginTime[2], SelUserLoginTime[0],
SelUserLoginTime[3], SelUserLoginTime[4], SelUserLoginTime[5]);
SetDlgItemText(hDlgUserInfo, IDC_LOGINTIME, (LPSTR) Text);
wsprintf(Text, ": %02X%02X%02X%02X",
SelUserNetworkAddr[0], SelUserNetworkAddr[1],
SelUserNetworkAddr[2], SelUserNetworkAddr[3]);
SetDlgItemText(hDlgUserInfo, IDC_NETWORK, (LPSTR) Text);
wsprintf(Text, ": %02X%02X%02X%02X%02X%02X",
SelUserNodeAddr[0], SelUserNodeAddr[1], SelUserNodeAddr[2],
SelUserNodeAddr[3], SelUserNodeAddr[4], SelUserNodeAddr[5]);
SetDlgItemText(hDlgUserInfo, IDC_NODE, (LPSTR) Text);
ShowWindow(hDlgUserInfo, SW_SHOWNORMAL);
}
/*****************************************************************************
FUNCTION: UserInfo
PURPOSE : Processes messages for user info box
*****************************************************************************/
long FAR PASCAL UserInfo(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
{
switch(wMsg)
{
case WM_COMMAND :
if(wParam == IDOK || wParam == IDCANCEL)
{
DestroyWindow(hWnd);
return(0L);
}
break;
case WM_CLOSE :
DestroyWindow(hWnd);
return(0L);
case WM_ACTIVATE :
hWndCurrent = (wParam == NULL) ? NULL : hWnd;
break;
default :
break;
}
return(DefDlgProc(hWnd, wMsg, wParam, lParam));
}