home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
pencod.zip
/
MMINK.C
< prev
next >
Wrap
Text File
|
1993-11-05
|
30KB
|
717 lines
/******************************************************************************
* *
* Name: MMINK.C *
* *
* Copyright : COPYRIGHT IBM CORPORATION, 1993 *
* LICENSED MATERIAL - PROGRAM PROPERTY OF IBM *
* *
* Description: This program loads a predefined bitmap in client window and *
* allows user to record the audio synchronized with stroke *
* data. Also allows to play it back. *
* *
* Execution Instruction: MMINK *
* *
* Hardware Requirement: Audio I/O device. *
* *
* Software Requirement: IBM OS/2 V2.1, Pen for OS/2 V1.0, and MMPM/2 V1.1 *
* *
* Subroutine Names and their function: *
* *
* main : main drive routine *
* *
* ClientWinProc : Client window procedure which has a bitmap in client *
* area and handles the annotation menu item. *
* *
* AudioDlgProc: Audio dialog procedure which handles the recording and *
* playing back of the recorded voice and strokes. *
* *
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is *
* sample code created by IBM Corporation. This sample code is not *
* part of any standard or IBM product and is provided to you solely *
* for the purpose of assisting you in the development of your *
* applications. The code is provided "AS IS", without *
* warranty of any kind. IBM shall not be liable for any damages *
* arising out of your use of the sample code, even if they have been *
* advised of the possibility of such damages. *
* *
******************************************************************************/
#define INCL_WIN
#define INCL_ERRORS
#define INCL_GPI
#define INCL_DOS
#define INCL_CIRCULARSLIDER
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <os2me.h>
#include <penpm.h>
#include <sw.h>
#include "mmink.h"
/*****************************************************************************
* *
* Subroutine Name : main *
* *
* Function: Main procedure to create the client window, process the window *
* messages, and exits the program. *
* *
* Parameters: None. *
* *
*****************************************************************************/
VOID main(VOID)
{
ULONG flFrameFlags = FCF_SIZEBORDER | FCF_MINMAX | FCF_TITLEBAR |
FCF_ICON | FCF_MENU | FCF_TASKLIST;
QMSG qmsg;
HMQ hmq;
USHORT i;
CHAR achClass[] = "MMINK";
hab = WinInitialize(0UL);
hmq = WinCreateMsgQueue(hab, 0);
WinRegisterClass(hab,
achClass,
ClientWinProc,
CS_SYNCPAINT,
0);
hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
WS_VISIBLE,
&flFrameFlags,
achClass,
NULL,
0UL,
0UL,
MMINK,
&hwndClient);
WinSetWindowPos(hwndFrame,
HWND_TOP,
(WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - CLIENTCX) / 2,
(WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - CLIENTCY) / 2,
CLIENTCX,
CLIENTCY,
SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
/************************************************************************
* When the modeless Audio dialog window ends, it makes the WinGetMsg *
* false. So, add a flag which is TRUE when user clicks Exit menu item. *
************************************************************************/
while (!fFinish)
{
while (WinGetMsg(hab, &qmsg, 0UL, 0UL, 0UL))
WinDispatchMsg( hab, &qmsg );
}
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue( hmq );
WinTerminate( hab );
DosExit(1, 0);
}
/*****************************************************************************
* *
* Subroutine Name : ClientWinProc *
* *
* Function: Window procedure of the main client window. *
* Process all messages and menu items in this window. *
* *
* Parameters: HWND hwnd *
* ULONG msg *
* MAPRAM mp1 *
* MPARAM mp2 *
* *
* Pen message processed: WM_RECO *
* *
*****************************************************************************/
MRESULT EXPENTRY ClientWinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
CHAR err[80];
static HDC hdc;
static HPS hpsMem;
HPS hps;
static HBITMAP hbm;
static BITMAPINFOHEADER2 bmhData;
static SIZEL sizel;
POINTL aptl[4];
RECTL rcl;
static LONG lCx, lCy;
switch (msg)
{
case WM_CREATE:
/*******************************************************************
* . Get the menu handle to enable/disable the ANNOTATE menu item *
* . Get the memory device context, create the presentation space, *
* and load predefined bitmap. *
* . Get the bitmap information. *
*******************************************************************/
hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
FID_MENU);
hdc = DevOpenDC(hab,
OD_MEMORY,
"*", /* No device info */
0L,
(PDEVOPENDATA) NULL,
NULLHANDLE);
sizel.cx = sizel.cy = 0;
hpsMem = GpiCreatePS(hab,
hdc,
&sizel,
PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
hbm = GpiLoadBitmap(hpsMem,
NULLHANDLE,
IDB_MMINK,
0L, /* NO stretch in X and Y direction */
0L);
GpiSetBitmap(hpsMem, hbm);
/* Get the bitmap information */
bmhData.cbFix = sizeof(bmhData);
GpiQueryBitmapInfoHeader(hbm, &bmhData);
sizel.cx = bmhData.cx;
sizel.cy = bmhData.cy;
return FALSE;
case WM_SIZE:
if ( hwndAudio )
{
WinSendMsg ( hwndAudio, WM_COMMAND, (MPARAM) AUDIOCTL_STOP, (MPARAM) 0 );
};
lCx = SHORT1FROMMP(mp2);
lCy = SHORT2FROMMP(mp2);
if ( hwndInk )
{
WinQueryWindowRect ( hwnd, &rcl );
WinSetWindowPos ( hwndInk,
HWND_TOP,
0,
0,
rcl.xRight,
rcl.yTop,
SWP_MOVE | SWP_SIZE );
}
else
WinInvalidateRect ( hwnd, NULL, TRUE );
return FALSE;
case WM_PAINT:
{
RECTL rctl;
hps = WinBeginPaint(hwnd, (ULONG) NULL, (PRECTL) &rctl);
/* Target coordinate */
aptl[0].x = rctl.xLeft;
aptl[0].y = rctl.yBottom;
aptl[1].x = rctl.xRight;
aptl[1].y = rctl.yTop;
/* Source Coordinate */
aptl[2].x = rctl.xLeft * sizel.cx / lCx;
aptl[2].y = rctl.yBottom * sizel.cy / lCy;
aptl[3].x = rctl.xRight * sizel.cx / lCx;
aptl[3].y = rctl.yTop * sizel.cy / lCy;
GpiBitBlt(hps,
hpsMem,
4L,
aptl,
ROP_SRCCOPY,
BBO_IGNORE);
WinEndPaint(hps);
return FALSE;
}
case WM_RECO:
{
RECODATA rcData;
/******************************************************************
* Process the uppercase 'A' gesture as if the Annotate menu item *
* is selected. *
******************************************************************/
rcData = * (RECODATA *) PVOIDFROMMP(mp2);
if ((rcData.virtual_id == VIRTUAL_ID) && (rcData.char_code == UPPERA))
{
WinPostMsg(hwnd, WM_COMMAND, MPFROMSHORT(IDM_ANNOT), NULL);
return((MRESULT) RECO_PROCESSED);
}
return(FALSE);
}
case WM_COMMAND:
switch(SHORT1FROMMP(mp1))
{
case IDM_ANNOT:
/*************************************************************
* Disable this menu item, it will be enabled later when the *
* dialog box is closed. *
*************************************************************/
WinSendMsg(hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_ANNOT, TRUE),
MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
hwndInk = InitTimedInk(hwnd, &CurrMMTime);
if ( !hwndInk )
{
SetText(hwnd, err, "Failed to initialize timed Ink.",
"Errors", 0,
(ULONG) MB_ERROR | MB_OK, TRUE);
WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
}
else
hwndAudio = WinLoadDlg(HWND_DESKTOP,
hwnd,
AudioDlgProc,
0UL,
IDD_AUDIO,
0UL);
return FALSE;
case IDM_EXIT:
fFinish = TRUE;
WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
return FALSE;
}
return FALSE;
case WM_CLOSE:
GpiDestroyPS(hpsMem);
DevCloseDC(hdc);
GpiDeleteBitmap(hbm);
break;
default:
break;
} /* end of switch */
return(WinDefWindowProc(hwnd, msg, mp1, mp2));
}
/*****************************************************************************
* *
* Subroutine Name : SetText *
* *
* Function: Error message is given in a message box if fMessage is TRUE. *
* This function put a text and number in ASCII in an array *
* so that the sprintf C function is not used. *
* *
* Parameters: HWND hwnd *
* PSZ pszArray:arrary which will have the error message *
* PSZ pszStr: error message *
* PSZ pszTitle: title of the message box *
* ULONG ulRc: error code *
* ULONG ulFlags: flags for the message box *
* BOOL fMessage: give message box or not *
* *
* All parameters are input. *
* *
*****************************************************************************/
VOID SetText(HWND hwnd, PSZ pszArray, PSZ pszStr, PSZ pszTitle, ULONG ulRc,
ULONG ulFlags, BOOL fMessage)
{
PSZ pszTemp;
strcpy(pszArray, pszStr);
pszTemp = pszArray + strlen(pszArray);
_itoa(ulRc, pszTemp, 10);
*(pszTemp + 3) = '\0';
if (fMessage)
{
WinMessageBox(HWND_DESKTOP,
hwnd,
pszArray,
pszTitle,
0,
ulFlags);
}
}
/*****************************************************************************
* *
* Subroutine Name : AudioDlgProc *
* *
* Function: Window procedure of the audio dialog window. *
* Process all messages and button messages in this window. *
* *
* Parameters: HWND hwnd *
* ULONG msg *
* MAPRAM mp1 *
* MPARAM mp2 *
* *
*****************************************************************************/
MRESULT EXPENTRY AudioDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
static SHORT sAudioLevel = 100;
static USHORT usTotTime = 0;
static SBCDATA sbc = { 14, 0, 0, 100, 50, 1, 100 };
static BTNCDATA bBut;
SHORT rc;
CHAR err[80];
HPS hps;
static SHORT currentMode = IDLE_MODE;
ULONG ulReturn, i;
static USHORT usPos = 0;
USHORT usNotifyCode; /* notification message code */
SHORT sWmControlID; /* WM_CONTROL id */
USHORT usTime; /* Duration and Elapsed Time in second */
switch (msg)
{
case WM_COMMAND:
{
switch (SHORT1FROMMP(mp1))
{
case AUDIOCTL_PLAY:
/******************************************************************
* User clicks the PLAY button after recording. *
* If any old stroke in window, erase it. *
* Acquire the audio device. *
* Play the recorded audio data. *
* For stroke data, convert sensor resolution to screen resolution*
* Enable STOP buttons and disable the other buttons. *
******************************************************************/
{
PSTROKEDATA pStroke;
if (ulReturn = mmsrvAcquire())
{
SetText(hwnd, err, "Error during Acquire, rc = ",
"MMPM/2 Error", ulReturn,
(ULONG) MB_ERROR | MB_OK, TRUE);
return FALSE;
}
if (ulReturn = mmsrvPlay(hwnd))
{
SetText(hwnd, err, "Error during Playback, rc = ",
"Audio Error", ulReturn,
(ULONG) MB_ERROR | MB_OK, TRUE);
return FALSE;
}
usPos = 0;
currentMode = PLAYING_MODE;
PlayTimedInk ( hwndInk );
WinSetDlgItemText(hwnd,
AUDIOCTL_INFO,
"Playing voice & handwriting.");
/***********************************************************
* Disable the PLAY and RECORD buttons but enable STOP but *
***********************************************************/
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), FALSE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), TRUE);
break;
} /* of case AUDIOCTL_PLAY */
case AUDIOCTL_REC:
/******************************************************************
* User clicks the RECORD button. *
* If any old stroke in window, erase it. *
* Acquire the audio device. *
* Record the audio data. *
* Enable STOP buttons and disable the other buttons. *
******************************************************************/
{
if (ulReturn = mmsrvAcquire())
{
SetText(hwnd, err, "Error during Acquire, rc = ",
"MMPM/2 Error", ulReturn,
(ULONG) MB_ERROR | MB_OK, TRUE);
return FALSE;
}
if (ulReturn = mmsrvRecord(hwnd))
{
SetText(hwnd, err, "Error during Recording, rc = ",
"Audio Error", ulReturn,
(ULONG) MB_ERROR | MB_OK, TRUE);
return FALSE;
}
usPos = 0;
currentMode = RECORDING_MODE;
WinSetDlgItemText(hwnd,
AUDIOCTL_INFO,
"Recording voice & handwriting.");
RecordTimedInk(hwndInk);
/************************************************************
* Enable the STOP button, but disables the PLAY and RECORD *
* buttons. *
************************************************************/
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), TRUE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), FALSE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
break;
} /* of case AUDIOCTL_REC */
case AUDIOCTL_STOP:
/******************************************************************
* User clicks the STOP button while recording or playing. *
* Depending upon the mode (playing or recording), set correct *
* text in INFO field of dialog box. *
* Stop recording/playing auiod data. *
******************************************************************/
{
StopTimedInk(hwndInk);
switch (currentMode)
{
case RECORDING_MODE:
{
WinSetDlgItemText(hwnd,
AUDIOCTL_INFO,
"Stopping voice/pen recording.");
break;
} /* of case RECORDING_MODE */
case PLAYING_MODE:
{
WinSetDlgItemText(hwnd,
AUDIOCTL_INFO,
"Stopping voice/pen playback.");
break;
} /* of case PLAYING_MODE */
} /* of switch(currentMode) */
(void) mmsrvStop();
currentMode = IDLE_MODE;
break;
} /* of case AUDIOCTL_STOP */
} /* of switch(SHORT1FROMMP(mp1)) */
return FALSE;
} /* of case WM_COMMAND */
case MM_MCINOTIFY:
/*********************************************************************
* This message is sent from MMPM/2 system when the MMPM/2 device *
* successfully completes the action indicated by media message or *
* when an error occurs. * *
*********************************************************************/
{
USHORT usNotifyCode;
USHORT usReceivedMessage;
StopTimedInk ( hwndInk );
usNotifyCode = SHORT1FROMMP(mp1);
usReceivedMessage = SHORT2FROMMP(mp2);
WinSetDlgItemText(hwnd,
AUDIOCTL_ELAP,
"Elapsed: 0");
WinSetDlgItemText(hwnd,
AUDIOCTL_INFO,
"");
if (usNotifyCode == MCI_NOTIFY_SUCCESSFUL
|| usNotifyCode == MCI_NOTIFY_SUPERSEDED
|| usNotifyCode == MCI_NOTIFY_ABORTED)
{
if (ulReturn = mmsrvRelease())
{
SetText(hwnd, err, "Error during Release, rc = ",
"MMPM/2 Error", ulReturn,
(ULONG) MB_ERROR | MB_OK, TRUE);
return FALSE;
};
if (usReceivedMessage == MCI_RECORD)
{
if (usPos == 0)
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY),
FALSE);
else
{
usTime = usPos / 10;
SetText(hwnd, err, "Duration: ",
NULL, usTime,
(ULONG) NULL, FALSE);
WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
};
};
}
else
{
SetText(hwnd, err, "Play/Record could not succeed",
"Audio Error", 0,
(ULONG) MB_ERROR | MB_OK, TRUE);
}; /* of else */
for (i = AUDIOCTL_PLAY; i < AUDIOCTL_STOP; i++)
WinEnableWindow(WinWindowFromID(hwnd, i),
TRUE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP),
FALSE);
return FALSE;
} /* of case MM_MCINOTIFY */
/**********************************************************************
* This message is sent from multi media device for every one tenth *
* second while audio data is played or recorded. This one tenth of *
* time interval was done in mmsrvOpen(). *
**********************************************************************/
case MM_MCIPOSITIONCHANGE:
{
usPos++;
usTime = usPos / 10;
switch (currentMode)
{
case RECORDING_MODE:
{
SetText(hwnd, err, "Duration: ",
NULL, usTime,
(ULONG) NULL, FALSE);
WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
SetText(hwnd, err, "Elapsed: ",
NULL, usTime,
(ULONG) NULL, FALSE);
WinSetDlgItemText(hwnd, AUDIOCTL_ELAP, err);
CurrMMTime = (MMTIME) mp2;
break;
}
case PLAYING_MODE:
{
SetText(hwnd, err, "Duration: ",
NULL, usTime,
(ULONG) NULL, FALSE);
WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
SetText(hwnd, err, "Elapsed: ",
NULL, usTime,
(ULONG) NULL, FALSE);
WinSetDlgItemText(hwnd, AUDIOCTL_ELAP, err);
CurrMMTime = (MMTIME) mp2;
InkTimedInk ( hwndInk, (MMTIME) mp2 );
break;
}
} /* end of switch(currentMode) */
return FALSE;
} /* of case MM_MCIPOSITIONCHANGE */
case WM_HSCROLL:
{
switch (SHORT2FROMMP(mp2))
{
case SB_LINELEFT:
sAudioLevel = max(0, sAudioLevel - 1);
break;
case SB_LINERIGHT:
sAudioLevel = min(100, sAudioLevel + 1);
break;
case SB_PAGELEFT:
sAudioLevel = max(0, sAudioLevel - 10);
break;
case SB_PAGERIGHT:
sAudioLevel = min(100, sAudioLevel + 10);
break;
case SB_SLIDERTRACK:
sAudioLevel = SHORT1FROMMP(mp2);
break;
case SB_ENDSCROLL:
case SB_SLIDERPOSITION:
mmsrvSetVolume((USHORT) sAudioLevel);
return FALSE;
} /* of switch(SHORT2FROMMP... */
WinSendDlgItemMsg(hwnd,
AUDIOCTL_SCRL,
SBM_SETPOS,
MPFROMSHORT(sAudioLevel),
NULL);
SetText(hwnd, err, "Volume: ",
NULL, sAudioLevel,
(ULONG) NULL, FALSE);
WinSetDlgItemText(hwnd, AUDIOCTL_VOL, err);
return FALSE;
} /* of case WM_HSCROLL */
case WM_INITDLG:
{
HWND hwndVol;
fAudioAvail = TRUE;
/* volume control scroll bar
WinCreateWindow(hwnd,
WC_SCROLLBAR,
NULL,
WS_VISIBLE | WS_SYNCPAINT | SBS_HORZ,
(ANWINSIZE / 2),
38,
(ANWINSIZE - 20) / 2,
18,
hwnd,
HWND_TOP,
AUDIOCTL_SCRL,
&sbc,
NULL); */
/* give slider position */
WinSendDlgItemMsg(hwnd,
AUDIOCTL_SCRL,
SBM_SETPOS,
MPFROMSHORT(sAudioLevel),
NULL);
/* Initial setup for recording */
currentMode = IDLE_MODE;
usTotTime = 0;
mmsrvOpen(hwnd);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), TRUE);
WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), FALSE);
return (FALSE);
} /* of case WM_CREATE */
case WM_CLOSE:
{
mmsrvClose();
DestroyTimedInk ( hwndInk );
fAudioActive = FALSE;
WinSetFocus(HWND_DESKTOP, hwndClient);
/*******************************************************************
* Enable the Voice & Ink menu item. *
*******************************************************************/
WinSendMsg(hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(IDM_ANNOT, TRUE),
MPFROM2SHORT(MIA_DISABLED, FALSE));
WinDestroyWindow(hwnd);
return(FALSE);
} /* of case WM_CLOSE */
} /* of switch(msg) */
return (WinDefDlgProc(hwnd, msg, mp1, mp2));
}