SimplePlayerSDI.c

 /*
    File:       SimplePlayerSDI.c
 
    Written by: Keith Gurganus
 
    SimplePlayerSDI.exe is a SDI application that plays a movie with QuickTime.This is a part 
    of the QuickTime sample source code and is provided as is.
 
    Copyright:  © 1997 by Apple Computer, Inc., all rights reserved.
*/
 
#include "QTML.h"
#include "Movies.h"
#include "stdwin.h"
#include "SimplePlayerSDI.h"
#include "resource.h"
#include "QTime.h"
 
#define APPNAME "SimplePlayerSDI"
 
// Makes it easier to determine appropriate code paths:
#if defined (WIN32)
    #define IS_WIN32 TRUE
#else
    #define IS_WIN32 FALSE
#endif
#define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
#define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
#define IS_WIN95 (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
 
 
// Global Variables:
HINSTANCE           hInst;                  // Current instance
char                szAppName[] = APPNAME;  // The name of this application
char                szTitle[]   = APPNAME;  // The title bar text
MovieStuff          gMovieStuff;            // Movie Structure
WINDOWPOS           gOldWindowPos = {nil, nil, 0, 0, 0, 0, 0};
 
// Prototypes
ATOM MyRegisterClass(CONST WNDCLASS*);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
 
 
/*
    WinMain
*/
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    HANDLE hAccelTable;
 
    if (!hPrevInstance) {
        // Perform instance initialization:
        if (!InitApplication(hInstance)) {
            return (FALSE);
        }
    }
 
    // Initialize QuickTime Media Layer
    InitializeQTML(0);
 
    // Initialize QuickTime
    EnterMovies();
 
    // Perform application initialization:
    if (!InitInstance(hInstance, nCmdShow)) {
        return (FALSE);
    }
 
    hAccelTable = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_ACCELSIMPLESDI));
 
    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0)) {
        if (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    // Deinitialize QuickTime Media Layer
    ExitMovies();
 
    // Deinitialize QuickTime Media Layer
    TerminateQTML();
    
    return (msg.wParam);
 
    lpCmdLine; // This will prevent 'unused formal parameter' warnings
}
 
 
/*
    MyRegisterClass
*/
ATOM MyRegisterClass(CONST WNDCLASS *lpwc)
{
    HANDLE  hMod;
    FARPROC proc;
    WNDCLASSEX wcex;
 
    hMod = GetModuleHandle ("USER32");
    if (hMod != NULL) {
 
#if defined (UNICODE)
        proc = GetProcAddress (hMod, "RegisterClassExW");
#else
        proc = GetProcAddress (hMod, "RegisterClassExA");
#endif
 
        if (proc != NULL) {
 
            wcex.style         = lpwc->style;
            wcex.lpfnWndProc   = lpwc->lpfnWndProc;
            wcex.cbClsExtra    = lpwc->cbClsExtra;
            wcex.cbWndExtra    = lpwc->cbWndExtra;
            wcex.hInstance     = lpwc->hInstance;
            wcex.hIcon         = lpwc->hIcon;
            wcex.hCursor       = lpwc->hCursor;
            wcex.hbrBackground = lpwc->hbrBackground;
            wcex.lpszMenuName  = lpwc->lpszMenuName;
            wcex.lpszClassName = lpwc->lpszClassName;
 
            // Added elements for Windows 95:
            wcex.cbSize = sizeof(WNDCLASSEX);
            wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDR_SMALL));
            
            return (*proc)(&wcex);//return RegisterClassEx(&wcex);
        }
    }
    return (RegisterClass(lpwc));
}
 
 
/*
    InitApplication
*/
BOOL InitApplication(HINSTANCE hInstance)
{
    WNDCLASS  wc;
    HWND      hwnd;
 
    // Win32 will always set hPrevInstance to NULL, so lets check
    // things a little closer. This is because we only want a single
    // version of this app to run at a time
    hwnd = FindWindow (szAppName, NULL);
    if (hwnd) {
        // We found another version of ourself. Lets defer to it:
        if (IsIconic(hwnd)) {
            ShowWindow(hwnd, SW_RESTORE);
        }
        SetForegroundWindow (hwnd);
 
        return FALSE;
    }
 
    // Fill in window class structure with parameters that describe
    // the main window.
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = (WNDPROC)WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_BIG));
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = MAKEINTRESOURCE(IDR_SIMPLESDI);
    wc.lpszClassName = szAppName;
 
    // Register the window class and return success/failure code.
    if (IS_WIN95) {
        return MyRegisterClass(&wc);
    } else {
        return RegisterClass(&wc);
    }
}
 
/*
    InitInstance
*/
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    
    hInst = hInstance; // Store instance handle in our global variable
 
    // Create our window
    hWnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
        NULL, NULL, hInstance, NULL);
 
    if (!hWnd) {
        return (FALSE);
    }
 
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
 
    return (TRUE);
}
 
/*
    WndProc
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        int         wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC         hdc;
 
    if(GetNativeWindowPort(hWnd)){
        MSG msg;
        EventRecord macEvent;
        LONG thePoints = GetMessagePos();
 
        msg.hwnd = hWnd;
        msg.message = message;
        msg.wParam = wParam;
        msg.lParam = lParam;
        msg.time = GetMessageTime();
        msg.pt.x = LOWORD(thePoints);
        msg.pt.y = HIWORD(thePoints);
        WinEventToMacEvent(&msg, &macEvent);  // Convert the message to a QTML event
 
        // if we have a Movie Controller, pass the QTML event
        if(gMovieStuff.theMC)
            MCIsPlayerEvent(gMovieStuff.theMC,(const EventRecord *)&macEvent);
    }   
 
    switch (message) { 
        case WM_CREATE:
            memset(&gMovieStuff, 0, sizeof(MovieStuff));
            
            // Register this HWND with QTML
            CreatePortAssociation(hWnd, NULL, 0L);  
            gMovieStuff.theHwnd = hWnd;
            break;
 
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
 
            //Parse the menu selections:
            switch (wmId) {
    
                case IDM_ABOUT:
                    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, (DLGPROC)About);
                    break;
 
                case IDM_EXIT:
                    CloseMovie(&gMovieStuff);
                    DestroyPortAssociation((CGrafPort *)GetNativeWindowPort(hWnd));
                    DestroyWindow(hWnd);
                    break;
 
                case IDM_OPEN:
                    // Open a movie file
                    if(GetFile(gMovieStuff.filename)){
                        // Close any open movie
                        CloseMovie(&gMovieStuff);
                        OpenMovie(hWnd, &gMovieStuff);  // open the movie and size the window
                    }
                    break;
            }
            break;
 
        case WM_PAINT:
            hdc = BeginPaint (hWnd, &ps);
            // Add any additional drawing code here...
            EndPaint (hWnd, &ps);
            break;
            
        case WM_CLOSE:
            // Unregister the HWND with QTML
            CloseMovie(&gMovieStuff);
            DestroyPortAssociation((CGrafPtr)GetNativeWindowPort(hWnd));
            break;
 
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
 
        case WM_ENTERSIZEMOVE:
            {
                RECT    clientRect;
 
                GetClientRect(hWnd, & clientRect );
 
                gOldWindowPos.cx = clientRect.right - clientRect.left;
                gOldWindowPos.cy = clientRect.bottom - clientRect.top;
            }
            break;
        case WM_EXITSIZEMOVE:
            if ( gMovieStuff.theMovie )
            {
                RECT        clientRect;
                long        widthAdjust = 0, heightAdjust = 0;
 
                GetClientRect(hWnd, &clientRect );
                widthAdjust = (clientRect.right - clientRect.left) - gOldWindowPos.cx;
                heightAdjust = (clientRect.bottom - clientRect.top) - gOldWindowPos.cy;
                if ( widthAdjust || heightAdjust )
                {
                    Rect        controllerBox;
 
                    MCGetControllerBoundsRect(gMovieStuff.theMC, &controllerBox);
                    controllerBox.right += (short)widthAdjust;
                    controllerBox.bottom += (short)heightAdjust;
                    MCSetControllerBoundsRect(gMovieStuff.theMC, &controllerBox);
                }   
            }
            break;
    }
    return (DefWindowProc(hWnd, message, wParam, lParam));
}
 
/*
    About
*/
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            break;
    }
    return FALSE;
}