Exemple #1
0
//開啟舊檔
void CFileControl::OpenFile(HWND hWnd)
{
	
	if( _bNeedSave)
	{
		short AskAboutSaveResult = AskAboutSave( hWnd, szTitleName);

		if( AskAboutSaveResult == IDCANCEL )
			return;
	}

	if( this->PopFileOpenDlg(hWnd, szFileName, szTitleName))
	{
		if( !PopFileRead( hWnd , szFileName)) 
		{
			this->OkMessage(hWnd, TEXT("企圖讀取非法檔案 %s!"), szTitleName);
			szFileName[0]  = '\0';
	        szTitleName[0] = '\0';
		}
		else
		{
			//清除所有歷程紀錄
			gRedoUndoController->Reset();
			this->DoCaption( hWnd, szTitleName,false );
			_bNeedSave = FALSE;
		}
	}
}
Exemple #2
0
//離開
void CFileControl::CloseProgram(HWND hWnd)
{
	if( _bNeedSave )
	{
		AskAboutSave(hWnd,szTitleName);
	}

	if ( IDNO == AskAboutExit(hWnd))
		return;
	else
		::DestroyWindow(hWnd);
}
Exemple #3
0
//按下清除選項
void CFileControl::ClickClearMenu(HWND hWnd)
{
	if( _bNeedSave)
	{
		 AskAboutSave(hWnd,szTitleName);
	}

	//重設檔案名稱
	this->ResetFileNameInfo(hWnd);
	_parent->SetHitID(-1);
	_parent->GetCSelectRecInfo().SetIsShow(false);
	//送出清除畫面的訊息
	_parent->ClickClearMenuItem();
	_parent->GetDrawTool()->ClearMonitor();
	_parent->SetDirectionMouse( CursorDirection_ARROW );
	gRedoUndoController->Reset();
}
Exemple #4
0
//開新檔案
void CFileControl::FileCreate(HWND hWnd)
{
	if( _bNeedSave && IDCANCEL == AskAboutSave(hWnd,szTitleName))
	{
		return;
	}

	//重設檔案資訊
	this->ResetFileNameInfo(hWnd);
	_bNeedSave = FALSE;
	
	_parent->SetHitID(-1);
	_parent->GetCSelectRecInfo().SetIsShow(false);
	//送出清除畫面的訊息
	_parent->ClickClearMenuItem();
	_parent->GetDrawTool()->ClearMonitor();
	gRedoUndoController->Reset();
}
Exemple #5
0
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static BOOL      bNeedSave = FALSE ;
     static HINSTANCE hInst ;
     static HWND      hwndEdit ;
     static int       iOffset ;
     static TCHAR     szFileName[MAX_PATH], szTitleName[MAX_PATH] ;
     static UINT      messageFindReplace ;
     int              iSelBeg, iSelEnd, iEnable ;
     LPFINDREPLACE    pfr ;
     
     switch (message)
     {
     case WM_CREATE:
          hInst = ((LPCREATESTRUCT) lParam) -> hInstance ;
          
               // Create the edit control child window
          
          hwndEdit = CreateWindow (TEXT ("edit"), NULL,
                              WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
                              WS_BORDER | ES_LEFT | ES_MULTILINE |
                              ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
                              0, 0, 0, 0,
                              hwnd, (HMENU) EDITID, hInst, NULL) ;
          
          SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ;
          
               // Initialize common dialog box stuff
          
          PopFileInitialize (hwnd) ;
          PopFontInitialize (hwndEdit) ;
          
          messageFindReplace = RegisterWindowMessage (FINDMSGSTRING) ;
          
          DoCaption (hwnd, szTitleName) ;
          return 0 ;
          
     case WM_SETFOCUS:
          SetFocus (hwndEdit) ;
          return 0 ;
          
     case WM_SIZE: 
          MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
          return 0 ;
          
     case WM_INITMENUPOPUP:
          switch (lParam)
          {
          case 1:             // Edit menu
               
                    // Enable Undo if edit control can do it
               
               EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO,
                    SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?
                                             MF_ENABLED : MF_GRAYED) ;
               
                    // Enable Paste if text is in the clipboard
               
               EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE,
                    IsClipboardFormatAvailable (CF_TEXT) ?
                                             MF_ENABLED : MF_GRAYED) ;
               
                    // Enable Cut, Copy, and Del if text is selected
               
               SendMessage (hwndEdit, EM_GETSEL, (WPARAM) &iSelBeg,
                                                 (LPARAM) &iSelEnd) ;
               
               iEnable = iSelBeg != iSelEnd ? MF_ENABLED : MF_GRAYED ;
               
               EnableMenuItem ((HMENU) wParam, IDM_EDIT_CUT,   iEnable) ;
               EnableMenuItem ((HMENU) wParam, IDM_EDIT_COPY,  iEnable) ;
               EnableMenuItem ((HMENU) wParam, IDM_EDIT_CLEAR, iEnable) ;
               break ;
               
          case 2:             // Search menu
               
               // Enable Find, Next, and Replace if modeless
               //   dialogs are not already active
               
               iEnable = hDlgModeless == NULL ?
                              MF_ENABLED : MF_GRAYED ;
               
               EnableMenuItem ((HMENU) wParam, IDM_SEARCH_FIND,    iEnable) ;
               EnableMenuItem ((HMENU) wParam, IDM_SEARCH_NEXT,    iEnable) ;
               EnableMenuItem ((HMENU) wParam, IDM_SEARCH_REPLACE, iEnable) ;
               break ;
          }
          return 0 ;
     
     case WM_COMMAND:
               // Messages from edit control
          
          if (lParam && LOWORD (wParam) == EDITID)
          {
               switch (HIWORD (wParam))
               {
               case EN_UPDATE :
                    bNeedSave = TRUE ;
                    return 0 ;
                    
               case EN_ERRSPACE :
               case EN_MAXTEXT :
                    MessageBox (hwnd, TEXT ("Edit control out of space."),
                                szAppName, MB_OK | MB_ICONSTOP) ;
                    return 0 ;
               }
               break ;
          }
          
          switch (LOWORD (wParam))
          {
               // Messages from File menu
               
          case IDM_FILE_NEW:
               if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName))
                    return 0 ;
               
               SetWindowText (hwndEdit, TEXT ("\0")) ;
               szFileName[0]  = '\0' ;
               szTitleName[0] = '\0' ;
               DoCaption (hwnd, szTitleName) ;
               bNeedSave = FALSE ;
               return 0 ;
               
          case IDM_FILE_OPEN:
               if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName))
                    return 0 ;
               
               if (PopFileOpenDlg (hwnd, szFileName, szTitleName))
               {
                    if (!PopFileRead (hwndEdit, szFileName))
                    {
                         OkMessage (hwnd, TEXT ("Could not read file %s!"),
                                    szTitleName) ;
                         szFileName[0]  = '\0' ;
                         szTitleName[0] = '\0' ;
                    }
               }
               
               DoCaption (hwnd, szTitleName) ;
               bNeedSave = FALSE ;
               return 0 ;
               
          case IDM_FILE_SAVE:
               if (szFileName[0])
               {
                    if (PopFileWrite (hwndEdit, szFileName))
                    {
                         bNeedSave = FALSE ;
                         return 1 ;
                    }
                    else
                    {
                         OkMessage (hwnd, TEXT ("Could not write file %s"),
                                    szTitleName) ;
                         return 0 ;
                    }
               }
                                   // fall through
          case IDM_FILE_SAVE_AS:
               if (PopFileSaveDlg (hwnd, szFileName, szTitleName))
               {
                    DoCaption (hwnd, szTitleName) ;
                    
                    if (PopFileWrite (hwndEdit, szFileName))
                    {
                         bNeedSave = FALSE ;
                         return 1 ;
                    }
                    else
                    {
                         OkMessage (hwnd, TEXT ("Could not write file %s"),
                                    szTitleName) ;
                         return 0 ;
                    }
               }
               return 0 ;
               
          case IDM_FILE_PRINT:
               if (!PopPrntPrintFile (hInst, hwnd, hwndEdit, szTitleName))
                    OkMessage (hwnd, TEXT ("Could not print file %s"),
                                     szTitleName) ;
               return 0 ;
               
          case IDM_APP_EXIT:
               SendMessage (hwnd, WM_CLOSE, 0, 0) ;
               return 0 ;
               
                    // Messages from Edit menu
               
          case IDM_EDIT_UNDO:
               SendMessage (hwndEdit, WM_UNDO, 0, 0) ;
               return 0 ;
               
          case IDM_EDIT_CUT:
               SendMessage (hwndEdit, WM_CUT, 0, 0) ;
               return 0 ;
               
          case IDM_EDIT_COPY:
               SendMessage (hwndEdit, WM_COPY, 0, 0) ;
               return 0 ;
               
          case IDM_EDIT_PASTE:
               SendMessage (hwndEdit, WM_PASTE, 0, 0) ;
               return 0 ;
               
          case IDM_EDIT_CLEAR:
               SendMessage (hwndEdit, WM_CLEAR, 0, 0) ;
               return 0 ;
               
          case IDM_EDIT_SELECT_ALL:
               SendMessage (hwndEdit, EM_SETSEL, 0, -1) ;
               return 0 ;
               
                    // Messages from Search menu
               
          case IDM_SEARCH_FIND:
               SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) &iOffset) ;
               hDlgModeless = PopFindFindDlg (hwnd) ;
               return 0 ;
               
          case IDM_SEARCH_NEXT:
               SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) &iOffset) ;
               
               if (PopFindValidFind ())
                    PopFindNextText (hwndEdit, &iOffset) ;
               else
                    hDlgModeless = PopFindFindDlg (hwnd) ;
               
               return 0 ;
               
          case IDM_SEARCH_REPLACE:
               SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) &iOffset) ;
               hDlgModeless = PopFindReplaceDlg (hwnd) ;
               return 0 ;
               
          case IDM_FORMAT_FONT:
               if (PopFontChooseFont (hwnd))
                    PopFontSetFont (hwndEdit) ;
               
               return 0 ;
               
                    // Messages from Help menu
               
          case IDM_HELP:
               OkMessage (hwnd, TEXT ("Help not yet implemented!"), 
                                TEXT ("\0")) ;
               return 0 ;
               
          case IDM_APP_ABOUT:
               DialogBox (hInst, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;
               return 0 ;
          }
          break ;
               
     case WM_CLOSE:
          if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
               DestroyWindow (hwnd) ;
          
          return 0 ;
          
     case WM_QUERYENDSESSION :
          if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
               return 1 ;
          
          return 0 ;
          
     case WM_DESTROY:
          PopFontDeinitialize () ;
          PostQuitMessage (0) ;
          return 0 ;
          
     default:
               // Process "Find-Replace" messages
          
          if (message == messageFindReplace)
          {
               pfr = (LPFINDREPLACE) lParam ;
               
               if (pfr->Flags & FR_DIALOGTERM)
                    hDlgModeless = NULL ;
               
               if (pfr->Flags & FR_FINDNEXT)
                    if (!PopFindFindText (hwndEdit, &iOffset, pfr))
                         OkMessage (hwnd, TEXT ("Text not found!"), 
                                          TEXT ("\0")) ;
                    
               if (pfr->Flags & FR_REPLACE || pfr->Flags & FR_REPLACEALL)
                    if (!PopFindReplaceText (hwndEdit, &iOffset, pfr))
                         OkMessage (hwnd, TEXT ("Text not found!"), 
                                          TEXT ("\0")) ;
                         
               if (pfr->Flags & FR_REPLACEALL)
                    while (PopFindReplaceText (hwndEdit, &iOffset, pfr)) ;
                              
               return 0 ;
          }
          break ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
Exemple #6
0
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static BOOL  bNeedSave ;
     static DRUM  drum ;
     static HMENU hMenu ;
     static int   iTempo = 50, iIndexLast ;
     static TCHAR szFileName  [MAX_PATH], szTitleName [MAX_PATH] ;
     HDC          hdc ;
     int          i, x, y ;
     PAINTSTRUCT  ps ;
     POINT        point ;
     RECT         rect ;
     TCHAR      * szError ;
     
     switch (message)
     {
     case WM_CREATE:
               // Initialize DRUM structure
          
          drum.iMsecPerBeat = 100 ;
          drum.iVelocity    =  64 ;
          drum.iNumBeats    =  32 ;
          
          DrumSetParams (&drum) ;
          
               // Other initialization
          
          cxChar = LOWORD (GetDialogBaseUnits ()) ;
          cyChar = HIWORD (GetDialogBaseUnits ()) ;

          GetWindowRect (hwnd, &rect) ;
          MoveWindow (hwnd, rect.left, rect.top, 
                            77 * cxChar, 29 * cyChar, FALSE) ;
          
          hMenu = GetMenu (hwnd) ;
          
               // Initialize "Volume" scroll bar
          
          SetScrollRange (hwnd, SB_HORZ, 1, 127, FALSE) ;
          SetScrollPos   (hwnd, SB_HORZ, drum.iVelocity, TRUE) ;
          
               // Initialize "Tempo" scroll bar
          
          SetScrollRange (hwnd, SB_VERT, 0, 100, FALSE) ;
          SetScrollPos   (hwnd, SB_VERT, iTempo, TRUE) ;
          
          DoCaption (hwnd, szTitleName) ;
          return 0 ;
          
     case WM_COMMAND:
          switch (LOWORD (wParam))
          {
          case IDM_FILE_NEW:
               if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName))
                    return 0 ;
               
                    // Clear drum pattern
               
               for (i = 0 ; i < NUM_PERC ; i++)
               {
                    drum.dwSeqPerc [i] = 0 ;
                    drum.dwSeqPian [i] = 0 ;
               }
               
               InvalidateRect (hwnd, NULL, FALSE) ;
               DrumSetParams (&drum) ;
               bNeedSave = FALSE ;
               return 0 ;
               
          case IDM_FILE_OPEN:
                    // Save previous file
               
               if (bNeedSave && IDCANCEL ==
                    AskAboutSave (hwnd, szTitleName))
                    return 0 ;
               
                    // Open the selected file
               
               if (DrumFileOpenDlg (hwnd, szFileName, szTitleName))
               {
                    szError = DrumFileRead (&drum, szFileName) ;
                    
                    if (szError != NULL)
                    {
                         ErrorMessage (hwnd, szError, szTitleName) ;
                         szTitleName [0] = '\0' ;
                    }
                    else
                    {
                              // Set new parameters
                         
                         iTempo = (int) (50 *
                              (log10 (drum.iMsecPerBeat) - 1)) ;
                         
                         SetScrollPos (hwnd, SB_VERT, iTempo, TRUE) ;
                         SetScrollPos (hwnd, SB_HORZ, drum.iVelocity, TRUE) ;
                         
                         DrumSetParams (&drum) ;
                         InvalidateRect (hwnd, NULL, FALSE) ;
                         bNeedSave = FALSE ;
                    }
                    
                    DoCaption (hwnd, szTitleName) ;
               }
               return 0 ;
               
          case IDM_FILE_SAVE:
          case IDM_FILE_SAVE_AS:
                    // Save the selected file
               
               if ((LOWORD (wParam) == IDM_FILE_SAVE && szTitleName [0]) ||
                         DrumFileSaveDlg (hwnd, szFileName, szTitleName))
               {
                    szError = DrumFileWrite (&drum, szFileName) ;
                    
                    if (szError != NULL)
                    {
                         ErrorMessage (hwnd, szError, szTitleName) ;
                         szTitleName [0] = '\0' ;
                    }
                    else
                         bNeedSave = FALSE ;
                    
                    DoCaption (hwnd, szTitleName) ;
               }
               return 0 ;
               
          case IDM_APP_EXIT:
               SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ;
               return 0 ;
               
          case IDM_SEQUENCE_RUNNING:
                    // Begin sequence
               
               if (!DrumBeginSequence (hwnd))
               {
                    ErrorMessage (hwnd,
                         TEXT ("Could not start MIDI sequence -- ")
                         TEXT ("MIDI Mapper device is unavailable!"),
                         szTitleName) ;
               }
               else
               {
                    CheckMenuItem (hMenu, IDM_SEQUENCE_RUNNING,   MF_CHECKED) ;
                    CheckMenuItem (hMenu, IDM_SEQUENCE_STOPPED, MF_UNCHECKED) ;
               }
               return 0 ;
               
          case IDM_SEQUENCE_STOPPED:
                    // Finish at end of sequence
               
               DrumEndSequence (FALSE) ;
               return 0 ;
               
          case IDM_APP_ABOUT:
               DialogBox (hInst, TEXT ("AboutBox"), hwnd, AboutProc) ;
               return 0 ;
          }
          return 0 ;
                    
     case WM_LBUTTONDOWN:
     case WM_RBUTTONDOWN:
          hdc = GetDC (hwnd) ;
          
               // Convert mouse coordinates to grid coordinates
          
          x =     LOWORD (lParam) / cxChar - 40 ;
          y = 2 * HIWORD (lParam) / cyChar -  2 ;
          
               // Set a new number of beats of sequence
          
          if (x > 0 && x <= 32 && y < 0)
          {
               SetTextColor (hdc, RGB (255, 255, 255)) ;
               TextOut (hdc, (40 + drum.iNumBeats) * cxChar, 0, TEXT (":|"), 2);
               SetTextColor (hdc, RGB (0, 0, 0)) ;
               
               if (drum.iNumBeats % 4 == 0)
                    TextOut (hdc, (40 + drum.iNumBeats) * cxChar, 0,
                             TEXT ("."), 1) ;
               
               drum.iNumBeats = x ;
               
               TextOut (hdc, (40 + drum.iNumBeats) * cxChar, 0, TEXT (":|"), 2);
               
               bNeedSave = TRUE ;
          }
          
               // Set or reset a percussion instrument beat
          
          if (x >= 0 && x < 32 && y >= 0 && y < NUM_PERC)
          {
               if (message == WM_LBUTTONDOWN)
                    drum.dwSeqPerc[y] ^= (1 << x) ;
               else
                    drum.dwSeqPian[y] ^= (1 << x) ;
               
               DrawRectangle (hdc, x, y, drum.dwSeqPerc, drum.dwSeqPian) ;
               
               bNeedSave = TRUE ;
          }
          
          ReleaseDC (hwnd, hdc) ;
          DrumSetParams (&drum) ;
          return 0 ;
          
     case WM_HSCROLL:
               // Change the note velocity
          
          switch (LOWORD (wParam))
          {
          case SB_LINEUP:         drum.iVelocity -= 1 ;  break ;
          case SB_LINEDOWN:       drum.iVelocity += 1 ;  break ;
          case SB_PAGEUP:         drum.iVelocity -= 8 ;  break ;
          case SB_PAGEDOWN:       drum.iVelocity += 8 ;  break ;
          case SB_THUMBPOSITION:
               drum.iVelocity = HIWORD (wParam) ;
               break ;
               
          default:
               return 0 ;
          }
          
          drum.iVelocity = max (1, min (drum.iVelocity, 127)) ;
          SetScrollPos (hwnd, SB_HORZ, drum.iVelocity, TRUE) ;
          DrumSetParams (&drum) ;
          bNeedSave = TRUE ;
          return 0 ;
     
     case WM_VSCROLL:
               // Change the tempo
          
          switch (LOWORD (wParam))
          {
          case SB_LINEUP:         iTempo -=  1 ;  break ;
          case SB_LINEDOWN:       iTempo +=  1 ;  break ;
          case SB_PAGEUP:         iTempo -= 10 ;  break ;
          case SB_PAGEDOWN:       iTempo += 10 ;  break ;
          case SB_THUMBPOSITION:
               iTempo = HIWORD (wParam) ;
               break ;
               
          default:
               return 0 ;
          }
          
          iTempo = max (0, min (iTempo, 100)) ;
          SetScrollPos (hwnd, SB_VERT, iTempo, TRUE) ;
          
          drum.iMsecPerBeat = (WORD) (10 * pow (100, iTempo / 100.0)) ;
          
          DrumSetParams (&drum) ;
          bNeedSave = TRUE ;
          return 0 ;
     
     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;
          
          SetTextAlign (hdc, TA_UPDATECP) ;
          SetBkMode (hdc, TRANSPARENT) ;
          
               // Draw the text strings and horizontal lines
          
          for (i = 0 ; i < NUM_PERC ; i++)
          {
               MoveToEx (hdc, i & 1 ? 20 * cxChar : cxChar,
                             (2 * i + 3) * cyChar / 4, NULL) ;
               
               TextOut (hdc, 0, 0, szPerc [i], lstrlen (szPerc [i])) ;
               
               GetCurrentPositionEx (hdc, &point) ;
               
               MoveToEx (hdc,  point.x + cxChar, point.y + cyChar / 2, NULL) ;
               LineTo   (hdc,       39 * cxChar, point.y + cyChar / 2) ;
          }
          
          SetTextAlign (hdc, 0) ;
          
               // Draw rectangular grid, repeat mark, and beat marks
          
          for (x = 0 ; x < 32 ; x++)
          {
               for (y = 0 ; y < NUM_PERC ; y++)
                    DrawRectangle (hdc, x, y, drum.dwSeqPerc, drum.dwSeqPian) ;
               
               SetTextColor (hdc, x == drum.iNumBeats - 1 ?
                                   RGB (0, 0, 0) : RGB (255, 255, 255)) ;
               
               TextOut (hdc, (41 + x) * cxChar, 0, TEXT (":|"), 2) ;
               
               SetTextColor (hdc, RGB (0, 0, 0)) ;
               
               if (x % 4 == 0)
                    TextOut (hdc, (40 + x) * cxChar, 0, TEXT ("."), 1) ;
          }
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_USER_NOTIFY:
               // Draw the "bouncing ball"
          
          hdc = GetDC (hwnd) ;
          
          SelectObject (hdc, GetStockObject (NULL_PEN)) ;
          SelectObject (hdc, GetStockObject (WHITE_BRUSH)) ;
          
          for (i = 0 ; i < 2 ; i++)
          {
               x = iIndexLast ;
               y = NUM_PERC + 1 ;
               
               Ellipse (hdc, (x + 40) * cxChar, (2 * y + 3) * cyChar / 4,
                    (x + 41) * cxChar, (2 * y + 5) * cyChar / 4);
               
               iIndexLast = wParam ;
               SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
          }
          
          ReleaseDC (hwnd, hdc) ;
          return 0 ;
          
     case WM_USER_ERROR:
          ErrorMessage (hwnd, TEXT ("Can't set timer event for tempo"),
                        szTitleName) ;
          
                                             // fall through
     case WM_USER_FINISHED:
          DrumEndSequence (TRUE) ;
          CheckMenuItem (hMenu, IDM_SEQUENCE_RUNNING,   MF_UNCHECKED) ;
          CheckMenuItem (hMenu, IDM_SEQUENCE_STOPPED, MF_CHECKED) ;
          return 0 ;
          
     case WM_CLOSE:
          if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
               DestroyWindow (hwnd) ;
          
          return 0 ;
          
     case WM_QUERYENDSESSION:
          if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
               return 1L ;
          
          return 0 ;
          
     case WM_DESTROY:
          DrumEndSequence (TRUE) ;
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
int NEAR PASCAL CommandHandler(WORD wParam, LONG lParam)
{
/*  if (HIWORD(lParam) == EN_CHANGE)
  {
    if (focus(GetDlgCtrlID(LOWORD(lParam))) && players.player_numb > -1)
      bNeedSaveP = TRUE;
    else if (courses.course_numb > -1)
      bNeedSaveC = TRUE;
  }
*/
  switch (wParam)
  {
    case IDOK:
      SendMessage(hWnd, WM_COMMAND, IDD_RLIST, MAKELONG(0, LBN_DBLCLK));
      return NULL;

    case IDM_CONTENTS:
    case IDM_SEARCHON:
    case IDM_USE:
      MessageBox(hWnd, "Help to come soon!", szAppName, MB_OK | MB_ICONEXCLAMATION);
      return NULL;

    case IDM_ABOUT:  /* display about dialog box */
      lpfnGenericDlgProc = MakeProcInstance((FARPROC)AboutDlgProc, hInst);
      DialogBox(hInst, "ABOUT", hWnd, lpfnGenericDlgProc);
      FreeProcInstance(lpfnGenericDlgProc); /* Release memory */
      return NULL;

    case IDM_HANDICAP:
      lpfnGenericDlgProc = MakeProcInstance((FARPROC)HandicapDlgProc, hInst);
      DialogBox(hInst, "HANDICAP", hWnd, lpfnGenericDlgProc);
      FreeProcInstance(lpfnGenericDlgProc); /* Release memory */
      return NULL;

    case IDM_P_SEARCH:
      if (!get_player(hWnd, &players, p_index, r_index))
	return NULL;
      /* fall through */

    case IDM_C_SEARCH:
      if (!get_course(hWnd, &courses, c_index))
	return NULL;
	wWhich = wParam;
	lpfnGenericDlgProc = MakeProcInstance((FARPROC)SearchDlgProc, hInst);
	DialogBox(hInst, "SEARCH", hWnd, lpfnGenericDlgProc);
	FreeProcInstance(lpfnGenericDlgProc); /* Release memory */
	return NULL;

    case IDM_GRAPH:
      if (!get_player(hWnd, &players, p_index, r_index))
	return NULL;
      if (!get_course(hWnd, &courses, c_index))
	return NULL;
      if (IDYES == MessageBox(hWnd, "You must have Microsoft Excel\nto use this option.  Continue?",
			      szAppName, MB_YESNO | MB_ICONQUESTION))
	GraphData(&(players).player[p_index].p_scores, &courses);
      return NULL;

    case IDM_NEW_P: /* save current file and clear viewport */
      if (bNeedSaveP && IDCANCEL == AskAboutSave(hWnd, szFileTitleP, PLAYER_MARKER))
	return FALSE;
      szFileTitleP[NULL] = '\0';
      bNeedSaveP = FALSE;
      p_index = r_index = r_last = 0;
      players.player_numb = -1;
      clear_player(hWnd, hWndRList);
      DoCaption(hWnd, szFileTitleP, szFileTitleC);
      return NULL;

    case IDM_NEW_C:
      if (bNeedSaveC && IDCANCEL == AskAboutSave(hWnd, szFileTitleC, COURSE_MARKER))
	return FALSE;
      szFileTitleC[NULL] = '\0';
      bNeedSaveC = FALSE;
      c_index = 0;
      courses.course_numb = -1;
      clear_course(hWnd);
      DoCaption(hWnd, szFileTitleP, szFileTitleC);
      return NULL;

    case IDM_OPEN_P:  /* open an existing file */
      of_player.lpstrTitle = "Open Player";
      of_player.Flags      = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;

      if (!GetOpenFileName(&of_player))
	return FALSE;

      if (ReadFile(hWnd, szFileP, szFileTitleP, szFileTitleC, bNeedSaveP,
		   &players, &courses, PLAYER_MARKER))
      {
	bNeedSaveP = FALSE;
	p_index = 0;
	show_player(hWnd, hWndRList, &players, &p_index, &r_index, &r_last);
	DoCaption(hWnd, szFileTitleP, szFileTitleC);
      } /* if */
      return NULL;

    case IDM_OPEN_C:  /* open an existing file */
      of_course.lpstrTitle = "Open Course";
      of_course.Flags      = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;

      if (!GetOpenFileName(&of_course))
	return FALSE;

      if (ReadFile(hWnd, szFileC, szFileTitleP, szFileTitleC, bNeedSaveC,
		   &players, &courses, COURSE_MARKER))
      {
	bNeedSaveC = FALSE;
	c_index = 0;
	show_course(hWnd, &courses, &c_index);
	DoCaption(hWnd, szFileTitleP, szFileTitleC);
      } /* if */
      return NULL;

    case IDM_SAVE_P:  /* write current file */
      if (szFileTitleP[NULL])
      {
	if (!get_player(hWnd, &players, p_index, r_index))
	  return NULL;

	if (WriteFile(hWnd, szFileP, &players, &courses, PLAYER_MARKER,
		      p_index, r_index, c_index))
	{
	  bNeedSaveP = FALSE;
	  return 1;
	} /* if */
	return NULL;
      } /* if fall through */

    case IDM_SAVEAS_P:  /* change file name */
      if (!get_player(hWnd, &players, p_index, r_index))
	return NULL;

      of_player.lpstrTitle = "Save Player";
      of_player.Flags      = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;

      if (!GetSaveFileName(&of_player))
	return FALSE;

      if (WriteFile(hWnd, szFileP, &players, &courses, PLAYER_MARKER,
		    p_index, r_index, c_index))
      {
	bNeedSaveP = FALSE;
	DoCaption(hWnd, szFileTitleP, szFileTitleC);
      }
      return NULL;

    case IDM_SAVE_C:  /* write current file */
      if (szFileTitleC[NULL])
      {
	if (!get_course(hWnd, &courses, c_index))
	  return NULL;

	if (WriteFile(hWnd, szFileC, &players, &courses, COURSE_MARKER,
		      p_index, r_index, c_index))
	{
	  bNeedSaveC = FALSE;
	  return 1;
	} /* if */
	return NULL;
      } /* if fall through */

    case IDM_SAVEAS_C:  /* change file name */
      if (!get_course(hWnd, &courses, c_index))
	return NULL;

      of_course.lpstrTitle = "Save Course";
      of_course.Flags      = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;

      if (!GetSaveFileName(&of_course))
	return FALSE;

      if (WriteFile(hWnd, szFileC, &players, &courses, COURSE_MARKER,
		    p_index, r_index, c_index))
      {
	bNeedSaveC = FALSE;
	DoCaption(hWnd, szFileTitleP, szFileTitleC);
      }
      return NULL;

    case IDM_PRINT_P:  /* Print current file */
      if (!get_player(hWnd, &players, p_index, r_index))
	return NULL;
      PrintFile(hInst, hWnd, szFileTitleP[NULL] ? szFileTitleP : szUntitled);
      return NULL;

    case IDM_PRINT_C:  /* Print current file */
      if (!get_course(hWnd, &courses, c_index))
	return NULL;
      PrintFile(hInst, hWnd, szFileTitleC[NULL] ? szFileTitleC : szUntitled);
      return NULL;

    case IDM_EXIT:  /* Send a close message, and exit the program */
      SendMessage(hWnd, WM_CLOSE, NULL, 0L);
      return NULL;

    case IDM_UNDO:  /* Check for undo status */
      SendMessage(GetFocus(), WM_UNDO, 0, 0L);
      return 0;

    case IDM_CUT:  /* Send cut message */
      SendMessage(GetFocus(), WM_CUT, 0, 0L);
      return 0;

    case IDM_COPY: /* Send copy message */
      SendMessage(GetFocus(), WM_COPY, 0, 0L);
      return 0;

    case IDM_PASTE:  /* Send paste message */
      SendMessage(GetFocus(), WM_PASTE, 0, 0L);
      return 0;

    case IDM_CLEAR:  /* Send clear message */
      SendMessage(GetFocus(), WM_CLEAR, 0, 0L);
      return 0;

    case IDM_P_ADD:
      if (AddPlayer(hWnd, &players, &p_index, &r_index))
	bNeedSaveP = TRUE;
      return NULL;

    case IDM_R_ADD:
      if (AddRound(hWnd, &players, &p_index, &r_index, &r_last))
	bNeedSaveP = TRUE;
      return NULL;

    case IDM_C_ADD:
      if (AddCourse(hWnd, &courses, &c_index))
	bNeedSaveC = TRUE;
      return NULL;

    case IDM_P_SORT:
      if (!get_player(hWnd, &players, p_index, r_index))
	return NULL;
      qsort(players.player, players.player_numb+1, sizeof(players.player[0]),
	    compare_player);
      bNeedSaveP = TRUE;
      p_index = r_index = 0;
      show_player(hWnd, hWndRList, &players, &p_index, &r_index, &r_last);
      return NULL;

    case IDM_R_SORT:
      if (!get_player(hWnd, &players, p_index, r_index))
	return NULL;
      qsort(players.player[p_index].p_scores.history,
	    players.player[p_index].p_scores.round_numb+1,
	    sizeof(players.player[p_index].p_scores.history[0]),
	    compare_round);
      bNeedSaveP = TRUE;
      r_index = 0;
      show_player(hWnd, hWndRList, &players, &p_index, &r_index, &r_last);
      return NULL;

    case IDM_C_SORT:
      if (!get_course(hWnd, &courses, c_index))
	return NULL;
      qsort(courses.course, courses.course_numb, sizeof(courses.course[0]),
	    compare_course);
      bNeedSaveC = TRUE;
      c_index = 0;
      show_course(hWnd, &courses, &c_index);
      return NULL;

    case IDM_P_DELETE:
      if (players.player_numb > -1)
      {
	GetDlgItemText(hWnd, IDD_PLAST, (players).player[p_index].p_last, LAST_NAME_LENGTH+1);
	GetDlgItemText(hWnd, IDD_PFIRST, (players).player[p_index].p_first, FIRST_NAME_LENGTH+1);
	lstrcpy(szDelete, "Delete : ");
	lstrcat(szDelete, (LPSTR)players.player[p_index].p_first);
	lstrcat(szDelete, " ");
	lstrcat(szDelete, (LPSTR)players.player[p_index].p_last);
	if (IDYES == MessageBox(hWnd, szDelete, "Delete Player", MB_YESNO | MB_ICONQUESTION))
	{
	  bNeedSaveP = TRUE;
	  delete_player(hWnd, hWndRList, &players, &p_index, &r_index, &r_last);
	}
      } /* if */
      return NULL;

    case IDM_R_DELETE:
      if (players.player[p_index].p_scores.round_numb > -1)
      {
	convert_date(&players.player[p_index].p_scores.history[r_index].date,
		     szDate);
	lstrcpy(szDelete, (LPSTR)"Delete : ");
	lstrcat(szDelete, (LPSTR)players.player[p_index].p_scores.history[r_index].course_name);
	lstrcat(szDelete, "  ");
	lstrcat(szDelete, szDate);
	if (IDYES == MessageBox(hWnd, szDelete, "Delete Round", MB_YESNO | MB_ICONQUESTION))
	{
	  delete_round(hWnd, hWndRList, &players, &p_index, &r_index, &r_last);
	  bNeedSaveP = TRUE;
	} /* if */
      } /* if */
      return NULL;

    case IDM_C_DELETE:
      if (courses.course_numb > -1)
      {
	GetDlgItemText(hWnd, IDD_CNAME, (courses).course[c_index].c_name, COURSE_NAME_LENGTH+1);
	lstrcpy(szc_name, (courses).course[c_index].c_name);
	lpfnGenericDlgProc = MakeProcInstance((FARPROC)DeleteCourseDlgProc, hInst);
	DialogBox(hInst, "DELETEC", hWnd, lpfnGenericDlgProc);
	FreeProcInstance(DeleteCourseDlgProc); /* Release memory */
	if (bYesNo == IDYES)
	{
	  bNeedSaveC = TRUE;
	  delete_course(&courses, &c_index);
	  if (bDeleteRounds &&  delete_rounds(&players, szc_name))
	  {
	    bNeedSaveP = TRUE;
	    show_rounds(hWnd, hWndRList, &(players).player[p_index].p_scores, &r_index, &r_last, TRUE);
	  } /* if */
	  show_course(hWnd, &courses, &c_index);
	} /* if */
      } /* if */
      return NULL;

    case IDD_RLIST:
      switch(HIWORD(lParam))
      {
	case LBN_DBLCLK:
	  if ((players.player_numb == -1) ||
	      (players.player[p_index].p_scores.round_numb == -1))
	    return NULL;
	  lstrcpy(szNDTitle, "Change Course / Name Date");
	  convert_date(&players.player[p_index].p_scores.history[r_index].date, szDate);
	  get_date_elements(szDate, szmm, szdd, szyy);
	  lstrcpy(szc_name, (LPSTR)players.player[p_index].p_scores.history[r_index].course_name);
	  lpfnGenericDlgProc = MakeProcInstance((FARPROC)NameDateDlgProc, hInst);
	  DialogBox(hInst, "NAMEDATE", hWnd, lpfnGenericDlgProc);
	  FreeProcInstance(NameDateDlgProc); /* Release memory */
	  if (bNameDate == IDOK)
	  {
	    bNeedSaveP = TRUE;
	    players.player[p_index].p_scores.history[r_index].date =
	      string_to_date(szmm, szdd, szyy);
	    lstrcpy((LPSTR)players.player[p_index].p_scores.history[r_index].course_name,
		    szc_name);
	    show_rounds(hWnd, hWndRList, &(players).player[p_index].p_scores, &r_index, &r_last, FALSE);
	  } /* if */
	  return NULL;

	case LBN_SELCHANGE:
	  if ((int)SendMessage(hWndRList, LB_GETCURSEL, 0, 0L) == r_index)
	    break;
	  if (!get_round(hWnd, &players, p_index, r_index))
	  {
	    SendMessage(hWndRList, LB_SETCURSEL, r_index, 0L);
	    return NULL;
	  }
	  r_index = (int)SendMessage(hWndRList, LB_GETCURSEL, 0, 0L);
	  if (r_index != LB_ERR && r_index != r_last)
	  {
	    show_round(hWnd, players.player[p_index].p_scores.history[r_index].score);
	    r_last = r_index;
	  } /* if */
	  return NULL;
      }  /* switch (HIWORD(lParam)) */
      return NULL;

    default:
      return FALSE;
  }  /* switch (wParam) */
} /* CommandHandler */
/*
--------------------------------------------------------------------------
MainWndProc

This is the main procedure which processes each message.

Inputs:
  hwnd     - The handle to the parent window
  message  - Message sent from MainWndProc
  wParam   - Command from MainWndProc
  lParam   - Additional message information

Outputs:
  Used as an boolean for the current message
--------------------------------------------------------------------------
*/
int FAR PASCAL MainWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
  WORD           wTabStop;

  switch (message)
  {
    case WM_INITDIALOG:
      hWnd = hwnd;
      hWndPScroll = GetDlgItem(hWnd, IDD_PSCROLL);
      hWndCScroll = GetDlgItem(hWnd, IDD_CSCROLL);
      hWndRList   = GetDlgItem(hWnd, IDD_RLIST);
      of_course.lStructSize       = sizeof(OPENFILENAME);
      of_player.lStructSize       = sizeof(OPENFILENAME);
      of_course.hwndOwner         = hWnd;
      of_player.hwndOwner         = hWnd;
      of_course.lpstrFilter       = "Course(*.GLC)\0*.glc\0";
      of_player.lpstrFilter       = "Player(*.GLP)\0*.glp\0";
      of_course.lpstrCustomFilter = (LPSTR) NULL;
      of_player.lpstrCustomFilter = (LPSTR) NULL;
      of_course.nMaxCustFilter    = 0L;
      of_player.nMaxCustFilter    = 0L;
      of_course.nFilterIndex      = 0L;
      of_player.nFilterIndex      = 0L;
      of_course.lpstrFile         = szFileC;
      of_player.lpstrFile         = szFileP;
      of_course.nMaxFile          = sizeof(szFileC);
      of_player.nMaxFile          = sizeof(szFileP);
      of_course.lpstrFileTitle    = szFileTitleC;
      of_player.lpstrFileTitle    = szFileTitleP;
      of_course.nMaxFileTitle     = sizeof(szFileTitleC);
      of_player.nMaxFileTitle     = sizeof(szFileTitleP);
      of_course.lpstrInitialDir   = NULL;
      of_player.lpstrInitialDir   = NULL;
      of_course.nFileOffset       = 0;
      of_player.nFileOffset       = 0;
      of_course.nFileExtension    = 0;
      of_player.nFileExtension    = 0;
      of_course.lpstrDefExt       = "GLC";
      of_player.lpstrDefExt       = "GLP";
      p_index = r_index = r_last = c_index = 0;
      players.player_numb = courses.course_numb = -1;
      SetClassWord(hWnd, GCW_HICON, LoadIcon(hInst, "GOLFICON"));
      wTabStop = 4 + TAB_PIXEL_SETTING / (LOWORD(GetDialogBaseUnits()) / 4);
      SendMessage(hWndRList, LB_SETTABSTOPS, 1, (LONG) (WORD FAR *) &wTabStop);
      DoCaption(hWnd, szFileTitleP, szFileTitleC);
      return TRUE;

    case WM_INITMENU:  /* Set the menu items */
      DoMenu(wParam, &players, &courses, p_index, hWndRList);
      return TRUE;

    case WM_HSCROLL:  /* move to next or previous record */
      if (HIWORD(lParam) == hWndPScroll)
	move_player(hWnd, hWndRList, wParam, &players, &p_index, &r_index, &r_last);
      else if (HIWORD(lParam) == hWndCScroll)
	move_course(hWnd, wParam, &courses, &c_index);
      return TRUE;

    case WM_COMMAND:
      return CommandHandler(wParam, lParam);

    case WM_QUERYENDSESSION:
      if (bNeedSaveP && IDCANCEL == AskAboutSave(hWnd, szFileTitleP, PLAYER_MARKER))
	return 1;
      if (bNeedSaveC && IDCANCEL == AskAboutSave(hWnd, szFileTitleC, COURSE_MARKER))
	return 1;
      EndDialog(hWnd, NULL);
      return 0;

    case WM_CLOSE:  /* Check if file has been saved and close window */
      if (bNeedSaveP && IDCANCEL == AskAboutSave(hWnd, szFileTitleP, PLAYER_MARKER))
	return 0;
      if (bNeedSaveC && IDCANCEL == AskAboutSave(hWnd, szFileTitleC, COURSE_MARKER))
	return 0;
      EndDialog(hWnd, NULL);
      return 1;

    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;

    default:
      return FALSE;
  } /* switch (message) */
} /* MainWndProc */