MAIN.C

//************************************************************************ 
//**
//** THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//** ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
//** TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
//** A PARTICULAR PURPOSE.
//**
//** Copyright 1993 - 1998 Microsoft Corporation. All Rights Reserved.
//**
//** main.c
//**
//** DESCRIPTION:
//** Performs window class registration, creations and message
//** polling.
//**
//************************************************************************

#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <stdio.h>

#define DECLARE_VARS
#include "idfedit.h"

/*+ ErrorBox ()
*
* bring up a message box with a string from the stringtable
*
*-=================================================================*/

#include <stdarg.h>

int WINAPI ErrorBox (UINT wStringID, UINT wType, ...)
{
char szFormat[512];
char szErr[512];
int cbSize;
va_list va;

va_start (va, wType);
cbSize = LoadString (hInst, wStringID, szFormat, NUMELMS(szFormat));
if (!cbSize)
wsprintf (szErr, "Error %d", wStringID);
else
wvsprintf (szErr, szFormat, va);
va_end (va);

return MessageBox (hWndMain, szErr, szApp, wType);
}

/*+ GetWindowPosFromIni
*
* retrieve the window position information from IDFEDIT.ini
*
*-=================================================================*/

static TCHAR cszProfile[] = TEXT ("MsIdfEd.ini");
static TCHAR cszSection[] = TEXT ("General");
static TCHAR cszWindow[] = TEXT ("Window");
static TCHAR cszWindowDef[] = TEXT ("");
static TCHAR cszWindowFmt[] = TEXT ("%d,%d,%d,%d");

BOOL WINAPI GetWindowPosFromIni (
LPRECT lprc)
{
TCHAR sz[100];
RECT rcScreen;
RECT rc;

GetPrivateProfileString (cszSection, cszWindow, cszWindowDef,
sz, NUMELMS (sz), cszProfile);

if ( ! SystemParametersInfo (SPI_GETWORKAREA, 0, &rcScreen, FALSE))
{
rcScreen.top = rcScreen.left = 0;
rcScreen.right = 640;
rcScreen.bottom = 480;
}

sscanf (sz, cszWindowFmt,
&lprc->left, &lprc->top,
&lprc->right, &lprc->bottom);

if ( ! IntersectRect (&rc, &rcScreen, lprc))
*lprc = rcScreen;

return ! IsRectEmpty (lprc);
}

/*+ SaveWindowPosToIni
*
* store the window position information in dragn.ini
*
*-=================================================================*/

BOOL WINAPI SaveWindowPosToIni (
LPRECT lprc)
{
TCHAR sz[100];

wsprintf (sz, cszWindowFmt,
lprc->left,
lprc->top,
lprc->right - lprc->left,
lprc->bottom - lprc->top);

WritePrivateProfileString (cszSection, cszWindow, sz, cszProfile);

return TRUE;
}

/*+ AboutDlgProc()
*
* callback function for the about dialog
*
*-=================================================================*/

BOOL CALLBACK AboutDlgProc (
HWND hWnd,
UINT wMsgID,
WPARAM wParam,
LPARAM lParam)
{
BOOL bRet = FALSE;

switch (wMsgID)
{
case WM_COMMAND:
{
UINT uID = GET_WM_COMMAND_ID(wParam, lParam);
//UINT Notify = GET_WM_COMMAND_CMD(wParam, lParam);
//HWND hWndCtl = GET_WM_COMMAND_HWND(wParam, lParam);

if (uID == IDOK || uID == IDCANCEL)
{
EndDialog(hWnd, uID);
bRet = TRUE;
}
break;
}
}

return bRet;
}

/*+ GetActiveData
*
* helper function, gets data space from the active MDI child
* window
*
*-=================================================================*/

static LPVOID GetActiveData ()
{
if (gs.pIDF && gs.pIDF->szFile[0])
return gs.pIDF;
return NULL;
}


/*+
*
*-======================================================================*/

STATICFN VOID WINAPI SetStandardCaption (VOID)
{
TCHAR sz[MAX_PATH + 20];
LoadString (hInst, IDS_CAPTION_BAR, sz, NUMELMS (sz));
lstrcat (sz, TEXT(" - "));
if (gs.szDefFile[0])
lstrcat (sz, gs.szDefFile);
else
{
UINT cb = lstrlen(sz);
LoadString (hInst, IDS_DEF_FILE_NAME, sz + cb, NUMELMS(sz) - cb);
}
SetWindowText (hWndMain, sz);
}

/*+ SaveAndCloseHeader
*
*-======================================================================*/

STATICFN BOOL SaveAndCloseHeader (
HWND hWnd,
BOOL bSaveAs)
{
LPIDFHEAD pIDF = gs.pIDF;
BOOL bRet;

if (!pIDF)
return TRUE;

if (!pIDF->szFile[0])
bSaveAs = TRUE;

if (pIDF->bReadOnly)
{
ErrorBox (IDS_ERR_READONLY, EB_INFO, gs.szDefFile);
bSaveAs = TRUE;
}

if (bSaveAs)
{
if (! PromptForIDFName(hWnd, gs.szDefFile, NULL, TRUE))
return FALSE;
}
else
lstrcpy (gs.szDefFile, pIDF->szFile);

if (!(bRet = SaveIDFToFile (pIDF, gs.szDefFile)))
ErrorBox (IDS_ERR_SAVE, EB_ERROR, gs.szDefFile);

SetStandardCaption();
return bRet;
}

/*+ QuerySaveChanges
*
*-======================================================================*/

BOOL QuerySaveChanges (
HWND hWnd,
BOOL bSetForeground)
{
UINT idBtn;
DWORD dwEB = EB_YNC;

if (!gs.pIDF)
return TRUE;

if (bSetForeground)
dwEB |= MB_SETFOREGROUND;

idBtn = ErrorBox (IDS_QUERY_SAVE, dwEB, gs.pIDF->szFile);
if (idBtn == IDYES)
return SaveAndCloseHeader (hWnd, FALSE);
else if (idBtn == IDCANCEL)
return FALSE;
return TRUE;
}

/*+ OpenHeader
*
*-======================================================================*/

STATICFN LONG WINAPI OpenHeader (
HWND hWnd,
BOOL bPrompt)
{
TCHAR szFile[MAX_PATH];
TCHAR szTitle[MAX_PATH];
LPIDFHEAD pIDF;

pIDF = gs.pIDF = &gs.idf;
if (gs.idf.bChanged && ! QuerySaveChanges (hWnd, FALSE))
return 0;

FreeIDFFile (gs.pIDF);

szFile[0] = 0;
if (bPrompt)
{
if ( ! PromptForIDFName (hWnd, szFile, szTitle, FALSE))
return 0;

lstrcpy (gs.szDefFile, szFile);
LoadIDFFromFile (pIDF, szFile);
}

if (!pIDF->hWndHead)
{
RECT rc;
GetClientRect (hWnd, &rc);

pIDF->hWndHead = CreateWindowEx (fdwExStyle | WS_EX_NOPARENTNOTIFY,
cszHdrClass,
"",
WS_CHILD | WS_VISIBLE,
0, 0, rc.right, rc.bottom,
hWnd,
(HMENU)1,
hInst,
pIDF);
}
else
{
Head_RefreshTree (pIDF->hWndHead);
}

SetStandardCaption();

return (LONG)pIDF->hWndHead;
}

/*+ MainCommands
*
*-=================================================================*/

LONG WINAPI MainCommands (
HWND hWnd,
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 1;
WORD wID = GET_WM_COMMAND_ID (wParam, lParam);
WORD wNotify = GET_WM_COMMAND_CMD (wParam, lParam);
HWND hWndCtl = GET_WM_COMMAND_HWND (wParam, lParam);

switch (wID)
{
case IDM_ABOUT:
return DialogBox (hInst,
MAKEINTRESOURCE(IDD_ABOUT),
hWnd,
AboutDlgProc);
break;

case IDM_HELP:
ErrorBox (IDS_ERR_NOHELP, MB_OK);
break;

case IDM_FILEOPEN:
lRet = OpenHeader (hWnd, TRUE);
break;

case IDM_FILENEW:
lRet = OpenHeader (hWnd, FALSE);
if (gs.pIDF)
{
NewIDFInstrum (gs.pIDF, NULL, "<untitled>");
gs.pIDF->bChanged = FALSE;
Head_RefreshTree (gs.pIDF->hWndHead);
}
break;

case IDM_FILESAVE:
case IDM_FILESAVEAS:
lRet = SaveAndCloseHeader (hWnd, wID == IDM_FILESAVEAS);
if (lRet)
{
// Saving has the side effect of also closing the file
// so we need to re-open it after the save completes
//
LoadIDFFromFile (gs.pIDF, gs.szDefFile);
}
Head_RefreshTree (gs.pIDF->hWndHead);
break;

case IDM_NEW_INSTRUMENT:
NewIDFInstrum (gs.pIDF, NULL, "<untitled>");
Head_RefreshTree (gs.pIDF->hWndHead);
break;

case IDM_FILEEXIT:
PostMessage (hWnd, WM_CLOSE, 0, 0);
break;

//case IDM_EDITUNDO:
// break;

case IDM_EDITCUT:
case IDM_EDITCOPY:
if (gs.pIDF && gs.pIDF->piSelect)
{
CopyInstrumToClip (gs.pIDF);
if (wID == IDM_EDITCUT)
DeleteInstrum (gs.pIDF);
}
break;

case IDM_EDITPASTE:
PasteInstrum (gs.pIDF);
break;

case IDM_EDITDELETE:
if (gs.pIDF && gs.pIDF->piSelect)
DeleteInstrum (gs.pIDF);
break;
}

return lRet;
}

/*+ MainWndProc
*
*-=================================================================*/

LRESULT CALLBACK MainWndProc (
HWND hWnd,
UINT wMsgID,
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 0; // return value from this routine

switch (wMsgID)
{
case WM_COMMAND:
lRet = MainCommands (hWnd, wParam, lParam);
break;

case WM_NOTIFY:
break;

case WM_SIZE:
if (gs.idf.hWndHead)
SetWindowPos (gs.idf.hWndHead, NULL,
0, 0, LOWORD(lParam), HIWORD(lParam),
SWP_NOZORDER);
break;

case WM_CREATE:
{
// send ourselves a command to create a document window.
//
PostMessage (hWnd, WM_COMMAND, IDM_FILEOPEN, 0);
}
break;

case WM_INITMENUPOPUP:
{
HMENU hPopup = (HMENU)wParam;
UINT uPos = (UINT) LOWORD (lParam);
BOOL fSystemMenu = HIWORD (lParam);
UINT uFirstID;

// if this is for the system menu, go no further.
//
if (fSystemMenu)
break;

// if this is the 'File' popup, do menu initialization
//
uFirstID = GetMenuItemID (hPopup, 0);
if (uFirstID == IDM_FILENEW)
{
EnableMenuItem (hPopup, IDM_FILESAVE, gs.pIDF ? MF_ENABLED : MF_GRAYED);
EnableMenuItem (hPopup, IDM_FILESAVEAS, gs.pIDF ? MF_ENABLED : MF_GRAYED);
}
else if (uFirstID == IDM_EDITCUT)
{
BOOL bCanPaste = IsClipboardFormatAvailable(CF_RIFF);
BOOL bCanCut = (gs.idf.piSelect != NULL);
// BOOL bCanUndo = FALSE;

// EnableMenuItem (hPopup, IDM_EDITUNDO, bCanUndo ? MF_ENABLED : MF_GRAYED);
EnableMenuItem (hPopup, IDM_EDITCUT, bCanCut ? MF_ENABLED : MF_GRAYED);
EnableMenuItem (hPopup, IDM_EDITDELETE, bCanCut ? MF_ENABLED : MF_GRAYED);
EnableMenuItem (hPopup, IDM_EDITCOPY, bCanCut ? MF_ENABLED : MF_GRAYED);
EnableMenuItem (hPopup, IDM_EDITPASTE, bCanPaste ? MF_ENABLED : MF_GRAYED);
}
break;
}

case WM_CLOSE:
case WM_QUERYENDSESSION:
{
WINDOWPLACEMENT wpl;

if (gs.idf.bChanged &&
!QuerySaveChanges (hWnd, wMsgID == WM_QUERYENDSESSION))
break;

//
// before we shutdown, save the current size and position
// of the window to the INI file.
//
ZeroMemory (&wpl, sizeof(wpl));
wpl.length = sizeof(wpl);
GetWindowPlacement (hWnd, &wpl);

SaveWindowPosToIni (&wpl.rcNormalPosition);

lRet = DefWindowProc (hWnd, wMsgID, wParam, lParam);
break;
}

case WM_DESTROY:
// close the app (by causing an exit from the message loop)
PostQuitMessage (0);
break;

default:
lRet = DefWindowProc (hWnd, wMsgID, wParam, lParam);
}
return lRet;
}

/*+ RegClasses ()
*
* Registers all window classes that will be
* used in this application.
*
* Called from WinMain
*
* returns: the return value of the call to RegisterClass ()
* TRUE if successful registration
* FALSE if registration failed
*
*-=================================================================*/

static CONST TCHAR cszMainClass[] = "Main";

extern LRESULT WINAPI ViewWndProc (HWND, UINT, WPARAM, LPARAM);

BOOL WINAPI RegClasses (
HANDLE hInstance)
{
WNDCLASS wc;
TCHAR ach[2];

LoadString(hInstance, IDS_IS_RTL, ach, sizeof(ach)/sizeof(ach[0]));
fdwExStyle = (ach[0] == '1') ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0;

//InitCommonControls();

// register the main window class
//
ZeroMemory (&wc, sizeof(wc));
wc.lpszClassName = cszMainClass;
wc.lpfnWndProc = MainWndProc;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDR_MAIN));
wc.lpszMenuName = MAKEINTRESOURCE (IDR_MAIN);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wc.hInstance = hInstance;
if (!RegisterClass (&wc))
return FALSE;

// register the idf instrument window class
//
ZeroMemory (&wc, sizeof(wc));
wc.lpszClassName = cszHdrClass;
wc.lpfnWndProc = HeadWndProc;
wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDR_MAIN));
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE+1);
wc.hInstance = hInstance;
if (!RegisterClass (&wc))
return FALSE;

ZeroMemory (&wc, sizeof(wc));
wc.lpszClassName = cszInstrumClass;
wc.lpfnWndProc = ViewWndProc;
wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDR_INSTRUM));
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wc.hInstance = hInstance;
if (!RegisterClass (&wc))
return FALSE;

return TRUE;
}

/*+ CreateMainWindow ()
*
* Creates the main window for the application.
*
* Called from WinMain
*
* returns: a valid window handle if CreateWindow succeeds
* or NULL if CreateWindow Fails
*
*-=================================================================*/

HWND WINAPI CreateMainWindow (
int nCmdShow)
{
HWND hWnd;
TCHAR szTitle[100];
RECT rc;

LoadString (hInst, IDS_CAPTION_BAR, szTitle, NUMELMS (szTitle));

// get x, y, cx, cy positions from ini files
//
if ( ! GetWindowPosFromIni (&rc))
rc.left = rc.right = CW_USEDEFAULT;

hWnd = CreateWindowEx (fdwExStyle, // RTL style
cszMainClass, // class
szTitle, // title
WS_OVERLAPPEDWINDOW,
rc.left,
rc.top, // position: x,y
rc.right,
rc.bottom, // size: width, height
NULL, // parent
NULL, // menu or child id
hInst, // instance
NULL); // params to pass on to WM_CREATE

if (hWnd)
ShowWindow (hWnd, nCmdShow);

return hWnd;
}

/*+ WinMain ()
*
*-=================================================================*/

int WINAPI WinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
MSG msg; // temp for current message
HACCEL hAccel;

// save off instance handle in a global. THIS MUST BE DONE FIRST!
// also load the application name into a global string
//
hInst = hInstance;
LoadString (hInst, IDS_APPNAME, szApp, NUMELMS (szApp));

// if this is not the first instance, register the class
// if class registration fails, put up a message box and quit
if (!RegClasses (hInstance))
return ErrorBox (IDS_ERR_REGCLASSES, EB_FATAL);

hAccel = LoadAccelerators (hInst, MAKEINTRESOURCE(IDR_MAIN));

// create the main window and save it's window handle in a global
// if the creation fails, put up a message box and quit.
//
hWndMain = CreateMainWindow (nCmdShow);
if ( !hWndMain)
return ErrorBox (IDS_ERR_CREATEMAIN, EB_FATAL);

// loop forever getting messages and dispatching them
// to the appropriate window.
//
while (GetMessage (&msg, NULL, 0,0))
{
if (TranslateAccelerator (hWndMain, hAccel, &msg))
continue;

TranslateMessage (&msg);
DispatchMessage (&msg);
}

// return the wParam of the last message (the QUIT message)
//
return msg.wParam;
}