Programming

Visual Basic is quite easy to use, but you could use BASIC (language) to make such things I believe. A coding technician can probably answer a lot more detailed.


I don't know whether to :rolleyes:, or :shake:, or:spank: .

:lol:

MarkC1 said:
that's not true....the hardest part is the graphics

Tell me about it... I tried making my own games back in the 90s. Next minute, Windows 95 comes along and Turbo Pascal becomes incompatible. Next minute, WinXP comes along, and ModeX is virtually incompatible (might be some work-arounds now, though). Then there's DirectX and Windows graphics API programing. :sad:

(atleast in DOS, it was a bit easier... now everyone wants 3D)

-----------------------------------------------------------------

But, the OP was only asking about Tic Tac Toe or a text-game. Those are simple. :p (ok, so Tic-Tac-Toe needs an AI, but that's optional if you're only doing a 2 player game with no AI.)

Ok, I guess the first question would be, "How much programming do you know right now?". If you really want to get your feet wet quickly, then maybe Visual Basic is for you (I'd recommend Visual Basic 6 actually, since you don't have to worry about .NET requirements, but it's probably not even sold anymore. Next up would be DevC++, a free C++ compilier, which is text-based by default.).


Here's something a teacher of mine told us once -- "Resist the temptation to code!". As with any software (game or not), you need a well, gameplan.

What are the requirements?
Do you have the needed resources for those requirements?
What are the objects (variables, functions, interface)?
What actions can be taken?
What are the rules?
What rules, actions and objects (that's being rather broad on purpose) do you need, and can do without? (i.e., creating the "wishlist")
How is your code going to be structured? Putting all of your code into one function is a huge nono, and is called speghetti-code.

"Graphics" (ASCII text) in text-mode is quite easy. For starters, you can make what's called a "Class" (Visual Basic 6 doesn't have these, but uses Modules, which aren't true classes, as you can instantiate them - i.e., MyClass c = New MyClass(/*put whatever vars you want to init here*/);), and put things like: (note: I'm gonna use the Visual Basic way here - let's use the Tic Tac Toe example)

DrawTicTacToeBoard()
PlaceXOMarker(XorO as boolean)
DrawPrompt(msg as string)
DrawScores()
DrawFinalScreen(WinOrLose as boolean)
DrawIntroScreen()

An AI class might be something like:

PlaceXOMarker(XorO as boolean) (yes, you can have the same function name in multiple classes - to have the same name in the same class, you need an override or operator overload type keyword - these are fun! :D)
FindBestSquare() as integer (this returns a value from 0-8 -- or 1-9)

And so on.


Your code would use the above classes. Also, don't put too much stock into listening how people have made their game "in just 5 minutes!" or, "just under a day". It depends on the tools they have. If you're starting from scratch, a game like TicTacToe might take a couple of days. If you have a gaming engine, then it might take a few minutes. Skill helps, too, and testing takes longer.



There's also pros and cons to using different compiliers.


Pascal or Turbo Pascal (now called Delphi I believe) - Somewhat outdated, and I don't know of what the more recent ones can do.
Borland C++ - Atleast the version I have (4.52) can't do "modern" programming like shortcuts for typecasting, and other neat things. It is outdated on the Operating System front -- made for Win 98 and below.
Visual Basic 6 - Great for making simple programs quickly, but doesn't really have the "omph" needed for making really complex games.
DevC++ - Can handle many of the freeware engines (Allegro, OpenGL) quite nicely.
Visual Studio .NET - Needs the .NET framework, which can be anywhere from 20-150+ megs in size. It's actually funny seeing a 4K file lugging around a 150 meg platform. You can still use Visual C++ without .NET, though, but to make 3D graphics, you'll need DirectX, and other things. There are graphics engines out there, at the tune of $50,000 on up.
 
Chieftess said:
"Resist the temptation to code!".
Indeed! As a professional software developer with over 20 years experience, I can agree with this one. I have found that actual "coding" usually is less than a third of the process; often less than a quarter.

Getting the requirements (what, exactly is the program supposed to do?) and the design (how is it going to do it?) right takes most of it. And let's not forget testing, too. ;)

And don't forget about Java, Chieftess. It's free, and multi-platform. It has some good free IDEs, too. (I prefer NetBeans, myself, but there are other good free ones out there, like Eclipse.)
 
That must the reason why strategy gamers all over the world are contended with level of AI in the games and why game graphics in general have improved so little in the last few years :mischief:

uhh graphics have not improved that much the past few years... Dx9.0c has been out since like 2005...can you point out a current game that blows away any game made in '05?
 
uhh graphics have not improved that much the past few years... Dx9.0c has been out since like 2005...can you point out a current game that blows away any game made in '05?

That recent game with really realistic graphics that I can't think of the name? (you see the ocean, a beach, and jungle, zoom in, and you see a shack - there's a site that shows the graphics, and the real world model they used). :)
 
Tell me about it... I tried making my own games back in the 90s. Next minute, Windows 95 comes along and Turbo Pascal becomes incompatible. Next minute, WinXP comes along, and ModeX is virtually incompatible (might be some work-arounds now, though). Then there's DirectX and Windows graphics API programing. :sad:
Although to be fair, DirectX has been fairly stable for a while now. They continually release new APIs that are sometimes incompatible with old APIs, but the old APIs continue to work. I recently ran a Direct3D project on Vista that I made back in 2000 and it still works.

Visual Studio .NET - Needs the .NET framework, which can be anywhere from 20-150+ megs in size. It's actually funny seeing a 4K file lugging around a 150 meg platform. You can still use Visual C++ without .NET, though, but to make 3D graphics, you'll need DirectX, and other things.
That's not true. .NET 2.0 is about 80 MB installed. The redistributable is ~23 MB. Visual Studio and Visual C++ IDEs themselves need .NET, but you can write programs with them that do not require .NET.
 
uhh graphics have not improved that much the past few years... Dx9.0c has been out since like 2005...can you point out a current game that blows away any game made in '05?

I guess that few > 2. Morrowind came out in 2002 and Oblivion in 2006. During those four years the graphics did change quite radically. Same thing when comparing Dungeon Siege (2002) and Titan Quest (2006). Also in the line of your 'blows away' request I presume you can name a game or a few that has AI unlike anything seen 2005 (or even 2002) and also new games with level of content (quality, diversity and size) that easily surpasses all games from 2005 (or even 2002) backwards.

I'm not claiming that graphics improve on their own and there's no challenge in making them - I'm just saying that it's not the most diffucult part of making quality games.
 
uhh graphics have not improved that much the past few years... Dx9.0c has been out since like 2005...can you point out a current game that blows away any game made in '05?
You haven't done much looking then. Even compare things like the original HL2 to the latest incarnation of the Source engine running HL2:Ep1 - almost a night and day difference. And that's not even scratching the surface of DX10 engines.
 
Java is actually very nice to learn if you use the Eclipse IDE. It's good for those who don't want to be overwhelmed at the start, and if you have an actual person to help get you started, you're fine.
 
Say I want to make an executable with Visual Basic, how should I start doing that? (I have some very basic knowledge of Visual Basic for Applications). I'm not looking at writing a specific program yet, just trying to learn how to start doing it.
 
Say I want to make an executable with Visual Basic, how should I start doing that? (I have some very basic knowledge of Visual Basic for Applications). I'm not looking at writing a specific program yet, just trying to learn how to start doing it.

Sub Page_Load()
msgbox "Hello World"
End Sub

Compile. :p

(Really, that's about as simple as it gets in making a simple executable)
 
You want Tic-Tac-Toe, I give you Tic-Tac-Toe in C++. It's probably not the most elegant way to do it, but it's just a product of a bored Sat afternoon when it's too damn hot & humid to do anything outside, and it lacks all the planning and etc that Padma and Chieftess were lecturing about. ;)

Code:
#include <iostream>
#include <conio.h>
#include <windows.h>

int menu( );
void clrScr( const HANDLE& );
void gameFunc( const HANDLE& );
void writeBoard( const HANDLE&, const char[3][3], const bool&, COORD&, const bool& );
int getInput( const HANDLE&, char[3][3], const bool&, COORD& );
bool checkWin( const char[3][3], bool&, int& );
void printWin( const int& );

int main( )
{
	HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
	
	while ( true )
	{
		switch ( menu( ) )
		{
		// start game
		case 1:
			clrScr( hStdOut );
			gameFunc( hStdOut );
			clrScr( hStdOut );
			break;
		// show instructions
		case 2:
			clrScr( hStdOut );
			std::cout << "Use the WASD keys to move the cursor to the desired position,\n"
				  << "and press Enter to select the location.  You may press Esc\n"
				  << "at any time to exit the game.\n\n"
				  << "Press any key to return to the main menu.\n";
			_getch( );
			clrScr( hStdOut );
			break;
		// exit
		case 3:
			return EXIT_SUCCESS;
		default:
			clrScr( hStdOut );
			std::cout << "Unknown selection\n\n";
			break;
		}
	}
}

int menu( )
{
	int input;

	std::cout << "Welcome to Tic-Tac-Toe!\n"
		  << "1. New Game\n"
		  << "2. Show Instructions\n"
		  << "3. Exit\n\n";
	std::cin >> input;

	if ( ! std::cin )
	{
		std::cin.clear( );
		std::cin.ignore( );
	}

	return input;
}

void clrScr( const HANDLE& hStdOut )
{
	COORD coord = { 0, 0 };
  DWORD count;
  CONSOLE_SCREEN_BUFFER_INFO csbi;

  GetConsoleScreenBufferInfo( hStdOut, &csbi );
  FillConsoleOutputCharacter( hStdOut, ' ', ( csbi.dwSize.X * csbi.dwSize.Y ), coord, &count );
  SetConsoleCursorPosition( hStdOut, coord );
}

void gameFunc( const HANDLE& hStdOut )
{
	char board[3][3] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
	COORD cursPos = { 0, 0 };
	int winner = 0;
	bool player = true;
	// player == true for player 1 (X)
	// player == flase for player 2 (O)

	do
	{
		clrScr( hStdOut );
		writeBoard( hStdOut, board, player, cursPos, false );
		if ( getInput( hStdOut, board, player, cursPos ) < 0 )
			return;		
	} while ( ! checkWin( board, player, winner ) );

	clrScr( hStdOut );
	printWin( winner );
	clrScr( hStdOut );
}

void writeBoard( const HANDLE& hStdOut, const char board[3][3], const bool& player, COORD& cursPos, const bool& error )
{
	if ( player )
		std::cout << "Player 1's move:\n";
	else
		std::cout << "Player 2's move:\n";
	std::cout << std::endl
						<< "  " << board[0][0] << "  |  " << board[1][0] << "  |  " << board[2][0] << std::endl
						<< " ---------------\n"
						<< "  " << board[0][1] << "  |  " << board[1][1] << "  |  " << board[2][1] << std::endl
						<< " ---------------\n"
						<< "  " << board[0][2] << "  |  " << board[1][2] << "  |  " << board[2][2] << std::endl
						<< std::endl;
	
	if ( player )
		std::cout << "Place a \"X\"\n";
	else
		std::cout << "Place an \"O\"\n";

	if ( error )
		std::cout << std::endl
							<< "Location is already filled...\n";

	cursPos.X = 2;
	cursPos.Y = 2;
	SetConsoleCursorPosition( hStdOut, cursPos );
}

int getInput( const HANDLE& hStdOut, char board[3][3], const bool& player, COORD& cursPos )
{
	int input,
			tempX,
			tempY;

	while ( true )
	{
		if ( _kbhit( ) )
		{
			input = _getch( );
			switch ( input )
			{
			// Enter; set position
			case 13:
				if ( cursPos.X == 2 )
					tempX = 0;
				else if ( cursPos.X == 8 )
					tempX = 1;
				else if ( cursPos.X == 14 )
					tempX = 2;

				if ( cursPos.Y == 2 )
					tempY = 0;
				else if ( cursPos.Y == 4 )
					tempY = 1;
				else if ( cursPos.Y == 6 )
					tempY = 2;

				clrScr( hStdOut );

				if ( board[tempX][tempY] != NULL )
					writeBoard( hStdOut, board, player, cursPos, true );
				else
				{
					if ( player )
						board[tempX][tempY] = 'X';
					else
						board[tempX][tempY] = 'O';
					writeBoard( hStdOut, board, player, cursPos, false );
					return 0;
				}
				break;
			// Esc; quit
			case 27:
				return -1;
			// W; move up
			case 87:
			case 119:
				if ( cursPos.Y == 2 )
					break;
				else
					cursPos.Y -= 2;
				break;
			// A; move left
			case 65:
			case 97:
				if ( cursPos.X == 2 )
					break;
				else
					cursPos.X -= 6;
				break;
			// S; move down
			case 83:
			case 115:
				if ( cursPos.Y == 6 )
					break;
				else
					cursPos.Y += 2;
				break;
			// D; move right
			case 68:
			case 100:
				if ( cursPos.X == 14 )
					break;
				else
					cursPos.X += 6;
				break;
			}

			SetConsoleCursorPosition( hStdOut, cursPos );
		}
	}
}

bool checkWin( const char board[3][3], bool& player, int& winner )
{
	if ( player )
		player = false;
	else
		player = true;

	// horizontal rows
	if (( board[0][0] != NULL ) && (( board[0][0] == board[1][0] ) && ( board[1][0] == board[2][0] )))
	{
		if ( board [0][0] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}
	else if (( board[0][1] != NULL ) && (( board[0][1] == board[1][1] ) && ( board[1][1] == board[2][1] )))
	{
		if ( board [0][1] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}
	else if (( board[0][2] != NULL ) && (( board[0][2] == board[1][2] ) && ( board[1][2] == board[2][2] )))
	{
		if ( board [0][2] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}

	// vertical rows
	else if (( board[0][0] != NULL ) && (( board[0][0] == board[0][1] ) && ( board[0][1] == board[0][2] )))
	{
		if ( board [0][0] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}
	else if (( board[1][0] != NULL ) && (( board[1][0] == board[1][1] ) && ( board[1][1] == board[1][2] )))
	{
		if ( board [1][0] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}
	else if (( board[2][0] != NULL ) && (( board[2][0] == board[2][1] ) && ( board[2][1] == board[2][2] )))
	{
		if ( board [2][0] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}

	// diagonals
	else if (( board[0][0] != NULL ) && (( board[0][0] == board[1][1] ) && ( board[1][1] == board[2][2] )))
	{
		if ( board [0][0] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}
	else if (( board[0][2] != NULL ) && (( board[0][2] == board[1][1] ) && ( board[1][1] == board[2][0] )))
	{
		if ( board [0][2] == 'X' )
			winner = 1;
		else
			winner = 2;
		return true;
	}

	else
	{
		for ( int i = 0; i < 3; i++ )
			for ( int j = 0; j < 3; j++ )
				if ( board[i][j] == NULL )
					return false;
		winner = -1;
		return true;
	}
}

void printWin( const int& winner)
{
	switch ( winner )
	{
	// draw
	case -1:
		std::cout << "The game is a draw!\n\n";
		break;
	// player 1
	case 1:
		std::cout << "Player 1 wins, the \"X\" is triumphant!\n\n";
		break;
	// player 2
	case 2:
		std::cout << "Player 2 wins, the \"O\" is triumphant!\n\n";
		break;
	}

	std::cout << "Press any key to return to the main menu...\n";
	_getch( );
}
 
A comment - Run the above in a new DevC++ Console project (or try it with a C++ (non .NET) console project in a Microsoft .NET compilier). It'll work with both. It will not work in Borland C++ 4.52. That thing is 12 years old, and can't run any of the "modern" code. (Personally, I'm surprised it was still in use even in 2001 at college. :ack:)
 
I only use Qbasic, only kno how to make quizes and pics and simple Programs
but try dis if ur usin QBasic..

10 CLS
20 PRINT "AcK!"
30 Goto 20
 
A comment - Run the above in a new DevC++ Console project (or try it with a C++ (non .NET) console project in a Microsoft .NET compilier). It'll work with both. It will not work in Borland C++ 4.52. That thing is 12 years old, and can't run any of the "modern" code. (Personally, I'm surprised it was still in use even in 2001 at college. :ack:)
If it's that old, does it even have headers for the windows API? :crazyeye:
 
If it's that old, does it even have headers for the windows API? :crazyeye:

Not modern ones. :p

It has a Windows GUI, but it's very cumbersome to use, and quite clunky.

Here's a sample of the code (it's a generated code by Borland -- a project called "Planets" which has nothing to do with planets, or the DOS BBS game Planets)

Code:
#include <owl\owlpch.h>
#pragma hdrstop

#include "apxprev.h"

#include "plntsapp.rh"


//{{PreviewWindow Implementation}}

DEFINE_RESPONSE_TABLE1(PreviewWindow, TDecoratedFrame)
    EV_COMMAND_ENABLE(APX_PPR_PREVIOUS, PPR_PreviousEnable),
    EV_COMMAND_ENABLE(APX_PPR_NEXT, PPR_NextEnable),
    EV_COMMAND(APX_PPR_PREVIOUS, PPR_Previous),
    EV_COMMAND(APX_PPR_NEXT, PPR_Next),
    EV_COMMAND(APX_PPR_ONEUP, PPR_OneUp),
    EV_COMMAND_ENABLE(APX_PPR_TWOUP, PPR_TwoUpEnable),
    EV_COMMAND(APX_PPR_TWOUP, PPR_TwoUp),
    EV_COMMAND(APX_PPR_DONE, PPR_Done),
//{{PreviewWindowRSP_TBL_BEGIN}}
//{{PreviewWindowRSP_TBL_END}}
END_RESPONSE_TABLE;


PreviewWindow::PreviewWindow (TWindow *parentWindow, TPrinter *printer, TWindow* currWindow, const char far* title, TLayoutWindow* client) :
                 TDecoratedFrame(parentWindow, title, client)
{
    CurrWindow = currWindow;
    Printer = printer;
    Client = client;
    Page1 = 0;
    Page2 = 0;

    TPrintDialog::TData& data = Printer->GetSetup();
    PrnDC = new TPrintDC(data.GetDriverName(),
                         data.GetDeviceName(),
                         data.GetOutputName(),
                         data.GetDevMode());

    PrintExtent = new TSize(PrnDC->GetDeviceCaps(HORZRES), PrnDC->GetDeviceCaps(VERTRES));
    Printout = new APXPrintOut(Printer, "Print Preview", currWindow, true);

    SetBkgndColor(::GetSysColor(COLOR_APPWORKSPACE));

    //
    // Create default toolbar New and associate toolbar buttons with commands.
    //
    PreviewSpeedBar = new TControlBar(this);
    PreviewSpeedBar->Insert(*new TButtonGadget(APX_PPR_PREVIOUS, APX_PPR_PREVIOUS, TButtonGadget::Command, true));
    PreviewSpeedBar->Insert(*new TButtonGadget(APX_PPR_NEXT, APX_PPR_NEXT, TButtonGadget::Command, true));
    PreviewSpeedBar->Insert(*new TSeparatorGadget(6));
    PreviewSpeedBar->Insert(*new TButtonGadget(APX_PPR_ONEUP, APX_PPR_ONEUP, TButtonGadget::Exclusive, true, TButtonGadget::Down));
    PreviewSpeedBar->Insert(*new TButtonGadget(APX_PPR_TWOUP, APX_PPR_TWOUP, TButtonGadget::Exclusive, true));
    PreviewSpeedBar->Insert(*new TSeparatorGadget(12));
    PreviewSpeedBar->Insert(*new TTextGadget(APX_PPR_CURRPAGE, TGadget::Recessed, TTextGadget::Left, 10, "Page 1"));
    PreviewSpeedBar->Insert(*new TSeparatorGadget(20));
    PreviewSpeedBar->Insert(*new TButtonGadget(CM_FILEPRINT, CM_FILEPRINT, TButtonGadget::Command, true));
    PreviewSpeedBar->Insert(*new TSeparatorGadget(20));
    PreviewSpeedBar->Insert(*new TButtonGadget(APX_PPR_DONE, APX_PPR_DONE, TButtonGadget::Command, true));
    Insert(*PreviewSpeedBar, TDecoratedFrame::Top);

    // We want a window that cannot be sized, maximized, or minimized.
    Attr.Style = (WS_VISIBLE | WS_POPUP);

    // Don't show the border of the preview window.
    Attr.X = 0;
    Attr.Y = -1;
    Attr.W = Parent->GetClientRect().Width();
    Attr.H = Parent->GetClientRect().Height() + 1;
    parentWindow->MapWindowPoints(HWindow, (TPoint *)&(Attr.X), 1);
}


PreviewWindow::~PreviewWindow ()
{
    delete Page1;
    Page1 = 0;
    delete Page2;
    Page2 = 0;

    delete PrnDC;
    PrnDC = 0;
    delete PrintExtent;
    PrintExtent = 0;
    delete Printout;
    Printout = 0;
}


void PreviewWindow::SetupWindow ()
{
    TDecoratedFrame::SetupWindow();

    TPrintDialog::TData& data = Printer->GetSetup();
    Page1 = new TPreviewPage(Client, *Printout, *PrnDC, *PrintExtent, 1);
    Page1->SetPageNumber(1);
    data.FromPage = 1;
    data.ToPage = 1;
    data.MinPage = 1;
    data.MaxPage = 1;

    Page2 = 0;

    TLayoutMetrics metrics1;

    metrics1.X.Set(lmLeft, lmRightOf, lmParent, lmLeft, 15);
    metrics1.Y.Set(lmTop, lmBelow, lmParent, lmTop, 15);

    //
    // Determine major axis of preview page, have that follow parent size.
    // Make minor axis a percentage (aspect ratio) of the page's major axis
    //
    TRect r = Client->GetClientRect();
    long ratio;

    if (PrintExtent->cx > PrintExtent->cy)
        ratio = ((long)PrintExtent->cy * 100) / PrintExtent->cx;
    else
        ratio = ((long)PrintExtent->cx * 100) / PrintExtent->cy;

    bool xMajor = (((r.Width() * ratio) / 100) > r.Height());
    if (xMajor){
        metrics1.Height.Set(lmBottom, lmAbove, lmParent, lmBottom, 15);
        metrics1.Width.PercentOf(Page1, (int)((long)PrintExtent->cx * 95 / PrintExtent->cy), lmHeight);
    } else {
        metrics1.Height.PercentOf(Page1, (int)((long)PrintExtent->cy * 95 / PrintExtent->cx), lmWidth);
        metrics1.Width.Set(lmRight, lmLeftOf, lmParent, lmRight, 15);
    }

    Page1->Create();

    Client->SetChildLayoutMetrics(*Page1, metrics1);
    Client->Layout();
}


void PreviewWindow::SpeedBarState ()
{
    TPrintDialog::TData &printerData = Printer->GetSetup();

    // Update the page count.
    TTextGadget *theTGadget = TYPESAFE_DOWNCAST(PreviewSpeedBar->GadgetWithId(APX_PPR_CURRPAGE), TTextGadget);
    if (theTGadget) {
        char    buffer[32];
        if (Page2 && (printerData.FromPage != printerData.ToPage))
            wsprintf(buffer, "Page &#37;d - %d", printerData.FromPage, printerData.ToPage);
        else
            wsprintf(buffer, "Page %d", printerData.FromPage);
        theTGadget->SetText(buffer);
    }
}


void PreviewWindow::PPR_PreviousEnable (TCommandEnabler &tce)
{
    // Only have previous on if we're not at the first page.
    TPrintDialog::TData &printerData = Printer->GetSetup();
    tce.Enable(printerData.FromPage != 1);
}


void PreviewWindow::PPR_NextEnable (TCommandEnabler &tce)
{
    // Only have next on if we're not at the last page.
    TPrintDialog::TData &printerData = Printer->GetSetup();
    tce.Enable(printerData.ToPage != printerData.MaxPage);
}


void PreviewWindow::PPR_Previous ()
{
    TPrintDialog::TData &printerData = Printer->GetSetup();

    if (printerData.FromPage > printerData.MinPage) { 
        printerData.FromPage--;
        printerData.ToPage--;

        Page1->SetPageNumber(printerData.FromPage);
        if (Page2)
            Page2->SetPageNumber(printerData.ToPage);
    }

    SpeedBarState();
}


void PreviewWindow::PPR_Next ()
{
    TPrintDialog::TData &printerData = Printer->GetSetup();

    if (printerData.ToPage < printerData.MaxPage) {
        printerData.FromPage++;
        printerData.ToPage++;

        Page1->SetPageNumber(printerData.FromPage);
        if (Page2)
            Page2->SetPageNumber(printerData.ToPage);
    }

    SpeedBarState();
}


void PreviewWindow::PPR_OneUp ()
{
    if (Page2) {
        Client->RemoveChildLayoutMetrics(*Page2);

        delete Page2;
        Page2 = 0;

        Client->Layout();

        TPrintDialog::TData &printerData = Printer->GetSetup();
        printerData.ToPage = printerData.FromPage;

        SpeedBarState();
    }
}


void PreviewWindow::PPR_TwoUpEnable (TCommandEnabler &tce)
{
    // Two up is only available for portrait mode.
    tce.Enable(PrintExtent->cx <= PrintExtent->cy);
}


void PreviewWindow::PPR_TwoUp ()
{
    if (Page2 == 0) {
        Page2 = new TPreviewPage(Client, *Printout, *PrnDC, *PrintExtent, PageNumber + 1);
        Page2->Create();

        TLayoutMetrics metrics2;

        metrics2.X.Set(lmLeft, lmRightOf, Page1, lmRight, 30);
        metrics2.Y.SameAs(Page1, lmTop);

        // Assume portrait
        //
        metrics2.Width.SameAs(Page1, lmWidth);
        metrics2.Height.SameAs(Page1, lmBottom);

        Client->SetChildLayoutMetrics(*Page2, metrics2);
        Client->Layout();

        TPrintDialog::TData &printerData = Printer->GetSetup();

        // Page 2 is the next page.  If the next page is outside of our
        // range then set the first page back one and the 2nd page is
        // the current page.  If the document is only 1 page long then
        // the 2nd page is empty.
        if (printerData.FromPage == printerData.MaxPage) {
            if (printerData.FromPage > 1) {
                printerData.FromPage--;
                printerData.ToPage = printerData.FromPage + 1;
                Page1->SetPageNumber(printerData.FromPage);
                Page2->SetPageNumber(printerData.ToPage);
            } else
                Page2->SetPageNumber(0);
        } else {
            printerData.ToPage = printerData.FromPage + 1;
            Page2->SetPageNumber(printerData.ToPage);
        }

        SpeedBarState();
    }
}


void PreviewWindow::PPR_Done ()
{
    // Don't call the base class EvClose we do not want PreviewWindow to be destructed.
    GetApplication()->GetMainWindow()->SetRedraw(false);
    GetApplication()->EndModal(IDCANCEL);
}

------------------------------------------------------------------

/*  Project planets
    
    Copyright &#65385; 1995. All Rights Reserved.

    SUBSYSTEM:    planets.exe Application
    FILE:         plntsapp.cpp
    AUTHOR:       


    OVERVIEW
    ========
    Source file for implementation of planetsApp (TApplication).      
*/


#include <owl\owlpch.h>
#pragma hdrstop

#include <dir.h>

#include "plntsapp.h"
#include "plntsedv.h"                        // Definition of client class.       
#include "plntsabd.h"                        // Definition of about dialog.       


// Drag / Drop support:
TFileDrop::TFileDrop (char* fileName, TPoint& p, bool inClient, TModule*)
{
    char    exePath[MAXPATH];
    
    exePath[0] = 0;
    FileName = strcpy(new char[strlen(fileName) + 1], fileName);
    Point = p;
    InClientArea = inClient;
}

TFileDrop::~TFileDrop ()
{
    delete FileName;
}

const char *TFileDrop::WhoAmI ()
{
  return FileName;
}


//{{planetsApp Implementation}}



//{{DOC_VIEW}}
DEFINE_DOC_TEMPLATE_CLASS(TFileDocument, planetsEditView, DocType1);
//{{DOC_VIEW_END}}

//{{DOC_MANAGER}}
DocType1 __dvt1("All Files (*.*)", "*.*", 0, "TXT", dtAutoDelete | dtUpdateDir);
//{{DOC_MANAGER_END}}


//
// Build a response table for all messages/commands handled
// by the application.
//
DEFINE_RESPONSE_TABLE1(planetsApp, TApplication)
//{{planetsAppRSP_TBL_BEGIN}}
    EV_OWLVIEW(dnCreate, EvNewView),
    EV_OWLVIEW(dnClose,  EvCloseView),
    EV_COMMAND(CM_HELPABOUT, CmHelpAbout),
    EV_COMMAND(CM_FILEPRINT, CmFilePrint),
    EV_COMMAND(CM_FILEPRINTERSETUP, CmFilePrintSetup),
    EV_COMMAND(CM_FILEPRINTPREVIEW, CmFilePrintPreview),
    EV_COMMAND_ENABLE(CM_FILEPRINT, CmPrintEnable),
    EV_COMMAND_ENABLE(CM_FILEPRINTERSETUP, CmPrintEnable),
    EV_COMMAND_ENABLE(CM_FILEPRINTPREVIEW, CmPrintEnable),
    EV_WM_DROPFILES,
    EV_WM_WININICHANGE,
//{{planetsAppRSP_TBL_END}}
END_RESPONSE_TABLE;


//////////////////////////////////////////////////////////
// planetsApp
// =====
//
planetsApp::planetsApp () : TApplication("planets")
{
    Printer = 0;
    Printing = 0;

    SetDocManager(new TDocManager(dmSDI, this));

    // INSERT>> Your constructor code here.
}


planetsApp::~planetsApp ()
{
    if (Printer)
        delete Printer;

    // INSERT>> Your destructor code here.
}




void planetsApp::CreateGadgets (TControlBar *cb, bool server)
{
    if (!server) {
        cb->Insert(*new TButtonGadget(CM_FILENEW, CM_FILENEW));
        cb->Insert(*new TButtonGadget(CM_FILEOPEN, CM_FILEOPEN));
        cb->Insert(*new TButtonGadget(CM_FILESAVE, CM_FILESAVE));
        cb->Insert(*new TSeparatorGadget(6));
    }

    cb->Insert(*new TButtonGadget(CM_EDITCUT, CM_EDITCUT));
    cb->Insert(*new TButtonGadget(CM_EDITCOPY, CM_EDITCOPY));
    cb->Insert(*new TButtonGadget(CM_EDITPASTE, CM_EDITPASTE));
    cb->Insert(*new TSeparatorGadget(6));
    cb->Insert(*new TButtonGadget(CM_EDITUNDO, CM_EDITUNDO));
    cb->Insert(*new TSeparatorGadget(6));
    cb->Insert(*new TButtonGadget(CM_EDITFIND, CM_EDITFIND));
    cb->Insert(*new TButtonGadget(CM_EDITFINDNEXT, CM_EDITFINDNEXT));

    if (!server) {
        cb->Insert(*new TSeparatorGadget(6));
        cb->Insert(*new TButtonGadget(CM_FILEPRINT, CM_FILEPRINT));
        cb->Insert(*new TButtonGadget(CM_FILEPRINTPREVIEW, CM_FILEPRINTPREVIEW));
    }

    // Add fly-over help hints.
    cb->SetHintMode(TGadgetWindow::EnterHints);
}


void planetsApp::SetupSpeedBar (TDecoratedFrame *frame)
{ 
    //
    // Create default toolbar New and associate toolbar buttons with commands.
    //   
    TControlBar* cb = new TControlBar(frame);
    CreateGadgets(cb);

    // Setup the toolbar ID used by OLE 2 for toolbar negotiation.
    cb->Attr.Id = IDW_TOOLBAR;

    frame->Insert(*cb, TDecoratedFrame::Top);
}


//////////////////////////////////////////////////////////
// planetsApp
// =====
// Application intialization.
//
void planetsApp::InitMainWindow ()
{
    if (nCmdShow != SW_HIDE)
        nCmdShow = (nCmdShow != SW_SHOWMINNOACTIVE) ? SW_SHOWNORMAL : nCmdShow;

    SDIDecFrame *frame = new SDIDecFrame(0, GetName(), 0, true, this);

    //
    // Assign ICON w/ this application.
    //
    frame->SetIcon(this, IDI_SDIAPPLICATION);

    //
    // Menu associated with window and accelerator table associated with table.
    //
    frame->AssignMenu(SDI_MENU);
    
    //
    // Associate with the accelerator table.
    //
    frame->Attr.AccelTable = SDI_MENU;

    SetupSpeedBar(frame);

    TStatusBar *sb = new TStatusBar(frame, TGadget::Recessed,
                                    TStatusBar::CapsLock        |
                                    TStatusBar::NumLock         |
                                    TStatusBar::ScrollLock      |
                                    TStatusBar::Overtype);
    frame->Insert(*sb, TDecoratedFrame::Bottom);
  
    SetMainWindow(frame);

    frame->SetMenuDescr(TMenuDescr(SDI_MENU));

}


//////////////////////////////////////////////////////////
// planetsApp
// =====
// Response Table handlers:
//
void planetsApp::EvNewView (TView& view)
{
    GetMainWindow()->SetClientWindow(view.GetWindow());
    if (!view.IsOK())
        GetMainWindow()->SetClientWindow(0);
    else if (view.GetViewMenu())
        GetMainWindow()->MergeMenu(*view.GetViewMenu());
}


void planetsApp::EvCloseView (TView&)
{
    GetMainWindow()->SetClientWindow(0);
    GetMainWindow()->SetCaption("planets");
}


//{{SDIDecFrame Implementation}}


SDIDecFrame::SDIDecFrame (TWindow *parent, const char far *title, TWindow *clientWnd, bool trackMenuSelection, TModule *module)
    : TDecoratedFrame(parent, title, clientWnd, trackMenuSelection, module)
{
    // INSERT>> Your constructor code here.

}


SDIDecFrame::~SDIDecFrame ()
{
    // INSERT>> Your destructor code here.

}


//////////////////////////////////////////////////////////
// planetsApp
// ==========
// Menu File Print command
void planetsApp::CmFilePrint ()
{
    //
    // Create Printer object if not already created.
    // 
    if (!Printer)
        Printer = new TPrinter(this);

    //
    // Create Printout window and set characteristics.
    //
    APXPrintOut printout(Printer, "Title", GetMainWindow()->GetClientWindow());
    printout.SetBanding(true);

    Printing++;

    //
    // Bring up the Print dialog and print the document.
    //
    Printer->Print(GetWindowPtr(GetActiveWindow()), printout, true);

    Printing--;
}


//////////////////////////////////////////////////////////
// planetsApp
// ==========
// Menu File Print Setup command
void planetsApp::CmFilePrintSetup ()
{
    if (!Printer)
        Printer = new TPrinter(this);

    //
    // Bring up the Print Setup dialog.
    //
    Printer->Setup(GetMainWindow());
}


//////////////////////////////////////////////////////////
// planetsApp
// ==========
// Menu File Print Preview command
void planetsApp::CmFilePrintPreview ()
{
    SDIDecFrame *sdiFrame = TYPESAFE_DOWNCAST(GetMainWindow(), SDIDecFrame); 
    if (sdiFrame) {
        if (!Printer)
            Printer = new TPrinter(this);

        Printing++;

        PreviewWindow *prevW = new PreviewWindow(sdiFrame, Printer, sdiFrame->GetClientWindow(), "Print Preview", new TLayoutWindow(0));
        prevW->Create();

        BeginModal(GetMainWindow());

        Printing--;

        // Now that printing is off we can invalidate because the edit window to repaint.
        GetMainWindow()->SetRedraw(true);
        GetMainWindow()->Invalidate();

        // We must destroy the preview window explicitly.  Otherwise, the window will not be destroyed until
        // it's parent the MainWindow is destroyed.
        prevW->Destroy();
        delete prevW;
    }
}


//////////////////////////////////////////////////////////
// planetsApp
// ==========
// Menu enabler used by Print, Print Setup and Print Preview.
void planetsApp::CmPrintEnable (TCommandEnabler &tce)
{
    // If we have a Printer already created just test if all is okay.
    // Otherwise create a Printer object and make sure the printer
    // really exists and then delete the Printer object.
    if (!Printer) {
        Printer = new TPrinter(this);
        
        tce.Enable(Printer->GetSetup().Error == 0);
    } else
        tce.Enable(Printer->GetSetup().Error == 0);
}


//////////////////////////////////////////////////////////
// planetsApp
// ===========
// Menu Help About planets.exe command
void planetsApp::CmHelpAbout ()
{
    //
    // Show the modal dialog.
    //
    planetsAboutDlg(GetMainWindow()).Execute();
}


void planetsApp::InitInstance ()
{
    TApplication::InitInstance();

    // Accept files via drag/drop in the frame window.
    GetMainWindow()->DragAcceptFiles(true);
}


void planetsApp::EvDropFiles (TDropInfo drop)
{
	// Tell DragQueryFile the file interested in (0) and the length of your buffer.
	int     fileLength = drop.DragQueryFileNameLen(0) + 1;
	char    *fileName = new char[fileLength];

	drop.DragQueryFile(0, fileName, fileLength);

	// Open the file that was dropped.
	AddFile(fileName);
    // Release the memory allocated for this handle with DragFinish.
    drop.DragFinish();
}


void planetsApp::AddFile (const char *FileName)
{
    TDocTemplate* tpl = GetDocManager()->MatchTemplate(FileName);
    if (tpl)
      tpl->CreateDoc(FileName);
}


void planetsApp::EvWinIniChange (char far* section)
{
    if (strcmp(section, "windows") == 0) {
        // If the device changed in the WIN.INI file then the printer
        // might have changed.  If we have a TPrinter (Printer) then
        // check and make sure it's identical to the current device
        // entry in WIN.INI.
        if (Printer) {
            char printDBuffer[255];
            LPSTR printDevice = printDBuffer;
            LPSTR devName;
            LPSTR driverName = 0;
            LPSTR outputName = 0;
        
            if (::GetProfileString("windows", "device", "", printDevice, sizeof(printDevice))) {
                // The string which should come back is something like:
                //
                //      HP LaserJet III,hppcl5a,LPT1:
                //
                // Where the format is:
                //
                //      devName,driverName,outputName
                //
                devName = printDevice;
                while (*printDevice) {
                    if (*printDevice == ',') {
                        *printDevice++ = 0;
                        if (!driverName)
                            driverName = printDevice;
                        else
                            outputName = printDevice;
                    } else
                        printDevice = ::AnsiNext(printDevice);
                }

                if ((Printer->GetSetup().Error != 0)                                ||
                    (strcmp(devName, Printer->GetSetup().GetDeviceName()) != 0)    ||
                    (strcmp(driverName, Printer->GetSetup().GetDriverName()) != 0) ||
                    (strcmp(outputName, Printer->GetSetup().GetOutputName()) != 0)) {
                
                    // New printer installed so get the new printer device now.
                    delete Printer;
                    Printer = new TPrinter(this);
                }
            } else {
                // No printer installed (GetProfileString failed).
                delete Printer;
                Printer = new TPrinter(this);
            }
        }
    }
}


int OwlMain (int , char* [])
{
    try {
        planetsApp    app;
        return app.Run();
    }
    catch (xmsg& x) {
        ::MessageBox(0, x.why().c_str(), "Exception", MB_OK);
    }

    return -1;
}
 
Back
Top Bottom