终于搭好了一个游戏的窗口框架(一个调试窗口,一个消息窗口,一个主窗口)

6 篇文章 0 订阅
4 篇文章 0 订阅
//Map.cpp
#include <StdAfx.h>
  terrain.cpp:
// terrain.cpp : Defines the entry point for the application.
//

#include "StdAfx.h"
#include "Map.h"
#include "Console.h"
#include "IO.H"
#include <sstream>
#include <iostream>
#include <stdio.h>
static bool IsInit=true;
std::wstring reader;
using std::wstring;
using std::wcout;
using std::cout;
using std::endl;
HWND	hWnd=NULL;	// 保存 Windows 分配给程序的窗口句柄
HWND	hWnd2=NULL;	// 保存 Windows 分配给程序的窗口句柄
HWND    hConsole;
int Width=800;
LRESULT WINAPI ght(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam );
int Height=600;
//声明消息处理函数
//创建对话框,显示系统消息:
LPCTSTR  title="游戏初始化中,请稍等";

void InitMessagePrint(LPCWSTR  text);
LRESULT WINAPI MsgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam );
LRESULT WINAPI lpDialogFunc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam );
//声明消息循环函数。
void GameLoop();
DWORD WINAPI ThreadFunc( LPVOID lpParam ) 
{ 
	int Width=200;
	int Height=200;
	bool fullScreen =TRUE;
	DWORD	dwExStyle;		// Window 扩展风格
	DWORD	dwStyle;		// Window 窗口风格
	RECT	windowRect;		// 窗口尺寸
	int		nX=0,nY=0;
	int wid=GetSystemMetrics(SM_CXSCREEN);		// 获取当前屏幕宽
	int hei=GetSystemMetrics(SM_CYSCREEN);		// 获取当前屏幕高
	nX=0;nY=0;			// 计算窗口居中用
	dwExStyle=WS_EX_WINDOWEDGE;	// 使窗口具有3D外观
	dwStyle=WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX;				//创建一个带边框和标题的窗口。
	AdjustWindowRectEx(&windowRect,dwStyle,FALSE,dwExStyle);
			char cc1[]="terrainmessage";
	//窗口类
    WNDCLASSEX wc1 = { 
		              sizeof(WNDCLASSEX),
		              //所有的窗口共用一个设备。
		              CS_CLASSDC, 
					  //消息循环函数
					  ght, 
                      //窗口类额外的存储空间
					  0L, 
					  //窗口实例额外的存储空间。
					  0L, 
					  //获得创建窗口的进程单元句柄(.EXE文件的文件句柄)
                      GetModuleHandle(NULL),
                      //
					  NULL,
					  NULL, 
					  NULL, 
					  NULL,
                      cc1, 
					  NULL 
	};
	//注册窗口类
    RegisterClassEx( &wc1 );

	hWnd2 = CreateWindowEx(NULL,cc1,"我的第一个3D地形程序",
						  dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
						  nX, nY,Width, Height,
						  NULL,NULL,NULL,NULL);	// 创建窗口

  //  PostQuitMessage(0);

	//显示窗口
	ShowWindow( hWnd2, SW_SHOWDEFAULT );				// 显示窗口

	//更新窗口
	UpdateWindow( hWnd2 );
	//消息循环
	//消息循环
	//窗口2的消息循环。

    GameLoop();	
//UnregisterClass(cc1,
  //  hInstance
//);
return 0;
} 

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{ 
    RedirectIOToConsole();
	//得到控制台窗口的窗口句柄。
//hConsole=GetConsoleWindow(void);
hConsole=FindWindow("ConsoleWindowClass",NULL); 
//HRGN hRgn=CreateRectRgn(0,0,500,500); 
//SetWindowRgn(h,hRgn,false); 

/*********************线程创建**********************/
  DWORD dwThreadId, dwThrdParam = 1; 
    HANDLE hThread; 
//创建线程ID,参数为dwThrdParam;
    hThread = CreateThread( 
        NULL,                        // default security attributes 
        0,                           // use default stack size  
        ThreadFunc,                  // thread function 
        &dwThrdParam,                // argument to thread function 
        0,                           // use default creation flags 
        &dwThreadId);                // returns the thread identifier 
 if (hThread == NULL) 
   {
      printf( "CreateThread failed (%d)\n", GetLastError() ); 
   }
   else 
   {
      
      CloseHandle( hThread );
   }
   //检测窗口是否初始化完毕。
   while(IsInit){
    Sleep(1);
   }

/************************我们的线程就在这里*********************************/
    //The AdjustWindowRectEx function
	//calculates the required size of the window rectangle,
	//based on the desired size of the client rectangle. 
	//The window rectangle can then be passed to the CreateWindowEx 
	//function to create a window
	//whose client area is the desired size. 
    //根据所要求的客户区大小,来创建窗口。
    //是否全屏模式。
    bool fullScreen =TRUE;
	DWORD	dwExStyle;		// Window 扩展风格
	DWORD	dwStyle;		// Window 窗口风格
	RECT	windowRect;		// 窗口尺寸
	int		nX=0,nY=0;
	int wid=GetSystemMetrics(SM_CXSCREEN);		// 获取当前屏幕宽
	int hei=GetSystemMetrics(SM_CYSCREEN);		// 获取当前屏幕高
	nX=(wid-Width)/2;nY=(hei-Height)/2;			// 计算窗口居中用
	dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;	// 使窗口具有3D外观
	dwStyle=WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MAXIMIZE|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;				//创建一个带边框和标题的窗口。
	AdjustWindowRectEx(&windowRect,dwStyle,FALSE,dwExStyle);
    /*	typedef struct {
    UINT cbSize;
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
    HICON hIconSm;
    } WNDCLASSEX, *PWNDCLASSEX;
    */
	//窗口类名
	char cc[]="terrain";
	//窗口类
	InitMessagePrint(L"注册窗口类");
    WNDCLASSEX wc = { 
		              sizeof(WNDCLASSEX),
		              //所有的窗口共用一个设备。
		              CS_CLASSDC, 
					  //消息循环函数
					  MsgProc, 
                      //窗口类额外的存储空间
					  0L, 
					  //窗口实例额外的存储空间。
					  0L, 
					  //获得创建窗口的进程单元句柄(.EXE文件的文件句柄)
                      GetModuleHandle(NULL),
                      //
					  NULL,
					  NULL, 
					  NULL, 
					  NULL,
                      cc, 
					  NULL 
	};
	RegisterClassEx( &wc );
/*****************************hWnd2用来显示初始消息**************************************/
    InitMessagePrint(L"正在创建窗口");
/************************************************************/
    hWnd = CreateWindowEx(NULL,cc,"我的第一个3D地形程序",
						  dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
						  nX, nY,Width, Height,
						  NULL,NULL,hInstance,NULL);	// 创建窗口
	//显示窗口发送
	ShowWindow( hWnd, SW_SHOWDEFAULT );				// 显示窗口
	//更新窗口
	PostThreadMessage(dwThreadId,WM_QUIT,0,0);
	UpdateWindow( hWnd );
   InitMessagePrint(L"正在处理小数点");
    //这个时候的消息循环再次发送至第一个窗口类的窗口函数,为什么。

	GameLoop();	
	return;
}
void GameLoop()
{   
	static int i=0;
	//cout<<i++<<endl;
	MSG msg; 
    BOOL fMessage;
	PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
    while(msg.message != WM_QUIT)	// 消息循环
    {   
		fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
        if(fMessage)				//有消息
			{
			TranslateMessage(&msg);
			//对DispatchMessage的深刻理解
			//DispatchMessage将不同的消息发往不同的HWND标识的窗口处理函数。
			//如果消息的HWND为NULL,那么将发送至所有的属于当前线程的函数。
            DispatchMessage(&msg);
			}
    }
	//cout<<"消息循环结束!"<<endl;
}
LRESULT WINAPI MsgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam ){
RECT rect;
static bool IsInit=true;

	switch(message)
	{
	case WM_PAINT:
		PAINTSTRUCT ps;
	HDC hdc=	BeginPaint(hWnd,&ps);
 GetClientRect(hWnd,&rect);
    Rectangle(hdc,rect.left-1,rect.top-1,rect.right+1,rect.bottom+1);
		EndPaint(hWnd,&ps);
		break;
	}
		//cout<<"我的事情我做主!"<<endl;
	//	wstring ws=wstring(L"ggggggggggg"); 
	//MyWrite(ws);
	//	InitMessagePrint(L"正在创建窗口");
	int state;
	switch(state){
	case START_STATE:
	  break;
	case WORKING_STATE:
	  break;
	case END_STATE:
	  break;
	}
	if(IsInit==true)
	{
	//设置窗口前置。
	IsInit=false;
    SetForegroundWindow( hWnd);
	}
	return (DefWindowProc(hWnd, message, wParam, lParam));
}

LRESULT WINAPI lpDialogFunc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam ){

	switch(message)
			{	
			case WM_CLOSE:	
				// 关闭窗口
			//m_OpenGL->CleanUp();			// 结束处理
			PostQuitMessage(0);
			return 0;
			}
}
 void InitMessagePrint(LPCWSTR   text)
{ 
    wstring ws=wstring(text); 
	MyWrite(ws);
	RECT rect; 
    GetClientRect(hWnd2,&rect);
	InvalidateRect(hWnd2,&rect,true);
	//这四个参数分别对应MSG结构体中的4个参数。
	//也对应于消息处理函数中的四个参数。
}

//消息窗口
LRESULT WINAPI ght(HWND hWnd2,UINT message,WPARAM wParam,LPARAM lParam ){
//cout<<"是系统消息么"<<endl;

    HDC hdc;
	HBRUSH hBr;
    RECT rect; 
	switch(message){
	case WM_CLOSE:
		DestroyWindow(hWnd2);
		// 关闭窗口
			//m_OpenGL->CleanUp();			// 结束处理
			PostQuitMessage(0);
			return 0;
    case WM_PAINT:
   // ReleaseDC(hWnd2, hdc);

//	LPSTR k[10]="123456789";
/*	char wsz[5] = "aadf";
	char the[5];
    //char thechar[10]=(char *)wsz;
    io.write(wsz,5);
	io.read(the,5);
	for(int i=0;i<5;i++)
	{
	cout<<"daaaaaaaaa"<<the[i]<<"ddddddd"<<endl;
	}
    //把单字节转化为多字节:
	//wchar_t the23[5] =L"1231";
	TextOutA(hdc,0,0,(const char *)the,100);
	*/
     //ostream& MyWrite(string s);
			
	// Paint into this DC
	//得到客户区坐标
	hdc = GetDCEx(hWnd2, (HRGN)1, DCX_INTERSECTRGN);
    GetClientRect(hWnd2,&rect);
    Rectangle(hdc,rect.left-1,rect.top-1,rect.right+1,rect.bottom+1);
	const wchar_t *pchar;
//	wcout<<L"reader"<<endl;	
	
 
	while(MyRead(reader)){
	//wcout<<reader;

    pchar=reader.c_str();
	TextOutW(hdc,0,0,pchar,reader.length());
	}
	ReleaseDC(hWnd2,hdc);
		if(IsInit==true)IsInit=false;
	break;
	}

	return DefWindowProc(hWnd2, message, wParam, lParam);
}

	/*
	// 注册窗口类
	bool fullScreen =TRUE;
	DWORD	dwExStyle;		// Window 扩展风格
	DWORD	dwStyle;		// Window 窗口风格
	RECT	windowRect;		// 窗口尺寸
	int		nX=0,nY=0;
	dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;	// 使窗口具有3D外观
	dwStyle=WS_OVERLAPPEDWINDOW;				// 使用标准窗口
	//WS_OVERLAPPEDWINDOW是有标题栏,窗口菜单,最大、小化按钮和可调整尺寸的窗口
	int wid=GetSystemMetrics(SM_CXSCREEN);		// 获取当前屏幕宽
	int hei=GetSystemMetrics(SM_CYSCREEN);		// 获取当前屏幕高
	nX=(wid-Width)/2;nY=(hei-Height)/2;			// 计算窗口居中用
//-------------------------------------------------------------------
	AdjustWindowRectEx(&windowRect,dwStyle,FALSE,dwExStyle);
									//根据窗口风格来调整窗口尺寸达到要求的大小
	char cc[]="tml";
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      cc, NULL };
    RegisterClassEx( &wc );
	m_OpenGL=new OpenGL();//
	hWnd = CreateWindowEx(NULL,cc,"我的第一个3D地形器",
						  dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
						  nX, nY,Width, Height,
						  NULL,NULL,hInst,NULL);	// 创建窗口
	ShowWindow( hWnd, SW_SHOWDEFAULT );				// 显示窗口
	UpdateWindow( hWnd );							// 刷新窗口
	GameLoop();										// 进入消息循环
    return 0;
	*/


Console.cpp:

 

//说明:此函数用来在MFC或者WindowsAPP中进行标准输入。
#include < process.h>
#include "stdafx.h"
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream.h>
#include <fstream.h>
#include "Console.h"
#define MAX_CONSOLE_LINES 10;
HANDLE  g_hConsoleOut;                   
// Handle to debug console
// This function dynamically creates a 
//"Console" window and points stdout and stderr to it.
// It also hooks stdin to the window
// You must free it later with FreeConsole
void RedirectIOToConsole()
{    
int                        hConHandle;
long                       lStdHandle;    
CONSOLE_SCREEN_BUFFER_INFO coninfo;  
FILE                       *fp;    
// allocate a console for this app    
AllocConsole();    
// set the screen buffer to be big enough to let us scroll text    
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);   
coninfo.dwSize.Y = MAX_CONSOLE_LINES; 
 // How many lines do you want to have in the console buffer    
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),coninfo.dwSize);   
 // redirect unbuffered STDOUT to the console    
g_hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);    
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);    
fp = _fdopen( hConHandle, "w" );    
*stdout = *fp; 
setvbuf( stdout, NULL, _IONBF, 0 );  
// redirect unbuffered STDIN to the console    
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);    
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);    
fp = _fdopen( hConHandle, "r" );    
*stdin = *fp;    
setvbuf( stdin, NULL, _IONBF, 0 );    
// redirect unbuffered STDERR to the console    
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);  
//把系统的文件句柄转化为c运行库的文件指针 
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
//用write 方法打开文件流    
fp = _fdopen( hConHandle, "w" );
//将stderr指向这个文件流。   
*stderr = *fp;  
//第二个参数为NULL,表明没有缓冲区和流相关联。 
setvbuf( stderr, NULL, _IONBF, 0 );		
SetConsoleTitle("The Console Titlebar Text");  
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog     
// point to console as well  Uncomment the next line if you are using c++ cio or comment if you don't    
ios::sync_with_stdio();
}

 

IO.cpp:

 

#include "StdAfx.h"
#include "IO.H"
#include <locale>
using std::wstringstream;
wstringstream *pBuffer=new wstringstream();
bool MyWrite(std::wstring s)
{
	static bool InitLocal=true;
	if(InitLocal){
	std::locale loc("chs");   
    pBuffer->imbue(loc);
	InitLocal=false;
	}
	pBuffer->clear();
	if((*pBuffer)<<s)
	{
		pBuffer->put(L'\n');
		return true;
	}
	return false;
}
bool MyRead(std::wstring& s)
{
   if(NULL!=pBuffer)
   {
	  wchar_t name[256];
	  pBuffer->clear();
      pBuffer->getline(name,256);
	  s=std::wstring(name);
	  	//  pBuffer->ignore();
      if(s.length()>0)
	  {
		  return true;
	  }
   }
   return false;
}

 

// stdafx.cpp : source file that includes just the standard includes
//	terrain.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

 

Map.h
//常量表示程序的各种状态
//要想使用const必须把头文件包含进去。
//定义全局的cons会造成意想不到的错误。因为重复定义!!
const int START_STATE=0;
const int END_STATE=1;
const int WORKING_STATE=2;

 

Console.h
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
void RedirectIOToConsole();

 

//IO.H
#ifndef IO_H
#define IO_H
#include <string>
#include <sstream>
extern bool MyWrite(std::wstring s);
extern bool MyRead(std::wstring& s);
#endif

 

//Map.H
//常量表示程序的各种状态
//要想使用const必须把头文件包含进去。
//定义全局的cons会造成意想不到的错误。因为重复定义!!
const int START_STATE=0;
const int END_STATE=1;
const int WORKING_STATE=2;

 

// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers

#include <windows.h>
// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值