|
|
/*
* PATCH.C * * Copyright (C) 1990 Microsoft Corporation. * * Edit patchmaps dialog box and support functions. */
/* Revision history:
March 92 Ported to 16/32 common code by Laurie Griffiths (LaurieGr) */ /*-=-=-=-=- Include Files -=-=-=-=-*/
#include "preclude.h"
#include <windows.h>
#include <mmsystem.h>
#include <port1632.h>
#include <string.h>
#include "hack.h"
#include "midimap.h"
#include "cphelp.h"
#include "midi.h"
#include "extern.h"
#if defined(WIN32)
#define _based(x)
#endif //WIN32
/*-=-=-=-=- Prototypes -=-=-=-=-*/
static SZCODE aszPatchNumFormat[] = "%3d"; static MMAPERR PASCAL MmaperrPatchInit(HWND); static MMAPERR PASCAL MmaperrPatchInitNew(VOID); static VOID PASCAL PatchEnumKeys(HWND); static VOID PASCAL PatchSize(HWND, BOOL); static VOID PASCAL PatchPaint(VOID); static VOID PASCAL PatchArrowScroll(WPARAM, LPARAM); static VOID PASCAL PatchWindowScroll(HWND, UINT, int); static VOID PASCAL PatchEditMsg(UINT id , WORD NotifCode); static VOID PASCAL PatchComboMsg(HWND hDlg, WORD NotifCode); static VOID PASCAL PatchButtonDown(HWND, LONG); static VOID PASCAL PatchSetFocus(HWND, UINT, int); static VOID PASCAL PatchActiveLine(UINT, UINT); static int PASCAL PatchSave(HWND, BOOL);
/*-=-=-=-=- Global Definitions -=-=-=-=-*/
#define PAL_SHOW 0 // show active line
#define PAL_HIDE 1 // hide active line
#define PSF_REDRAW 0x0001 // redraw where line used to be
#define PSF_SHOWIFHIDDEN 0x0002 // show line if hidden
#define DEF_PATCH_ROWS 16 // number of default patch rows
/*-=-=-=-=- Global Variables -=-=-=-=-*/
static HWND hCombo, // keymap combo-box control handle
hScroll, // scroll bar control handle
hVolEdit, // volume edit control handle
hVolArrow; // volume arrow control handle
static HGLOBAL hPatchMap; static int nKeys, // number of key maps in mapfile
iPatchBase, xArrowOffset, // patch arrow ctrl positional offset
xVolArrowOffset; // volume arrow ctrl positional offset
static char szCaption[80]; static char szCaptionFormat[80];
/*-=-=-=-=- Functions -=-=-=-=-*/
/*
* PATCHBOX */ BOOL FAR PASCAL _loadds PatchBox( HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam ) { int iRet = FALSE; char szBuf [50]; MMAPERR mmaperr;
switch (uMessage) { case WM_INITDIALOG : hWnd = hDlg; SetFocus(GetDlgItem(hDlg, ID_PATCHNUMEDIT)); if ((mmaperr = MmaperrPatchInit(hDlg)) != MMAPERR_SUCCESS) { VShowError(hDlg, mmaperr); EndDialog(hDlg, FALSE); } SetScrollRange(hScroll, SB_CTL, 0, iVertMax, FALSE); SetScrollPos(hScroll, SB_CTL, iVertPos, TRUE); PlaceWindow(hWnd); return FALSE;
case WM_COMMAND : { WORD id = LOWORD(wParam); #if defined(WIN16)
WORD NotifCode = HIWORD(lParam); HWND hwnd = LOWORD(lParam); #else
WORD NotifCode = HIWORD(wParam); HWND hwnd = (HWND)lParam; #endif //WIN16
switch(id) { case IDH_DLG_MIDI_PATCHEDIT: goto DoHelp;
case ID_PATCHGHOSTEDITFIRST:
/* assume the user back-tabbed before the first
* control on the current row, so jump to the * previous row (if iCurPos > 0) or the last row * (if iCurPos == 0) */ if (fHidden) // we shouldn't get these
break; // messages when we're hidden -jyg
if (NotifCode != EN_SETFOCUS) break; if (iCurPos < 0) /* do nothing */ ; else if (iCurPos > 0) iCurPos--; else { if (iVertPos != 0) { /* at top -- scroll up one line */ PatchWindowScroll(hDlg, SB_LINEUP, 0); iCurPos = 0; } else { PatchWindowScroll(hDlg, SB_THUMBPOSITION,iVertMax); iCurPos = nLines - 1;
PatchSetFocus(hDlg, PSF_REDRAW|PSF_SHOWIFHIDDEN, 0L); PatchActiveLine(PAL_SHOW, SWP_SHOWWINDOW); } } PatchSetFocus(hDlg, PSF_REDRAW, 1); SetFocus(hCombo); break;
case ID_PATCHGHOSTEDITLAST:
/* assume the user forward-tabbed beyond the last
* control on the current row, so jump to the * next row (if iCurPos < nLines - 1) or the first row * (if iCurPos == nLines - 1) */ if (fHidden) //we shouldn't get these messages
break; //when we're hidden -jyg
if (NotifCode != EN_SETFOCUS) break; if (iCurPos < 0) /* do nothing */ ; else if (iCurPos < nLines - 1) iCurPos++; else { if (iVertPos != iVertMax) { /* at bottom -- scroll down one line */ PatchWindowScroll(hDlg, SB_LINEDOWN, 0); iCurPos = nLines - 1; } else { /* wrap to the top cell */ PatchWindowScroll(hDlg, SB_THUMBPOSITION,-iVertMax); iCurPos = 0;
PatchSetFocus(hDlg, PSF_REDRAW|PSF_SHOWIFHIDDEN, 0L); PatchActiveLine(PAL_SHOW, SWP_SHOWWINDOW); } } PatchSetFocus(hDlg, PSF_REDRAW, 1); SetFocus(hEdit);
#if defined(WIN16)
SendMessage(hEdit, EM_SETSEL, (WPARAM)0, MAKELPARAM(0, 32767)); #else
SendMessage(hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1); #endif //WIN16
break;
case IDOK : case IDCANCEL : if (NotifCode != BN_CLICKED) break; if (!fReadOnly && (id == IDOK) && fModified) { iRet = PatchSave(hDlg, TRUE); if (iRet == IDCANCEL) break; iRet = (iRet == IDYES); } else iRet = FALSE;
GlobalFree(hPatchMap); nKeys = 0; EndDialog(hDlg, iRet); break;
case ID_PATCHNUMEDIT : case ID_PATCHVOLEDIT : PatchEditMsg(id, NotifCode); break;
case ID_PATCHCOMBO : PatchComboMsg(hDlg, NotifCode); break;
case ID_PATCHBASED : if (NotifCode != BN_CLICKED) break; iPatchBase = !iPatchBase; wsprintf(szBuf, aszPatchNumber, !iPatchBase); SetWindowText(hwnd, szBuf); PatchEditMsg(ID_PATCHNUMEDIT, EN_ACTIVATE); SetFocus(hEdit); #if defined(WIN16)
SendMessage(hEdit, EM_SETSEL, (WPARAM)0, MAKELPARAM(0, 32767)); #else
SendMessage(hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1); #endif //WIN16
InvalidateRect(hWnd, &rcBox, TRUE); break;
default : return FALSE; } break; } /* end of WM_COMMAND */ case WM_PAINT : PatchPaint(); break;
case WM_LBUTTONDOWN : PatchButtonDown(hDlg, (LONG)lParam); break;
case WM_VSCROLL : #if defined(WIN16)
if ((HWND)HIWORD(lParam) == hScroll) PatchWindowScroll(hDlg, (WORD)wParam, (int)LOWORD(lParam)); else PatchArrowScroll((WORD)wParam, (LONG)lParam); #else
if ((HWND)(lParam) == hScroll) PatchWindowScroll(hDlg, LOWORD(wParam), HIWORD(wParam)); else PatchArrowScroll(LOWORD(wParam), lParam);
#endif //WIN16
break;
case WM_CLOSE : PostMessage(hDlg, WM_COMMAND, (WPARAM)IDOK, (LPARAM)0); break;
default: if (uMessage == uHelpMessage) { DoHelp: WinHelp(hWnd, szMidiHlp, HELP_CONTEXT, IDH_DLG_MIDI_PATCHEDIT); return TRUE; } else return FALSE; break; }
return TRUE; } /* PatchBox */
/*
* MmaperrPatchInit */ static MMAPERR PASCAL MmaperrPatchInit( HWND hDlg) { PATCHMAP FAR* lpPatch; LONG lDBU; MMAPERR mmaperr; UINT xBU, yBU, xWidth, // width of current column
xArrow, // width of arrow control
xEdit, // width of edit controls
yEdit, // height of edit/arrow controls
xCombo, // width of combo boxes
yCombo; // height of combo boxes
int i;
fHidden = FALSE; iVertPos = 0; iCurPos = 0; nKeys = 0; nLines = 0; // necessary?
iPatchBase = 1; // getprofile
hEdit = GetDlgItem(hWnd, ID_PATCHNUMEDIT); hArrow = GetDlgItem(hWnd, ID_PATCHNUMARROW); hVolEdit = GetDlgItem(hWnd, ID_PATCHVOLEDIT); hVolArrow = GetDlgItem(hWnd, ID_PATCHVOLARROW); hCombo = GetDlgItem(hWnd, ID_PATCHCOMBO); hScroll = GetDlgItem(hWnd, ID_PATCHSCROLL);
if (fReadOnly) { EnableWindow(GetDlgItem(hWnd,IDOK),FALSE); SendMessage(hWnd, DM_SETDEFID, (WPARAM)IDCANCEL, (LPARAM)0); }
lDBU = GetDialogBaseUnits(); xBU = LOWORD(lDBU); yBU = HIWORD(lDBU);
xArrow = (10 * xBU) / 4; // about yea big
xEdit = (40 * xBU) / 4; // 10 chars wide
yEdit = (10 * yBU) / 8; // cookie heaven
xCombo = (64 * xBU) / 4; // 16 chars wide
yCombo = (46 * yBU) / 8; // oreos
rcBox.left = (HORZMARGIN * xBU) / 4; for (i = 0, rcBox.right = rcBox.left; i < 6; i++) { rgxPos [i] = rcBox.right;
switch (i) {
case 0 : // width of src patch # text (3.5 chars wide)
rcBox.right += xEdit; break;
case 1 : // width of src patch name text
rcBox.right += (72 * xBU) / 4; // 18 chars wide
break;
case 2 : // width of dst patch # edit control
xWidth = xEdit; SetWindowPos(hEdit, NULL, 0L, 0L, xWidth, yEdit, SWP_NOZORDER | SWP_NOMOVE);
// set global arrow control offset to proper position
rcBox.right += xArrowOffset = xWidth - 1;
// width of dst patch # arrow control
xWidth = xArrow; SetWindowPos(hArrow, NULL, 0L, 0L, xWidth, yEdit, SWP_NOZORDER | SWP_NOMOVE); rcBox.right += xWidth - 1; break;
case 3 : // width of volume % edit control
xWidth = xEdit; SetWindowPos(hVolEdit, NULL, 0L, 0L, xWidth, yEdit, SWP_NOZORDER | SWP_NOMOVE);
// set global arrow control offset to proper position
rcBox.right += xVolArrowOffset = xWidth - 1;
// width of volume % arrow control
xWidth = xArrow; SetWindowPos(hVolArrow, NULL, 0L, 0L, xWidth, yEdit, SWP_NOZORDER | SWP_NOMOVE); rcBox.right += xWidth - 1; break;
case 4 : // width of keymap combo box. I'd use MMAP_MAXLEN
xWidth = xCombo; SetWindowPos(hCombo, NULL, 0L, 0L, xWidth, yCombo, SWP_NOZORDER | SWP_NOMOVE); rcBox.right += xWidth - 1; break;
case 5 : break;
} }
if (!nKeys) PatchEnumKeys(hCombo);
if (!fNew) { if ((hPatchMap = GlobalAlloc(GHND, sizeof(PATCHMAP))) == NULL) return MMAPERR_MEMORY; lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap); if ((mmaperr = mapReadPatchMap(szCurrent, lpPatch)) == MMAPERR_SUCCESS) if (lstrcmp(lpPatch->aszPatchMapDescription, szCurDesc)) { lstrcpy(lpPatch->aszPatchMapDescription, szCurDesc); fNew = TRUE; } GlobalUnlock(hPatchMap); if (mmaperr != MMAPERR_SUCCESS) { GlobalFree(hPatchMap); hPatchMap = NULL; return mmaperr; } } else if ((mmaperr = MmaperrPatchInitNew()) != MMAPERR_SUCCESS) return mmaperr;
LoadString(hLibInst, IDS_PATCHES ,szCaptionFormat, sizeof(szCaptionFormat)); wsprintf(szCaption, szCaptionFormat, (LPSTR)szCurrent); SetWindowText(hWnd, szCaption);
SendMessage(GetDlgItem(hWnd, ID_PATCHDESTMNEM), WM_SETFONT, (WPARAM)hFont, (LPARAM)0); SendMessage(GetDlgItem(hWnd, ID_PATCHVOLMNEM), WM_SETFONT, (WPARAM)hFont, (LPARAM)0); SendMessage(GetDlgItem(hWnd, ID_PATCHKEYMNEM), WM_SETFONT, (WPARAM)hFont, (LPARAM)0); PatchSize(hDlg, TRUE); i = rcBox.top - yChar + 5; SetWindowPos(GetDlgItem(hWnd, ID_PATCHDESTMNEM), NULL, rgxPos [2] - xChar + 7, i, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER); SetWindowPos(GetDlgItem(hWnd, ID_PATCHVOLMNEM), NULL, rgxPos [3] + xChar - 6, i, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER); SetWindowPos(GetDlgItem(hWnd, ID_PATCHKEYMNEM), NULL, rgxPos [4] + xChar, i, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER); #if defined(WIN16)
SendMessage(hWnd, WM_COMMAND, (WPARAM)ID_PATCHBASED, MAKELPARAM(GetDlgItem(hWnd, ID_PATCHBASED), BN_CLICKED)); #else
SendMessage( hWnd , WM_COMMAND , (WPARAM)MAKELONG(ID_PATCHBASED, BN_CLICKED) , (LPARAM)GetDlgItem(hWnd, ID_PATCHBASED) ); #endif //WIN16
Modify(fNew); return MMAPERR_SUCCESS; } /* MmaperrPatchInit */
/*
* MmaperrPatchInitNew */ static MMAPERR PASCAL MmaperrPatchInitNew( VOID) { PATCHMAP FAR* lpPatch; UINT u;
if ((hPatchMap = GlobalAlloc(GHND, (DWORD)sizeof(PATCHMAP))) == NULL) return MMAPERR_MEMORY; lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap); lstrcpy(lpPatch->aszPatchMapName, szCurrent); lstrcpy(lpPatch->aszPatchMapDescription, szCurDesc); for (u = 0; u < MIDIPATCHSIZE; u++) { lpPatch->keymaps[u].bVolume = 100; lpPatch->keymaps[u].bDestination = (BYTE)u; lstrcpy(lpPatch->keymaps[u].aszKeyMapName, szNone); } GlobalUnlock(hPatchMap); return MMAPERR_SUCCESS; } /* MmaperrPatchInitNew */
/*
* PATCHENUMKEYS */ static VOID PASCAL PatchEnumKeys(HWND hCombo) { mapEnumerate(MMAP_KEY, EnumFunc, MMENUM_BASIC, hCombo, NULL); SendMessage(hCombo, CB_ADDSTRING, (WPARAM)0, (LPARAM)(LPSTR)szNone); nKeys = (int)(LONG)SendMessage(hCombo, CB_GETCOUNT, (WPARAM)NULL, (LPARAM)0); } /* PatchEnumKeys */
/*
* PATCHSIZE */ static VOID PASCAL PatchSize(HWND hDlg, BOOL fMaximize) { HWND hBanana; RECT rcBanana; RECT rcOK, rcWnd; LONG lDBU; UINT xBU, yBU; int xButton, xCenter, yTopMar, yBotMar, yLeftOver, yBox, yMiniBotMar;
lDBU = GetDialogBaseUnits(); xBU = LOWORD(lDBU); yBU = HIWORD(lDBU);
// get the rectangle of the OK button
GetClientRect(GetDlgItem(hWnd, IDOK), &rcOK);
// get x-extent of button
xButton = rcOK.right - rcOK.left;
// top margin is 4 characters
yTopMar = (32 * yBU) / 8 - 6; // cookie land
// bottom margin is 2 * minimum bottom margin dialog units +
// height of button in pixels
yBotMar = (VERTMARGIN * 2 * yBU) / 8 + rcOK.bottom - rcOK.top;
if (fMaximize) { // maximize the patch box
SetWindowPos(hWnd, NULL, 0L, 0L, rcBox.right - rcBox.left + (2 * HORZMARGIN * xBU) / 4 + GetSystemMetrics(SM_CXVSCROLL) + (GetSystemMetrics(SM_CXDLGFRAME) + 1) * 2, (DEF_PATCH_ROWS * 10 * yBU) / 8 + yTopMar + yBotMar + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) * 2, SWP_NOZORDER | SWP_NOMOVE); }
// get the x and y extents of the client rectangle
GetClientRect(hWnd, &rcWnd); xClient = rcWnd.right - rcWnd.left; yClient = rcWnd.bottom - rcWnd.top;
// yChar is the height of one row in pixels - 1
yChar = (10 * yBU) / 8 - 1;
// xChar is the average width of a character
xChar = xBU;
// yBox is the room we actually have to display patchmap rows
yBox = yClient - yTopMar - yBotMar;
// nLines is the number of setup rows we can display
nLines = min(16, yBox / yChar);
// yLeftOver is how many pixels are left over
yLeftOver = yBox - nLines * yChar;
// add half the leftovers to the top margin
yTopMar += yLeftOver / 2;
// rcBox is the box of rows and columns inside the client area
SetRect( &rcBox, rcBox.left, yTopMar, rcBox.right, yTopMar + nLines * yChar);
// xCenter is used to center the OK and CANCEL buttons horizontally
xCenter = (rcBox.right - rcBox.left - xButton * 3) / 4;
// yMiniBotMar is the spacing above and below the button
yMiniBotMar = (VERTMARGIN * yBU) / 8 + yLeftOver / 4;
SetWindowPos( GetDlgItem(hWnd, IDOK), NULL, rcBox.left + xCenter, rcBox.bottom + yMiniBotMar, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER);
SetWindowPos( GetDlgItem(hWnd, IDCANCEL), NULL, rcBox.left + xButton + xCenter * 2, rcBox.bottom + yMiniBotMar, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER);
SetWindowPos( GetDlgItem(hWnd, IDH_DLG_MIDI_PATCHEDIT), NULL, rcBox.left + xButton * 2 + xCenter * 3, rcBox.bottom + yMiniBotMar, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER);
// get the banana button
hBanana = GetDlgItem(hWnd, ID_PATCHBASED);
// get the rectangle of the banana button
GetClientRect(hBanana, &rcBanana);
// set the banana position
SetWindowPos( hBanana, NULL, rcBox.left + (rcBox.right - rcBox.left - rcBanana.right) / 2, (6 * yBU) / 8, 0L, 0L, SWP_NOSIZE | SWP_NOZORDER);
SetWindowPos( hScroll, NULL, rcBox.right, rcBox.top, GetSystemMetrics(SM_CXVSCROLL), rcBox.bottom - rcBox.top + 1, SWP_NOZORDER);
iVertMax = max(0, MIDIPATCHSIZE - nLines); iVertPos = min(iVertMax, iVertPos); SetScrollRange(hScroll, SB_CTL, 0, iVertMax, FALSE); SetScrollPos(hScroll, SB_CTL, iVertPos, TRUE);
if (iCurPos >= 0 && iCurPos < nLines) PatchSetFocus(hDlg, PSF_SHOWIFHIDDEN, 1); else PatchActiveLine(PAL_HIDE, SWP_NOREDRAW); } /* PatchSize */
/*
* PATCHPAINT */ static VOID PASCAL PatchPaint(VOID) { HPEN hPen = 0; PATCHMAP FAR* lpPatch; PAINTSTRUCT ps; int i, iVert, iLeft, nBegin, nEnd, iTop, iBottom; BOOL fSelected = FALSE; char szBuf [50];
BeginPaint(hWnd, &ps);
if (!ps.rcPaint.bottom) goto DonePainting;
hPen = SelectObject(ps.hdc, GetStockObject(BLACK_PEN)); hFont = SelectObject(ps.hdc, hFont); fSelected = TRUE;
SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWTEXT)); SetBkMode(ps.hdc, TRANSPARENT);
if (ps.rcPaint.top < rcBox.top) { iVert = rcBox.top - yChar + 5; TextOut(ps.hdc, 11, iVert, aszSourcePatch, lstrlen(aszSourcePatch)); TextOut(ps.hdc, rgxPos [1] + xChar * 2 - 15, iVert, aszSourcePatchName, lstrlen(aszSourcePatchName)); }
// calculate top and bottom y coordinates of invalid area
iTop = max(ps.rcPaint.top, rcBox.top);
// if top is below the box, forget about painting
if (iTop > rcBox.bottom) goto DonePainting;
iBottom = min(ps.rcPaint.bottom, rcBox.bottom);
// calculate left x coordinate of invalid area
iLeft = max(ps.rcPaint.left, rcBox.left);
// calculate beginning and ending data row to be repainted
nBegin = max(0, (iTop - rcBox.top) / yChar); nEnd = min(nLines, (iBottom - rcBox.top) / yChar);
for (i = 0; i < 6; i++) { MMoveTo(ps.hdc, rgxPos [i], iTop); LineTo(ps.hdc, rgxPos [i], iBottom + 1); } // vertical position of first line we have to draw
iVert = rcBox.top + nBegin * yChar;
// lock the map
lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap); for (i = nBegin; i <= nEnd; i++, iVert += yChar) { MMoveTo(ps.hdc, iLeft, iVert); LineTo(ps.hdc, min(ps.rcPaint.right, rcBox.right), iVert);
if (i == nLines) break;
if (iLeft < rgxPos [1]) { wsprintf(szBuf, aszPatchNumFormat, iVertPos + iPatchBase + i); TextOut(ps.hdc, rgxPos [0] + xChar, iVert + 2, szBuf, 3); } if (iLeft < rgxPos [2]) { if (!LoadString(hLibInst, IDS_PATCHMAP_BASE + iVertPos + i + 1, szBuf, sizeof(szBuf))) LoadString(hLibInst, IDS_RESERVED, szBuf, sizeof(szBuf)); TextOut(ps.hdc, rgxPos [1] + 2, iVert + 2, szBuf, lstrlen(szBuf)); }
if (i == iCurPos) continue;
if (iLeft < rgxPos [3]) { wsprintf(szBuf, aszPatchNumFormat, lpPatch->keymaps[iVertPos + i].bDestination + iPatchBase); TextOut(ps.hdc, rgxPos [2] + xChar * 2, iVert + 2, szBuf, 3); } if (iLeft < rgxPos [4]) { wsprintf(szBuf, aszPatchNumFormat, lpPatch->keymaps[iVertPos + i].bVolume); TextOut(ps.hdc, rgxPos [3] + xChar * 2, iVert + 2, szBuf, 3); } if (iLeft < rgxPos [5]) TextOut(ps.hdc, rgxPos [4] + 2, iVert + 2, lpPatch->keymaps[iVertPos + i].aszKeyMapName, lstrlen(lpPatch->keymaps[iVertPos + i].aszKeyMapName)); } GlobalUnlock(hPatchMap);
DonePainting: if (fSelected) { hFont = SelectObject(ps.hdc, hFont); hPen = SelectObject(ps.hdc, hPen); } EndPaint(hWnd, &ps); } /* PatchPaint */
/*
* PATCHARROWSCROLL * * Interpret a scroll message for the arrow control. */ static VOID PASCAL PatchArrowScroll( WPARAM wParam, // scroll code only (even on 32 bit)
LPARAM lParam ) // (hwnd,posn) (16 bit), hwnd (32 bit)
// posn not actually used.
{ PATCHMAP FAR* lpPatch; UINT uId; BYTE bPatch, bMax, bMin;
lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap);
#if defined(WIN16)
if ((HWND)HIWORD(lParam) == hArrow) { #else
if ((HWND)lParam == hArrow) { #endif
uId = ID_PATCHNUMEDIT; bPatch = lpPatch->keymaps[iVertPos + iCurPos].bDestination + (BYTE)iPatchBase; bMax = (BYTE)(127 + iPatchBase); // MMAP_MAXPATCHES
bMin = (BYTE)iPatchBase; } else { uId = ID_PATCHVOLEDIT; bPatch = lpPatch->keymaps[iVertPos + iCurPos].bVolume; bMax = 200; // MMAP_MAXVOLUME
bMin = 0; } GlobalUnlock(hPatchMap);
switch (wParam) {
case SB_LINEDOWN : if (bPatch-- == bMin) bPatch = bMax; break;
case SB_LINEUP : if (bPatch++ == bMax) bPatch = bMin; break;
default: break; } SetDlgItemInt(hWnd, uId, bPatch, FALSE); } /* PatchArrowScroll */
/*
* PATCHWINDOWSCROLL */ static VOID PASCAL PatchWindowScroll( HWND hDlg, UINT wParam, int iPos ) { HDC hDC; RECT rc; int iVertInc; BOOL fWillBeVisible; // will it be visible after scroll?
switch (wParam) {
case SB_LINEUP : iVertInc = -1; break;
case SB_LINEDOWN : iVertInc = 1; break;
case SB_PAGEUP : iVertInc = min(-1, -nLines); break;
case SB_PAGEDOWN : iVertInc = max(1, nLines); break;
case SB_THUMBTRACK : case SB_THUMBPOSITION : iVertInc = iPos - iVertPos; break;
default : iVertInc = 0; }
iVertInc = max(-iVertPos, min(iVertInc, iVertMax - iVertPos));
if (iVertInc != 0) { iVertPos += iVertInc; iCurPos -= iVertInc;
if (iCurPos < 0 || iCurPos >= nLines) { SetFocus(NULL); fWillBeVisible = FALSE; } else fWillBeVisible = TRUE;
// Scroll to the correct position
SetScrollPos(hScroll, SB_CTL, iVertPos, TRUE);
hDC = GetDC(hWnd); ScrollDC(hDC, 0L, -yChar * iVertInc, &rcBox, &rcBox, NULL, &rc); ReleaseDC(hWnd, hDC);
if (!fHidden) PatchActiveLine(PAL_HIDE, SWP_NOREDRAW);
if (fWillBeVisible) { PatchSetFocus(hDlg, 0L, 0L); PatchActiveLine(PAL_SHOW, SWP_NOREDRAW); } InvalidateRect(hWnd, &rc, TRUE); UpdateWindow(hWnd); } } /* PatchWindowScroll */
/*
* PatchEditMsg * * This function deals with EN_UPDATE and EN_ACTIVATE messages sent * to the patch number and volume percent edit controls through the * WM_COMMAND message. */ static VOID PASCAL PatchEditMsg( UINT id, WORD NotifCode ) { PATCHMAP FAR* lpPatch; UINT uVal, // value of control
uMin, // min value allowed
uMax; // max value allowed
BOOL bTranslate;
if (NotifCode != EN_UPDATE && NotifCode != EN_ACTIVATE) return;
lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap);
switch (NotifCode) {
case EN_UPDATE : if (id == ID_PATCHNUMEDIT) { uMax = 127 + iPatchBase;// MMAP_MAXPATCHES
uMin = iPatchBase; } else { uMax = 200; // MMAP_MAXVOLUME
uMin = 0; }
uVal = (UINT)GetDlgItemInt(hWnd, id, &bTranslate, TRUE);
if ((int)uVal < (int)uMin) { uVal = uMin; SetDlgItemInt(hWnd, id, uVal, FALSE); } else if (uVal > uMax) { uVal = uMax; SetDlgItemInt(hWnd, id, uVal, FALSE); } else { if (id == ID_PATCHNUMEDIT) { uVal -= iPatchBase; if (uVal != lpPatch->keymaps[iVertPos + iCurPos].bDestination) { lpPatch->keymaps[iVertPos + iCurPos].bDestination = (BYTE)uVal; Modify(TRUE); } } else if (uVal != lpPatch->keymaps[iVertPos + iCurPos].bVolume) { lpPatch->keymaps[iVertPos + iCurPos].bVolume = (BYTE)uVal; Modify(TRUE); } } break;
case EN_ACTIVATE : if (id == ID_PATCHNUMEDIT) SetDlgItemInt(hWnd, id, lpPatch->keymaps[iVertPos + iCurPos].bDestination + iPatchBase, FALSE); else SetDlgItemInt(hWnd, id, lpPatch->keymaps[iVertPos + iCurPos].bVolume, FALSE); break;
default : break;
}
GlobalUnlock(hPatchMap); } /* PatchEditMsg */
/*
* PatchComboMsg * * This function deals with the CBN_ACTIVATE and CBN_SELCHANGE messages sent * to the keymap name combo box through the WM_COMMAND message. */ static VOID PASCAL PatchComboMsg(HWND hDlg, WORD NotifCode) { PATCHMAP FAR* lpPatch; char szBuf [MMAP_MAXNAME];
if (NotifCode != CBN_ACTIVATE && NotifCode != CBN_SELCHANGE) return;
lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap);
switch (NotifCode) {
case CBN_ACTIVATE : SendMessage(hCombo, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)(lpPatch->keymaps[iVertPos + iCurPos].aszKeyMapName)); break;
case CBN_SELCHANGE: GetWindowText(hCombo, szBuf, MMAP_MAXNAME); if (!lstrcmpi(szBuf, lpPatch->keymaps[iVertPos + iCurPos].aszKeyMapName)) break; lstrcpy(lpPatch->keymaps[iVertPos + iCurPos].aszKeyMapName, szBuf); Modify(TRUE); break;
default : break; }
GlobalUnlock(hPatchMap); } /* PatchComboMsg */
/*
* PATCHBUTTONDOWN */ static VOID PASCAL PatchButtonDown(HWND hDlg, LONG lParam) { int x = LOWORD(lParam), y = HIWORD(lParam), iPos; UINT uFlags;
if (x < rcBox.left || x > rcBox.right) return; if (y < rcBox.top || y > rcBox.bottom) return;
iPos = min(nLines - 1, (y - rcBox.top) / yChar);
if (iPos == iCurPos) return;
if (iCurPos >= 0 && iCurPos < nLines) { uFlags = PSF_REDRAW; SendMessage(hCombo, CB_SHOWDROPDOWN, (WPARAM)FALSE, (LPARAM)0); UpdateWindow(hWnd); } else uFlags = PSF_SHOWIFHIDDEN;
iCurPos = iPos; PatchSetFocus(hDlg, uFlags, x); } /* PatchButtonDown */
/*
* PATCHSETFOCUS */ static VOID PASCAL PatchSetFocus( HWND hDlg, UINT uFlags, int xPos ) { RECT rc; int yPos = rcBox.top + iCurPos * yChar;
PatchEditMsg(ID_PATCHNUMEDIT, EN_ACTIVATE); PatchEditMsg(ID_PATCHVOLEDIT, EN_ACTIVATE); PatchComboMsg(hDlg, CBN_ACTIVATE);
GetWindowRect(hEdit, &rc);
SetWindowPos(hEdit, NULL, rgxPos [2], yPos, 0L, 0L, SWP_NOZORDER | SWP_NOSIZE); SetWindowPos(hArrow, NULL, rgxPos [2] + xArrowOffset, yPos, 0L, 0L, SWP_NOZORDER | SWP_NOSIZE); SetWindowPos(hVolEdit, NULL, rgxPos [3], yPos, 0L, 0L, SWP_NOZORDER | SWP_NOSIZE); SetWindowPos(hVolArrow, NULL, rgxPos [3] + xVolArrowOffset, yPos, 0L, 0L, SWP_NOZORDER | SWP_NOSIZE); SetWindowPos(hCombo, NULL, rgxPos [4], yPos, 0L, 0L, SWP_NOZORDER | SWP_NOSIZE);
if (fHidden && uFlags & PSF_SHOWIFHIDDEN) { PatchActiveLine(PAL_SHOW, 0L); UpdateWindow(hEdit); UpdateWindow(hArrow); UpdateWindow(hVolEdit); UpdateWindow(hVolArrow); UpdateWindow(hCombo); }
if (uFlags & PSF_REDRAW && rc.right) { ScreenToClient(hWnd, (LPPOINT)&rc); ScreenToClient(hWnd, (LPPOINT)&rc + 1); rc.right = rcBox.right + 1; InvalidateRect(hWnd, &rc, FALSE); UpdateWindow(hWnd); }
if (xPos < rgxPos [3]) { if (!fHidden) SetFocus(hEdit); #if defined(WIN16)
SendMessage(hEdit, EM_SETSEL, (WPARAM)NULL, MAKELPARAM(0, 32767)); #else
SendMessage(hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1); #endif //WIN16
} else if (xPos < rgxPos [4]) { if (!fHidden) SetFocus(hVolEdit); #if defined(WIN16)
SendMessage(hVolEdit, EM_SETSEL, (WPARAM)NULL, MAKELPARAM(0, 32767)); #else
SendMessage(hVolEdit, EM_SETSEL, (WPARAM)0, (LPARAM)-1); #endif //WIN16
} else if (xPos < rgxPos [5] && !fHidden) SetFocus(hCombo); } /* PatchSetFocus */
/*
* PATCHACTIVELINE */ static VOID PASCAL PatchActiveLine( UINT uCase, UINT uFlags ) { static const UINT uDefFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
switch (uCase) {
case PAL_SHOW : if (!fHidden) return;
uFlags |= SWP_SHOWWINDOW; fHidden = FALSE; break;
case PAL_HIDE : if (fHidden) return;
uFlags |= SWP_HIDEWINDOW; fHidden = TRUE; break;
default : break;
} uFlags |= uDefFlags; SetWindowPos(hEdit, NULL, 0L, 0L, 0L, 0L, uFlags); SetWindowPos(hArrow, NULL, 0L, 0L, 0L, 0L, uFlags); SetWindowPos(hVolEdit, NULL, 0L, 0L, 0L, 0L, uFlags); SetWindowPos(hVolArrow, NULL, 0L, 0L, 0L, 0L, uFlags); SetWindowPos(hCombo, NULL, 0L, 0L, 0L, 0L, uFlags);
if (uCase == PAL_SHOW && !fHidden) SetFocus(hEdit); } /* PatchActiveLine */
/*
* PATCHSAVE */ static int PASCAL PatchSave( HWND hDlg, BOOL bQuery) { PATCHMAP FAR* lpPatch; MMAPERR mmaperr; int iRet = 0; // a value other than IDCANCEL or IDYES
if (bQuery) { iRet = QuerySave(); if (iRet != IDYES) return iRet; } lpPatch = (PATCHMAP FAR*)GlobalLock(hPatchMap); mmaperr = mapWrite(MMAP_PATCH, lpPatch); GlobalUnlock(hPatchMap); if (mmaperr != MMAPERR_SUCCESS) { VShowError(hDlg, mmaperr); return IDCANCEL; } Modify(FALSE); if (fNew) fNew = FALSE; return iRet; } /* PatchSave */
|