Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
BIN
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/directx.ico
Normal file
BIN
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/directx.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/image1.bmp
Normal file
BIN
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/image1.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/image2.bmp
Normal file
BIN
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/image2.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
965
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/multimon.cpp
Normal file
965
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/multimon.cpp
Normal file
@@ -0,0 +1,965 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: Multimon.cpp
|
||||
//
|
||||
// Desc: This sample demonstrates the following programming concepts:
|
||||
// Writing code for a multi-monitor program that works on both Windows 95
|
||||
// (which does not support multiple monitors) and later Windows versions
|
||||
// (which do support it).
|
||||
// Using DirectDrawEnumerateEx to enumerate displays.
|
||||
// Working with separate device and focus windows.
|
||||
// Creating a video-memory sprite that spans multiple screens using multiple
|
||||
// copies of the image data.
|
||||
// Creating a system-memory sprite that spans multiple screens using a shared
|
||||
// copy of the image data.
|
||||
//
|
||||
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
// Multimon.h implements support of the multimon APIs for when your program
|
||||
// runs on Windows 95 systems. You can #include multimon.h in all your source
|
||||
// files that use multimon APIs, and you should #define COMPILE_MULTIMON_STUBS
|
||||
// in only one of your source files.
|
||||
#define COMPILE_MULTIMON_STUBS
|
||||
#include <windows.h>
|
||||
#include <multimon.h>
|
||||
#include <ddraw.h>
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines, constants, and global variables
|
||||
//-----------------------------------------------------------------------------
|
||||
#define NAME TEXT("MultiMon DirectDraw Sample")
|
||||
#define TITLE TEXT("MultiMon DirectDraw Sample")
|
||||
|
||||
|
||||
// An EnumInfo contains extra enumeration information that is passed
|
||||
// into the the DDEnumCallbackEx function.
|
||||
struct EnumInfo
|
||||
{
|
||||
BOOL bMultimonSupported;
|
||||
HRESULT hr;
|
||||
};
|
||||
|
||||
|
||||
// A Screen represents one display that images can be drawn to.
|
||||
struct Screen
|
||||
{
|
||||
GUID guid;
|
||||
TCHAR szDesc[200];
|
||||
HMONITOR hmon;
|
||||
LPDIRECTDRAW7 pDD;
|
||||
LPDIRECTDRAWSURFACE7 pDDSFront;
|
||||
LPDIRECTDRAWSURFACE7 pDDSBack;
|
||||
Screen* pScreenNext; // For linked list
|
||||
};
|
||||
|
||||
|
||||
// A ScreenSurface holds a DirectDrawSurface that can be used on a
|
||||
// particular screen.
|
||||
struct ScreenSurface
|
||||
{
|
||||
Screen* pScreen;
|
||||
LPDIRECTDRAWSURFACE7 pDDS;
|
||||
ScreenSurface* pScreenSurfaceNext; // For linked list
|
||||
// Could add a "last used time" field, which could be used to
|
||||
// determine whether this ScreenSurface should be
|
||||
// removed to free up video memory for another surface
|
||||
};
|
||||
|
||||
|
||||
// A Sprite holds generic information about a drawable image, and
|
||||
// a linked list of ScreenSurfaces (one per screen).
|
||||
struct Sprite
|
||||
{
|
||||
TCHAR szName[64]; // Name of this Sprite
|
||||
BOOL bForceSystem; // If TRUE, don't try to create video memory surfaces
|
||||
RECT rcSrc; // Dimensions of the image
|
||||
RECT rcDest; // Destination rectangle to draw image into
|
||||
LONG xVel; // X-Velocity for animation
|
||||
LONG yVel; // Y-Velocity for animation
|
||||
HBITMAP hbmImage; // Loaded bitmap image
|
||||
BYTE* pImageData; // Sharable pointer to DD surface data
|
||||
DDSURFACEDESC2 ddsd; // Holds pitch and pixel format of pImageData
|
||||
ScreenSurface* pScreenSurfaceFirst; // Linked list of ScreenSurfaces
|
||||
};
|
||||
|
||||
|
||||
Screen* g_pScreenFirst = NULL; // Linked list of Screens
|
||||
Sprite* g_pSprite1 = NULL; // A sprite that uses video memory where possible
|
||||
Sprite* g_pSprite2 = NULL; // A sprite that always uses system memory
|
||||
HWND g_hWnd = NULL; // Main app focus HWND
|
||||
BOOL g_bActive = TRUE; // Whether app is actively drawing
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function prototypes
|
||||
//-----------------------------------------------------------------------------
|
||||
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow );
|
||||
HRESULT CreateFocusWindow( HINSTANCE hInstance );
|
||||
HRESULT EnumerateScreens( VOID );
|
||||
BOOL WINAPI DDEnumCallback( GUID* pGuid, LPTSTR pszDesc, LPTSTR pszDriverName, VOID* pContext );
|
||||
BOOL WINAPI DDEnumCallbackEx( GUID* pGuid, LPTSTR pszDesc, LPTSTR pszDriverName, VOID* pContext, HMONITOR hmon );
|
||||
HRESULT InitScreens( VOID );
|
||||
HRESULT InitSprites( VOID );
|
||||
HRESULT MainLoop( VOID );
|
||||
LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
VOID UpdateFrame( VOID );
|
||||
BOOL RectIntersectsMonitor( RECT* prcSrc, HMONITOR hmon, RECT* prcScreen );
|
||||
HRESULT FindOrBuildScreenSurface( Sprite* pSprite, Screen* pScreen, ScreenSurface** ppScreenSurface );
|
||||
HRESULT SetupScreenSurfaceDDS( Sprite* pSprite, ScreenSurface* pScreenSurface );
|
||||
VOID DestroyScreenSurfaces( Sprite* pSprite );
|
||||
VOID Cleanup( VOID );
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: WinMain()
|
||||
// Desc: Initializes the application, then starts the main application loop.
|
||||
//-----------------------------------------------------------------------------
|
||||
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if( FAILED( hr = CreateFocusWindow(hInst) ) )
|
||||
return 0;
|
||||
|
||||
if( FAILED( hr = EnumerateScreens() ) )
|
||||
return 0;
|
||||
|
||||
if( FAILED( hr = InitScreens() ) )
|
||||
return 0;
|
||||
|
||||
if( FAILED( hr = InitSprites() ) )
|
||||
return 0;
|
||||
|
||||
if( FAILED( hr = MainLoop() ) )
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CreateFocusWindow()
|
||||
// Desc: Creates the focus window, which is the window which will receive user
|
||||
// input.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CreateFocusWindow( HINSTANCE hInstance )
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON1) );
|
||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = NAME;
|
||||
RegisterClass( &wc );
|
||||
|
||||
// Window style and dimensions are not important,
|
||||
// since they will be adjusted elsewhere.
|
||||
g_hWnd = CreateWindowEx( 0, NAME, TITLE, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, hInstance, NULL );
|
||||
|
||||
// It is important to call ShowWindow on this window to ensure
|
||||
// that any activity from other windows is obscured.
|
||||
ShowWindow( g_hWnd, SW_SHOW );
|
||||
|
||||
if( g_hWnd == NULL )
|
||||
return E_FAIL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: EnumerateScreens()
|
||||
// Desc: Creates a Screen structure for every appropriate screen in the user's
|
||||
// computer.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT EnumerateScreens()
|
||||
{
|
||||
HRESULT hr;
|
||||
EnumInfo enumInfo;
|
||||
|
||||
ZeroMemory( &enumInfo, sizeof(enumInfo) );
|
||||
enumInfo.bMultimonSupported = TRUE;
|
||||
|
||||
if( FAILED( hr = DirectDrawEnumerateEx( DDEnumCallbackEx,
|
||||
&enumInfo,
|
||||
DDENUM_ATTACHEDSECONDARYDEVICES ) ) )
|
||||
return hr;
|
||||
|
||||
// If something failed inside the enumeration, be sure to return that HRESULT
|
||||
if( FAILED(enumInfo.hr) )
|
||||
return enumInfo.hr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: DDEnumCallbackEx()
|
||||
// Desc: This callback function is called by DirectDraw once for each
|
||||
// available DirectDraw device. In this implementation, it saves the
|
||||
// GUID, device description, and hmon in a Screen structure for later use.
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL WINAPI DDEnumCallbackEx( GUID* pGuid, LPTSTR pszDesc, LPTSTR pszDriverName,
|
||||
VOID* pContext, HMONITOR hmon )
|
||||
{
|
||||
Screen* pScreenNew;
|
||||
EnumInfo* pEnumInfo = (EnumInfo*)pContext;
|
||||
GUID guidNull;
|
||||
|
||||
ZeroMemory( &guidNull, sizeof(GUID) );
|
||||
if( g_pScreenFirst != NULL &&
|
||||
g_pScreenFirst->guid == guidNull )
|
||||
{
|
||||
// We must be running on a multimon system, so get rid of the
|
||||
// guidNull Screen -- we want Screens with specific GUIDs.
|
||||
delete g_pScreenFirst;
|
||||
g_pScreenFirst = NULL;
|
||||
}
|
||||
|
||||
// Store all the info in a Screen structure
|
||||
pScreenNew = new Screen;
|
||||
if( pScreenNew == NULL )
|
||||
{
|
||||
pEnumInfo->hr = E_OUTOFMEMORY;
|
||||
return FALSE; // fatal error, stop enumerating
|
||||
}
|
||||
|
||||
ZeroMemory( pScreenNew, sizeof(Screen) );
|
||||
if( pGuid == NULL )
|
||||
pScreenNew->guid = guidNull;
|
||||
else
|
||||
pScreenNew->guid = *pGuid;
|
||||
|
||||
lstrcpy( pScreenNew->szDesc, pszDesc );
|
||||
pScreenNew->hmon = hmon;
|
||||
|
||||
// Insert Screen into global linked list
|
||||
if( g_pScreenFirst == NULL )
|
||||
{
|
||||
g_pScreenFirst = pScreenNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert at end of list
|
||||
Screen* pScreen = g_pScreenFirst;
|
||||
while( pScreen->pScreenNext != NULL )
|
||||
pScreen = pScreen->pScreenNext;
|
||||
|
||||
pScreen->pScreenNext = pScreenNew;
|
||||
}
|
||||
|
||||
return TRUE; // Keep enumerating
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: InitScreens()
|
||||
// Desc: For each Screen, this function initializes DirectDraw and sets up the
|
||||
// front buffer, back buffer, and a clipper. Many fullscreen DirectDraw
|
||||
// programs don't need to create clippers, but this one does so to allow
|
||||
// the sprites to be automatically clipped to each display.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT InitScreens( VOID )
|
||||
{
|
||||
HRESULT hr;
|
||||
Screen* pScreen = NULL;
|
||||
GUID* pGuid = NULL;
|
||||
DWORD dwFlags;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
LPDIRECTDRAWCLIPPER pClip = NULL;
|
||||
DDSCAPS2 ddsCaps;
|
||||
RECT rc;
|
||||
HRGN hrgn;
|
||||
BYTE rgnDataBuffer[1024];
|
||||
GUID guidNull;
|
||||
|
||||
ZeroMemory( &guidNull, sizeof(GUID) );
|
||||
|
||||
for( pScreen = g_pScreenFirst; pScreen != NULL; pScreen = pScreen->pScreenNext )
|
||||
{
|
||||
if( pScreen->guid == guidNull )
|
||||
pGuid = NULL;
|
||||
else
|
||||
pGuid = &pScreen->guid;
|
||||
|
||||
if( FAILED(hr = DirectDrawCreateEx( pGuid, (VOID**) &(pScreen->pDD),
|
||||
IID_IDirectDraw7, NULL ) ) )
|
||||
return hr;
|
||||
|
||||
if( pScreen == g_pScreenFirst)
|
||||
{
|
||||
dwFlags = DDSCL_SETFOCUSWINDOW;
|
||||
if( FAILED( hr = pScreen->pDD->SetCooperativeLevel( g_hWnd, dwFlags ) ) )
|
||||
return hr;
|
||||
|
||||
dwFlags = DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
|
||||
if( FAILED( hr = pScreen->pDD->SetCooperativeLevel(g_hWnd, dwFlags ) ) )
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwFlags = DDSCL_SETFOCUSWINDOW | DDSCL_CREATEDEVICEWINDOW |
|
||||
DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
|
||||
if( FAILED( hr = pScreen->pDD->SetCooperativeLevel(g_hWnd, dwFlags ) ) )
|
||||
return hr;
|
||||
}
|
||||
|
||||
if( FAILED( hr = pScreen->pDD->SetDisplayMode( 640, 480, 16, 0, 0 ) ) )
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Note: It is recommended that programs call SetDisplayMode on all screens
|
||||
// before creating/acquiring any DirectDrawSurfaces.
|
||||
for( pScreen = g_pScreenFirst; pScreen != NULL; pScreen = pScreen->pScreenNext )
|
||||
{
|
||||
ZeroMemory( &ddsd, sizeof(ddsd) );
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
|
||||
ddsd.dwBackBufferCount = 1;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE;
|
||||
|
||||
if( FAILED( hr = pScreen->pDD->CreateSurface( &ddsd,
|
||||
&pScreen->pDDSFront, NULL ) ) )
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
ZeroMemory( &ddsCaps, sizeof(ddsCaps) );
|
||||
ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
|
||||
if( FAILED( hr = pScreen->pDDSFront->GetAttachedSurface( &ddsCaps,
|
||||
&pScreen->pDDSBack ) ) )
|
||||
return hr;
|
||||
|
||||
ZeroMemory( &ddsd, sizeof(ddsd) );
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
if( FAILED( hr = pScreen->pDDSFront->GetSurfaceDesc( &ddsd ) ) )
|
||||
return hr;
|
||||
|
||||
SetRect( &rc, 0, 0, ddsd.dwWidth, ddsd.dwHeight );
|
||||
hrgn = CreateRectRgn( 0, 0, ddsd.dwWidth, ddsd.dwHeight );
|
||||
GetRegionData( hrgn, sizeof(rgnDataBuffer), (RGNDATA*)rgnDataBuffer );
|
||||
DeleteObject( hrgn );
|
||||
|
||||
if( FAILED( hr = pScreen->pDD->CreateClipper( 0, &pClip, 0 ) ) )
|
||||
return hr;
|
||||
|
||||
if( FAILED( hr = pClip->SetClipList( (RGNDATA*)rgnDataBuffer, 0 ) ) )
|
||||
{
|
||||
pClip->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
if( FAILED( hr = pScreen->pDDSFront->SetClipper( pClip ) ) )
|
||||
{
|
||||
pClip->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
if( FAILED( hr = pScreen->pDDSBack->SetClipper( pClip ) ) )
|
||||
{
|
||||
pClip->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
pClip->Release();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: InitSprites()
|
||||
// Desc: Initializes the objects that will be drawn and animated. Note that
|
||||
// the ScreenSurfaces are created when they are first needed, not here.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT InitSprites( VOID )
|
||||
{
|
||||
BITMAP bm;
|
||||
|
||||
// Initialize the first Sprite. This sprite will try to use video memory
|
||||
// on each Screen.
|
||||
g_pSprite1 = new Sprite;
|
||||
if( g_pSprite1 == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ZeroMemory( g_pSprite1, sizeof(Sprite) );
|
||||
lstrcpy( g_pSprite1->szName, TEXT("Sprite 1") );
|
||||
g_pSprite1->bForceSystem = FALSE; // This sprite will try to use video memory
|
||||
|
||||
g_pSprite1->hbmImage = (HBITMAP) LoadImage( GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDB_BITMAP1),
|
||||
IMAGE_BITMAP, 0, 0,
|
||||
LR_CREATEDIBSECTION );
|
||||
if( g_pSprite1->hbmImage == NULL )
|
||||
return E_FAIL;
|
||||
|
||||
GetObject( g_pSprite1->hbmImage, sizeof(bm), &bm ); // get size of bitmap
|
||||
SetRect( &g_pSprite1->rcSrc, 0, 0, bm.bmWidth, bm.bmHeight );
|
||||
|
||||
g_pSprite1->rcDest = g_pSprite1->rcSrc;
|
||||
g_pSprite1->xVel = 2; // Animation velocity
|
||||
g_pSprite1->yVel = 1;
|
||||
|
||||
// Initialize the second Sprite. This sprite will use system memory (and
|
||||
// share that memory between ScreenSurfaces whenever possible).
|
||||
g_pSprite2 = new Sprite;
|
||||
if( g_pSprite2 == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ZeroMemory( g_pSprite2, sizeof(Sprite) );
|
||||
lstrcpy(g_pSprite2->szName, TEXT("Sprite 2"));
|
||||
g_pSprite2->bForceSystem = TRUE; // This sprite will always use system memory
|
||||
g_pSprite2->hbmImage = (HBITMAP) LoadImage( GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDB_BITMAP2),
|
||||
IMAGE_BITMAP, 0, 0,
|
||||
LR_CREATEDIBSECTION );
|
||||
if( g_pSprite2->hbmImage == NULL )
|
||||
return E_FAIL;
|
||||
|
||||
GetObject( g_pSprite2->hbmImage, sizeof(bm), &bm ); // get size of bitmap
|
||||
SetRect( &g_pSprite2->rcSrc, 0, 0, bm.bmWidth, bm.bmHeight );
|
||||
g_pSprite2->rcDest = g_pSprite1->rcSrc;
|
||||
g_pSprite2->xVel = -1; // Animation velocity
|
||||
g_pSprite2->yVel = -2;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: MainLoop()
|
||||
// Desc: The main window message pump. When the application is active (not
|
||||
// minimized), it uses PeekMessage so that UpdateFrame can be called
|
||||
// frequently once all window messages are handled. When it is not
|
||||
// active, GetMessage is used instead to give more processing time to
|
||||
// other running programs.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT MainLoop( VOID )
|
||||
{
|
||||
MSG msg;
|
||||
BOOL bGotMsg;
|
||||
|
||||
while( TRUE )
|
||||
{
|
||||
if( g_bActive)
|
||||
bGotMsg = PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
|
||||
else
|
||||
bGotMsg = GetMessage( &msg, NULL, 0, 0);
|
||||
|
||||
if( msg.message == WM_QUIT)
|
||||
return S_OK;
|
||||
|
||||
if( bGotMsg)
|
||||
{
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
}
|
||||
else if( g_bActive)
|
||||
{
|
||||
UpdateFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: WindowProc()
|
||||
// Desc: Handler for window messages.
|
||||
//-----------------------------------------------------------------------------
|
||||
LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_SIZE:
|
||||
if( SIZE_MAXHIDE == wParam || SIZE_MINIMIZED == wParam )
|
||||
{
|
||||
g_bActive = FALSE;
|
||||
// Give window an icon and system menu on the taskbar when minimized
|
||||
SetWindowLong(hWnd, GWL_STYLE, WS_SYSMENU);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_bActive = TRUE;
|
||||
// Remove any window "decoration" when fullscreen
|
||||
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP);
|
||||
}
|
||||
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
|
||||
case WM_CLOSE:
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
|
||||
case WM_CHAR:
|
||||
DestroyWindow( hWnd );
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
Cleanup();
|
||||
PostQuitMessage( 0 );
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: UpdateFrame()
|
||||
// Desc: Renders one frame of animation, then updates the sprites for the next
|
||||
// frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID UpdateFrame( VOID )
|
||||
{
|
||||
HRESULT hr;
|
||||
Screen* pScreen;
|
||||
RECT rcScreen;
|
||||
ScreenSurface* pScreenSurface;
|
||||
DDBLTFX ddbltfx;
|
||||
|
||||
for( pScreen = g_pScreenFirst; pScreen != NULL; pScreen = pScreen->pScreenNext )
|
||||
{
|
||||
// Handle lost surfaces
|
||||
if( pScreen->pDDSFront->IsLost() == DDERR_SURFACELOST )
|
||||
{
|
||||
// Though surface memory can be reaquired via RestoreAllSurfaces, the
|
||||
// image contents will be undefined. So we destroy all the ScreenSurfaces
|
||||
// and let them be recreated as needed. Calling RestoreAllSurfaces
|
||||
// takes care of the remaining surfaces (the front and back buffers).
|
||||
DestroyScreenSurfaces( g_pSprite1 );
|
||||
DestroyScreenSurfaces( g_pSprite2 );
|
||||
hr = pScreen->pDD->RestoreAllSurfaces();
|
||||
}
|
||||
|
||||
// Clear the back buffer for this Screen
|
||||
ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
|
||||
ddbltfx.dwSize = sizeof(ddbltfx);
|
||||
ddbltfx.dwFillColor = 0; // Black
|
||||
hr = pScreen->pDDSBack->Blt( NULL, NULL, NULL,
|
||||
DDBLT_COLORFILL | DDBLT_WAIT,
|
||||
&ddbltfx );
|
||||
|
||||
// Draw first sprite
|
||||
if( RectIntersectsMonitor( &g_pSprite1->rcDest, pScreen->hmon, &rcScreen ) )
|
||||
{
|
||||
hr = FindOrBuildScreenSurface( g_pSprite1, pScreen, &pScreenSurface );
|
||||
|
||||
if( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = pScreen->pDDSBack->Blt( &rcScreen, pScreenSurface->pDDS,
|
||||
&g_pSprite1->rcSrc,
|
||||
DDBLT_WAIT, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw second sprite
|
||||
if( RectIntersectsMonitor( &g_pSprite2->rcDest, pScreen->hmon, &rcScreen ) )
|
||||
{
|
||||
hr = FindOrBuildScreenSurface( g_pSprite2, pScreen, &pScreenSurface );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = pScreen->pDDSBack->Blt( &rcScreen, pScreenSurface->pDDS,
|
||||
&g_pSprite2->rcSrc, DDBLT_WAIT, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flip all screens. This is done in a separate loop to make the flips happen
|
||||
// as close together in time as possible
|
||||
for( pScreen = g_pScreenFirst; pScreen != NULL; pScreen = pScreen->pScreenNext )
|
||||
{
|
||||
hr = pScreen->pDDSFront->Flip( NULL, DDFLIP_WAIT );
|
||||
}
|
||||
|
||||
// Animate Sprites for the next frame. The sprites are bounced against the
|
||||
// virtual desktop, which may cause them to partially or totally disappear
|
||||
// if your screens are set up in a way that is non-rectangular. Since the
|
||||
// animation is not the purpose of this demo, this simplified approach is used.
|
||||
RECT rcDesktop;
|
||||
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||
rcDesktop.right = rcDesktop.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||
rcDesktop.bottom = rcDesktop.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
|
||||
// Animate first sprite
|
||||
OffsetRect( &g_pSprite1->rcDest, g_pSprite1->xVel, g_pSprite1->yVel );
|
||||
|
||||
if( ( g_pSprite1->rcDest.right > rcDesktop.right && g_pSprite1->xVel > 0 ) ||
|
||||
( g_pSprite1->rcDest.left < rcDesktop.left && g_pSprite1->xVel < 0 ) )
|
||||
{
|
||||
g_pSprite1->xVel = -g_pSprite1->xVel;
|
||||
}
|
||||
|
||||
if( ( g_pSprite1->rcDest.bottom > rcDesktop.bottom && g_pSprite1->yVel > 0 ) ||
|
||||
( g_pSprite1->rcDest.top < rcDesktop.top && g_pSprite1->yVel < 0 ) )
|
||||
{
|
||||
g_pSprite1->yVel = -g_pSprite1->yVel;
|
||||
}
|
||||
|
||||
// Animate second sprite
|
||||
OffsetRect( &g_pSprite2->rcDest, g_pSprite2->xVel, g_pSprite2->yVel );
|
||||
if( ( g_pSprite2->rcDest.right > rcDesktop.right && g_pSprite2->xVel > 0 ) ||
|
||||
( g_pSprite2->rcDest.left < rcDesktop.left && g_pSprite2->xVel < 0 ) )
|
||||
{
|
||||
g_pSprite2->xVel = -g_pSprite2->xVel;
|
||||
}
|
||||
|
||||
if( ( g_pSprite2->rcDest.bottom > rcDesktop.bottom && g_pSprite2->yVel > 0 ) ||
|
||||
( g_pSprite2->rcDest.top < rcDesktop.top && g_pSprite2->yVel < 0 ) )
|
||||
{
|
||||
g_pSprite2->yVel = -g_pSprite2->yVel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: RectIntersectsMonitor()
|
||||
// Desc: Returns TRUE if prcSrc intersects the monitor hmon, and uses prcScreen
|
||||
// to store prcSrc in that monitor's local coordinate system.
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL RectIntersectsMonitor( RECT* prcSrc, HMONITOR hmon, RECT* prcScreen )
|
||||
{
|
||||
MONITORINFO mi;
|
||||
RECT rcIntersection;
|
||||
BOOL bIntersects;
|
||||
|
||||
ZeroMemory( &mi, sizeof(mi) );
|
||||
mi.cbSize = sizeof(mi);
|
||||
if( hmon == NULL )
|
||||
{
|
||||
SetRect( &mi.rcMonitor, 0, 0, GetSystemMetrics(SM_CXSCREEN),
|
||||
GetSystemMetrics(SM_CYSCREEN) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMonitorInfo(hmon, &mi);
|
||||
}
|
||||
|
||||
bIntersects = IntersectRect( &rcIntersection, prcSrc, &mi.rcMonitor );
|
||||
if( !bIntersects)
|
||||
return FALSE;
|
||||
|
||||
*prcScreen = *prcSrc;
|
||||
OffsetRect( prcScreen, -mi.rcMonitor.left, -mi.rcMonitor.top );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: FindOrBuildScreenSurface()
|
||||
// Desc: This is called when UpdateFrame needs to draw the image of a Sprite
|
||||
// onto a particular Screen. If a ScreenSurface already exists for this
|
||||
// Screen and Sprite, a pointer to it is returned. Otherwise, a new
|
||||
// ScreenSurface is created (and stored for future reuse).
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT FindOrBuildScreenSurface( Sprite* pSprite, Screen* pScreen,
|
||||
ScreenSurface** ppScreenSurface )
|
||||
{
|
||||
HRESULT hr;
|
||||
ScreenSurface* pScreenSurface;
|
||||
|
||||
for( pScreenSurface = pSprite->pScreenSurfaceFirst;
|
||||
pScreenSurface != NULL;
|
||||
pScreenSurface = pScreenSurface->pScreenSurfaceNext )
|
||||
{
|
||||
if( pScreenSurface->pScreen == pScreen )
|
||||
{
|
||||
// ScreenSurface exists for this Screen, so return a pointer to it
|
||||
*ppScreenSurface = pScreenSurface;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// No ScreenSurface for this Screen exists yet, so build one.
|
||||
pScreenSurface = new ScreenSurface;
|
||||
if( pScreenSurface == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ZeroMemory( pScreenSurface, sizeof(ScreenSurface) );
|
||||
|
||||
pScreenSurface->pScreen = pScreen;
|
||||
if( FAILED( hr = SetupScreenSurfaceDDS(pSprite, pScreenSurface ) ) )
|
||||
{
|
||||
delete pScreenSurface;
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Insert this new ScreenSurface in the Sprite's list:
|
||||
pScreenSurface->pScreenSurfaceNext = pSprite->pScreenSurfaceFirst;
|
||||
pSprite->pScreenSurfaceFirst = pScreenSurface;
|
||||
*ppScreenSurface = pScreenSurface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: SetupScreenSurfaceDDS()
|
||||
// Desc: Generates the DirectDrawSurface for a new ScreenSurface, and draws
|
||||
// the appropriate image into it.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT SetupScreenSurfaceDDS( Sprite* pSprite, ScreenSurface* pScreenSurface )
|
||||
{
|
||||
HRESULT hr;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
TCHAR sz[200];
|
||||
Screen* pScreen = pScreenSurface->pScreen;
|
||||
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
ddsd.dwWidth = pSprite->rcSrc.right - pSprite->rcSrc.left;
|
||||
ddsd.dwHeight = pSprite->rcSrc.bottom - pSprite->rcSrc.top;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
|
||||
|
||||
// Try to create the surface in video memory, unless the bForceSystem flag
|
||||
// is set on the Sprite.
|
||||
if( pSprite->bForceSystem ||
|
||||
FAILED( hr = pScreen->pDD->CreateSurface( &ddsd, &pScreenSurface->pDDS, NULL ) ) )
|
||||
{
|
||||
// Either this sprite has the bForceSystem flag, or creation in video
|
||||
// memory failed, so try to create the surface in system memory.
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
if( FAILED( hr = pScreen->pDD->CreateSurface( &ddsd, &pScreenSurface->pDDS, NULL ) ) )
|
||||
return hr;
|
||||
}
|
||||
|
||||
if( ddsd.ddsCaps.dwCaps == DDSCAPS_SYSTEMMEMORY &&
|
||||
pSprite->pImageData != NULL )
|
||||
{
|
||||
// See if we can reuse the image data that is stored in the Sprite.
|
||||
// As long as the pixel formats match, the image is reusable.
|
||||
ZeroMemory( &ddsd, sizeof(ddsd) );
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
if( FAILED( hr = pScreenSurface->pDDS->GetSurfaceDesc( &ddsd ) ) )
|
||||
return hr;
|
||||
|
||||
if( ddsd.ddpfPixelFormat.dwRGBBitCount == pSprite->ddsd.ddpfPixelFormat.dwRGBBitCount &&
|
||||
ddsd.ddpfPixelFormat.dwRBitMask == pSprite->ddsd.ddpfPixelFormat.dwRBitMask &&
|
||||
ddsd.ddpfPixelFormat.dwGBitMask == pSprite->ddsd.ddpfPixelFormat.dwGBitMask &&
|
||||
ddsd.ddpfPixelFormat.dwBBitMask == pSprite->ddsd.ddpfPixelFormat.dwBBitMask )
|
||||
{
|
||||
// Make the DDS use the Sprite's pImageData for its surface contents
|
||||
if( FAILED( hr = pScreenSurface->pDDS->SetSurfaceDesc( &pSprite->ddsd, 0 ) ) )
|
||||
return hr;
|
||||
|
||||
return S_OK; // All done! This DDS is ready to use.
|
||||
}
|
||||
// Otherwise, we can't share image data, and this system memory surface
|
||||
// will be for this Screen only.
|
||||
}
|
||||
|
||||
// Copy image data from the Sprite to this ScreenSurface:
|
||||
HDC hdc;
|
||||
if( FAILED( hr = pScreenSurface->pDDS->GetDC( &hdc ) ) )
|
||||
return hr;
|
||||
|
||||
HDC hdcImage;
|
||||
HGDIOBJ hgdiobjOld;
|
||||
DWORD dwWidth = pSprite->rcSrc.right - pSprite->rcSrc.left;
|
||||
DWORD dwHeight = pSprite->rcSrc.bottom - pSprite->rcSrc.top;
|
||||
|
||||
hdcImage = CreateCompatibleDC(NULL);
|
||||
hgdiobjOld = SelectObject(hdcImage, pSprite->hbmImage);
|
||||
StretchBlt( hdc, 0, 0, dwWidth, dwHeight,
|
||||
hdcImage, 0, 0, dwWidth, dwHeight, SRCCOPY );
|
||||
|
||||
SelectObject( hdcImage, hgdiobjOld ); // restore previously selected object
|
||||
DeleteDC( hdcImage );
|
||||
TextOut( hdc, 0, 0, pSprite->szName, lstrlen(pSprite->szName) );
|
||||
pScreenSurface->pDDS->ReleaseDC(hdc);
|
||||
|
||||
if( ddsd.ddsCaps.dwCaps == DDSCAPS_VIDEOMEMORY )
|
||||
{
|
||||
if( FAILED( hr = pScreenSurface->pDDS->GetDC( &hdc ) ) )
|
||||
return hr;
|
||||
|
||||
wsprintf( sz, TEXT("Video memory copy") );
|
||||
TextOut( hdc, 0, 20, sz, lstrlen(sz) );
|
||||
|
||||
wsprintf( sz, TEXT("for %s"), pScreen->szDesc );
|
||||
TextOut( hdc, 0, 40, sz, lstrlen(sz) );
|
||||
|
||||
pScreenSurface->pDDS->ReleaseDC(hdc);
|
||||
}
|
||||
else if( pSprite->pImageData == NULL )
|
||||
{
|
||||
// No shared copy exists yet, so create one using data in this
|
||||
// system memory surface.
|
||||
if( FAILED( hr = pScreenSurface->pDDS->GetDC( &hdc ) ) )
|
||||
return hr;
|
||||
|
||||
wsprintf(sz, TEXT("Shared System memory copy") );
|
||||
TextOut(hdc, 0, 20, sz, lstrlen(sz) );
|
||||
pScreenSurface->pDDS->ReleaseDC( hdc );
|
||||
|
||||
// Copy image to pImageData so it can be shared among ScreenSurfaces:
|
||||
if( SUCCEEDED( hr = pScreenSurface->pDDS->Lock( NULL, &ddsd,
|
||||
DDLOCK_READONLY | DDLOCK_WAIT,
|
||||
NULL ) ) )
|
||||
{
|
||||
pSprite->pImageData = new BYTE[ ddsd.lPitch * ddsd.dwHeight ];
|
||||
if( pSprite->pImageData != NULL )
|
||||
{
|
||||
// Store size, pitch, pixel format, and surface pointer info in Sprite
|
||||
pSprite->ddsd = ddsd;
|
||||
pSprite->ddsd.lpSurface = pSprite->pImageData;
|
||||
pSprite->ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH |
|
||||
DDSD_PIXELFORMAT | DDSD_LPSURFACE;
|
||||
|
||||
// Copy image data from DDS's surface memory to Sprite's buffer
|
||||
CopyMemory( pSprite->pImageData, ddsd.lpSurface,
|
||||
ddsd.lPitch * ddsd.dwHeight );
|
||||
}
|
||||
|
||||
pScreenSurface->pDDS->Unlock(NULL);
|
||||
|
||||
if( pSprite->pImageData != NULL )
|
||||
{
|
||||
// May as well make this ScreenSurface use the sharable copy too:
|
||||
if( FAILED( hr = pScreenSurface->pDDS->SetSurfaceDesc( &pSprite->ddsd, 0 ) ) )
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Shared copy exists, but attempt to use it failed (probably due to
|
||||
// mismatched pixel format), so indicate that this as a non-shared sysmem copy:
|
||||
if( FAILED( hr = pScreenSurface->pDDS->GetDC( &hdc ) ) )
|
||||
return hr;
|
||||
|
||||
wsprintf( sz, TEXT("System memory copy") );
|
||||
TextOut( hdc, 0, 20, sz, lstrlen(sz) );
|
||||
wsprintf( sz, TEXT("for %s"), pScreen->szDesc );
|
||||
TextOut( hdc, 0, 40, sz, lstrlen(sz) );
|
||||
|
||||
pScreenSurface->pDDS->ReleaseDC( hdc );
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: DestroyScreenSurfaces()
|
||||
// Desc: Destroys all ScreenSurfaces attached to the given Sprite. This is
|
||||
// called after restoring all surfaces (since image data may be lost) and
|
||||
// when preparing to exit the program.
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID DestroyScreenSurfaces( Sprite* pSprite )
|
||||
{
|
||||
ScreenSurface* pScreenSurface;
|
||||
ScreenSurface* pScreenSurfaceNext;
|
||||
|
||||
pScreenSurface = pSprite->pScreenSurfaceFirst;
|
||||
pSprite->pScreenSurfaceFirst = NULL;
|
||||
while( pScreenSurface != NULL )
|
||||
{
|
||||
pScreenSurfaceNext = pScreenSurface->pScreenSurfaceNext;
|
||||
pScreenSurface->pDDS->Release();
|
||||
|
||||
delete pScreenSurface;
|
||||
|
||||
pScreenSurface = pScreenSurfaceNext;
|
||||
}
|
||||
|
||||
if( pSprite->pImageData != NULL )
|
||||
{
|
||||
delete pSprite->pImageData;
|
||||
pSprite->pImageData = NULL;
|
||||
}
|
||||
|
||||
ZeroMemory( &pSprite->ddsd, sizeof(pSprite->ddsd) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Cleanup()
|
||||
// Desc: Releases all resources allocated during this program.
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID Cleanup( VOID )
|
||||
{
|
||||
if( g_pSprite1 != NULL )
|
||||
{
|
||||
DestroyScreenSurfaces(g_pSprite1);
|
||||
delete g_pSprite1;
|
||||
g_pSprite1 = NULL;
|
||||
}
|
||||
|
||||
if( g_pSprite2 != NULL )
|
||||
{
|
||||
DestroyScreenSurfaces(g_pSprite2);
|
||||
delete g_pSprite2;
|
||||
g_pSprite2 = NULL;
|
||||
}
|
||||
|
||||
Screen* pScreen;
|
||||
Screen* pScreenNext;
|
||||
|
||||
pScreen = g_pScreenFirst;
|
||||
g_pScreenFirst = NULL;
|
||||
|
||||
while( pScreen != NULL )
|
||||
{
|
||||
pScreenNext = pScreen->pScreenNext;
|
||||
|
||||
pScreen->pDDSBack->Release();
|
||||
pScreen->pDDSFront->Release();
|
||||
pScreen->pDD->RestoreDisplayMode();
|
||||
pScreen->pDD->SetCooperativeLevel(g_hWnd, DDSCL_NORMAL);
|
||||
pScreen->pDD->Release();
|
||||
|
||||
delete pScreen;
|
||||
pScreen = pScreenNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
127
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/multimon.dsp
Normal file
127
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/multimon.dsp
Normal file
@@ -0,0 +1,127 @@
|
||||
# Microsoft Developer Studio Project File - Name="multimon" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=multimon - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "multimon.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "multimon.mak" CFG="multimon - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "multimon - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "multimon - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "multimon - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 dxguid.lib odbc32.lib odbccp32.lib dxerr8.lib ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /machine:I386 /stack:0x200000,0x200000
|
||||
|
||||
!ELSEIF "$(CFG)" == "multimon - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 dxguid.lib odbc32.lib odbccp32.lib dxerr8.lib ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /stack:0x200000,0x200000
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "multimon - Win32 Release"
|
||||
# Name "multimon - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\multimon.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\multimon.rc
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\directx.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\image1.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\image2.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\readme.txt
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "multimon"=.\multimon.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
220
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/multimon.mak
Normal file
220
Library/dxx8/samples/Multimedia/DirectDraw/Multimon/multimon.mak
Normal file
@@ -0,0 +1,220 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Based on multimon.dsp
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=multimon - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to multimon - Win32 Debug.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "multimon - Win32 Release" && "$(CFG)" != "multimon - Win32 Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "multimon.mak" CFG="multimon - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "multimon - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "multimon - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "multimon - Win32 Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\multimon.exe"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\multimon.obj"
|
||||
-@erase "$(INTDIR)\multimon.res"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\multimon.exe"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"$(INTDIR)\multimon.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\multimon.res" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\multimon.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=dxguid.lib odbc32.lib odbccp32.lib dxerr8.lib ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\multimon.pdb" /machine:I386 /out:"$(OUTDIR)\multimon.exe" /stack:0x200000,0x200000
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\multimon.obj" \
|
||||
"$(INTDIR)\multimon.res"
|
||||
|
||||
"$(OUTDIR)\multimon.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "multimon - Win32 Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\multimon.exe" "$(OUTDIR)\multimon.bsc"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\multimon.obj"
|
||||
-@erase "$(INTDIR)\multimon.res"
|
||||
-@erase "$(INTDIR)\multimon.sbr"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\multimon.bsc"
|
||||
-@erase "$(OUTDIR)\multimon.exe"
|
||||
-@erase "$(OUTDIR)\multimon.ilk"
|
||||
-@erase "$(OUTDIR)\multimon.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\multimon.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\multimon.res" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\multimon.bsc"
|
||||
BSC32_SBRS= \
|
||||
"$(INTDIR)\multimon.sbr"
|
||||
|
||||
"$(OUTDIR)\multimon.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
|
||||
$(BSC32) @<<
|
||||
$(BSC32_FLAGS) $(BSC32_SBRS)
|
||||
<<
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=dxguid.lib odbc32.lib odbccp32.lib dxerr8.lib ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\multimon.pdb" /debug /machine:I386 /out:"$(OUTDIR)\multimon.exe" /pdbtype:sept /stack:0x200000,0x200000
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\multimon.obj" \
|
||||
"$(INTDIR)\multimon.res"
|
||||
|
||||
"$(OUTDIR)\multimon.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1"
|
||||
!IF EXISTS("multimon.dep")
|
||||
!INCLUDE "multimon.dep"
|
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "multimon.dep"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "multimon - Win32 Release" || "$(CFG)" == "multimon - Win32 Debug"
|
||||
SOURCE=.\multimon.cpp
|
||||
|
||||
!IF "$(CFG)" == "multimon - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\multimon.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "multimon - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\multimon.obj" "$(INTDIR)\multimon.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\multimon.rc
|
||||
|
||||
"$(INTDIR)\multimon.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) $(RSC_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "resource.h"
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "directx.ico"
|
||||
|
||||
IDB_BITMAP1 BITMAP DISCARDABLE "image1.bmp"
|
||||
IDB_BITMAP2 BITMAP DISCARDABLE "image2.bmp"
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sample Name: Multimon Sample
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
Description
|
||||
===========
|
||||
Multimon demonstrates some of the techniques that can be used in writing
|
||||
an application that takes advantage of multiple monitors.
|
||||
|
||||
Path
|
||||
====
|
||||
Source: DXSDK\Samples\Multimedia\DDraw\Multimon
|
||||
|
||||
Executable: DXSDK\Samples\Multimedia\DDraw\Bin
|
||||
|
||||
User's Guide
|
||||
============
|
||||
Multimon requires no user input. Press the ESC key to quit the program. Two
|
||||
"sprites" (moving surfaces) are created. "Sprite 1" uses video memory
|
||||
whenever possible. "Sprite 2" always uses system memory.
|
||||
|
||||
Programming Notes
|
||||
=================
|
||||
Multimon shows examples of a variety of topics:
|
||||
|
||||
- To use the multimonitor APIs such as GetMonitorInfo and MonitorFromRect
|
||||
on Windows 95, you can include the file multimon.h. In addition, in one
|
||||
of the C or C++ files, you need to #define COMPILE_MULTIMON_STUBS before
|
||||
including multimon.h. This allows the multimon APIs to return reasonable
|
||||
values when running on Windows 95. If your program does not need to be
|
||||
compatible with Windows 95, or if you do not use any of the multimonitor
|
||||
APIs, you do not need to include multimon.h or #define
|
||||
COMPILE_MULTIMON_STUBS.
|
||||
|
||||
- When enumerating DirectDraw devices, you can use either DirectDrawEnumerate
|
||||
or DirectDrawEnumerateEx. DirectDrawEnumerateEx is available on Windows 98
|
||||
systems with DX5 and later, and all other systems with DX6 or later.
|
||||
Because not all systems can be assumed to have DirectDrawEnumerateEx,
|
||||
DirectDraw was set up so programmers had to use LoadLibrary and
|
||||
GetProcAddress to check for its presence. In DX7, this restriction has
|
||||
been removed, so you can call DirectDrawEnumerateEx directly in code, but
|
||||
you should note that this will prevent your program from running on a system
|
||||
which does not have at least DX7 installed. This sample shows how to do the
|
||||
LoadLibrary/GetProcAddress technique, and how to fall back on
|
||||
DirectDrawEnumerate if DirectDrawEnumerateEx is not available.
|
||||
|
||||
- Fullscreen, multimonitor apps need to deal with focus and device windows.
|
||||
The focus window receives user input messages, and the device windows are
|
||||
used to cover each screen. This program shows how to call
|
||||
SetCooperativeLevel to properly create and assign these windows.
|
||||
|
||||
- Each screen gets its own DirectDraw interface, and DirectDrawSurfaces created
|
||||
on one DD interface cannot be used by any other DD interface. So creating
|
||||
graphics that span multiple monitors takes some extra work. This sample
|
||||
demonstrates two techniques. For best performance, video memory surfaces
|
||||
should be used. A separate video memory DirectDrawSurface must be created
|
||||
on each screen. For the cases where a system memory surface is required or
|
||||
desired, one must still create separate DirectDrawSurfaces for each screen,
|
||||
but they can be configured to point to the same surface data memory. The
|
||||
SetSurfaceDesc API can be used to accomplish this. Doing this has no
|
||||
performance impact, but it avoids unnecessary consumption of system memory.
|
||||
|
||||
- Blt calls usually fail when they would cause data to be written outside the
|
||||
borders of the destination surface. This failure can be avoided by attaching
|
||||
clipper objects to the destinations. This sample shows how to create a
|
||||
clipper for each screen and attach it to the front and back buffers so that
|
||||
the sprite surfaces can be blitted without being manually clipped by the
|
||||
application first.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#define IDI_ICON1 100
|
||||
#define IDB_BITMAP1 101
|
||||
#define IDB_BITMAP2 102
|
||||
Reference in New Issue
Block a user