home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
info
/
redbook4
/
dmphone.c
< prev
next >
Wrap
Text File
|
1992-06-28
|
9KB
|
292 lines
//**************************************************************************************** */
//
// DMPHONE.C - a demo program by Alan Chambers - UK PS Technical Support, on residency
// at the ITSC, Boca Raton
//
// Modified 6 May 1992 to work with GA code.
//
//
// This program is designed to be used with the DMCUST sample program. A customer
// can be dragged onto the telephone icon displayed by this program, with the result
// that a series of beeps, reminiscent of touchtone dialling tones, are sounded.
//
// The program illustrates the use of a private rendering mechanism, DRM_SHAREMEM, from
// the target's point of view.
//
//**************************************************************************************** */
//
// The program displays a telephone icon as using the WC_STATIC class, then subclasses
// this static window to add function for drag/drop, moving the icon around the desktop,
// and providing a context (pop-up) menu.
//
/**************************************************************************************** */
#define INCL_WIN
#define INCL_GPI
#define INCL_DOS
#include <os2.h> /* PM header file */
#include "dmphone.h" /* Resource symbolic identifiers*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <memory.h>
#define OBJECTDATASIZE 100
#define DRAGXFERMEMNAME "\\SHAREMEM\\Drgphone.mem"
typedef struct {
char name[30];
char address[100];
char phone[15];
int credit_limit;
}
CUSTOMER, *PCUSTOMER;
typedef struct{
RECORDCORE core;
CUSTOMER cust;
}
CONTRECORD, *PCONTRECORD;
MRESULT EXPENTRY PhoneSubclassProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
void mfbeep(ULONG, ULONG);
void phonedial(PCHAR phone);
HAB hab;
HPOINTER hptrPostIcon, hptrArrow;
PFNWP StaticWinProc;
HWND hwndPhone,
hwndMenu;
INT main (VOID)
{
HMQ hmq; /* Message queue handle */
QMSG qmsg; /* Message from message queue */
hab = WinInitialize(0);
hmq = WinCreateMsgQueue( hab, 0 );
hptrPostIcon = WinLoadPointer(HWND_DESKTOP, 0, ID_MYPOINTER);
hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
hwndPhone = WinCreateWindow(HWND_DESKTOP, WC_STATIC, "#9999",
WS_VISIBLE | SS_ICON,
10, 10, 64, 64,
HWND_DESKTOP, HWND_TOP, ID_PHONEICON,
0, 0);
StaticWinProc = WinSubclassWindow(hwndPhone, PhoneSubclassProc);
hwndMenu = WinLoadMenu(hwndPhone, (ULONG)NULL, RESID_MENU);
while(WinGetMsg(hab, &qmsg, 0L, 0, 0)) // message processing loop
WinDispatchMsg(hab, &qmsg);
WinDestroyMsgQueue( hmq );
WinTerminate( hab );
}
MRESULT EXPENTRY PhoneSubclassProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
SWP swp;
PDRAGTRANSFER pdxfer;
PCUSTOMER pxfercust;
PDRAGINFO pdinfo;
PDRAGITEM pditem;
ULONG rc;
static char IconText[20] = "Icon #";
char curDir[100];
char msgtext[100];
static BOOL button2down = FALSE;
static POINTS oldpos, newpos;
static BOOL moved = FALSE;
switch( msg )
{
case DM_DRAGOVER:
pdinfo = (PDRAGINFO)mp1;
DrgAccessDraginfo(pdinfo);
pditem = DrgQueryDragitemPtr(pdinfo, 0);
if(DrgVerifyRMF(pditem, "DRM_SHAREMEM", "DRF_TEXT"))
{
DrgFreeDraginfo(pdinfo);
return(MPFROM2SHORT(DOR_DROP, DO_COPY));
}
else
{
DrgFreeDraginfo(pdinfo);
return(MPFROM2SHORT(DOR_NEVERDROP, 0));
}
break;
case DM_DROP:
pdinfo = (PDRAGINFO)mp1;
DrgAccessDraginfo(pdinfo);
pditem = DrgQueryDragitemPtr(pdinfo, 0);
// allocated a named shared memory object for a customer *pxfercust
rc = DosAllocSharedMem((PPVOID)&pxfercust, DRAGXFERMEMNAME, sizeof(CUSTOMER), PAG_COMMIT | PAG_WRITE | PAG_READ);
// allocate and fill the dxfer structure;
pdxfer = DrgAllocDragtransfer(1);
pdxfer->cb = sizeof(DRAGTRANSFER);
pdxfer->hwndClient = hwnd;
pdxfer->pditem = pditem;
pdxfer->hstrSelectedRMF = DrgAddStrHandle("<DRM_CUSTOMER,DRF_TEXT>");
pdxfer->hstrRenderToName = DrgAddStrHandle(DRAGXFERMEMNAME);
pdxfer->ulTargetInfo = 0;
pdxfer->usOperation = DO_COPY;
rc = (ULONG)DrgSendTransferMsg(pdinfo->hwndSource, DM_RENDER, (MPARAM)pdxfer, NULL);
if(rc == TRUE)
{
phonedial(pxfercust->phone);
}
DrgFreeDraginfo(pdinfo);
DrgFreeDragtransfer(pdxfer);
DosFreeMem((PVOID)pxfercust);
break;
//*****************************************************************************
// The next three cases are to detect a user's request for the context menu
// If he presses button 2, then releases it without moving the mouse
// the context menu is displayed. Pressing button 2 and moving before releasing
// is the way the telephone can be moved about the screen.
//*****************************************************************************
case WM_BUTTON2DOWN:
button2down = TRUE;
moved = FALSE;
memcpy((PVOID)&oldpos, (PVOID)&mp1, sizeof(POINTS)); //save mouse pos.
break;
case WM_BUTTON2UP:
button2down = FALSE;
if(moved)
{
WinSetPointer(HWND_DESKTOP, hptrArrow);
WinSetCapture(HWND_DESKTOP, (HWND)NULL);
memcpy((PVOID)&newpos, (PVOID)&mp1, sizeof(POINTS)); //save mouse pos.
WinQueryWindowPos(hwndPhone, &swp);
WinSetWindowPos(hwndPhone, HWND_TOP, swp.x + (newpos.x - oldpos.x),
swp.y + (newpos.y - oldpos.y),
swp.cx, swp.cy, SWP_MOVE);
}
else
{
rc = WinPopupMenu(hwndPhone, hwndPhone, hwndMenu, 0, 0, 0,
PU_MOUSEBUTTON1 /*| PU_POSITIONONITEM | PU_HCONSTRAIN | PU_VCONSTRAIN*/ );
}
break;
case WM_MOUSEMOVE:
if(button2down)
{
if(!moved)
{
WinSetPointer(HWND_DESKTOP, hptrPostIcon);
WinSetCapture(HWND_DESKTOP, hwndPhone);
}
moved = TRUE;
}
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case ID_EXITPROG:
WinPostMsg(hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0);
break;
}
break;
case WM_CLOSE:
WinPostMsg(hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0);
break;
default:
return (MRESULT)StaticWinProc(hwnd, msg, mp1, mp2);
}
return (MRESULT)FALSE;
}
//****************************************************************************
//
// The following two functions implement the phone dialling functions.
// Unfortunately, OS/2 does not support the production of multiple concurrent
// tones on the PC speaker. Since a touchtone phone generates a pair of tones
// for each number, we can't reproduce this accurately. For this sample program
// therefore, all we do is rapidly alternate the two tones in each case. The
// frequencies used are correct.
//
//****************************************************************************
void phonedial(PCHAR phone)
{
char *p;
ULONG num;
int hi, lo;
for(p=phone; p != '\0' && (p-phone) < 8; p++)
{
if(*p >= '0' && *p <= '9')
{
num = (*p - '0');
if(num == 1 || num == 2 || num == 3)
lo = 697;
else if(num == 4 || num == 5 || num == 6)
lo = 770;
else if(num == 7 || num == 8 || num == 9)
lo = 852;
else
lo = 941; // zero
if(num == 1 || num == 4 || num == 7)
hi = 1209;
else if(num == 2 || num == 5 || num == 8)
hi = 1336;
else if(num == 3 || num == 6 || num == 9)
hi = 1477;
mfbeep(lo, hi);
}
}
}
#define FLIPTIME 10
void mfbeep(ULONG f1, ULONG f2)
{
int i;
for(i=1; i<30/FLIPTIME; i++)
{
DosBeep(f1, FLIPTIME);
DosBeep(f2, FLIPTIME);
}
DosSleep(50);
}